From headius at headius.com Wed Jun 2 07:39:01 2010 From: headius at headius.com (Charles Oliver Nutter) Date: Wed, 2 Jun 2010 09:39:01 -0500 Subject: Mac OS X build available from 2010 05 28 In-Reply-To: References: <98EDE505-3327-4763-89E3-D0D8AB701E9A@oracle.com> Message-ID: All looks good, thanks Stephen! On Mon, May 31, 2010 at 10:34 PM, Stephen Bannasch wrote: > Thanks for the tips John, > >>On May 31, 2010, at 4:34 PM, Stephen Bannasch wrote: >> >>> At 12:41 PM -0500 5/31/10, Charles Oliver Nutter wrote: >>>> I'll make a shameless request, since you have a build env set up and >>>> I've been too lazy to refresh mine: can you post a fastdebug build >>>> too? I needz me opto assemblyz! >>> >>> Remind me (or point me to the info) about how to make a fastdebug build. >> >>I think you can set SKIP_FASTDEBUG_BUILD=true on the original make command line (at the end of build.sh). >> >>It might also work to set "export SKIP_FASTDEBUG_BUILD=true" in the shell. > > OK, in my build script (update.sh at http://gist.github.com/243072) where I set the variable 'sets' I've added: > > ?DEBUG_NAME=fastdebug > ?SKIP_FASTDEBUG_BUILD=true > > I find the name SKIP_FASTDEBUG_BUILD confusing if setting it to true causes the build to be a 'fastdebug' build -- seems 'skip'means the opposite would be true. > > How can I tell if I've created a fastdebug build? > > >>You can also chdir into the build directory and build and test the JVM incrementally: >> ?$ cd $DAVINCI/sources >> ?$ export JAVA_BUILD=$(cd build/bsd-i586/j2sdk-image; pwd -P) >> ?$ cd build/bsd-i586/hotspot/outputdir/bsd_i486_compiler2/fastdebug >> ?$ make >> ?$ alias gamma='JAVA_HOME=$JAVA_BUILD DYLD_LIBRARY_PATH=. ./gamma' >> ?$ gamma Queens #etc. >> >>> I also need to learn how to easily move backwards in the mlvm patch repo because the tip didn't build for me yesterday (patch conflicts). >> >>The "hg qpush" command manipulates the applied patch set. >> ?$ cd $DAVINCI/sources/hotspot >> ?$ hg qpop -a ?# pop all >> ?$ hg qpush meth-ldc-6939203.patch ?# push to that point >> ?$ hg qpop ? # pop one back >> >>Sorry about the mismatched patches. ?I did a bunch of pushing to hotspot-comp last week and didn't clean up properly. Will fix shortly. > > > I tried just commenting out cpindex-6957080.patch in patches/hotspot/series > > ?# cpindex-6957080.patch ? ? ? ? ? #-/meth #+d6d1af32c5f9 > > and that seemed to work. > > *** but I see you just updated the patches so tip compiles again, thanks ;-) > > > ?$ ./build/bsd-i586/j2sdk-image/bin/java -version > > ?openjdk version "1.7.0-internal-fastdebug" > ?OpenJDK Runtime Environment (build 1.7.0-internal-fastdebug-stephen_2010_05_31_22_38-b00) > ?OpenJDK Server VM (build 18.0-b04-fastdebug, mixed mode) > > I just finished uploading a new build (hopefully one built w/fastdebug) here: > > ?http://www.concord.org/~sbannasch/mlvm/java-1.7.0-internal-2010_05_31.tar.gz > > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > From lukas.stadler at jku.at Wed Jun 2 09:14:14 2010 From: lukas.stadler at jku.at (lukas.stadler at jku.at) Date: Wed, 02 Jun 2010 16:14:14 +0000 Subject: hg: mlvm/mlvm/hotspot: added 64 bit support Message-ID: <20100602161414.D1CB446EC9@hg.openjdk.java.net> Changeset: 4c9c806f7fa2 Author: lstadler Date: 2010-06-02 18:12 +0200 URL: http://hg.openjdk.java.net/mlvm/mlvm/hotspot/rev/4c9c806f7fa2 added 64 bit support ! coro.patch ! series From lukas.stadler at jku.at Wed Jun 2 09:15:58 2010 From: lukas.stadler at jku.at (lukas.stadler at jku.at) Date: Wed, 02 Jun 2010 16:15:58 +0000 Subject: hg: mlvm/mlvm/jdk: added tests and CoroutineLocals Message-ID: <20100602161558.F24FE46ECA@hg.openjdk.java.net> Changeset: d1e4354e024a Author: lstadler Date: 2010-06-02 18:12 +0200 URL: http://hg.openjdk.java.net/mlvm/mlvm/jdk/rev/d1e4354e024a added tests and CoroutineLocals ! coro.patch ! series From stephen.bannasch at deanbrook.org Wed Jun 2 10:06:00 2010 From: stephen.bannasch at deanbrook.org (Stephen Bannasch) Date: Wed, 2 Jun 2010 13:06:00 -0400 Subject: hg: mlvm/mlvm/jdk: added tests and CoroutineLocals In-Reply-To: <20100602161558.F24FE46ECA@hg.openjdk.java.net> References: <20100602161558.F24FE46ECA@hg.openjdk.java.net> Message-ID: Hi Lukas, It's great to coro land. I'm now getting these errors trying to build coroutine.cpp on MacOS X 10.5.8: ./hotspot/src/share/vm/runtime/coroutine.cpp: In static member function 'static Coroutine* Coroutine::create_coroutine(JavaThread*, CoroutineStack*, oopDesc*)': ./hotspot/src/share/vm/runtime/coroutine.cpp:282: error: 'coroutine_start' was not declared in this scope ./hotspot/src/share/vm/runtime/coroutine.cpp: In member function 'bool Coroutine::is_disposable()': ./hotspot/src/share/vm/runtime/coroutine.cpp:347: error: 'coroutine_start' was not declared in this scope make[6]: *** [coroutine.o] Error 1 make[6]: *** Waiting for unfinished jobs.... make[5]: *** [the_vm] Error 2 make[4]: *** [fastdebug] Error 2 make[3]: *** [generic_build2] Error 2 make[2]: *** [fastdebug] Error 2 make[1]: *** [hotspot-build] Error 2 make: *** [build_product_image] Error 2 In the chance it might help debug the issue you can see the compiler invocation that generated this error here: http://gist.github.com/422670 ref: my build script: http://gist.github.com/243072 From john.r.rose at oracle.com Wed Jun 2 15:32:34 2010 From: john.r.rose at oracle.com (john.r.rose at oracle.com) Date: Wed, 02 Jun 2010 22:32:34 +0000 Subject: hg: mlvm/mlvm/jdk: meth-ldc: remove boolean argument from findGetter/findSetter (EG request); improve test coverage Message-ID: <20100602223234.CB51D46EE7@hg.openjdk.java.net> Changeset: 3253303243ca Author: jrose Date: 2010-06-02 15:32 -0700 URL: http://hg.openjdk.java.net/mlvm/mlvm/jdk/rev/3253303243ca meth-ldc: remove boolean argument from findGetter/findSetter (EG request); improve test coverage ! meth-ldc-6939203.patch From stephen.bannasch at deanbrook.org Wed Jun 2 18:55:04 2010 From: stephen.bannasch at deanbrook.org (Stephen Bannasch) Date: Wed, 2 Jun 2010 21:55:04 -0400 Subject: hg: mlvm/mlvm/jdk: added tests and CoroutineLocals In-Reply-To: References: <20100602161558.F24FE46ECA@hg.openjdk.java.net> Message-ID: At 1:06 PM -0400 6/2/10, Stephen Bannasch wrote: >Hi Lukas, > >It's great to see coro land. > >I'm now getting these errors trying to build coroutine.cpp on MacOS X 10.5.8: > >./hotspot/src/share/vm/runtime/coroutine.cpp: In static member function 'static Coroutine* >Coroutine::create_coroutine(JavaThread*, CoroutineStack*, oopDesc*)': >./hotspot/src/share/vm/runtime/coroutine.cpp:282: error: 'coroutine_start' was not declared in thisscope Taking a closer look the problem is obvious -- the method coroutine_start is only defined in two #ifdef blocks, one for WINDOWSand one for LINUX. I tried duplicating the Linux implementation wrapping it in #ifdef __APPLE__ but I got he following errors compiling hotspot/src/share/vm/runtime/signature.cpp: ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp: In function 'void create_switchTo_contents(MacroAssembler*, int, OopMapSet*, int&, int, BasicType*, VMRegPair*, BasicType, bool)': ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp:3446: error: call of overloaded 'movptr(Address, NULL)' is ambiguous ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2196: note: candidates are: void MacroAssembler::movptr(Address, intptr_t) ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2198: note: void MacroAssembler::movptr(Address, RegisterImpl*) ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp:3449: error: call of overloaded 'movptr(Address, NULL)' is ambiguous ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2196: note: candidates are: void MacroAssembler::movptr(Address, intptr_t) ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2198: note: void MacroAssembler::movptr(Address, RegisterImpl*) ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp:3491: error: call of overloaded 'movptr(Address, NULL)' is ambiguous ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2196: note: candidates are: void MacroAssembler::movptr(Address, intptr_t) ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2198: note: void MacroAssembler::movptr(Address, RegisterImpl*) ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp:3492: error: call of overloaded 'movptr(RegisterImpl* const&, int)' is ambiguous ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2194: note: candidates are: void MacroAssembler::movptr(RegisterImpl*, intptr_t) ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2195: note: void MacroAssembler::movptr(RegisterImpl*, RegisterImpl*) ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2200: note: void MacroAssembler::movptr(RegisterImpl*, RegisterOrConstant) make[6]: *** [sharedRuntime_x86_32.o] Error 1 From bodden at st.informatik.tu-darmstadt.de Fri Jun 4 01:43:19 2010 From: bodden at st.informatik.tu-darmstadt.de (Eric Bodden) Date: Fri, 4 Jun 2010 10:43:19 +0200 Subject: Invokedynamic slower than reflection? Message-ID: Hi all. I did some simple micro-benchmarking with the current implementation of invokedynamic. In the attached test class, I call a method "greeter" 100,000,000 times using invokedynamic and then using reflection. Reflection only takes about 1338ms, while invokedynamic takes about 12099. (This was taken on OSX 10.6, with build "1.7.0-internal-stephen_2010_05_28_19_48-b00"). By the way invokedynamic works, I had expected it to be at least as fast as a reflective call. Can you tell me if this kind of performance is expected in general? Best wishes, Eric -- Dr. Eric Bodden Software Technology Group, Technische Universit?t Darmstadt, Germany Tel: +49 6151 16-5478 Fax: +49 6151 16-5410 Mailing Address: S2|02 A209, Hochschulstra?e 10, 64289 Darmstadt -------------- next part -------------- A non-text attachment was scrubbed... Name: Hello.java Type: application/octet-stream Size: 2256 bytes Desc: not available Url : http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20100604/140dbda0/attachment.obj From forax at univ-mlv.fr Fri Jun 4 04:40:11 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Fri, 04 Jun 2010 13:40:11 +0200 Subject: Invokedynamic slower than reflection? In-Reply-To: References: Message-ID: <4C08E61B.7060604@univ-mlv.fr> It's funny, I've found the same error last night. Yes, there is a problem, if you run with -XX:+PrintCompilation, you will see lot of "made not entrant" on the same bytecode location. 183% made not entrant (2) Hello::main @ -2 (145 bytes) 184% Hello::main @ 6 (145 bytes) It seems that invokedynamic have trouble and cycle between optimization and deoptimization phases. R?mi Le 04/06/2010 10:43, Eric Bodden a ?crit : > Hi all. > > I did some simple micro-benchmarking with the current implementation > of invokedynamic. In the attached test class, I call a method > "greeter" 100,000,000 times using invokedynamic and then using > reflection. Reflection only takes about 1338ms, while invokedynamic > takes about 12099. (This was taken on OSX 10.6, with build > "1.7.0-internal-stephen_2010_05_28_19_48-b00"). By the way > invokedynamic works, I had expected it to be at least as fast as a > reflective call. > > Can you tell me if this kind of performance is expected in general? > > Best wishes, > Eric > > -- > Dr. Eric Bodden > Software Technology Group, Technische Universit?t Darmstadt, Germany > Tel: +49 6151 16-5478 Fax: +49 6151 16-5410 > Mailing Address: S2|02 A209, Hochschulstra?e 10, 64289 Darmstadt > > > > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20100604/b487a02a/attachment.html From john.r.rose at oracle.com Fri Jun 4 17:01:43 2010 From: john.r.rose at oracle.com (John Rose) Date: Fri, 4 Jun 2010 17:01:43 -0700 Subject: Invokedynamic slower than reflection? In-Reply-To: <4C08E61B.7060604@univ-mlv.fr> References: <4C08E61B.7060604@univ-mlv.fr> Message-ID: <77A79EFE-4D5F-44A2-A170-03AD125CA40C@oracle.com> Is the call site megamutable? (Is it linked many times instead of once?) -- John On Jun 4, 2010, at 4:40 AM, R?mi Forax wrote: > It's funny, I've found the same error last night. > > Yes, there is a problem, > if you run with -XX:+PrintCompilation, you will see > lot of "made not entrant" on the same bytecode location. > > 183% made not entrant (2) Hello::main @ -2 (145 bytes) > 184% Hello::main @ 6 (145 bytes) > > It seems that invokedynamic have trouble and > cycle between optimization and deoptimization phases. > > R?mi > > Le 04/06/2010 10:43, Eric Bodden a ?crit : >> Hi all. >> >> I did some simple micro-benchmarking with the current implementation >> of invokedynamic. In the attached test class, I call a method >> "greeter" 100,000,000 times using invokedynamic and then using >> reflection. Reflection only takes about 1338ms, while invokedynamic >> takes about 12099. (This was taken on OSX 10.6, with build >> "1.7.0-internal-stephen_2010_05_28_19_48-b00"). By the way >> invokedynamic works, I had expected it to be at least as fast as a >> reflective call. >> >> Can you tell me if this kind of performance is expected in general? >> >> Best wishes, >> Eric >> >> -- >> Dr. Eric Bodden >> Software Technology Group, Technische Universit?t Darmstadt, Germany >> Tel: +49 6151 16-5478 Fax: +49 6151 16-5410 >> Mailing Address: S2|02 A209, Hochschulstra?e 10, 64289 Darmstadt >> >> >> >> _______________________________________________ >> mlvm-dev mailing list >> >> mlvm-dev at openjdk.java.net >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >> >> >> > > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev From forax at univ-mlv.fr Sat Jun 5 10:58:11 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 05 Jun 2010 19:58:11 +0200 Subject: Invokedynamic slower than reflection? In-Reply-To: <77A79EFE-4D5F-44A2-A170-03AD125CA40C@oracle.com> References: <4C08E61B.7060604@univ-mlv.fr> <77A79EFE-4D5F-44A2-A170-03AD125CA40C@oracle.com> Message-ID: <4C0A9033.4010900@univ-mlv.fr> Le 05/06/2010 02:01, John Rose a ?crit : > Is the call site megamutable? (Is it linked many times instead of once?) -- John > no ! The callsite is linked only once. R?mi > On Jun 4, 2010, at 4:40 AM, R?mi Forax wrote: > > >> It's funny, I've found the same error last night. >> >> Yes, there is a problem, >> if you run with -XX:+PrintCompilation, you will see >> lot of "made not entrant" on the same bytecode location. >> >> 183% made not entrant (2) Hello::main @ -2 (145 bytes) >> 184% Hello::main @ 6 (145 bytes) >> >> It seems that invokedynamic have trouble and >> cycle between optimization and deoptimization phases. >> >> R?mi >> >> Le 04/06/2010 10:43, Eric Bodden a ?crit : >> >>> Hi all. >>> >>> I did some simple micro-benchmarking with the current implementation >>> of invokedynamic. In the attached test class, I call a method >>> "greeter" 100,000,000 times using invokedynamic and then using >>> reflection. Reflection only takes about 1338ms, while invokedynamic >>> takes about 12099. (This was taken on OSX 10.6, with build >>> "1.7.0-internal-stephen_2010_05_28_19_48-b00"). By the way >>> invokedynamic works, I had expected it to be at least as fast as a >>> reflective call. >>> >>> Can you tell me if this kind of performance is expected in general? >>> >>> Best wishes, >>> Eric >>> >>> -- >>> Dr. Eric Bodden >>> Software Technology Group, Technische Universit?t Darmstadt, Germany >>> Tel: +49 6151 16-5478 Fax: +49 6151 16-5410 >>> Mailing Address: S2|02 A209, Hochschulstra?e 10, 64289 Darmstadt >>> >>> >>> >>> _______________________________________________ >>> mlvm-dev mailing list >>> >>> mlvm-dev at openjdk.java.net >>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >>> >>> >>> >>> >> _______________________________________________ >> mlvm-dev mailing list >> mlvm-dev at openjdk.java.net >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >> > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > From Christian.Thalinger at Sun.COM Mon Jun 7 02:24:48 2010 From: Christian.Thalinger at Sun.COM (Christian Thalinger) Date: Mon, 07 Jun 2010 11:24:48 +0200 Subject: Invokedynamic slower than reflection? In-Reply-To: <4C0A9033.4010900@univ-mlv.fr> References: <4C08E61B.7060604@univ-mlv.fr> <77A79EFE-4D5F-44A2-A170-03AD125CA40C@oracle.com> <4C0A9033.4010900@univ-mlv.fr> Message-ID: <1275902688.1455.2.camel@macbook> On Sat, 2010-06-05 at 19:58 +0200, R?mi Forax wrote: > Le 05/06/2010 02:01, John Rose a ?crit : > > Is the call site megamutable? (Is it linked many times instead of once?) -- John > > > > no ! > The callsite is linked only once. Yeah, that bug is around since: 6939134: JSR 292 adjustments to method handle invocation 6939196: method handle signatures off the boot class path get linkage errors Not sure which one of these two actually breaks it. -- Christian From lukas.stadler at jku.at Mon Jun 7 10:17:51 2010 From: lukas.stadler at jku.at (Lukas Stadler) Date: Mon, 07 Jun 2010 19:17:51 +0200 Subject: hg: mlvm/mlvm/jdk: added tests and CoroutineLocals In-Reply-To: References: <20100602161558.F24FE46ECA@hg.openjdk.java.net> Message-ID: <4C0D29BF.90402@jku.at> Well, I finally got my hands on a Mac machine, I'll investigate as soon as I've finished installing. - Lukas On 03.06.2010 03:55, Stephen Bannasch wrote: > At 1:06 PM -0400 6/2/10, Stephen Bannasch wrote: > >> Hi Lukas, >> >> It's great to see coro land. >> >> I'm now getting these errors trying to build coroutine.cpp on MacOS X 10.5.8: >> >> ./hotspot/src/share/vm/runtime/coroutine.cpp: In static member function 'static Coroutine* >> Coroutine::create_coroutine(JavaThread*, CoroutineStack*, oopDesc*)': >> ./hotspot/src/share/vm/runtime/coroutine.cpp:282: error: 'coroutine_start' was not declared in thisscope >> > Taking a closer look the problem is obvious -- the method coroutine_start is only defined in two #ifdef blocks, one for WINDOWSand one for LINUX. > > I tried duplicating the Linux implementation wrapping it in #ifdef __APPLE__ > > but I got he following errors compiling hotspot/src/share/vm/runtime/signature.cpp: > > ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp: In function 'void create_switchTo_contents(MacroAssembler*, int, OopMapSet*, int&, int, BasicType*, VMRegPair*, BasicType, bool)': > ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp:3446: error: call of overloaded 'movptr(Address, NULL)' is ambiguous > ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2196: note: candidates are: void MacroAssembler::movptr(Address, intptr_t) > ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2198: note: void MacroAssembler::movptr(Address, RegisterImpl*) > ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp:3449: error: call of overloaded 'movptr(Address, NULL)' is ambiguous > ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2196: note: candidates are: void MacroAssembler::movptr(Address, intptr_t) > ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2198: note: void MacroAssembler::movptr(Address, RegisterImpl*) > ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp:3491: error: call of overloaded 'movptr(Address, NULL)' is ambiguous > ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2196: note: candidates are: void MacroAssembler::movptr(Address, intptr_t) > ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2198: note: void MacroAssembler::movptr(Address, RegisterImpl*) > ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp:3492: error: call of overloaded 'movptr(RegisterImpl* const&, int)' is ambiguous > ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2194: note: candidates are: void MacroAssembler::movptr(RegisterImpl*, intptr_t) > ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2195: note: void MacroAssembler::movptr(RegisterImpl*, RegisterImpl*) > ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2200: note: void MacroAssembler::movptr(RegisterImpl*, RegisterOrConstant) > make[6]: *** [sharedRuntime_x86_32.o] Error 1 > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > From headius at headius.com Mon Jun 7 11:23:45 2010 From: headius at headius.com (Charles Oliver Nutter) Date: Mon, 7 Jun 2010 18:23:45 +0000 Subject: hg: mlvm/mlvm/jdk: added tests and CoroutineLocals In-Reply-To: <4C0D29BF.90402@jku.at> References: <20100602161558.F24FE46ECA@hg.openjdk.java.net> <4C0D29BF.90402@jku.at> Message-ID: Exciting :) Once you get it in, perhaps you can release the changes you made to JRuby. I have no problem shipping a reflectively-loaded version of Fiber that uses JVM coroutines! (and I'd like to do the same for 1.8 mode Enumerator, which also requires coroutine support) On Mon, Jun 7, 2010 at 5:17 PM, Lukas Stadler wrote: > Well, I finally got my hands on a Mac machine, I'll investigate as soon > as I've finished installing. > > - Lukas > > On 03.06.2010 03:55, Stephen Bannasch wrote: >> At 1:06 PM -0400 6/2/10, Stephen Bannasch wrote: >> >>> Hi Lukas, >>> >>> It's great to see coro land. >>> >>> I'm now getting these errors trying to build coroutine.cpp on MacOS X 10.5.8: >>> >>> ./hotspot/src/share/vm/runtime/coroutine.cpp: In static member function 'static Coroutine* >>> Coroutine::create_coroutine(JavaThread*, CoroutineStack*, oopDesc*)': >>> ./hotspot/src/share/vm/runtime/coroutine.cpp:282: error: 'coroutine_start' was not declared in thisscope >>> >> Taking a closer look the problem is obvious -- the method coroutine_start is only defined in two #ifdef blocks, one for WINDOWSand one for LINUX. >> >> I tried duplicating the Linux implementation wrapping it in #ifdef __APPLE__ >> >> but I got he following errors compiling hotspot/src/share/vm/runtime/signature.cpp: >> >> ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp: In function 'void create_switchTo_contents(MacroAssembler*, int, OopMapSet*, int&, int, BasicType*, VMRegPair*, BasicType, bool)': >> ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp:3446: error: call of overloaded 'movptr(Address, NULL)' is ambiguous >> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2196: note: candidates are: void MacroAssembler::movptr(Address, intptr_t) >> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2198: note: ? ? ? ? ? ? ? ? void MacroAssembler::movptr(Address, RegisterImpl*) >> ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp:3449: error: call of overloaded 'movptr(Address, NULL)' is ambiguous >> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2196: note: candidates are: void MacroAssembler::movptr(Address, intptr_t) >> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2198: note: ? ? ? ? ? ? ? ? void MacroAssembler::movptr(Address, RegisterImpl*) >> ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp:3491: error: call of overloaded 'movptr(Address, NULL)' is ambiguous >> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2196: note: candidates are: void MacroAssembler::movptr(Address, intptr_t) >> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2198: note: ? ? ? ? ? ? ? ? void MacroAssembler::movptr(Address, RegisterImpl*) >> ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp:3492: error: call of overloaded 'movptr(RegisterImpl* const&, int)' is ambiguous >> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2194: note: candidates are: void MacroAssembler::movptr(RegisterImpl*, intptr_t) >> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2195: note: ? ? ? ? ? ? ? ? void MacroAssembler::movptr(RegisterImpl*, RegisterImpl*) >> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2200: note: ? ? ? ? ? ? ? ? void MacroAssembler::movptr(RegisterImpl*, RegisterOrConstant) >> make[6]: *** [sharedRuntime_x86_32.o] Error 1 >> _______________________________________________ >> mlvm-dev mailing list >> mlvm-dev at openjdk.java.net >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >> > > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > From forax at univ-mlv.fr Mon Jun 7 14:03:43 2010 From: forax at univ-mlv.fr (=?UTF-8?B?UsOpbWkgRm9yYXg=?=) Date: Mon, 07 Jun 2010 23:03:43 +0200 Subject: hg: mlvm/mlvm/jdk: added tests and CoroutineLocals In-Reply-To: References: <20100602161558.F24FE46ECA@hg.openjdk.java.net> <4C0D29BF.90402@jku.at> Message-ID: <4C0D5EAF.5030205@univ-mlv.fr> Le 07/06/2010 20:23, Charles Oliver Nutter a ?crit : > Exciting :) Once you get it in, perhaps you can release the changes > you made to JRuby. I have no problem shipping a reflectively-loaded > version of Fiber that uses JVM coroutines! (and I'd like to do the > same for 1.8 mode Enumerator, which also requires coroutine support) > It remember something. I wonder if we can try to release a binary version of the DaVinci VM, let say 2 weeks before the JVM Summit. The idea is to coordinate our schedules to produce a set of patches applicable on the same VM version. If we got that I will be able (and I think I won't be the only one) to produce a runtime that use the corresponding features on non trivial examples. I've done that for the FOSDEM last February but I was not able to have all patches working for c1 and c2 on Linux. My idea is to do a binary release with at least indy, coroutine, tail calls on Mac, Linux, Solaris and Windows. What do you think ? R?mi > On Mon, Jun 7, 2010 at 5:17 PM, Lukas Stadler wrote: > >> Well, I finally got my hands on a Mac machine, I'll investigate as soon >> as I've finished installing. >> >> - Lukas >> >> On 03.06.2010 03:55, Stephen Bannasch wrote: >> >>> At 1:06 PM -0400 6/2/10, Stephen Bannasch wrote: >>> >>> >>>> Hi Lukas, >>>> >>>> It's great to see coro land. >>>> >>>> I'm now getting these errors trying to build coroutine.cpp on MacOS X 10.5.8: >>>> >>>> ./hotspot/src/share/vm/runtime/coroutine.cpp: In static member function 'static Coroutine* >>>> Coroutine::create_coroutine(JavaThread*, CoroutineStack*, oopDesc*)': >>>> ./hotspot/src/share/vm/runtime/coroutine.cpp:282: error: 'coroutine_start' was not declared in thisscope >>>> >>>> >>> Taking a closer look the problem is obvious -- the method coroutine_start is only defined in two #ifdef blocks, one for WINDOWSand one for LINUX. >>> >>> I tried duplicating the Linux implementation wrapping it in #ifdef __APPLE__ >>> >>> but I got he following errors compiling hotspot/src/share/vm/runtime/signature.cpp: >>> >>> ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp: In function 'void create_switchTo_contents(MacroAssembler*, int, OopMapSet*, int&, int, BasicType*, VMRegPair*, BasicType, bool)': >>> ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp:3446: error: call of overloaded 'movptr(Address, NULL)' is ambiguous >>> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2196: note: candidates are: void MacroAssembler::movptr(Address, intptr_t) >>> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2198: note: void MacroAssembler::movptr(Address, RegisterImpl*) >>> ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp:3449: error: call of overloaded 'movptr(Address, NULL)' is ambiguous >>> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2196: note: candidates are: void MacroAssembler::movptr(Address, intptr_t) >>> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2198: note: void MacroAssembler::movptr(Address, RegisterImpl*) >>> ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp:3491: error: call of overloaded 'movptr(Address, NULL)' is ambiguous >>> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2196: note: candidates are: void MacroAssembler::movptr(Address, intptr_t) >>> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2198: note: void MacroAssembler::movptr(Address, RegisterImpl*) >>> ./hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp:3492: error: call of overloaded 'movptr(RegisterImpl* const&, int)' is ambiguous >>> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2194: note: candidates are: void MacroAssembler::movptr(RegisterImpl*, intptr_t) >>> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2195: note: void MacroAssembler::movptr(RegisterImpl*, RegisterImpl*) >>> ./hotspot/src/cpu/x86/vm/assembler_x86.hpp:2200: note: void MacroAssembler::movptr(RegisterImpl*, RegisterOrConstant) >>> make[6]: *** [sharedRuntime_x86_32.o] Error 1 >>> _______________________________________________ >>> mlvm-dev mailing list >>> mlvm-dev at openjdk.java.net >>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >>> >>> >> _______________________________________________ >> mlvm-dev mailing list >> mlvm-dev at openjdk.java.net >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >> >> > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > From headius at headius.com Mon Jun 7 14:10:27 2010 From: headius at headius.com (Charles Oliver Nutter) Date: Mon, 7 Jun 2010 21:10:27 +0000 Subject: hg: mlvm/mlvm/jdk: added tests and CoroutineLocals In-Reply-To: <4C0D5EAF.5030205@univ-mlv.fr> References: <20100602161558.F24FE46ECA@hg.openjdk.java.net> <4C0D29BF.90402@jku.at> <4C0D5EAF.5030205@univ-mlv.fr> Message-ID: On Mon, Jun 7, 2010 at 9:03 PM, R?mi Forax wrote: > My idea is to do a binary release with at least indy, coroutine, tail calls > on Mac, Linux, Solaris and Windows. > > What do you think ? That would be fantastic. It's unfortunate that neither coro or tailc will get into Java 7, but for ambitious souls who want to use them it would be nice to get the whole bunch working together. - Charlie From lukas.stadler at jku.at Tue Jun 8 05:25:29 2010 From: lukas.stadler at jku.at (lukas.stadler at jku.at) Date: Tue, 08 Jun 2010 12:25:29 +0000 Subject: hg: mlvm/mlvm/hotspot: BSD support Message-ID: <20100608122529.807B647046@hg.openjdk.java.net> Changeset: 21e6fa0e8bea Author: lstadler Date: 2010-06-08 14:21 +0200 URL: http://hg.openjdk.java.net/mlvm/mlvm/hotspot/rev/21e6fa0e8bea BSD support ! coro.patch From lukas.stadler at jku.at Tue Jun 8 05:36:44 2010 From: lukas.stadler at jku.at (Lukas Stadler) Date: Tue, 08 Jun 2010 14:36:44 +0200 Subject: hg: mlvm/mlvm/jdk: added tests and CoroutineLocals In-Reply-To: <4C0D29BF.90402@jku.at> References: <20100602161558.F24FE46ECA@hg.openjdk.java.net> <4C0D29BF.90402@jku.at> Message-ID: <4C0E395C.20700@jku.at> I had to change a few bits here and there, and it now works on my Mac (at least in 32 bit). Charlie: cleaning up the JRuby code and sending it to you is now officially the next thing on my list... - Lukas On 07.06.2010 19:17, Lukas Stadler wrote: > Well, I finally got my hands on a Mac machine, I'll investigate as soon > as I've finished installing. > > - Lukas > > On 03.06.2010 03:55, Stephen Bannasch wrote: > >> At 1:06 PM -0400 6/2/10, Stephen Bannasch wrote: >> >> >>> Hi Lukas, >>> >>> It's great to see coro land. >>> >>> I'm now getting these errors trying to build coroutine.cpp on MacOS X 10.5.8: >>> >>> ./hotspot/src/share/vm/runtime/coroutine.cpp: In static member function 'static Coroutine* >>> Coroutine::create_coroutine(JavaThread*, CoroutineStack*, oopDesc*)': >>> ./hotspot/src/share/vm/runtime/coroutine.cpp:282: error: 'coroutine_start' was not declared in thisscope >>> >>> >> Taking a closer look the problem is obvious -- the method coroutine_start is only defined in two #ifdef blocks, one for WINDOWSand one for LINUX. >> >> From lukas.stadler at jku.at Tue Jun 8 05:30:14 2010 From: lukas.stadler at jku.at (lukas.stadler at jku.at) Date: Tue, 08 Jun 2010 12:30:14 +0000 Subject: hg: mlvm/mlvm/jdk: 2 new changesets Message-ID: <20100608123014.69ACE47047@hg.openjdk.java.net> Changeset: ce987dd2dfd3 Author: lstadler Date: 2010-06-08 14:22 +0200 URL: http://hg.openjdk.java.net/mlvm/mlvm/jdk/rev/ce987dd2dfd3 fixed missing class ! coro.patch Changeset: 3a9c60819392 Author: lstadler Date: 2010-06-08 14:27 +0200 URL: http://hg.openjdk.java.net/mlvm/mlvm/jdk/rev/3a9c60819392 merge From headius at headius.com Tue Jun 8 06:23:14 2010 From: headius at headius.com (Charles Oliver Nutter) Date: Tue, 8 Jun 2010 13:23:14 +0000 Subject: hg: mlvm/mlvm/jdk: added tests and CoroutineLocals In-Reply-To: <4C0E395C.20700@jku.at> References: <20100602161558.F24FE46ECA@hg.openjdk.java.net> <4C0D29BF.90402@jku.at> <4C0E395C.20700@jku.at> Message-ID: Excellent! And I promise something will land on JRuby master soon after :) - Charlie (from mobile) On Jun 8, 2010 8:37 AM, "Lukas Stadler" wrote: > I had to change a few bits here and there, and it now works on my Mac > (at least in 32 bit). > Charlie: cleaning up the JRuby code and sending it to you is now > officially the next thing on my list... > > - Lukas > > On 07.06.2010 19:17, Lukas Stadler wrote: >> Well, I finally got my hands on a Mac machine, I'll investigate as soon >> as I've finished installing. >> >> - Lukas >> >> On 03.06.2010 03:55, Stephen Bannasch wrote: >> >>> At 1:06 PM -0400 6/2/10, Stephen Bannasch wrote: >>> >>> >>>> Hi Lukas, >>>> >>>> It's great to see coro land. >>>> >>>> I'm now getting these errors trying to build coroutine.cpp on MacOS X 10.5.8: >>>> >>>> ./hotspot/src/share/vm/runtime/coroutine.cpp: In static member function 'static Coroutine* >>>> Coroutine::create_coroutine(JavaThread*, CoroutineStack*, oopDesc*)': >>>> ./hotspot/src/share/vm/runtime/coroutine.cpp:282: error: 'coroutine_start' was not declared in thisscope >>>> >>>> >>> Taking a closer look the problem is obvious -- the method coroutine_start is only defined in two #ifdef blocks, one for WINDOWSand one for LINUX. >>> >>> > > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20100608/b5bfa07f/attachment.html From stephen.bannasch at deanbrook.org Tue Jun 8 17:10:48 2010 From: stephen.bannasch at deanbrook.org (Stephen Bannasch) Date: Tue, 8 Jun 2010 20:10:48 -0400 Subject: hg: mlvm/mlvm/jdk: added tests and CoroutineLocals In-Reply-To: <4C0E395C.20700@jku.at> References: <20100602161558.F24FE46ECA@hg.openjdk.java.net> <4C0D29BF.90402@jku.at> <4C0E395C.20700@jku.at> Message-ID: At 2:36 PM +0200 6/8/10, Lukas Stadler wrote: >I had to change a few bits here and there, and it now works on my Mac >(at least in 32 bit). It compiles cleanly on my 64-bit Mac (Intel Core 2 Duo, 10.5.8). How do I run the coroutine tests? Updated build here for Charlie: http://www.concord.org/~sbannasch/mlvm/java-1.7.0-internal-2010_06_08.tar.gz From headius at headius.com Tue Jun 8 19:04:59 2010 From: headius at headius.com (Charles Oliver Nutter) Date: Tue, 8 Jun 2010 22:04:59 -0400 Subject: hg: mlvm/mlvm/jdk: added tests and CoroutineLocals In-Reply-To: References: <20100602161558.F24FE46ECA@hg.openjdk.java.net> <4C0D29BF.90402@jku.at> <4C0E395C.20700@jku.at> Message-ID: Oh man, now I need Lukas's patch and I can wow the whole Ruby world :) Lukas: Don't worry if it's ugly, I can clean it up :) On Tue, Jun 8, 2010 at 8:10 PM, Stephen Bannasch wrote: > At 2:36 PM +0200 6/8/10, Lukas Stadler wrote: >>I had to change a few bits here and there, and it now works on my Mac >>(at least in 32 bit). > > It compiles cleanly on my 64-bit Mac (Intel Core 2 Duo, 10.5.8). > > How do I run the coroutine tests? > > Updated build here for Charlie: > > ?http://www.concord.org/~sbannasch/mlvm/java-1.7.0-internal-2010_06_08.tar.gz > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > From john.r.rose at oracle.com Wed Jun 9 01:05:26 2010 From: john.r.rose at oracle.com (john.r.rose at oracle.com) Date: Wed, 09 Jun 2010 08:05:26 +0000 Subject: hg: mlvm/mlvm/hotspot: meth-ldc: fixes from code review, including SA and compiler support Message-ID: <20100609080526.D5B9B47081@hg.openjdk.java.net> Changeset: ae441dcef1fb Author: jrose Date: 2010-06-09 01:02 -0700 URL: http://hg.openjdk.java.net/mlvm/mlvm/hotspot/rev/ae441dcef1fb meth-ldc: fixes from code review, including SA and compiler support ! meth-ldc-6939203.patch From john.r.rose at oracle.com Wed Jun 9 20:41:43 2010 From: john.r.rose at oracle.com (john.r.rose at oracle.com) Date: Thu, 10 Jun 2010 03:41:43 +0000 Subject: hg: mlvm/mlvm/hotspot: meth-ldc: SA code is tested on indy and ldc/MH examples (jdis, dumpclass commands) Message-ID: <20100610034144.2C8F9470C5@hg.openjdk.java.net> Changeset: 4b05de31c666 Author: jrose Date: 2010-06-09 20:38 -0700 URL: http://hg.openjdk.java.net/mlvm/mlvm/hotspot/rev/4b05de31c666 meth-ldc: SA code is tested on indy and ldc/MH examples (jdis, dumpclass commands) ! meth-ldc-6939203.patch From howard.lovatt at gmail.com Sat Jun 12 01:03:29 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Sat, 12 Jun 2010 18:03:29 +1000 Subject: Bootstrap method question Message-ID: This is probably my mistake, but I thought it worth checking anyway! I am playing around with multiple dispatch in the MLVM, in particular. public class Cost { /* Written by PEC! */ static { final MethodHandle bootstrap = MethodHandles.lookup().findStatic( CostCalculatorDispatcher.class, "cost", Dispatchers.bootstrapType ); Linkage.registerBootstrapMethod( Cost.class, bootstrap ); } public static void main( final String[] notUsed ) { final List shoppingCart = new ArrayList(); shoppingCart.add( new Book( 20, 0.5 ) ); shoppingCart.add( new CD( 25 ) ); System.out.println( "cost = " + cost( shoppingCart ) ); } public static double cost( final List shoppingCart ) { final CostCalculator price = new Price(); final CostCalculator postage = new Postage(); double cost = 0; for ( final Item item : shoppingCart ) { try { /* Written by PEC! */ cost += InvokeDynamic.cost( price, item ); } catch ( Throwable e ) { throw new MultipleDispatchException( e ); } try { /* Written by PEC! */ cost += InvokeDynamic.cost( postage, item ); } catch ( Throwable e ) { throw new MultipleDispatchException( e ); } } return cost; } } The bootstrap method gets called, but its type argument is: (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double IE the static types, I was expecting the dynamic types: (invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.Book)double etc. What am I doing wrong? -- Howard. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20100612/6126bcb1/attachment.html From forax at univ-mlv.fr Sat Jun 12 05:09:48 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 12 Jun 2010 14:09:48 +0200 Subject: Bootstrap method question In-Reply-To: References: Message-ID: <4C13790C.9010400@univ-mlv.fr> Le 12/06/2010 10:03, Howard Lovatt a ?crit : > This is probably my mistake, but I thought it worth checking anyway! > > I am playing around with multiple dispatch in the MLVM, in particular. > > public class Cost { > /* Written by PEC! */ static { > final MethodHandle bootstrap = MethodHandles.lookup().findStatic( > CostCalculatorDispatcher.class, > > "cost", > > Dispatchers.bootstrapType ); > Linkage.registerBootstrapMethod( Cost.class, bootstrap ); > } > > public static void main( final String[] notUsed ) { > final List shoppingCart = new ArrayList(); > shoppingCart.add( new Book( 20, 0.5 ) ); > shoppingCart.add( new CD( 25 ) ); > System.out.println( "cost = " + cost( shoppingCart ) ); > } > > public static double cost( final List shoppingCart ) { > final CostCalculator price = new Price(); > final CostCalculator postage = new Postage(); > double cost = 0; > for ( final Item item : shoppingCart ) { > try { /* Written by PEC! */ > cost += InvokeDynamic.cost( price, item ); > } catch ( Throwable e ) { > throw new MultipleDispatchException( e ); > } > try { /* Written by PEC! */ > cost += InvokeDynamic.cost( postage, item ); > } catch ( Throwable e ) { > throw new MultipleDispatchException( e ); > } > } > return cost; > } > } > > The bootstrap method gets called, but its type argument is: > > (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double > > IE the static types, I was expecting the dynamic types: > > (invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.Book)double > etc. > > What am I doing wrong? Hi Howard, the bootstrap method is called when the VM need an implementation. Because some VMs has no interpreter, JikesRVM or JRockit by example, this linking can be done before the evaluation of the calling arguments. So if you want to have access to the actual classes of the calling arguments, the bootstrap method must register a method handle to collect them. Here is a skeleton of how it should work : public class RT { public static CallSite bootstrap(Class declaringClass, String name, MethodType methodType) { CallSite callSite = new CallSite(); MethodHandle target = MethodHandles.insertArguments(slowPath, 0, callSite); target = MethodHandles.collectArguments(target, methodType); callSite.setTarget(target); return callSite; } private static final MethodHandle slowPath = RT#slowPath(ClassSite,Object[]); public Object slowPath(CallSite callsite, Object[] args) { // find the target method handle depending of the classes of arguments MethodHandle specific = ... // create a test for those classes MethodHandle test = ... MethodHandle guard = MethodHandles.guardWithTest(test, specific, callSite.getTarget()); callSite.setTarget(guard); return specific.invokeVarargs(args); } } The idea is to first register a generic method that will be called with an array of all arguments, I've named it slowPath. slowPath is also the name of the corresponding method handle (created with using a ldc, the syntax with a sharp in the middle). In the bootstrap method, I use adapters to adapt the generic method to the signature of the callsite, with collectArguments. I also 'specialize' the slowpath with the callsite to be able to change the callsite target later. So slowpath will be called with an array of arguments, here you have to find the most specific method depending on the argument classes. You have also to create a test method that will returns true if the arguments classes doesn't change. This part is not mandatory but allow to avoid to do the lookup each time. After I create a guard that says, if the test is true called the specific method otherwise, called the last target (which can be the slowpath or a guard with a test and an older target). So I create a tree of guard that ends with an adapter to the slowpath. At the end, I need to find the result of the call and use invokeVarargs which will call the method handle using the array values as calling arguments. > > > -- Howard. R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20100612/34673e1b/attachment.html From headius at headius.com Mon Jun 14 07:38:18 2010 From: headius at headius.com (Charles Oliver Nutter) Date: Mon, 14 Jun 2010 14:38:18 +0000 Subject: hg: mlvm/mlvm/jdk: added tests and CoroutineLocals In-Reply-To: References: <20100602161558.F24FE46ECA@hg.openjdk.java.net> <4C0D29BF.90402@jku.at> <4C0E395C.20700@jku.at> Message-ID: I managed to get a simple patch written to partially convert Ruby's Enumerator#next (a cursor over arbitrarily-complex iteration logic; implemented with Threads in standard JRuby) to use coro with the help of Stephen's build. It seems to work very well, even though I don't have all the appropriate logic here (like raising an error on end-of-iteration calls to next). Here's the numbers for it compared to Ruby 1.9 (Ruby 1.8 uses substantially slower logic for this...orders of magnitude slower than either JRuby or Ruby 1.9): # JRuby with threaded enumerator ~/projects/jruby ? ../jruby-1.4.0/bin/jruby -e "5.times { ary = (1..1_000_000).to_a.to_enum; t = Time.now; 1_000_000.times { ary.next }; puts Time.now - t }" 2.815 2.326 2.195 3.119 2.999 # Ruby 1.9.2, recent build ~/projects/jruby ? ruby1.9 -e "5.times { ary = (1..1_000_000).to_a.to_enum; t = Time.now; 1_000_000.times { ary.next }; puts Time.now - t }"1.63799 1.61982 1.622199 1.61865 1.634846 # JRuby with native coroutines in JVM ~/projects/jruby ? jruby -e "5.times { ary = (1..1_000_000).to_a.to_enum; t = Time.now; 1_000_000.times { ary.next }; puts Time.now - t }" 0.506 0.342 0.176 0.178 0.18 I've also done some runs logging the final result, and it is indeed iterating. There have been a few glitches though. * if I add "p n if n % 100_000 == 0" to the loop, it appears to crash. I can provide the crash artifacts if you like. * If the coroutine is never explicitly terminated it seems to delay shutting down the JVM. In this naive implementation the final element "eached" over will get ret'ed from the coroutine, pausing the each loop one last time. Until the last + 1 call to next, it will not know the iteration has walked all elements and will not exit. This seems to delay JVM shutdown. All told it was almost scary how easy it was to get this to work, even if my patch is fairly primitive. I've provided it here: http://gist.github.com/437762 - Charlie On Wed, Jun 9, 2010 at 2:04 AM, Charles Oliver Nutter wrote: > Oh man, now I need Lukas's patch and I can wow the whole Ruby world :) > > Lukas: Don't worry if it's ugly, I can clean it up :) > > On Tue, Jun 8, 2010 at 8:10 PM, Stephen Bannasch > wrote: >> At 2:36 PM +0200 6/8/10, Lukas Stadler wrote: >>>I had to change a few bits here and there, and it now works on my Mac >>>(at least in 32 bit). >> >> It compiles cleanly on my 64-bit Mac (Intel Core 2 Duo, 10.5.8). >> >> How do I run the coroutine tests? >> >> Updated build here for Charlie: >> >> ?http://www.concord.org/~sbannasch/mlvm/java-1.7.0-internal-2010_06_08.tar.gz >> _______________________________________________ >> mlvm-dev mailing list >> mlvm-dev at openjdk.java.net >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >> > From lukas.stadler at jku.at Tue Jun 15 06:37:15 2010 From: lukas.stadler at jku.at (lukas.stadler at jku.at) Date: Tue, 15 Jun 2010 13:37:15 +0000 Subject: hg: mlvm/mlvm/jdk: added yieldTo method Message-ID: <20100615133715.C6CBD47259@hg.openjdk.java.net> Changeset: 103d9a6b740e Author: lstadler Date: 2010-06-15 15:36 +0200 URL: http://hg.openjdk.java.net/mlvm/mlvm/jdk/rev/103d9a6b740e added yieldTo method ! coro.patch From stephen.bannasch at deanbrook.org Tue Jun 15 08:33:29 2010 From: stephen.bannasch at deanbrook.org (Stephen Bannasch) Date: Tue, 15 Jun 2010 11:33:29 -0400 Subject: hg: mlvm/mlvm/jdk: added yieldTo method In-Reply-To: <20100615133715.C6CBD47259@hg.openjdk.java.net> References: <20100615133715.C6CBD47259@hg.openjdk.java.net> Message-ID: At 1:37 PM +0000 6/15/10, lukas.stadler at jku.at wrote: >Changeset: 103d9a6b740e >Author: lstadler >Date: 2010-06-15 15:36 +0200 >URL: http://hg.openjdk.java.net/mlvm/mlvm/jdk/rev/103d9a6b740e > >added yieldTo method > >! coro.patch Can't find symbol: CoroutineDeath ../../../src/share/classes/java/dyn/CoroutineBase.java:62: cannot find symbol if (!(t instanceof CoroutineDeath)) ^ symbol: class CoroutineDeath location: class CoroutineBase From lukas.stadler at jku.at Tue Jun 15 09:05:49 2010 From: lukas.stadler at jku.at (Lukas Stadler) Date: Tue, 15 Jun 2010 18:05:49 +0200 Subject: hg: mlvm/mlvm/jdk: added yieldTo method In-Reply-To: References: <20100615133715.C6CBD47259@hg.openjdk.java.net> Message-ID: <4C17A4DD.2030304@jku.at> ah... sorry. I forgot that I renamed this file (CoroutineExitException to CoroutineDeath). I'll fix it first thing tomorrow morning. - Lukas On 15.06.2010 17:33, Stephen Bannasch wrote: > At 1:37 PM +0000 6/15/10, lukas.stadler at jku.at wrote: > >> Changeset: 103d9a6b740e >> Author: lstadler >> Date: 2010-06-15 15:36 +0200 >> URL: http://hg.openjdk.java.net/mlvm/mlvm/jdk/rev/103d9a6b740e >> >> added yieldTo method >> >> ! coro.patch >> > Can't find symbol: CoroutineDeath > > ../../../src/share/classes/java/dyn/CoroutineBase.java:62: cannot find symbol > if (!(t instanceof CoroutineDeath)) > ^ > symbol: class CoroutineDeath > location: class CoroutineBase > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > From john.r.rose at oracle.com Tue Jun 15 17:34:35 2010 From: john.r.rose at oracle.com (john.r.rose at oracle.com) Date: Wed, 16 Jun 2010 00:34:35 +0000 Subject: hg: mlvm/mlvm/hotspot: meth-ldc: fix buglet 6960865 from nightly testing Message-ID: <20100616003435.E028447288@hg.openjdk.java.net> Changeset: 41f82e9941c1 Author: jrose Date: 2010-06-15 17:34 -0700 URL: http://hg.openjdk.java.net/mlvm/mlvm/hotspot/rev/41f82e9941c1 meth-ldc: fix buglet 6960865 from nightly testing + meth-ldc-6960865.patch ! series From lukas.stadler at jku.at Wed Jun 16 00:51:22 2010 From: lukas.stadler at jku.at (lukas.stadler at jku.at) Date: Wed, 16 Jun 2010 07:51:22 +0000 Subject: hg: mlvm/mlvm/jdk: coro: renamed ExitException to CoroutineDeath Message-ID: <20100616075123.455314729B@hg.openjdk.java.net> Changeset: 3f195638e5b2 Author: lstadler Date: 2010-06-16 09:50 +0200 URL: http://hg.openjdk.java.net/mlvm/mlvm/jdk/rev/3f195638e5b2 coro: renamed ExitException to CoroutineDeath ! coro.patch From stephen.bannasch at deanbrook.org Wed Jun 16 10:19:12 2010 From: stephen.bannasch at deanbrook.org (Stephen Bannasch) Date: Wed, 16 Jun 2010 13:19:12 -0400 Subject: hg: mlvm/mlvm/jdk: coro: renamed ExitException to CoroutineDeath In-Reply-To: <20100616075123.455314729B@hg.openjdk.java.net> References: <20100616075123.455314729B@hg.openjdk.java.net> Message-ID: At 7:51 AM +0000 6/16/10, lukas.stadler at jku.at wrote: >Changeset: 3f195638e5b2 >Author: lstadler >Date: 2010-06-16 09:50 +0200 >URL: http://hg.openjdk.java.net/mlvm/mlvm/jdk/rev/3f195638e5b2 > >coro: renamed ExitException to CoroutineDeath > >! coro.patch > >_______________________________________________ >mlvm-dev mailing list >mlvm-dev at openjdk.java.net >http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev Thanks. Updated build on Mac OS X here: http://www.concord.org/~sbannasch/mlvm/java-1.7.0-internal-2010_06_16.tar.gz From headius at headius.com Wed Jun 16 13:49:05 2010 From: headius at headius.com (Charles Oliver Nutter) Date: Wed, 16 Jun 2010 15:49:05 -0500 Subject: hg: mlvm/mlvm/jdk: coro: renamed ExitException to CoroutineDeath In-Reply-To: References: <20100616075123.455314729B@hg.openjdk.java.net> Message-ID: Thanks Stephen! Lukas: Does this now have all changes needed to use it? The patches you sent me for JRuby were accompanied by a java.lang.Thread modification that you said I'd need to add to classpath/bootclasspath. On Wed, Jun 16, 2010 at 12:19 PM, Stephen Bannasch wrote: > At 7:51 AM +0000 6/16/10, lukas.stadler at jku.at wrote: >>Changeset: 3f195638e5b2 >>Author: ? ?lstadler >>Date: ? ? ?2010-06-16 09:50 +0200 >>URL: ? ? ? http://hg.openjdk.java.net/mlvm/mlvm/jdk/rev/3f195638e5b2 >> >>coro: renamed ExitException to CoroutineDeath >> >>! coro.patch >> >>_______________________________________________ >>mlvm-dev mailing list >>mlvm-dev at openjdk.java.net >>http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > > > Thanks. > > Updated build on Mac OS X here: > > ?http://www.concord.org/~sbannasch/mlvm/java-1.7.0-internal-2010_06_16.tar.gz > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > From lukas.stadler at jku.at Thu Jun 17 08:58:44 2010 From: lukas.stadler at jku.at (Lukas Stadler) Date: Thu, 17 Jun 2010 17:58:44 +0200 Subject: hg: mlvm/mlvm/jdk: coro: renamed ExitException to CoroutineDeath In-Reply-To: References: <20100616075123.455314729B@hg.openjdk.java.net> Message-ID: <4C1A4634.1010602@jku.at> Yes, this is in there as well. The Thread modification was just the reason why you had to prepend it to the classpath. - Lukas On 16.06.2010 22:49, Charles Oliver Nutter wrote: > Thanks Stephen! > > Lukas: Does this now have all changes needed to use it? The patches > you sent me for JRuby were accompanied by a java.lang.Thread > modification that you said I'd need to add to classpath/bootclasspath. > > On Wed, Jun 16, 2010 at 12:19 PM, Stephen Bannasch > wrote: > >> At 7:51 AM +0000 6/16/10, lukas.stadler at jku.at wrote: >> >>> Changeset: 3f195638e5b2 >>> Author: lstadler >>> Date: 2010-06-16 09:50 +0200 >>> URL: http://hg.openjdk.java.net/mlvm/mlvm/jdk/rev/3f195638e5b2 >>> >>> coro: renamed ExitException to CoroutineDeath >>> >>> ! coro.patch >>> >>> _______________________________________________ >>> mlvm-dev mailing list >>> mlvm-dev at openjdk.java.net >>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >>> >> >> Thanks. >> >> Updated build on Mac OS X here: >> >> http://www.concord.org/~sbannasch/mlvm/java-1.7.0-internal-2010_06_16.tar.gz >> _______________________________________________ >> mlvm-dev mailing list >> mlvm-dev at openjdk.java.net >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >> >> > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > From headius at headius.com Thu Jun 17 10:22:59 2010 From: headius at headius.com (Charles Oliver Nutter) Date: Thu, 17 Jun 2010 12:22:59 -0500 Subject: hg: mlvm/mlvm/jdk: coro: renamed ExitException to CoroutineDeath In-Reply-To: <4C1A4634.1010602@jku.at> References: <20100616075123.455314729B@hg.openjdk.java.net> <4C1A4634.1010602@jku.at> Message-ID: Perfect :) Once I get your changes integrated (in a way that doesn't tie JRuby to them) I'll write up a blog post. On Thu, Jun 17, 2010 at 10:58 AM, Lukas Stadler wrote: > Yes, this is in there as well. The Thread modification was just the > reason why you had to prepend it to the classpath. > > - Lukas > > On 16.06.2010 22:49, Charles Oliver Nutter wrote: >> Thanks Stephen! >> >> Lukas: Does this now have all changes needed to use it? The patches >> you sent me for JRuby were accompanied by a java.lang.Thread >> modification that you said I'd need to add to classpath/bootclasspath. >> >> On Wed, Jun 16, 2010 at 12:19 PM, Stephen Bannasch >> ?wrote: >> >>> At 7:51 AM +0000 6/16/10, lukas.stadler at jku.at wrote: >>> >>>> Changeset: 3f195638e5b2 >>>> Author: ? ?lstadler >>>> Date: ? ? ?2010-06-16 09:50 +0200 >>>> URL: ? ? ? http://hg.openjdk.java.net/mlvm/mlvm/jdk/rev/3f195638e5b2 >>>> >>>> coro: renamed ExitException to CoroutineDeath >>>> >>>> ! coro.patch >>>> >>>> _______________________________________________ >>>> mlvm-dev mailing list >>>> mlvm-dev at openjdk.java.net >>>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >>>> >>> >>> Thanks. >>> >>> Updated build on Mac OS X here: >>> >>> ? http://www.concord.org/~sbannasch/mlvm/java-1.7.0-internal-2010_06_16.tar.gz >>> _______________________________________________ >>> mlvm-dev mailing list >>> mlvm-dev at openjdk.java.net >>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >>> >>> >> _______________________________________________ >> mlvm-dev mailing list >> mlvm-dev at openjdk.java.net >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >> > > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > From howard.lovatt at gmail.com Fri Jun 18 00:21:08 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Fri, 18 Jun 2010 17:21:08 +1000 Subject: build 18.0-b04-fastdebug regression? Message-ID: Hi, I am seeing a change in?behavior?which I think might be a regression from build 17.0-b10 to build 18.0-b04-fastdebug. I am using?Stephen Bannasch builds on Mac OS 10.6. The working version of my code with 17.0-b10 to build gives: wizziewol-ln:Invoke Dynamic Multiple Dispatch lov080$ $a/java -ea -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles -XX:+EnableInvokeDynamic -cp dist/Invoke\ Dynamic\ Multiple\ Dispatch.jar invokedynamicmultipledispatch.Cost type = (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double nearest = cost, type = (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double target = cost, type = (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double type = (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double nearest = cost, type = (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double target = cost, type = (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double cost = 0.0 Which is as expected for the test code I am running. With the newer 18.0-b04-fastdebug build I get: wizziewol-ln:Invoke Dynamic Multiple Dispatch lov080$ $b/java -ea -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles -XX:+EnableInvokeDynamic -cp dist/Invoke\ Dynamic\ Multiple\ Dispatch.jar invokedynamicmultipledispatch.Cost VM option '+UnlockExperimentalVMOptions' VM option '+EnableMethodHandles' VM option '+EnableInvokeDynamic' type = (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double nearest = cost, type = (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double target = cost, type = (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double # To suppress the following error report, specify this argument # after -XX: or in .hotspotrc: SuppressErrorAt=/cpCacheOop.hpp:133 # # A fatal error has been detected by the Java Runtime Environment: # # Internal Error (/Users/stephen/dev/java/src/bsd-port/hotspot/src/share/vm/oops/cpCacheOop.hpp:133), pid=57368, tid=2953121792 # Error: assert(_f2 == 0 || _f2 == f2,"illegal field change") # # JRE version: 7.0 # Java VM: OpenJDK Server VM (18.0-b04-fastdebug mixed mode bsd-x86 ) # An error report file with more information is saved as: # /Users/lov080/Dropbox/Personal/Java/examples/Invoke Dynamic Multiple Dispatch/hs_err_pid57368.log # # If you would like to submit a bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp # Current thread is 2953121792 Dumping core ... Abort trap The code is failing in the bootstrap method invoked by the first of my InvokeDynamic calls when it tries to create a CallSite from a MethodHandle. Is this a known problem or would it be useful if I investigate further? ?-- Howard. From howard.lovatt at gmail.com Fri Jun 18 00:52:09 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Fri, 18 Jun 2010 17:52:09 +1000 Subject: Bug in findSpecial? Message-ID: In the following code: public class Price extends CostCalculator { /* Written by PEC! */ static { final MethodHandles.Lookup l = MethodHandles.lookup(); MethodHandle mh; mh = l.findSpecial( Price.class, "cost", MethodType.methodType( double.class, Price.class, Book.class ), Price.class ); System.out.println(" Price cost type = "+mh.type()); CostCalculatorDispatcher.register( mh ); mh = l.findSpecial( Price.class, "cost", MethodType.methodType( double.class, Price.class, CD.class ), Price.class ); System.out.println(" Price cost type = "+mh.type()); CostCalculatorDispatcher.register( mh ); } @MultipleDispatch public double cost( final Price notUsed, final Book b ) { return b.getPrice(); } @MultipleDispatch public double cost( final Price notUsed, final CD c ) { return c.getPrice(); } } The findSpecial methods find methods, the printlns give: Price cost type = (invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.Book)double Price cost type = (invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.CD)double Note the double Price argument. I think the findSpecials should throw NoAccessException. Is this a bug? -- -- Howard. From forax at univ-mlv.fr Fri Jun 18 00:55:05 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Fri, 18 Jun 2010 09:55:05 +0200 Subject: build 18.0-b04-fastdebug regression? In-Reply-To: References: Message-ID: <4C1B2659.5040407@univ-mlv.fr> Le 18/06/2010 09:21, Howard Lovatt a ?crit : > Hi, > I am seeing a change in behavior which I think might be a regression > from build 17.0-b10 to build 18.0-b04-fastdebug. I am using Stephen > Bannasch builds on Mac OS 10.6. The working version of my code with > 17.0-b10 to build gives: > > wizziewol-ln:Invoke Dynamic Multiple Dispatch lov080$ $a/java -ea > -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles > -XX:+EnableInvokeDynamic -cp dist/Invoke\ Dynamic\ Multiple\ > Dispatch.jar invokedynamicmultipledispatch.Cost > type = (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double > nearest = cost, type = > (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double > target = cost, type = > (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double > type = (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double > nearest = cost, type = > (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double > target = cost, type = > (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double > cost = 0.0 > > Which is as expected for the test code I am running. With the newer > 18.0-b04-fastdebug build I get: > > wizziewol-ln:Invoke Dynamic Multiple Dispatch lov080$ $b/java -ea > -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles > -XX:+EnableInvokeDynamic -cp dist/Invoke\ Dynamic\ Multiple\ > Dispatch.jar invokedynamicmultipledispatch.Cost > VM option '+UnlockExperimentalVMOptions' > VM option '+EnableMethodHandles' > VM option '+EnableInvokeDynamic' > type = (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double > nearest = cost, type = > (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double > target = cost, type = > (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double > # To suppress the following error report, specify this argument > # after -XX: or in .hotspotrc: SuppressErrorAt=/cpCacheOop.hpp:133 > # > # A fatal error has been detected by the Java Runtime Environment: > # > # Internal Error > (/Users/stephen/dev/java/src/bsd-port/hotspot/src/share/vm/oops/cpCacheOop.hpp:133), > pid=57368, tid=2953121792 > # Error: assert(_f2 == 0 || _f2 == f2,"illegal field change") > # > # JRE version: 7.0 > # Java VM: OpenJDK Server VM (18.0-b04-fastdebug mixed mode bsd-x86 ) > # An error report file with more information is saved as: > # /Users/lov080/Dropbox/Personal/Java/examples/Invoke Dynamic Multiple > Dispatch/hs_err_pid57368.log > # > # If you would like to submit a bug report, please visit: > # http://java.sun.com/webapps/bugreport/crash.jsp > # > Current thread is 2953121792 > Dumping core ... > Abort trap > > The code is failing in the bootstrap method invoked by the first of my > InvokeDynamic calls when it tries to create a CallSite from a > MethodHandle. > > Is this a known problem or would it be useful if I investigate further? > It's a known problem, changes have been made into hotspot repository but jdk API was not updated: see http://mail.openjdk.java.net/pipermail/mlvm-dev/2010-May/001728.html > -- Howard. > R?mi From howard.lovatt at gmail.com Fri Jun 18 00:54:45 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Fri, 18 Jun 2010 17:54:45 +1000 Subject: build 18.0-b04-fastdebug regression? Message-ID: Ignore previous code. Typo in code. Sorry, -- -- Howard. From howard.lovatt at gmail.com Fri Jun 18 01:08:19 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Fri, 18 Jun 2010 18:08:19 +1000 Subject: build 18.0-b04-fastdebug regression? Message-ID: Thanks for the help. The suggested solution doesn't work, I get a different error: wizziewol-ln:Invoke Dynamic Multiple Dispatch lov080$ $b/java -ea -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles -XX:+EnableInvokeDynamic -Xbootclasspath/p:/System/Library/Frameworks/JavaVM.framework/Versions/1.7.0.2010_06_16/Home/bin/hs19-b01-jsr292-patch.jar -cp dist/Invoke\ Dynamic\ Multiple\ Dispatch.jar invokedynamicmultipledispatch.Cost VM option '+UnlockExperimentalVMOptions' VM option '+EnableMethodHandles' VM option '+EnableInvokeDynamic' Exception in thread "main" java.lang.InternalError: ARG_SLOT_PUSH_SHIFT: access failed, got java.lang.NoSuchFieldException: ARG_SLOT_PUSH_SHIFT at sun.dyn.MethodHandleNatives.verifyConstants(MethodHandleNatives.java:277) at sun.dyn.MethodHandleNatives.(MethodHandleNatives.java:283) at sun.dyn.MethodHandleImpl.init(MethodHandleImpl.java:118) at sun.dyn.MethodTypeImpl.initForm(MethodTypeImpl.java:383) at java.dyn.MethodType.makeImpl(MethodType.java:220) at java.dyn.MethodType.access$200(MethodType.java:60) at java.dyn.MethodType$1.makeImpl(MethodType.java:85) at sun.dyn.MethodTypeImpl.canonicalize(MethodTypeImpl.java:426) at sun.dyn.MethodTypeImpl.findForm(MethodTypeImpl.java:388) at sun.dyn.MethodTypeImpl.initForm(MethodTypeImpl.java:379) at java.dyn.MethodType.makeImpl(MethodType.java:220) at java.dyn.MethodType.methodType(MethodType.java:177) at sun.dyn.MethodHandleImpl.(MethodHandleImpl.java:1210) at java.dyn.MethodHandles.(MethodHandles.java:64) at invokedynamicmultipledispatch.Cost.(Cost.java:41) However the patch is for build 19 and I am using build 18. Anyway not a big problem for me, I will go back to build 8 which works. -- Howard. From forax at univ-mlv.fr Fri Jun 18 01:19:15 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Fri, 18 Jun 2010 10:19:15 +0200 Subject: build 18.0-b04-fastdebug regression? In-Reply-To: References: Message-ID: <4C1B2C03.4020502@univ-mlv.fr> Le 18/06/2010 10:08, Howard Lovatt a ?crit : > Thanks for the help. > > The suggested solution doesn't work, I get a different error: > > wizziewol-ln:Invoke Dynamic Multiple Dispatch lov080$ $b/java -ea > -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles > -XX:+EnableInvokeDynamic > -Xbootclasspath/p:/System/Library/Frameworks/JavaVM.framework/Versions/1.7.0.2010_06_16/Home/bin/hs19-b01-jsr292-patch.jar > -cp dist/Invoke\ Dynamic\ Multiple\ Dispatch.jar > invokedynamicmultipledispatch.Cost > VM option '+UnlockExperimentalVMOptions' > VM option '+EnableMethodHandles' > VM option '+EnableInvokeDynamic' > Exception in thread "main" java.lang.InternalError: > ARG_SLOT_PUSH_SHIFT: access failed, got > java.lang.NoSuchFieldException: ARG_SLOT_PUSH_SHIFT > at sun.dyn.MethodHandleNatives.verifyConstants(MethodHandleNatives.java:277) > at sun.dyn.MethodHandleNatives.(MethodHandleNatives.java:283) > at sun.dyn.MethodHandleImpl.init(MethodHandleImpl.java:118) > at sun.dyn.MethodTypeImpl.initForm(MethodTypeImpl.java:383) > at java.dyn.MethodType.makeImpl(MethodType.java:220) > at java.dyn.MethodType.access$200(MethodType.java:60) > at java.dyn.MethodType$1.makeImpl(MethodType.java:85) > at sun.dyn.MethodTypeImpl.canonicalize(MethodTypeImpl.java:426) > at sun.dyn.MethodTypeImpl.findForm(MethodTypeImpl.java:388) > at sun.dyn.MethodTypeImpl.initForm(MethodTypeImpl.java:379) > at java.dyn.MethodType.makeImpl(MethodType.java:220) > at java.dyn.MethodType.methodType(MethodType.java:177) > at sun.dyn.MethodHandleImpl.(MethodHandleImpl.java:1210) > at java.dyn.MethodHandles.(MethodHandles.java:64) > at invokedynamicmultipledispatch.Cost.(Cost.java:41) > > However the patch is for build 19 and I am using build 18. Anyway not > a big problem for me, I will go back to build 8 which works. > > > -- Howard. > I haven't checked but perhaps the latest build of Stephen Bannasch http://mail.openjdk.java.net/pipermail/mlvm-dev/2010-June/001780.html is based on build 19. R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20100618/836e2092/attachment.html From howard.lovatt at gmail.com Fri Jun 18 23:40:40 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Sat, 19 Jun 2010 16:40:40 +1000 Subject: Bootstrap method question Message-ID: @R?mi, Thanks for the advise about using a "slowPath" method to discover the runtime types. I have coded up something along the lines you suggested: private static double slowPath( final CallSite callSite, final CostCalculator cC, final Item i ) throws Throwable { System.out.println("callSite = " + callSite + ", CostCalculator = " + cC + ", i = " + i ); final MethodHandle nearest = Dispatchers.nearest( mhs.values(), double.class, cC, i ); System.out.println( "nearest = " + Dispatchers.toString( nearest ) ); final MethodHandle converted = MethodHandles.collectArguments( nearest, callSite.getTarget().type() ); System.out.println( "converted = " + Dispatchers.toString( converted ) ); callSite.setTarget( converted ); return converted.invokeExact( cC, i ); } When run I get the following: callSite = CallSite#29596205[from invokedynamicmultipledispatch.Cost : (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double => slowPath], CostCalculator = invokedynamicmultipledispatch.Price at bf2d5e, i = [Ljava.lang.Object;@13bad12 Exception in thread "main" invokedynamicmultipledispatch.MultipleDispatchException at invokedynamicmultipledispatch.Cost.cost(Cost.java:62) at invokedynamicmultipledispatch.Cost.main(Cost.java:51) Caused by: invokedynamicmultipledispatch.MultipleDispatchException: Cannot find type, (invokedynamicmultipledispatch.Price,java.lang.Object[])double, compatible method in, [cost(invokedynamicmultipledispatch.Postage,invokedynamicmultipledispatch.CD)double, cost(invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double, cost(invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.Book)double, cost(invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.CD)double, cost(invokedynamicmultipledispatch.Postage,invokedynamicmultipledispatch.Book)double] at invokedynamicmultipledispatch.Dispatchers.nearest(Dispatchers.java:182) at invokedynamicmultipledispatch.Dispatchers.nearest(Dispatchers.java:145) at invokedynamicmultipledispatch.CostCalculatorDispatcher.slowPath(CostCalculatorDispatcher.java:35) at sun.dyn.FromGeneric$A2.invoke_D2(FromGeneric.java:534) at sun.dyn.FilterGeneric$F2.invoke_C1(FilterGeneric.java:550) at sun.dyn.ToGeneric$A2.target(ToGeneric.java:661) at sun.dyn.ToGeneric$A2.targetA2(ToGeneric.java:662) at sun.dyn.ToGeneric$A2.invoke_D(ToGeneric.java:671) at invokedynamicmultipledispatch.Cost.cost(Cost.java:60) ... 1 more The interesting bit is "i = [Ljava.lang.Object;@13bad12" on the first line of the printout (ignoring wrapping). This Object[] contains 1 element, the expected Item. What is not expected is wrapping this in an array. Also this is a type unsafe at runtime since an array is passed into a method in a position where an Item is coded. Any idea what is going on? -- Howard. R?mi Forax forax at univ-mlv.fr Sat Jun 12 05:09:48 PDT 2010 wrote: [snip] > public class RT { > public static CallSite bootstrap(Class declaringClass, String name, MethodType methodType) { > CallSite callSite = new CallSite(); > MethodHandle target = MethodHandles.insertArguments(slowPath, 0, callSite); > target = MethodHandles.collectArguments(target, methodType); > callSite.setTarget(target); > return callSite; > } > > private static final MethodHandle slowPath = RT#slowPath(ClassSite,Object[]); > > public Object slowPath(CallSite callsite, Object[] args) { > // find the target method handle depending of the classes of arguments > MethodHandle specific = ... > // create a test for those classes > MethodHandle test = ... > > MethodHandle guard = MethodHandles.guardWithTest(test, specific, callSite.getTarget()); > callSite.setTarget(guard); > > return specific.invokeVarargs(args); > } > } [snip] From forax at univ-mlv.fr Sat Jun 19 04:00:38 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 19 Jun 2010 13:00:38 +0200 Subject: Bootstrap method question In-Reply-To: References: Message-ID: <4C1CA356.9080700@univ-mlv.fr> Le 19/06/2010 08:40, Howard Lovatt a ?crit : > @R?mi, > > Thanks for the advise about using a "slowPath" method to discover the > runtime types. I have coded up something along the lines you > suggested: > > private static double slowPath( final CallSite callSite, final > CostCalculator cC, final Item i ) throws Throwable { > System.out.println("callSite = " + callSite + ", CostCalculator = > " + cC + ", i = " + i ); > final MethodHandle nearest = Dispatchers.nearest( mhs.values(), > double.class, cC, i ); > System.out.println( "nearest = " + Dispatchers.toString( nearest ) ); > final MethodHandle converted = MethodHandles.collectArguments( > nearest, callSite.getTarget().type() ); > System.out.println( "converted = " + Dispatchers.toString( converted ) ); > callSite.setTarget( converted ); > return converted.invokeExact( cC, i ); > } > > When run I get the following: > > callSite = CallSite#29596205[from invokedynamicmultipledispatch.Cost : > (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double > => slowPath], CostCalculator = > invokedynamicmultipledispatch.Price at bf2d5e, i = > [Ljava.lang.Object;@13bad12 > Exception in thread "main" > invokedynamicmultipledispatch.MultipleDispatchException > at invokedynamicmultipledispatch.Cost.cost(Cost.java:62) > at invokedynamicmultipledispatch.Cost.main(Cost.java:51) > Caused by: invokedynamicmultipledispatch.MultipleDispatchException: > Cannot find type, > (invokedynamicmultipledispatch.Price,java.lang.Object[])double, > compatible method in, > [cost(invokedynamicmultipledispatch.Postage,invokedynamicmultipledispatch.CD)double, > cost(invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double, > cost(invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.Book)double, > cost(invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.CD)double, > cost(invokedynamicmultipledispatch.Postage,invokedynamicmultipledispatch.Book)double] > at invokedynamicmultipledispatch.Dispatchers.nearest(Dispatchers.java:182) > at invokedynamicmultipledispatch.Dispatchers.nearest(Dispatchers.java:145) > at invokedynamicmultipledispatch.CostCalculatorDispatcher.slowPath(CostCalculatorDispatcher.java:35) > at sun.dyn.FromGeneric$A2.invoke_D2(FromGeneric.java:534) > at sun.dyn.FilterGeneric$F2.invoke_C1(FilterGeneric.java:550) > at sun.dyn.ToGeneric$A2.target(ToGeneric.java:661) > at sun.dyn.ToGeneric$A2.targetA2(ToGeneric.java:662) > at sun.dyn.ToGeneric$A2.invoke_D(ToGeneric.java:671) > at invokedynamicmultipledispatch.Cost.cost(Cost.java:60) > ... 1 more > > The interesting bit is "i = [Ljava.lang.Object;@13bad12" on the first > line of the printout (ignoring wrapping). This Object[] contains 1 > element, the expected Item. What is not expected is wrapping this in > an array. Also this is a type unsafe at runtime since an array is > passed into a method in a position where an Item is coded. > > Any idea what is going on? > > -- Howard. > And what is the code of the bootstrap method ? R?mi From howard.lovatt at gmail.com Sun Jun 20 19:26:59 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Mon, 21 Jun 2010 12:26:59 +1000 Subject: Bootstrap method question In-Reply-To: <4C1CA356.9080700@univ-mlv.fr> References: <4C1CA356.9080700@univ-mlv.fr> Message-ID: Hi R?mi, A more complete listing is: public final class CostCalculatorDispatcher { private static final Map mhs = new HashMap<>(); private static final String costName = "cost"; private static final MethodHandle slowPathHandle = MethodHandles.lookup().findStatic( CostCalculatorDispatcher.class, "slowPath", MethodType.methodType( double.class, CallSite.class, CostCalculator.class, Item.class ) ); public static void register( final MethodHandle from ) { Dispatchers.add( mhs, from, costName ); } public static CallSite bootstrap( final Class notUsed, final String name, final MethodType type ) { Dispatchers.checkName( name, costName ); return Dispatchers.dispatcher( slowPathHandle, type ); } private static double slowPath( final CallSite cS, final CostCalculator cC, final Item i ) throws Throwable { System.out.println( "cS = " + cS ); System.out.println( "cC = " + cC ); System.out.println( "i = " + i ); final MethodHandle nearest = Dispatchers.nearest( mhs.values(), double.class, cC, i ); System.out.println( "nearest = " + Dispatchers.toString( nearest ) ); final MethodHandle converted = MethodHandles.collectArguments( nearest, cS.getTarget().type() ); System.out.println( "converted = " + Dispatchers.toString( converted ) ); cS.setTarget( converted ); return converted.invokeExact( cC, i ); } } public final class Dispatchers { [snip] /** * Add given {@code MethodHandle} to given {@code Map} and throw an exception if it is already * in the {@code Map} or if it has the wrong name. * * @param mhs {@code Map} of {@code MethodType}s to {@code MethodHandle}s to be added to * @param mh {@code MethodHandle} to add to {@code Map} * @param expectedName the name {@code mh} should have * * @throws PECBug if {@code mh} is already in {@code mhs} or if the name of {@code mh} * isn't {@code expectedName} */ public static void add( final Map mhs, final MethodHandle mh, final String expectedName ) { if ( !mh.toString().equals( expectedName ) ) { throw new PECBug( "MethodHandle, " + toString( mh ) + ", doesn't have expected name, " + expectedName ); } if ( mhs.put( mh.type(), mh ) != null ) { throw new PECBug( "Given MethodHandle, " + toString( mh ) + ", already in map, " + toString( mhs.values() ) ); } } /** * Check that the name given matches the expected name. * * @param name given name * @param expectedName expected name * * @throws PECBug if names don't match */ public static void checkName( final String name, final String expectedName ) throws PECBug { if ( !name.equals( expectedName ) ) { throw new PECBug( "Name, " + name + ", isn't " + expectedName ); } } /** * Return a call site that calls the given {@code MethodHandle}, the purpose is to delay calling * an actual method until the runtime types are known. The given handle when called returns the * a handle to the nearest available method (in a symmetric-multiple-dispatch sense). * Details: wrap the given {@code MethodHandle} in another handle that binds the first * argument of the given handle to the returned {@code CallSite} and then set the site * to call this second handle and return the site. * * @param slowPath handle to a method that returns a handle to the nearest fit * multiple-dispatch method * @param type the declared, not dynamic, type of the required multiple dispatch method * * @return the {@code MethodHandle} wrapped in a call site and with its first argument bound to * the call site */ public static CallSite dispatcher( final MethodHandle slowPath, final MethodType type) { final CallSite callSite = new CallSite(); final MethodHandle bound = MethodHandles.insertArguments( slowPath, 0, callSite ); System.out.println( "bound = " + toString( bound ) ); final MethodHandle converted = MethodHandles.collectArguments( bound, type ); System.out.println( "converted = " + toString( converted ) ); callSite.setTarget( converted ); return callSite; } /** * Find the {@code MethodHandle} in the given {@code Collection} that has the closest type match, * in a symmetric multiple dispatch sense, to the given arguments. * * @param mhs {@code Collection} of {@code MethodHandle}s that are compared to {@code type} * @param returnType the return type of the returned {@code MethodHandle} * @param args the arguments for the returned {@code MethodHandle} (used for types only) * * @return the nearest {@code MethodHandle} * * @throws MultipleDispatchException if no unique, compatible method exists * @throws PECBug if there is a bug in the the code to find the nearest * multiple dispatch method */ public static MethodHandle nearest( final Collection mhs, final Class returnType, final Object... args ) throws MultipleDispatchException, PECBug { final Class[] argTypes = new Class[ args.length ]; for ( int i = 0; i < args.length; i++ ) { argTypes[ i ] = args[ i ].getClass(); } final MethodType mt = MethodType.methodType( returnType, argTypes ); return nearest( mhs, mt ); } /** * Find the {@code MethodHandle} in the given {@code Collection} that has the closest type match, * in a symmetric multiple dispatch sense, to the given type. * * @param mhs {@code Collection} of {@code MethodHandle}s that are compared to {@code type} * @param type the required type for the returned method handle * * @return the nearest {@code MethodHandle} * * @throws MultipleDispatchException if no unique, compatible method exists * @throws PECBug if there is a bug in the the code to find the nearest * multiple dispatch method */ private static MethodHandle nearest( final Collection mhs, final MethodType type ) throws MultipleDispatchException, PECBug { [snip] } [snip] } Your help is much appreciated, -- Howard. On 19 June 2010 21:00, R?mi Forax wrote: > Le 19/06/2010 08:40, Howard Lovatt a ?crit : >> >> @R?mi, >> >> Thanks for the advise about using a "slowPath" method to discover the >> runtime types. I have coded up something along the lines you >> suggested: >> >> ? private static double slowPath( final CallSite callSite, final >> CostCalculator cC, final Item i ) throws Throwable { >> ? ? System.out.println("callSite = " + callSite + ", CostCalculator = >> " + cC + ", i = " + i ); >> ? ? final MethodHandle nearest = Dispatchers.nearest( mhs.values(), >> double.class, cC, i ); >> ? ? System.out.println( "nearest = " + Dispatchers.toString( nearest ) ); >> ? ? final MethodHandle converted = MethodHandles.collectArguments( >> nearest, callSite.getTarget().type() ); >> ? ? System.out.println( "converted = " + Dispatchers.toString( converted ) >> ); >> ? ? callSite.setTarget( converted ); >> ? ? return converted.invokeExact( cC, i ); >> ? } >> >> When run I get the following: >> >> callSite = CallSite#29596205[from invokedynamicmultipledispatch.Cost : >> >> (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double >> => ?slowPath], CostCalculator = >> invokedynamicmultipledispatch.Price at bf2d5e, i = >> [Ljava.lang.Object;@13bad12 >> Exception in thread "main" >> invokedynamicmultipledispatch.MultipleDispatchException >> ? ? ? ? at invokedynamicmultipledispatch.Cost.cost(Cost.java:62) >> ? ? ? ? at invokedynamicmultipledispatch.Cost.main(Cost.java:51) >> Caused by: invokedynamicmultipledispatch.MultipleDispatchException: >> Cannot find type, >> (invokedynamicmultipledispatch.Price,java.lang.Object[])double, >> compatible method in, >> >> [cost(invokedynamicmultipledispatch.Postage,invokedynamicmultipledispatch.CD)double, >> >> cost(invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double, >> >> cost(invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.Book)double, >> >> cost(invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.CD)double, >> >> cost(invokedynamicmultipledispatch.Postage,invokedynamicmultipledispatch.Book)double] >> ? ? ? ? at >> invokedynamicmultipledispatch.Dispatchers.nearest(Dispatchers.java:182) >> ? ? ? ? at >> invokedynamicmultipledispatch.Dispatchers.nearest(Dispatchers.java:145) >> ? ? ? ? at >> invokedynamicmultipledispatch.CostCalculatorDispatcher.slowPath(CostCalculatorDispatcher.java:35) >> ? ? ? ? at sun.dyn.FromGeneric$A2.invoke_D2(FromGeneric.java:534) >> ? ? ? ? at sun.dyn.FilterGeneric$F2.invoke_C1(FilterGeneric.java:550) >> ? ? ? ? at sun.dyn.ToGeneric$A2.target(ToGeneric.java:661) >> ? ? ? ? at sun.dyn.ToGeneric$A2.targetA2(ToGeneric.java:662) >> ? ? ? ? at sun.dyn.ToGeneric$A2.invoke_D(ToGeneric.java:671) >> ? ? ? ? at invokedynamicmultipledispatch.Cost.cost(Cost.java:60) >> ? ? ? ? ... 1 more >> >> The interesting bit is "i = [Ljava.lang.Object;@13bad12" on the first >> line of the printout (ignoring wrapping). This Object[] contains 1 >> element, the expected Item. What is not expected is wrapping this in >> an array. Also this is a type unsafe at runtime since an array is >> passed into a method in a position where an Item is coded. >> >> Any idea what is going on? >> >> ? -- Howard. >> > > And what is the code of the bootstrap method ? > > R?mi > -- -- Howard. From forax at univ-mlv.fr Mon Jun 21 01:15:08 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Mon, 21 Jun 2010 10:15:08 +0200 Subject: Bootstrap method question In-Reply-To: References: <4C1CA356.9080700@univ-mlv.fr> Message-ID: <4C1F1F8C.2080102@univ-mlv.fr> I think I 've found the bug, in Dispatcher you use collectArguments instead of convertArguments. R?mi Le 21/06/2010 04:26, Howard Lovatt a ?crit : > Hi R?mi, > > A more complete listing is: > > public final class CostCalculatorDispatcher { > private static final Map mhs = new HashMap<>(); > > private static final String costName = "cost"; > > private static final MethodHandle slowPathHandle = > MethodHandles.lookup().findStatic( > CostCalculatorDispatcher.class, "slowPath", > MethodType.methodType( double.class, CallSite.class, > CostCalculator.class, Item.class ) ); > > public static void register( final MethodHandle from ) { > Dispatchers.add( mhs, from, costName ); } > > public static CallSite bootstrap( final Class notUsed, final > String name, final MethodType type ) { > Dispatchers.checkName( name, costName ); > return Dispatchers.dispatcher( slowPathHandle, type ); > } > > private static double slowPath( final CallSite cS, final > CostCalculator cC, final Item i ) > throws Throwable { > System.out.println( "cS = " + cS ); > System.out.println( "cC = " + cC ); > System.out.println( "i = " + i ); > final MethodHandle nearest = Dispatchers.nearest( mhs.values(), > double.class, cC, i ); > System.out.println( "nearest = " + Dispatchers.toString( nearest ) ); > final MethodHandle converted = MethodHandles.collectArguments( > nearest, cS.getTarget().type() ); > System.out.println( "converted = " + Dispatchers.toString( converted ) ); > cS.setTarget( converted ); > return converted.invokeExact( cC, i ); > } > } > > > > > public final class Dispatchers { > [snip] > > /** > * Add given {@code MethodHandle} to given {@code Map} and throw an > exception if it is already > * in the {@code Map} or if it has the wrong name. > * > * @param mhs {@code Map} of {@code MethodType}s to > {@code MethodHandle}s to be added to > * @param mh {@code MethodHandle} to add to {@code Map} > * @param expectedName the name {@code mh} should have > * > * @throws PECBug if {@code mh} is already in {@code mhs} or > if the name of {@code mh} > * isn't {@code expectedName} > */ > public static void add( final Map mhs, > final MethodHandle mh, final String expectedName ) { > if ( !mh.toString().equals( expectedName ) ) { > throw new PECBug( "MethodHandle, " + toString( mh ) + ", doesn't > have expected name, " + expectedName ); > } > if ( mhs.put( mh.type(), mh ) != null ) { > throw new PECBug( "Given MethodHandle, " + toString( mh ) + ", > already in map, " + toString( mhs.values() ) ); > } > } > > /** > * Check that the name given matches the expected name. > * > * @param name given name > * @param expectedName expected name > * > * @throws PECBug if names don't match > */ > public static void checkName( final String name, final String > expectedName ) throws PECBug { > if ( !name.equals( expectedName ) ) { > throw new PECBug( "Name, " + name + ", isn't " + expectedName ); > } > } > > /** > * Return a call site that calls the given {@code MethodHandle}, the > purpose is to delay calling > * an actual method until the runtime types are known. The given > handle when called returns the > * a handle to the nearest available method (in a > symmetric-multiple-dispatch sense). > * Details: wrap the given {@code MethodHandle} in another handle > that binds the first > * argument of the given handle to the returned {@code CallSite} and > then set the site > * to call this second handle and return the site. > * > * @param slowPath handle to a method that returns a handle to > the nearest fit > * multiple-dispatch method > * @param type the declared, not dynamic, type of the > required multiple dispatch method > * > * @return the {@code MethodHandle} wrapped in a call site and with > its first argument bound to > * the call site > */ > public static CallSite dispatcher( final MethodHandle slowPath, > final MethodType type) { > final CallSite callSite = new CallSite(); > final MethodHandle bound = MethodHandles.insertArguments( > slowPath, 0, callSite ); > System.out.println( "bound = " + toString( bound ) ); > final MethodHandle converted = MethodHandles.collectArguments( > bound, type ); > System.out.println( "converted = " + toString( converted ) ); > callSite.setTarget( converted ); > return callSite; > } > > /** > * Find the {@code MethodHandle} in the given {@code Collection} > that has the closest type match, > * in a symmetric multiple dispatch sense, to the given arguments. > * > * @param mhs {@code Collection} of {@code MethodHandle}s > that are compared to {@code type} > * @param returnType the return type of the returned {@code MethodHandle} > * @param args the arguments for the returned {@code > MethodHandle} (used for types only) > * > * @return the nearest {@code MethodHandle} > * > * @throws MultipleDispatchException if no unique, compatible method exists > * @throws PECBug if there is a bug in the the > code to find the nearest > * multiple dispatch method > */ > public static MethodHandle nearest( final Collection mhs, > final Class returnType, final Object... args ) throws > MultipleDispatchException, PECBug { > final Class[] argTypes = new Class[ args.length ]; > for ( int i = 0; i< args.length; i++ ) { argTypes[ i ] = args[ i > ].getClass(); } > final MethodType mt = MethodType.methodType( returnType, argTypes ); > return nearest( mhs, mt ); > } > > /** > * Find the {@code MethodHandle} in the given {@code Collection} > that has the closest type match, > * in a symmetric multiple dispatch sense, to the given type. > * > * @param mhs {@code Collection} of {@code MethodHandle}s that > are compared to {@code type} > * @param type the required type for the returned method handle > * > * @return the nearest {@code MethodHandle} > * > * @throws MultipleDispatchException if no unique, compatible method exists > * @throws PECBug if there is a bug in the the > code to find the nearest > * multiple dispatch method > */ > private static MethodHandle nearest( final Collection > mhs, final MethodType type ) > throws MultipleDispatchException, PECBug { > [snip] > } > [snip] > } > > Your help is much appreciated, > > -- Howard. > > On 19 June 2010 21:00, R?mi Forax wrote: > >> Le 19/06/2010 08:40, Howard Lovatt a ?crit : >> >>> @R?mi, >>> >>> Thanks for the advise about using a "slowPath" method to discover the >>> runtime types. I have coded up something along the lines you >>> suggested: >>> >>> private static double slowPath( final CallSite callSite, final >>> CostCalculator cC, final Item i ) throws Throwable { >>> System.out.println("callSite = " + callSite + ", CostCalculator = >>> " + cC + ", i = " + i ); >>> final MethodHandle nearest = Dispatchers.nearest( mhs.values(), >>> double.class, cC, i ); >>> System.out.println( "nearest = " + Dispatchers.toString( nearest ) ); >>> final MethodHandle converted = MethodHandles.collectArguments( >>> nearest, callSite.getTarget().type() ); >>> System.out.println( "converted = " + Dispatchers.toString( converted ) >>> ); >>> callSite.setTarget( converted ); >>> return converted.invokeExact( cC, i ); >>> } >>> >>> When run I get the following: >>> >>> callSite = CallSite#29596205[from invokedynamicmultipledispatch.Cost : >>> >>> (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double >>> => slowPath], CostCalculator = >>> invokedynamicmultipledispatch.Price at bf2d5e, i = >>> [Ljava.lang.Object;@13bad12 >>> Exception in thread "main" >>> invokedynamicmultipledispatch.MultipleDispatchException >>> at invokedynamicmultipledispatch.Cost.cost(Cost.java:62) >>> at invokedynamicmultipledispatch.Cost.main(Cost.java:51) >>> Caused by: invokedynamicmultipledispatch.MultipleDispatchException: >>> Cannot find type, >>> (invokedynamicmultipledispatch.Price,java.lang.Object[])double, >>> compatible method in, >>> >>> [cost(invokedynamicmultipledispatch.Postage,invokedynamicmultipledispatch.CD)double, >>> >>> cost(invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double, >>> >>> cost(invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.Book)double, >>> >>> cost(invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.CD)double, >>> >>> cost(invokedynamicmultipledispatch.Postage,invokedynamicmultipledispatch.Book)double] >>> at >>> invokedynamicmultipledispatch.Dispatchers.nearest(Dispatchers.java:182) >>> at >>> invokedynamicmultipledispatch.Dispatchers.nearest(Dispatchers.java:145) >>> at >>> invokedynamicmultipledispatch.CostCalculatorDispatcher.slowPath(CostCalculatorDispatcher.java:35) >>> at sun.dyn.FromGeneric$A2.invoke_D2(FromGeneric.java:534) >>> at sun.dyn.FilterGeneric$F2.invoke_C1(FilterGeneric.java:550) >>> at sun.dyn.ToGeneric$A2.target(ToGeneric.java:661) >>> at sun.dyn.ToGeneric$A2.targetA2(ToGeneric.java:662) >>> at sun.dyn.ToGeneric$A2.invoke_D(ToGeneric.java:671) >>> at invokedynamicmultipledispatch.Cost.cost(Cost.java:60) >>> ... 1 more >>> >>> The interesting bit is "i = [Ljava.lang.Object;@13bad12" on the first >>> line of the printout (ignoring wrapping). This Object[] contains 1 >>> element, the expected Item. What is not expected is wrapping this in >>> an array. Also this is a type unsafe at runtime since an array is >>> passed into a method in a position where an Item is coded. >>> >>> Any idea what is going on? >>> >>> -- Howard. >>> >>> >> And what is the code of the bootstrap method ? >> >> R?mi >> >> > > > From howard.lovatt at gmail.com Tue Jun 22 03:40:00 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Tue, 22 Jun 2010 20:40:00 +1000 Subject: Bootstrap method question In-Reply-To: <4C1F1F8C.2080102@univ-mlv.fr> References: <4C1CA356.9080700@univ-mlv.fr> <4C1F1F8C.2080102@univ-mlv.fr> Message-ID: R?mi, Many thanks, collectArguments was indeed the bug. My multiple dispatch example is now working. As an aside I am still surprised that neither collectArguments or the call to the MethodHandle threw an exception. -- Howard. On 21 June 2010 18:15, R?mi Forax wrote: > I think I 've found the bug, > in Dispatcher you use collectArguments instead of convertArguments. > > R?mi > > > Le 21/06/2010 04:26, Howard Lovatt a ?crit : >> >> Hi R?mi, >> >> A more complete listing is: >> >> public final class CostCalculatorDispatcher { >> ? private static final Map ?mhs = new >> HashMap<>(); >> >> ? private static final String costName = "cost"; >> >> ? private static final MethodHandle slowPathHandle = >> MethodHandles.lookup().findStatic( >> ? ? ? ? CostCalculatorDispatcher.class, "slowPath", >> ? ? ? ? MethodType.methodType( double.class, CallSite.class, >> CostCalculator.class, Item.class ) ); >> >> ? public static void register( final MethodHandle from ) { >> Dispatchers.add( mhs, from, costName ); } >> >> ? public static CallSite bootstrap( final Class ?notUsed, final >> String name, final MethodType type ) { >> ? ? Dispatchers.checkName( name, costName ); >> ? ? return Dispatchers.dispatcher( slowPathHandle, type ); >> ? } >> >> ? private static double slowPath( final CallSite cS, final >> CostCalculator cC, final Item i ) >> ? ? ? ? ? throws Throwable { >> ? ? System.out.println( "cS = " + cS ); >> ? ? System.out.println( "cC = " + cC ); >> ? ? System.out.println( "i ?= " + i ); >> ? ? final MethodHandle nearest = Dispatchers.nearest( mhs.values(), >> double.class, cC, i ); >> ? ? System.out.println( "nearest ? = " + Dispatchers.toString( nearest ) >> ); >> ? ? final MethodHandle converted = MethodHandles.collectArguments( >> nearest, cS.getTarget().type() ); >> ? ? System.out.println( "converted = " + Dispatchers.toString( converted ) >> ); >> ? ? cS.setTarget( converted ); >> ? ? return converted.invokeExact( cC, i ); >> ? } >> } >> >> >> >> >> public final class Dispatchers { >> ? [snip] >> >> ? /** >> ? ?* Add given {@code MethodHandle} to given {@code Map} and throw an >> exception if it is already >> ? ?* in the {@code Map} or if it has the wrong name. >> ? ?* >> ? ?* @param ? mhs ? ? ? ? ?{@code Map} of {@code MethodType}s to >> {@code MethodHandle}s to be added to >> ? ?* @param ? mh ? ? ? ? ? {@code MethodHandle} to add to {@code Map} >> ? ?* @param ? expectedName the name {@code mh} should have >> ? ?* >> ? ?* @throws ?PECBug ? ? ? if {@code mh} is already in {@code mhs} or >> if the name of {@code mh} >> ? ?* ? ? ? ? ? ? ? ? ? ? ? isn't {@code expectedName} >> ? ?*/ >> ? public static void add( final Map ?mhs, >> final MethodHandle mh, final String expectedName ) { >> ? ? if ( !mh.toString().equals( expectedName ) ) { >> ? ? ? throw new PECBug( "MethodHandle, " + toString( mh ) + ", doesn't >> have expected name, " + expectedName ); >> ? ? } >> ? ? if ( mhs.put( mh.type(), mh ) != null ) { >> ? ? ? throw new PECBug( "Given MethodHandle, " + toString( mh ) + ", >> already in map, " + toString( mhs.values() ) ); >> ? ? } >> ? } >> >> ? /** >> ? ?* Check that the name given matches the expected name. >> ? ?* >> ? ?* @param ? name ? ? ? ? ?given name >> ? ?* @param ? expectedName ?expected name >> ? ?* >> ? ?* @throws ?PECBug ? ? ? ?if names don't match >> ? ?*/ >> ? public static void checkName( final String name, final String >> expectedName ) throws PECBug { >> ? ? if ( !name.equals( expectedName ) ) { >> ? ? ? throw new PECBug( "Name, " + name + ", isn't " + expectedName ); >> ? ? } >> ? } >> >> ? /** >> ? ?* Return a call site that calls the given {@code MethodHandle}, the >> purpose is to delay calling >> ? ?* an actual method until the runtime types are known. The given >> handle when called returns the >> ? ?* a handle to the nearest available method (in a >> symmetric-multiple-dispatch sense). >> ? ?* Details: wrap the given {@code MethodHandle} in another handle >> that binds the first >> ? ?* argument of the given handle to the returned {@code CallSite} and >> then set the site >> ? ?* to call this second handle and return the site. >> ? ?* >> ? ?* @param ? slowPath ? handle to a method that returns a handle to >> the nearest fit >> ? ?* ? ? ? ? ? ? ? ? ? ? multiple-dispatch method >> ? ?* @param ? type ? ? ? the declared, not dynamic, type of the >> required multiple dispatch method >> ? ?* >> ? ?* @return ?the {@code MethodHandle} wrapped in a call site and with >> its first argument bound to >> ? ?* ? ? ? ? ?the call site >> ? ?*/ >> ? public static CallSite dispatcher( final MethodHandle slowPath, >> final MethodType type) { >> ? ? final CallSite callSite = new CallSite(); >> ? ? final MethodHandle bound = MethodHandles.insertArguments( >> slowPath, 0, callSite ); >> ? ? System.out.println( "bound = " + toString( bound ) ); >> ? ? final MethodHandle converted = MethodHandles.collectArguments( >> bound, type ); >> ? ? System.out.println( "converted = " + toString( converted ) ); >> ? ? callSite.setTarget( converted ); >> ? ? return callSite; >> ? } >> >> ? /** >> ? ?* Find the {@code MethodHandle} in the given {@code Collection} >> that has the closest type match, >> ? ?* in a symmetric multiple dispatch sense, to the given arguments. >> ? ?* >> ? ?* @param ? mhs ? ? ? ?{@code Collection} of {@code MethodHandle}s >> that are compared to {@code type} >> ? ?* @param ? returnType the return type of the returned {@code >> MethodHandle} >> ? ?* @param ? args ? ? ? the arguments for the returned {@code >> MethodHandle} (used for types only) >> ? ?* >> ? ?* @return ?the nearest {@code MethodHandle} >> ? ?* >> ? ?* @throws ?MultipleDispatchException ?if no unique, compatible method >> exists >> ? ?* @throws ?PECBug ? ? ? ? ? ? ? ? ? ? if there is a bug in the the >> code to find the nearest >> ? ?* ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? multiple dispatch method >> ? ?*/ >> ? public static MethodHandle nearest( final Collection ?mhs, >> ? ? ? ? final Class ?returnType, final Object... args ) throws >> MultipleDispatchException, PECBug { >> ? ? final Class[] argTypes = new Class[ args.length ]; >> ? ? for ( int i = 0; i< ?args.length; i++ ) { argTypes[ i ] = args[ i >> ].getClass(); } >> ? ? final MethodType mt = MethodType.methodType( returnType, argTypes ); >> ? ? return nearest( mhs, mt ); >> ? } >> >> ? /** >> ? ?* Find the {@code MethodHandle} in the given {@code Collection} >> that has the closest type match, >> ? ?* in a symmetric multiple dispatch sense, to the given type. >> ? ?* >> ? ?* @param ? mhs ? {@code Collection} of {@code MethodHandle}s that >> are compared to {@code type} >> ? ?* @param ? type ?the required type for the returned method handle >> ? ?* >> ? ?* @return ?the nearest {@code MethodHandle} >> ? ?* >> ? ?* @throws ?MultipleDispatchException ?if no unique, compatible method >> exists >> ? ?* @throws ?PECBug ? ? ? ? ? ? ? ? ? ? if there is a bug in the the >> code to find the nearest >> ? ?* ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? multiple dispatch method >> ? ?*/ >> ? private static MethodHandle nearest( final Collection >> mhs, final MethodType type ) >> ? ? ? throws MultipleDispatchException, PECBug { >> ? ? [snip] >> ? } >> ? [snip] >> } >> >> Your help is much appreciated, >> >> ?-- Howard. >> >> On 19 June 2010 21:00, R?mi Forax ?wrote: >> >>> >>> Le 19/06/2010 08:40, Howard Lovatt a ?crit : >>> >>>> >>>> @R?mi, >>>> >>>> Thanks for the advise about using a "slowPath" method to discover the >>>> runtime types. I have coded up something along the lines you >>>> suggested: >>>> >>>> ? private static double slowPath( final CallSite callSite, final >>>> CostCalculator cC, final Item i ) throws Throwable { >>>> ? ? System.out.println("callSite = " + callSite + ", CostCalculator = >>>> " + cC + ", i = " + i ); >>>> ? ? final MethodHandle nearest = Dispatchers.nearest( mhs.values(), >>>> double.class, cC, i ); >>>> ? ? System.out.println( "nearest = " + Dispatchers.toString( nearest ) >>>> ); >>>> ? ? final MethodHandle converted = MethodHandles.collectArguments( >>>> nearest, callSite.getTarget().type() ); >>>> ? ? System.out.println( "converted = " + Dispatchers.toString( converted >>>> ) >>>> ); >>>> ? ? callSite.setTarget( converted ); >>>> ? ? return converted.invokeExact( cC, i ); >>>> ? } >>>> >>>> When run I get the following: >>>> >>>> callSite = CallSite#29596205[from invokedynamicmultipledispatch.Cost : >>>> >>>> >>>> (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double >>>> => ? ?slowPath], CostCalculator = >>>> invokedynamicmultipledispatch.Price at bf2d5e, i = >>>> [Ljava.lang.Object;@13bad12 >>>> Exception in thread "main" >>>> invokedynamicmultipledispatch.MultipleDispatchException >>>> ? ? ? ? at invokedynamicmultipledispatch.Cost.cost(Cost.java:62) >>>> ? ? ? ? at invokedynamicmultipledispatch.Cost.main(Cost.java:51) >>>> Caused by: invokedynamicmultipledispatch.MultipleDispatchException: >>>> Cannot find type, >>>> (invokedynamicmultipledispatch.Price,java.lang.Object[])double, >>>> compatible method in, >>>> >>>> >>>> [cost(invokedynamicmultipledispatch.Postage,invokedynamicmultipledispatch.CD)double, >>>> >>>> >>>> cost(invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double, >>>> >>>> >>>> cost(invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.Book)double, >>>> >>>> >>>> cost(invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.CD)double, >>>> >>>> >>>> cost(invokedynamicmultipledispatch.Postage,invokedynamicmultipledispatch.Book)double] >>>> ? ? ? ? at >>>> invokedynamicmultipledispatch.Dispatchers.nearest(Dispatchers.java:182) >>>> ? ? ? ? at >>>> invokedynamicmultipledispatch.Dispatchers.nearest(Dispatchers.java:145) >>>> ? ? ? ? at >>>> >>>> invokedynamicmultipledispatch.CostCalculatorDispatcher.slowPath(CostCalculatorDispatcher.java:35) >>>> ? ? ? ? at sun.dyn.FromGeneric$A2.invoke_D2(FromGeneric.java:534) >>>> ? ? ? ? at sun.dyn.FilterGeneric$F2.invoke_C1(FilterGeneric.java:550) >>>> ? ? ? ? at sun.dyn.ToGeneric$A2.target(ToGeneric.java:661) >>>> ? ? ? ? at sun.dyn.ToGeneric$A2.targetA2(ToGeneric.java:662) >>>> ? ? ? ? at sun.dyn.ToGeneric$A2.invoke_D(ToGeneric.java:671) >>>> ? ? ? ? at invokedynamicmultipledispatch.Cost.cost(Cost.java:60) >>>> ? ? ? ? ... 1 more >>>> >>>> The interesting bit is "i = [Ljava.lang.Object;@13bad12" on the first >>>> line of the printout (ignoring wrapping). This Object[] contains 1 >>>> element, the expected Item. What is not expected is wrapping this in >>>> an array. Also this is a type unsafe at runtime since an array is >>>> passed into a method in a position where an Item is coded. >>>> >>>> Any idea what is going on? >>>> >>>> ? -- Howard. >>>> >>>> >>> >>> And what is the code of the bootstrap method ? >>> >>> R?mi >>> >>> >> >> >> > > -- -- Howard. From howard.lovatt at gmail.com Tue Jun 22 03:48:36 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Tue, 22 Jun 2010 20:48:36 +1000 Subject: Latest Thinking Message-ID: A couple of comments on the current MethodHandle API: 1. Having only one bootstrap method for InvokeDynamic is a bit limiting, it it possible to have one per use site? 2. Has thought been given to using the .( args ) notation (or what ever it ends up as) from lambda dev for invokeGeneric( args )? 3. Are there plans to add MethodHandle literals, e.g. Class#method( types )? 4. Assuming 3 above; are there plans for a binding literal, e.g. MethodHandle addA = String#concat( String, "A" )? I am sure these items have been already discussed in the expert group, just wondering what the latest thinking is. -- Howard. From forax at univ-mlv.fr Tue Jun 22 05:30:48 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Tue, 22 Jun 2010 14:30:48 +0200 Subject: Latest Thinking In-Reply-To: References: Message-ID: <4C20ACF8.1010701@univ-mlv.fr> Le 22/06/2010 12:48, Howard Lovatt a ?crit : > A couple of comments on the current MethodHandle API: > > 1. Having only one bootstrap method for InvokeDynamic is a bit > limiting, it it possible to have one per use site? > It's an open issue, we're working on it. > 2. Has thought been given to using the .( args ) notation (or what > ever it ends up as) from lambda dev for invokeGeneric( args )? > My opinion is that the lambda spec has to mature a little bit before looking at this kind of things. Currently, the lambda super type is not MethodHandle but Object > 3. Are there plans to add MethodHandle literals, e.g. Class#method( types )? > The mlvm workspace already contains method handle literals :) > 4. Assuming 3 above; are there plans for a binding literal, e.g. > MethodHandle addA = String#concat( String, "A" )? > > As far as I know, No. I don't think it worth the introduction of a new syntax MethodHandle addA = insertArguments(String#concat( String, String ), 1, "A"); Morever, your proposed syntax has a bad property. It allow type and expression to occur at the same place. > I am sure these items have been already discussed in the expert group, > just wondering what the latest thinking is. > > -- Howard. > cheers, R?mi From forax at univ-mlv.fr Tue Jun 22 06:16:30 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Tue, 22 Jun 2010 15:16:30 +0200 Subject: Bootstrap method question In-Reply-To: References: <4C1CA356.9080700@univ-mlv.fr> <4C1F1F8C.2080102@univ-mlv.fr> Message-ID: <4C20B7AE.5020303@univ-mlv.fr> Le 22/06/2010 12:40, Howard Lovatt a ?crit : > R?mi, > > Many thanks, collectArguments was indeed the bug. My multiple dispatch > example is now working. > > As an aside I am still surprised that neither collectArguments or the > call to the MethodHandle threw an exception. > > -- Howard. > It's a bug, collectArguments should throw an exception because the last parameter type of the method handle is not an array or a supertype of an array (Object, Serializable, Cloneable). The open question is why it doesn't throw a ClassCastException ? R?mi > On 21 June 2010 18:15, R?mi Forax wrote: > >> I think I 've found the bug, >> in Dispatcher you use collectArguments instead of convertArguments. >> >> R?mi >> >> >> Le 21/06/2010 04:26, Howard Lovatt a ?crit : >> >>> Hi R?mi, >>> >>> A more complete listing is: >>> >>> public final class CostCalculatorDispatcher { >>> private static final Map mhs = new >>> HashMap<>(); >>> >>> private static final String costName = "cost"; >>> >>> private static final MethodHandle slowPathHandle = >>> MethodHandles.lookup().findStatic( >>> CostCalculatorDispatcher.class, "slowPath", >>> MethodType.methodType( double.class, CallSite.class, >>> CostCalculator.class, Item.class ) ); >>> >>> public static void register( final MethodHandle from ) { >>> Dispatchers.add( mhs, from, costName ); } >>> >>> public static CallSite bootstrap( final Class notUsed, final >>> String name, final MethodType type ) { >>> Dispatchers.checkName( name, costName ); >>> return Dispatchers.dispatcher( slowPathHandle, type ); >>> } >>> >>> private static double slowPath( final CallSite cS, final >>> CostCalculator cC, final Item i ) >>> throws Throwable { >>> System.out.println( "cS = " + cS ); >>> System.out.println( "cC = " + cC ); >>> System.out.println( "i = " + i ); >>> final MethodHandle nearest = Dispatchers.nearest( mhs.values(), >>> double.class, cC, i ); >>> System.out.println( "nearest = " + Dispatchers.toString( nearest ) >>> ); >>> final MethodHandle converted = MethodHandles.collectArguments( >>> nearest, cS.getTarget().type() ); >>> System.out.println( "converted = " + Dispatchers.toString( converted ) >>> ); >>> cS.setTarget( converted ); >>> return converted.invokeExact( cC, i ); >>> } >>> } >>> >>> >>> >>> >>> public final class Dispatchers { >>> [snip] >>> >>> /** >>> * Add given {@code MethodHandle} to given {@code Map} and throw an >>> exception if it is already >>> * in the {@code Map} or if it has the wrong name. >>> * >>> * @param mhs {@code Map} of {@code MethodType}s to >>> {@code MethodHandle}s to be added to >>> * @param mh {@code MethodHandle} to add to {@code Map} >>> * @param expectedName the name {@code mh} should have >>> * >>> * @throws PECBug if {@code mh} is already in {@code mhs} or >>> if the name of {@code mh} >>> * isn't {@code expectedName} >>> */ >>> public static void add( final Map mhs, >>> final MethodHandle mh, final String expectedName ) { >>> if ( !mh.toString().equals( expectedName ) ) { >>> throw new PECBug( "MethodHandle, " + toString( mh ) + ", doesn't >>> have expected name, " + expectedName ); >>> } >>> if ( mhs.put( mh.type(), mh ) != null ) { >>> throw new PECBug( "Given MethodHandle, " + toString( mh ) + ", >>> already in map, " + toString( mhs.values() ) ); >>> } >>> } >>> >>> /** >>> * Check that the name given matches the expected name. >>> * >>> * @param name given name >>> * @param expectedName expected name >>> * >>> * @throws PECBug if names don't match >>> */ >>> public static void checkName( final String name, final String >>> expectedName ) throws PECBug { >>> if ( !name.equals( expectedName ) ) { >>> throw new PECBug( "Name, " + name + ", isn't " + expectedName ); >>> } >>> } >>> >>> /** >>> * Return a call site that calls the given {@code MethodHandle}, the >>> purpose is to delay calling >>> * an actual method until the runtime types are known. The given >>> handle when called returns the >>> * a handle to the nearest available method (in a >>> symmetric-multiple-dispatch sense). >>> * Details: wrap the given {@code MethodHandle} in another handle >>> that binds the first >>> * argument of the given handle to the returned {@code CallSite} and >>> then set the site >>> * to call this second handle and return the site. >>> * >>> * @param slowPath handle to a method that returns a handle to >>> the nearest fit >>> * multiple-dispatch method >>> * @param type the declared, not dynamic, type of the >>> required multiple dispatch method >>> * >>> * @return the {@code MethodHandle} wrapped in a call site and with >>> its first argument bound to >>> * the call site >>> */ >>> public static CallSite dispatcher( final MethodHandle slowPath, >>> final MethodType type) { >>> final CallSite callSite = new CallSite(); >>> final MethodHandle bound = MethodHandles.insertArguments( >>> slowPath, 0, callSite ); >>> System.out.println( "bound = " + toString( bound ) ); >>> final MethodHandle converted = MethodHandles.collectArguments( >>> bound, type ); >>> System.out.println( "converted = " + toString( converted ) ); >>> callSite.setTarget( converted ); >>> return callSite; >>> } >>> >>> /** >>> * Find the {@code MethodHandle} in the given {@code Collection} >>> that has the closest type match, >>> * in a symmetric multiple dispatch sense, to the given arguments. >>> * >>> * @param mhs {@code Collection} of {@code MethodHandle}s >>> that are compared to {@code type} >>> * @param returnType the return type of the returned {@code >>> MethodHandle} >>> * @param args the arguments for the returned {@code >>> MethodHandle} (used for types only) >>> * >>> * @return the nearest {@code MethodHandle} >>> * >>> * @throws MultipleDispatchException if no unique, compatible method >>> exists >>> * @throws PECBug if there is a bug in the the >>> code to find the nearest >>> * multiple dispatch method >>> */ >>> public static MethodHandle nearest( final Collection mhs, >>> final Class returnType, final Object... args ) throws >>> MultipleDispatchException, PECBug { >>> final Class[] argTypes = new Class[ args.length ]; >>> for ( int i = 0; i< args.length; i++ ) { argTypes[ i ] = args[ i >>> ].getClass(); } >>> final MethodType mt = MethodType.methodType( returnType, argTypes ); >>> return nearest( mhs, mt ); >>> } >>> >>> /** >>> * Find the {@code MethodHandle} in the given {@code Collection} >>> that has the closest type match, >>> * in a symmetric multiple dispatch sense, to the given type. >>> * >>> * @param mhs {@code Collection} of {@code MethodHandle}s that >>> are compared to {@code type} >>> * @param type the required type for the returned method handle >>> * >>> * @return the nearest {@code MethodHandle} >>> * >>> * @throws MultipleDispatchException if no unique, compatible method >>> exists >>> * @throws PECBug if there is a bug in the the >>> code to find the nearest >>> * multiple dispatch method >>> */ >>> private static MethodHandle nearest( final Collection >>> mhs, final MethodType type ) >>> throws MultipleDispatchException, PECBug { >>> [snip] >>> } >>> [snip] >>> } >>> >>> Your help is much appreciated, >>> >>> -- Howard. >>> >>> On 19 June 2010 21:00, R?mi Forax wrote: >>> >>> >>>> Le 19/06/2010 08:40, Howard Lovatt a ?crit : >>>> >>>> >>>>> @R?mi, >>>>> >>>>> Thanks for the advise about using a "slowPath" method to discover the >>>>> runtime types. I have coded up something along the lines you >>>>> suggested: >>>>> >>>>> private static double slowPath( final CallSite callSite, final >>>>> CostCalculator cC, final Item i ) throws Throwable { >>>>> System.out.println("callSite = " + callSite + ", CostCalculator = >>>>> " + cC + ", i = " + i ); >>>>> final MethodHandle nearest = Dispatchers.nearest( mhs.values(), >>>>> double.class, cC, i ); >>>>> System.out.println( "nearest = " + Dispatchers.toString( nearest ) >>>>> ); >>>>> final MethodHandle converted = MethodHandles.collectArguments( >>>>> nearest, callSite.getTarget().type() ); >>>>> System.out.println( "converted = " + Dispatchers.toString( converted >>>>> ) >>>>> ); >>>>> callSite.setTarget( converted ); >>>>> return converted.invokeExact( cC, i ); >>>>> } >>>>> >>>>> When run I get the following: >>>>> >>>>> callSite = CallSite#29596205[from invokedynamicmultipledispatch.Cost : >>>>> >>>>> >>>>> (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double >>>>> => slowPath], CostCalculator = >>>>> invokedynamicmultipledispatch.Price at bf2d5e, i = >>>>> [Ljava.lang.Object;@13bad12 >>>>> Exception in thread "main" >>>>> invokedynamicmultipledispatch.MultipleDispatchException >>>>> at invokedynamicmultipledispatch.Cost.cost(Cost.java:62) >>>>> at invokedynamicmultipledispatch.Cost.main(Cost.java:51) >>>>> Caused by: invokedynamicmultipledispatch.MultipleDispatchException: >>>>> Cannot find type, >>>>> (invokedynamicmultipledispatch.Price,java.lang.Object[])double, >>>>> compatible method in, >>>>> >>>>> >>>>> [cost(invokedynamicmultipledispatch.Postage,invokedynamicmultipledispatch.CD)double, >>>>> >>>>> >>>>> cost(invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double, >>>>> >>>>> >>>>> cost(invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.Book)double, >>>>> >>>>> >>>>> cost(invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.CD)double, >>>>> >>>>> >>>>> cost(invokedynamicmultipledispatch.Postage,invokedynamicmultipledispatch.Book)double] >>>>> at >>>>> invokedynamicmultipledispatch.Dispatchers.nearest(Dispatchers.java:182) >>>>> at >>>>> invokedynamicmultipledispatch.Dispatchers.nearest(Dispatchers.java:145) >>>>> at >>>>> >>>>> invokedynamicmultipledispatch.CostCalculatorDispatcher.slowPath(CostCalculatorDispatcher.java:35) >>>>> at sun.dyn.FromGeneric$A2.invoke_D2(FromGeneric.java:534) >>>>> at sun.dyn.FilterGeneric$F2.invoke_C1(FilterGeneric.java:550) >>>>> at sun.dyn.ToGeneric$A2.target(ToGeneric.java:661) >>>>> at sun.dyn.ToGeneric$A2.targetA2(ToGeneric.java:662) >>>>> at sun.dyn.ToGeneric$A2.invoke_D(ToGeneric.java:671) >>>>> at invokedynamicmultipledispatch.Cost.cost(Cost.java:60) >>>>> ... 1 more >>>>> >>>>> The interesting bit is "i = [Ljava.lang.Object;@13bad12" on the first >>>>> line of the printout (ignoring wrapping). This Object[] contains 1 >>>>> element, the expected Item. What is not expected is wrapping this in >>>>> an array. Also this is a type unsafe at runtime since an array is >>>>> passed into a method in a position where an Item is coded. >>>>> >>>>> Any idea what is going on? >>>>> >>>>> -- Howard. >>>>> >>>>> >>>>> >>>> And what is the code of the bootstrap method ? >>>> >>>> R?mi >>>> >>>> >>>> >>> >>> >>> >> >> > > > From john.r.rose at oracle.com Tue Jun 22 13:32:35 2010 From: john.r.rose at oracle.com (John Rose) Date: Tue, 22 Jun 2010 13:32:35 -0700 Subject: Latest Thinking In-Reply-To: <4C20ACF8.1010701@univ-mlv.fr> References: <4C20ACF8.1010701@univ-mlv.fr> Message-ID: On Jun 22, 2010, at 5:30 AM, R?mi Forax wrote: > Le 22/06/2010 12:48, Howard Lovatt a ?crit : >> A couple of comments on the current MethodHandle API: >> >> 1. Having only one bootstrap method for InvokeDynamic is a bit >> limiting, it it possible to have one per use site? >> > > It's an open issue, we're working on it. I'm prototyping an option for this, this week. We'll see what the EG comes up with. The most compelling use case is code weaving. >> 2. Has thought been given to using the .( args ) notation (or what >> ever it ends up as) from lambda dev for invokeGeneric( args )? >> > > My opinion is that the lambda spec has to mature a little bit > before looking at this kind of things. > Currently, the lambda super type is not MethodHandle but Object I hope we can closely converge the lambda and method handle designs, even though they live at different levels of the stack. For now, let's listen closely to what the lambda folks need and see how to get it to them without mixing levels too much. >> 3. Are there plans to add MethodHandle literals, e.g. Class#method( types )? >> > The mlvm workspace already contains method handle literals :) The back-end support (hotspot, jdk) for this will be pushed RSN into a real JDK7 build. But there's no javac support, other than as a prototype in the mlvm patch repo. This is because 292 is mostly about bytecodes supporting languages, not languages per se. The small amount of support in javac for 292 is a low-level punch-through to allow assembly-level programming. First class support for MHs at the language level would require a type system, syntaxes, binary compatibility rules, and more: This is the sort of thing the lambda people have to explore first. >> 4. Assuming 3 above; are there plans for a binding literal, e.g. >> MethodHandle addA = String#concat( String, "A" )? > > As far as I know, No. > I don't think it worth the introduction of a new syntax > > MethodHandle addA = insertArguments(String#concat( String, String ), 1, "A"); The prototype in mlvm supports the very special (but common) case of receiver binding: String#concat(String) vs. "foo"#concat(String). They are MHs of arity 1 and 2, respectively. But the lambda project will drive creation of such things, not 292. > Morever, your proposed syntax has a bad property. > It allow type and expression to occur at the same place. > >> I am sure these items have been already discussed in the expert group, >> just wondering what the latest thinking is. The 292 expert group has enough to worry about without also getting into language design wars. Just keeping up with lambda-dev is probably a full-time job. -- John From john.r.rose at oracle.com Tue Jun 22 13:46:39 2010 From: john.r.rose at oracle.com (John Rose) Date: Tue, 22 Jun 2010 13:46:39 -0700 Subject: Latest Thinking In-Reply-To: References: <4C20ACF8.1010701@univ-mlv.fr> Message-ID: <3784040A-84FF-4AD3-B28D-69B744D1C3E0@oracle.com> On Jun 22, 2010, at 1:32 PM, John Rose wrote: > The small amount of support in javac for 292 is a low-level punch-through to allow assembly-level programming. A little more detail: Here's the sort of thing I'm experimenting with, for local BSMs on invokedynamic: Object x = InvokeDynamic. <@BootstrapMethod(value=MyLinker.class, name="myBootstrap") Object> greet(1,"two"); Observations: 1. Yes, it's ugly, and by design. It's a moral approximate to an asm statement. 2. The optional BSM data is injected via a JSR 308 type-use annotation, in the only possible place. 3. The @BootstrapMethod annotation can also go on larger program elements, providing a default for all enclosed indy. 4. With this design, we can probably get rid of registerBootstrapMethod, and use a purely declarative BSM encoding. 5. I would of course have preferred to do @BootstrapMethod(MyLinker#myBootstrap), except it's too disturbing to too many layers of the stack, for little benefit. (As I found out when I started prototyping.) It would be nice if the 309 EG decided to put MH literal values into the annotation schema, but if you look at their design docs, you'll see that they don't want to bite off any more design chunks that large. It will have to be a future. A note on encoding: The BSM data is encoded in new constant pool entries, linked from the instruction. Despite the extra zero bytes in the instruction format, the EG does not want to "cleverly" put two indexes into one instruction. Instead, we have something like a Methodref, but with the BSM taking the class of the class reference. -- John From forax at univ-mlv.fr Tue Jun 22 14:25:52 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Tue, 22 Jun 2010 23:25:52 +0200 Subject: Latest Thinking In-Reply-To: <3784040A-84FF-4AD3-B28D-69B744D1C3E0@oracle.com> References: <4C20ACF8.1010701@univ-mlv.fr> <3784040A-84FF-4AD3-B28D-69B744D1C3E0@oracle.com> Message-ID: <4C212A60.5030408@univ-mlv.fr> Le 22/06/2010 22:46, John Rose a ?crit : > On Jun 22, 2010, at 1:32 PM, John Rose wrote: > > >> The small amount of support in javac for 292 is a low-level punch-through to allow assembly-level programming. >> > A little more detail: Here's the sort of thing I'm experimenting with, for local BSMs on invokedynamic: > > Object x = InvokeDynamic.<@BootstrapMethod(value=MyLinker.class, name="myBootstrap") Object> greet(1,"two"); > > Observations: > > 1. Yes, it's ugly, and by design. It's a moral approximate to an asm statement. > > 2. The optional BSM data is injected via a JSR 308 type-use annotation, in the only possible place. > > 3. The @BootstrapMethod annotation can also go on larger program elements, providing a default for all enclosed indy. > > 4. With this design, we can probably get rid of registerBootstrapMethod, and use a purely declarative BSM encoding. > > 5. I would of course have preferred to do @BootstrapMethod(MyLinker#myBootstrap), except it's too disturbing to too many layers of the stack, for little benefit. (As I found out when I started prototyping.) It would be nice if the 309 EG decided to put MH literal values into the annotation schema, but if you look at their design docs, you'll see that they don't want to bite off any more design chunks that large. It will have to be a future. > > A note on encoding: The BSM data is encoded in new constant pool entries, linked from the instruction. Despite the extra zero bytes in the instruction format, the EG does not want to "cleverly" put two indexes into one instruction. Instead, we have something like a Methodref, but with the BSM taking the class of the class reference. > There is another possible design. Allow users to create fake types like java.dyn.Invokedynamic and define the annotation on that type. Example: @BootstrapMethod(value=MyLinker.class, name="myBootstrap") class MyInvokeDynamic { } ... MyInvokeDynamic.greet(1, "two"); > -- John > R?mi From john.r.rose at oracle.com Tue Jun 22 14:29:38 2010 From: john.r.rose at oracle.com (John Rose) Date: Tue, 22 Jun 2010 14:29:38 -0700 Subject: Latest Thinking In-Reply-To: <4C212A60.5030408@univ-mlv.fr> References: <4C20ACF8.1010701@univ-mlv.fr> <3784040A-84FF-4AD3-B28D-69B744D1C3E0@oracle.com> <4C212A60.5030408@univ-mlv.fr> Message-ID: On Jun 22, 2010, at 2:25 PM, R?mi Forax wrote: > There is another possible design. > Allow users to create fake types like java.dyn.Invokedynamic > and define the annotation on that type. I'd rather not let the magic signature polymorphism escape beyond the current set of names (InvokeDynamic and two methods of MethodHandle). It pulls an "innocent" name into a dark corner of the language. Also, putting an optional annotation on each call site is more flexible. I wish we had expression annotations... -- John From forax at univ-mlv.fr Tue Jun 22 15:33:53 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Wed, 23 Jun 2010 00:33:53 +0200 Subject: Latest Thinking In-Reply-To: References: <4C20ACF8.1010701@univ-mlv.fr> <3784040A-84FF-4AD3-B28D-69B744D1C3E0@oracle.com> <4C212A60.5030408@univ-mlv.fr> Message-ID: <4C213A51.5030205@univ-mlv.fr> Le 22/06/2010 23:29, John Rose a ?crit : > On Jun 22, 2010, at 2:25 PM, R?mi Forax wrote: > > >> There is another possible design. >> Allow users to create fake types like java.dyn.Invokedynamic >> and define the annotation on that type. >> > I'd rather not let the magic signature polymorphism escape beyond the current set of names (InvokeDynamic and two methods of MethodHandle). It pulls an "innocent" name into a dark corner of the language. > As you said before, the use cases are weaving, AOP or interceptor, basically a way to specify a protocol. virtual method is such kind of protocol, in Java or in C#, you don't specify it at each call sites. In Java, this is enable by default, in C# you add an annotation (the override keyword) at callee site. If you specify a protocol only a each call sites, you don't offer one common place to document that protocol. > Also, putting an optional annotation on each call site is more flexible. > perhaps but I think it doesn't fit with the use cases. In general, you will have few bootstrap methods, each one corresponding to a specific protocol. And you will have lot of more call sites using these few protocols. Encoding BSM at each callsite means a lot of information duplication. And we all know that kind of boilerplate code is error prone. Remember that currently, you specify the BSM name using a String ! Another to say the same thing, I don't see how to do refactoring of the corresponding all callsites if the name of one BSM change. > I wish we had expression annotations... > > -- John > R?mi From howard.lovatt at gmail.com Tue Jun 22 16:24:54 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Wed, 23 Jun 2010 09:24:54 +1000 Subject: Latest Thinking Message-ID: R?mi Forax forax at univ-mlv.fr Tue Jun 22 05:30:48 PDT 2010 wrote: > Le 22/06/2010 12:48, Howard Lovatt a ?crit : >> A couple of comments on the current MethodHandle API: >> >> 1. Having only one bootstrap method for InvokeDynamic is a bit >> limiting, it it possible to have one per use site? >> > > It's an open issue, we're working on it. With multiple dispatch the problem is that you can have more than one multiple dispatch per class, hence one bootstrap is limiting. Defining an instance of InvokeDynamic might work, e.g. using my cost multiple dispatch example: private static final InvokeDynamic costDistpatch = new InvokeDynamic( double.class, callerClass.class, bootstrapHandle ); // note return type, double, encoded ... cost += costDistpatch.invoke( costCalculator, item ); // no need for method name since we have unique InvokeDynamic instance >> 2. Has thought been given to using the .( args ) notation (or what >> ever it ends up as) from lambda dev for invokeGeneric( args )? >> > > My opinion is that the lambda spec has to mature a little bit > before looking at this kind of things. > Currently, the lambda super type is not MethodHandle but Object Yes, if lamda-dev uses MethodHandle, which seems likely, it would be nice to unify them to the extent that a lambda 'is a' MethodHandle. >> 3. Are there plans to add MethodHandle literals, e.g. Class#method( types )? >> > > The mlvm workspace already contains method handle literals :) Good to see >> 4. Assuming 3 above; are there plans for a binding literal, e.g. >> MethodHandle addA = String#concat( String, "A" )? > > As far as I know, No. > I don't think it worth the introduction of a new syntax > > MethodHandle addA = insertArguments(String#concat( String, String ), 1, "A"); > > > Morever, your proposed syntax has a bad property. > It allow type and expression to occur at the same place. As John has pointed out in this thread it does exist for binding 'this'. An extension to all arguments would be useful, because like the method literal it would be compiler, rather than runtime, checked. I don't think there is confusion between a type name and a value, therefore proposed syntax OK (but maybe not the preferred). If you want a class you have to append '.class'. > I am sure these items have been already discussed in the expert group, > just wondering what the latest thinking is. > > -- Howard. > cheers, R?mi -- -- Howard. From john.r.rose at oracle.com Tue Jun 22 17:17:44 2010 From: john.r.rose at oracle.com (John Rose) Date: Tue, 22 Jun 2010 17:17:44 -0700 Subject: Latest Thinking In-Reply-To: References: Message-ID: On Jun 22, 2010, at 4:24 PM, Howard Lovatt wrote: > I don't think there is confusion between a type name and a value, > therefore proposed syntax OK (but maybe not the preferred). If you > want a class you have to append '.class'. Sorry, that would be a breaking change to the language, not an extension. The rules for identifier resolution are exquisitely balanced, and cannot be compatibly extended in this way. // $ javac Foo.java && java Foo // String! and String2! class Foo { public static void main(String... args) { String String = "String!"; String String2 = "String2!"; System.out.println(String + (String)" and "+ String2); } } -- John -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20100622/86ed3471/attachment.html From john.r.rose at oracle.com Wed Jun 23 16:52:34 2010 From: john.r.rose at oracle.com (John Rose) Date: Wed, 23 Jun 2010 16:52:34 -0700 Subject: Latest Thinking In-Reply-To: <4C213A51.5030205@univ-mlv.fr> References: <4C20ACF8.1010701@univ-mlv.fr> <3784040A-84FF-4AD3-B28D-69B744D1C3E0@oracle.com> <4C212A60.5030408@univ-mlv.fr> <4C213A51.5030205@univ-mlv.fr> Message-ID: On Jun 22, 2010, at 3:33 PM, R?mi Forax wrote: > Another to say the same thing, I don't see how to do refactoring > of the corresponding all callsites if the name of one BSM change. Yes, I see that. Well, there must be other ways to do that without sharing the magic of InvokeDynamic. Perhaps allow user-defined annotations instead of @BootstrapMethod. There is no annotation inheritance which would allow us to use a subclassing pattern, but there are meta-annotations: @BootstrapProtocolAnnotation(<
>) @interface MyBootstrapProtocol { <> } ... InvokeDynamic.<@MyBootstrapProtocol Object> foo(bar) This introduces the level of named indirection you want, without entangling InvokeDynamic itself. What would the details look like? BTW, here's part of the puzzle: JSR 308 (nb. not 309 if that's what I said earlier) mandates that all non-source type annotations go into a complicated, hard-to-use table in a classfile attribute. I don't want to rely on that, if possible. Annotations that affect the construction of indy sites are going to have the "SOURCE" retention policy, so they don't go two places at once. (Would there be a sensible default java.dyn.BootstrapProtocol?) My draft of @BootstrapProtocol looks like this: @Target({ElementType.TYPE_USE, // For defaulting every indy site within a program element; cf. @SuppressWarnings: TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, TYPE_PARAMETER}) @Retention(RetentionPolicy.SOURCE) public @interface BootstrapMethod { Class value(); String name() default "bootstrapInvokeDynamic"; } -- John From howard.lovatt at gmail.com Wed Jun 23 20:27:23 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Thu, 24 Jun 2010 13:27:23 +1000 Subject: Latest Thinking Message-ID: Can't you just qualify the name, e.g.: class Main { static String String(String String) { return String; } public static void main(String... notUsed) throws Throwable { String String = "String!"; // MethodHandle variable = MethodHandles.insertArguments( // MethodHandles.lookup().findStatic( // Main.class, // "String", // MethodType.methodType(String.class, String.class)), // 0, // String); MethodHandle variable = #String(String); System.out.println("variable.() = " + variable.invokeGeneric()); // MethodHandle type = MethodHandles.lookup().findStatic( // Main.class, // "String", // MethodType.methodType(String.class, String.class)); MethodHandle variable = #String(java.lang.String); System.out.println("type.( String ) = " + type.invokeGeneric(String)); } } Isn't this already covered in JLS 6.5.2? -- Howard. John Rose john.r.rose at oracle.com Tue Jun 22 17:17:44 PDT 2010 wrote: > On Jun 22, 2010, at 4:24 PM, Howard Lovatt wrote: > > > I don't think there is confusion between a type name and a value, > > therefore proposed syntax OK (but maybe not the preferred). If you > > want a class you have to append '.class'. > > Sorry, that would be a breaking change to the language, not an extension. The rules for identifier resolution are exquisitely balanced, and cannot be compatibly extended in this way. > > // $ javac Foo.java && java Foo > // String! and String2! > class Foo { > public static void main(String... args) { > String String = "String!"; > String String2 = "String2!"; > System.out.println(String + (String)" and "+ String2); > } > } From john.r.rose at oracle.com Thu Jun 24 00:28:38 2010 From: john.r.rose at oracle.com (John Rose) Date: Thu, 24 Jun 2010 00:28:38 -0700 Subject: Latest Thinking In-Reply-To: References: Message-ID: <3BED2E1B-0090-4375-86BD-9C6E96DBD40B@oracle.com> On Jun 23, 2010, at 8:27 PM, Howard Lovatt wrote: > Can't you just qualify the name The same observation applies to 'java' in 'java.lang.String' as to unqualified 'String'. The point is that identifiers have context-sensitive meanings in Java. Expression contexts have different resolution rules from type contexts, which means type names aren't compatible with expression contexts. The JLS documents this fully in the section on names, and is worth reading carefully when pondering language puzzles like this. It is true that previously-undefined names could in principle be given new meanings without breaking old programs, but this is a dangerous design tactic given wildcard imports and inheritance, which can bring names into scope suddenly due to non-local API changes. Java will never be a single-namespace language. Try Scala or Scheme! -- John From howard.lovatt at gmail.com Thu Jun 24 01:45:06 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Thu, 24 Jun 2010 18:45:06 +1000 Subject: Latest Thinking Message-ID: Yes you can hide a type name, but you can do that at present - therefore no change. My reading of JLS 6.5 is that what I am proposing is fine, it will simply resolve to the variable if their is ambiguity. What I was saying was that if you have hidden the type name then you can qualify it. What I didn't add is that you might also have hidden the qualifier, but hiding the qualifier is already a problem and therefore no different than currently (and the problem, hiding the type name and the qualifier simultaneously, to the best of my knowledge, doesn't occur in practice). Here is a current example of hiding the qualifier and using a qualifier name in the same position as a variable name (the two print lines are identical, the first refers to a type and the second a variable): public class Bar { static class integer { static String toString(int i) { return java.lang.Integer.toString(i + 1); } } static class Lang { static integer Integer = new integer(); } static class Java { static Lang lang = new Lang(); } public static void main(String... notUsed) throws Throwable { System.out.println("java.lang.Integer.toString(1) = " + java.lang.Integer.toString(1)); Java java = new Java(); System.out.println("java.lang.Integer.toString(1) = " + java.lang.Integer.toString(1)); } } Which prints: java.lang.Integer.toString(1) = 1 java.lang.Integer.toString(1) = 2 -- Howard. PS Yes a single namespace would be nice (Newspeak's solution is particularly good). John Rose john.r.rose at oracle.com Thu Jun 24 00:28:38 PDT 2010 wrote: > On Jun 23, 2010, at 8:27 PM, Howard Lovatt wrote: > >> Can't you just qualify the name > > The same observation applies to 'java' in 'java.lang.String' as to unqualified 'String'. The point is that identifiers have context-sensitive meanings in Java. > > Expression contexts have different resolution rules from type contexts, which means type names aren't compatible with expression contexts. > > The JLS documents this fully in the section on names, and is worth reading carefully when pondering language puzzles like this. > > It is true that previously-undefined names could in principle be given new meanings without breaking old programs, but this is a dangerous design tactic > given wildcard imports and inheritance, which can bring names into scope suddenly due to non-local API changes. > > Java will never be a single-namespace language. Try Scala or Scheme! > > -- John From john.r.rose at oracle.com Tue Jun 29 00:55:28 2010 From: john.r.rose at oracle.com (john.r.rose at oracle.com) Date: Tue, 29 Jun 2010 07:55:28 +0000 Subject: hg: mlvm/mlvm/hotspot: indy-bsm: initial implementation of per-instruction BSMs Message-ID: <20100629075529.0D46D475FB@hg.openjdk.java.net> Changeset: b2110191649b Author: jrose Date: 2010-06-29 00:55 -0700 URL: http://hg.openjdk.java.net/mlvm/mlvm/hotspot/rev/b2110191649b indy-bsm: initial implementation of per-instruction BSMs + indy-bsm-6964498.patch ! series From y.s.ramakrishna at oracle.com Tue Jun 29 00:56:40 2010 From: y.s.ramakrishna at oracle.com (y.s.ramakrishna at oracle.com) Date: Tue, 29 Jun 2010 00:56:40 -0700 (PDT) Subject: Auto Reply: hg: mlvm/mlvm/hotspot: indy-bsm: initial implementation of per-instruction BSMs Message-ID: <0784c39c-9e5f-4914-9e55-1b0499b490dc@default> This is an automatic response. I am on vacation, and not generally not reading email, from 6/25 through 7/4/2010. For urgent matters please contact my manager David Cox. From y.s.ramakrishna at oracle.com Tue Jun 29 00:59:04 2010 From: y.s.ramakrishna at oracle.com (y.s.ramakrishna at oracle.com) Date: Tue, 29 Jun 2010 00:59:04 -0700 (PDT) Subject: Auto Reply: Auto Reply: hg: mlvm/mlvm/hotspot: indy-bsm: initial implementation of per-instruction BSMs Message-ID: <865fe474-6dff-4103-94ee-acfc89b585e3@default> This is an automatic response. I am on vacation, and not generally not reading email, from 6/25 through 7/4/2010. For urgent matters please contact my manager David Cox. From john.r.rose at oracle.com Tue Jun 29 18:57:27 2010 From: john.r.rose at oracle.com (john.r.rose at oracle.com) Date: Wed, 30 Jun 2010 01:57:27 +0000 Subject: hg: mlvm/mlvm/langtools: meth: patch for javac/jdk version skew, if needed Message-ID: <20100630015727.BE03C47635@hg.openjdk.java.net> Changeset: d5f083ee4032 Author: jrose Date: 2010-06-29 18:57 -0700 URL: http://hg.openjdk.java.net/mlvm/mlvm/langtools/rev/d5f083ee4032 meth: patch for javac/jdk version skew, if needed + meth-edrfix.patch ! series