changeset 2019:2bb5c8fd9e83

2009-08-28 Gary Benson <gbenson@redhat.com> * ports/hotspot/src/share/vm/shark/sharkBuilder.hpp (SharkBuilder::osr_migration_end): New method. * ports/hotspot/src/share/vm/shark/sharkBuilder.cpp (SharkBuilder::osr_migration_end): Likewise. * ports/hotspot/src/share/vm/shark/sharkType.hpp (SharkType::_osr_entry_point_type): New field. (SharkType::osr_entry_point_type): New method. * ports/hotspot/src/share/vm/shark/sharkType.cpp (SharkType::_osr_entry_point_type): New field. (SharkType::initialize): Initialize the above. * ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp (SharkCacher::process_local_slot): Made virtual. (SharkNormalEntryCacher): New class. (SharkOSREntryCacher): Likewise. * ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp (SharkOSREntryCacher::CreateAddressOfOSRBufEntry): New method. (SharkOSREntryCacher::process_monitor): Likewise. (SharkOSREntryCacher::process_local_slot): Likewise. * ports/hotspot/src/share/vm/shark/sharkState.hpp (SharkEntryState): Renamed as... (SharkNormalEntryState): ...this. (SharkOSREntryState::SharkOSREntryState): New class. * ports/hotspot/src/share/vm/shark/sharkState.cpp (SharkEntryState::SharkEntryState): Renamed as... (SharkNormalEntryState::SharkNormalEntryState): ...this. (SharkOSREntryState::SharkOSREntryState): New method. * ports/hotspot/src/share/vm/shark/sharkFunction.hpp (SharkFunction::is_osr): New method. (SharkFunction::entry_point_type): Likewise. * ports/hotspot/src/share/vm/shark/sharkFunction.cpp (SharkFunction::initialize): Handle OSR typeflows. * ports/hotspot/src/share/vm/shark/sharkCompiler.hpp (SharkCompiler::supports_osr): Return true instead of false. * ports/hotspot/src/share/vm/shark/sharkCompiler.cpp (SharkCompiler::compile_method): Remove method-isn't-OSR assertion, and add code to generate OSR typeflows.
author Gary Benson <gbenson@redhat.com>
date Fri, 28 Aug 2009 09:18:57 -0400
parents 5c88e6546ce4
children 4442abcf2ff5
files ChangeLog ports/hotspot/src/share/vm/shark/sharkBuilder.cpp ports/hotspot/src/share/vm/shark/sharkBuilder.hpp ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp ports/hotspot/src/share/vm/shark/sharkCompiler.cpp ports/hotspot/src/share/vm/shark/sharkCompiler.hpp ports/hotspot/src/share/vm/shark/sharkFunction.cpp ports/hotspot/src/share/vm/shark/sharkFunction.hpp ports/hotspot/src/share/vm/shark/sharkState.cpp ports/hotspot/src/share/vm/shark/sharkState.hpp ports/hotspot/src/share/vm/shark/sharkType.cpp ports/hotspot/src/share/vm/shark/sharkType.hpp
diffstat 13 files changed, 266 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Aug 28 11:01:49 2009 +0100
+++ b/ChangeLog	Fri Aug 28 09:18:57 2009 -0400
@@ -1,3 +1,47 @@
+2009-08-28  Gary Benson  <gbenson@redhat.com>
+
+	* ports/hotspot/src/share/vm/shark/sharkBuilder.hpp
+	(SharkBuilder::osr_migration_end): New method.
+	* ports/hotspot/src/share/vm/shark/sharkBuilder.cpp
+	(SharkBuilder::osr_migration_end): Likewise.
+
+	* ports/hotspot/src/share/vm/shark/sharkType.hpp
+	(SharkType::_osr_entry_point_type): New field.
+	(SharkType::osr_entry_point_type): New method.
+	* ports/hotspot/src/share/vm/shark/sharkType.cpp
+	(SharkType::_osr_entry_point_type): New field.
+	(SharkType::initialize): Initialize the above.
+	
+	* ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp
+	(SharkCacher::process_local_slot): Made virtual.
+	(SharkNormalEntryCacher): New class.
+	(SharkOSREntryCacher): Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp
+	(SharkOSREntryCacher::CreateAddressOfOSRBufEntry): New method.
+	(SharkOSREntryCacher::process_monitor): Likewise.
+	(SharkOSREntryCacher::process_local_slot): Likewise.
+
+	* ports/hotspot/src/share/vm/shark/sharkState.hpp
+	(SharkEntryState): Renamed as...
+	(SharkNormalEntryState): ...this.
+	(SharkOSREntryState::SharkOSREntryState): New class.
+	* ports/hotspot/src/share/vm/shark/sharkState.cpp
+	(SharkEntryState::SharkEntryState): Renamed as...
+	(SharkNormalEntryState::SharkNormalEntryState): ...this.
+	(SharkOSREntryState::SharkOSREntryState): New method.
+
+	* ports/hotspot/src/share/vm/shark/sharkFunction.hpp
+	(SharkFunction::is_osr): New method.
+	(SharkFunction::entry_point_type): Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkFunction.cpp
+	(SharkFunction::initialize): Handle OSR typeflows.
+	
+	* ports/hotspot/src/share/vm/shark/sharkCompiler.hpp
+	(SharkCompiler::supports_osr): Return true instead of false.
+	* ports/hotspot/src/share/vm/shark/sharkCompiler.cpp
+	(SharkCompiler::compile_method): Remove method-isn't-OSR
+	assertion, and add code to generate OSR typeflows.
+
 2009-08-28  Gary Benson  <gbenson@redhat.com>
 
 	* ports/hotspot/src/share/vm/shark/sharkState.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp	Fri Aug 28 11:01:49 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp	Fri Aug 28 09:18:57 2009 -0400
