< prev index next >

src/share/vm/runtime/sharedRuntime.cpp

Print this page

        

@@ -1106,10 +1106,11 @@
   methodHandle caller(THREAD, vfst.method());
   int          bci   = vfst.bci();
 
   Bytecode_invoke bytecode(caller, bci);
   int bytecode_index = bytecode.index();
+  bc = bytecode.invoke_code();
 
   methodHandle attached_method = extract_attached_method(vfst);
   if (attached_method.not_null()) {
     methodHandle callee = bytecode.static_target(CHECK_NH);
     vmIntrinsics::ID id = callee->intrinsic_id();

@@ -1131,13 +1132,13 @@
             bc = attached_method->is_static() ? Bytecodes::_invokestatic
                                               : Bytecodes::_invokevirtual;
           }
           break;
       }
-    }
   } else {
-    bc = bytecode.invoke_code();
+      assert(ValueTypePassFieldsAsArgs, "invalid use of attached methods");
+    }
   }
 
   bool has_receiver = bc != Bytecodes::_invokestatic &&
                       bc != Bytecodes::_invokedynamic &&
                       bc != Bytecodes::_invokehandle;

@@ -1160,12 +1161,13 @@
     }
     if (ValueTypePassFieldsAsArgs && callee->method_holder()->is_value()) {
       // If the receiver is a value type that is passed as fields, no oop is available.
       // Resolve the call without receiver null checking.
       assert(bc == Bytecodes::_invokevirtual, "only allowed with invokevirtual");
+      assert(!attached_method.is_null(), "must have attached method");
       constantPoolHandle constants(THREAD, caller->constants());
-      LinkInfo link_info(constants, bytecode_index, CHECK_NH);
+      LinkInfo link_info(attached_method->method_holder(), attached_method->name(), attached_method->signature());
       LinkResolver::resolve_virtual_call(callinfo, receiver, NULL, link_info, /*check_null_or_abstract*/ false, CHECK_NH);
       return receiver; // is null
     } else {
       // Retrieve from a compiled argument list
       receiver = Handle(THREAD, callerFrame.retrieve_receiver(&reg_map2));

@@ -1370,10 +1372,14 @@
   if (is_virtual) {
     Klass* receiver_klass = NULL;
     if (ValueTypePassFieldsAsArgs && callee_method->method_holder()->is_value()) {
       // If the receiver is a value type that is passed as fields, no oop is available
       receiver_klass = callee_method->method_holder();
+      if (FullGCALotWithValueTypes) {
+        // Trigger a full GC to verify that the GC knows about the contents of oop fields
+        Universe::heap()->collect(GCCause::_full_gc_alot);
+      }
     } else {
       assert(receiver.not_null() || invoke_code == Bytecodes::_invokehandle, "sanity check");
       receiver_klass = invoke_code == Bytecodes::_invokehandle ? NULL : receiver->klass();
     }
     bool static_bound = call_info.resolved_method()->can_be_statically_bound();

@@ -2454,13 +2460,13 @@
  public:
   AdapterHandlerTable()
     : BasicHashtable<mtCode>(293, (DumpSharedSpaces ? sizeof(CDSAdapterHandlerEntry) : sizeof(AdapterHandlerEntry))) { }
 
   // Create a new entry suitable for insertion in the table
-  AdapterHandlerEntry* new_entry(AdapterFingerPrint* fingerprint, address i2c_entry, address c2i_entry, address c2i_unverified_entry) {
+  AdapterHandlerEntry* new_entry(AdapterFingerPrint* fingerprint, address i2c_entry, address c2i_entry, address c2i_unverified_entry, Symbol* sig_extended) {
     AdapterHandlerEntry* entry = (AdapterHandlerEntry*)BasicHashtable<mtCode>::new_entry(fingerprint->compute_hash());
-    entry->init(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
+    entry->init(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry, sig_extended);
     if (DumpSharedSpaces) {
       ((CDSAdapterHandlerEntry*)entry)->init();
     }
     return entry;
   }

@@ -2605,12 +2611,13 @@
 }
 
 AdapterHandlerEntry* AdapterHandlerLibrary::new_entry(AdapterFingerPrint* fingerprint,
                                                       address i2c_entry,
                                                       address c2i_entry,
-                                                      address c2i_unverified_entry) {
-  return _adapters->new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
+                                                      address c2i_unverified_entry,
+                                                      Symbol* sig_extended) {
+  return _adapters->new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry, sig_extended);
 }
 
 // Value type arguments are not passed by reference, instead each
 // field of the value type is passed as an argument. This helper
 // function collects the fields of the value types (including embedded

@@ -3351,5 +3358,28 @@
   }
   thread->set_vm_result(array());
   thread->set_vm_result_2(callee()); // TODO: required to keep callee live?
 }
 JRT_END
+
+// Iterate of the array of heap allocated value types and apply the GC post barrier to all reference fields.
+// This is called from the C2I adapter after value type arguments are heap allocated and initialized.
+JRT_LEAF(void, SharedRuntime::apply_post_barriers(JavaThread* thread, objArrayOopDesc* array))
+{
+  assert(ValueTypePassFieldsAsArgs, "no reason to call this");
+  assert(array->is_oop(), "should be oop");
+  for (int i = 0; i < array->length(); ++i) {
+    instanceOop valueOop = (instanceOop)array->obj_at(i);
+    ValueKlass* vk = ValueKlass::cast(valueOop->klass());
+    if (vk->contains_oops()) {
+      const address dst_oop_addr = ((address) (void*) valueOop);
+      OopMapBlock* map = vk->start_of_nonstatic_oop_maps();
+      OopMapBlock* const end = map + vk->nonstatic_oop_map_count();
+      while (map != end) {
+        address doop_address = dst_oop_addr + map->offset();
+        oopDesc::bs()->write_ref_array((HeapWord*) doop_address, map->count());
+        map++;
+      }
+    }
+  }
+}
+JRT_END
< prev index next >