Feedback on LW1 EAR

Remi Forax forax at univ-mlv.fr
Sat Aug 18 17:44:51 UTC 2018


----- Mail original -----
> De: "Uberto Barbini" <uberto.gama at gmail.com>
> À: "valhalla-dev" <valhalla-dev at openjdk.java.net>
> Envoyé: Samedi 18 Août 2018 12:40:36
> Objet: Feedback on LW1 EAR

> Good morning,
> 

hi Uberto,

> 
> I've played a bit in these days with the EAR and here is my feedback.

thanks for doing that !

> 
> First of all, thanks for the great work! It's really nice to be able to use
> ValueTypes for immutable small objects.
> 
> We the London Java Community we are organizing a hack day on this for
> middle of September, if someone is interested.
> 
> Now I've a few question and a fatal error to report.
> 
> 1) I saw there I can create Value Types using makeDefault + setField in a
> static method or I can use the "normal" new Value() syntax?
> The byte code produced seems identical:
> 4 invokestatic #3 <com/gamasoft/Point.$makeValue$>
> Is there a difference or a preference for the future ?

The current prototype focus on the VM side of the value types, not the language side (the Java side), we have voluntarily move all the syntax discussion into a latter phase because, it's hard to do both the VM and the Java side at the same time so the only answer i can provide is we don't know :) 

So the syntax for accessing to the opcodes default and withfield are placeholders.

That's said having a similar way to describe the initialization of a value type compared to the initialization of a class is something which is appealing, it's aligned with our moto . 

> 
> 2) Currently == won't compile. It will work eventually? It would be nice to
> be able to control a few of operator (== + - * / say)...

Again, it's a surface syntax discussion, so i will wanser with another question, what about == if the right side is an Object and the left side is a value type (or vice versa).

What we know is that acmp (the bytecode of == between object) returns false if one of the Object is a value type.

> 
> 3) in the declaration
> final __ByVal public class
> final seems to be optional. Will it stay so ?

again, syntax discussion, what we now is that a value class can not be inherited and is immutable.

> 
> 4) isValue() is still not present, is there another way to know if an
> instance or a class is a Value or not with current EAR?

isValue() is declared on the class i.e. foo.getClass().isValue()  

> 
> 5) I saw that I can override toString() and call super.toString() to have
> the standard Object behavior. I wonder if there will be some kind of base
> class for all ValueTypes or not.

no base class, a value type is a subtype of Object the same way an interface is a subtype of an Object,
i.e. the relation between a value type and Object is not an inheritance relationship but a subtyping relationship,
so you can see a value as an Object 
  Object o = value;
but you can not expect all the methods of java.lang.Object to be available on a value type.

The only 3 methods from j.l.Object available are toString(), equals() and hashCode().
Currently, the compiler (and the JDK) provides a default implementation for those methods and you can override them. 

> 
> 
> Then I've tried to replace some immutable classes into Value Types use them
> in my other projects.
> The main hindrance has been the missing support for generics.

not only, but i let you find the other issues by yourself :) 

You can disable the error about generics using javac -XDallowGenericsOverValues,
obviously, it doesn't provide any support of reified generics, it just disable the error.

> As workaround I've created a interface and based the collection on the
> interface. It worked in a few projects but I had a Fatal Error on a simple
> algorithm. I've tried to understand the exact problem but the same code
> seems to work as standalone project... If it's something worth
> investigating I can dig it more
> 
> https://github.com/uberto/eopi/blob/ValhallaLW01/src/test/java/com/gamasoft/eopi/cap17_DynamicProgramming/KnapsackTest.java

Thanks for the report !

regards,
Rémi

[1] https://bugs.openjdk.java.net/browse/JDK-8209009

