diff src/share/vm/runtime/sharedRuntime.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 d8ce2825b193
children 2cb439954abf
line wrap: on
line diff
--- a/src/share/vm/runtime/sharedRuntime.cpp	Mon Nov 12 18:11:17 2012 +0100
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Mon Nov 12 23:14:12 2012 +0100
@@ -88,6 +88,7 @@
 RuntimeStub*        SharedRuntime::_resolve_static_call_blob;
 
 DeoptimizationBlob* SharedRuntime::_deopt_blob;
+SafepointBlob*      SharedRuntime::_polling_page_vectors_safepoint_handler_blob;
 SafepointBlob*      SharedRuntime::_polling_page_safepoint_handler_blob;
 SafepointBlob*      SharedRuntime::_polling_page_return_handler_blob;
 
@@ -104,8 +105,14 @@
   _resolve_virtual_call_blob           = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_virtual_call_C),      "resolve_virtual_call");
   _resolve_static_call_blob            = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_static_call_C),       "resolve_static_call");
 
-  _polling_page_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), false);
-  _polling_page_return_handler_blob    = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), true);
+#ifdef COMPILER2
+  // Vectors are generated only by C2.
+  if (is_wide_vector(MaxVectorSize)) {
+    _polling_page_vectors_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_VECTOR_LOOP);
+  }
+#endif // COMPILER2
+  _polling_page_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_LOOP);
+  _polling_page_return_handler_blob    = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_RETURN);
 
   generate_deopt_blob();
 
@@ -535,10 +542,15 @@
     "Only polling locations are used for safepoint");
 
   bool at_poll_return = ((nmethod*)cb)->is_at_poll_return(pc);
+  bool has_wide_vectors = ((nmethod*)cb)->has_wide_vectors();
   if (at_poll_return) {
     assert(SharedRuntime::polling_page_return_handler_blob() != NULL,
            "polling page return stub not created yet");
     stub = SharedRuntime::polling_page_return_handler_blob()->entry_point();
+  } else if (has_wide_vectors) {
+    assert(SharedRuntime::polling_page_vectors_safepoint_handler_blob() != NULL,
+           "polling page vectors safepoint stub not created yet");
+    stub = SharedRuntime::polling_page_vectors_safepoint_handler_blob()->entry_point();
   } else {
     assert(SharedRuntime::polling_page_safepoint_handler_blob() != NULL,
            "polling page safepoint stub not created yet");
@@ -590,13 +602,13 @@
 // to modify the compilers to generate calls to this function.
 //
 JRT_LEAF(int, SharedRuntime::rc_trace_method_entry(
-    JavaThread* thread, methodOopDesc* method))
+    JavaThread* thread, Method* method))
   assert(RC_TRACE_IN_RANGE(0x00001000, 0x00002000), "wrong call");
 
   if (method->is_obsolete()) {
     // We are calling an obsolete method, but this is not necessarily
     // an error. Our method could have been redefined just after we
-    // fetched the methodOop from the constant pool.
+    // fetched the Method* from the constant pool.
 
     // RC_TRACE macro has an embedded ResourceMark
     RC_TRACE_WITH_THREAD(0x00001000, thread,
@@ -746,8 +758,8 @@
 JRT_ENTRY(void, SharedRuntime::throw_StackOverflowError(JavaThread* thread))
   // We avoid using the normal exception construction in this case because
   // it performs an upcall to Java, and we're already out of stack space.
-  klassOop k = SystemDictionary::StackOverflowError_klass();
-  oop exception_oop = instanceKlass::cast(k)->allocate_instance(CHECK);
+  Klass* k = SystemDictionary::StackOverflowError_klass();
+  oop exception_oop = InstanceKlass::cast(k)->allocate_instance(CHECK);
   Handle exception (thread, exception_oop);
   if (StackTraceInThrowable) {
     java_lang_Throwable::fill_in_stack_trace(exception);
@@ -953,8 +965,8 @@
 
 JRT_ENTRY_NO_ASYNC(void, SharedRuntime::register_finalizer(JavaThread* thread, oopDesc* obj))
   assert(obj->is_oop(), "must be a valid oop");
-  assert(obj->klass()->klass_part()->has_finalizer(), "shouldn't be here otherwise");
-  instanceKlass::register_finalizer(instanceOop(obj), CHECK);
+  assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
+  InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
 JRT_END
 
 
@@ -979,7 +991,7 @@
 
 int SharedRuntime::dtrace_object_alloc_base(Thread* thread, oopDesc* o) {
   assert(DTraceAllocProbes, "wrong call");
-  Klass* klass = o->blueprint();
+  Klass* klass = o->klass();
   int size = o->size();
   Symbol* name = klass->name();
 #ifndef USDT2
@@ -994,7 +1006,7 @@
 }
 
 JRT_LEAF(int, SharedRuntime::dtrace_method_entry(
-    JavaThread* thread, methodOopDesc* method))
+    JavaThread* thread, Method* method))
   assert(DTraceMethodProbes, "wrong call");
   Symbol* kname = method->klass_name();
   Symbol* name = method->name();
@@ -1015,7 +1027,7 @@
 JRT_END
 
 JRT_LEAF(int, SharedRuntime::dtrace_method_exit(
-    JavaThread* thread, methodOopDesc* method))
+    JavaThread* thread, Method* method))
   assert(DTraceMethodProbes, "wrong call");
   Symbol* kname = method->klass_name();
   Symbol* name = method->name();
