changeset 2248:a044595518ad

PR icedtea/323: Backport new frame anchor and stack overflow code for Zero and Shark 2010-05-10 Gary Benson <gbenson@redhat.com> PR icedtea/323 * ports/hotspot/src/share/vm/shark/sharkBuilder.hpp (SharkBuilder::throw_StackOverflowError): New method. * ports/hotspot/src/share/vm/shark/sharkBuilder.cpp (SharkBuilder::throw_StackOverflowError): Likewise. * ports/hotspot/src/share/vm/shark/sharkStack.hpp (SharkStack::initialize): Removed argument. (SharkStack::CreateStackOverflowCheck): Updated. (SharkStack::CreateCheckStack): Removed method. (SharkStack::frame_anchor_addr): Likewise. (SharkStack::last_Java_sp_addr): New method. (SharkStack::last_Java_fp_addr): New method. (SharkStack::CreateSetLastJavaFrame): Use new frame anchor code. (SharkStack::CreateResetLastJavaFrame): Likewise. (SharkStack::CreateAssertLastJavaSPIsNull): New method. * ports/hotspot/src/share/vm/shark/sharkStack.cpp (SharkStack::initialize): Updated for new stack overflow code. (SharkStack::CreateStackOverflowCheck): Likewise. (SharkStack::CreateCheckStack): Removed. (SharkStackWithNormalFrame::SharkStackWithNormalFrame): Updated for new stack overflow code. (SharkStackWithNativeFrame::SharkStackWithNativeFrame): Likewise. (SharkStack::CreateAssertLastJavaSPIsNull): New method. * ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp (SharkNativeWrapper::initialize): Whitespace fix.
author Gary Benson <gbenson@redhat.com>
date Wed, 09 Jun 2010 17:37:28 +0100
parents b645643e700f
children 1de4376d0732
files ChangeLog ports/hotspot/src/share/vm/shark/sharkBuilder.cpp ports/hotspot/src/share/vm/shark/sharkBuilder.hpp ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp ports/hotspot/src/share/vm/shark/sharkStack.cpp ports/hotspot/src/share/vm/shark/sharkStack.hpp
diffstat 6 files changed, 124 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Jun 09 14:26:24 2010 +0100
+++ b/ChangeLog	Wed Jun 09 17:37:28 2010 +0100
@@ -1,3 +1,31 @@
+2010-05-10  Gary Benson  <gbenson@redhat.com>
+
+	PR icedtea/323
+	* ports/hotspot/src/share/vm/shark/sharkBuilder.hpp
+	(SharkBuilder::throw_StackOverflowError): New method.
+	* ports/hotspot/src/share/vm/shark/sharkBuilder.cpp
+	(SharkBuilder::throw_StackOverflowError): Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkStack.hpp
+	(SharkStack::initialize): Removed argument.
+	(SharkStack::CreateStackOverflowCheck): Updated.
+	(SharkStack::CreateCheckStack): Removed method.
+	(SharkStack::frame_anchor_addr): Likewise.
+	(SharkStack::last_Java_sp_addr): New method.
+	(SharkStack::last_Java_fp_addr): New method.
+	(SharkStack::CreateSetLastJavaFrame): Use new frame anchor code.
+	(SharkStack::CreateResetLastJavaFrame): Likewise.
+	(SharkStack::CreateAssertLastJavaSPIsNull): New method.
+	* ports/hotspot/src/share/vm/shark/sharkStack.cpp
+	(SharkStack::initialize): Updated for new stack overflow code.
+	(SharkStack::CreateStackOverflowCheck): Likewise.
+	(SharkStack::CreateCheckStack): Removed.
+	(SharkStackWithNormalFrame::SharkStackWithNormalFrame): Updated
+	for new stack overflow code.
+	(SharkStackWithNativeFrame::SharkStackWithNativeFrame): Likewise.
+	(SharkStack::CreateAssertLastJavaSPIsNull): New method.
+	* ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp
+	(SharkNativeWrapper::initialize): Whitespace fix.
+
 2010-05-07  Deepak Bhole <dbhole@redhat.com>
 
 	PR icedtea/436:
--- a/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp	Wed Jun 09 14:26:24 2010 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp	Wed Jun 09 17:37:28 2010 +0100
@@ -319,13 +319,17 @@
   return make_function((address) SharedRuntime::OSR_migration_end, "C", "v");
 }
 
-// Uncommon trap
+// Semi-VM calls
+
+Value* SharkBuilder::throw_StackOverflowError() {
+  return make_function((address) ZeroStack::handle_overflow, "T", "v");
+}
 
 Value* SharkBuilder::uncommon_trap() {
   return make_function((address) SharkRuntime::uncommon_trap, "Ti", "v");
 }
 
