diff src/share/vm/runtime/sharedRuntime.cpp @ 14909:4ca6dc0799b6

Backout jdk9 merge
author Gilles Duboscq <duboscq@ssw.jku.at>
date Tue, 01 Apr 2014 13:57:07 +0200
parents 3e9a960f0da1
children 954c9df6ac79
line wrap: on
line diff
--- a/src/share/vm/runtime/sharedRuntime.cpp	Tue Apr 01 14:09:03 2014 +0200
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Tue Apr 01 13:57:07 2014 +0200
@@ -127,6 +127,14 @@
 
 #include <math.h>
 
+#ifndef USDT2
+HS_DTRACE_PROBE_DECL4(hotspot, object__alloc, Thread*, char*, int, size_t);
+HS_DTRACE_PROBE_DECL7(hotspot, method__entry, int,
+                      char*, int, char*, int, char*, int);
+HS_DTRACE_PROBE_DECL7(hotspot, method__return, int,
+                      char*, int, char*, int, char*, int);
+#endif /* !USDT2 */
+
 // Implementation of SharedRuntime
 
 #ifndef PRODUCT
@@ -400,7 +408,7 @@
 
 #endif
 
-#if defined(__SOFTFP__) || defined(PPC32)
+#if defined(__SOFTFP__) || defined(PPC)
 double SharedRuntime::dsqrt(double f) {
   return sqrt(f);
 }
@@ -464,7 +472,7 @@
   return (jdouble)x;
 JRT_END
 
-// Exception handling across interpreter/compiler boundaries
+// Exception handling accross interpreter/compiler boundaries
 //
 // exception_handler_for_return_address(...) returns the continuation address.
 // The continuation address is the entry point of the exception handler of the
@@ -492,13 +500,6 @@
     assert(!nm->is_native_method(), "no exception handler");
     assert(nm->header_begin() != nm->exception_begin(), "no exception handler");
     if (nm->is_deopt_pc(return_address)) {
-      // If we come here because of a stack overflow, the stack may be
-      // unguarded. Reguard the stack otherwise if we return to the
-      // deopt blob and the stack bang causes a stack overflow we
-      // crash.
-      bool guard_pages_enabled = thread->stack_yellow_zone_enabled();
-      if (!guard_pages_enabled) guard_pages_enabled = thread->reguard_stack();
-      assert(guard_pages_enabled, "stack banging in deopt blob may cause crash");
       return SharedRuntime::deopt_blob()->unpack_with_exception();
     } else {
       return nm->exception_begin();
@@ -713,8 +714,8 @@
     // Allow abbreviated catch tables.  The idea is to allow a method
     // to materialize its exceptions without committing to the exact
     // routing of exceptions.  In particular this is needed for adding
-    // a synthetic handler to unlock monitors when inlining
-    // synchronized methods since the unlock path isn't represented in
+    // a synthethic handler to unlock monitors when inlining
+    // synchonized methods since the unlock path isn't represented in
     // the bytecodes.
     t = table.entry_for(catch_pco, -1, 0);
   }
@@ -852,7 +853,7 @@
           // Exception happened in CodeCache. Must be either:
           // 1. Inline-cache check in C2I handler blob,
           // 2. Inline-cache check in nmethod, or
-          // 3. Implicit null exception in nmethod
+          // 3. Implict null exception in nmethod
 
           if (!cb->is_nmethod()) {
             bool is_in_blob = cb->is_adapter_blob() || cb->is_method_handles_adapter_blob();
@@ -1026,9 +1027,14 @@
   Klass* klass = o->klass();
   int size = o->size();
   Symbol* name = klass->name();
+#ifndef USDT2
+  HS_DTRACE_PROBE4(hotspot, object__alloc, get_java_tid(thread),
+                   name->bytes(), name->utf8_length(), size * HeapWordSize);
+#else /* USDT2 */
   HOTSPOT_OBJECT_ALLOC(
                    get_java_tid(thread),
                    (char *) name->bytes(), name->utf8_length(), size * HeapWordSize);
+#endif /* USDT2 */
   return 0;
 }
 
@@ -1038,11 +1044,18 @@
   Symbol* kname = method->klass_name();
   Symbol* name = method->name();
   Symbol* sig = method->signature();