@@ -1103,7 +1115,7 @@
   if (bc != Bytecodes::_invokestatic && bc != Bytecodes::_invokedynamic) {
     assert(receiver.not_null(), "should have thrown exception");
     KlassHandle receiver_klass(THREAD, receiver->klass());
-    klassOop rk = constants->klass_ref_at(bytecode_index, CHECK_(nullHandle));
+    Klass* rk = constants->klass_ref_at(bytecode_index, CHECK_(nullHandle));
                             // klass is already loaded
     KlassHandle static_receiver_klass(THREAD, rk);
     // Method handle invokes might have been optimized to a direct call
@@ -1115,11 +1127,11 @@
            callee->is_compiled_lambda_form(),
            "actual receiver must be subclass of static receiver klass");
     if (receiver_klass->oop_is_instance()) {
-      if (instanceKlass::cast(receiver_klass())->is_not_initialized()) {
+      if (InstanceKlass::cast(receiver_klass())->is_not_initialized()) {
         tty->print_cr("ERROR: Klass not yet initialized!!");
-        receiver_klass.print();
+        receiver_klass()->print();
       }
-      assert(!instanceKlass::cast(receiver_klass())->is_not_initialized(), "receiver_klass must be initialized");
+      assert(!InstanceKlass::cast(receiver_klass())->is_not_initialized(), "receiver_klass must be initialized");
     }
   }
 #endif