-// Native-Java transition.
+// Native-Java transition
 
 Value* SharkBuilder::check_special_condition_for_native_trans() {
   return make_function(
--- a/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp	Wed Jun 09 14:26:24 2010 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp	Wed Jun 09 17:37:28 2010 +0100
@@ -125,12 +125,13 @@
   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
-  //   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.
+  // Intrinsics and external functions, part 3: semi-VM calls.
+  //   These are special cases that do VM call stuff but are invoked
+  //   as though they were normal calls.  This is acceptable so long
+  //   as the method that calls them returns to its immediately that
+  //   the semi VM call returns.
  public:
+  llvm::Value* throw_StackOverflowError();
   llvm::Value* uncommon_trap();
 
   // Intrinsics and external functions, part 4: Native-Java transition.
--- a/ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp	Wed Jun 09 14:26:24 2010 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp	Wed Jun 09 17:37:28 2010 +0100
@@ -99,7 +99,7 @@
     builder()->CreateStore(
       builder()->CreateInlineOop(
         JNIHandles::make_local(
-        target()->method_holder()->klass_part()->java_mirror())),
+          target()->method_holder()->klass_part()->java_mirror())),
       oop_tmp_slot());
 
     param_types.push_back(box_type);
--- a/ports/hotspot/src/share/vm/shark/sharkStack.cpp	Wed Jun 09 14:26:24 2010 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkStack.cpp	Wed Jun 09 17:37:28 2010 +0100
@@ -28,7 +28,9 @@
 
 using namespace llvm;
 
-void SharkStack::initialize(Value* method, bool setup_sp_and_method) {
+void SharkStack::initialize(Value* method) {
+  bool setup_sp_and_method = (method != NULL);
+
   int locals_words  = max_locals();
   int extra_locals  = locals_words - arg_size();
   int header_words  = SharkFrame::header_words;
@@ -42,7 +44,7 @@
   Value *stack_pointer = builder()->CreateSub(
     CreateLoadStackPointer(),
     LLVMValue::intptr_constant((frame_words + extra_locals) * wordSize));
-  CreateStackOverflowCheck(stack_pointer, method);
+  CreateStackOverflowCheck(stack_pointer);
   if (setup_sp_and_method)
     CreateStoreStackPointer(stack_pointer);
 
@@ -94,61 +96,48 @@
     builder()->CreatePtrToInt(fp, SharkType::intptr_type()));
 }
 