+#ifndef USDT2
+  HS_DTRACE_PROBE7(hotspot, method__entry, get_java_tid(thread),
+      kname->bytes(), kname->utf8_length(),
+      name->bytes(), name->utf8_length(),
+      sig->bytes(), sig->utf8_length());
+#else /* USDT2 */
   HOTSPOT_METHOD_ENTRY(
       get_java_tid(thread),
       (char *) kname->bytes(), kname->utf8_length(),
       (char *) name->bytes(), name->utf8_length(),
       (char *) sig->bytes(), sig->utf8_length());
+#endif /* USDT2 */
   return 0;
 JRT_END
 
@@ -1052,11 +1065,18 @@
   Symbol* kname = method->klass_name();
   Symbol* name = method->name();
   Symbol* sig = method->signature();
+#ifndef USDT2
+  HS_DTRACE_PROBE7(hotspot, method__return, get_java_tid(thread),
+      kname->bytes(), kname->utf8_length(),
+      name->bytes(), name->utf8_length(),
+      sig->bytes(), sig->utf8_length());
+#else /* USDT2 */
   HOTSPOT_METHOD_RETURN(
       get_java_tid(thread),
       (char *) kname->bytes(), kname->utf8_length(),
       (char *) name->bytes(), name->utf8_length(),
       (char *) sig->bytes(), sig->utf8_length());
+#endif /* USDT2 */
   return 0;
 JRT_END
 
@@ -2444,7 +2464,7 @@
   ResourceMark rm;
 
   NOT_PRODUCT(int insts_size);
-  AdapterBlob* new_adapter = NULL;
+  AdapterBlob* B = NULL;
   AdapterHandlerEntry* entry = NULL;
   AdapterFingerPrint* fingerprint = NULL;
   {
@@ -2476,8 +2496,7 @@
 
 #ifdef ASSERT
     AdapterHandlerEntry* shared_entry = NULL;
-    // Start adapter sharing verification only after the VM is booted.
-    if (VerifyAdapterSharing && (entry != NULL)) {
+    if (VerifyAdapterSharing && entry != NULL) {
       shared_entry = entry;
       entry = NULL;
     }
@@ -2493,44 +2512,41 @@
     // Make a C heap allocated version of the fingerprint to store in the adapter
     fingerprint = new AdapterFingerPrint(total_args_passed, sig_bt);
 
-    // StubRoutines::code2() is initialized after this function can be called. As a result,
-    // VerifyAdapterCalls and VerifyAdapterSharing can fail if we re-use code that generated
-    // prior to StubRoutines::code2() being set. Checks refer to checks generated in an I2C
-    // stub that ensure that an I2C stub is called from an interpreter frame.
-    bool contains_all_checks = StubRoutines::code2() != NULL;
-
     // Create I2C & C2I handlers
+
     BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache
     if (buf != NULL) {
       CodeBuffer buffer(buf);
       short buffer_locs[20];
       buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs,
                                              sizeof(buffer_locs)/sizeof(relocInfo));
-
       MacroAssembler _masm(&buffer);
+
       entry = SharedRuntime::generate_i2c2i_adapters(&_masm,
                                                      total_args_passed,
                                                      comp_args_on_stack,
                                                      sig_bt,
                                                      regs,
                                                      fingerprint);
+
 #ifdef ASSERT
       if (VerifyAdapterSharing) {
         if (shared_entry != NULL) {
-          assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size()), "code must match");
+          assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt),
+                 "code must match");
           // Release the one just created and return the original
           _adapters->free_entry(entry);
           return shared_entry;
         } else  {
-          entry->save_code(buf->code_begin(), buffer.insts_size());
+          entry->save_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt);
         }
       }
 #endif
 
-      new_adapter = AdapterBlob::create(&buffer);
+      B = AdapterBlob::create(&buffer);
       NOT_PRODUCT(insts_size = buffer.insts_size());
     }
-    if (new_adapter == NULL) {
+    if (B == NULL) {
       // CodeCache is full, disable compilation
       // Ought to log this but compile log is only per compile thread
       // and we're some non descript Java thread.
@@ -2538,7 +2554,7 @@
       CompileBroker::handle_full_code_cache();
       return NULL; // Out of CodeCache space
     }
-    entry->relocate(new_adapter->content_begin());
+    entry->relocate(B->content_begin());
 #ifndef PRODUCT
     // debugging suppport
     if (PrintAdapterHandlers || PrintStubCode) {
@@ -2557,25 +2573,22 @@
       }
     }
 #endif
