Bytecodes::Code VMEvent::get_verifier_breakpoint_opcode(const Method* this_method, int bci) { UsingFastOops fast_oops; InstanceClass::Fast cl; // We may get called from Method::check_bytecodes() and the holder // hasn't been set yet. Check for 0xFFFF class id which is illegal if (this_method->holder_id() == 0xFFFF) { // No class has been set yet, just return the breakpoint opcode return Bytecodes::_breakpoint; } cl = this_method->holder(); /* point to class of method */ // We may get called during GC when stackmaps are generated and we are // iterating over bytecodes. So, we can't allocate. VMEvent::Raw ep = find_breakpoint_event(JavaDebugger::get_object_id_by_ref(&cl), JavaDebugger::get_method_id(this_method), (jlong)bci, -1); if (ep.is_null()) { return Bytecodes::_illegal; } LocationModifier::Raw location = get_modifier(&ep, JDWP_EventRequest_Set_Out_modifiers_Modifier_LocationOnly); GUARANTEE(!location.is_null(), "No location modifier for event"); return(location().save_opcode()); }
void VMEvent::clear_event_request(VMEvent *ep) { LocationModifier::Raw mod; Thread::Raw thread; VMEvent::remove_event_request(ep); #ifdef AZZERT if (TraceDebugger) { tty->print_cr("VMEvent: clear 0x%x, id 0x%x", (int)ep->obj(), ep->event_id()); } #endif switch (ep->event_kind()) { case JDWP_EventKind_BREAKPOINT: mod = get_modifier(ep, JDWP_EventRequest_Set_Out_modifiers_Modifier_LocationOnly); GUARANTEE(!mod.is_null(), "No location modifier for breakpoint event"); if (!mod.is_null()) { #if ENABLE_ISOLATES // See if any other task already has a breakpoint here. VMEvent::Raw epb = find_breakpoint_event(&mod); if (!epb.is_null()) { // Has to be some other task since we have unlinked this event GUARANTEE(epb().task_id() != ep->task_id(), "Duplicate breakpoint event for this task"); } else { #endif mod().set_method_opcode(mod().save_opcode(), false); #if ENABLE_ISOLATES } #endif } break; case JDWP_EventKind_SINGLE_STEP: mod = get_modifier(ep, JDWP_EventRequest_Set_Out_modifiers_Modifier_Step); if (mod.not_null()) { thread = JavaDebugger::get_thread_by_id(mod().thread_id()); if (thread.not_null()) thread().set_is_stepping(false); JavaDebugger::set_stepping(false); } break; } // see if there are any other breakpoints in this method. If no other // breakpoints and the compiler is active then clear the // impossible_to_compile flag. if (mod.not_null() && (ep->event_kind() == JDWP_EventKind_BREAKPOINT || ep->event_kind() == JDWP_EventKind_SINGLE_STEP)) { clear_impossible_to_compile(&mod, ep); } }
void LocationModifier::find_and_set_rom_method_id(Method *debug_rom_method) { VMEventStream es; VMEvent::Raw ep; LocationModifier::Raw mod; Method::Raw dm; ep = es.next_by_kind(JDWP_EventKind_BREAKPOINT); while(!ep.is_null()) { mod = VMEvent::get_modifier(&ep, JDWP_EventRequest_Set_Out_modifiers_Modifier_LocationOnly); if (!mod.is_null()) { dm = mod().rom_debug_method(); if (!dm.is_null() && dm.obj() == debug_rom_method->obj()) { set_method_id(mod().method_id()); break; } } ep = es.next_by_kind(JDWP_EventKind_BREAKPOINT); } }
ReturnOop LocationModifier::get_dup_rom_method(Method *in_rom_method) { VMEventStream es; VMEvent::Raw ep; LocationModifier::Raw mod; Method::Raw sm; ep = es.next_by_kind(JDWP_EventKind_BREAKPOINT); while(!ep.is_null()) { mod = VMEvent::get_modifier(&ep, JDWP_EventRequest_Set_Out_modifiers_Modifier_LocationOnly); if (!mod.is_null()) { sm = mod().method(); if (!sm.is_null() && sm.obj() == in_rom_method->obj()) { return mod().rom_debug_method(); } } ep = es.next_by_kind(JDWP_EventKind_BREAKPOINT); } return NULL; }
address get_rom_debug_method(Thread *thread, OopDesc *md) { (void)thread; // always passed from interpreter but not used here. VMEventStream es; Method::Raw m = md; VMEvent::Raw ep; LocationModifier::Raw mod; ep = es.next_by_kind(JDWP_EventKind_BREAKPOINT); while(!ep.is_null()) { mod = VMEvent::get_modifier(&ep, JDWP_EventRequest_Set_Out_modifiers_Modifier_LocationOnly); if (!mod.is_null() && mod().method_id() == JavaDebugger::get_method_id(&m)) { Method::Raw dm = mod().rom_debug_method(); if (!dm.is_null()) { return (address)((char *)dm.obj()); } } ep = es.next_by_kind(JDWP_EventKind_BREAKPOINT); } return (address)md; }
ReturnOop VMEvent::find_breakpoint_event(int class_id, jlong method_id, jlong offset, int task_id) { // May be called during GC via GenerateStackMap::run(). VMEventStream es; VMEvent::Raw ep; LocationModifier::Raw loc; while (!es.at_end()) { ep = es.next_by_kind(JDWP_EventKind_BREAKPOINT); if (ep.is_null()) { return NULL; } #if ENABLE_ISOLATES // If task_id == -1 && ep.task_id == -1 then we don't care // which task this is we check the event otherwise we skip it if (task_id != -1 && ep().task_id() != -1 && (ep().task_id() != task_id)) { continue; } #else (void)task_id; #endif loc = get_modifier(&ep, JDWP_EventRequest_Set_Out_modifiers_Modifier_LocationOnly); if (loc.not_null()) { if (loc().clazz_id() == class_id && loc().method_id() == method_id && loc().offset() == offset) { return ep; } } } return (ReturnOop)NULL; }
void VMEvent::replace_event_opcode(Method *method, Bytecodes::Code bcode, int bci) { UsingFastOops fast_oops; InstanceClass::Fast clazz = method->holder(); // find this breakpoint VMEvent::Raw ep = find_breakpoint_event(JavaDebugger::get_object_id_by_ref(&clazz), JavaDebugger::get_method_id(method), (jlong)bci, -1); if (ep.is_null()) { // if we didn't find the breakpoint event, then just replace the bytecode method->bytecode_at_put_raw(bci, bcode); } else { // Set the saved opcode to the new fast opcode LocationModifier::Raw location = get_modifier(&ep, JDWP_EventRequest_Set_Out_modifiers_Modifier_LocationOnly); GUARANTEE(!location.is_null(), "No location modifier for event"); location().set_save_opcode(bcode); } return; }