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; }
void VMEvent::create_event_request(PacketInputStream *in, PacketOutputStream *out, jbyte event_kind) { UsingFastOops fast_oops; VMEvent::Fast ep; int i; bool error = false; VMEventModifier::Fast current_modifier_slot, new_modifier, event_modifier; ep = create_vm_event_request(); ep().set_event_kind(event_kind); ep().set_suspend_policy(in->read_byte()); ep().set_num_modifiers(in->read_int()); Transport *transport = in->transport(); ep().set_transport(transport); #if ENABLE_ISOLATES ep().set_task_id(transport->task_id()); TaskGCContext tmp(transport->task_id()); #endif for (i=0; i < ep().num_modifiers(); i++) { new_modifier = VMEventModifier::new_modifier(in, out, error); if (error) { // some sort of error happened if (out->error() != 0) { out->send_packet(); } return; } if (new_modifier.is_null()) { // Most likely we don't support this modifier continue; } if (event_kind == JDWP_EventKind_BREAKPOINT && new_modifier().mod_kind() == JDWP_EventRequest_Set_Out_modifiers_Modifier_LocationOnly) { UsingFastOops fastoops2; LocationModifier *lmp = (LocationModifier *)&new_modifier; VMEvent::Fast epb = VMEvent::find_breakpoint_event(lmp, transport->task_id()); if (epb.not_null()) { out->write_int(epb().event_id()); out->send_packet(); // out->send_error(JDWP_Error_NOT_IMPLEMENTED); // there's a breakpoint here already, don't bother installing another return; } #if ENABLE_ISOLATES InstanceClass::Raw ic = JavaDebugger::get_object_by_id(new_modifier().clazz_id()); if (ic().class_id() < ROM::number_of_system_classes()) { // breakpoint in system class, allow in any task ep().set_task_id(-1); } // See if any other task already has a breakpoint here. epb = find_breakpoint_event(lmp); if (!epb.is_null()) { // Has to be some other task since we haven't linked in this event GUARANTEE(epb().task_id() != transport->task_id(), "Breakpoint already inserted"); LocationModifier::Raw lmod = get_modifier(&epb, JDWP_EventRequest_Set_Out_modifiers_Modifier_LocationOnly); GUARANTEE(!lmod.is_null(),"Breakpoint event has no location modifier"); lmp->set_save_opcode(lmod().save_opcode()); } else { #endif /* Return an error back to the debugger if * the breakpoint could not be installed. */ lmp->unlink_method(); lmp->save_method_entry(); if (lmp->set_method_opcode(Bytecodes::_breakpoint, true) == false){ out->send_error(JDWP_Error_INVALID_LOCATION); return; } #if ENABLE_ISOLATES } #endif } // insert the mod at the end of the list of modifiers event_modifier = ep().mods(); if (event_modifier.is_null()) { ep().set_mods(&new_modifier); current_modifier_slot = ep().mods(); } else { current_modifier_slot().set_next(&new_modifier); current_modifier_slot = new_modifier; } } #ifdef AZZERT if (TraceDebugger) { tty->print_cr("Create Event: xprt = 0x%x, ep = 0x%lx, id = 0x%x, kind = 0x%lx, suspend = 0x%lx, num mods = 0x%lx", transport->obj(), ep.obj(), ep().event_id(), ep().event_kind(), ep().suspend_policy(), ep().num_modifiers()); } #endif ep().set_next((VMEvent *)Universe::vmevent_request_head()); *Universe::vmevent_request_head() = ep; out->write_int(ep().event_id()); out->send_packet(); VMEvent::add_notification(JDWP_eventkind_to_dbg_eventkind(event_kind)); }