< prev index next >
src/share/vm/runtime/sharedRuntime.cpp
Print this page
*** 1106,1115 ****
--- 1106,1116 ----
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,1143 ****
bc = attached_method->is_static() ? Bytecodes::_invokestatic
: Bytecodes::_invokevirtual;
}
break;
}
- }
} else {
! bc = bytecode.invoke_code();
}
bool has_receiver = bc != Bytecodes::_invokestatic &&
bc != Bytecodes::_invokedynamic &&
bc != Bytecodes::_invokehandle;
--- 1132,1144 ----
bc = attached_method->is_static() ? Bytecodes::_invokestatic
: Bytecodes::_invokevirtual;
}
break;
}
} else {
! assert(ValueTypePassFieldsAsArgs, "invalid use of attached methods");
! }
}
bool has_receiver = bc != Bytecodes::_invokestatic &&
bc != Bytecodes::_invokedynamic &&
bc != Bytecodes::_invokehandle;
*** 1160,1171 ****
}
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");
constantPoolHandle constants(THREAD, caller->constants());
! LinkInfo link_info(constants, bytecode_index, CHECK_NH);
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(®_map2));
--- 1161,1173 ----
}
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(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(®_map2));
*** 1370,1379 ****
--- 1372,1385 ----
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,2466 ****
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* entry = (AdapterHandlerEntry*)BasicHashtable<mtCode>::new_entry(fingerprint->compute_hash());
! entry->init(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
if (DumpSharedSpaces) {
((CDSAdapterHandlerEntry*)entry)->init();
}
return entry;
}
--- 2460,2472 ----
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, Symbol* sig_extended) {
AdapterHandlerEntry* entry = (AdapterHandlerEntry*)BasicHashtable<mtCode>::new_entry(fingerprint->compute_hash());
! entry->init(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry, sig_extended);
if (DumpSharedSpaces) {
((CDSAdapterHandlerEntry*)entry)->init();
}
return entry;
}
*** 2605,2616 ****
}
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);
}
// 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
--- 2611,2623 ----
}
AdapterHandlerEntry* AdapterHandlerLibrary::new_entry(AdapterFingerPrint* fingerprint,
address i2c_entry,
address c2i_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,3355 ****
--- 3358,3385 ----
}
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 >