> 
> 
> #
> # A fatal error has been detected by the Java Runtime Environment:
> #
> #  SIGSEGV (0xb) at pc=0x00007f08c3d648aa, pid=18399, tid=18426
> #
> # JRE version: OpenJDK Runtime Environment (11.0) (build
> 11-lworldea+0-2018-07-30-1734349.david.simms.valhalla)
> # Java VM: OpenJDK 64-Bit Server VM
> (11-lworldea+0-2018-07-30-1734349.david.simms.valhalla, mixed mode,
> compressed oops, g1 gc, linux-amd64)
> # Problematic frame:
> # V  [libjvm.so+0x4148aa]  AddPNode::Value(PhaseGVN*) const+0x7a
> #
> # No core dump will be written. Core dumps have been disabled. To enable
> core dumping, try "ulimit -c unlimited" before starting Java again
> #
> # If you would like to submit a bug report, please visit:
> #   http://bugreport.java.com/bugreport/crash.jsp
> #
> 
> ---------------  S U M M A R Y ------------
> 
> Command Line: -ea -XX:+EnableValhalla
> -Didea.test.cyclic.buffer.size=1048576
> -javaagent:/home/uberto/idea-IC-181.4203.550/lib/idea_rt.jar=35303:/home/uberto/idea-IC-181.4203.550/bin
> -Dfile.encoding=UTF-8 com.intellij.rt.execution.junit.JUnitStarter
> -ideVersion5 -junit4
> com.gamasoft.eopi.cap17_DynamicProgramming.KnapsackTest,bigShop
> 
> Host: Intel(R) Core(TM) i7-4750HQ CPU @ 2.00GHz, 8 cores, 15G, Ubuntu
> 16.04.4 LTS
> Time: Sat Aug 18 11:05:34 2018 BST elapsed time: 0 seconds (0d 0h 0m 0s)
> 
> ---------------  T H R E A D  ---------------
> 
> Current thread (0x00007f0880159800):  JavaThread "C2 CompilerThread1"
> daemon [_thread_in_native, id=18426,
> stack(0x00007f089c2f5000,0x00007f089c3f6000)]
> 
> 
> Current CompileTask:
> C2:    805  250
> com.gamasoft.eopi.cap17_DynamicProgramming.Knapsack$WatchV::equals (8 bytes)
> 
> Stack: [0x00007f089c2f5000,0x00007f089c3f6000],  sp=0x00007f089c3f1f10,
> free space=1011k
> Native frames: (J=compiled Java code, A=aot compiled Java code,
> j=interpreted, Vv=VM code, C=native code)
> V  [libjvm.so+0x4148aa]  AddPNode::Value(PhaseGVN*) const+0x7a
> V  [libjvm.so+0xc95769]  PhaseGVN::transform_no_reclaim(Node*)+0x49
> V  [libjvm.so+0xc750b5]  Parse::optimize_cmp_with_klass(Node*)+0x125
> V  [libjvm.so+0xc7c6c8]  Parse::do_one_bytecode()+0x3f28
> V  [libjvm.so+0xc6aa78]  Parse::do_one_block()+0x218
> V  [libjvm.so+0xc6aea3]  Parse::do_all_blocks()+0xc3
> V  [libjvm.so+0xc6cf60]  Parse::Parse(JVMState*, ciMethod*, float)+0x940
> V  [libjvm.so+0x561968]  ParseGenerator::generate(JVMState*)+0x78
> V  [libjvm.so+0x749360]  Parse::do_call()+0x2c0
> V  [libjvm.so+0xc7c4a4]  Parse::do_one_bytecode()+0x3d04
> V  [libjvm.so+0xc6aa78]  Parse::do_one_block()+0x218
> V  [libjvm.so+0xc6aea3]  Parse::do_all_blocks()+0xc3
> V  [libjvm.so+0xc6cf60]  Parse::Parse(JVMState*, ciMethod*, float)+0x940
> V  [libjvm.so+0x561968]  ParseGenerator::generate(JVMState*)+0x78
> 
> 
> 
> ---class code
> 
> 
>    interface Watch{ //mini interface for use with generics
>        int weight();
>        int price();
>    }
> 
> 
>    __ByValue public static class WatchV implements Watch {
>        public final int weight;
>        public final int price;
> 
>        public WatchV(int weight, int price) {
>            this.weight = weight;
>            this.price = price;
>        }
> 
>        @Override
>        public String toString() {
>            return "W{"+ weight +
>                    "," + price +
>                    '}';
>        }
> 
>        @Override
>        public int weight() {
>            return weight;
>        }
> 
>        @Override
>        public int price() {
>            return price;
>        }
>     }



More information about the valhalla-dev mailing list