-    // Add the entry only if the entry contains all required checks (see sharedRuntime_xxx.cpp)
-    // The checks are inserted only if -XX:+VerifyAdapterCalls is specified.
-    if (contains_all_checks || !VerifyAdapterCalls) {
-      _adapters->add(entry);
-    }
+
+    _adapters->add(entry);
   }
   // Outside of the lock
-  if (new_adapter != NULL) {
+  if (B != NULL) {
     char blob_id[256];
     jio_snprintf(blob_id,
                  sizeof(blob_id),
                  "%s(%s)@" PTR_FORMAT,
-                 new_adapter->name(),
+                 B->name(),
                  fingerprint->as_string(),
-                 new_adapter->content_begin());
-    Forte::register_stub(blob_id, new_adapter->content_begin(),new_adapter->content_end());
+                 B->content_begin());
+    Forte::register_stub(blob_id, B->content_begin(), B->content_end());
 
     if (JvmtiExport::should_post_dynamic_code_generated()) {
-      JvmtiExport::post_dynamic_code_generated(blob_id, new_adapter->content_begin(), new_adapter->content_end());
+      JvmtiExport::post_dynamic_code_generated(blob_id, B->content_begin(), B->content_end());
     }
   }
   return entry;
@@ -2607,6 +2620,7 @@
   delete _fingerprint;
 #ifdef ASSERT
   if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code, mtCode);
+  if (_saved_sig)  FREE_C_HEAP_ARRAY(Basictype, _saved_sig, mtCode);
 #endif
 }
 
@@ -2615,30 +2629,35 @@
 // Capture the code before relocation so that it can be compared
 // against other versions.  If the code is captured after relocation
 // then relative instructions won't be equivalent.
-void AdapterHandlerEntry::save_code(unsigned char* buffer, int length) {
+void AdapterHandlerEntry::save_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) {
   _saved_code = NEW_C_HEAP_ARRAY(unsigned char, length, mtCode);
-  _saved_code_length = length;
+  _code_length = length;
   memcpy(_saved_code, buffer, length);
+  _total_args_passed = total_args_passed;
+  _saved_sig = NEW_C_HEAP_ARRAY(BasicType, _total_args_passed, mtCode);
+  memcpy(_saved_sig, sig_bt, _total_args_passed * sizeof(BasicType));
 }
 
 
-bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length) {
-  if (length != _saved_code_length) {
+bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) {
+  if (length != _code_length) {
     return false;
   }
-
-  return (memcmp(buffer, _saved_code, length) == 0) ? true : false;
+  for (int i = 0; i < length; i++) {
+    if (buffer[i] != _saved_code[i]) {
+      return false;
+    }
+  }
+  return true;
 }
 #endif
 
 
-/**
- * Create a native wrapper for this native method.  The wrapper converts the
- * Java-compiled calling convention to the native convention, handles
- * arguments, and transitions to native.  On return from the native we transition
- * back to java blocking if a safepoint is in progress.
- */
-void AdapterHandlerLibrary::create_native_wrapper(methodHandle method) {
+// Create a native wrapper for this native method.  The wrapper converts the
+// java compiled calling convention to the native convention, handlizes
+// arguments, and transitions to native.  On return from the native we transition
+// back to java blocking if a safepoint is in progress.
+nmethod *AdapterHandlerLibrary::create_native_wrapper(methodHandle method, int compile_id) {
   ResourceMark rm;
   nmethod* nm = NULL;
 
@@ -2647,19 +2666,16 @@
          method->has_native_function(), "must have something valid to call!");
 
   {
-    // Perform the work while holding the lock, but perform any printing outside the lock
+    // perform the work while holding the lock, but perform any printing outside the lock
     MutexLocker mu(AdapterHandlerLibrary_lock);
     // See if somebody beat us to it
     nm = method->code();
-    if (nm != NULL) {
-      return;
+    if (nm) {
+      return nm;
     }
 
-    const int compile_id = CompileBroker::assign_compile_id(method, CompileBroker::standard_entry_bci);
-    assert(compile_id > 0, "Must generate native wrapper");
-
-
     ResourceMark rm;
+
     BufferBlob*  buf = buffer_blob(); // the temporary code buffer in CodeCache
     if (buf != NULL) {
       CodeBuffer buffer(buf);
@@ -2691,14 +2707,16 @@
       int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, is_outgoing);
 
       // Generate the compiled-to-native wrapper code
-      nm = SharedRuntime::generate_native_wrapper(&_masm, method, compile_id, sig_bt, regs, ret_type);
-
-      if (nm != NULL) {
-        method->set_code(method, nm);
-      }
+      nm = SharedRuntime::generate_native_wrapper(&_masm,
+                                                  method,
+                                                  compile_id,
+                                                  sig_bt,
+                                                  regs,
+                                                  ret_type);
     }
-  } // Unlock AdapterHandlerLibrary_lock
-
+  }
+
+  // Must unlock before calling set_code
 
   // Install the generated code.
   if (nm != NULL) {
@@ -2706,11 +2724,13 @@
       ttyLocker ttyl;
       CompileTask::print_compilation(tty, nm, method->is_static() ? "(static)" : "");
     }
+    method->set_code(method, nm);
     nm->post_compiled_method_load_event();
   } else {
     // CodeCache is full, disable compilation
     CompileBroker::handle_full_code_cache();
   }
