| Index: src/frames.cc
|
| diff --git a/src/frames.cc b/src/frames.cc
|
| index f206dbdd996a69e0b01c27af8ce6f04f5bc32f5c..c503114c929749979add82adec0421fc19261798 100644
|
| --- a/src/frames.cc
|
| +++ b/src/frames.cc
|
| @@ -182,6 +182,29 @@ void StackTraceFrameIterator::AdvanceToArgumentsFrame() {
|
|
|
| // -------------------------------------------------------------------------
|
|
|
| +namespace {
|
| +
|
| +bool IsInterpreterFramePc(Isolate* isolate, Address pc) {
|
| + Code* interpreter_entry_trampoline =
|
| + isolate->builtins()->builtin(Builtins::kInterpreterEntryTrampoline);
|
| + Code* interpreter_bytecode_advance =
|
| + isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeAdvance);
|
| + Code* interpreter_bytecode_dispatch =
|
| + isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeDispatch);
|
| +
|
| + return (pc >= interpreter_entry_trampoline->instruction_start() &&
|
| + pc < interpreter_entry_trampoline->instruction_end()) ||
|
| + (pc >= interpreter_bytecode_advance->instruction_start() &&
|
| + pc < interpreter_bytecode_advance->instruction_end()) ||
|
| + (pc >= interpreter_bytecode_dispatch->instruction_start() &&
|
| + pc < interpreter_bytecode_dispatch->instruction_end());
|
| +}
|
| +
|
| +DISABLE_ASAN Address ReadMemoryAt(Address address) {
|
| + return Memory::Address_at(address);
|
| +}
|
| +
|
| +} // namespace
|
|
|
| SafeStackFrameIterator::SafeStackFrameIterator(
|
| Isolate* isolate,
|
| @@ -194,6 +217,7 @@ SafeStackFrameIterator::SafeStackFrameIterator(
|
| StackFrame::State state;
|
| StackFrame::Type type;
|
| ThreadLocalTop* top = isolate->thread_local_top();
|
| + bool advance_frame = true;
|
| if (IsValidTop(top)) {
|
| type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state);
|
| top_frame_type_ = type;
|
| @@ -203,6 +227,19 @@ SafeStackFrameIterator::SafeStackFrameIterator(
|
| state.sp = sp;
|
| state.pc_address = StackFrame::ResolveReturnAddressLocation(
|
| reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp)));
|
| +
|
| + // If the top of stack is a return address to the interpreter trampoline,
|
| + // then we are likely in a bytecode handler with elided frame. In that
|
| + // case, set the PC properly and make sure we do not drop the frame.
|
| + if (IsValidStackAddress(sp)) {
|
| + MSAN_MEMORY_IS_INITIALIZED(sp, kPointerSize);
|
| + Address tos = ReadMemoryAt(reinterpret_cast<Address>(sp));
|
| + if (IsInterpreterFramePc(isolate, tos)) {
|
| + state.pc_address = reinterpret_cast<Address*>(sp);
|
| + advance_frame = false;
|
| + }
|
| + }
|
| +
|
| // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset,
|
| // we check only that kMarkerOffset is within the stack bounds and do
|
| // compile time check that kContextOffset slot is pushed on the stack before
|
| @@ -213,6 +250,10 @@ SafeStackFrameIterator::SafeStackFrameIterator(
|
| if (IsValidStackAddress(frame_marker)) {
|
| type = StackFrame::ComputeType(this, &state);
|
| top_frame_type_ = type;
|
| + // We only keep the top frame if we believe it to be interpreted frame.
|
| + if (type != StackFrame::INTERPRETED) {
|
| + advance_frame = true;
|
| + }
|
| } else {
|
| // Mark the frame as JAVA_SCRIPT if we cannot determine its type.
|
| // The frame anyways will be skipped.
|
| @@ -224,7 +265,7 @@ SafeStackFrameIterator::SafeStackFrameIterator(
|
| return;
|
| }
|
| frame_ = SingletonFor(type, &state);
|
| - if (frame_) Advance();
|
| + if (advance_frame && frame_) Advance();
|
| }
|
|
|
|
|
| @@ -389,22 +430,6 @@ void StackFrame::SetReturnAddressLocationResolver(
|
| return_address_location_resolver_ = resolver;
|
| }
|
|
|
| -static bool IsInterpreterFramePc(Isolate* isolate, Address pc) {
|
| - Code* interpreter_entry_trampoline =
|
| - isolate->builtins()->builtin(Builtins::kInterpreterEntryTrampoline);
|
| - Code* interpreter_bytecode_advance =
|
| - isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeAdvance);
|
| - Code* interpreter_bytecode_dispatch =
|
| - isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeDispatch);
|
| -
|
| - return (pc >= interpreter_entry_trampoline->instruction_start() &&
|
| - pc < interpreter_entry_trampoline->instruction_end()) ||
|
| - (pc >= interpreter_bytecode_advance->instruction_start() &&
|
| - pc < interpreter_bytecode_advance->instruction_end()) ||
|
| - (pc >= interpreter_bytecode_dispatch->instruction_start() &&
|
| - pc < interpreter_bytecode_dispatch->instruction_end());
|
| -}
|
| -
|
| StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
|
| State* state) {
|
| DCHECK(state->fp != NULL);
|
|
|