diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc index f6c040754c2..54f01fe289c 100644 --- a/runtime/vm/compiler/backend/il_printer.cc +++ b/runtime/vm/compiler/backend/il_printer.cc @@ -34,7 +34,7 @@ DECLARE_FLAG(bool, trace_inlining_intervals); static bool IsRedundant(Instruction* instr) { if (auto constant = instr->AsConstant()) { - return !constant->HasUses(); + return constant->HasSSATemp() && !constant->HasUses(); } else if (auto move = instr->AsParallelMove()) { return move->IsRedundant(); } else { diff --git a/runtime/vm/compiler/stub_code_compiler.cc b/runtime/vm/compiler/stub_code_compiler.cc index 1ba8908934c..7572a31eef9 100644 --- a/runtime/vm/compiler/stub_code_compiler.cc +++ b/runtime/vm/compiler/stub_code_compiler.cc @@ -2542,11 +2542,12 @@ void StubCodeCompiler::GenerateResumeStub() { } SPILLS_RETURN_ADDRESS_FROM_LR_TO_REGISTER({}); // Undo SetReturnAddress(). #endif - __ Comment("Resume interpreter with exception"); + __ Comment("Resume interpreter"); __ Bind(&resume_interpreter); __ PushObject(NullObject()); // Make room for result. - __ PushObject(NullObject()); // Return value. - __ PushRegistersInOrder({kException, kStackTrace}); + // Load the value to pass to the resumed bytecode. + __ LoadFromOffset(kTemp, FPREG, param_offset + 3 * target::kWordSize); + __ PushRegistersInOrder({kTemp, kException, kStackTrace}); __ CallRuntime(kResumeInterpreterRuntimeEntry, /*argument_count=*/3); __ Drop(3); // Drop arguments. __ PopRegister(CallingConventions::kReturnReg); // Get result. diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc index 836edfdfb0e..ea93d56714b 100644 --- a/runtime/vm/interpreter.cc +++ b/runtime/vm/interpreter.cc @@ -439,6 +439,54 @@ DART_NOINLINE void Interpreter::WriteInstructionToTrace(const KBCInstr* pc) { } } +void Interpreter::PrintStackFrames(const ObjectPtr* FP, + const ObjectPtr* SP, + intptr_t depth) { + const word *fp = reinterpret_cast(FP), + *sp = reinterpret_cast(SP); + for (intptr_t i = 0; i < depth; i++) { + const word caller_pc = fp[kKBCSavedCallerPcSlotFromFp]; + const bool is_entry_frame = caller_pc == kEntryFramePcMarker; + // The entry frame slots are printed separately from the rest of the frame. + auto* const frame_end = fp + (is_entry_frame ? kKBCEntrySavedSlots : 0); + + THR_Print("Frame %" Pd "%s:\n", i, is_entry_frame ? " (entry)" : ""); + for (auto* current = sp; current >= frame_end; --current) { + THR_Print(" %#" Px ": %#" Px "\n", reinterpret_cast(current), + *current); + } + + if (is_entry_frame) { + THR_Print(" %#" Px ": %#" Px " (pool pointer)\n", + reinterpret_cast(fp + kKBCSavedPpSlotFromEntryFp), + fp[kKBCSavedPpSlotFromEntryFp]); + THR_Print(" %#" Px ": %#" Px " (args descriptor)\n", + reinterpret_cast(fp + kKBCSavedArgDescSlotFromEntryFp), + fp[kKBCSavedArgDescSlotFromEntryFp]); + THR_Print(" %#" Px ": %#" Px " (exit link)\n", + reinterpret_cast(fp + kKBCExitLinkSlotFromEntryFp), + fp[kKBCExitLinkSlotFromEntryFp]); + } + + THR_Print(" %#" Px ": %#" Px " (saved caller fp)\n", + reinterpret_cast(fp + kKBCSavedCallerFpSlotFromFp), + fp[kKBCSavedCallerFpSlotFromFp]); + THR_Print(" %#" Px ": %#" Px " (saved caller pc)\n", + reinterpret_cast(fp + kKBCSavedCallerPcSlotFromFp), + fp[kKBCSavedCallerPcSlotFromFp]); + if (is_entry_frame) break; + THR_Print(" %#" Px ": %#" Px " (caller pc)\n", + reinterpret_cast(fp + kKBCPcMarkerSlotFromFp), + fp[kKBCPcMarkerSlotFromFp]); + THR_Print(" %#" Px ": %#" Px " (called function)\n", + reinterpret_cast(fp + kKBCFunctionSlotFromFp), + fp[kKBCFunctionSlotFromFp]); + sp = fp + kKBCCallerSpSlotFromFp; + fp = reinterpret_cast(fp[kKBCSavedCallerFpSlotFromFp]); + THR_Print("\n"); + } +} + #endif // defined(DEBUG) // Calls into the Dart runtime are based on this interface. diff --git a/runtime/vm/interpreter.h b/runtime/vm/interpreter.h index e030498cd85..11b9f95f335 100644 --- a/runtime/vm/interpreter.h +++ b/runtime/vm/interpreter.h @@ -289,6 +289,15 @@ class Interpreter { void FlushTraceBuffer(); void WriteInstructionToTrace(const KBCInstr* pc); + // Prints at most the requested number of interpreted stack frames + // up to the most recent entry frame. + // + // If [depth] is non-positive, prints all interpreted stack frames + // up to the most recent entry frame. + void PrintStackFrames(const ObjectPtr* FP, + const ObjectPtr* SP, + intptr_t depth = 0); + void* trace_file_; uint64_t trace_file_bytes_written_;