diff options
Diffstat (limited to 'src/share/vm/c1/c1_Runtime1.cpp')
-rw-r--r-- | src/share/vm/c1/c1_Runtime1.cpp | 77 |
1 files changed, 52 insertions, 25 deletions
diff --git a/src/share/vm/c1/c1_Runtime1.cpp b/src/share/vm/c1/c1_Runtime1.cpp index 5100c5ebb..df05521d0 100644 --- a/src/share/vm/c1/c1_Runtime1.cpp +++ b/src/share/vm/c1/c1_Runtime1.cpp @@ -140,9 +140,7 @@ void Runtime1::generate_blob_for(BufferBlob* buffer_blob, StubID id) { case slow_subtype_check_id: case fpu2long_stub_id: case unwind_exception_id: -#ifndef TIERED - case counter_overflow_id: // Not generated outside the tiered world -#endif + case counter_overflow_id: #if defined(SPARC) || defined(PPC) case handle_exception_nofpu_id: // Unused on sparc #endif @@ -322,31 +320,60 @@ JRT_ENTRY(void, Runtime1::post_jvmti_exception_throw(JavaThread* thread)) } JRT_END -#ifdef TIERED -JRT_ENTRY(void, Runtime1::counter_overflow(JavaThread* thread, int bci)) - RegisterMap map(thread, false); - frame fr = thread->last_frame().sender(&map); +// This is a helper to allow us to safepoint but allow the outer entry +// to be safepoint free if we need to do an osr +static nmethod* counter_overflow_helper(JavaThread* THREAD, int branch_bci, methodOopDesc* m) { + nmethod* osr_nm = NULL; + methodHandle method(THREAD, m); + + RegisterMap map(THREAD, false); + frame fr = THREAD->last_frame().sender(&map); nmethod* nm = (nmethod*) fr.cb(); - assert(nm!= NULL && nm->is_nmethod(), "what?"); - methodHandle method(thread, nm->method()); - if (bci == 0) { - // invocation counter overflow - if (!Tier1CountOnly) { - CompilationPolicy::policy()->method_invocation_event(method, CHECK); - } else { - method()->invocation_counter()->reset(); - } - } else { - if (!Tier1CountOnly) { - // Twe have a bci but not the destination bci and besides a backedge - // event is more for OSR which we don't want here. - CompilationPolicy::policy()->method_invocation_event(method, CHECK); - } else { - method()->backedge_counter()->reset(); + assert(nm!= NULL && nm->is_nmethod(), "Sanity check"); + methodHandle enclosing_method(THREAD, nm->method()); + + CompLevel level = (CompLevel)nm->comp_level(); + int bci = InvocationEntryBci; + if (branch_bci != InvocationEntryBci) { + // Compute desination bci + address pc = method()->code_base() + branch_bci; + Bytecodes::Code branch = Bytecodes::code_at(pc, method()); + int offset = 0; + switch (branch) { + case Bytecodes::_if_icmplt: case Bytecodes::_iflt: + case Bytecodes::_if_icmpgt: case Bytecodes::_ifgt: + case Bytecodes::_if_icmple: case Bytecodes::_ifle: + case Bytecodes::_if_icmpge: case Bytecodes::_ifge: + case Bytecodes::_if_icmpeq: case Bytecodes::_if_acmpeq: case Bytecodes::_ifeq: + case Bytecodes::_if_icmpne: case Bytecodes::_if_acmpne: case Bytecodes::_ifne: + case Bytecodes::_ifnull: case Bytecodes::_ifnonnull: case Bytecodes::_goto: + offset = (int16_t)Bytes::get_Java_u2(pc + 1); + break; + case Bytecodes::_goto_w: + offset = Bytes::get_Java_u4(pc + 1); + break; + default: ; } + bci = branch_bci + offset; } + + osr_nm = CompilationPolicy::policy()->event(enclosing_method, method, branch_bci, bci, level, THREAD); + return osr_nm; +} + +JRT_BLOCK_ENTRY(address, Runtime1::counter_overflow(JavaThread* thread, int bci, methodOopDesc* method)) + nmethod* osr_nm; + JRT_BLOCK + osr_nm = counter_overflow_helper(thread, bci, method); + if (osr_nm != NULL) { + RegisterMap map(thread, false); + frame fr = thread->last_frame().sender(&map); + VM_DeoptimizeFrame deopt(thread, fr.id()); + VMThread::execute(&deopt); + } + JRT_BLOCK_END + return NULL; JRT_END -#endif // TIERED extern void vm_exit(int code); @@ -898,7 +925,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i NativeMovConstReg* n_copy = nativeMovConstReg_at(copy_buff); assert(n_copy->data() == 0 || - n_copy->data() == (int)Universe::non_oop_word(), + n_copy->data() == (intptr_t)Universe::non_oop_word(), "illegal init value"); assert(load_klass() != NULL, "klass not set"); n_copy->set_data((intx) (load_klass())); |