# HG changeset patch # User Andrew Haley # Date 1232646926 0 # Node ID 0507a324ec22080f061b0357e707d5e4f7ae3b84 # Parent 62c52213166ec273d4200b1702905f535ed3aea3 2009-01-22 Andrew Haley * ports/hotspot/src/cpu/zero/vm/stack_zero.hpp (class ZeroFrame::FrameType): Set ENTRY_FRAME = 0xCAFEBABE. * ports/hotspot/src/share/vm/shark/shark_globals.hpp (SHARK_FLAGS): Add SharkPrintAsmOf. * ports/hotspot/src/share/vm/shark/sharkFunction.hpp: Add comment. * ports/hotspot/src/share/vm/shark/sharkFunction.cpp (SharkFunction::initialize): Set builder()->sharkEntry. Use fnmatch() instead of strcmp(). Generate debugging dumps. * ports/hotspot/src/share/vm/shark/sharkEntry.hpp (SharkEntry::code_start, code_limit): Rewrite. (SharkEntry::setBounds): New. * ports/hotspot/src/share/vm/shark/sharkBuilder.hpp (SharkBuilder::pointer_constant): New function. * ports/hotspot/src/share/vm/shark/sharkBytecodeTracer.cpp (SharkBytecodeTracer::decode_one_word): use SharkBuilder::pointer_constant. * ports/hotspot/src/share/vm/shark/sharkBuilder.cpp (SharkBuilder::sharkEntry): New. (SharkBuilder::CreateUnimplemented): use SharkBuilder::pointer_constant. (SharkBuilder::CreateShouldNotReachHere): Likewise. (MyJITMemoryManager::endFunctionBody): New method. * ports/hotspot/src/share/vm/shark/sharkBlock.cpp (SharkBlock::check_zero): use SharkBuilder::pointer_constant. (SharkBlock::check_bounds): Likewise. (SharkBlock::add_safepoint): Likewise. (SharkBlock::do_new): Likewise. (SharkBlock::do_monitorexit): Don't check for null monitor. * ports/hotspot/src/share/vm/shark/llvmHeaders.hpp: Add llvm/ExecutionEngine/JITMemoryManager.h, llvm/Support/CommandLine.h. * ports/hotspot/src/share/vm/includeDB_shark (sharkBuilder.hpp): add sharkEntry.hpp. diff -r 62c52213166e -r 0507a324ec22 ChangeLog --- a/ChangeLog Thu Jan 22 10:21:33 2009 -0500 +++ b/ChangeLog Thu Jan 22 17:55:26 2009 +0000 @@ -1,3 +1,44 @@ +2009-01-22 Andrew Haley + + * ports/hotspot/src/cpu/zero/vm/stack_zero.hpp (class + ZeroFrame::FrameType): Set ENTRY_FRAME = 0xCAFEBABE. + + * ports/hotspot/src/share/vm/shark/shark_globals.hpp (SHARK_FLAGS): + Add SharkPrintAsmOf. + + * ports/hotspot/src/share/vm/shark/sharkFunction.hpp: Add comment. + + * ports/hotspot/src/share/vm/shark/sharkFunction.cpp + (SharkFunction::initialize): Set builder()->sharkEntry. + Use fnmatch() instead of strcmp(). + Generate debugging dumps. + * ports/hotspot/src/share/vm/shark/sharkEntry.hpp + (SharkEntry::code_start, code_limit): Rewrite. + (SharkEntry::setBounds): New. + + * ports/hotspot/src/share/vm/shark/sharkBuilder.hpp + (SharkBuilder::pointer_constant): New function. + * ports/hotspot/src/share/vm/shark/sharkBytecodeTracer.cpp + (SharkBytecodeTracer::decode_one_word): + use SharkBuilder::pointer_constant. + * ports/hotspot/src/share/vm/shark/sharkBuilder.cpp + (SharkBuilder::sharkEntry): New. + (SharkBuilder::CreateUnimplemented): use SharkBuilder::pointer_constant. + (SharkBuilder::CreateShouldNotReachHere): Likewise. + (MyJITMemoryManager::endFunctionBody): New method. + * ports/hotspot/src/share/vm/shark/sharkBlock.cpp + (SharkBlock::check_zero): use SharkBuilder::pointer_constant. + (SharkBlock::check_bounds): Likewise. + (SharkBlock::add_safepoint): Likewise. + (SharkBlock::do_new): Likewise. + (SharkBlock::do_monitorexit): Don't check for null monitor. + + * ports/hotspot/src/share/vm/shark/llvmHeaders.hpp: Add + llvm/ExecutionEngine/JITMemoryManager.h, + llvm/Support/CommandLine.h. + * ports/hotspot/src/share/vm/includeDB_shark (sharkBuilder.hpp): + add sharkEntry.hpp. + 2009-01-22 Lillian Angel * NEWS: Updated for release candidate. diff -r 62c52213166e -r 0507a324ec22 ports/hotspot/src/cpu/zero/vm/stack_zero.hpp --- a/ports/hotspot/src/cpu/zero/vm/stack_zero.hpp Thu Jan 22 10:21:33 2009 -0500 +++ b/ports/hotspot/src/cpu/zero/vm/stack_zero.hpp Thu Jan 22 17:55:26 2009 +0000 @@ -142,7 +142,7 @@ }; enum FrameType { - ENTRY_FRAME = 1, + ENTRY_FRAME = 0xCAFEBABE, INTERPRETER_FRAME, SHARK_FRAME, DEOPTIMIZER_FRAME diff -r 62c52213166e -r 0507a324ec22 ports/hotspot/src/share/vm/includeDB_shark --- a/ports/hotspot/src/share/vm/includeDB_shark Thu Jan 22 10:21:33 2009 -0500 +++ b/ports/hotspot/src/share/vm/includeDB_shark Thu Jan 22 17:55:26 2009 +0000 @@ -112,6 +112,7 @@ sharkBuilder.hpp sizes.hpp sharkBuilder.hpp sharkType.hpp sharkBuilder.hpp sharkValue.inline.hpp +sharkBuilder.hpp sharkEntry.hpp sharkBytecodeTracer.cpp sharkBytecodeTracer.hpp sharkBytecodeTracer.cpp sharkState.inline.hpp @@ -269,3 +270,4 @@ sharkValue.inline.hpp ciType.hpp sharkValue.inline.hpp llvmHeaders.hpp sharkValue.inline.hpp sharkValue.hpp + diff -r 62c52213166e -r 0507a324ec22 ports/hotspot/src/share/vm/shark/llvmHeaders.hpp --- a/ports/hotspot/src/share/vm/shark/llvmHeaders.hpp Thu Jan 22 10:21:33 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/llvmHeaders.hpp Thu Jan 22 17:55:26 2009 +0000 @@ -36,6 +36,10 @@ #include #include #include +#include +#include + +#include #ifdef assert #undef assert diff -r 62c52213166e -r 0507a324ec22 ports/hotspot/src/share/vm/shark/sharkBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Thu Jan 22 10:21:33 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Thu Jan 22 17:55:26 2009 +0000 @@ -992,7 +992,7 @@ if (value->is_jobject()) { call_vm_nocheck( SharkRuntime::throw_NullPointerException(), - LLVMValue::intptr_constant((intptr_t) __FILE__), + builder()->pointer_constant(__FILE__), LLVMValue::jint_constant(__LINE__)); } else { @@ -1021,7 +1021,7 @@ SharkTrackingState *saved_state = current_state()->copy(); call_vm_nocheck( SharkRuntime::throw_ArrayIndexOutOfBoundsException(), - LLVMValue::intptr_constant((intptr_t) __FILE__), + builder()->pointer_constant(__FILE__), LLVMValue::jint_constant(__LINE__), index->jint_value()); handle_exception(function()->CreateGetPendingException()); @@ -1141,8 +1141,7 @@ Value *state = builder()->CreateLoad( builder()->CreateIntToPtr( - LLVMValue::intptr_constant( - (intptr_t) SafepointSynchronize::address_of_state()), + builder()->pointer_constant(SafepointSynchronize::address_of_state()), PointerType::getUnqual(SharkType::jint_type())), "state"); @@ -2238,13 +2237,13 @@ builder()->SetInsertPoint(heap_alloc); Value *top_addr = builder()->CreateIntToPtr( - LLVMValue::intptr_constant((intptr_t) Universe::heap()->top_addr()), + builder()->pointer_constant(Universe::heap()->top_addr()), PointerType::getUnqual(SharkType::intptr_type()), "top_addr"); Value *end = builder()->CreateLoad( builder()->CreateIntToPtr( - LLVMValue::intptr_constant((intptr_t) Universe::heap()->end_addr()), + builder()->pointer_constant(Universe::heap()->end_addr()), PointerType::getUnqual(SharkType::intptr_type())), "end"); @@ -2473,7 +2472,10 @@ void SharkBlock::do_monitorexit() { SharkValue *lockee = pop(); - check_null(lockee); + // The monitorexit can't throw an NPE because the verifier checks + // that the monitor operations are block structured before we + // compile. + // check_null(lockee); Value *object = lockee->jobject_value(); // Find the monitor associated with this object @@ -2513,5 +2515,8 @@ // Release the lock builder()->SetInsertPoint(got_monitor); monitor->release(this); - check_pending_exception(); + // The monitorexit can't throw an NPE because the verifier checks + // that the monitor operations are block structured before we + // compile. + // check_pending_exception(); } diff -r 62c52213166e -r 0507a324ec22 ports/hotspot/src/share/vm/shark/sharkBuilder.cpp --- a/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Thu Jan 22 10:21:33 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Thu Jan 22 17:55:26 2009 +0000 @@ -28,12 +28,15 @@ using namespace llvm; +std::map SharkBuilder::sharkEntry; + SharkBuilder::SharkBuilder() : IRBuilder<>(), _module("shark"), _module_provider(module()), - _execution_engine(ExecutionEngine::create(&_module_provider)) -{ + _execution_engine(ExecutionEngine::createJIT + (&_module_provider, NULL, new MyJITMemoryManager(), + /* Fast */ false)) { init_external_functions(); } @@ -152,7 +155,7 @@ { return CreateCall2( SharkRuntime::unimplemented(), - LLVMValue::intptr_constant((intptr_t) file), + pointer_constant(file), LLVMValue::jint_constant(line)); } @@ -160,7 +163,7 @@ { return CreateCall2( SharkRuntime::should_not_reach_here(), - LLVMValue::intptr_constant((intptr_t) file), + pointer_constant(file), LLVMValue::jint_constant(line)); } @@ -174,3 +177,16 @@ ConstantInt::get(Type::Int1Ty, 0)}; return CreateCall(llvm_memory_barrier_fn(), args, args + 5); } + +void SharkBuilder::MyJITMemoryManager::endFunctionBody + (const llvm::Function *F, unsigned char *FunctionStart, + unsigned char *FunctionEnd) +{ + mm->endFunctionBody(F, FunctionStart, FunctionEnd); +#ifndef PRODUCT + SharkEntry *e = sharkEntry[F]; + if (e) + e->setBounds(FunctionStart, FunctionEnd); +#endif // !PRODUCT +} + diff -r 62c52213166e -r 0507a324ec22 ports/hotspot/src/share/vm/shark/sharkBuilder.hpp --- a/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Thu Jan 22 10:21:33 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Thu Jan 22 17:55:26 2009 +0000 @@ -27,11 +27,76 @@ public: SharkBuilder(); + static std::map sharkEntry; + private: llvm::Module _module; llvm::ExistingModuleProvider _module_provider; llvm::ExecutionEngine* _execution_engine; + // MyJITMemoryManager wraps the JIT Memory Manager: this allows us + // to run our own memory allocation policies, but the purpose here + // is to allow us to intercept JITMemoryManager::endFunctionBody. + class MyJITMemoryManager : public llvm::JITMemoryManager { + + llvm::JITMemoryManager *mm; + + public: + + MyJITMemoryManager() + { + mm = llvm::JITMemoryManager::CreateDefaultMemManager(); + } + + virtual void AllocateGOT() { + mm->AllocateGOT(); + } + + virtual unsigned char *getGOTBase() const { + return mm->getGOTBase(); + } + + virtual unsigned char *startFunctionBody(const llvm::Function *F, + uintptr_t &ActualSize) { + return mm->startFunctionBody(F, ActualSize); + } + + virtual unsigned char *allocateStub(const llvm::GlobalValue* F, + unsigned StubSize, + unsigned Alignment) { + return mm->allocateStub(F, StubSize, Alignment); + } + + void endFunctionBody(const llvm::Function *F, unsigned char *FunctionStart, + unsigned char *FunctionEnd); + + virtual void deallocateMemForFunction(const llvm::Function *F) { + return mm->deallocateMemForFunction(F); + } + + virtual unsigned char* startExceptionTable(const llvm::Function* F, + uintptr_t &ActualSize) { + return mm->startExceptionTable(F, ActualSize); + } + + virtual void endExceptionTable(const llvm::Function *F, + unsigned char *TableStart, + unsigned char *TableEnd, + unsigned char* FrameRegister) { + mm->endExceptionTable(F, TableStart, TableEnd, FrameRegister); + } + + virtual void setMemoryWritable() { + mm->setMemoryWritable(); + } + + virtual void setMemoryExecutable() { + mm->setMemoryExecutable(); + } + }; + + MyJITMemoryManager *MemMgr; + public: llvm::Module* module() { @@ -125,9 +190,37 @@ const llvm::FunctionType* sig, const char* name); + llvm::Constant* pointer_constant(const void *ptr) + { + // 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 + + using namespace llvm; + + // 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()); +// } + + 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()); + } + // Helper for making pointers public: - llvm::Constant* make_pointer(intptr_t addr, const llvm::Type* type) const + llvm::Constant* make_pointer(intptr_t addr, const llvm::Type* type) { return llvm::ConstantExpr::getIntToPtr( LLVMValue::intptr_constant(addr), @@ -193,8 +286,7 @@ LLVMValue::jbyte_constant(CardTableModRefBS::dirty_card), CreateIntToPtr( CreateAdd( - LLVMValue::intptr_constant( - (intptr_t) ((CardTableModRefBS *) bs)->byte_map_base), + pointer_constant(((CardTableModRefBS *) bs)->byte_map_base), CreateLShr( CreatePtrToInt(field, SharkType::intptr_type()), LLVMValue::intptr_constant(CardTableModRefBS::card_shift))), diff -r 62c52213166e -r 0507a324ec22 ports/hotspot/src/share/vm/shark/sharkBytecodeTracer.cpp --- a/ports/hotspot/src/share/vm/shark/sharkBytecodeTracer.cpp Thu Jan 22 10:21:33 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkBytecodeTracer.cpp Thu Jan 22 17:55:26 2009 +0000 @@ -89,7 +89,7 @@ break; case T_ADDRESS: - *dst = LLVMValue::intptr_constant(value->returnAddress_value()); + *dst = builder->pointer_constant((const void*)value->returnAddress_value()); break; default: diff -r 62c52213166e -r 0507a324ec22 ports/hotspot/src/share/vm/shark/sharkEntry.cpp --- a/ports/hotspot/src/share/vm/shark/sharkEntry.cpp Thu Jan 22 10:21:33 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkEntry.cpp Thu Jan 22 17:55:26 2009 +0000 @@ -41,30 +41,6 @@ // Lots of the stuff down here is machine- and LLVM-specific. // It's only debug stuff though, and none of it's critical. -address SharkEntry::code_start() const -{ - return (address) entry_point(); -} - -address SharkEntry::code_limit() const -{ -#ifdef PPC - // LLVM seems to insert three junk instructions and a null after - // every function. Only the first junk instruction seems to be - // kept after the next function is generated, however, so this - // method will only work before you generate another function. - // I wish there was a nicer way to do this, but that's life... - uint32_t *limit = (uint32_t *) code_start(); - while (*limit) - limit++; - assert(limit[-1] == 0xd143cfec && limit[-2] == 0xd143cfec, "should be"); - limit -= 3; - return (address) limit; -#else - Unimplemented(); -#endif // PPC -} - void SharkEntry::print_pd_statistics(address start, address limit) const { #ifdef PPC diff -r 62c52213166e -r 0507a324ec22 ports/hotspot/src/share/vm/shark/sharkEntry.hpp --- a/ports/hotspot/src/share/vm/shark/sharkEntry.hpp Thu Jan 22 10:21:33 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkEntry.hpp Thu Jan 22 17:55:26 2009 +0000 @@ -48,8 +48,24 @@ #ifndef PRODUCT private: - address code_start() const; - address code_limit() const; + address code_start() const + { + return start; + } + address code_limit() const + { + return limit; + } void print_pd_statistics(address start, address limit) const; + + address start, limit; + +public: + void setBounds(unsigned char *FunctionStart, unsigned char *FunctionEnd) + { + start = (address)FunctionStart; + limit = (address)FunctionEnd; + } + #endif // !PRODUCT }; diff -r 62c52213166e -r 0507a324ec22 ports/hotspot/src/share/vm/shark/sharkFunction.cpp --- a/ports/hotspot/src/share/vm/shark/sharkFunction.cpp Thu Jan 22 10:21:33 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkFunction.cpp Thu Jan 22 17:55:26 2009 +0000 @@ -26,6 +26,8 @@ #include "incls/_precompiled.incl" #include "incls/_sharkFunction.cpp.incl" +#include + using namespace llvm; void SharkFunction::initialize() @@ -37,6 +39,11 @@ // Create the function _function = builder()->CreateFunction(); entry->set_llvm_function(function()); +#ifndef PRODUCT + // FIXME: there should be a mutex when updating sharkEntry in case + // there are multiple compilation threads. + builder()->sharkEntry[function()] = entry; +#endif // !PRODUCT // Create the list of blocks set_block_insertion_point(NULL); @@ -122,10 +129,25 @@ // Dump the bitcode, if requested if (SharkPrintBitcodeOf != NULL) { - if (!strcmp(SharkPrintBitcodeOf, name())) + if (!fnmatch(SharkPrintBitcodeOf, name(), 0)) function()->dump(); } + if (SharkPrintAsmOf != NULL) { +#if defined (__x86_64) || defined (__i386) + std::vector Args; + Args.push_back(""); // program name + if (!fnmatch(SharkPrintAsmOf, name(), 0)) + // Oh, yuck. The LLVM name for this debugging dump is + // target-specific. + Args.push_back("-debug-only=" "x86-emitter"); + else + Args.push_back("-debug-only="); + Args.push_back(0); // Null terminator. + cl::ParseCommandLineOptions(Args.size()-1, (char**)&Args[0]); +#endif + } + // Compile to native code void *code = builder()->execution_engine()->getPointerToFunction(function()); entry->set_entry_point((ZeroEntry::method_entry_t) code); diff -r 62c52213166e -r 0507a324ec22 ports/hotspot/src/share/vm/shark/sharkFunction.hpp --- a/ports/hotspot/src/share/vm/shark/sharkFunction.hpp Thu Jan 22 10:21:33 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkFunction.hpp Thu Jan 22 17:55:26 2009 +0000 @@ -232,6 +232,8 @@ // OopMap support public: + // Every time a new, distinct pc is required, an extra byte is + // emitted into the codebuffer int code_offset() const { int offset = masm()->offset(); diff -r 62c52213166e -r 0507a324ec22 ports/hotspot/src/share/vm/shark/shark_globals.hpp --- a/ports/hotspot/src/share/vm/shark/shark_globals.hpp Thu Jan 22 10:21:33 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/shark_globals.hpp Thu Jan 22 17:55:26 2009 +0000 @@ -48,6 +48,9 @@ develop(ccstr, SharkPrintBitcodeOf, NULL, \ "Print the LLVM bitcode of the specified method") \ \ + develop(ccstr, SharkPrintAsmOf, NULL, \ + "Print the asm of the specified method") \ + \ develop(bool, SharkTraceBytecodes, false, \ "Trace bytecode compilation") \ \