diff src/share/vm/compiler/compileBroker.cpp @ 6948:e522a00b91aa

Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/ after NPG - C++ build works
author Doug Simon <doug.simon@oracle.com>
date Mon, 12 Nov 2012 23:14:12 +0100
parents 957c266d8bc5 18fb7da42534
children 1baf7f1e3f23
line wrap: on
line diff
--- a/src/share/vm/compiler/compileBroker.cpp	Mon Nov 12 18:11:17 2012 +0100
+++ b/src/share/vm/compiler/compileBroker.cpp	Mon Nov 12 23:14:12 2012 +0100
@@ -31,8 +31,8 @@
 #include "compiler/compilerOracle.hpp"
 #include "interpreter/linkResolver.hpp"
 #include "memory/allocation.inline.hpp"
-#include "oops/methodDataOop.hpp"
-#include "oops/methodOop.hpp"
+#include "oops/methodData.hpp"
+#include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/nativeLookup.hpp"
 #include "runtime/arguments.hpp"
@@ -200,9 +200,9 @@
 
   void log_compile(JavaThread* thread, CompileTask* task) {
     StringLogMessage lm;
-    stringStream msg = lm.stream();
+    stringStream sstr = lm.stream();
     // msg.time_stamp().update_to(tty->time_stamp().ticks());
-    task->print_compilation(&msg, true);
+    task->print_compilation(&sstr, NULL, true);
     log(thread, "%s", (const char*)lm);
   }
 
@@ -245,7 +245,7 @@
   if (log != NULL)  task->log_task_done(log);
   thread->set_task(NULL);
   task->set_code_handle(NULL);
-  DEBUG_ONLY(thread->set_env((ciEnv*)badAddress));
+  thread->set_env(NULL);
   if (task->is_blocking()) {
     MutexLocker notifier(task->lock(), thread);
     task->mark_complete();
@@ -274,7 +274,8 @@
   assert(!_lock->is_locked(), "bad locking");
 
   _compile_id = compile_id;
-  _method = JNIHandles::make_global(method);
+  _method = method();
+  _method_loader = JNIHandles::make_global(_method->method_holder()->class_loader());
   _osr_bci = osr_bci;
   _is_blocking = is_blocking;
   _comp_level = comp_level;
@@ -285,6 +286,7 @@
   _code_handle = NULL;
 
   _hot_method = NULL;
+  _hot_method_loader = NULL;
   _hot_count = hot_count;
   _time_queued = 0;  // tidy
   _comment = comment;
@@ -295,8 +297,9 @@
       if (hot_method == method) {
         _hot_method = _method;
       } else {
-        _hot_method = JNIHandles::make_global(hot_method);
+        _hot_method = hot_method();
       }
+      _hot_method_loader = JNIHandles::make_global(_hot_method->method_holder()->class_loader());
     }
   }
 
@@ -321,19 +324,25 @@
 void CompileTask::free() {
   set_code(NULL);
   assert(!_lock->is_locked(), "Should not be locked when freed");
-  if (_hot_method != NULL && _hot_method != _method) {
-    JNIHandles::destroy_global(_hot_method);
-  }
-  JNIHandles::destroy_global(_method);
+  JNIHandles::destroy_global(_method_loader);
+  JNIHandles::destroy_global(_hot_method_loader);
 }
 
 
