Shark direct call improvements

Gary Benson gbenson at redhat.com
Wed Jun 3 06:36:04 PDT 2009


Hi all,

This commit replaces the interpreter-style lookup of the callee in
the constant pool with a server-JIT-style callee inlined in the code
buffer for direct calls (ie invokestatic, invokespecial, and final
invokevirtual).  This gives a small speedup in itself, but opens the
door to a ton of other optimizations.

Cheers,
Gary

-- 
http://gbenson.net/
-------------- next part --------------
diff -r e01a6da1a425 -r 6bbac4cbc210 ChangeLog
--- a/ChangeLog	Tue Jun 02 15:41:45 2009 +0100
+++ b/ChangeLog	Wed Jun 03 14:32:52 2009 +0100
@@ -1,3 +1,33 @@
+2009-06-03  Gary Benson  <gbenson at redhat.com>
+
+	* ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp
+	(MacroAssembler::store_oop): New method.
+	* ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp
+	(MacroAssembler::store_oop): Likewise.
+
+	* ports/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp
+	(Relocation::pd_address_in_code): Implement.
+
+	* ports/hotspot/src/share/vm/shark/sharkCompiler.cpp
+	(SharkCompiler::compile_method): Create CodeBuffer
+	with space for relocations.
+
+	* ports/hotspot/src/share/vm/shark/sharkFunction.hpp
+	(SharkFunction::code_offset): Renamed as...
+	(SharkFunction::create_unique_pc_offset): New method.
+	(SharkFunction::CreateAddressOfCodeBufferEntry): Likewise.
+	(SharkFunction::CreateAddressOfOopInCodeBuffer): Likewise.
+
+	* ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp
+	(SharkDecacher::start_frame): Updated to use new offset code.
+	(SharkDecacher::start_stack): Likewise.
+
+	* ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp
+	(SharkTopLevelBlock::scan_for_traps): Direct calls need no
+	checking.
+	(SharkTopLevelBlock::get_direct_callee): Replace constant
+	pool lookup with oop load from CodeBuffer.
+
 2009-06-02  Gary Benson  <gbenson at redhat.com>
 
 	* ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp
diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp
--- a/ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp	Tue Jun 02 15:41:45 2009 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp	Wed Jun 03 14:32:52 2009 +0100
@@ -60,6 +60,12 @@
   sync();
 }
 