@@ -360,6 +360,11 @@
   return make_function((address) Unsafe_field_offset_to_byte_offset, "l", "l");
 }
 
+Value* SharkBuilder::osr_migration_end()
+{
+  return make_function((address) SharedRuntime::OSR_migration_end, "C", "v");
+}
+
 // Uncommon trap
 
 Value* SharkBuilder::uncommon_trap()
--- a/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp	Fri Aug 28 11:01:49 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp	Fri Aug 28 09:18:57 2009 -0400
@@ -128,6 +128,7 @@
   llvm::Value* exp();
   llvm::Value* fabs();
   llvm::Value* unsafe_field_offset_to_byte_offset();
+  llvm::Value* osr_migration_end();
 
   // Intrinsics and external functions, part 3: Uncommon trap.
   //   This is a special case in that it is invoked like a non-VM
--- a/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp	Fri Aug 28 11:01:49 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp	Fri Aug 28 09:18:57 2009 -0400
@@ -185,6 +185,27 @@
   }
 }
 
+void SharkOSREntryCacher::process_monitor(int index,
+                                          int box_offset,
+                                          int obj_offset)
+{
+  if (max_monitors() > 1)
+    Unimplemented();   // XXX which order will they be in?
+
+  // Copy the monitor from the OSR buffer to the frame
+  int src_offset = max_locals() + index * 2;
+  builder()->CreateStore(
+    builder()->CreateLoad(
+      CreateAddressOfOSRBufEntry(src_offset, SharkType::intptr_type())),
+    function()->CreateAddressOfFrameEntry(
+      box_offset, SharkType::intptr_type()));
+  builder()->CreateStore(
+    builder()->CreateLoad(
+      CreateAddressOfOSRBufEntry(src_offset + 1, SharkType::oop_type())),
+    function()->CreateAddressOfFrameEntry(
+      obj_offset, SharkType::oop_type()));
+}
+
 void SharkCacher::process_oop_tmp_slot(Value** value, int offset)
 {
   // Cache the temporary oop
@@ -221,6 +242,33 @@
   }
 }
 
+Value* SharkOSREntryCacher::CreateAddressOfOSRBufEntry(int         offset,
+                                                       const Type* type)
+{
+  Value *result = builder()->CreateStructGEP(osr_buf(), offset);
+  if (type != SharkType::intptr_type())
+    result = builder()->CreateBitCast(result, PointerType::getUnqual(type));
+  return result;
+}
+
+void SharkOSREntryCacher::process_local_slot(int          index,
+                                             SharkValue** addr,
+                                             int          offset)
+{
+  SharkValue *value = *addr;
+
+  // Read the value from the OSR buffer if necessary
+  if (local_slot_needs_read(index, value)) {
+    *addr = SharkValue::create_generic(
+      value->type(),
+      builder()->CreateLoad(
+        CreateAddressOfOSRBufEntry(
+          adjusted_offset(value, max_locals() - 1 - index),
+          SharkType::to_stackType(value->basic_type()))),
+      value->zero_checked());
+  }
+}
+
 void SharkDecacher::write_value_to_frame(const Type* type,
                                          Value*      value,
                                          int         offset)