+  return nm;
 }
 
 JRT_ENTRY_NO_ASYNC(void, SharedRuntime::block_for_jni_critical(JavaThread* thread))
@@ -2788,71 +2808,6 @@
 }
 #endif // ndef HAVE_DTRACE_H
 
-int SharedRuntime::convert_ints_to_longints_argcnt(int in_args_count, BasicType* in_sig_bt) {
-  int argcnt = in_args_count;
-  if (CCallingConventionRequiresIntsAsLongs) {
-    for (int in = 0; in < in_args_count; in++) {
-      BasicType bt = in_sig_bt[in];
-      switch (bt) {
-        case T_BOOLEAN:
-        case T_CHAR:
-        case T_BYTE:
-        case T_SHORT:
-        case T_INT:
-          argcnt++;
-          break;
-        default:
-          break;
-      }
-    }
-  } else {
-    assert(0, "This should not be needed on this platform");
-  }
-
-  return argcnt;
-}
-
-void SharedRuntime::convert_ints_to_longints(int i2l_argcnt, int& in_args_count,
-                                             BasicType*& in_sig_bt, VMRegPair*& in_regs) {
-  if (CCallingConventionRequiresIntsAsLongs) {
-    VMRegPair *new_in_regs   = NEW_RESOURCE_ARRAY(VMRegPair, i2l_argcnt);
-    BasicType *new_in_sig_bt = NEW_RESOURCE_ARRAY(BasicType, i2l_argcnt);
-
-    int argcnt = 0;
-    for (int in = 0; in < in_args_count; in++, argcnt++) {
-      BasicType bt  = in_sig_bt[in];
-      VMRegPair reg = in_regs[in];
-      switch (bt) {
-        case T_BOOLEAN:
-        case T_CHAR:
-        case T_BYTE:
-        case T_SHORT:
-        case T_INT:
-          // Convert (bt) to (T_LONG,bt).
-          new_in_sig_bt[argcnt  ] = T_LONG;
-          new_in_sig_bt[argcnt+1] = bt;
-          assert(reg.first()->is_valid() && !reg.second()->is_valid(), "");
-          new_in_regs[argcnt  ].set2(reg.first());
-          new_in_regs[argcnt+1].set_bad();
-          argcnt++;
-          break;
-        default:
-          // No conversion needed.
-          new_in_sig_bt[argcnt] = bt;
-          new_in_regs[argcnt]   = reg;
-          break;
-      }
-    }
-    assert(argcnt == i2l_argcnt, "must match");
-
-    in_regs = new_in_regs;
-    in_sig_bt = new_in_sig_bt;
-    in_args_count = i2l_argcnt;
-  } else {
-    assert(0, "This should not be needed on this platform");
-  }
-}
-
 // -------------------------------------------------------------------------
 // Java-Java calling convention
 // (what you use when Java calls Java)
@@ -2952,7 +2907,7 @@
 // called from very start of a compiled OSR nmethod.  A temp array is
 // allocated to hold the interesting bits of the interpreter frame.  All
 // active locks are inflated to allow them to move.  The displaced headers and
-// active interpreter locals are copied into the temp buffer.  Then we return
+// active interpeter locals are copied into the temp buffer.  Then we return
 // back to the compiled code.  The compiled code then pops the current
 // interpreter frame off the stack and pushes a new compiled frame.  Then it
 // copies the interpreter locals and displaced headers where it wants.