From enevill at arm.com Fri Jul 3 01:50:14 2009 From: enevill at arm.com (Edward Nevill) Date: Fri, 3 Jul 2009 09:50:14 +0100 Subject: Infelicity in OpenJDK Message-ID: <000601c9fbbb$4858e010$d90aa030$@com> There is a potential insecurity in native_entry() in cppInterpreter_zero.cpp It does void **arguments; { ... void **dst = arguments; ... void *mirror = NULL; if (method->is_static()) { ... *(dst++) = &mirror; // ECN: Address of mirror stored in argument list here } ... } // ECN: Now follows more code which processes the argument list // however, 'mirror' is no longer in scope so the address is potentially invalid. What needs to happen is the definition of 'mirror' needs to be moved up to the same scope as 'arguments'. Regards, Ed. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/zero-dev/attachments/20090703/d68b9a80/attachment.html From gbenson at redhat.com Fri Jul 3 12:32:33 2009 From: gbenson at redhat.com (Gary Benson) Date: Fri, 3 Jul 2009 20:32:33 +0100 Subject: Infelicity in OpenJDK In-Reply-To: <000601c9fbbb$4858e010$d90aa030$@com> References: <000601c9fbbb$4858e010$d90aa030$@com> Message-ID: <20090703193233.GA20546@redhat.com> Hi Ed, Good catch, I'll get a fix committed on Monday or Tuesday when I'm back in. Cheers, Gary Edward Nevill wrote: > There is a potential insecurity in native_entry() in cppInterpreter_zero.cpp > > It does > void **arguments; > { > ... > void **dst = arguments; > ... > > void *mirror = NULL; > if (method->is_static()) { > ... > *(dst++) = &mirror; > // ECN: Address of mirror stored in argument list here > } > ... > > } > > // ECN: Now follows more code which processes the argument list > // however, 'mirror' is no longer in scope so the address is > // potentially invalid. > > What needs to happen is the definition of 'mirror' needs to be moved > up to the same scope as 'arguments'. > > Regards, > Ed. -- http://gbenson.net/ From xerxes at zafena.se Fri Jul 3 17:34:04 2009 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Sat, 04 Jul 2009 02:34:04 +0200 Subject: RFC: shark + llvm2.6svn LLVMContext api change Message-ID: <4A4EA37C.2000309@zafena.se> LLVM 2.6svn trunk now require the passing of a LLVMContext while creating a LLVM Module in order for LLVM clients to use the LLVM JIT multithreaded. [1] Fortunate for us LLVM have also provided a new backward compatible API, by using getGlobalContext() a LLVMContext are returned that can be used by current singlethreaded compiler clients to quickly fullfill this change. [2] I have added some comments to help future shark hackers find what needs to change if someone wants to make the shark compiler multi-threaded. I have tested this patch using llvm r74781 and icedtea6 http://icedtea.classpath.org/hg/icedtea6/rev/308c172cd230 on ia32 / F11 [1] http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-June/023505.html - [LLVMdev] MAJOR API CHANGE: LLVMContext [2] http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-June/023507.html Cheers Xerxes -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: 4jun_shark_llvm2.6svn_LLVMContext.patch Url: http://mail.openjdk.java.net/pipermail/zero-dev/attachments/20090704/658827d6/attachment.ksh From gbenson at redhat.com Tue Jul 7 01:38:02 2009 From: gbenson at redhat.com (Gary Benson) Date: Tue, 7 Jul 2009 09:38:02 +0100 Subject: RFC: shark + llvm2.6svn LLVMContext api change In-Reply-To: <4A4EA37C.2000309@zafena.se> References: <4A4EA37C.2000309@zafena.se> Message-ID: <20090707083801.GA3224@redhat.com> Please commit this, it's better than the solution I made :) Cheers, Gary Xerxes R?nby wrote: > LLVM 2.6svn trunk now require the passing of a LLVMContext while > creating a LLVM Module in order for LLVM clients to use the LLVM JIT > multithreaded. [1] > Fortunate for us LLVM have also provided a new backward compatible API, > by using getGlobalContext() a LLVMContext are returned that can be used > by current singlethreaded compiler clients to quickly fullfill this > change. [2] > > I have added some comments to help future shark hackers find what needs > to change if someone wants to make the shark compiler multi-threaded. > > I have tested this patch using llvm r74781 and icedtea6 > http://icedtea.classpath.org/hg/icedtea6/rev/308c172cd230 on ia32 / F11 > > [1] http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-June/023505.html - > [LLVMdev] MAJOR API CHANGE: LLVMContext > [2] http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-June/023507.html > > Cheers > Xerxes > > > > Index: icedtea6/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp > =================================================================== > --- icedtea6.orig/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp > +++ icedtea6/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp > @@ -43,7 +43,15 @@ SharkCompiler::SharkCompiler() > #endif > > // Create a module to build our functions into > +#if SHARK_LLVM_VERSION >= 26 > + // LLVM 2.6 and later requires passing a LLVMContext during module > + // creation. The LLVM API getGlobalContext() returns a LLVMContext that > + // can be used safely as long as the shark compiler stays single threaded > + // and only uses one module. > + _module = new Module("shark", getGlobalContext()); > +#else > _module = new Module("shark"); > +#endif > > // Create the builder to build our functions > _builder = new SharkBuilder(this); > Index: icedtea6/ports/hotspot/src/share/vm/shark/llvmHeaders.hpp > =================================================================== > --- icedtea6.orig/ports/hotspot/src/share/vm/shark/llvmHeaders.hpp > +++ icedtea6/ports/hotspot/src/share/vm/shark/llvmHeaders.hpp > @@ -32,6 +32,9 @@ > #include > #include > #include > +#if SHARK_LLVM_VERSION >= 26 > +#include > +#endif > #include > #include > #include -- http://gbenson.net/ From xerxes at zafena.se Wed Jul 8 02:09:57 2009 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Wed, 08 Jul 2009 11:09:57 +0200 Subject: RFC: GlobalVariable shark + llvm2.6svn LLVMContext api change Message-ID: <4A546265.4040206@zafena.se> Similar to yesterdays llvm2.6svn api change patch, today the llvm GlobalVariable constructor got LLVMContextifyed and shark needs patching accordingly. Cheers Xerxes -------------- next part -------------- A non-text attachment was scrubbed... Name: LLVMContext_sharkBuilder_GlobalVariable.patch Type: text/x-patch Size: 1838 bytes Desc: not available Url : http://mail.openjdk.java.net/pipermail/zero-dev/attachments/20090708/6a7bc457/attachment.bin From gbenson at redhat.com Wed Jul 8 02:15:43 2009 From: gbenson at redhat.com (Gary Benson) Date: Wed, 8 Jul 2009 10:15:43 +0100 Subject: RFC: GlobalVariable shark + llvm2.6svn LLVMContext api change In-Reply-To: <4A546265.4040206@zafena.se> References: <4A546265.4040206@zafena.se> Message-ID: <20090708091542.GB3236@redhat.com> Hi Xerxes, Please commit this. Cheers, Gary Xerxes R?nby wrote: > Similar to yesterdays llvm2.6svn api change patch, today the llvm > GlobalVariable constructor got LLVMContextifyed and shark needs patching > accordingly. > > Cheers > Xerxes > Index: icedtea6/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp > =================================================================== > --- icedtea6.orig/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp 2009-07-08 10:31:09.000000000 +0200 > +++ icedtea6/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp 2009-07-08 10:44:05.000000000 +0200 > @@ -174,7 +174,14 @@ > char name[128]; > snprintf(name, sizeof name - 1, "pointer_constant_%p", ptr); > > - GlobalVariable *value = new GlobalVariable(SharkType::intptr_type(), > + GlobalVariable *value = new GlobalVariable( > +#if SHARK_LLVM_VERSION >= 26 > + // LLVM 2.6 requires a LLVMContext during GlobalVariable construction. > + // getGlobalConext() returns one that can be used as long as the shark > + // compiler are single-threaded. > + getGlobalContext(), > +#endif > + SharkType::intptr_type(), > false, GlobalValue::ExternalLinkage, > NULL, name, module()); > execution_engine()->addGlobalMapping(value, const_cast(ptr)); > Index: icedtea6/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp > =================================================================== > --- icedtea6.orig/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp 2009-07-08 10:43:34.000000000 +0200 > +++ icedtea6/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp 2009-07-08 10:44:43.000000000 +0200 > @@ -187,6 +187,12 @@ > Value *name = CreatePtrToInt( > CreateStructGEP( > new GlobalVariable( > +#if SHARK_LLVM_VERSION >= 26 > + // LLVM 2.6 requires a LLVMContext during GlobalVariable construction. > + // getGlobalConext() returns one that can be used as long as the shark > + // compiler are single-threaded. > + getGlobalContext(), > +#endif > const_name->getType(), > true, GlobalValue::InternalLinkage, > const_name, "dump", module()), -- http://gbenson.net/ From ed at camswl.com Wed Jul 8 07:42:16 2009 From: ed at camswl.com (Edward Nevill) Date: Wed, 8 Jul 2009 15:42:16 +0100 Subject: Optimisation work on Zero/ARM Message-ID: <200907081442.n68EgGjd017487@parsley.camswl.com> Hi All, I have been fairly quiet on this list for the past few months but I have been beavering away optimising Zero for ARM. I have put together a website describing the optimisation work I have done. (http://camswl.com/openjdk). Some highlights: 3.7 X improvement on ECM 4.8 X improvement on EEMBC Between 2.6 X improvement and 3.3X improvement opening a document in Think Free Office The VM uses some new technology called a 'Bytecode Interpreter Generator' which generates an interpreter which can peephole up to 4 bytecode in advance. See URL above for details. Binaries and sources are available on the website. The binaries should work on ARMV5TE or later platforms. I have tested it only on ARMV7 so any feedback regarding other platforms is particularly welcome. Regards, Ed. From xerxes at zafena.se Wed Jul 8 06:03:05 2009 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Wed, 08 Jul 2009 15:03:05 +0200 Subject: Optimisation work on Zero/ARM In-Reply-To: <200907081442.n68EgGjd017487@parsley.camswl.com> References: <200907081442.n68EgGjd017487@parsley.camswl.com> Message-ID: <4A549909.9080202@zafena.se> Greetings Ed! I quickly tested to run your compiled binaries on a ARMV5TE Sheeva-plugcomputer running Ubuntu Jaunty and it worked as expected! Gave me instantly a 3.3 X improvement on the jython test in the dacapo benchmark. http://www.dacapo-bench.org/ I am thrilled to try combine your work with the LLVM based Shark JIT. I peeked at the sourcecode and it looks great! Your changes are most portable for inclusion into Icedtea6/OpenJDK since they are already contained in separate patches against the Icedtea6 tree from 23 june 2009 in the debian/patches directory, fantastic. Have a great week! Cheers Xerxes Edward Nevill skrev: > Hi All, > > I have been fairly quiet on this list for the past few months but I have been > beavering away optimising Zero for ARM. > > I have put together a website describing the optimisation work I have done. > (http://camswl.com/openjdk). > > Some highlights: > > 3.7 X improvement on ECM > 4.8 X improvement on EEMBC > Between 2.6 X improvement and 3.3X improvement opening a document in Think Free Office > > The VM uses some new technology called a 'Bytecode Interpreter Generator' which > generates an interpreter which can peephole up to 4 bytecode in advance. See URL > above for details. > > Binaries and sources are available on the website. > > The binaries should work on ARMV5TE or later platforms. I have tested it only on > ARMV7 so any feedback regarding other platforms is particularly welcome. > > Regards, > Ed. > From camswl at camswl.com Wed Jul 8 07:29:56 2009 From: camswl at camswl.com (Cambridge Software Labs) Date: Wed, 8 Jul 2009 15:29:56 +0100 Subject: Optimisation work on Zero for ARM Message-ID: <200907081429.n68ETuMu017381@parsley.camswl.com> Hi All, I have been fairly quiet on this list for the past few months but I have been beavering away optimising Zero for ARM. I have put together a website describing the optimisation work I have done (http://camswl.com/openjdk). The optimisation includes a new 'Bytecode Interpreter Generator', which can peephole up to 4 bytecodes in advance. Some highlights: 3.7 X improvement on ECM 4.8 X improvement on EEMBC Between 2.6 X and 3.3 X improvment opening a blank document in ThinkFree Office. (2.6 X Word, 2.8 X XCel, 3.3 X PPT). Binaries and source are available from the above link. I am working on checking them into Ubuntu 9.10 (karmic) and hope to push the work back into IcedTea and OpenJDK. The binaries should work on any ARMV5TE or later platform. I have tested the binaries on ARMV7 only so any feedback relating to other platforms would be welcome. Regards, Ed From enevill at arm.com Wed Jul 8 09:44:10 2009 From: enevill at arm.com (Edward Nevill) Date: Wed, 8 Jul 2009 17:44:10 +0100 Subject: Optimisation work on Zero for ARM In-Reply-To: <200907081429.n68ETuMu017381@parsley.camswl.com> References: <200907081429.n68ETuMu017381@parsley.camswl.com> Message-ID: <000b01c9ffeb$51c3be70$f54b3b50$@com> Sorry about that post appearing twice. Gremlins at work. Ed. From Dalibor.Topic at Sun.COM Wed Jul 8 10:47:51 2009 From: Dalibor.Topic at Sun.COM (Dalibor Topic) Date: Wed, 08 Jul 2009 19:47:51 +0200 Subject: Optimisation work on Zero for ARM In-Reply-To: <000b01c9ffeb$51c3be70$f54b3b50$@com> References: <200907081429.n68ETuMu017381@parsley.camswl.com> <000b01c9ffeb$51c3be70$f54b3b50$@com> Message-ID: <4A54DBC7.1010801@sun.com> Edward Nevill wrote: > Sorry about that post appearing twice. Gremlins at work. Ed. > > > My bad. I didn't realize the other version had passed through already. :/ cheers, dalibor topic -- ******************************************************************* Dalibor Topic Tel: (+49 40) 23 646 738 Java F/OSS Ambassador AIM: robiladonaim Sun Microsystems GmbH Mobile: (+49 177) 2664 192 Nagelsweg 55 http://openjdk.java.net D-20097 Hamburg mailto:Dalibor.Topic at sun.com Sitz der Gesellschaft: Sonnenallee 1, D-85551 Kirchheim-Heimstetten Amtsgericht M?nchen: HRB 161028 Gesch?ftsf?hrer: Thomas Schr?der, Wolfgang Engels, Wolf Frenkel Vorsitzender des Aufsichtsrates: Martin H?ring From xerxes at zafena.se Thu Jul 9 03:15:23 2009 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Thu, 09 Jul 2009 12:15:23 +0200 Subject: RFC: IRBuilder shark + llvm2.6svn LLVMContext api change + shark mm Message-ID: <4A55C33B.2000003@zafena.se> This patch fixes the following build errors: /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/sharkBuilder.cpp: In constructor 'SharkBuilder::SharkBuilder(SharkCompiler*)': /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/sharkBuilder.cpp:65: error: no matching function for call to 'llvm::IRBuilder::IRBuilder()' /usr/local/include/llvm/Support/IRBuilder.h:56: note: candidates are: llvm::IRBuilder::IRBuilder(llvm::BasicBlock*, llvm::ilist_iterator, const T&) [with bool preserveNames = true, T = llvm::ConstantFolder] /usr/local/include/llvm/Support/IRBuilder.h:51: note: llvm::IRBuilder::IRBuilder(llvm::BasicBlock*, const T&) [with bool preserveNames = true, T = llvm::ConstantFolder] /usr/local/include/llvm/Support/IRBuilder.h:48: note: llvm::IRBuilder::IRBuilder(llvm::LLVMContext&, const T&) [with bool preserveNames = true, T = llvm::ConstantFolder] /usr/local/include/llvm/Support/IRBuilder.h:42: note: llvm::IRBuilder::IRBuilder(const llvm::IRBuilder&) make[7]: *** [sharkBuilder.o] Error 1 and /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/sharkCompiler.cpp: In constructor 'SharkCompiler::SharkCompiler()': /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/sharkCompiler.cpp:67: error: cannot allocate an object of abstract type 'SharkMemoryManager' /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/sharkMemoryManager.hpp:30: note: because the following virtual functions are pure within 'SharkMemoryManager': /usr/local/include/llvm/ExecutionEngine/JITMemoryManager.h:50: note: virtual void llvm::JITMemoryManager::setPoisonMemory(bool) /usr/local/include/llvm/ExecutionEngine/JITMemoryManager.h:125: note: virtual uint8_t* llvm::JITMemoryManager::allocateGlobal(uintptr_t, unsigned int) with this patch it builds fine but... I have had a bit trouble running shark using the latest llvm svn tip. r75126 got segfaults compiling string::indexOf on ia32 Cheers Xerxes -------------- next part -------------- A non-text attachment was scrubbed... Name: IRBuilder_LLVMContext.patch Type: text/x-patch Size: 2208 bytes Desc: not available Url : http://mail.openjdk.java.net/pipermail/zero-dev/attachments/20090709/eb9938b8/attachment.bin From gbenson at redhat.com Thu Jul 9 03:35:23 2009 From: gbenson at redhat.com (Gary Benson) Date: Thu, 9 Jul 2009 11:35:23 +0100 Subject: RFC: IRBuilder shark + llvm2.6svn LLVMContext api change + shark mm In-Reply-To: <4A55C33B.2000003@zafena.se> References: <4A55C33B.2000003@zafena.se> Message-ID: <20090709103522.GE3175@redhat.com> Commit away! Xerxes R?nby wrote: > This patch fixes the following build errors: > > /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/sharkBuilder.cpp: > In constructor 'SharkBuilder::SharkBuilder(SharkCompiler*)': > /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/sharkBuilder.cpp:65: > error: no matching function for call to 'llvm::IRBuilder llvm::ConstantFolder>::IRBuilder()' > /usr/local/include/llvm/Support/IRBuilder.h:56: note: candidates are: > llvm::IRBuilder::IRBuilder(llvm::BasicBlock*, > llvm::ilist_iterator, const T&) [with bool > preserveNames = true, T = llvm::ConstantFolder] > /usr/local/include/llvm/Support/IRBuilder.h:51: note: > llvm::IRBuilder::IRBuilder(llvm::BasicBlock*, const > T&) [with bool preserveNames = true, T = llvm::ConstantFolder] > /usr/local/include/llvm/Support/IRBuilder.h:48: note: > llvm::IRBuilder::IRBuilder(llvm::LLVMContext&, const > T&) [with bool preserveNames = true, T = llvm::ConstantFolder] > /usr/local/include/llvm/Support/IRBuilder.h:42: note: > llvm::IRBuilder::IRBuilder(const > llvm::IRBuilder&) > make[7]: *** [sharkBuilder.o] Error 1 > > and > > /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/sharkCompiler.cpp: > In constructor 'SharkCompiler::SharkCompiler()': > /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/sharkCompiler.cpp:67: > error: cannot allocate an object of abstract type 'SharkMemoryManager' > /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/sharkMemoryManager.hpp:30: > note: because the following virtual functions are pure within > 'SharkMemoryManager': > /usr/local/include/llvm/ExecutionEngine/JITMemoryManager.h:50: note: > virtual void llvm::JITMemoryManager::setPoisonMemory(bool) > /usr/local/include/llvm/ExecutionEngine/JITMemoryManager.h:125: note: > virtual uint8_t* llvm::JITMemoryManager::allocateGlobal(uintptr_t, > unsigned int) > > with this patch it builds fine but... > > I have had a bit trouble running shark using the latest llvm svn tip. r75126 > got segfaults compiling string::indexOf on ia32 > > Cheers > Xerxes > Index: icedtea6/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp > =================================================================== > --- icedtea6.orig/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp 2009-07-09 11:02:37.000000000 +0200 > +++ icedtea6/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp 2009-07-09 11:13:29.000000000 +0200 > @@ -61,7 +61,14 @@ > #endif > > SharkBuilder::SharkBuilder(SharkCompiler* compiler) > +#if SHARK_LLVM_VERSION >= 26 > + // LLVM 2.6 requires a LLVMContext during IRBuilder construction. > + // getGlobalConext() returns one that can be used as long as the shark > + // compiler are single-threaded. > + : IRBuilder<>(getGlobalContext()), > +#else > : IRBuilder<>(), > +#endif > _compiler(compiler) > { > init_external_functions(); > Index: icedtea6/ports/hotspot/src/share/vm/shark/sharkMemoryManager.cpp > =================================================================== > --- icedtea6.orig/ports/hotspot/src/share/vm/shark/sharkMemoryManager.cpp 2009-07-09 11:24:52.000000000 +0200 > +++ icedtea6/ports/hotspot/src/share/vm/shark/sharkMemoryManager.cpp 2009-07-09 11:32:14.000000000 +0200 > @@ -92,6 +92,11 @@ > } > > #if SHARK_LLVM_VERSION >= 26 > +uint8_t* SharkMemoryManager::allocateGlobal(uintptr_t Size, unsigned int Alignment) > +{ > + return mm()->allocateGlobal(Size, Alignment); > +} > + > void* SharkMemoryManager::getDlsymTable() const > { > return mm()->getDlsymTable(); > @@ -102,6 +107,11 @@ > mm()->SetDlsymTable(ptr); > } > > +void SharkMemoryManager::setPoisonMemory(bool poison) > +{ > + mm()->setPoisonMemory(poison); > +} > + > #endif > > #if SHARK_LLVM_VERSION >= 25 > Index: icedtea6/ports/hotspot/src/share/vm/shark/sharkMemoryManager.hpp > =================================================================== > --- icedtea6.orig/ports/hotspot/src/share/vm/shark/sharkMemoryManager.hpp 2009-07-09 11:14:47.000000000 +0200 > +++ icedtea6/ports/hotspot/src/share/vm/shark/sharkMemoryManager.hpp 2009-07-09 11:16:31.000000000 +0200 > @@ -74,6 +74,8 @@ > #if SHARK_LLVM_VERSION >= 26 > void* getDlsymTable() const; > void SetDlsymTable(void *ptr); > + void setPoisonMemory(bool); > + uint8_t* allocateGlobal(uintptr_t, unsigned int); > #endif > void setMemoryWritable(); > void setMemoryExecutable(); -- http://gbenson.net/ From enevill at arm.com Fri Jul 10 02:46:01 2009 From: enevill at arm.com (Edward Nevill) Date: Fri, 10 Jul 2009 10:46:01 +0100 Subject: Optimisation work on Zero/ARM In-Reply-To: <4A549909.9080202@zafena.se> References: <200907081442.n68EgGjd017487@parsley.camswl.com> <4A549909.9080202@zafena.se> Message-ID: <001501ca0143$3c7fb740$b57f25c0$@com> >I quickly tested to run your compiled binaries on a ARMV5TE >Sheeva-plugcomputer running Ubuntu Jaunty and it worked as expected! >Gave me instantly a 3.3 X improvement on the jython test in the dacapo >benchmark. >http://www.dacapo-bench.org/ Good. Thats what I like to hear. I have added dacapo to my benchmark suite. >I am thrilled to try combine your work with the LLVM based Shark JIT. At the moment the assembler interpreter does not pay any attention to UseCompiler. If UseCompiler is set the assembler interpreter will in fact just call the C interpreter instead. This is done once on init so if UseCompiler is set on init it reverts completely back to C. (There is also a backdoor if you ever want to run the C interpreter, Specify -XX:+PrintCommandLineFlags on the command line and it will revert completely to C). It is possible to make the asm interpreter pay attention to UseCompiler (its not that difficult and should have little impact on performance). What does Shark use for profiling, does it use CountCompiledCalls and UseLoopCounter? - or something else). The asm interpreter maintains the same frame structure. I have added one word at offset 28 from the lowest address of the frame (ie istate) This is ISTATE_SAVED_ISTATE where it saves the previous istate. This Is overlaid with the ISATE_MSG which the asm interpreter does not use. I am not clear how Shark (or any JIT for that matter) replaces a threaded method (ie if you are executing say, SieveAtom, how does it hijack control from the interpreter?). And how does it replace methods which might be lower down on the machine stack. I can see how you might do this non portably by grubbing around on the machine stack. It could also be done more portably by using say setcontext() and getcontext() in the interpreter so the compiler can unwind the interpreter and then continue executing in compiled code (at the location corresponding to the saved byte code pointers). Is there any docs to describe how this is done? Or pointers to where I should look? >I peeked at the sourcecode and it looks great! >Your changes are most portable for inclusion into Icedtea6/OpenJDK since >they are already contained in separate patches against the Icedtea6 tree >from 23 june 2009 in the debian/patches directory, fantastic. Would you be happy to review the changes for inclusion into IcedTea. There are 3 diff files in debian/patches relating to the asm interpreter, the rest of them all relate to the debian port. The 3 diffs are === zero-notice-safepoints.diff This is the only change to the shared code and is a single line change to change the definition of notice_safepoints() and ignore_safepoints() in cppInterpreter.hpp to a declaration. This is currently conditionalised on PRODUCT && HOTSPOT_ASM but it might make more sense to conditionalise it on say something like CPP_INTERPRETER_NOTICES_SAFEPOINTS. Alternatively it could be changed unconditionally as it seems pointless to me at least to have a definition in a shared header file so that it cannot be overridden by any code that actually wants to use it. What is the point of the function call in the first place if there is just a null implementation in its header file. === zero-asm-port.diff This contains the diffs to the ports/... part of IcedTea. The diffs are quite small (141 line) and are there mainly to provide hooks for the asm interpreter. The files affected are - zero.make Adds cppInterpreter_arm.o and rules to build it. - bytecodes_zero.cpp Adds definitions for bytecode pairs and fast version of invoke and getfield. - bytecodes_zero.hpp Declarations for the above - cppInterpreter_zero.cpp Adds a single call to 'asm_generate_method_entry(...)'. This is conditionalised on PRODUCT and HOTSPOT_ASM and is called if (!UseCompiler && !TaggedStackInterpreter && !JvmtiExport... && !PrintCommandLineFlags) { asm_entry = asm_generate_method_entry(kind); if (asm_entry) return(this->generate_entry(asm_entry)); } So, if the asm interpreter can execute this 'kind' of method it returns the entrypoint, otherwise NULL and the CPP interpreter returns its entrypoint instead. - os_linux_zero.cpp This adds a hook to allow the asm interpreter to detect Null pointers using SIGSEGV and does, in the signal handler if (sig == SIGSEGV) { if (asm_check_null(uc)) return 1; } Ie. if the assembler interpreter can handle it because it was one of its null pointer checks it just returns 1 and continues execution (the asm interpreter has updated the PC to point to 'null_pointer_exception'. === zero-asm-newfiles.diff This diff contains the new files for the asm interpreter. These all go into ports/hotspot/src/cpu/zero/vm. The files are bc.def - The bytecode definition file bytecodes.s - generated (manually) by 'mkbc' from bc.def cppInterpreter_asm.S - support code for bytecodes.s mkbc.c - The bytecode interpreter generator source Note: At the moment the bytecode interpreter generator is not integrated into the build, you have to manually do gcc -o mkbc mkbc.c mkbc bc.def bytecodes.s This is why bytecodes.s is also check in. Obviously it would be more desirable to integrate 'mkbc' into the build so we do not have generated files checked in. I have tried to keep the actual diffs (where existing files are modified), especially any which involve changes to shared code as these need to be merged into OpenJDK. BTW: I have signed the SCA so it is OK for any of these changes to be checked into OpenJDK. ARM has disclaimed copyright interest as per GPLv2 (although I have yet to get this in writing:-(). I have also requested the JCK from Sun so hopefully should be in a positions to verify it as Java Compliant. Best Regards, Ed. From gbenson at redhat.com Fri Jul 10 03:19:31 2009 From: gbenson at redhat.com (Gary Benson) Date: Fri, 10 Jul 2009 11:19:31 +0100 Subject: Optimisation work on Zero/ARM In-Reply-To: <001501ca0143$3c7fb740$b57f25c0$@com> References: <200907081442.n68EgGjd017487@parsley.camswl.com> <4A549909.9080202@zafena.se> <001501ca0143$3c7fb740$b57f25c0$@com> Message-ID: <20090710101930.GC3229@redhat.com> Hi Ed, Edward Nevill wrote: > I am not clear how Shark (or any JIT for that matter) replaces a > threaded method (ie if you are executing say, SieveAtom, how does > it hijack control from the interpreter?). So each method is defined in HotSpot with a methodOop object (defined in hotspot/src/share/vm/oops/methodOop.hpp). Each methodOop has two volatile pointers, _from_interpreted_entry and _from_compiled_entry, which are the entry points from interpreted and compiled code. When a bytecode method is loaded these are initialized to point to the code in the interpreter that executes methods (CppInterpreter::normal_entry in Zero). When methods are compiled these pointers are replaced. > And how does it replace methods which might be lower down on the > machine stack. I can see how you might do this non portably by > grubbing around on the machine stack. HotSpot can do this, but Shark doesn't yet -- ie, I haven't looked at it so I don't know how it works :) If you grep for OnStackReplacement or OSR you should find somewhere to start. Cheers, Gary -- http://gbenson.net/ From xerxes at zafena.se Fri Jul 10 03:24:10 2009 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Fri, 10 Jul 2009 12:24:10 +0200 Subject: Optimisation work on Zero/ARM In-Reply-To: <001501ca0143$3c7fb740$b57f25c0$@com> References: <200907081442.n68EgGjd017487@parsley.camswl.com> <4A549909.9080202@zafena.se> <001501ca0143$3c7fb740$b57f25c0$@com> Message-ID: <4A5716CA.6080409@zafena.se> Greetings Ed! I have been trying to compile the "BIG ASM" interpreter today in order to check if something needs changing before moving your work into Icedtea. Edward Nevill skrev: >> I peeked at the sourcecode and it looks great! >> Your changes are most portable for inclusion into Icedtea6/OpenJDK since >> they are already contained in separate patches against the Icedtea6 tree >> > >from 23 june 2009 in the debian/patches directory, fantastic. > > Would you be happy to review the changes for inclusion into IcedTea. > > === zero-asm-port.diff > > This contains the diffs to the ports/... part of IcedTea. The diffs are > quite small (141 line) and are there mainly to provide hooks for the asm > interpreter. The files affected are > > - zero.make > > Adds cppInterpreter_arm.o and rules to build it. > I have found this line of zero.make in my way: zero-asm-port.diff:+CFLAGS += -DHOTSPOT_ASM -DHW_NULL_PTR_CHECK -march=armv5t -mtune=cortex-a8 -O2 -falign-functions=64 -falign-loops=8 -g0 I think it are causing my crosscompile build for my armv5te system to fail with this error: -fpic -fno-rtti -fno-exceptions -D_REENTRANT -fcheck-new -g -pipe -fno-strict-aliasing -DHOTSPOT_ASM -DHW_NULL_PTR_CHECK -march=armv5t -mtune=cortex-a8 -O2 -falign-functions=64 -falign-loops=8 -g0 -DVM_LITTLE_ENDIAN -Wpointer-arith -Wsign-compare -c -o adjoiningGenerations.o /usr/src/openembedded/verdexpro/tmp/work/armv5te-angstrom-linux-gnueabi/openjdk-6-jre-6b16-r3/hg/icedtea6/openjdk-ecj/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.cpp | {standard input}: Assembler messages: | {standard input}:14: Fatal error: alignments greater than 32 bytes not supported in .text sections. | {standard input}: Assembler messages: | {standard input}:14: Fatal error: alignments greater than 32 bytes not supported in .text sections. | make[7]: *** [abstractCompiler.o] Error 1 | make[7]: *** Waiting for unfinished jobs.... | make[7]: *** [accessFlags.o] Error 1 | {standard input}: Assembler messages: | {standard input}:14: Fatal error: alignments greater than 32 bytes not supported in .text sections. | make[7]: *** [adjoiningGenerations.o] Error 1 | {standard input}: Assembler messages: | {standard input}:14: Fatal error: alignments greater than 32 bytes not supported in .text sections. | make[7]: *** [adaptiveSizePolicy.o] Error 1 | make[7]: Leaving directory `/usr/src/openembedded/verdexpro/tmp/work/armv5te-angstrom-linux-gnueabi/openjdk-6-jre-6b16-r3/hg/icedtea6/openjdk-ecj/build/linux-arm/hotspot/outputdir/linux_zero_core/product' | make[6]: *** [the_vm] Error 2 Are any of the cflags -march=armv5t -mtune=cortex-a8 -O2 -falign-functions=64 -falign-loops=8 -g0 crucial or just optimization related? Most ARM Linux distributions will supply the correct CFLAGS so i dont think we should have these turned on as default. Cheers Xerxes From doko at ubuntu.com Fri Jul 10 03:39:17 2009 From: doko at ubuntu.com (Matthias Klose) Date: Fri, 10 Jul 2009 12:39:17 +0200 Subject: Optimisation work on Zero/ARM In-Reply-To: <4A5716CA.6080409@zafena.se> References: <200907081442.n68EgGjd017487@parsley.camswl.com> <4A549909.9080202@zafena.se> <001501ca0143$3c7fb740$b57f25c0$@com> <4A5716CA.6080409@zafena.se> Message-ID: <4A571A55.7030209@ubuntu.com> Xerxes R?nby schrieb: > Greetings Ed! > > I have been trying to compile the "BIG ASM" interpreter today in order > to check if something needs changing before moving your work into Icedtea. > > Edward Nevill skrev: >>> I peeked at the sourcecode and it looks great! >>> Your changes are most portable for inclusion into Icedtea6/OpenJDK since >>> they are already contained in separate patches against the Icedtea6 tree >>> >> >from 23 june 2009 in the debian/patches directory, fantastic. >> >> Would you be happy to review the changes for inclusion into IcedTea. >> >> === zero-asm-port.diff >> >> This contains the diffs to the ports/... part of IcedTea. The diffs are >> quite small (141 line) and are there mainly to provide hooks for the asm >> interpreter. The files affected are >> >> - zero.make >> >> Adds cppInterpreter_arm.o and rules to build it. >> > I have found this line of zero.make in my way: > > zero-asm-port.diff:+CFLAGS += -DHOTSPOT_ASM -DHW_NULL_PTR_CHECK > -march=armv5t -mtune=cortex-a8 -O2 -falign-functions=64 -falign-loops=8 -g0 > > I think it are causing my crosscompile build for my armv5te system to > fail with this error: [...] this requires http://sourceware.org/ml/binutils/2009-06/msg00289.html > Are any of the cflags > -march=armv5t -mtune=cortex-a8 -O2 -falign-functions=64 -falign-loops=8 -g0 > crucial or just optimization related? I didn't run tests for armv4 yet. > Most ARM Linux distributions will supply the correct CFLAGS so i dont > think we should have these turned on as default. Yes, these could be set in the packaging as well. Matthias From gbenson at redhat.com Fri Jul 10 05:18:08 2009 From: gbenson at redhat.com (Gary Benson) Date: Fri, 10 Jul 2009 13:18:08 +0100 Subject: Optimisation work on Zero/ARM In-Reply-To: <200907081442.n68EgGjd017487@parsley.camswl.com> References: <200907081442.n68EgGjd017487@parsley.camswl.com> Message-ID: <20090710121808.GE3229@redhat.com> Hi Ed, I finally got a chance to look at this today. I don't have ARM hardware so I can't try it, but I've been looking at the sources to see how it all hooks in. I have to say I'm a little confused by how it relates to Zero. I see that you have asm method entries for everything that Zero has a method entry for, and looking at the symbols the assembly code references it doesn't seem to call back into any Zero code. So it seems that the only bit of Zero it uses is the call stub. Am I right? Cheers, Gary Edward Nevill wrote: > Hi All, > > I have been fairly quiet on this list for the past few months but > I have been beavering away optimising Zero for ARM. > > I have put together a website describing the optimisation work I > have done. (http://camswl.com/openjdk). > > Some highlights: > > 3.7 X improvement on ECM > 4.8 X improvement on EEMBC > Between 2.6 X improvement and 3.3X improvement opening a document > in Think Free Office > > The VM uses some new technology called a 'Bytecode Interpreter > Generator' which generates an interpreter which can peephole up > to 4 bytecode in advance. See URL above for details. > > Binaries and sources are available on the website. > > The binaries should work on ARMV5TE or later platforms. I have > tested it only on ARMV7 so any feedback regarding other platforms > is particularly welcome. > > Regards, > Ed. -- http://gbenson.net/ From xerxes at zafena.se Fri Jul 10 05:28:35 2009 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Fri, 10 Jul 2009 14:28:35 +0200 Subject: Optimisation work on Zero/ARM In-Reply-To: <4A571A55.7030209@ubuntu.com> References: <200907081442.n68EgGjd017487@parsley.camswl.com> <4A549909.9080202@zafena.se> <001501ca0143$3c7fb740$b57f25c0$@com> <4A5716CA.6080409@zafena.se> <4A571A55.7030209@ubuntu.com> Message-ID: <4A5733F3.3070905@zafena.se> Matthias Klose skrev: > >> I have found this line of zero.make in my way: >> >> zero-asm-port.diff:+CFLAGS += -DHOTSPOT_ASM -DHW_NULL_PTR_CHECK >> -march=armv5t -mtune=cortex-a8 -O2 -falign-functions=64 -falign-loops=8 -g0 >> >> I think it are causing my crosscompile build for my armv5te system to >> fail with this error: >> > > [...] > this requires http://sourceware.org/ml/binutils/2009-06/msg00289.html > > Thank you Matthias for the pointer to the binutils patch! For the record: when i removed those optimization options my build succeeded and i have now built a cross compiled armv5te BIG ASM jvm using the Jalimo cross compile infrastructure. I will push this work into Jalimo, the project that provides Icedtea/OpenJDK for OpenEmbedded distributions like ?ngstrom, and after then see if i can fix the OpenEmbedded binutils so that all these optimizations can be used for cross compiled builds. http://evolvis.org/projects/jalimo Cheers Xerxes From enevill at arm.com Fri Jul 10 06:20:39 2009 From: enevill at arm.com (Edward Nevill) Date: Fri, 10 Jul 2009 14:20:39 +0100 Subject: Zero/ARM In-Reply-To: <20090710121808.GE3229@redhat.com> References: <200907081442.n68EgGjd017487@parsley.camswl.com> <20090710121808.GE3229@redhat.com> Message-ID: <001c01ca0161$37e8a750$a7b9f5f0$@com> >I finally got a chance to look at this today. I don't have ARM >hardware so I can't try it, but I've been looking at the sources >to see how it all hooks in. If you need some ARM hardware I am going on holiday from Weds of next week so could lend you one of my boards for 3 weeks. Alternatively, I could make arrangements for you to access the boards on my desk remotely - but that won'cput help you if you need to reset them. >I have to say I'm a little confused by how it relates to Zero. >I see that you have asm method entries for everything that Zero >has a method entry for, and looking at the symbols the assembly >code references it doesn't seem to call back into any Zero code. >So it seems that the only bit of Zero it uses is the call stub. >Am I right? Hmmm. Yes, possibly. I hadn't realised how little of Zero it still depends on. It started depending on a lot more when I only optimised bytecodeInterpreter.cpp, but as I moved to optimising the entry points (normal_entry and then native_entry) it grew less and less. Here are the pieces of Zero I believe it still uses. - It uses the Zero stack. - It uses Zero in all the cases it cannot support IE UseCompiler == true TaggedStackInterpreter == true JvmtiExport::can_post_interpreter_events == true - It uses a lot of the other files in cpu/zero/vm. assembler_zero.cpp, bytecodeInterpreter_zero.cpp, ... May of these are just Unimplemented() or have trivial implementations. - It uses 'ffi' to do native calls, so relies on stuff in interpreterRT_zero.cpp to do the signature parsing. - It relies on all of os_cpu/linux_zero/vm/... I haven't touched any of this. So it is still reliant on quite a bit of Zero. Regards, Ed. From gbenson at redhat.com Fri Jul 10 06:55:45 2009 From: gbenson at redhat.com (Gary Benson) Date: Fri, 10 Jul 2009 14:55:45 +0100 Subject: Zero/ARM In-Reply-To: <001c01ca0161$37e8a750$a7b9f5f0$@com> References: <200907081442.n68EgGjd017487@parsley.camswl.com> <20090710121808.GE3229@redhat.com> <001c01ca0161$37e8a750$a7b9f5f0$@com> Message-ID: <20090710135545.GF3229@redhat.com> Edward Nevill wrote: > > I finally got a chance to look at this today. I don't have ARM > > hardware so I can't try it, but I've been looking at the sources > > to see how it all hooks in. > > If you need some ARM hardware I am going on holiday from Weds of > next week so could lend you one of my boards for 3 weeks. > > Alternatively, I could make arrangements for you to access the > boards on my desk remotely - but that won'cput help you if you > need to reset them. Thanks for the offer, but I'll decline. If you say it works then I believe you. I see too many people saying how hard it is to build on ARM, and I don't fancy sharing the pain ;) > > I have to say I'm a little confused by how it relates to Zero. > > I see that you have asm method entries for everything that Zero > > has a method entry for, and looking at the symbols the assembly > > code references it doesn't seem to call back into any Zero code. > > So it seems that the only bit of Zero it uses is the call stub. > > Am I right? > > Hmmm. Yes, possibly. I hadn't realised how little of Zero it still > depends on. It started depending on a lot more when I only optimised > bytecodeInterpreter.cpp, but as I moved to optimising the entry > points (normal_entry and then native_entry) it grew less and less. > > Here are the pieces of Zero I believe it still uses. > > - It uses the Zero stack. You're probably taking a performance hit for that. I presume your assembly is setting up native frames for the methods? You could extend that to allocate things that you need in the native frames. You'd have to rewrite the stack walker though, and you'd use the ability to use Shark. BTW, Shark, you're using the same calling convention as Zero right? ie methods have three arguments: methodOop, base_pc, thread? If so, then Shark should work unmodified assuming your interpreter counts method calls. You'd probably have to tweak the deoptimization code to jump to your normal entry rather than the C++ interpreter's, but that's all. > - It uses Zero in all the cases it cannot support IE > UseCompiler == true > TaggedStackInterpreter == true > JvmtiExport::can_post_interpreter_events == true Zero doesn't support TaggedStackInterpreter either. > - It uses 'ffi' to do native calls, so relies on stuff in > interpreterRT_zero.cpp to do the signature parsing. You're probably taking a performance hit on this too, especially for GUI code (which has a lot of native calls back to GTK or whatever else is implementing it all). The original signature parser is supposed to return a block of native code that converts the arguments from the Java calling convention (ie the top of the Zero stack) to the native one. Have a look at the x86 and SPARC ones to see what they do. Cheers, Gary -- http://gbenson.net/ From xerxes at zafena.se Tue Jul 14 03:24:40 2009 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Tue, 14 Jul 2009 12:24:40 +0200 Subject: RFC: shark + llvm2.6svn api change ConstantFP::get implementation have been moved to LLVMContext Message-ID: <4A5C5CE8.3030108@zafena.se> The attached patch fixes the build error that orgin from the r75546 change of the llvm 2.6 svn tip. http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20090713/080939.html For some reason beyond my understanding the ConstantFP::get implementation have been moved from lib/VMCore/Constants to getConstantFP in lib/VMCore/LLVMContext . Should we push this change to shark or wait some days to see if the implementation moves back to Constants again in llvm ? ... ct\"" -DHOTSPOT_BUILD_USER="\"xerxes\"" -DHOTSPOT_LIB_ARCH=\"i386\" -DJRE_RELEASE_VERSION="\"1.6.0_0-b16\"" -DHOTSPOT_VM_DISTRO="\"OpenJDK\"" -DSHARK -I/usr/local/include -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -g -fPIC -Woverloaded-virtual -DSHARK_LLVM_VERSION=26 -fpic -fno-rtti -fno-exceptions -D_REENTRANT -fcheck-new -g -m32 -pipe -O3 -fno-strict-aliasing -DVM_LITTLE_ENDIAN -Wpointer-arith -Wconversion -Wsign-compare -c -o sharkBuilder.o /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/sharkBuilder.cpp In file included from ../generated/incls/_sharkBuilder.cpp.incl:3, from /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/sharkBuilder.cpp:27: /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/llvmValue.hpp: In static member function 'static llvm::Constant* LLVMValue::jfloat_constant(jfloat)': /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/llvmValue.hpp:46: error: no matching function for call to 'llvm::ConstantFP::get(const llvm::Type*, jfloat&)' /usr/local/include/llvm/Constants.h:257: note: candidates are: static llvm::ConstantFP* llvm::ConstantFP::get(const llvm::APFloat&) /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/llvmValue.hpp: In static member function 'static llvm::Constant* LLVMValue::jdouble_constant(jdouble)': /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/llvmValue.hpp:54: error: no matching function for call to 'llvm::ConstantFP::get(const llvm::Type*, jdouble&)' /usr/local/include/llvm/Constants.h:257: note: candidates are: static llvm::ConstantFP* llvm::ConstantFP::get(const llvm::APFloat&) In file included from ../generated/incls/_sharkBlock.cpp.incl:3, from /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/sharkBlock.cpp:27: /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/llvmValue.hpp: In static member function 'static llvm::Constant* LLVMValue::jfloat_constant(jfloat)': /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/llvmValue.hpp:46: error: no matching function for call to 'llvm::ConstantFP::get(const llvm::Type*, jfloat&)' /usr/local/include/llvm/Constants.h:257: note: candidates are: static llvm::ConstantFP* llvm::ConstantFP::get(const llvm::APFloat&) /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/llvmValue.hpp: In static member function 'static llvm::Constant* LLVMValue::jdouble_constant(jdouble)': /home/xerxes/icedtea6/openjdk-ecj/hotspot/src/share/vm/shark/llvmValue.hpp:54: error: no matching function for call to 'llvm::ConstantFP::get(const llvm::Type*, jdouble&)' /usr/local/include/llvm/Constants.h:257: note: candidates are: static llvm::ConstantFP* llvm::ConstantFP::get(const llvm::APFloat&) make[7]: *** [sharkBuilder.o] Error 1 Cheers Xerxes -------------- next part -------------- A non-text attachment was scrubbed... Name: llvmValue.hpp_LLVMContext_ConstantFP.patch Type: text/x-patch Size: 1160 bytes Desc: not available Url : http://mail.openjdk.java.net/pipermail/zero-dev/attachments/20090714/7bdb7ed0/attachment.bin From gbenson at redhat.com Tue Jul 14 03:34:05 2009 From: gbenson at redhat.com (Gary Benson) Date: Tue, 14 Jul 2009 11:34:05 +0100 Subject: RFC: shark + llvm2.6svn api change ConstantFP::get implementation have been moved to LLVMContext In-Reply-To: <4A5C5CE8.3030108@zafena.se> References: <4A5C5CE8.3030108@zafena.se> Message-ID: <20090714103404.GB3177@redhat.com> Xerxes R?nby wrote: > The attached patch fixes the build error that orgin from the r75546 > change of the llvm 2.6 svn tip. > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20090713/080939.html > > For some reason beyond my understanding the ConstantFP::get > implementation have been moved from lib/VMCore/Constants to > getConstantFP in lib/VMCore/LLVMContext . Should we push this > change to shark or wait some days to see if the implementation > moves back to Constants again in llvm ? Commit away. As I understand it, the constants code was leaking things between functions, and the LLVMContext stuff is an attempt to address this. I think you need to expect more of the same in the next few days as they move other stuff in there. Cheers, Gary -- http://gbenson.net/ From illia.romanenko at googlemail.com Tue Jul 14 12:26:37 2009 From: illia.romanenko at googlemail.com (=?UTF-8?B?0IbQu9C70Y8g0KDQvtC80LDQvdC10L3QutC+?=) Date: Tue, 14 Jul 2009 22:26:37 +0300 Subject: Poring Shark to Google Android Dalvik Virtual Machine Message-ID: Hi, I was wondering if it would be good idea to port Shark Dalvik Virtual Machine? As dalvik didn't have JIT for now so apps works very slow. You may look at http://www.koushikdutta.com/2009/01/dalvik-vs-mono.html to see how bad is it :) Let me know what do you think about it... Cheers, Illia Romanenko -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/zero-dev/attachments/20090714/4377c7a5/attachment.html From xerxes at zafena.se Tue Jul 14 14:18:28 2009 From: xerxes at zafena.se (=?UTF-8?B?WGVyeGVzIFLDpW5ieQ==?=) Date: Tue, 14 Jul 2009 23:18:28 +0200 Subject: Poring Shark to Google Android Dalvik Virtual Machine In-Reply-To: References: Message-ID: <4A5CF624.5040509@zafena.se> Den 2009-07-14 21:26, ???? ????????? skrev: > Hi, > I was wondering if it would be good idea to port Shark Dalvik Virtual > Machine? As dalvik didn't have JIT for now so apps works very slow. > You may look at > http://www.koushikdutta.com/2009/01/dalvik-vs-mono.html to see how bad > is it :) > > Let me know what do you think about it... > > Cheers, > Illia Romanenko It would actually be quite a good idea to get OpenJDK using zero/shark running on Android as is as an alternative java implementation instead of using Dalvik, it will give Android Java SE compatibility and prevent a split in the embedded Java world. OpenJDK currently have two jits for ARM the and Shark JIT (work in progress on stabilising llvm for ARM) and the Cacao JIT we also have a brand new and fast ASM optimized interpreter for ARM to be used on top of Zero. Another option are to use PhoneME on Android as is, it also contains a JIT and would give Android Java ME compatibility, currently as fair as i know Android are only compatible with itself since it only uses a subset of apache harmony. You can probably use the caciocavallo project to enable OpenJDK to draw all swing and awt guis on Android. http://openjdk.java.net/projects/caciocavallo/ Cheers Xerxes From xerxes at zafena.se Wed Jul 15 01:27:48 2009 From: xerxes at zafena.se (=?UTF-8?B?WGVyeGVzIFLDpW5ieQ==?=) Date: Wed, 15 Jul 2009 10:27:48 +0200 Subject: Poring Shark to Google Android Dalvik Virtual Machine In-Reply-To: References: <4A5CF624.5040509@zafena.se> Message-ID: <4A5D9304.80009@zafena.se> ???? ????????? skrev: > Hi Xerxes, > Thanks for your answer! > > Can we port only Shark(JIT) into Dalvik? Shark are designed to slot into the OpenJDK hotspot on top of zero, the JIT inside Shark are from the LLVM project, i will quote a nice article on this matter: "To implement a JIT without introducing platform-specific code, we turned to another free software library, LLVM (Low Level Virtual Machine). LLVM has a wide range of applicability -- it's an infrastructure for building both compilers and virtual machines -- but the feature that was interesting for this project is that it includes JITs that generate native functions from code expressed in LLVM's intermediate representation (IR). Shark is, in essence, very simple. It uses the same interface as HotSpot's platform-specific compilers, so it slots in with very little modification to HotSpot itself. When running in mixed mode, HotSpot's compiler scheduler locates hot methods and invokes Shark to compile them, one at a time. Shark translates the Java bytecode of these methods to LLVM IR, and invokes LLVM's JIT to generate the native code. The native code is then installed in the VM, where it replaces the interpreted version of the method, and control returns to the compiler scheduler." http://today.java.net/pub/a/today/2009/05/21/zero-and-shark-openjdk-port.html Thus you can use the LLVM compiler infrastructure libraries to fit a JIT into Dalvik in a similar way that we have used LLVM in Shark to fit the LLVM JIT into Hotspot. Try work with the LLVM JIT tutorials to see how the LLVM JIT can be fitted into Dalvik. http://llvm.org/docs/tutorial/ Now the main issue for you are: *where do you obtain the Dalvik sourcecode?* AFAIK it are not available outside of Google. so sorry you cant port the Shark JIT to Dalvik unless Dalvik are released as free software. The Dalivk interpreter looks on the surface as a obfuscated Jamvm so try fit the LLVM JIT to JamVM and it will probably end up in Dalvik automagically. If the Dalvik sourcecode have been released please give me a pointer to it. Cheers Xerxes > > 15 ????? 2009 ?. 00:18 Xerxes R?nby > ???????: > > Den 2009-07-14 21:26, ???? ????????? skrev: > > Hi, > > I was wondering if it would be good idea to port Shark Dalvik > Virtual > > Machine? As dalvik didn't have JIT for now so apps works very slow. > > You may look at > > http://www.koushikdutta.com/2009/01/dalvik-vs-mono.html to see > how bad > > is it :) > > > > Let me know what do you think about it... > > > > Cheers, > > Illia Romanenko > > It would actually be quite a good idea to get OpenJDK using zero/shark > running on Android as is as an alternative java implementation instead > of using Dalvik, it will give Android Java SE compatibility and > prevent > a split in the embedded Java world. > > OpenJDK currently have two jits for ARM the and Shark JIT (work in > progress on stabilising llvm for ARM) and the Cacao JIT we also have a > brand new and fast ASM optimized interpreter for ARM to be used on top > of Zero. > > Another option are to use PhoneME on Android as is, it also contains a > JIT and would give Android Java ME compatibility, > > currently as fair as i know Android are only compatible with itself > since it only uses a subset of apache harmony. > > You can probably use the caciocavallo project to enable OpenJDK to > draw > all swing and awt guis on Android. > http://openjdk.java.net/projects/caciocavallo/ > > Cheers > Xerxes > > From xerxes at zafena.se Wed Jul 15 03:21:25 2009 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Wed, 15 Jul 2009 12:21:25 +0200 Subject: RFC: shark + llvm2.6svn api change ConstantInt::get and ConstantArray::get implementation have been moved to LLVMContext Message-ID: <4A5DADA5.2030404@zafena.se> Patch to fix build errors with LLVM API changes in svn r75703 ConstantInt::get and ConstantArray::get implementation have been moved to LLVMContext http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20090713/081100.html Cheers Xerxes -------------- next part -------------- A non-text attachment was scrubbed... Name: ConstantInt_ConstantArray_moved_to_LLVMContext.patch Type: text/x-patch Size: 3356 bytes Desc: not available Url : http://mail.openjdk.java.net/pipermail/zero-dev/attachments/20090715/8bb524ab/attachment.bin From gbenson at redhat.com Wed Jul 15 03:29:31 2009 From: gbenson at redhat.com (Gary Benson) Date: Wed, 15 Jul 2009 11:29:31 +0100 Subject: RFC: shark + llvm2.6svn api change ConstantInt::get and ConstantArray::get implementation have been moved to LLVMContext In-Reply-To: <4A5DADA5.2030404@zafena.se> References: <4A5DADA5.2030404@zafena.se> Message-ID: <20090715102930.GA3179@redhat.com> Hi Xerxes, Please commit this. Feel free to commit similar API fixes in future, you're pretty good at them :) Cheers, Gary Xerxes R?nby wrote: > Patch to fix build errors with LLVM API changes in svn r75703 > ConstantInt::get and ConstantArray::get implementation have been > moved to LLVMContext > > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20090713/081100.html > > Cheers > Xerxes > Index: icedtea6/ports/hotspot/src/share/vm/shark/llvmValue.hpp > =================================================================== > --- icedtea6.orig/ports/hotspot/src/share/vm/shark/llvmValue.hpp 2009-07-15 11:34:29.000000000 +0200 > +++ icedtea6/ports/hotspot/src/share/vm/shark/llvmValue.hpp 2009-07-15 11:39:21.000000000 +0200 > @@ -27,15 +27,27 @@ > public: > static llvm::ConstantInt* jbyte_constant(jbyte value) > { > +#if SHARK_LLVM_VERSION >= 26 > + return llvm::getGlobalContext().getConstantInt(SharkType::jbyte_type(), value, true); > +#else > return llvm::ConstantInt::get(SharkType::jbyte_type(), value, true); > +#endif > } > static llvm::ConstantInt* jint_constant(jint value) > { > +#if SHARK_LLVM_VERSION >= 26 > + return llvm::getGlobalContext().getConstantInt(SharkType::jint_type(), value, true); > +#else > return llvm::ConstantInt::get(SharkType::jint_type(), value, true); > +#endif > } > static llvm::ConstantInt* jlong_constant(jlong value) > { > +#if SHARK_LLVM_VERSION >= 26 > + return llvm::getGlobalContext().getConstantInt(SharkType::jlong_type(), value, true); > +#else > return llvm::ConstantInt::get(SharkType::jlong_type(), value, true); > +#endif > } > #if SHARK_LLVM_VERSION >= 26 > static llvm::Constant* jfloat_constant(jfloat value) > @@ -67,6 +79,10 @@ > public: > static llvm::ConstantInt* intptr_constant(intptr_t value) > { > +#if SHARK_LLVM_VERSION >= 26 > + return llvm::getGlobalContext().getConstantInt(SharkType::intptr_type(), value, false); > +#else > return llvm::ConstantInt::get(SharkType::intptr_type(), value, false); > +#endif > } > }; > Index: icedtea6/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp > =================================================================== > --- icedtea6.orig/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp 2009-07-15 11:40:21.000000000 +0200 > +++ icedtea6/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp 2009-07-15 11:44:42.000000000 +0200 > @@ -187,9 +187,15 @@ > { > Constant *const_name; > if (value->hasName()) > +#if SHARK_LLVM_VERSION >= 26 > + const_name = getGlobalContext().getConstantArray(value->getName()); > + else > + const_name = getGlobalContext().getConstantArray("unnamed_value"); > +#else > const_name = ConstantArray::get(value->getName()); > else > const_name = ConstantArray::get("unnamed_value"); > +#endif > > Value *name = CreatePtrToInt( > CreateStructGEP( > @@ -260,10 +266,18 @@ > CallInst *SharkBuilder::CreateMemoryBarrier(BarrierFlags flags) > { > Value *args[] = { > +#if SHARK_LLVM_VERSION >= 26 > + getGlobalContext().getConstantInt(Type::Int1Ty, (flags & BARRIER_LOADLOAD) ? 1 : 0), > + getGlobalContext().getConstantInt(Type::Int1Ty, (flags & BARRIER_LOADSTORE) ? 1 : 0), > + getGlobalContext().getConstantInt(Type::Int1Ty, (flags & BARRIER_STORELOAD) ? 1 : 0), > + getGlobalContext().getConstantInt(Type::Int1Ty, (flags & BARRIER_STORESTORE) ? 1 : 0), > + getGlobalContext().getConstantInt(Type::Int1Ty, 0)}; > +#else > ConstantInt::get(Type::Int1Ty, (flags & BARRIER_LOADLOAD) ? 1 : 0), > ConstantInt::get(Type::Int1Ty, (flags & BARRIER_LOADSTORE) ? 1 : 0), > ConstantInt::get(Type::Int1Ty, (flags & BARRIER_STORELOAD) ? 1 : 0), > ConstantInt::get(Type::Int1Ty, (flags & BARRIER_STORESTORE) ? 1 : 0), > ConstantInt::get(Type::Int1Ty, 0)}; > +#endif > return CreateCall(llvm_memory_barrier_fn(), args, args + 5); > } -- http://gbenson.net/ From gbenson at redhat.com Tue Jul 28 05:19:26 2009 From: gbenson at redhat.com (Gary Benson) Date: Tue, 28 Jul 2009 13:19:26 +0100 Subject: Removing support for LLVM 2.4 on AMD64 from Shark Message-ID: <20090728121926.GA3268@redhat.com> Hi all, SharkBuilder, which I'm currently refactoring, contains a workaround for a bug in LLVM 2.4, http://www.llvm.org/bugs/show_bug.cgi?id=2920, that has been fixed in LLVM 2.5. Does anybody object to my removing this workaround? Cheers, Gary -- http://gbenson.net/ From aph at redhat.com Thu Jul 30 00:47:39 2009 From: aph at redhat.com (Andrew Haley) Date: Thu, 30 Jul 2009 08:47:39 +0100 Subject: Removing support for LLVM 2.4 on AMD64 from Shark In-Reply-To: <20090728121926.GA3268@redhat.com> References: <20090728121926.GA3268@redhat.com> Message-ID: <4A71501B.4090704@redhat.com> Gary Benson wrote: > SharkBuilder, which I'm currently refactoring, contains a workaround > for a bug in LLVM 2.4, http://www.llvm.org/bugs/show_bug.cgi?id=2920, > that has been fixed in LLVM 2.5. Does anybody object to my removing > this workaround? I think this one was mine. It's no problem if you remove it. Andrew. From gbenson at redhat.com Thu Jul 30 01:01:29 2009 From: gbenson at redhat.com (Gary Benson) Date: Thu, 30 Jul 2009 09:01:29 +0100 Subject: Removing support for LLVM 2.4 on AMD64 from Shark In-Reply-To: <4A71501B.4090704@redhat.com> References: <20090728121926.GA3268@redhat.com> <4A71501B.4090704@redhat.com> Message-ID: <20090730080129.GB3382@redhat.com> Andrew Haley wrote: > Gary Benson wrote: > > SharkBuilder, which I'm currently refactoring, contains a workaround > > for a bug in LLVM 2.4, http://www.llvm.org/bugs/show_bug.cgi?id=2920, > > that has been fixed in LLVM 2.5. Does anybody object to my removing > > this workaround? > > I think this one was mine. It's no problem if you remove it. Cool. Cheers, Gary -- http://gbenson.net/ From gbenson at redhat.com Thu Jul 30 02:18:11 2009 From: gbenson at redhat.com (Gary Benson) Date: Thu, 30 Jul 2009 10:18:11 +0100 Subject: SharkBuilder refactoring Message-ID: <20090730091811.GC3382@redhat.com> Hi all, This commit is a big refactoring I've been working on this past week or so. It mainly relates to the creation of LLVM callable objects to represent external functions, but SharkBuilder has, over time, ended up as a kind of storehouse of dirty hacks and I've taken the opportunity to clean them out. Shark code calls a certain number of external functions, and the LLVM objects representing these were previously split between two classes (SharkBuilder and SharkRuntime). Both classes did much the same thing with their own callables, which is messy. This patch puts all callables into SharkBuilder. The other thing was that such callables were created when Shark was initialized, and cached for the lifetime of the VM. This doesn't actually work -- if a you free an LLVM function, it would free the callables in it, and everything else would bomb. In the new code, callables are created on the fly, and never cached. One consequence of this patch is that Shark will no longer work with LLVM 2.4 on AMD64, so if you're building on AMD64 you need to upgrade to 2.5. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r ff01867e1a2a -r 051ca564791d ChangeLog --- a/ChangeLog Wed Jul 29 10:57:38 2009 -0400 +++ b/ChangeLog Thu Jul 30 04:51:32 2009 -0400 @@ -1,3 +1,79 @@ +2009-07-30 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkRuntime.hpp: + * ports/hotspot/src/share/vm/shark/sharkRuntime.cpp: + Moved everything except the actual methods called by + JIT-compiled code into SharkBuilder. + + * ports/hotspot/src/share/vm/shark/sharkBuilder.hpp + * ports/hotspot/src/share/vm/shark/sharkBuilder.cpp + Merged code to create LLVM callable objects for runtime + methods from SharkRuntime, and refactored it (and the + existing code to create LLVM callable objects for LLVM + intrinsics) to create such objects on the fly. + + * ports/hotspot/src/share/vm/shark/sharkCompiler.hpp + (SharkCompiler::_builder): Removed. + (SharkCompiler::builder): Likewise. + * ports/hotspot/src/share/vm/shark/sharkInvariants.hpp + (SharkCompileInvariants::SharkCompileInvariants): Take a new + argument, builder, and store it. + (SharkCompileInvariants::builder): Updated. + (SharkCompileInvariants::code_buffer): New method. + (SharkTargetInvariants::SharkTargetInvariants): Take a new + argument, builder, and pass it along to SharkCompileInvariants + constructor. + * ports/hotspot/src/share/vm/shark/sharkFunction.hpp + (SharkFunction::build): Take a new argument, builder, and pass + it along to SharkFunction consructor. + (SharkFunction::SharkFunction): Take a new argument, builder, + and pass it along to SharkTargetInvariants consructor. + * ports/hotspot/src/share/vm/shark/sharkCompiler.cpp + (SharkCompiler::SharkCompiler): Remove builder creation and + SharkRuntime initialization. + (SharkCompiler::compile_method): Create builder and pass it + to SharkFunction::build. + + * ports/hotspot/src/share/vm/shark/sharkBlock.cpp + (SharkBlock::parse_bytecode): Updated for new style calls. + * ports/hotspot/src/share/vm/shark/sharkIntrinsics.hpp + (SharkIntrinsics::do_Math_1to1): Likewise. + (SharkIntrinsics::do_Math_2to1): Likewise. + * ports/hotspot/src/share/vm/shark/sharkIntrinsics.cpp + (SharkIntrinsics::do_intrinsic): Likewise. + (SharkIntrinsics::do_Math_1to1): Likewise. + (SharkIntrinsics::do_Math_2to1): Likewise. + (SharkIntrinsics::do_System_currentTimeMillis): Likewise. + (SharkIntrinsics::do_Unsafe_compareAndSwapInt): Likewise. + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp + (SharkTopLevelBlock::call_vm): Likewise. + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::zero_check_value): Likewise. + (SharkTopLevelBlock::check_bounds): Likewise. + (SharkTopLevelBlock::maybe_add_safepoint): Likewise. + (SharkTopLevelBlock::do_trap): Likewise. + (SharkTopLevelBlock::call_register_finalizer): Likewise. + (SharkTopLevelBlock::get_interface_callee): Likewise. + (SharkTopLevelBlock::do_new): Likewise. + (SharkTopLevelBlock::do_newarray): Likewise. + (SharkTopLevelBlock::do_anewarray): Likewise. + (SharkTopLevelBlock::do_multianewarray): Likewise. + (SharkTopLevelBlock::acquire_lock): Likewise. + (SharkTopLevelBlock::release_lock): Likewise. + + * ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp + (SharkDecacher::start_frame): Updated for new style codebuffer access. + * ports/hotspot/src/share/vm/shark/sharkFunction.cpp + (SharkFunction::initialize): Likewise. + + * ports/hotspot/src/share/vm/shark/llvmValue.hpp + (LLVMValue::bit_constant): New method. + + * ports/hotspot/src/share/vm/shark/sharkBlock.hpp + (SharkBlock::call_vm_leaf): Removed. + + * ports/hotspot/src/share/vm/includeDB_shark: Updated. + 2009-07-29 Omair Majid * rt/net/sourceforge/jnlp/IconDesc.java: Add new icon kind SHORTCUT. diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/includeDB_shark --- a/ports/hotspot/src/share/vm/includeDB_shark Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/includeDB_shark Thu Jul 30 04:51:32 2009 -0400 @@ -72,7 +72,6 @@ sharkBlock.cpp sharkBlock.hpp sharkBlock.cpp sharkBuilder.hpp sharkBlock.cpp sharkConstant.hpp -sharkBlock.cpp sharkRuntime.hpp sharkBlock.cpp sharkState.hpp sharkBlock.cpp sharkValue.hpp @@ -149,7 +148,6 @@ sharkCompiler.cpp sharkEntry.hpp sharkCompiler.cpp sharkFunction.hpp sharkCompiler.cpp sharkMemoryManager.hpp -sharkCompiler.cpp sharkRuntime.hpp sharkCompiler.hpp abstractCompiler.hpp sharkCompiler.hpp ciEnv.hpp @@ -212,7 +210,6 @@ sharkIntrinsics.cpp llvmHeaders.hpp sharkIntrinsics.cpp shark_globals.hpp sharkIntrinsics.cpp sharkIntrinsics.hpp -sharkIntrinsics.cpp sharkRuntime.hpp sharkIntrinsics.cpp sharkState.hpp sharkIntrinsics.cpp sharkValue.hpp @@ -246,15 +243,12 @@ sharkRuntime.cpp deoptimization.hpp sharkRuntime.cpp llvmHeaders.hpp sharkRuntime.cpp klassOop.hpp -sharkRuntime.cpp sharkBuilder.hpp sharkRuntime.cpp sharkRuntime.hpp -sharkRuntime.cpp sharkType.hpp sharkRuntime.cpp thread.hpp sharkRuntime.hpp allocation.hpp sharkRuntime.hpp llvmHeaders.hpp sharkRuntime.hpp klassOop.hpp -sharkRuntime.hpp sharkBuilder.hpp sharkRuntime.hpp thread.hpp sharkState.cpp allocation.hpp @@ -298,7 +292,6 @@ sharkTopLevelBlock.cpp sharkBuilder.hpp sharkTopLevelBlock.cpp sharkConstant.hpp sharkTopLevelBlock.cpp sharkInliner.hpp -sharkTopLevelBlock.cpp sharkRuntime.hpp sharkTopLevelBlock.cpp sharkState.hpp sharkTopLevelBlock.cpp sharkValue.hpp diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/shark/llvmValue.hpp --- a/ports/hotspot/src/share/vm/shark/llvmValue.hpp Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/llvmValue.hpp Thu Jul 30 04:51:32 2009 -0400 @@ -1,6 +1,6 @@ /* * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * Copyright 2008 Red Hat, Inc. + * Copyright 2008, 2009 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,6 +77,14 @@ } public: + static llvm::ConstantInt* bit_constant(int value) + { +#if SHARK_LLVM_VERSION >= 26 + return llvm::getGlobalContext().getConstantInt(llvm::Type::Int1Ty, value, false); +#else + return llvm::ConstantInt::get(llvm::Type::Int1Ty, value, false); +#endif + } static llvm::ConstantInt* intptr_constant(intptr_t value) { #if SHARK_LLVM_VERSION >= 26 diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/shark/sharkBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Thu Jul 30 04:51:32 2009 -0400 @@ -694,11 +694,13 @@ case Bytecodes::_f2i: push(SharkValue::create_jint( - call_vm_leaf(SharkRuntime::f2i(), pop()->jfloat_value()), false)); + builder()->CreateCall( + builder()->f2i(), pop()->jfloat_value()), false)); break; case Bytecodes::_f2l: push(SharkValue::create_jlong( - call_vm_leaf(SharkRuntime::f2l(), pop()->jfloat_value()), false)); + builder()->CreateCall( + builder()->f2l(), pop()->jfloat_value()), false)); break; case Bytecodes::_f2d: push(SharkValue::create_jdouble( @@ -708,11 +710,13 @@ case Bytecodes::_d2i: push(SharkValue::create_jint( - call_vm_leaf(SharkRuntime::d2i(), pop()->jdouble_value()), false)); + builder()->CreateCall( + builder()->d2i(), pop()->jdouble_value()), false)); break; case Bytecodes::_d2l: push(SharkValue::create_jlong( - call_vm_leaf(SharkRuntime::d2l(), pop()->jdouble_value()), false)); + builder()->CreateCall( + builder()->d2l(), pop()->jdouble_value()), false)); break; case Bytecodes::_d2f: push(SharkValue::create_jfloat( diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/shark/sharkBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkBlock.hpp Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkBlock.hpp Thu Jul 30 04:51:32 2009 -0400 @@ -174,13 +174,6 @@ protected: virtual void do_zero_check(SharkValue* value); - // Leaf calls - protected: - llvm::CallInst* call_vm_leaf(llvm::Constant* callee, llvm::Value* arg1) - { - return builder()->CreateCall(callee, arg1); - } - // Zero checking protected: void check_null(SharkValue* object) diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/shark/sharkBuilder.cpp --- a/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Thu Jul 30 04:51:32 2009 -0400 @@ -28,39 +28,7 @@ using namespace llvm; -#ifdef ARM -/* - * ARM lacks atomic operation implementation in LLVM - * http://llvm.org/bugs/show_bug.cgi?id=3877 - * - * These two functions zero_cmpxchg_int_fn and zero_cmpxchg_ptr_fn - * are defined so that they can be inserted into llvm as a workaround to - * make shark reroute all atomic calls back to the implementation in zero. - * The actual insertion are done in SharkBuilder::init_external_functions(). - */ - -extern "C" { - jint zero_cmpxchg_int_fn(volatile jint *ptr, - jint *oldval, - jint *newval) - { - return Atomic::cmpxchg(*newval, - ptr, - *oldval); - } - - intptr_t* zero_cmpxchg_ptr_fn(volatile void* ptr, - intptr_t* oldval, - intptr_t* newval) - { - return (intptr_t *) Atomic::cmpxchg_ptr((void *) newval, - ptr, - (void *) oldval); - } -}; -#endif - -SharkBuilder::SharkBuilder(SharkCompiler* compiler) +SharkBuilder::SharkBuilder(Module* module, SharkCodeBuffer* code_buffer) #if SHARK_LLVM_VERSION >= 26 // LLVM 2.6 requires a LLVMContext during IRBuilder construction. // getGlobalConext() returns one that can be used as long as the shark @@ -68,149 +36,480 @@ : IRBuilder<>(getGlobalContext()), #else : IRBuilder<>(), -#endif - _compiler(compiler) +#endif // SHARK_LLVM_VERSION >= 26 + _module(module), + _code_buffer(code_buffer) { - init_external_functions(); } -Constant* SharkBuilder::make_function(intptr_t addr, - const FunctionType* sig, - const char* name) +// Helpers for accessing structures +Value* SharkBuilder::CreateAddressOfStructEntry(Value* base, + ByteSize offset, + const Type* type, + const char* name) { - Constant *func = make_pointer(addr, sig); + return CreateBitCast(CreateStructGEP(base, in_bytes(offset)), type, name); +} + +LoadInst* SharkBuilder::CreateValueOfStructEntry(Value* base, + ByteSize offset, + const Type* type, + const char* name) +{ + return CreateLoad( + CreateAddressOfStructEntry( + base, offset, PointerType::getUnqual(type)), + name); +} + +// Helpers for accessing arrays + +LoadInst* SharkBuilder::CreateArrayLength(Value* arrayoop) +{ + return CreateValueOfStructEntry( + arrayoop, in_ByteSize(arrayOopDesc::length_offset_in_bytes()), + SharkType::jint_type(), "length"); +} + +Value* SharkBuilder::CreateArrayAddress(Value* arrayoop, + const Type* element_type, + int element_bytes, + ByteSize base_offset, + Value* index, + const char* name) +{ + Value* offset = CreateIntCast(index, SharkType::intptr_type(), false); + if (element_bytes != 1) + offset = CreateShl( + offset, + LLVMValue::intptr_constant(exact_log2(element_bytes))); + offset = CreateAdd( + LLVMValue::intptr_constant(in_bytes(base_offset)), offset); + + return CreateIntToPtr( + CreateAdd(CreatePtrToInt(arrayoop, SharkType::intptr_type()), offset), + PointerType::getUnqual(element_type), + name); +} + +Value* SharkBuilder::CreateArrayAddress(Value* arrayoop, + BasicType basic_type, + ByteSize base_offset, + Value* index, + const char* name) +{ + return CreateArrayAddress( + arrayoop, + SharkType::to_arrayType(basic_type), + type2aelembytes(basic_type), + base_offset, index, name); +} + +Value* SharkBuilder::CreateArrayAddress(Value* arrayoop, + BasicType basic_type, + Value* index, + const char* name) +{ + return CreateArrayAddress( + arrayoop, basic_type, + in_ByteSize(arrayOopDesc::base_offset_in_bytes(basic_type)), + index, name); +} + +// Helpers for creating intrinsics and external functions. + +const Type* SharkBuilder::make_type(char type, bool void_ok) +{ + switch (type) { + // Primitive types + case 'c': + return SharkType::jbyte_type(); + case 'i': + return SharkType::jint_type(); + case 'l': + return SharkType::jlong_type(); + case 'x': + return SharkType::intptr_type(); + case 'f': + return SharkType::jfloat_type(); + case 'd': + return SharkType::jdouble_type(); + + // Pointers to primitive types + case 'C': + case 'I': + case 'L': + case 'X': + case 'F': + case 'D': + return PointerType::getUnqual(make_type(tolower(type), false)); + + // VM objects + case 'T': + return SharkType::thread_type(); + case 'M': + return PointerType::getUnqual(SharkType::monitor_type()); + case 'O': + return SharkType::oop_type(); + + // Miscellaneous + case 'v': + assert(void_ok, "should be"); + return Type::VoidTy; + case '1': + return Type::Int1Ty; + + default: + ShouldNotReachHere(); + } +} + +const FunctionType* SharkBuilder::make_ftype(const char* params, + const char* ret) +{ + std::vector param_types; + for (const char* c = params; *c; c++) + param_types.push_back(make_type(*c, false)); + + assert(strlen(ret) == 1, "should be"); + const Type *return_type = make_type(*ret, true); + + return FunctionType::get(return_type, param_types, false); +} + +// Create an object representing an intrinsic or external function by +// referencing the symbol by name. This is the LLVM-style approach, +// but it cannot be used on functions within libjvm.so its symbols +// are not exported. Note that you cannot make this work simply by +// exporting the symbols, as some symbols have the same names as +// symbols in the standard libraries (eg, atan2, fabs) and would +// obscure them were they visible. +Value* SharkBuilder::make_function(const char* name, + const char* params, + const char* ret) +{ + return module()->getOrInsertFunction(name, make_ftype(params, ret)); +} + +// Create an object representing an external function by inlining a +// function pointer in the code. This is not the LLVM way, but it's +// the only way to access functions in libjvm.so and functions like +// __kernel_dmb on ARM which is accessed via an absolute address. +Value* SharkBuilder::make_function(address func, + const char* params, + const char* ret) +{ + return CreateIntToPtr( + LLVMValue::intptr_constant((intptr_t) func), + PointerType::getUnqual(make_ftype(params, ret))); +} + +// VM calls + +Value* SharkBuilder::find_exception_handler() +{ + return make_function( + (address) SharkRuntime::find_exception_handler, "TIi", "i"); +} + +Value* SharkBuilder::monitorenter() +{ + return make_function((address) SharkRuntime::monitorenter, "TM", "v"); +} + +Value* SharkBuilder::monitorexit() +{ + return make_function((address) SharkRuntime::monitorexit, "TM", "v"); +} + +Value* SharkBuilder::new_instance() +{ + return make_function((address) SharkRuntime::new_instance, "Ti", "v"); +} + +Value* SharkBuilder::newarray() +{ + return make_function((address) SharkRuntime::newarray, "Tii", "v"); +} + +Value* SharkBuilder::anewarray() +{ + return make_function((address) SharkRuntime::anewarray, "Tii", "v"); +} + +Value* SharkBuilder::multianewarray() +{ + return make_function((address) SharkRuntime::multianewarray, "TiiI", "v"); +} + +Value* SharkBuilder::register_finalizer() +{ + return make_function((address) SharkRuntime::register_finalizer, "TO", "v"); +} + +Value* SharkBuilder::safepoint() +{ + return make_function((address) SafepointSynchronize::block, "T", "v"); +} + +Value* SharkBuilder::throw_ArrayIndexOutOfBoundsException() +{ + return make_function( + (address) SharkRuntime::throw_ArrayIndexOutOfBoundsException, "TCii", "v"); +} + +Value* SharkBuilder::throw_NullPointerException() +{ + return make_function( + (address) SharkRuntime::throw_NullPointerException, "TCi", "v"); +} + +// High-level non-VM calls + +Value* SharkBuilder::f2i() +{ + return make_function((address) SharedRuntime::f2i, "f", "i"); +} + +Value* SharkBuilder::f2l() +{ + return make_function((address) SharedRuntime::f2l, "f", "l"); +} + +Value* SharkBuilder::d2i() +{ + return make_function((address) SharedRuntime::d2i, "d", "i"); +} + +Value* SharkBuilder::d2l() +{ + return make_function((address) SharedRuntime::d2l, "d", "l"); +} + +Value* SharkBuilder::is_subtype_of() +{ + return make_function((address) SharkRuntime::is_subtype_of, "OO", "c"); +} + +Value* SharkBuilder::current_time_millis() +{ + return make_function((address) os::javaTimeMillis, "", "l"); +} + +Value* SharkBuilder::sin() +{ + return make_function("llvm.sin.f64", "d", "d"); +} + +Value* SharkBuilder::cos() +{ + return make_function("llvm.cos.f64", "d", "d"); +} + +Value* SharkBuilder::tan() +{ + return make_function((address) ::tan, "d", "d"); +} + +Value* SharkBuilder::atan2() +{ + return make_function((address) ::atan2, "dd", "d"); +} + +Value* SharkBuilder::sqrt() +{ + return make_function("llvm.sqrt.f64", "d", "d"); +} + +Value* SharkBuilder::log() +{ + return make_function("llvm.log.f64", "d", "d"); +} + +Value* SharkBuilder::log10() +{ + return make_function("llvm.log10.f64", "d", "d"); +} + +Value* SharkBuilder::pow() +{ + return make_function("llvm.pow.f64", "dd", "d"); +} + +Value* SharkBuilder::exp() +{ + return make_function("llvm.exp.f64", "d", "d"); +} + +Value* SharkBuilder::fabs() +{ + return make_function((address) ::fabs, "d", "d"); +} + +Value* SharkBuilder::unsafe_field_offset_to_byte_offset() +{ + extern jlong Unsafe_field_offset_to_byte_offset(jlong field_offset); + return make_function((address) Unsafe_field_offset_to_byte_offset, "l", "l"); +} + +// Uncommon trap + +Value* SharkBuilder::uncommon_trap() +{ + return make_function((address) SharkRuntime::uncommon_trap, "Ti", "v"); +} + +// Low-level non-VM calls + +// The ARM-specific code here is to work around unimplemented +// atomic exchange and memory barrier intrinsics in LLVM. +// +// Delegating to external functions for these would normally +// incur a speed penalty, but Linux on ARM is a special case +// in that atomic operations on that platform are handled by +// external functions anyway. It would be *preferable* for +// the calls to be hidden away in LLVM, but it's not hurting +// performance so having the calls here is acceptable. +// +// If you are building Shark on a platform without atomic +// exchange and/or memory barrier intrinsics then it is only +// acceptable to mimic this approach if your platform cannot +// perform these operations without delegating to a function. + +#ifdef ARM +static jint zero_cmpxchg_int(volatile jint *ptr, jint *oldval, jint newval) +{ + return Atomic::cmpxchg(*newval, ptr, *oldval); +} +#endif // ARM + +Value* SharkBuilder::cmpxchg_int() +{ + return make_function( +#ifdef ARM + (address) zero_cmpxchg_int, +#else + "llvm.atomic.cmp.swap.i32", +#endif // ARM + "Iii", "i"); +} + +#ifdef ARM +static intptr_t zero_cmpxchg_ptr(volatile intptr_t* ptr, + intptr_t* oldval, + intptr_t* newval) +{ + return Atomic::cmpxchg_ptr(*newval, ptr, *oldval); +} +#endif // ARM + +Value* SharkBuilder::cmpxchg_ptr() +{ + return make_function( +#ifdef ARM + (address) zero_cmpxchg_ptr, +#else + "llvm.atomic.cmp.swap.i" LP64_ONLY("64") NOT_LP64("32"), +#endif // ARM + "Xxx", "x"); +} + +Value* SharkBuilder::memory_barrier() +{ + return make_function( +#ifdef ARM + (address) 0xffff0fa0, // __kernel_dmb +#else + "llvm.memory.barrier", +#endif // ARM + "11111", "v"); +} + +Value* SharkBuilder::memset() +{ + return make_function("llvm.memset.i32", "Ccii", "v"); +} + +Value* SharkBuilder::unimplemented() +{ + return make_function((address) report_unimplemented, "Ci", "v"); +} + +Value* SharkBuilder::should_not_reach_here() +{ + return make_function((address) report_should_not_reach_here, "Ci", "v"); +} + +Value* SharkBuilder::dump() +{ + return make_function((address) SharkRuntime::dump, "Cx", "v"); +} + +// Public interface to low-level non-VM calls + +CallInst* SharkBuilder::CreateCmpxchgInt(Value* exchange_value, + Value* dst, + Value* compare_value) +{ + return CreateCall3(cmpxchg_int(), dst, compare_value, exchange_value); +} + +CallInst* SharkBuilder::CreateCmpxchgPtr(Value* exchange_value, + Value* dst, + Value* compare_value) +{ + return CreateCall3(cmpxchg_ptr(), dst, compare_value, exchange_value); +} + +CallInst *SharkBuilder::CreateMemoryBarrier(int flags) +{ + Value *args[] = { + LLVMValue::bit_constant((flags & BARRIER_LOADLOAD) ? 1 : 0), + LLVMValue::bit_constant((flags & BARRIER_LOADSTORE) ? 1 : 0), + LLVMValue::bit_constant((flags & BARRIER_STORELOAD) ? 1 : 0), + LLVMValue::bit_constant((flags & BARRIER_STORESTORE) ? 1 : 0), + LLVMValue::bit_constant(0)}; + + return CreateCall(memory_barrier(), args, args + 5); +} + +CallInst* SharkBuilder::CreateMemset(Value* dst, + Value* value, + Value* len, + Value* align) +{ + return CreateCall4(memset(), dst, value, len, align); +} + +CallInst* SharkBuilder::CreateUnimplemented(const char* file, int line) +{ + return CreateCall2( + unimplemented(), + CreateIntToPtr( + LLVMValue::intptr_constant((intptr_t) file), + PointerType::getUnqual(SharkType::jbyte_type())), + LLVMValue::jint_constant(line)); +} + +CallInst* SharkBuilder::CreateShouldNotReachHere(const char* file, int line) +{ + return CreateCall2( + should_not_reach_here(), + CreateIntToPtr( + LLVMValue::intptr_constant((intptr_t) file), + PointerType::getUnqual(SharkType::jbyte_type())), + LLVMValue::jint_constant(line)); +} #ifndef PRODUCT - ResourceMark rm; - - // Use a trampoline to make dumped code more readable - Function *trampoline = (Function *) module()->getOrInsertFunction(name, sig); - SetInsertPoint(BasicBlock::Create("", trampoline)); - - Value **args = NEW_RESOURCE_ARRAY(Value*, trampoline->arg_size()); - Function::arg_iterator ai = trampoline->arg_begin(); - for (unsigned i = 0; i < trampoline->arg_size(); i++) - args[i] = ai++; - - Value *result = CreateCall(func, args, args + trampoline->arg_size()); - if (sig->getReturnType() == Type::VoidTy) - CreateRetVoid(); +CallInst* SharkBuilder::CreateDump(Value* value) +{ + const char *name; + if (value->hasName()) + // XXX this leaks, but it's only debug code + name = strdup(value->getName().c_str()); else - CreateRet(result); - - func = trampoline; -#endif // !PRODUCT - - return func; -} - -void SharkBuilder::init_external_functions() -{ - std::vector params; - params.push_back(PointerType::getUnqual(SharkType::jbyte_type())); - params.push_back(SharkType::jbyte_type()); - params.push_back(SharkType::jint_type()); - params.push_back(SharkType::jint_type()); - FunctionType *type = FunctionType::get(Type::VoidTy, params, false); - set_llvm_memset_fn(module()->getOrInsertFunction("llvm.memset.i32", type)); - - params.clear(); - params.push_back(PointerType::getUnqual(SharkType::jint_type())); - params.push_back(SharkType::jint_type()); - params.push_back(SharkType::jint_type()); - type = FunctionType::get(SharkType::jint_type(), params, false); - set_llvm_cmpxchg_int_fn( -#ifdef ARM - make_function( - (intptr_t) zero_cmpxchg_int_fn, - type, - "zero_cmpxchg_int_fn")); -#else - module()->getOrInsertFunction("llvm.atomic.cmp.swap.i32", type)); -#endif - - params.clear(); - params.push_back(PointerType::getUnqual(SharkType::intptr_type())); - params.push_back(SharkType::intptr_type()); - params.push_back(SharkType::intptr_type()); - type = FunctionType::get(SharkType::intptr_type(), params, false); - set_llvm_cmpxchg_ptr_fn( -#ifdef ARM - make_function( - (intptr_t) zero_cmpxchg_ptr_fn, - type, - "zero_cmpxchg_ptr_fn")); -#else - module()->getOrInsertFunction( - "llvm.atomic.cmp.swap.i" LP64_ONLY("64") NOT_LP64("32"), type)); -#endif - - /* - * The five booleans passed to llvm.memory.barrier are used like this: - * The first four arguments enables a specific barrier in this order: - * load-load, load-store, store-load and store-store. - * The fith argument specifies that the barrier applies to io or device - * or uncached memory. - */ - params.clear(); - for (int i = 0; i < 5; i++) - params.push_back(Type::Int1Ty); - type = FunctionType::get(Type::VoidTy, params, false); - set_llvm_memory_barrier_fn( -#ifdef ARM - make_function( - 0xffff0fa0, // __kernel_dmb - type, - "__kernel_dmb")); -#else - module()->getOrInsertFunction("llvm.memory.barrier", type)); -#endif - - params.clear(); - params.push_back(SharkType::jdouble_type()); - type = FunctionType::get(SharkType::jdouble_type(), params, false); - set_llvm_sin_fn (module()->getOrInsertFunction("llvm.sin.f64", type)); - set_llvm_cos_fn (module()->getOrInsertFunction("llvm.cos.f64", type)); - set_llvm_sqrt_fn (module()->getOrInsertFunction("llvm.sqrt.f64", type)); - set_llvm_log_fn (module()->getOrInsertFunction("llvm.log.f64", type)); - set_llvm_log10_fn(module()->getOrInsertFunction("llvm.log10.f64", type)); - set_llvm_exp_fn (module()->getOrInsertFunction("llvm.exp.f64", type)); - - params.clear(); - params.push_back(SharkType::jdouble_type()); - params.push_back(SharkType::jdouble_type()); - type = FunctionType::get(SharkType::jdouble_type(), params, false); - set_llvm_pow_fn(module()->getOrInsertFunction("llvm.pow.f64", type)); -} - -CallInst* SharkBuilder::CreateDump(llvm::Value* value) -{ - Constant *const_name; - if (value->hasName()) -#if SHARK_LLVM_VERSION >= 26 - const_name = getGlobalContext().getConstantArray(value->getName()); - else - const_name = getGlobalContext().getConstantArray("unnamed_value"); -#else - const_name = ConstantArray::get(value->getName()); - else - const_name = ConstantArray::get("unnamed_value"); -#endif - - Value *name = CreatePtrToInt( - CreateStructGEP( - new GlobalVariable( -#if SHARK_LLVM_VERSION >= 26 - // LLVM 2.6 requires a LLVMContext during GlobalVariable construction. - // getGlobalConext() returns one that can be used as long as the shark - // compiler are single-threaded. - getGlobalContext(), -#endif - const_name->getType(), - true, GlobalValue::InternalLinkage, - const_name, "dump", module()), - 0), - SharkType::intptr_type()); + name = "unnamed_value"; if (isa(value->getType())) value = CreatePtrToInt(value, SharkType::intptr_type()); @@ -219,65 +518,77 @@ else Unimplemented(); - Value *args[] = {name, value}; - return CreateCall2(SharkRuntime::dump(), name, value); + return CreateCall2( + dump(), + CreateIntToPtr( + LLVMValue::intptr_constant((intptr_t) name), + PointerType::getUnqual(SharkType::jbyte_type())), + value); +} +#endif // PRODUCT + +// HotSpot memory barriers + +void SharkBuilder::CreateUpdateBarrierSet(BarrierSet* bs, Value* field) +{ + if (bs->kind() != BarrierSet::CardTableModRef) + Unimplemented(); + + CreateStore( + LLVMValue::jbyte_constant(CardTableModRefBS::dirty_card), + CreateIntToPtr( + CreateAdd( + LLVMValue::intptr_constant( + (intptr_t) ((CardTableModRefBS *) bs)->byte_map_base), + CreateLShr( + CreatePtrToInt(field, SharkType::intptr_type()), + LLVMValue::intptr_constant(CardTableModRefBS::card_shift))), + PointerType::getUnqual(SharkType::jbyte_type()))); } -CallInst* SharkBuilder::CreateCmpxchgInt(Value* exchange_value, - Value* dst, - Value* compare_value) +// Helpers for accessing the code buffer + +Value* SharkBuilder::code_buffer_address(int offset) { - return CreateCall3( - llvm_cmpxchg_int_fn(), dst, compare_value, exchange_value); + return CreateAdd( + code_buffer()->base_pc(), + LLVMValue::intptr_constant(offset)); } -CallInst* SharkBuilder::CreateCmpxchgPtr(Value* exchange_value, - Value* dst, - Value* compare_value) +Value* SharkBuilder::CreateInlineOop(ciObject* object, const char* name) { - return CreateCall3( - llvm_cmpxchg_ptr_fn(), dst, compare_value, exchange_value); + return CreateLoad( + CreateIntToPtr( + code_buffer_address(code_buffer()->inline_oop(object)), + PointerType::getUnqual(SharkType::jobject_type())), + name); } -CallInst* SharkBuilder::CreateMemset(Value* dst, - Value* value, - Value* len, - Value* align) +// Helpers for creating basic blocks. + +BasicBlock* SharkBuilder::GetBlockInsertionPoint() const { - return CreateCall4(llvm_memset_fn(), dst, value, len, align); + BasicBlock *cur = GetInsertBlock(); + + // BasicBlock::Create takes an insertBefore argument, so + // we need to find the block _after_ the current block + Function::iterator iter = cur->getParent()->begin(); + Function::iterator end = cur->getParent()->end(); + while (iter != end) { + iter++; + if (&*iter == cur) { + iter++; + break; + } + } + + if (iter == end) + return NULL; + else + return iter; } -CallInst* SharkBuilder::CreateUnimplemented(const char* file, int line) +BasicBlock* SharkBuilder::CreateBlock(BasicBlock* ip, const char* name) const { - return CreateCall2( - SharkRuntime::unimplemented(), - pointer_constant(file), - LLVMValue::jint_constant(line)); -} - -CallInst* SharkBuilder::CreateShouldNotReachHere(const char* file, int line) -{ - return CreateCall2( - SharkRuntime::should_not_reach_here(), - pointer_constant(file), - LLVMValue::jint_constant(line)); -} - -CallInst *SharkBuilder::CreateMemoryBarrier(BarrierFlags flags) -{ - Value *args[] = { -#if SHARK_LLVM_VERSION >= 26 - getGlobalContext().getConstantInt(Type::Int1Ty, (flags & BARRIER_LOADLOAD) ? 1 : 0), - getGlobalContext().getConstantInt(Type::Int1Ty, (flags & BARRIER_LOADSTORE) ? 1 : 0), - getGlobalContext().getConstantInt(Type::Int1Ty, (flags & BARRIER_STORELOAD) ? 1 : 0), - getGlobalContext().getConstantInt(Type::Int1Ty, (flags & BARRIER_STORESTORE) ? 1 : 0), - getGlobalContext().getConstantInt(Type::Int1Ty, 0)}; -#else - ConstantInt::get(Type::Int1Ty, (flags & BARRIER_LOADLOAD) ? 1 : 0), - ConstantInt::get(Type::Int1Ty, (flags & BARRIER_LOADSTORE) ? 1 : 0), - ConstantInt::get(Type::Int1Ty, (flags & BARRIER_STORELOAD) ? 1 : 0), - ConstantInt::get(Type::Int1Ty, (flags & BARRIER_STORESTORE) ? 1 : 0), - ConstantInt::get(Type::Int1Ty, 0)}; -#endif - return CreateCall(llvm_memory_barrier_fn(), args, args + 5); -} + return BasicBlock::Create(name, GetInsertBlock()->getParent(), ip); +} diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/shark/sharkBuilder.hpp --- a/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Thu Jul 30 04:51:32 2009 -0400 @@ -24,322 +24,150 @@ */ class SharkBuilder : public llvm::IRBuilder<> { - public: - SharkBuilder(SharkCompiler* compiler); - - private: - SharkCompiler* _compiler; + friend class SharkCompileInvariants; public: - SharkCompiler* compiler() const - { - return _compiler; - } + SharkBuilder(llvm::Module* module, SharkCodeBuffer* code_buffer); + + // The LLVM module and Shark code buffer we are building into. + private: + llvm::Module* _module; + SharkCodeBuffer* _code_buffer; private: llvm::Module* module() const { - return compiler()->module(); + return _module; } - llvm::ExecutionEngine* execution_engine() const + protected: + SharkCodeBuffer* code_buffer() const { - return compiler()->execution_engine(); + return _code_buffer; } - // Helpers for creating basic blocks - // NB don't use unless SharkFunction::CreateBlock is unavailable - public: - llvm::BasicBlock* GetBlockInsertionPoint() const - { - llvm::BasicBlock *cur = GetInsertBlock(); - - // BasicBlock::Create takes an insertBefore argument, so - // we need to find the block _after_ the current block - llvm::Function::iterator iter = cur->getParent()->begin(); - llvm::Function::iterator end = cur->getParent()->end(); - while (iter != end) { - iter++; - if (&*iter == cur) { - iter++; - break; - } - } - - if (iter == end) - return NULL; - else - return iter; - } - llvm::BasicBlock* CreateBlock(llvm::BasicBlock* ip, const char* name="") const - { - return llvm::BasicBlock::Create(name, GetInsertBlock()->getParent(), ip); - } - - // Helpers for accessing structures and arrays + // Helpers for accessing structures. public: llvm::Value* CreateAddressOfStructEntry(llvm::Value* base, ByteSize offset, const llvm::Type* type, - const char *name = "") - { - return CreateBitCast(CreateStructGEP(base, in_bytes(offset)), type, name); - } - + const char *name = ""); llvm::LoadInst* CreateValueOfStructEntry(llvm::Value* base, ByteSize offset, const llvm::Type* type, - const char *name = "") - { - return CreateLoad( - CreateAddressOfStructEntry( - base, offset, llvm::PointerType::getUnqual(type)), - name); - } + const char *name = ""); - llvm::LoadInst* CreateArrayLength(llvm::Value* array) - { - return CreateValueOfStructEntry( - array, in_ByteSize(arrayOopDesc::length_offset_in_bytes()), - SharkType::jint_type(), "length"); - } - + // Helpers for accessing arrays. + public: + llvm::LoadInst* CreateArrayLength(llvm::Value* arrayoop); llvm::Value* CreateArrayAddress(llvm::Value* arrayoop, const llvm::Type* element_type, int element_bytes, ByteSize base_offset, llvm::Value* index, - const char* name = "") - { - llvm::Value* offset = CreateIntCast(index, SharkType::intptr_type(), false); - if (element_bytes != 1) - offset = CreateShl( - offset, - LLVMValue::intptr_constant(exact_log2(element_bytes))); - offset = CreateAdd( - LLVMValue::intptr_constant(in_bytes(base_offset)), offset); - - return CreateIntToPtr( - CreateAdd(CreatePtrToInt(arrayoop, SharkType::intptr_type()), offset), - llvm::PointerType::getUnqual(element_type), - name); - } - + const char* name = ""); llvm::Value* CreateArrayAddress(llvm::Value* arrayoop, BasicType basic_type, ByteSize base_offset, llvm::Value* index, - const char* name = "") - { - return CreateArrayAddress( - arrayoop, - SharkType::to_arrayType(basic_type), - type2aelembytes(basic_type), - base_offset, index, name); - } - + const char* name = ""); llvm::Value* CreateArrayAddress(llvm::Value* arrayoop, BasicType basic_type, llvm::Value* index, - const char* name = "") - { - return CreateArrayAddress( - arrayoop, basic_type, - in_ByteSize(arrayOopDesc::base_offset_in_bytes(basic_type)), - index, name); - } + const char* name = ""); - // Helper for making function pointers + // Helpers for creating intrinsics and external functions. + private: + static const llvm::Type* make_type(char type, bool void_ok); + static const llvm::FunctionType* make_ftype(const char* params, + const char* ret); + llvm::Value* make_function(const char* name, + const char* params, + const char* ret); + llvm::Value* make_function(address func, + const char* params, + const char* ret); + + // Intrinsics and external functions, part 1: VM calls. + // These are functions declared with JRT_ENTRY and JRT_EXIT, + // macros which flip the thread from _thread_in_Java to + // _thread_in_vm and back. VM calls always safepoint, and can + // therefore throw exceptions. VM calls require of setup and + // teardown, and must be called with SharkTopLevelBlock::call_vm. public: - llvm::Constant* make_function(intptr_t addr, - const llvm::FunctionType* sig, - const char* name); + llvm::Value* find_exception_handler(); + llvm::Value* monitorenter(); + llvm::Value* monitorexit(); + llvm::Value* new_instance(); + llvm::Value* newarray(); + llvm::Value* anewarray(); + llvm::Value* multianewarray(); + llvm::Value* register_finalizer(); + llvm::Value* safepoint(); + llvm::Value* throw_ArrayIndexOutOfBoundsException(); + llvm::Value* throw_NullPointerException(); - llvm::Constant* pointer_constant(const void *ptr) - { -#if SHARK_LLVM_VERSION >= 25 || !defined(AMD64) - return LLVMValue::intptr_constant((intptr_t) ptr); -#else - // Create a pointer constant that points at PTR. We do this by - // creating a GlobalVariable mapped at PTR. This is a workaround - // for http://www.llvm.org/bugs/show_bug.cgi?id=2920 + // Intrinsics and external functions, part 2: High-level non-VM calls. + // These are called like normal functions. The stack is not set + // up for walking so they must not safepoint or throw exceptions, + // or call anything that might. + public: + llvm::Value* f2i(); + llvm::Value* f2l(); + llvm::Value* d2i(); + llvm::Value* d2l(); + llvm::Value* is_subtype_of(); + llvm::Value* current_time_millis(); + llvm::Value* sin(); + llvm::Value* cos(); + llvm::Value* tan(); + llvm::Value* atan2(); + llvm::Value* sqrt(); + llvm::Value* log(); + llvm::Value* log10(); + llvm::Value* pow(); + llvm::Value* exp(); + llvm::Value* fabs(); + llvm::Value* unsafe_field_offset_to_byte_offset(); - using namespace llvm; + // Intrinsics and external functions, part 3: Uncommon trap. + // This is a special case in that it is invoked like a non-VM + // call but it does VM call stuff. This is acceptable so long + // as the method that calls uncommon_trap returns to its caller + // immediately that uncommon_trap returns. + public: + llvm::Value* uncommon_trap(); - // This might be useful but it returns a const pointer that can't - // be used for anything. Go figure... -// { -// const GlobalValue *value -// = execution_engine()->getGlobalValueAtAddress(const_cast(ptr)); -// if (value) -// return ConstantExpr::getPtrToInt(value, SharkType::intptr_type()); -// } + // Intrinsics and external functions, part 4: Low-level non-VM calls. + // These have the same caveats as the high-level non-VM calls + // above. They are not accessed directly; rather, you should + // access them via the various Create* methods below. + private: + llvm::Value* cmpxchg_int(); + llvm::Value* cmpxchg_ptr(); + llvm::Value* memory_barrier(); + llvm::Value* memset(); + llvm::Value* unimplemented(); + llvm::Value* should_not_reach_here(); + llvm::Value* dump(); - char name[128]; - snprintf(name, sizeof name - 1, "pointer_constant_%p", ptr); - - GlobalVariable *value = new GlobalVariable( - SharkType::intptr_type(), - false, GlobalValue::ExternalLinkage, - NULL, name, module()); - execution_engine()->addGlobalMapping(value, const_cast(ptr)); - - return ConstantExpr::getPtrToInt(value, SharkType::intptr_type()); -#endif // SHARK_LLVM_VERSION >= 25 || !AMD64 - } - - // Helper for making pointers + // Public interface to low-level non-VM calls. public: - llvm::Constant* make_pointer(intptr_t addr, const llvm::Type* type) - { - return llvm::ConstantExpr::getIntToPtr( - LLVMValue::intptr_constant(addr), - llvm::PointerType::getUnqual(type)); - } - - // External functions (and intrinsics) - private: - llvm::Constant* _llvm_cmpxchg_int_fn; - llvm::Constant* _llvm_cmpxchg_ptr_fn; - llvm::Constant* _llvm_memory_barrier_fn; - llvm::Constant* _llvm_memset_fn; - llvm::Constant* _llvm_sin_fn; - llvm::Constant* _llvm_cos_fn; - llvm::Constant* _llvm_sqrt_fn; - llvm::Constant* _llvm_log_fn; - llvm::Constant* _llvm_log10_fn; - llvm::Constant* _llvm_pow_fn; - llvm::Constant* _llvm_exp_fn; - - void set_llvm_cmpxchg_int_fn(llvm::Constant* llvm_cmpxchg_int_fn) - { - _llvm_cmpxchg_int_fn = llvm_cmpxchg_int_fn; - } - void set_llvm_cmpxchg_ptr_fn(llvm::Constant* llvm_cmpxchg_ptr_fn) - { - _llvm_cmpxchg_ptr_fn = llvm_cmpxchg_ptr_fn; - } - void set_llvm_memory_barrier_fn(llvm::Constant* llvm_memory_barrier_fn) - { - _llvm_memory_barrier_fn = llvm_memory_barrier_fn; - } - void set_llvm_memset_fn(llvm::Constant* llvm_memset_fn) - { - _llvm_memset_fn = llvm_memset_fn; - } - void set_llvm_sin_fn(llvm::Constant* llvm_sin_fn) - { - _llvm_sin_fn = llvm_sin_fn; - } - void set_llvm_cos_fn(llvm::Constant* llvm_cos_fn) - { - _llvm_cos_fn = llvm_cos_fn; - } - void set_llvm_sqrt_fn(llvm::Constant* llvm_sqrt_fn) - { - _llvm_sqrt_fn = llvm_sqrt_fn; - } - void set_llvm_log_fn(llvm::Constant* llvm_log_fn) - { - _llvm_log_fn = llvm_log_fn; - } - void set_llvm_log10_fn(llvm::Constant* llvm_log10_fn) - { - _llvm_log10_fn = llvm_log10_fn; - } - void set_llvm_pow_fn(llvm::Constant* llvm_pow_fn) - { - _llvm_pow_fn = llvm_pow_fn; - } - void set_llvm_exp_fn(llvm::Constant* llvm_exp_fn) - { - _llvm_exp_fn = llvm_exp_fn; - } - - void init_external_functions(); - - protected: - llvm::Constant* llvm_cmpxchg_int_fn() const - { - return _llvm_cmpxchg_int_fn; - } - llvm::Constant* llvm_cmpxchg_ptr_fn() const - { - return _llvm_cmpxchg_ptr_fn; - } - llvm::Constant* llvm_memory_barrier_fn() const - { - return _llvm_memory_barrier_fn; - } - llvm::Constant* llvm_memset_fn() const - { - return _llvm_memset_fn; - } - - public: - llvm::Constant* llvm_sin_fn() const - { - return _llvm_sin_fn; - } - llvm::Constant* llvm_cos_fn() const - { - return _llvm_cos_fn; - } - llvm::Constant* llvm_sqrt_fn() const - { - return _llvm_sqrt_fn; - } - llvm::Constant* llvm_log_fn() const - { - return _llvm_log_fn; - } - llvm::Constant* llvm_log10_fn() const - { - return _llvm_log10_fn; - } - llvm::Constant* llvm_pow_fn() const - { - return _llvm_pow_fn; - } - llvm::Constant* llvm_exp_fn() const - { - return _llvm_exp_fn; - } - - public: - llvm::CallInst* CreateDump(llvm::Value* value); + llvm::CallInst* CreateCmpxchgInt(llvm::Value* exchange_value, + llvm::Value* dst, + llvm::Value* compare_value); + llvm::CallInst* CreateCmpxchgPtr(llvm::Value* exchange_value, + llvm::Value* dst, + llvm::Value* compare_value); + llvm::CallInst* CreateMemoryBarrier(int flags); llvm::CallInst* CreateMemset(llvm::Value* dst, llvm::Value* value, llvm::Value* len, llvm::Value* align); - llvm::CallInst* CreateCmpxchgInt(llvm::Value* exchange_value, - llvm::Value* dst, - llvm::Value* compare_value); - llvm::CallInst* CreateCmpxchgPtr(llvm::Value* exchange_value, - llvm::Value* dst, - llvm::Value* compare_value); + llvm::CallInst* CreateUnimplemented(const char* file, int line); llvm::CallInst* CreateShouldNotReachHere(const char* file, int line); - llvm::CallInst* CreateUnimplemented(const char* file, int line); - - // HotSpot memory barriers - public: - void CreateUpdateBarrierSet(BarrierSet* bs, llvm::Value* field) - { - if (bs->kind() != BarrierSet::CardTableModRef) { - Unimplemented(); - } - - CreateStore( - LLVMValue::jbyte_constant(CardTableModRefBS::dirty_card), - CreateIntToPtr( - CreateAdd( - pointer_constant(((CardTableModRefBS *) bs)->byte_map_base), - CreateLShr( - CreatePtrToInt(field, SharkType::intptr_type()), - LLVMValue::intptr_constant(CardTableModRefBS::card_shift))), - llvm::PointerType::getUnqual(SharkType::jbyte_type()))); - } - - // Hardware memory barriers + NOT_PRODUCT(llvm::CallInst* CreateDump(llvm::Value* value)); + + // Flags for CreateMemoryBarrier. public: enum BarrierFlags { BARRIER_LOADLOAD = 1, @@ -348,48 +176,20 @@ BARRIER_STORESTORE = 8 }; + // HotSpot memory barriers public: - llvm::CallInst* CreateMemoryBarrier(BarrierFlags flags); + void CreateUpdateBarrierSet(BarrierSet* bs, llvm::Value* field); - // Alignment + // Helpers for accessing the code buffer. public: - llvm::Value* CreateAlign(llvm::Value* x, intptr_t s, const char* name = "") - { - assert(is_power_of_2(s), "should be"); - return CreateAnd( - CreateAdd(x, LLVMValue::intptr_constant(s - 1)), - LLVMValue::intptr_constant(~(s - 1)), - name); - } + llvm::Value* code_buffer_address(int offset); + llvm::Value* CreateInlineOop(ciObject* object, const char* name = ""); - // CodeBuffer interface - private: - SharkCodeBuffer* _code_buffer; - + // Helpers for creating basic blocks. + // NB don't use unless SharkFunction::CreateBlock is unavailable. + // XXX these are hacky and should be removed. public: - SharkCodeBuffer* code_buffer() const - { - return _code_buffer; - } - void set_code_buffer(SharkCodeBuffer* code_buffer) - { - _code_buffer = code_buffer; - } - - public: - llvm::Value* code_buffer_address(int offset) - { - return CreateAdd( - code_buffer()->base_pc(), LLVMValue::intptr_constant(offset)); - } - - public: - llvm::Value* CreateInlineOop(ciObject* object, const char* name = "") - { - return CreateLoad( - CreateIntToPtr( - code_buffer_address(code_buffer()->inline_oop(object)), - llvm::PointerType::getUnqual(SharkType::jobject_type())), - name); - } + llvm::BasicBlock* GetBlockInsertionPoint() const; + llvm::BasicBlock* CreateBlock(llvm::BasicBlock* ip, + const char* name="") const; }; diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp --- a/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp Thu Jul 30 04:51:32 2009 -0400 @@ -31,7 +31,7 @@ void SharkDecacher::start_frame() { // Start recording the debug information - _pc_offset = builder()->code_buffer()->create_unique_offset(); + _pc_offset = code_buffer()->create_unique_offset(); _oopmap = new OopMap( oopmap_slot_munge(function()->oopmap_frame_size()), oopmap_slot_munge(arg_size())); diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/shark/sharkCompiler.cpp --- a/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp Thu Jul 30 04:51:32 2009 -0400 @@ -53,9 +53,6 @@ _module = new Module("shark"); #endif - // Create the builder to build our functions - _builder = new SharkBuilder(this); - #if SHARK_LLVM_VERSION >= 26 // If we have a native target, initialize it to ensure it is linked in and // usable by the JIT. @@ -82,7 +79,6 @@ // Initialize Shark components that need it SharkType::initialize(); - SharkRuntime::initialize(builder()); mark_initialized(); } @@ -137,22 +133,19 @@ env->debug_info()->set_oopmaps(&oopmaps); env->set_dependencies(new Dependencies(env)); - // Create the code buffer and hook it into the builder + // Create the code buffer and builder SharkCodeBuffer cb(env->oop_recorder()); - builder()->set_code_buffer(&cb); + SharkBuilder builder(module(), &cb); // Emit the entry point SharkEntry *entry = (SharkEntry *) cb.malloc(sizeof(SharkEntry)); // Build the LLVM IR for the method - Function *function = SharkFunction::build(this, env, flow, name); + Function *function = SharkFunction::build(this, env, &builder, flow, name); if (SharkPrintBitcodeOf != NULL) { if (!fnmatch(SharkPrintBitcodeOf, name, 0)) function->dump(); } - - // Unhook the code buffer - builder()->set_code_buffer(NULL); // Compile to native code #ifndef PRODUCT diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/shark/sharkCompiler.hpp --- a/ports/hotspot/src/share/vm/shark/sharkCompiler.hpp Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.hpp Thu Jul 30 04:51:32 2009 -0400 @@ -22,8 +22,6 @@ * have any questions. * */ - -class SharkBuilder; class SharkCompiler : public AbstractCompiler { public: @@ -50,7 +48,6 @@ // LLVM interface private: llvm::Module* _module; - SharkBuilder* _builder; SharkMemoryManager* _memory_manager; llvm::ExecutionEngine* _execution_engine; @@ -58,10 +55,6 @@ llvm::Module* module() const { return _module; - } - SharkBuilder* builder() const - { - return _builder; } SharkMemoryManager* memory_manager() const { diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/shark/sharkFunction.cpp --- a/ports/hotspot/src/share/vm/shark/sharkFunction.cpp Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkFunction.cpp Thu Jul 30 04:51:32 2009 -0400 @@ -42,7 +42,7 @@ method->setName("method"); Argument *base_pc = ai++; base_pc->setName("base_pc"); - builder()->code_buffer()->set_base_pc(base_pc); + code_buffer()->set_base_pc(base_pc); Argument *thread = ai++; thread->setName("thread"); set_thread(thread); diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/shark/sharkFunction.hpp --- a/ports/hotspot/src/share/vm/shark/sharkFunction.hpp Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkFunction.hpp Thu Jul 30 04:51:32 2009 -0400 @@ -30,19 +30,21 @@ public: static llvm::Function* build(SharkCompiler* compiler, ciEnv* env, + SharkBuilder* builder, ciTypeFlow* flow, const char* name) { - SharkFunction function(compiler, env, flow, name); + SharkFunction function(compiler, env, builder, flow, name); return function.function(); } private: SharkFunction(SharkCompiler* compiler, ciEnv* env, + SharkBuilder* builder, ciTypeFlow* flow, const char* name) - : SharkTargetInvariants(compiler, env, flow) { initialize(name); } + : SharkTargetInvariants(compiler, env, builder, flow) { initialize(name); } private: void initialize(const char* name); diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/shark/sharkIntrinsics.cpp --- a/ports/hotspot/src/share/vm/shark/sharkIntrinsics.cpp Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkIntrinsics.cpp Thu Jul 30 04:51:32 2009 -0400 @@ -92,34 +92,34 @@ do_Math_minmax(llvm::ICmpInst::ICMP_SGE); break; case vmIntrinsics::_dabs: - do_Math_1to1(SharkRuntime::fabs()); + do_Math_1to1(builder()->fabs()); break; case vmIntrinsics::_dsin: - do_Math_1to1(builder()->llvm_sin_fn()); + do_Math_1to1(builder()->sin()); break; case vmIntrinsics::_dcos: - do_Math_1to1(builder()->llvm_cos_fn()); + do_Math_1to1(builder()->cos()); break; case vmIntrinsics::_dtan: - do_Math_1to1(SharkRuntime::tan()); + do_Math_1to1(builder()->tan()); break; case vmIntrinsics::_datan2: - do_Math_2to1(SharkRuntime::atan2()); + do_Math_2to1(builder()->atan2()); break; case vmIntrinsics::_dsqrt: - do_Math_1to1(builder()->llvm_sqrt_fn()); + do_Math_1to1(builder()->sqrt()); break; case vmIntrinsics::_dlog: - do_Math_1to1(builder()->llvm_log_fn()); + do_Math_1to1(builder()->log()); break; case vmIntrinsics::_dlog10: - do_Math_1to1(builder()->llvm_log10_fn()); + do_Math_1to1(builder()->log10()); break; case vmIntrinsics::_dpow: - do_Math_2to1(builder()->llvm_pow_fn()); + do_Math_2to1(builder()->pow()); break; case vmIntrinsics::_dexp: - do_Math_1to1(builder()->llvm_exp_fn()); + do_Math_1to1(builder()->exp()); break; // java.lang.Object @@ -181,7 +181,7 @@ sa->zero_checked() && sb->zero_checked())); } -void SharkIntrinsics::do_Math_1to1(Constant *function) +void SharkIntrinsics::do_Math_1to1(Value *function) { SharkValue *empty = state()->pop(); assert(empty == NULL, "should be"); @@ -192,7 +192,7 @@ state()->push(NULL); } -void SharkIntrinsics::do_Math_2to1(Constant *function) +void SharkIntrinsics::do_Math_2to1(Value *function) { SharkValue *empty = state()->pop(); assert(empty == NULL, "should be"); @@ -235,7 +235,7 @@ { state()->push( SharkValue::create_jlong( - builder()->CreateCall(SharkRuntime::current_time_millis()), + builder()->CreateCall(builder()->current_time_millis()), false)); state()->push(NULL); } @@ -264,7 +264,7 @@ // Convert the offset offset = builder()->CreateCall( - SharkRuntime::unsafe_field_offset_to_byte_offset(), + builder()->unsafe_field_offset_to_byte_offset(), offset); // Locate the field diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/shark/sharkIntrinsics.hpp --- a/ports/hotspot/src/share/vm/shark/sharkIntrinsics.hpp Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkIntrinsics.hpp Thu Jul 30 04:51:32 2009 -0400 @@ -46,8 +46,8 @@ private: void do_Math_minmax(llvm::ICmpInst::Predicate p); - void do_Math_1to1(llvm::Constant* function); - void do_Math_2to1(llvm::Constant* function); + void do_Math_1to1(llvm::Value* function); + void do_Math_2to1(llvm::Value* function); void do_Object_getClass(); void do_System_currentTimeMillis(); void do_Thread_currentThread(); diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/shark/sharkInvariants.hpp --- a/ports/hotspot/src/share/vm/shark/sharkInvariants.hpp Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkInvariants.hpp Thu Jul 30 04:51:32 2009 -0400 @@ -31,25 +31,30 @@ class SharkCompileInvariants : public ResourceObj { protected: - SharkCompileInvariants(SharkCompiler* compiler, ciEnv* env) + SharkCompileInvariants(SharkCompiler* compiler, + ciEnv* env, + SharkBuilder* builder) : _compiler(compiler), _env(env), + _builder(builder), _thread(NULL) {} SharkCompileInvariants(const SharkCompileInvariants* parent) : _compiler(parent->_compiler), _env(parent->_env), + _builder(parent->_builder), _thread(parent->_thread) {} private: SharkCompiler* _compiler; ciEnv* _env; + SharkBuilder* _builder; llvm::Value* _thread; // The SharkCompiler that is compiling this method. Holds the - // classes that form the interface with LLVM (the builder, the - // module, the memory manager, etc) and provides the compile() - // method to convert LLVM functions to native code. + // classes that form the interface with LLVM (the module, the + // memory manager, etc) and provides the compile() method to + // convert LLVM functions to native code. protected: SharkCompiler* compiler() const { @@ -71,6 +76,13 @@ return _env; } + // The SharkBuilder that is used to build LLVM IR. + protected: + SharkBuilder* builder() const + { + return _builder; + } + // Pointer to this thread's JavaThread object. This is not // available until a short way into SharkFunction creation // so a setter is required. Assertions are used to enforce @@ -89,10 +101,6 @@ // Objects that handle various aspects of the compilation. protected: - SharkBuilder* builder() const - { - return compiler()->builder(); - } DebugInformationRecorder* debug_info() const { return env()->debug_info(); @@ -100,6 +108,10 @@ Dependencies* dependencies() const { return env()->dependencies(); + } + SharkCodeBuffer* code_buffer() const + { + return builder()->code_buffer(); } // That well-known class... @@ -112,8 +124,11 @@ class SharkTargetInvariants : public SharkCompileInvariants { protected: - SharkTargetInvariants(SharkCompiler* compiler, ciEnv* env, ciTypeFlow* flow) - : SharkCompileInvariants(compiler, env), + SharkTargetInvariants(SharkCompiler* compiler, + ciEnv* env, + SharkBuilder* builder, + ciTypeFlow* flow) + : SharkCompileInvariants(compiler, env, builder), _target(flow->method()), _flow(flow), _max_monitors(count_monitors()) {} diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/shark/sharkRuntime.cpp --- a/ports/hotspot/src/share/vm/shark/sharkRuntime.cpp Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkRuntime.cpp Thu Jul 30 04:51:32 2009 -0400 @@ -28,222 +28,9 @@ using namespace llvm; -// VM calls -Constant* SharkRuntime::_find_exception_handler; -Constant* SharkRuntime::_monitorenter; -Constant* SharkRuntime::_monitorexit; -Constant* SharkRuntime::_new_instance; -Constant* SharkRuntime::_newarray; -Constant* SharkRuntime::_anewarray; -Constant* SharkRuntime::_multianewarray; -Constant* SharkRuntime::_register_finalizer; -Constant* SharkRuntime::_safepoint; -Constant* SharkRuntime::_throw_ArrayIndexOutOfBoundsException; -Constant* SharkRuntime::_throw_NullPointerException; - -// Leaf calls -Constant* SharkRuntime::_f2i; -Constant* SharkRuntime::_f2l; -Constant* SharkRuntime::_d2i; -Constant* SharkRuntime::_d2l; - -// Non-VM calls -Constant* SharkRuntime::_dump; -Constant* SharkRuntime::_is_subtype_of; -Constant* SharkRuntime::_should_not_reach_here; -Constant* SharkRuntime::_unimplemented; -Constant* SharkRuntime::_uncommon_trap; -Constant* SharkRuntime::_current_time_millis; -Constant* SharkRuntime::_fabs; -Constant* SharkRuntime::_tan; -Constant* SharkRuntime::_atan2; -Constant* SharkRuntime::_unsafe_field_offset_to_byte_offset; - -extern jlong Unsafe_field_offset_to_byte_offset(jlong field_offset); - -void SharkRuntime::initialize(SharkBuilder* builder) -{ - // VM calls - std::vector params; - params.push_back(SharkType::thread_type()); - params.push_back(PointerType::getUnqual(SharkType::jint_type())); - params.push_back(SharkType::jint_type()); - _find_exception_handler = builder->make_function( - (intptr_t) find_exception_handler_C, - FunctionType::get(SharkType::jint_type(), params, false), - "SharkRuntime__find_exception_handler"); - - params.clear(); - params.push_back(SharkType::thread_type()); - params.push_back(PointerType::getUnqual(SharkType::monitor_type())); - _monitorenter = builder->make_function( - (intptr_t) monitorenter_C, - FunctionType::get(Type::VoidTy, params, false), - "SharkRuntime__monitorenter"); - _monitorexit = builder->make_function( - (intptr_t) monitorexit_C, - FunctionType::get(Type::VoidTy, params, false), - "SharkRuntime__monitorexit"); - - params.clear(); - params.push_back(SharkType::thread_type()); - params.push_back(SharkType::jint_type()); - _new_instance = builder->make_function( - (intptr_t) new_instance_C, - FunctionType::get(Type::VoidTy, params, false), - "SharkRuntime__new_instance"); - - params.clear(); - params.push_back(SharkType::thread_type()); - params.push_back(SharkType::jint_type()); - params.push_back(SharkType::jint_type()); - _newarray = builder->make_function( - (intptr_t) newarray_C, - FunctionType::get(Type::VoidTy, params, false), - "SharkRuntime__newarray"); - _anewarray = builder->make_function( - (intptr_t) anewarray_C, - FunctionType::get(Type::VoidTy, params, false), - "SharkRuntime__anewarray"); - - params.clear(); - params.push_back(SharkType::thread_type()); - params.push_back(SharkType::jint_type()); - params.push_back(SharkType::jint_type()); - params.push_back(PointerType::getUnqual(SharkType::jint_type())); - _multianewarray = builder->make_function( - (intptr_t) multianewarray_C, - FunctionType::get(Type::VoidTy, params, false), - "SharkRuntime__multianewarray"); - - params.clear(); - params.push_back(SharkType::thread_type()); - params.push_back(SharkType::oop_type()); - _register_finalizer = builder->make_function( - (intptr_t) register_finalizer_C, - FunctionType::get(Type::VoidTy, params, false), - "SharkRuntime__register_finalizer"); - - params.clear(); - params.push_back(SharkType::thread_type()); - _safepoint = builder->make_function( - (intptr_t) SafepointSynchronize::block, - FunctionType::get(Type::VoidTy, params, false), - "SafepointSynchronize__block"); - - params.clear(); - params.push_back(SharkType::thread_type()); - params.push_back(SharkType::intptr_type()); - params.push_back(SharkType::jint_type()); - params.push_back(SharkType::jint_type()); - _throw_ArrayIndexOutOfBoundsException = builder->make_function( - (intptr_t) throw_ArrayIndexOutOfBoundsException_C, - FunctionType::get(Type::VoidTy, params, false), - "SharkRuntime__throw_ArrayIndexOutOfBoundsException"); - - params.clear(); - params.push_back(SharkType::thread_type()); - params.push_back(SharkType::intptr_type()); - params.push_back(SharkType::jint_type()); - _throw_NullPointerException = builder->make_function( - (intptr_t) throw_NullPointerException_C, - FunctionType::get(Type::VoidTy, params, false), - "SharkRuntime__throw_NullPointerException"); - - // Leaf calls - params.clear(); - params.push_back(SharkType::jfloat_type()); - _f2i = builder->make_function( - (intptr_t) SharedRuntime::f2i, - FunctionType::get(SharkType::jint_type(), params, false), - "SharedRuntime__f2i"); - _f2l = builder->make_function( - (intptr_t) SharedRuntime::f2l, - FunctionType::get(SharkType::jlong_type(), params, false), - "SharedRuntime__f2l"); - - params.clear(); - params.push_back(SharkType::jdouble_type()); - _d2i = builder->make_function( - (intptr_t) SharedRuntime::d2i, - FunctionType::get(SharkType::jint_type(), params, false), - "SharedRuntime__d2i"); - _d2l = builder->make_function( - (intptr_t) SharedRuntime::d2l, - FunctionType::get(SharkType::jlong_type(), params, false), - "SharedRuntime__d2l"); - - // Non-VM calls - params.clear(); - params.push_back(SharkType::intptr_type()); - params.push_back(SharkType::intptr_type()); - _dump = builder->make_function( - (intptr_t) dump_C, - FunctionType::get(Type::VoidTy, params, false), - "SharkRuntime__dump"); - - params.clear(); - params.push_back(SharkType::oop_type()); - params.push_back(SharkType::oop_type()); - assert(sizeof(bool) == 1, "fix this"); - _is_subtype_of = builder->make_function( - (intptr_t) is_subtype_of_C, - FunctionType::get(Type::Int8Ty, params, false), - "SharkRuntime__is_subtype_of"); - - params.clear(); - params.push_back(SharkType::intptr_type()); - params.push_back(SharkType::jint_type()); - _should_not_reach_here = builder->make_function( - (intptr_t) report_should_not_reach_here, - FunctionType::get(Type::VoidTy, params, false), - "report_should_not_reach_here"); - _unimplemented = builder->make_function( - (intptr_t) report_unimplemented, - FunctionType::get(Type::VoidTy, params, false), - "report_unimplemented"); - - params.clear(); - params.push_back(SharkType::thread_type()); - params.push_back(SharkType::jint_type()); - _uncommon_trap = builder->make_function( - (intptr_t) uncommon_trap_C, - FunctionType::get(Type::VoidTy, params, false), - "SharkRuntime__uncommon_trap"); - - params.clear(); - _current_time_millis = builder->make_function( - (intptr_t) os::javaTimeMillis, - FunctionType::get(SharkType::jlong_type(), params, false), - "os__javaTimeMillis"); - - params.clear(); - params.push_back(SharkType::jdouble_type()); - _fabs = builder->make_function( - (intptr_t) ::fabs, - FunctionType::get(SharkType::jdouble_type(), params, false), - "fabs"); - _tan = builder->make_function( - (intptr_t) ::tan, - FunctionType::get(SharkType::jdouble_type(), params, false), - "tan"); - params.push_back(SharkType::jdouble_type()); - _atan2 = builder->make_function( - (intptr_t) ::atan2, - FunctionType::get(SharkType::jdouble_type(), params, false), - "atan2"); - - params.clear(); - params.push_back(SharkType::jlong_type()); - _unsafe_field_offset_to_byte_offset = builder->make_function( - (intptr_t) Unsafe_field_offset_to_byte_offset, - FunctionType::get(SharkType::jlong_type(), params, false), - "Unsafe_field_offset_to_byte_offset"); -} - -JRT_ENTRY(int, SharkRuntime::find_exception_handler_C(JavaThread* thread, - int* indexes, - int num_indexes)) +JRT_ENTRY(int, SharkRuntime::find_exception_handler(JavaThread* thread, + int* indexes, + int num_indexes)) { constantPoolHandle pool(thread, method(thread)->constants()); KlassHandle exc_klass(thread, ((oop) tos_at(thread, 0))->klass()); @@ -263,8 +50,8 @@ } JRT_END -JRT_ENTRY(void, SharkRuntime::monitorenter_C(JavaThread* thread, - BasicObjectLock* lock)) +JRT_ENTRY(void, SharkRuntime::monitorenter(JavaThread* thread, + BasicObjectLock* lock)) { if (PrintBiasedLockingStatistics) Atomic::inc(BiasedLocking::slow_path_entry_count_addr()); @@ -281,8 +68,8 @@ } JRT_END -JRT_ENTRY(void, SharkRuntime::monitorexit_C(JavaThread* thread, - BasicObjectLock* lock)) +JRT_ENTRY(void, SharkRuntime::monitorexit(JavaThread* thread, + BasicObjectLock* lock)) { Handle object(thread, lock->obj()); assert(Universe::heap()->is_in_reserved_or_null(object()), "should be"); @@ -293,7 +80,7 @@ } JRT_END -JRT_ENTRY(void, SharkRuntime::new_instance_C(JavaThread* thread, int index)) +JRT_ENTRY(void, SharkRuntime::new_instance(JavaThread* thread, int index)) { klassOop k_oop = method(thread)->constants()->klass_at(index, CHECK); instanceKlassHandle klass(THREAD, k_oop); @@ -323,18 +110,18 @@ } JRT_END -JRT_ENTRY(void, SharkRuntime::newarray_C(JavaThread* thread, - BasicType type, - int size)) +JRT_ENTRY(void, SharkRuntime::newarray(JavaThread* thread, + BasicType type, + int size)) { oop obj = oopFactory::new_typeArray(type, size, CHECK); thread->set_vm_result(obj); } JRT_END -JRT_ENTRY(void, SharkRuntime::anewarray_C(JavaThread* thread, - int index, - int size)) +JRT_ENTRY(void, SharkRuntime::anewarray(JavaThread* thread, + int index, + int size)) { klassOop klass = method(thread)->constants()->klass_at(index, CHECK); objArrayOop obj = oopFactory::new_objArray(klass, size, CHECK); @@ -342,10 +129,10 @@ } JRT_END -JRT_ENTRY(void, SharkRuntime::multianewarray_C(JavaThread* thread, - int index, - int ndims, - int* dims)) +JRT_ENTRY(void, SharkRuntime::multianewarray(JavaThread* thread, + int index, + int ndims, + int* dims)) { klassOop klass = method(thread)->constants()->klass_at(index, CHECK); oop obj = arrayKlass::cast(klass)->multi_allocate(ndims, dims, CHECK); @@ -353,8 +140,8 @@ } JRT_END -JRT_ENTRY(void, SharkRuntime::register_finalizer_C(JavaThread* thread, - oop object)) +JRT_ENTRY(void, SharkRuntime::register_finalizer(JavaThread* thread, + oop object)) { assert(object->is_oop(), "should be"); assert(object->klass()->klass_part()->has_finalizer(), "should have"); @@ -362,7 +149,7 @@ } JRT_END -JRT_ENTRY(void, SharkRuntime::throw_ArrayIndexOutOfBoundsException_C( +JRT_ENTRY(void, SharkRuntime::throw_ArrayIndexOutOfBoundsException( JavaThread* thread, const char* file, int line, @@ -377,9 +164,9 @@ } JRT_END -JRT_ENTRY(void, SharkRuntime::throw_NullPointerException_C(JavaThread* thread, - const char* file, - int line)) +JRT_ENTRY(void, SharkRuntime::throw_NullPointerException(JavaThread* thread, + const char* file, + int line)) { Exceptions::_throw_msg( thread, file, line, @@ -391,7 +178,7 @@ // Non-VM calls // Nothing in these must ever GC! -void SharkRuntime::dump_C(const char *name, intptr_t value) +void SharkRuntime::dump(const char *name, intptr_t value) { oop valueOop = (oop) value; tty->print("%s = ", name); @@ -404,12 +191,12 @@ tty->print_cr(""); } -bool SharkRuntime::is_subtype_of_C(klassOop check_klass, klassOop object_klass) +bool SharkRuntime::is_subtype_of(klassOop check_klass, klassOop object_klass) { return object_klass->klass_part()->is_subtype_of(check_klass); } -void SharkRuntime::uncommon_trap_C(JavaThread* thread, int trap_request) +void SharkRuntime::uncommon_trap(JavaThread* thread, int trap_request) { // In C2, uncommon_trap_blob creates a frame, so all the various // deoptimization functions expect to find the frame of the method diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/shark/sharkRuntime.hpp --- a/ports/hotspot/src/share/vm/shark/sharkRuntime.hpp Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkRuntime.hpp Thu Jul 30 04:51:32 2009 -0400 @@ -24,94 +24,32 @@ */ class SharkRuntime : public AllStatic { + // VM calls public: - static void initialize(SharkBuilder* builder); + static int find_exception_handler(JavaThread* thread, + int* indexes, + int num_indexes); - // VM calls - private: - static llvm::Constant* _find_exception_handler; - static llvm::Constant* _monitorenter; - static llvm::Constant* _monitorexit; - static llvm::Constant* _new_instance; - static llvm::Constant* _newarray; - static llvm::Constant* _anewarray; - static llvm::Constant* _multianewarray; - static llvm::Constant* _register_finalizer; - static llvm::Constant* _safepoint; - static llvm::Constant* _throw_ArrayIndexOutOfBoundsException; - static llvm::Constant* _throw_NullPointerException; + static void monitorenter(JavaThread* thread, BasicObjectLock* lock); + static void monitorexit(JavaThread* thread, BasicObjectLock* lock); - public: - static llvm::Constant* find_exception_handler() - { - return _find_exception_handler; - } - static llvm::Constant* monitorenter() - { - return _monitorenter; - } - static llvm::Constant* monitorexit() - { - return _monitorexit; - } - static llvm::Constant* new_instance() - { - return _new_instance; - } - static llvm::Constant* newarray() - { - return _newarray; - } - static llvm::Constant* anewarray() - { - return _anewarray; - } - static llvm::Constant* multianewarray() - { - return _multianewarray; - } - static llvm::Constant* register_finalizer() - { - return _register_finalizer; - } - static llvm::Constant* safepoint() - { - return _safepoint; - } - static llvm::Constant* throw_ArrayIndexOutOfBoundsException() - { - return _throw_ArrayIndexOutOfBoundsException; - } - static llvm::Constant* throw_NullPointerException() - { - return _throw_NullPointerException; - } + static void new_instance(JavaThread* thread, int index); + static void newarray(JavaThread* thread, BasicType type, int size); + static void anewarray(JavaThread* thread, int index, int size); + static void multianewarray(JavaThread* thread, + int index, + int ndims, + int* dims); - private: - static int find_exception_handler_C(JavaThread* thread, - int* indexes, - int num_indexes); + static void register_finalizer(JavaThread* thread, oop object); - static void monitorenter_C(JavaThread* thread, BasicObjectLock* lock); - static void monitorexit_C(JavaThread* thread, BasicObjectLock* lock); - - static void new_instance_C(JavaThread* thread, int index); - static void newarray_C(JavaThread* thread, BasicType type, int size); - static void anewarray_C(JavaThread* thread, int index, int size); - static void multianewarray_C(JavaThread* thread, - int index, - int ndims, - int* dims); - - static void register_finalizer_C(JavaThread* thread, oop object); - - static void throw_ArrayIndexOutOfBoundsException_C(JavaThread* thread, - const char* file, - int line, - int index); - static void throw_NullPointerException_C(JavaThread* thread, - const char* file, - int line); + static void throw_ArrayIndexOutOfBoundsException(JavaThread* thread, + const char* file, + int line, + int index); + static void throw_NullPointerException(JavaThread* thread, + const char* file, + int line); // Helpers for VM calls private: @@ -136,88 +74,9 @@ return *(thread->zero_stack()->sp() + offset); } - // Leaf calls - private: - static llvm::Constant* _f2i; - static llvm::Constant* _f2l; - static llvm::Constant* _d2i; - static llvm::Constant* _d2l; - + // Non-VM calls public: - static llvm::Constant* f2i() - { - return _f2i; - } - static llvm::Constant* f2l() - { - return _f2l; - } - static llvm::Constant* d2i() - { - return _d2i; - } - static llvm::Constant* d2l() - { - return _d2l; - } - - // Non-VM calls - private: - static llvm::Constant* _dump; - static llvm::Constant* _is_subtype_of; - static llvm::Constant* _should_not_reach_here; - static llvm::Constant* _unimplemented; - static llvm::Constant* _uncommon_trap; - static llvm::Constant* _current_time_millis; - static llvm::Constant* _fabs; - static llvm::Constant* _tan; - static llvm::Constant* _atan2; - static llvm::Constant* _unsafe_field_offset_to_byte_offset; - - public: - static llvm::Constant* dump() - { - return _dump; - } - static llvm::Constant* is_subtype_of() - { - return _is_subtype_of; - } - static llvm::Constant* should_not_reach_here() - { - return _should_not_reach_here; - } - static llvm::Constant* unimplemented() - { - return _unimplemented; - } - static llvm::Constant* uncommon_trap() - { - return _uncommon_trap; - } - static llvm::Constant* current_time_millis() - { - return _current_time_millis; - } - static llvm::Constant* fabs() - { - return _fabs; - } - static llvm::Constant* tan() - { - return _tan; - } - static llvm::Constant* atan2() - { - return _atan2; - } - static llvm::Constant* unsafe_field_offset_to_byte_offset() - { - return _unsafe_field_offset_to_byte_offset; - } - - private: - static void dump_C(const char *name, intptr_t value); - static bool is_subtype_of_C(klassOop check_klass, klassOop object_klass); - static void uncommon_trap_C(JavaThread* thread, int trap_request); + static void dump(const char *name, intptr_t value); + static bool is_subtype_of(klassOop check_klass, klassOop object_klass); + static void uncommon_trap(JavaThread* thread, int trap_request); }; diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Thu Jul 30 04:51:32 2009 -0400 @@ -324,8 +324,10 @@ builder()->SetInsertPoint(zero_block); if (value->is_jobject()) { call_vm( - SharkRuntime::throw_NullPointerException(), - builder()->pointer_constant(__FILE__), + builder()->throw_NullPointerException(), + builder()->CreateIntToPtr( + LLVMValue::intptr_constant((intptr_t) __FILE__), + PointerType::getUnqual(SharkType::jbyte_type())), LLVMValue::jint_constant(__LINE__), EX_CHECK_NONE); } @@ -349,8 +351,10 @@ builder()->SetInsertPoint(out_of_bounds); SharkState *saved_state = current_state()->copy(); call_vm( - SharkRuntime::throw_ArrayIndexOutOfBoundsException(), - builder()->pointer_constant(__FILE__), + builder()->throw_ArrayIndexOutOfBoundsException(), + builder()->CreateIntToPtr( + LLVMValue::intptr_constant((intptr_t) __FILE__), + PointerType::getUnqual(SharkType::jbyte_type())), LLVMValue::jint_constant(__LINE__), index->jint_value(), EX_CHECK_NONE); @@ -433,7 +437,7 @@ builder()->CreateStructGEP(options, i)); Value *index = call_vm( - SharkRuntime::find_exception_handler(), + builder()->find_exception_handler(), builder()->CreateStructGEP(options, 0), LLVMValue::jint_constant(num_options), EX_CHECK_NO_CATCH); @@ -483,7 +487,8 @@ Value *state = builder()->CreateLoad( builder()->CreateIntToPtr( - builder()->pointer_constant(SafepointSynchronize::address_of_state()), + LLVMValue::intptr_constant( + (intptr_t) SafepointSynchronize::address_of_state()), PointerType::getUnqual(SharkType::jint_type())), "state"); @@ -494,7 +499,7 @@ do_safepoint, safepointed); builder()->SetInsertPoint(do_safepoint); - call_vm(SharkRuntime::safepoint(), EX_CHECK_FULL); + call_vm(builder()->safepoint(), EX_CHECK_FULL); BasicBlock *safepointed_block = builder()->GetInsertBlock(); builder()->CreateBr(safepointed); @@ -553,7 +558,7 @@ { decache_for_trap(); builder()->CreateCall2( - SharkRuntime::uncommon_trap(), + builder()->uncommon_trap(), thread(), LLVMValue::jint_constant(trap_request)); builder()->CreateRetVoid(); @@ -594,7 +599,7 @@ do_call, done); builder()->SetInsertPoint(do_call); - call_vm(SharkRuntime::register_finalizer(), receiver, EX_CHECK_FULL); + call_vm(builder()->register_finalizer(), receiver, EX_CHECK_FULL); BasicBlock *branch_block = builder()->GetInsertBlock(); builder()->CreateBr(done); @@ -989,16 +994,19 @@ builder()->CreateIntCast(vtable_length, SharkType::intptr_type(), false); bool needs_aligning = HeapWordsPerLong > 1; - const char *itable_start_name = "itable_start"; Value *itable_start = builder()->CreateAdd( vtable_start, builder()->CreateShl( vtable_length, LLVMValue::intptr_constant(exact_log2(vtableEntry::size() * wordSize))), - needs_aligning ? "" : itable_start_name); - if (needs_aligning) - itable_start = builder()->CreateAlign( - itable_start, BytesPerLong, itable_start_name); + needs_aligning ? "" : "itable_start"); + if (needs_aligning) { + itable_start = builder()->CreateAnd( + builder()->CreateAdd( + itable_start, LLVMValue::intptr_constant(BytesPerLong - 1)), + LLVMValue::intptr_constant(~(BytesPerLong - 1)), + "itable_start"); + } // Locate this interface's entry in the table Value *iklass = builder()->CreateInlineOop(method->holder()); @@ -1327,7 +1335,7 @@ builder()->CreateCondBr( builder()->CreateICmpNE( builder()->CreateCall2( - SharkRuntime::is_subtype_of(), check_klass, object_klass), + builder()->is_subtype_of(), check_klass, object_klass), LLVMValue::jbyte_constant(0)), is_instance, not_instance); @@ -1483,13 +1491,13 @@ // Heap allocation Value *top_addr = builder()->CreateIntToPtr( - builder()->pointer_constant(Universe::heap()->top_addr()), + LLVMValue::intptr_constant((intptr_t) Universe::heap()->top_addr()), PointerType::getUnqual(SharkType::intptr_type()), "top_addr"); Value *end = builder()->CreateLoad( builder()->CreateIntToPtr( - builder()->pointer_constant(Universe::heap()->end_addr()), + LLVMValue::intptr_constant((intptr_t) Universe::heap()->end_addr()), PointerType::getUnqual(SharkType::intptr_type())), "end"); @@ -1565,7 +1573,7 @@ // The slow path call_vm( - SharkRuntime::new_instance(), + builder()->new_instance(), LLVMValue::jint_constant(iter()->get_klass_index()), EX_CHECK_FULL); slow_object = function()->CreateGetVMResult(); @@ -1595,7 +1603,7 @@ BasicType type = (BasicType) iter()->get_index(); call_vm( - SharkRuntime::newarray(), + builder()->newarray(), LLVMValue::jint_constant(type), pop()->jint_value(), EX_CHECK_FULL); @@ -1618,7 +1626,7 @@ } call_vm( - SharkRuntime::anewarray(), + builder()->anewarray(), LLVMValue::jint_constant(iter()->get_klass_index()), pop()->jint_value(), EX_CHECK_FULL); @@ -1650,7 +1658,7 @@ } call_vm( - SharkRuntime::multianewarray(), + builder()->multianewarray(), LLVMValue::jint_constant(iter()->get_klass_index()), LLVMValue::jint_constant(ndims), builder()->CreateStructGEP(dimensions, 0), @@ -1764,7 +1772,7 @@ // It's not a recursive case so we need to drop into the runtime builder()->SetInsertPoint(not_recursive); call_vm( - SharkRuntime::monitorenter(), monitor_addr, + builder()->monitorenter(), monitor_addr, exception_action | EAM_MONITOR_FUDGE); BasicBlock *acquired_slow = builder()->GetInsertBlock(); builder()->CreateBr(lock_acquired); @@ -1817,7 +1825,7 @@ // Need to drop into the runtime to release this one builder()->SetInsertPoint(slow_path); - call_vm(SharkRuntime::monitorexit(), monitor_addr, exception_action); + call_vm(builder()->monitorexit(), monitor_addr, exception_action); BasicBlock *released_slow = builder()->GetInsertBlock(); builder()->CreateBr(lock_released); diff -r ff01867e1a2a -r 051ca564791d ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Wed Jul 29 10:57:38 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Thu Jul 30 04:51:32 2009 -0400 @@ -256,10 +256,10 @@ // VM calls private: - llvm::CallInst* call_vm(llvm::Constant* callee, - llvm::Value** args_start, - llvm::Value** args_end, - int exception_action) + llvm::CallInst* call_vm(llvm::Value* callee, + llvm::Value** args_start, + llvm::Value** args_end, + int exception_action) { decache_for_VM_call(); function()->set_last_Java_frame(); @@ -274,32 +274,32 @@ } public: - llvm::CallInst* call_vm(llvm::Constant* callee, - int exception_action) + llvm::CallInst* call_vm(llvm::Value* callee, + int exception_action) { llvm::Value *args[] = {thread()}; return call_vm(callee, args, args + 1, exception_action); } - llvm::CallInst* call_vm(llvm::Constant* callee, - llvm::Value* arg1, - int exception_action) + llvm::CallInst* call_vm(llvm::Value* callee, + llvm::Value* arg1, + int exception_action) { llvm::Value *args[] = {thread(), arg1}; return call_vm(callee, args, args + 2, exception_action); } - llvm::CallInst* call_vm(llvm::Constant* callee, - llvm::Value* arg1, - llvm::Value* arg2, - int exception_action) + llvm::CallInst* call_vm(llvm::Value* callee, + llvm::Value* arg1, + llvm::Value* arg2, + int exception_action) { llvm::Value *args[] = {thread(), arg1, arg2}; return call_vm(callee, args, args + 3, exception_action); } - llvm::CallInst* call_vm(llvm::Constant* callee, - llvm::Value* arg1, - llvm::Value* arg2, - llvm::Value* arg3, - int exception_action) + llvm::CallInst* call_vm(llvm::Value* callee, + llvm::Value* arg1, + llvm::Value* arg2, + llvm::Value* arg3, + int exception_action) { llvm::Value *args[] = {thread(), arg1, arg2, arg3}; return call_vm(callee, args, args + 4, exception_action);