--- a/ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp	Fri Aug 28 11:01:49 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp	Fri Aug 28 09:18:57 2009 -0400
@@ -34,6 +34,8 @@
 //       - SharkJavaCallCacher
 //       - SharkVMCallCacher
 //       - SharkFunctionEntryCacher
+//         - SharkNormalEntryCacher
+//         - SharkOSREntryCacher
 
 class SharkCacherDecacher : public SharkStateScanner {
  protected:
@@ -329,7 +331,7 @@
   void process_oop_tmp_slot(llvm::Value** value, int offset);
   virtual void process_method_slot(llvm::Value** value, int offset);
 
-  void process_local_slot(int index, SharkValue** value, int offset);
+  virtual void process_local_slot(int index, SharkValue** value, int offset);
 
   // Stack slot helper
  protected:
@@ -410,8 +412,47 @@
 
   // Local slot helper
  protected:
-  virtual bool local_slot_needs_read(int index, SharkValue* value)
+  bool local_slot_needs_read(int index, SharkValue* value)
   {
     return value != NULL;
   }
 };
+
+class SharkNormalEntryCacher : public SharkFunctionEntryCacher {
+ public:
+  SharkNormalEntryCacher(SharkFunction* function, llvm::Value* method)
+    : SharkFunctionEntryCacher(function, method) {}
+};
+
+class SharkOSREntryCacher : public SharkFunctionEntryCacher {
+ public:
+  SharkOSREntryCacher(SharkFunction* function,
+                      llvm::Value*   method,
+                      llvm::Value*   osr_buf)
+    : SharkFunctionEntryCacher(function, method),
+      _osr_buf(
+        builder()->CreateBitCast(
+          osr_buf,
+          llvm::PointerType::getUnqual(
+            llvm::ArrayType::get(
+              SharkType::intptr_type(),
+              max_locals() + max_monitors() * 2)))) {}
+
+ private:
+  llvm::Value* _osr_buf;
+
+ private:
+  llvm::Value* osr_buf() const
+  {
+    return _osr_buf;
+  }
+
+  // Callbacks
+ protected:
+  void process_monitor(int index, int box_offset, int obj_offset);
+  void process_local_slot(int index, SharkValue** value, int offset);
+
+  // Helper
+ private:
+  llvm::Value* CreateAddressOfOSRBufEntry(int offset, const llvm::Type* type);
+};
--- a/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp	Fri Aug 28 11:01:49 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp	Fri Aug 28 09:18:57 2009 -0400
@@ -90,7 +90,6 @@
 void SharkCompiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci)
 {
   assert(is_initialized(), "should be");
-  assert(entry_bci == InvocationEntryBci, "OSR is not supported");
 
   ResourceMark rm;
   const char *name = methodname(target);
@@ -117,7 +116,11 @@
   }
 
   // Do the typeflow analysis
-  ciTypeFlow *flow = target->get_flow_analysis();
+  ciTypeFlow *flow;
+  if (entry_bci == InvocationEntryBci)
+    flow = target->get_flow_analysis();
+  else
+    flow = target->get_osr_flow_analysis(entry_bci);
   if (env->failing())
     return;
   if (SharkPrintTypeflowOf != NULL) {
--- a/ports/hotspot/src/share/vm/shark/sharkCompiler.hpp	Fri Aug 28 11:01:49 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.hpp	Fri Aug 28 09:18:57 2009 -0400
@@ -33,7 +33,7 @@
 
   // Missing feature tests
   bool supports_native() { return false; }
-  bool supports_osr()    { return false; }
+  bool supports_osr()    { return true; }
 
   // Customization
   bool needs_adapters()  { return false; }
--- a/ports/hotspot/src/share/vm/shark/sharkFunction.cpp	Fri Aug 28 11:01:49 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkFunction.cpp	Fri Aug 28 09:18:57 2009 -0400
@@ -32,7 +32,7 @@
 {
   // Create the function
   _function = Function::Create(
-    SharkType::entry_point_type(),
+    entry_point_type(),
     GlobalVariable::InternalLinkage,
     name);
 
@@ -40,6 +40,11 @@
   Function::arg_iterator ai = function()->arg_begin();
   Argument *method = ai++;
   method->setName("method");
+  Argument *osr_buf = NULL;
+  if (is_osr()) {
+    osr_buf = ai++;
+    osr_buf->setName("osr_buf");
+  }
   Argument *base_pc = ai++;
   base_pc->setName("base_pc");
   code_buffer()->set_base_pc(base_pc);
@@ -62,8 +67,8 @@
 
   // Walk the tree from the start block to determine which
   // blocks are entered and which blocks require phis
-  SharkTopLevelBlock *start_block = block(0);
-  assert(start_block->start() == 0, "blocks out of order");
+  SharkTopLevelBlock *start_block = block(flow()->start_block_num());
+  assert(start_block->start() == flow()->start_bci(), "blocks out of order");
   start_block->enter();
 
   // Initialize all entered blocks
@@ -84,17 +89,28 @@
       SharkType::methodOop_type(),
       "method_slot")));
 
