changeset 22538:ea6d1727fdc6

Remove BufferBlob from JavaThread and allocate as needed during compilation
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Tue, 08 Sep 2015 16:41:04 -0700
parents 9554ce7b6eb5
children 9ad3b2d1e7cd
files src/share/vm/compiler/abstractCompiler.cpp src/share/vm/jvmci/jvmciCodeInstaller.cpp src/share/vm/jvmci/jvmciCodeInstaller.hpp src/share/vm/jvmci/jvmciCompiler.cpp src/share/vm/jvmci/jvmciRuntime.cpp src/share/vm/jvmci/jvmciRuntime.hpp src/share/vm/runtime/thread.cpp src/share/vm/runtime/thread.hpp
diffstat 8 files changed, 29 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/compiler/abstractCompiler.cpp	Tue Sep 08 11:13:51 2015 -0700
+++ b/src/share/vm/compiler/abstractCompiler.cpp	Tue Sep 08 16:41:04 2015 -0700
@@ -58,7 +58,7 @@
 }
 
 void AbstractCompiler::set_state(int state) {
-  // Ensure that ste is only set by one thread at a time
+  // Ensure that state is only set by one thread at a time
   MutexLocker only_one(CompileThread_lock);
   _compiler_state =  state;
   CompileThread_lock->notify_all();
--- a/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Tue Sep 08 11:13:51 2015 -0700
+++ b/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Tue Sep 08 16:41:04 2015 -0700
@@ -390,12 +390,7 @@
 
 // constructor used to create a method
 JVMCIEnv::CodeInstallResult CodeInstaller::install(Handle target, Handle& compiled_code, CodeBlob*& cb, Handle installed_code, Handle speculation_log) {
-  BufferBlob* buffer_blob = JVMCIRuntime::initialize_buffer_blob();
-  if (buffer_blob == NULL) {
-    return JVMCIEnv::cache_full;
-  }
-
-  CodeBuffer buffer(buffer_blob);
+  CodeBuffer buffer("JVMCI Compiler CodeBuffer");
   jobject compiled_code_obj = JNIHandles::make_local(compiled_code());
   initialize_dependencies(JNIHandles::resolve(compiled_code_obj));
 
@@ -403,18 +398,15 @@
   _instructions = buffer.insts();
   _constants = buffer.consts();
 
-  {
-    jobject target_obj = JNIHandles::make_local(target());
-    initialize_fields(JNIHandles::resolve(target_obj), JNIHandles::resolve(compiled_code_obj));
-    if (!initialize_buffer(buffer)) {
-      return JVMCIEnv::code_too_large;
-    }
-    process_exception_handlers();
+  initialize_fields(target(), JNIHandles::resolve(compiled_code_obj));
+  JVMCIEnv::CodeInstallResult result = initialize_buffer(buffer);
+  if (result != JVMCIEnv::ok) {
+    return result;
   }
+  process_exception_handlers();
 
   int stack_slots = _total_frame_size / HeapWordSize; // conversion to words
 
-  JVMCIEnv::CodeInstallResult result;
   if (!compiled_code->is_a(HotSpotCompiledNmethod::klass())) {
     oop stubName = HotSpotCompiledCode::name(compiled_code_obj);
     char* name = strdup(java_lang_String::as_utf8_string(stubName));
@@ -488,7 +480,7 @@
   _word_kind_handle = JNIHandles::make_local(Architecture::wordKind(arch));
 }
 
-int CodeInstaller::estimate_stub_entries() {
+int CodeInstaller::estimate_stubs_size() {
   // Estimate the number of static call stubs that might be emitted.
   int static_call_stubs = 0;
   objArrayOop sites = this->sites();
@@ -505,21 +497,31 @@
       }
     }
   }
-  return static_call_stubs;
+  return static_call_stubs * CompiledStaticCall::to_interp_stub_size();
 }
 
 // perform data and call relocation on the CodeBuffer
-bool CodeInstaller::initialize_buffer(CodeBuffer& buffer) {
+JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer) {
   HandleMark hm;
   objArrayHandle sites = this->sites();
   int locs_buffer_size = sites->length() * (relocInfo::length_limit + sizeof(relocInfo));
-  char* locs_buffer = NEW_RESOURCE_ARRAY(char, locs_buffer_size);
-  buffer.insts()->initialize_shared_locs((relocInfo*)locs_buffer, locs_buffer_size / sizeof(relocInfo));
+
   // Allocate enough space in the stub section for the static call
   // stubs.  Stubs have extra relocs but they are managed by the stub
   // section itself so they don't need to be accounted for in the
   // locs_buffer above.
-  buffer.initialize_stubs_size(estimate_stub_entries() * CompiledStaticCall::to_interp_stub_size());
+  int stubs_size = estimate_stubs_size();
+  int total_size = round_to(_code_size, buffer.insts()->alignment()) + round_to(_constants_size, buffer.consts()->alignment()) + round_to(stubs_size, buffer.stubs()->alignment());
+
+  if (total_size > JVMCINMethodSizeLimit) {
+    return JVMCIEnv::code_too_large;
+  }
+
+  buffer.initialize(total_size, locs_buffer_size);
+  if (buffer.blob() == NULL) {
+    return JVMCIEnv::cache_full;
+  }
+  buffer.initialize_stubs_size(stubs_size);
   buffer.initialize_consts_size(_constants_size);
 
   _debug_recorder = new DebugInformationRecorder(_oop_recorder);
@@ -534,9 +536,7 @@
 
   // copy the code into the newly created CodeBuffer
   address end_pc = _instructions->start() + _code_size;
-  if (!_instructions->allocates2(end_pc)) {
-    return false;
-  }
+  guarantee(_instructions->allocates2(end_pc), "initialize should have reserved enough space for all the code");
   memcpy(_instructions->start(), code()->base(T_BYTE), _code_size);
   _instructions->set_end(end_pc);
 
@@ -617,7 +617,7 @@
     }
   }
 #endif