@@ -1277,7 +1289,7 @@
   {
     MutexLocker ml_patch(CompiledIC_lock);
 
-    // Now that we are ready to patch if the methodOop was redefined then
+    // Now that we are ready to patch if the Method* was redefined then
     // don't update call site and let the caller retry.
 
     if (!callee_method->is_old()) {
@@ -1289,7 +1301,9 @@
       }
 #endif
       if (is_virtual) {
-        CompiledIC* inline_cache = CompiledIC_before(caller_frame.pc());
+        nmethod* nm = callee_nm;
+        if (nm == NULL) CodeCache::find_blob(caller_frame.pc());
+        CompiledIC* inline_cache = CompiledIC_before(caller_nm, caller_frame.pc());
         if (inline_cache->is_clean()) {
           inline_cache->set_to_monomorphic(virtual_call_info);
         }
@@ -1318,8 +1332,8 @@
   methodHandle callee_method;
   JRT_BLOCK
     callee_method = SharedRuntime::handle_ic_miss_helper(thread, CHECK_NULL);
-    // Return methodOop through TLS
-    thread->set_vm_result(callee_method());
+    // Return Method* through TLS
+    thread->set_vm_result_2(callee_method());
   JRT_BLOCK_END
   // return compiled code entry point after potential safepoints
   assert(callee_method->verified_code_entry() != NULL, " Jump to zero!");
@@ -1351,9 +1365,9 @@
 
   if (caller_frame.is_interpreted_frame() ||
       caller_frame.is_entry_frame()) {
-    methodOop callee = thread->callee_target();
+    Method* callee = thread->callee_target();
     guarantee(callee != NULL && callee->is_method(), "bad handshake");
-    thread->set_vm_result(callee);
+    thread->set_vm_result_2(callee);
     thread->set_callee_target(NULL);
     return callee->get_c2i_entry();
   }
@@ -1363,7 +1377,7 @@
   JRT_BLOCK
     // Force resolving of caller (if we called from compiled frame)
     callee_method = SharedRuntime::reresolve_call_site(thread, CHECK_NULL);
-    thread->set_vm_result(callee_method());
+    thread->set_vm_result_2(callee_method());
   JRT_BLOCK_END
   // return compiled code entry point after potential safepoints
   assert(callee_method->verified_code_entry() != NULL, " Jump to zero!");
@@ -1376,7 +1390,7 @@
   methodHandle callee_method;
   JRT_BLOCK
     callee_method = SharedRuntime::resolve_helper(thread, false, false, CHECK_NULL);
-    thread->set_vm_result(callee_method());
+    thread->set_vm_result_2(callee_method());
   JRT_BLOCK_END
   // return compiled code entry point after potential safepoints
   assert(callee_method->verified_code_entry() != NULL, " Jump to zero!");
@@ -1389,7 +1403,7 @@
   methodHandle callee_method;
   JRT_BLOCK
     callee_method = SharedRuntime::resolve_helper(thread, true, false, CHECK_NULL);
-    thread->set_vm_result(callee_method());
+    thread->set_vm_result_2(callee_method());
   JRT_BLOCK_END
   // return compiled code entry point after potential safepoints
   assert(callee_method->verified_code_entry() != NULL, " Jump to zero!");
@@ -1403,7 +1417,7 @@
   methodHandle callee_method;
   JRT_BLOCK
     callee_method = SharedRuntime::resolve_helper(thread, true, true, CHECK_NULL);
-    thread->set_vm_result(callee_method());
+    thread->set_vm_result_2(callee_method());
   JRT_BLOCK_END
   // return compiled code entry point after potential safepoints
   assert(callee_method->verified_code_entry() != NULL, " Jump to zero!");
@@ -1486,7 +1500,7 @@
     CodeBlob* cb = caller_frame.cb();
     if (cb->is_nmethod() && ((nmethod*)cb)->is_in_use()) {
       // Not a non-entrant nmethod, so find inline_cache
-      CompiledIC* inline_cache = CompiledIC_before(caller_frame.pc());
+      CompiledIC* inline_cache = CompiledIC_before(((nmethod*)cb), caller_frame.pc());
       bool should_be_mono = false;
       if (inline_cache->is_optimized()) {
         if (TraceCallFixup) {
@@ -1496,9 +1510,9 @@
           tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code());
         }
         should_be_mono = true;
-      } else {
-        compiledICHolderOop ic_oop = (compiledICHolderOop) inline_cache->cached_oop();
-        if ( ic_oop != NULL && ic_oop->is_compiledICHolder()) {
+      } else if (inline_cache->is_icholder_call()) {
+        CompiledICHolder* ic_oop = inline_cache->cached_icholder();
+        if ( ic_oop != NULL) {
 
           if (receiver()->klass() == ic_oop->holder_klass()) {
             // This isn't a real miss. We must have seen that compiled code
@@ -1635,7 +1649,7 @@
           ssc->set_to_clean();
         } else {
           // compiled, dispatched call (which used to call an interpreted method)
-          CompiledIC* inline_cache = CompiledIC_at(call_addr);
+          CompiledIC* inline_cache = CompiledIC_at(caller_nm, call_addr);
           inline_cache->set_to_clean();
         }
       }
@@ -1660,16 +1674,39 @@
   return callee_method;
 }
 
+#ifdef ASSERT
+void SharedRuntime::check_member_name_argument_is_last_argument(methodHandle method,
+                                                                const BasicType* sig_bt,
+                                                                const VMRegPair* regs) {
+  ResourceMark rm;
+  const int total_args_passed = method->size_of_parameters();
+  const VMRegPair*    regs_with_member_name = regs;
+        VMRegPair* regs_without_member_name = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed - 1);
+
+  const int member_arg_pos = total_args_passed - 1;
+  assert(member_arg_pos >= 0 && member_arg_pos < total_args_passed, "oob");
+  assert(sig_bt[member_arg_pos] == T_OBJECT, "dispatch argument must be an object");
+
+  const bool is_outgoing = method->is_method_handle_intrinsic();
+  int comp_args_on_stack = java_calling_convention(sig_bt, regs_without_member_name, total_args_passed - 1, is_outgoing);
+
+  for (int i = 0; i < member_arg_pos; i++) {
+    VMReg a =    regs_with_member_name[i].first();
+    VMReg b = regs_without_member_name[i].first();
+    assert(a->value() == b->value(), err_msg_res("register allocation mismatch: a=%d, b=%d", a->value(), b->value()));
+  }
+  assert(regs_with_member_name[member_arg_pos].first()->is_valid(), "bad member arg");
+}
+#endif
+
 // ---------------------------------------------------------------------------
 // We are calling the interpreter via a c2i. Normally this would mean that
 // we were called by a compiled method. However we could have lost a race
 // where we went int -> i2c -> c2i and so the caller could in fact be
 // interpreted. If the caller is compiled we attempt to patch the caller
 // so he no longer calls into the interpreter.
-IRT_LEAF(void, SharedRuntime::fixup_callers_callsite(methodOopDesc* method, address caller_pc))
-  methodOop moop(method);
-
-  assert(moop->is_oop(false) && moop->is_method(), "method oop from call site is invalid");
+IRT_LEAF(void, SharedRuntime::fixup_callers_callsite(Method* method, address caller_pc))
+  Method* moop(method);
 
   address entry_point = moop->from_compiled_entry();
 
@@ -1680,7 +1717,7 @@
   // Also it is possible that we lost a race in that from_compiled_entry
   // is now back to the i2c in that case we don't need to patch and if
   // we did we'd leap into space because the callsite needs to use
-  // "to interpreter" stub in order to load up the methodOop. Don't
+  // "to interpreter" stub in order to load up the Method*. Don't
   // ask me how I know this...
 
   CodeBlob* cb = CodeCache::find_blob(caller_pc);
@@ -1953,7 +1990,7 @@
   static int _max_size;                       // max. arg size seen
 
   static void add_method_to_histogram(nmethod* nm) {
-    methodOop m = nm->method();
+    Method* m = nm->method();
     ArgumentCount args(m->signature());
     int arity   = args.size() + (m->is_static() ? 0 : 1);
     int argsize = m->size_of_parameters();
@@ -2467,6 +2504,7 @@
 #ifndef PRODUCT
     // debugging suppport
     if (PrintAdapterHandlers || PrintStubCode) {
+      ttyLocker ttyl;
       entry->print_adapter_on(tty);
       tty->print_cr("i2c argument handler #%d for: %s %s (%d bytes generated)",
                     _adapters->number_of_entries(), (method->is_static() ? "static" : "receiver"),
@@ -2474,8 +2512,10 @@
       tty->print_cr("c2i argument handler starts at %p",entry->get_c2i_entry());
       if (Verbose || PrintStubCode) {
         address first_pc = entry->base_address();
-        if (first_pc != NULL)
+        if (first_pc != NULL) {
           Disassembler::decode(first_pc, first_pc + insts_size);
+          tty->cr();
+        }
       }
     }
 #endif
@@ -2590,10 +2630,10 @@
       MacroAssembler _masm(&buffer);
 
       // Fill in the signature array, for the calling-convention call.
-      int total_args_passed = method->size_of_parameters();
-
-      BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType,total_args_passed);
-      VMRegPair*   regs = NEW_RESOURCE_ARRAY(VMRegPair,total_args_passed);
+      const int total_args_passed = method->size_of_parameters();
+
+      BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed);
+      VMRegPair*   regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed);
       int i=0;
       if( !method->is_static() )  // Pass in receiver first
         sig_bt[i++] = T_OBJECT;
@@ -2603,7 +2643,7 @@
         if( ss.type() == T_LONG || ss.type() == T_DOUBLE )
           sig_bt[i++] = T_VOID;   // Longs & doubles take 2 Java slots
       }