+void MacroAssembler::store_oop(jobject obj)
+{
+  code_section()->relocate(pc(), oop_Relocation::spec_for_immediate());
+  emit_address((address) obj);
+}
+
 static void _UnimplementedStub()
 {
   report_unimplemented(__FILE__, __LINE__);
diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp
--- a/ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp	Tue Jun 02 15:41:45 2009 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp	Wed Jun 03 14:32:52 2009 +0100
@@ -1,6 +1,6 @@
 /*
  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
- * Copyright 2007, 2008 Red Hat, Inc.
+ * Copyright 2007, 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
@@ -45,8 +45,10 @@
   void align(int modulus);
   void bang_stack_with_offset(int offset);
   bool needs_explicit_null_check(intptr_t offset);
+
  public:
   void advance(int bytes);
+  void store_oop(jobject obj);
 };
 
 #ifdef ASSERT
diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp
--- a/ports/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp	Tue Jun 02 15:41:45 2009 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp	Wed Jun 03 14:32:52 2009 +0100
@@ -48,7 +48,8 @@
 
 address* Relocation::pd_address_in_code()
 {
-  Unimplemented();
+  // Relocations in Shark are just stored directly
+  return (address *) addr();
 }
 
 int Relocation::pd_breakpoint_size()
diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp	Tue Jun 02 15:41:45 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp	Wed Jun 03 14:32:52 2009 +0100
@@ -31,7 +31,7 @@
 void SharkDecacher::start_frame()
 {
   // Start recording the debug information
-  _pc_offset = function()->code_offset();
+  _pc_offset = function()->create_unique_pc_offset();
   _oopmap = new OopMap(
     oopmap_slot_munge(function()->oopmap_frame_size()),
     oopmap_slot_munge(function()->arg_size()));
@@ -119,8 +119,7 @@
 {
   // Record the PC
   builder()->CreateStore(
-    builder()->CreateAdd(
-      function()->base_pc(), LLVMValue::intptr_constant(pc_offset())),
+    function()->CreateAddressOfCodeBufferEntry(pc_offset()),
     function()->CreateAddressOfFrameEntry(offset));
 }
   
diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/share/vm/shark/sharkCompiler.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp	Tue Jun 02 15:41:45 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp	Wed Jun 03 14:32:52 2009 +0100
@@ -116,8 +116,7 @@
   env->set_dependencies(new Dependencies(env));
 
   // Create the CodeBuffer and MacroAssembler
-  BufferBlob *bb = BufferBlob::create("shark_temp", 256 * K);
-  CodeBuffer cb(bb->instructions_begin(), bb->instructions_size());
+  CodeBuffer cb("Shark", 256 * K, 64 * K);
   cb.initialize_oop_recorder(env->oop_recorder());
   MacroAssembler *masm = new MacroAssembler(&cb);
 
@@ -148,9 +147,6 @@
                        env->comp_level(),
                        false,
                        false);
-
-  // Free the BufferBlob
-  BufferBlob::free(bb);
 }
 
 
diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/share/vm/shark/sharkFunction.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkFunction.hpp	Tue Jun 02 15:41:45 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkFunction.hpp	Wed Jun 03 14:32:52 2009 +0100
@@ -137,6 +137,28 @@
     return flow()->method();
   }
 
+  // CodeBuffer interface
+ public:
+  int create_unique_pc_offset() const
+  {
+    int offset = masm()->offset();
+    masm()->advance(1);
+    return offset;
+  }
+  llvm::Value* CreateAddressOfCodeBufferEntry(int offset) const
+  {
+    return builder()->CreateAdd(base_pc(), LLVMValue::intptr_constant(offset));
+  }
+  llvm::Value* CreateAddressOfOopInCodeBuffer(ciObject* object) const
+  {
+    masm()->align(BytesPerWord);
+    int offset = masm()->offset();
+    masm()->store_oop(object->encoding());
+    return builder()->CreateIntToPtr(
+      CreateAddressOfCodeBufferEntry(offset),
+      llvm::PointerType::getUnqual(SharkType::jobject_type()));
+  }
+
   // Block management
  private:
   llvm::BasicBlock* _block_insertion_point;
@@ -217,17 +239,6 @@
  private:
   llvm::Value* CreateBuildFrame();
 
-  // 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();
-    masm()->advance(1); // keeps PCs unique
-    return offset;
-  }
-
  private:
   int _extended_frame_size;
   int _stack_slots_offset;
diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp	Tue Jun 02 15:41:45 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp	Wed Jun 03 14:32:52 2009 +0100
@@ -91,28 +91,26 @@
       index = iter()->get_field_index();
       break;
 
-    case Bytecodes::_invokespecial:
-    case Bytecodes::_invokestatic:
     case Bytecodes::_invokevirtual:
+      method = iter()->get_method(will_link);
+      assert(will_link, "typeflow responsibility");
+
+      // If this is a non-final invokevirtual then we need to
+      // check that its holder is linked, because its vtable
+      // won't have been set up otherwise.
+      if (!method->is_final_method() && !method->holder()->is_linked()) {
+        set_trap(
+          Deoptimization::make_trap_request(
+            Deoptimization::Reason_uninitialized,
+            Deoptimization::Action_reinterpret), bci());
+          return;
+      }
+      break;
+
     case Bytecodes::_invokeinterface:
       method = iter()->get_method(will_link);
       assert(will_link, "typeflow responsibility");
 
-      // If this is a non-final invokevirtual then there won't
-      // be a pool access.  We do need to check that its holder
-      // is linked, however, because its vtable won't have been
-      // set up otherwise.
-      if (bc() == Bytecodes::_invokevirtual && !method->is_final_method()) {
-        if (!method->holder()->is_linked()) {
-          set_trap(
-            Deoptimization::make_trap_request(
-              Deoptimization::Reason_uninitialized,
-              Deoptimization::Action_reinterpret), bci());
-          return;
-        }
-        break;
-      }
-
       // Continue to the check
       index = iter()->get_method_index();
       break;
@@ -897,15 +895,10 @@
 // invokevirtual is direct in some circumstances.
 Value *SharkTopLevelBlock::get_direct_callee(ciMethod* method)
 {
-  SharkConstantPool constants(this);
-  Value *cache = constants.cache_entry_at(iter()->get_method_index());
-  return builder()->CreateValueOfStructEntry(
-    cache,
-    bc() == Bytecodes::_invokevirtual ?
-      ConstantPoolCacheEntry::f2_offset() :
-      ConstantPoolCacheEntry::f1_offset(),
-    SharkType::methodOop_type(),
-    "callee");
+  return builder()->CreateLoad(
+    builder()->CreateBitCast(
+      function()->CreateAddressOfOopInCodeBuffer(method),
+      PointerType::getUnqual(SharkType::methodOop_type())), "callee");
 }
 
 // Non-direct virtual calls are handled here


More information about the distro-pkg-dev mailing list