< prev index next >

src/hotspot/share/code/vtableStubs.cpp

Print this page

        

*** 205,282 **** check_and_set_size_limit(is_vtable_stub, masm->offset(), slop_bytes); s->set_exception_points(npe_addr, ame_addr); } ! address VtableStubs::find_stub(bool is_vtable_stub, int vtable_index) { assert(vtable_index >= 0, "must be positive"); VtableStub* s; { MutexLocker ml(VtableStubs_lock, Mutex::_no_safepoint_check_flag); ! s = ShareVtableStubs ? lookup(is_vtable_stub, vtable_index) : NULL; if (s == NULL) { if (is_vtable_stub) { ! s = create_vtable_stub(vtable_index); } else { ! s = create_itable_stub(vtable_index); } // Creation of vtable or itable can fail if there is not enough free space in the code cache. if (s == NULL) { return NULL; } ! enter(is_vtable_stub, vtable_index, s); if (PrintAdapterHandlers) { ! tty->print_cr("Decoding VtableStub %s[%d]@" INTX_FORMAT, is_vtable_stub? "vtbl": "itbl", vtable_index, p2i(VtableStub::receiver_location())); Disassembler::decode(s->code_begin(), s->code_end()); } // Notify JVMTI about this stub. The event will be recorded by the enclosing // JvmtiDynamicCodeEventCollector and posted when this thread has released // all locks. if (JvmtiExport::should_post_dynamic_code_generated()) { ! JvmtiExport::post_dynamic_code_generated_while_holding_locks(is_vtable_stub? "vtable stub": "itable stub", s->code_begin(), s->code_end()); } } } return s->entry_point(); } ! inline uint VtableStubs::hash(bool is_vtable_stub, int vtable_index){ // Assumption: receiver_location < 4 in most cases. int hash = ((vtable_index << 2) ^ VtableStub::receiver_location()->value()) + vtable_index; return (is_vtable_stub ? ~hash : hash) & mask; } ! VtableStub* VtableStubs::lookup(bool is_vtable_stub, int vtable_index) { assert_lock_strong(VtableStubs_lock); ! unsigned hash = VtableStubs::hash(is_vtable_stub, vtable_index); VtableStub* s = _table[hash]; ! while( s && !s->matches(is_vtable_stub, vtable_index)) s = s->next(); return s; } ! void VtableStubs::enter(bool is_vtable_stub, int vtable_index, VtableStub* s) { assert_lock_strong(VtableStubs_lock); ! assert(s->matches(is_vtable_stub, vtable_index), "bad vtable stub"); ! unsigned int h = VtableStubs::hash(is_vtable_stub, vtable_index); // enter s at the beginning of the corresponding list s->set_next(_table[h]); _table[h] = s; _number_of_vtable_stubs++; } VtableStub* VtableStubs::entry_point(address pc) { MutexLocker ml(VtableStubs_lock, Mutex::_no_safepoint_check_flag); VtableStub* stub = (VtableStub*)(pc - VtableStub::entry_offset()); ! uint hash = VtableStubs::hash(stub->is_vtable_stub(), stub->index()); VtableStub* s; for (s = _table[hash]; s != NULL && s != stub; s = s->next()) {} return (s == stub) ? s : NULL; } --- 205,285 ---- check_and_set_size_limit(is_vtable_stub, masm->offset(), slop_bytes); s->set_exception_points(npe_addr, ame_addr); } ! address VtableStubs::find_stub(bool is_vtable_stub, int vtable_index, bool caller_is_c1) { assert(vtable_index >= 0, "must be positive"); VtableStub* s; { MutexLocker ml(VtableStubs_lock, Mutex::_no_safepoint_check_flag); ! s = ShareVtableStubs ? lookup(is_vtable_stub, vtable_index, caller_is_c1) : NULL; if (s == NULL) { if (is_vtable_stub) { ! s = create_vtable_stub(vtable_index, caller_is_c1); } else { ! s = create_itable_stub(vtable_index, caller_is_c1); } // Creation of vtable or itable can fail if there is not enough free space in the code cache. if (s == NULL) { return NULL; } ! enter(is_vtable_stub, vtable_index, caller_is_c1, s); if (PrintAdapterHandlers) { ! tty->print_cr("Decoding VtableStub (%s) %s[%d]@" INTX_FORMAT, caller_is_c1 ? "c1" : "full opt", is_vtable_stub? "vtbl": "itbl", vtable_index, p2i(VtableStub::receiver_location())); Disassembler::decode(s->code_begin(), s->code_end()); } // Notify JVMTI about this stub. The event will be recorded by the enclosing // JvmtiDynamicCodeEventCollector and posted when this thread has released // all locks. if (JvmtiExport::should_post_dynamic_code_generated()) { ! JvmtiExport::post_dynamic_code_generated_while_holding_locks(is_vtable_stub? "vtable stub": "itable stub", // FIXME: need to pass caller_is_c1?? s->code_begin(), s->code_end()); } } } return s->entry_point(); } ! inline uint VtableStubs::hash(bool is_vtable_stub, int vtable_index, bool caller_is_c1) { // Assumption: receiver_location < 4 in most cases. int hash = ((vtable_index << 2) ^ VtableStub::receiver_location()->value()) + vtable_index; + if (caller_is_c1) { + hash = 7 - hash; + } return (is_vtable_stub ? ~hash : hash) & mask; } ! VtableStub* VtableStubs::lookup(bool is_vtable_stub, int vtable_index, bool caller_is_c1) { assert_lock_strong(VtableStubs_lock); ! unsigned hash = VtableStubs::hash(is_vtable_stub, vtable_index, caller_is_c1); VtableStub* s = _table[hash]; ! while( s && !s->matches(is_vtable_stub, vtable_index, caller_is_c1)) s = s->next(); return s; } ! void VtableStubs::enter(bool is_vtable_stub, int vtable_index, bool caller_is_c1, VtableStub* s) { assert_lock_strong(VtableStubs_lock); ! assert(s->matches(is_vtable_stub, vtable_index, caller_is_c1), "bad vtable stub"); ! unsigned int h = VtableStubs::hash(is_vtable_stub, vtable_index, caller_is_c1); // enter s at the beginning of the corresponding list s->set_next(_table[h]); _table[h] = s; _number_of_vtable_stubs++; } VtableStub* VtableStubs::entry_point(address pc) { MutexLocker ml(VtableStubs_lock, Mutex::_no_safepoint_check_flag); VtableStub* stub = (VtableStub*)(pc - VtableStub::entry_offset()); ! uint hash = VtableStubs::hash(stub->is_vtable_stub(), stub->index(), stub->caller_is_c1()); VtableStub* s; for (s = _table[hash]; s != NULL && s != stub; s = s->next()) {} return (s == stub) ? s : NULL; }
< prev index next >