-      assert( i==total_args_passed, "" );
+      assert(i == total_args_passed, "");
       BasicType ret_type = ss.type();
 
       // Now get the compiled-Java layout as input (or output) arguments.
@@ -2616,9 +2656,8 @@
       nm = SharedRuntime::generate_native_wrapper(&_masm,
                                                   method,
                                                   compile_id,
-                                                  total_args_passed,
-                                                  comp_args_on_stack,
-                                                  sig_bt,regs,
+                                                  sig_bt,
+                                                  regs,
                                                   ret_type);
     }
   }
@@ -2710,7 +2749,7 @@
   int          jlsLen    = java_lang_String::length(src);
   jchar*       jlsPos    = (jlsLen == 0) ? NULL :
                                            jlsValue->char_at_addr(jlsOffset);
-  assert(typeArrayKlass::cast(jlsValue->klass())->element_type() == T_CHAR, "compressed string");
+  assert(TypeArrayKlass::cast(jlsValue->klass())->element_type() == T_CHAR, "compressed string");
   (void) UNICODE::as_utf8(jlsPos, jlsLen, (char *)dst, max_dtrace_string_size);
 }
 #endif // ndef HAVE_DTRACE_H
@@ -2846,7 +2885,7 @@
   // QQQ we could place number of active monitors in the array so that compiled code
   // could double check it.
 
-  methodOop moop = fr.interpreter_frame_method();
+  Method* moop = fr.interpreter_frame_method();
   int max_locals = moop->max_locals();
   // Allocate temp buffer, 1 word per local & 2 per active monitor
   int buf_size_words = max_locals + active_monitor_count*2;