+void CompileTask::mark_on_stack() {
+  // Mark these methods as something redefine classes cannot remove.
+  _method->set_on_stack(true);
+  if (_hot_method != NULL) {
+    _hot_method->set_on_stack(true);
+  }
+}
+
 // ------------------------------------------------------------------
 // CompileTask::print
 void CompileTask::print() {
   tty->print("<CompileTask compile_id=%d ", _compile_id);
   tty->print("method=");
-  ((methodOop)JNIHandles::resolve(_method))->print_name(tty);
+  _method->print_name(tty);
   tty->print_cr(" osr_bci=%d is_blocking=%s is_complete=%s is_success=%s>",
              _osr_bci, bool_to_str(_is_blocking),
              bool_to_str(_is_complete), bool_to_str(_is_success));
@@ -368,7 +377,7 @@
 
 // ------------------------------------------------------------------
 // CompileTask::print_compilation_impl
-void CompileTask::print_compilation_impl(outputStream* st, methodOop method, int compile_id, int comp_level,
+void CompileTask::print_compilation_impl(outputStream* st, Method* method, int compile_id, int comp_level,
                                          bool is_osr_method, int osr_bci, bool is_blocking,
                                          const char* msg, bool short_form) {
   if (!short_form) {
@@ -485,20 +494,16 @@
 
 // ------------------------------------------------------------------
 // CompileTask::print_compilation
-void CompileTask::print_compilation(outputStream* st, bool short_form) {
-  oop rem = JNIHandles::resolve(method_handle());
-  assert(rem != NULL && rem->is_method(), "must be");
-  methodOop method = (methodOop) rem;
+void CompileTask::print_compilation(outputStream* st, const char* msg, bool short_form) {
   bool is_osr_method = osr_bci() != InvocationEntryBci;
-  print_compilation_impl(st, method, compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking(), NULL, short_form);
+  print_compilation_impl(st, method(), compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking(), msg, short_form);
 }
 
 // ------------------------------------------------------------------
 // CompileTask::log_task
 void CompileTask::log_task(xmlStream* log) {
   Thread* thread = Thread::current();
-  methodHandle method(thread,
-                      (methodOop)JNIHandles::resolve(method_handle()));
+  methodHandle method(thread, this->method());
   ResourceMark rm(thread);
 
   // <task id='9' method='M' osr_bci='X' level='1' blocking='1' stamp='1.234'>
@@ -533,10 +538,8 @@
     xtty->print(" comment='%s'", _comment);
   }
   if (_hot_method != NULL) {
-    methodHandle hot(thread,
-                     (methodOop)JNIHandles::resolve(_hot_method));
-    methodHandle method(thread,
-                        (methodOop)JNIHandles::resolve(_method));
+    methodHandle hot(thread, _hot_method);
+    methodHandle method(thread, _method);
     if (hot() != method()) {
       xtty->method(hot);
     }
@@ -561,8 +564,7 @@
 // CompileTask::log_task_done
 void CompileTask::log_task_done(CompileLog* log) {
   Thread* thread = Thread::current();
-  methodHandle method(thread,
-                      (methodOop)JNIHandles::resolve(method_handle()));
+  methodHandle method(thread, this->method());
   ResourceMark rm(thread);
 
   // <task_done ... stamp='1.234'>  </task>
@@ -613,7 +615,7 @@
   ++_size;
 
   // Mark the method as being in the compile queue.
-  ((methodOop)JNIHandles::resolve(task->method_handle()))->set_queued_for_compilation();
+  task->method()->set_queued_for_compilation();
 
   if (CIPrintCompileQueue) {
     print();
@@ -677,6 +679,16 @@
   --_size;
 }
 
+// methods in the compile queue need to be marked as used on the stack
+// so that they don't get reclaimed by Redefine Classes
+void CompileQueue::mark_on_stack() {
+  CompileTask* task = _first;
+  while (task != NULL) {
+    task->mark_on_stack();
+    task = task->next();
+  }
+}
+
 // ------------------------------------------------------------------
 // CompileQueue::print
 void CompileQueue::print() {
@@ -875,7 +887,7 @@
 CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, TRAPS) {
   CompilerThread* compiler_thread = NULL;
 
-  klassOop k =
+  Klass* k =
     SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(),
                                       true, CHECK_0);
   instanceKlassHandle klass (THREAD, k);
@@ -994,6 +1006,18 @@
   }
 }
 
+
+// Set the methods on the stack as on_stack so that redefine classes doesn't
+// reclaim them
+void CompileBroker::mark_on_stack() {
+  if (_c2_method_queue != NULL) {
+    _c2_method_queue->mark_on_stack();
+  }
+  if (_c1_method_queue != NULL) {
+    _c1_method_queue->mark_on_stack();
+  }
+}
+
 // ------------------------------------------------------------------
 // CompileBroker::is_idle
 bool CompileBroker::is_idle() {
@@ -1033,9 +1057,9 @@
   }
 
   guarantee(!method->is_abstract(), "cannot compile abstract methods");
-  assert(method->method_holder()->klass_part()->oop_is_instance(),
+  assert(method->method_holder()->oop_is_instance(),
          "sanity check");
-  assert(!instanceKlass::cast(method->method_holder())->is_not_initialized(),
+  assert(!method->method_holder()->is_not_initialized(),
          "method holder must be initialized");
   assert(!method->is_method_handle_intrinsic(), "do not enqueue these guys");
 
@@ -1092,7 +1116,7 @@
   // the pending list lock or a 3-way deadlock may occur
   // between the reference handler thread, a GC (instigated
   // by a compiler thread), and compiled method registration.
-  if (instanceRefKlass::owns_pending_list_lock(JavaThread::current())) {
+  if (InstanceRefKlass::owns_pending_list_lock(JavaThread::current())) {
     return;
   }
 #ifdef GRAAL
@@ -1196,10 +1220,10 @@
                                        methodHandle hot_method, int hot_count,
                                        const char* comment, Thread* THREAD) {
   // make sure arguments make sense
-  assert(method->method_holder()->klass_part()->oop_is_instance(), "not an instance method");
+  assert(method->method_holder()->oop_is_instance(), "not an instance method");
   assert(osr_bci == InvocationEntryBci || (0 <= osr_bci && osr_bci < method->code_size()), "bci out of range");
   assert(!method->is_abstract() && (osr_bci == InvocationEntryBci || !method->is_native()), "cannot compile abstract/native methods");
-  assert(!instanceKlass::cast(method->method_holder())->is_not_initialized(), "method holder must be initialized");
+  assert(!method->method_holder()->is_not_initialized(), "method holder must be initialized");
 
   if (!TieredCompilation) {
     comp_level = CompLevel_highest_tier;
@@ -1242,7 +1266,7 @@
     // We accept a higher level osr method
     nmethod* nm = method->lookup_osr_nmethod_for(osr_bci, comp_level, false);
     if (nm != NULL) return nm;
-    if (method->is_not_osr_compilable()) return NULL;
+    if (method->is_not_osr_compilable(comp_level)) return NULL;
   }
 
   assert(!HAS_PENDING_EXCEPTION, "No exception should be present");
@@ -1251,7 +1275,7 @@
     method->constants()->resolve_string_constants(CHECK_AND_CLEAR_NULL);
     // Resolve all classes seen in the signature of the method
     // we are compiling.
-    methodOopDesc::load_signature_classes(method, CHECK_AND_CLEAR_NULL);
+    Method::load_signature_classes(method, CHECK_AND_CLEAR_NULL);
   }
 
   // If the method is native, do the lookup in the thread requesting
@@ -1323,7 +1347,7 @@
                                             int          comp_level) {
   bool is_osr = (osr_bci != standard_entry_bci);
   if (is_osr) {
-    if (method->is_not_osr_compilable()) {
+    if (method->is_not_osr_compilable(comp_level)) {
       return true;
     } else {
       nmethod* result = method->lookup_osr_nmethod_for(osr_bci, comp_level, true);
@@ -1374,7 +1398,7 @@
   // Some compilers may not support on stack replacement.
   if (is_osr &&
       (!CICompileOSR || !compiler(comp_level)->supports_osr())) {
-    method->set_not_osr_compilable();
+    method->set_not_osr_compilable(comp_level);
     return true;
   }
 
@@ -1433,7 +1457,7 @@
 // Should the current thread be blocked until this compilation request
 // has been fulfilled?
 bool CompileBroker::is_compile_blocking(methodHandle method, int osr_bci) {
-  assert(!instanceRefKlass::owns_pending_list_lock(JavaThread::current()), "possible deadlock");
+  assert(!InstanceRefKlass::owns_pending_list_lock(JavaThread::current()), "possible deadlock");
   return !BackgroundCompilation;
 }
 
@@ -1514,8 +1538,7 @@
   JavaThread *thread = JavaThread::current();
   thread->set_blocked_on_compilation(true);
 
-  methodHandle method(thread,
-                      (methodOop)JNIHandles::resolve(task->method_handle()));
+  methodHandle method(thread, task->method());
   {
     MutexLocker waiter(task->lock(), thread);
 
@@ -1564,7 +1587,8 @@
   }
   CompileLog* log = thread->log();
   if (log != NULL) {
-    log->begin_elem("start_compile_thread thread='" UINTX_FORMAT "' process='%d'",
+    log->begin_elem("start_compile_thread name='%s' thread='" UINTX_FORMAT "' process='%d'",
+                    thread->name(),
                     os::current_thread_id(),
                     os::current_process_id());
     log->stamp();
@@ -1600,8 +1624,7 @@
       CompileTaskWrapper ctw(task);
       nmethodLocker result_handle;  // (handle for the nmethod produced by this task)
       task->set_code_handle(&result_handle);
-      methodHandle method(thread,
-                     (methodOop)JNIHandles::resolve(task->method_handle()));
+      methodHandle method(thread, task->method());
 
       // Never compile a method if breakpoints are present in it
       if (method()->number_of_breakpoints() == 0) {
@@ -1707,7 +1730,6 @@
   }
 }
 
-
 // ------------------------------------------------------------------
 // CompileBroker::invoke_compiler_on_method
 //
@@ -1738,8 +1760,7 @@
     // accidentally be referenced once the thread transitions to
     // native.  The NoHandleMark before the transition should catch
     // any cases where this occurs in the future.
-    methodHandle method(thread,
-                        (methodOop)JNIHandles::resolve(task->method_handle()));
+    methodHandle method(thread, task->method());
     should_break = check_break_at(method, compile_id, is_osr);
     if (should_log && !CompilerOracle::should_log(method)) {
       should_log = false;
@@ -1754,7 +1775,7 @@
 
   // Allocate a new set of JNI handles.
   push_jni_handle_block();
-  jobject target_handle = JNIHandles::make_local(thread, JNIHandles::resolve(task->method_handle()));
+  Method* target_handle = task->method();
   int compilable = ciEnv::MethodCompilable;
   {
     int system_dictionary_modification_counter;
@@ -1804,11 +1825,10 @@
         _compilation_log->log_failure(thread, task, ci_env.failure_reason(), retry_message);
       }
       if (PrintCompilation) {
-        tty->print("%4d   COMPILE SKIPPED: %s", compile_id, ci_env.failure_reason());
-        if (retry_message != NULL) {
-          tty->print(" (%s)", retry_message);
-        }
-        tty->cr();
+        FormatBufferResource msg = retry_message != NULL ?
+            err_msg_res("COMPILE SKIPPED: %s (%s)", ci_env.failure_reason(), retry_message) :
+            err_msg_res("COMPILE SKIPPED: %s",      ci_env.failure_reason());
+        task->print_compilation(tty, msg);
       }
     } else {
       task->mark_success();
@@ -1823,8 +1843,7 @@
   }
   pop_jni_handle_block();
 
-  methodHandle method(thread,
-                      (methodOop)JNIHandles::resolve(task->method_handle()));
+  methodHandle method(thread, task->method());
 
   DTRACE_METHOD_COMPILE_END_PROBE(compiler(task->comp_level()), method, task->is_success());
 
@@ -1838,14 +1857,20 @@
     tty->print_cr("size: %d time: %d inlined: %d bytes", code_size, (int)time.milliseconds(), task->num_inlined_bytecodes());
   }
 
-  if (compilable == ciEnv::MethodCompilable_never) {
-    if (is_osr) {
-      method->set_not_osr_compilable();
-    } else {
+  // Disable compilation, if required.
+  switch (compilable) {
+  case ciEnv::MethodCompilable_never:
+    if (is_osr)
+      method->set_not_osr_compilable_quietly();
+    else
       method->set_not_compilable_quietly();
-    }
-  } else if (compilable == ciEnv::MethodCompilable_not_at_tier) {
-    method->set_not_compilable_quietly(task->comp_level());
+    break;
+  case ciEnv::MethodCompilable_not_at_tier:
+    if (is_osr)
+      method->set_not_osr_compilable_quietly(task->comp_level());
+    else
+      method->set_not_compilable_quietly(task->comp_level());
+    break;
   }
 
   // Note that the queued_for_compilation bits are cleared without
@@ -1918,7 +1943,7 @@
   size_t maxLen = CompilerCounters::cmname_buffer_length;
 
   if (UsePerfData) {
-    const char* class_name = method->method_holder()->klass_part()->name()->as_C_string();
+    const char* class_name = method->method_holder()->name()->as_C_string();
 
     size_t s1len = strlen(class_name);
     size_t s2len = strlen(method_name);
@@ -2012,7 +2037,7 @@
 
 void CompileBroker::collect_statistics(CompilerThread* thread, elapsedTimer time, CompileTask* task) {
   bool success = task->is_success();
-  methodHandle method (thread, (methodOop)JNIHandles::resolve(task->method_handle()));
+  methodHandle method (thread, task->method());
   uint compile_id = task->compile_id();
   bool is_osr = (task->osr_bci() != standard_entry_bci);
   nmethod* code = task->code();