< 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(&reg_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(&reg_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 >