changeset 1329:0507a324ec22

2009-01-22 Andrew Haley <aph@redhat.com> * 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.
author Andrew Haley <aph@redhat.com>
date Thu, 22 Jan 2009 17:55:26 +0000
parents 62c52213166e
children 15437352b69c
files ChangeLog ports/hotspot/src/cpu/zero/vm/stack_zero.hpp ports/hotspot/src/share/vm/includeDB_shark ports/hotspot/src/share/vm/shark/llvmHeaders.hpp ports/hotspot/src/share/vm/shark/sharkBlock.cpp ports/hotspot/src/share/vm/shark/sharkBuilder.cpp ports/hotspot/src/share/vm/shark/sharkBuilder.hpp ports/hotspot/src/share/vm/shark/sharkBytecodeTracer.cpp ports/hotspot/src/share/vm/shark/sharkEntry.cpp ports/hotspot/src/share/vm/shark/sharkEntry.hpp ports/hotspot/src/share/vm/shark/sharkFunction.cpp ports/hotspot/src/share/vm/shark/sharkFunction.hpp ports/hotspot/src/share/vm/shark/shark_globals.hpp
diffstat 13 files changed, 223 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- 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  <aph@redhat.com>
+
+	* 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  <langel@redhat.com>
 
 	* NEWS: Updated for release candidate.
--- 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
--- 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
+
--- 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 <llvm/ModuleProvider.h>
 #include <llvm/Support/IRBuilder.h>
 #include <llvm/Type.h>
+#include <llvm/ExecutionEngine/JITMemoryManager.h>
+#include <llvm/Support/CommandLine.h>
+
+#include <map>
 
 #ifdef assert
   #undef assert
--- 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();
 }
--- 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<const llvm::Function*, SharkEntry*> 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
+}
+
--- 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<const llvm::Function*, SharkEntry*> 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<void*>(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<void*>(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))),
--- 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:
--- 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
--- 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
 };
--- 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 <fnmatch.h>
+
 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<const char*> 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);
--- 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();
--- 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")                                       \
                                                                               \