-// Check that a stack overflow is not imminent, bailing to the
-// interpreter to throw a StackOverflowError if one is while
-// we still have some stack left to do it with.  This function
-// should mirror CppInterpreter::stack_overflow_imminent.
-void SharkStack::CreateStackOverflowCheck(Value* sp, Value* method) {
-  BasicBlock *overflow = CreateBlock("overflow_imminent");
+// This function should match ZeroStack::overflow_check
+void SharkStack::CreateStackOverflowCheck(Value* sp) {
+  BasicBlock *zero_ok  = CreateBlock("zero_stack_ok");
+  BasicBlock *overflow = CreateBlock("stack_overflow");
   BasicBlock *abi_ok   = CreateBlock("abi_stack_ok");
-  BasicBlock *zero_ok  = CreateBlock("zero_stack_ok");
+
+  // Check the Zero stack
+  builder()->CreateCondBr(
+    builder()->CreateICmpULT(sp, stack_base()),
+    overflow, zero_ok);
 
   // Check the ABI stack
-  CreateCheckStack(
-    builder()->CreateSub(
-      builder()->CreateValueOfStructEntry(
-        thread(),
-        Thread::stack_base_offset(),
-        SharkType::intptr_type(),
-        "abi_base"),
-      builder()->CreateValueOfStructEntry(
-        thread(),
-        Thread::stack_size_offset(),
-        SharkType::intptr_type(),
-        "abi_size")),
+  builder()->SetInsertPoint(zero_ok);
+  Value *stack_top = builder()->CreateSub(
+    builder()->CreateValueOfStructEntry(
+      thread(),
+      Thread::stack_base_offset(),
+      SharkType::intptr_type(),
+      "abi_base"),
+    builder()->CreateValueOfStructEntry(
+      thread(),
+      Thread::stack_size_offset(),
+      SharkType::intptr_type(),
+      "abi_size"));
+  Value *free_stack = builder()->CreateSub(
     builder()->CreatePtrToInt(
       builder()->CreateGetFrameAddress(),
       SharkType::intptr_type(),
-      "abi_pointer"),
+      "abi_sp"),
+    stack_top);
+  builder()->CreateCondBr(
+    builder()->CreateICmpULT(
+      free_stack,
+      LLVMValue::intptr_constant(StackShadowPages * os::vm_page_size())),
     overflow, abi_ok);
 
-  // Check the Zero stack
-  builder()->SetInsertPoint(abi_ok);
-  CreateCheckStack(stack_base(), sp, overflow, zero_ok);
-
-  // Bail to the interpreter if an overflow is imminent
+  // Handle overflows
   builder()->SetInsertPoint(overflow);
-  builder()->CreateCall3(
-    builder()->CreateIntToPtr(
-      LLVMValue::intptr_constant((intptr_t) interpreter_entry_point()),
-      PointerType::getUnqual(SharkType::entry_point_type())),
-    method,
-    LLVMValue::intptr_constant(0),
-    thread());
+  builder()->CreateCall(builder()->throw_StackOverflowError(), thread());
   builder()->CreateRetVoid();
 
-  builder()->SetInsertPoint(zero_ok);
-}
-
-void SharkStack::CreateCheckStack(Value*      base,
-                                  Value*      sp,
-                                  BasicBlock* overflow,
-                                  BasicBlock* no_overflow) {
-  builder()->CreateCondBr(
-    builder()->CreateICmpULT(
-      builder()->CreateSub(sp, base),
-      LLVMValue::intptr_constant(StackShadowPages * os::vm_page_size())),
-    overflow, no_overflow);
+  builder()->SetInsertPoint(abi_ok);
 }
 
 Value* SharkStack::CreatePopFrame(int result_slots) {
@@ -202,12 +191,12 @@
   // be set during each decache, so it is not necessary to do them
   // at the time the frame is created.  However, we set them for
   // non-PRODUCT builds to make crash dumps easier to understand.
-  initialize(method, NOT_PRODUCT(true) PRODUCT_ONLY(false));
+  initialize(PRODUCT_ONLY(NULL) NOT_PRODUCT(method));
 }
 SharkStackWithNativeFrame::SharkStackWithNativeFrame(SharkNativeWrapper* wrp,
                                                      Value*              method)
   : SharkStack(wrp), _wrapper(wrp) {
-  initialize(method, true);
+  initialize(method);
 }
 
 int SharkStackWithNormalFrame::arg_size() const {
@@ -251,3 +240,24 @@
 address SharkStackWithNativeFrame::interpreter_entry_point() const {
   return (address) CppInterpreter::native_entry;
 }
+
+#ifndef PRODUCT
+void SharkStack::CreateAssertLastJavaSPIsNull() const {
+#ifdef ASSERT
+  BasicBlock *fail = CreateBlock("assert_failed");
+  BasicBlock *pass = CreateBlock("assert_ok");
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(
+      builder()->CreateLoad(last_Java_sp_addr()),
+      LLVMValue::intptr_constant(0)),
+    pass, fail);
+
+  builder()->SetInsertPoint(fail);
+  builder()->CreateShouldNotReachHere(__FILE__, __LINE__);
+  builder()->CreateUnreachable();
+
+  builder()->SetInsertPoint(pass);
+#endif // ASSERT
+}
+#endif // !PRODUCT
--- a/ports/hotspot/src/share/vm/shark/sharkStack.hpp	Wed Jun 09 14:26:24 2010 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkStack.hpp	Wed Jun 09 17:37:28 2010 +0100
@@ -40,16 +40,10 @@
     : SharkCompileInvariants(parent) {}
 
  protected:
-  void initialize(llvm::Value* method, bool setup_sp_and_method);
+  void initialize(llvm::Value* method);
 
  protected:
-  void CreateStackOverflowCheck(llvm::Value* sp, llvm::Value* method);
-
- private:
-  void CreateCheckStack(llvm::Value*      base,
-                        llvm::Value*      sp,
-                        llvm::BasicBlock* overflow,
-                        llvm::BasicBlock* no_overflow);
+  void CreateStackOverflowCheck(llvm::Value* sp);
 
   // Properties of the method being compiled
  protected:
@@ -114,24 +108,39 @@
 
   // Interface with the frame anchor
  private:
-  llvm::Value* frame_anchor_addr() const {
+  llvm::Value* last_Java_sp_addr() const {
     return builder()->CreateAddressOfStructEntry(
       thread(),
       JavaThread::last_Java_sp_offset(),
       llvm::PointerType::getUnqual(SharkType::intptr_type()),
-      "frame_anchor_addr");
+      "last_Java_sp_addr");
+  }
+  llvm::Value* last_Java_fp_addr() const {
+    return builder()->CreateAddressOfStructEntry(
+      thread(),
+      JavaThread::last_Java_fp_offset(),
+      llvm::PointerType::getUnqual(SharkType::intptr_type()),
+      "last_Java_fp_addr");
   }
 
  public:
-  llvm::StoreInst* CreateSetLastJavaFrame() {
-    return builder()->CreateStore(
-      CreateLoadFramePointer(), frame_anchor_addr());
+  void CreateSetLastJavaFrame() {
+    // Note that whenever _last_Java_sp != NULL other anchor fields
+    // must be valid.  The profiler apparently depends on this.
+    NOT_PRODUCT(CreateAssertLastJavaSPIsNull());
+    builder()->CreateStore(CreateLoadFramePointer(), last_Java_fp_addr());
+    // XXX There's last_Java_pc as well, but I don't think anything uses it
+    // Also XXX: should we fence here?  Zero doesn't...
+    builder()->CreateStore(CreateLoadStackPointer(), last_Java_sp_addr());
+    // Also also XXX: we could probably cache the sp (and the fp we know??)
   }
-  llvm::StoreInst* CreateResetLastJavaFrame() {
-    return builder()->CreateStore(
-      LLVMValue::intptr_constant(0), frame_anchor_addr());
+  void CreateResetLastJavaFrame() {
+    builder()->CreateStore(LLVMValue::intptr_constant(0), last_Java_sp_addr());
   }
 
+ private:
+  void CreateAssertLastJavaSPIsNull() const PRODUCT_RETURN;
+
   // Our method's frame
  private:
   llvm::Value* _frame;