-  return true;
+  return JVMCIEnv::ok;
 }
 
 void CodeInstaller::assumption_NoFinalizableSubclass(Handle assumption) {
--- a/src/share/vm/jvmci/jvmciCodeInstaller.hpp	Tue Sep 08 11:13:51 2015 -0700
+++ b/src/share/vm/jvmci/jvmciCodeInstaller.hpp	Tue Sep 08 16:41:04 2015 -0700
@@ -128,10 +128,10 @@
   void initialize_fields(oop target, oop target_method);
   void initialize_dependencies(oop target_method);
   
-  int estimate_stub_entries();
+  int estimate_stubs_size();
   
   // perform data and call relocation on the CodeBuffer
-  bool initialize_buffer(CodeBuffer& buffer);
+  JVMCIEnv::CodeInstallResult initialize_buffer(CodeBuffer& buffer);
 
   void assumption_NoFinalizableSubclass(Handle assumption);
   void assumption_ConcreteSubtype(Handle assumption);
--- a/src/share/vm/jvmci/jvmciCompiler.cpp	Tue Sep 08 11:13:51 2015 -0700
+++ b/src/share/vm/jvmci/jvmciCompiler.cpp	Tue Sep 08 16:41:04 2015 -0700
@@ -50,12 +50,8 @@
     return;
   }
 
-  BufferBlob* buffer_blob = JVMCIRuntime::initialize_buffer_blob();
-  if (buffer_blob == NULL) {
-    set_state(failed);
-  } else {
-    set_state(initialized);
-  }
+  set_state(initialized);
+
   // JVMCI is considered as application code so we need to
   // stop the VM deferring compilation now.
   CompilationPolicy::completed_vm_startup();
--- a/src/share/vm/jvmci/jvmciRuntime.cpp	Tue Sep 08 11:13:51 2015 -0700
+++ b/src/share/vm/jvmci/jvmciRuntime.cpp	Tue Sep 08 16:41:04 2015 -0700
@@ -83,18 +83,6 @@
   }
 }
 
-BufferBlob* JVMCIRuntime::initialize_buffer_blob() {
-  JavaThread* THREAD = JavaThread::current();
-  BufferBlob* buffer_blob = THREAD->get_buffer_blob();
-  if (buffer_blob == NULL) {
-    buffer_blob = BufferBlob::create("JVMCI thread-local CodeBuffer", JVMCINMethodSizeLimit);
-    if (buffer_blob != NULL) {
-      THREAD->set_buffer_blob(buffer_blob);
-    }
-  }
-  return buffer_blob;
-}
-
 BasicType JVMCIRuntime::kindToBasicType(jchar ch) {
   switch(ch) {
     case 'z': return T_BOOLEAN;
--- a/src/share/vm/jvmci/jvmciRuntime.hpp	Tue Sep 08 11:13:51 2015 -0700
+++ b/src/share/vm/jvmci/jvmciRuntime.hpp	Tue Sep 08 16:41:04 2015 -0700
@@ -184,8 +184,6 @@
    */
   static Klass* load_required_class(Symbol* name);
 
-  static BufferBlob* initialize_buffer_blob();
-
   static BasicType kindToBasicType(jchar ch);
 
   // The following routines are all called from compiled JVMCI code
--- a/src/share/vm/runtime/thread.cpp	Tue Sep 08 11:13:51 2015 -0700
+++ b/src/share/vm/runtime/thread.cpp	Tue Sep 08 16:41:04 2015 -0700
@@ -1458,7 +1458,6 @@
   // Set the claimed par_id to UINT_MAX (ie not claiming any par_ids)
   set_claimed_par_id(UINT_MAX);
 
-  _buffer_blob = NULL;
   set_saved_exception_pc(NULL);
   set_threadObj(NULL);
   _anchor.clear();
--- a/src/share/vm/runtime/thread.hpp	Tue Sep 08 11:13:51 2015 -0700
+++ b/src/share/vm/runtime/thread.hpp	Tue Sep 08 16:41:04 2015 -0700
@@ -785,10 +785,6 @@
   JavaThread*    _next;                          // The next thread in the Threads list
   oop            _threadObj;                     // The Java level thread object
 
-  // (thomaswue) Necessary for holding a compilation buffer.
-  // Moved up from CompilerThread to JavaThread in order to enable code
-  // installation from Java application code.
-  BufferBlob*   _buffer_blob;
 #ifdef ASSERT
  private:
   int _java_call_counter;
@@ -1036,10 +1032,6 @@
     return (struct JNINativeInterface_ *)_jni_environment.functions;
   }
 
-
-  BufferBlob*   get_buffer_blob()                { return _buffer_blob; }
-  void          set_buffer_blob(BufferBlob* b)   { _buffer_blob = b; };
-
   // This function is called at thread creation to allow
   // platform specific thread variables to be initialized.
   void cache_global_variables();