-  // Lock if necessary
-  SharkState *entry_state = new SharkEntryState(start_block, method);
-  if (is_synchronized()) {
-    SharkTopLevelBlock *locker =
-      new SharkTopLevelBlock(this, start_block->ciblock());
-    locker->add_incoming(entry_state);
+  // Create the entry state
+  SharkState *entry_state;
+  if (is_osr()) {
+    entry_state = new SharkOSREntryState(start_block, method, osr_buf);
+
+    // Free the OSR buffer
+    builder()->CreateCall(builder()->osr_migration_end(), osr_buf);
+  }
+  else {
+    entry_state = new SharkNormalEntryState(start_block, method);
 
-    set_block_insertion_point(start_block->entry_block());
-    locker->acquire_method_lock();
-
-    entry_state = locker->current_state();
+    // Lock if necessary
+    if (is_synchronized()) {
+      SharkTopLevelBlock *locker =
+        new SharkTopLevelBlock(this, start_block->ciblock());
+      locker->add_incoming(entry_state);
+    
+      set_block_insertion_point(start_block->entry_block());
+      locker->acquire_method_lock();
+    
+      entry_state = locker->current_state();
+    }
   }
 
   // Transition into the method proper
--- a/ports/hotspot/src/share/vm/shark/sharkFunction.hpp	Fri Aug 28 11:01:49 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkFunction.hpp	Fri Aug 28 09:18:57 2009 -0400
@@ -73,6 +73,20 @@
     return &_deferred_zero_checks;
   }
 
+  // On-stack replacement
+ private:
+  bool is_osr() const
+  {
+    return flow()->is_osr_flow();
+  }
+  const llvm::FunctionType* entry_point_type() const
+  {
+    if (is_osr())
+      return SharkType::osr_entry_point_type();      
+    else
+      return SharkType::entry_point_type();
+  }
+
   // Block management
  private:
   llvm::BasicBlock* _block_insertion_point;
--- a/ports/hotspot/src/share/vm/shark/sharkState.cpp	Fri Aug 28 11:01:49 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkState.cpp	Fri Aug 28 09:18:57 2009 -0400
@@ -193,7 +193,8 @@
   }
 }
 
-SharkEntryState::SharkEntryState(SharkTopLevelBlock* block, Value* method)
+SharkNormalEntryState::SharkNormalEntryState(SharkTopLevelBlock* block,
+                                             Value*              method)
   : SharkState(block)
 {
   assert(!block->stack_depth_at_entry(), "entry block shouldn't have stack");
@@ -232,7 +233,49 @@
     }
     set_local(i, value);
   }
