inline void vframeStreamCommon::fill_from_interpreter_frame() { methodOop method = _frame.interpreter_frame_method(); intptr_t bcx = _frame.interpreter_frame_bcx(); int bci = method->validate_bci_from_bcx(bcx); // 6379830 AsyncGetCallTrace sometimes feeds us wild frames. if (bci < 0) { found_bad_method_frame(); bci = 0; // pretend it's on the point of entering } _mode = interpreted_mode; _method = method; _bci = bci; }
inline void vframeStreamCommon::fill_from_interpreter_frame() { Method* method = _frame.interpreter_frame_method(); address bcp = _frame.interpreter_frame_bcp(); int bci = method->validate_bci_from_bcp(bcp); // 6379830 AsyncGetCallTrace sometimes feeds us wild frames. // AsyncGetCallTrace interrupts the VM asynchronously. As a result // it is possible to access an interpreter frame for which // no Java-level information is yet available (e.g., becasue // the frame was being created when the VM interrupted it). // In this scenario, pretend that the interpreter is at the point // of entering the method. if (bci < 0) { found_bad_method_frame(); bci = 0; } _mode = interpreted_mode; _method = method; _bci = bci; }
inline void vframeStreamCommon::fill_from_compiled_frame(int decode_offset) { _mode = compiled_mode; // Range check to detect ridiculous offsets. if (decode_offset == DebugInformationRecorder::serialized_null || decode_offset < 0 || decode_offset >= nm()->scopes_data_size()) { // 6379830 AsyncGetCallTrace sometimes feeds us wild frames. // If we attempt to read nmethod::scopes_data at serialized_null (== 0), // or if we read some at other crazy offset, // we will decode garbage and make wild references into the heap, // leading to crashes in product mode. // (This isn't airtight, of course, since there are internal // offsets which are also crazy.) #ifdef ASSERT if (WizardMode) { tty->print_cr("Error in fill_from_frame: pc_desc for " INTPTR_FORMAT " not found or invalid at %d", _frame.pc(), decode_offset); nm()->print(); nm()->method()->print_codes(); nm()->print_code(); nm()->print_pcs(); } #endif // Provide a cheap fallback in product mode. (See comment above.) found_bad_method_frame(); fill_from_compiled_native_frame(); return; } // Decode first part of scopeDesc DebugInfoReadStream buffer(nm(), decode_offset); _sender_decode_offset = buffer.read_int(); _method = methodOop(buffer.read_oop()); _bci = buffer.read_bci(); assert(_method->is_method(), "checking type of decoded method"); }
inline void vframeStreamCommon::fill_from_compiled_frame(int decode_offset) { _mode = compiled_mode; // Range check to detect ridiculous offsets. if (decode_offset == DebugInformationRecorder::serialized_null || decode_offset < 0 || decode_offset >= nm()->scopes_data_size()) { // 6379830 AsyncGetCallTrace sometimes feeds us wild frames. // If we read nmethod::scopes_data at serialized_null (== 0) // or if read some at other invalid offset, invalid values will be decoded. // Based on these values, invalid heap locations could be referenced // that could lead to crashes in product mode. // Therefore, do not use the decode offset if invalid, but fill the frame // as it were a native compiled frame (no Java-level assumptions). #ifdef ASSERT if (WizardMode) { tty->print_cr("Error in fill_from_frame: pc_desc for " INTPTR_FORMAT " not found or invalid at %d", p2i(_frame.pc()), decode_offset); nm()->print(); nm()->method()->print_codes(); nm()->print_code(); nm()->print_pcs(); } #endif // Provide a cheap fallback in product mode. (See comment above.) found_bad_method_frame(); fill_from_compiled_native_frame(); return; } // Decode first part of scopeDesc DebugInfoReadStream buffer(nm(), decode_offset); _sender_decode_offset = buffer.read_int(); _method = buffer.read_method(); _bci = buffer.read_bci(); assert(_method->is_method(), "checking type of decoded method"); }