-  SharkFunctionEntryCacher(block->function(), method).scan(this);  
+  SharkNormalEntryCacher(block->function(), method).scan(this);  
+}
+
+SharkOSREntryState::SharkOSREntryState(SharkTopLevelBlock* block,
+                                       Value*              method,
+                                       Value*              osr_buf)
+  : SharkState(block)
+{
+  assert(!block->stack_depth_at_entry(), "entry block shouldn't have stack");
+  set_num_monitors(block->ciblock()->monitor_count());
+
+  // Local variables
+  for (int i = 0; i < max_locals(); i++) {
+    ciType *type = block->local_type_at_entry(i);
+
+    SharkValue *value = NULL;
+    switch (type->basic_type()) {
+    case T_INT:
+    case T_LONG:
+    case T_FLOAT:
+    case T_DOUBLE:
+    case T_OBJECT:
+    case T_ARRAY:
+      value = SharkValue::create_generic(type, NULL, false);
+      break;
+    
+    case ciTypeFlow::StateVector::T_NULL:
+      value = SharkValue::null();
+      break;
+
+    case ciTypeFlow::StateVector::T_BOTTOM:
+      break;
+
+    case ciTypeFlow::StateVector::T_LONG2:
+    case ciTypeFlow::StateVector::T_DOUBLE2:
+      break;
+
+    default:
+      ShouldNotReachHere();
+    }
+    set_local(i, value);
+  }
+  SharkOSREntryCacher(block->function(), method, osr_buf).scan(this);
 }
 
 SharkPHIState::SharkPHIState(SharkTopLevelBlock* block)
--- a/ports/hotspot/src/share/vm/shark/sharkState.hpp	Fri Aug 28 11:01:49 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkState.hpp	Fri Aug 28 09:18:57 2009 -0400
@@ -171,11 +171,21 @@
 
 class SharkTopLevelBlock;
 
-// SharkEntryState objects are used to manage the state
-// that the method will be entered with.
-class SharkEntryState : public SharkState {
+// SharkNormalEntryState objects are used to create the state
+// that the method will be entered with for a normal invocation.
+class SharkNormalEntryState : public SharkState {
  public:
-  SharkEntryState(SharkTopLevelBlock* block, llvm::Value* method);
+  SharkNormalEntryState(SharkTopLevelBlock* block,
+                        llvm::Value*        method);
+};
+
+// SharkOSREntryState objects are used to create the state
+// that the method will be entered with for an OSR invocation.
+class SharkOSREntryState : public SharkState {
+ public:
+  SharkOSREntryState(SharkTopLevelBlock* block,
+                     llvm::Value*        method,
+                     llvm::Value*        osr_buf);
 };
 
 // SharkPHIState objects are used to manage the entry state
--- a/ports/hotspot/src/share/vm/shark/sharkType.cpp	Fri Aug 28 11:01:49 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkType.cpp	Fri Aug 28 09:18:57 2009 -0400
@@ -30,6 +30,7 @@
 
 const PointerType*  SharkType::_cpCacheEntry_type;
 const FunctionType* SharkType::_entry_point_type;
+const FunctionType* SharkType::_osr_entry_point_type;
 const PointerType*  SharkType::_itableOffsetEntry_type;
 const PointerType*  SharkType::_klass_type;
 const PointerType*  SharkType::_methodOop_type;
@@ -111,6 +112,17 @@
   _entry_point_type = FunctionType::get(Type::VoidTy, params, false);
 #endif
 
+  params.clear();
+  params.push_back(methodOop_type());
+  params.push_back(PointerType::getUnqual(jbyte_type()));
+  params.push_back(intptr_type());
+  params.push_back(thread_type());
+#if SHARK_LLVM_VERSION >= 26
+  _osr_entry_point_type = FunctionType::get(Type::getVoidTy(getGlobalContext()), params, false);
+#else
+  _osr_entry_point_type = FunctionType::get(Type::VoidTy, params, false);
+#endif
+
   // Java types a) on the stack and in fields, and b) in arrays
   for (int i = 0; i < T_CONFLICT + 1; i++) {
     switch (i) {
--- a/ports/hotspot/src/share/vm/shark/sharkType.hpp	Fri Aug 28 11:01:49 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkType.hpp	Fri Aug 28 09:18:57 2009 -0400
@@ -44,6 +44,7 @@
  private:
   static const llvm::PointerType*  _cpCacheEntry_type;
   static const llvm::FunctionType* _entry_point_type;
+  static const llvm::FunctionType* _osr_entry_point_type;
   static const llvm::PointerType*  _itableOffsetEntry_type;
   static const llvm::PointerType*  _klass_type;
   static const llvm::PointerType*  _methodOop_type;
@@ -61,6 +62,10 @@
   {
     return _entry_point_type;
   }
+  static const llvm::FunctionType* osr_entry_point_type()
+  {
+    return _osr_entry_point_type;
+  }
   static const llvm::PointerType* itableOffsetEntry_type()
   {
     return _itableOffsetEntry_type;