diff --git a/src/isolate.cc b/src/isolate.cc index 3a9b93a42d..10835256cc 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -346,21 +346,17 @@ class StackTraceHelper { break; } encountered_strict_function_ = false; - sloppy_frames_ = 0; } + // Poison stack frames below the first strict mode frame. // The stack trace API should not expose receivers and function // objects on frames deeper than the top-most one with a strict mode - // function. The number of sloppy frames is stored as first element in - // the result array. - void CountSloppyFrames(JSFunction* fun) { + // function. + bool IsStrictFrame(JSFunction* fun) { if (!encountered_strict_function_) { - if (is_strict(fun->shared()->language_mode())) { - encountered_strict_function_ = true; - } else { - sloppy_frames_++; - } + encountered_strict_function_ = is_strict(fun->shared()->language_mode()); } + return encountered_strict_function_; } // Determines whether the given stack frame should be displayed in a stack @@ -370,8 +366,6 @@ class StackTraceHelper { IsInSameSecurityContext(fun); } - int sloppy_frames() const { return sloppy_frames_; } - private: // This mechanism excludes a number of uninteresting frames from the stack // trace. This can be be the first frame (which will be a builtin-exit frame @@ -417,7 +411,6 @@ class StackTraceHelper { const Handle caller_; bool skip_next_frame_; - int sloppy_frames_; bool encountered_strict_function_; }; @@ -475,23 +468,27 @@ Handle Isolate::CaptureSimpleStackTrace(Handle error_object, // Filter out internal frames that we do not want to show. if (!helper.IsVisibleInStackTrace(*fun)) continue; - helper.CountSloppyFrames(*fun); Handle recv = frames[i].receiver(); Handle abstract_code = frames[i].abstract_code(); + const int offset = frames[i].code_offset(); + + bool force_constructor = false; if (frame->type() == StackFrame::BUILTIN) { // Help CallSite::IsConstructor correctly detect hand-written // construct stubs. - Code* code = Code::cast(*abstract_code); - if (code->is_construct_stub()) { - recv = handle(heap()->call_site_constructor_symbol(), this); + if (Code::cast(*abstract_code)->is_construct_stub()) { + force_constructor = true; } } - const int offset = frames[i].code_offset(); - elements = FrameArray::AppendJSFrame(elements, - TheHoleToUndefined(this, recv), - fun, abstract_code, offset); + int flags = 0; + if (helper.IsStrictFrame(*fun)) flags |= FrameArray::kIsStrict; + if (force_constructor) flags |= FrameArray::kForceConstructor; + + elements = FrameArray::AppendJSFrame( + elements, TheHoleToUndefined(this, recv), fun, abstract_code, + offset, flags); } } break; @@ -501,32 +498,27 @@ Handle Isolate::CaptureSimpleStackTrace(Handle error_object, // Filter out internal frames that we do not want to show. if (!helper.IsVisibleInStackTrace(*fun)) continue; - helper.CountSloppyFrames(*fun); - Handle code = handle(exit_frame->LookupCode(), this); + Handle recv(exit_frame->receiver(), this); + Handle code(exit_frame->LookupCode(), this); int offset = static_cast(exit_frame->pc() - code->instruction_start()); - // In order to help CallSite::IsConstructor detect builtin constructors, - // we reuse the receiver field to pass along a special symbol. - Handle recv; - if (exit_frame->IsConstructor()) { - recv = factory()->call_site_constructor_symbol(); - } else { - recv = handle(exit_frame->receiver(), this); - } + int flags = 0; + if (helper.IsStrictFrame(*fun)) flags |= FrameArray::kIsStrict; + if (exit_frame->IsConstructor()) flags |= FrameArray::kForceConstructor; - elements = FrameArray::AppendJSFrame( - elements, recv, fun, Handle::cast(code), offset); + elements = FrameArray::AppendJSFrame(elements, recv, fun, + Handle::cast(code), + offset, flags); } break; case StackFrame::WASM: { WasmFrame* wasm_frame = WasmFrame::cast(frame); - Handle wasm_object = handle(wasm_frame->wasm_obj(), this); + Handle wasm_object(wasm_frame->wasm_obj(), this); const int wasm_function_index = wasm_frame->function_index(); Code* code = wasm_frame->unchecked_code(); - Handle abstract_code = - Handle(AbstractCode::cast(code), this); + Handle abstract_code(AbstractCode::cast(code), this); const int offset = static_cast(wasm_frame->pc() - code->instruction_start()); @@ -536,7 +528,8 @@ Handle Isolate::CaptureSimpleStackTrace(Handle error_object, wasm_object->IsUndefined(this)); elements = FrameArray::AppendWasmFrame( - elements, wasm_object, wasm_function_index, abstract_code, offset); + elements, wasm_object, wasm_function_index, abstract_code, offset, + FrameArray::kIsWasmFrame); } break; default: @@ -544,7 +537,6 @@ Handle Isolate::CaptureSimpleStackTrace(Handle error_object, } } - elements->SetSloppyFrameCount(helper.sloppy_frames()); elements->ShrinkToFit(); // TODO(yangguo): Queue this structured stack trace for preprocessing on GC. diff --git a/src/messages.cc b/src/messages.cc index bf0126c197..e7508fb955 100644 --- a/src/messages.cc +++ b/src/messages.cc @@ -499,15 +499,13 @@ MaybeHandle GetStackFrames(Isolate* isolate, const int frame_count = elems->FrameCount(); - int sloppy_frames = elems->SloppyFrameCount(); - Handle frames = isolate->factory()->NewFixedArray(frame_count); for (int i = 0; i < frame_count; i++) { + const int flags = elems->Flags(i)->value(); Handle code(elems->Code(i), isolate); Handle pc(elems->Offset(i), isolate); - - sloppy_frames--; - Handle strict = isolate->factory()->ToBoolean(sloppy_frames < 0); + Handle strict = + isolate->factory()->ToBoolean(flags & FrameArray::kIsStrict); if (elems->IsWasmFrame(i)) { Handle wasm_obj(elems->WasmObject(i), isolate); @@ -531,6 +529,10 @@ MaybeHandle GetStackFrames(Isolate* isolate, Handle pos(Smi::FromInt(code->SourcePosition(pc->value())), isolate); + if (flags & FrameArray::kForceConstructor) { + recv = handle(isolate->heap()->call_site_constructor_symbol()); + } + Handle callsite; ASSIGN_RETURN_ON_EXCEPTION( isolate, callsite, diff --git a/src/objects-inl.h b/src/objects-inl.h index 3f44c718ab..0e5b4e1a71 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -2625,18 +2625,9 @@ Object** FixedArray::RawFieldOfElementAt(int index) { FRAME_ARRAY_FIELD_LIST(DEFINE_FRAME_ARRAY_ACCESSORS) #undef DEFINE_FRAME_ARRAY_ACCESSORS -int FrameArray::SloppyFrameCount() const { - return Smi::cast(get(kSloppyFramesIndex))->value(); -} - -void FrameArray::SetSloppyFrameCount(int count) { - return set(kSloppyFramesIndex, Smi::FromInt(count)); -} - bool FrameArray::IsWasmFrame(int frame_ix) const { - Object* obj = get(kFirstIndex + frame_ix * kElementsPerFrame + - kWasmFunctionIndexOffset); - return obj->IsSmi(); + const int flags = Flags(frame_ix)->value(); + return (flags & kIsWasmFrame) != 0; } int FrameArray::FrameCount() const { diff --git a/src/objects.cc b/src/objects.cc index 9916e6e1a8..f6ae8470da 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -10208,7 +10208,7 @@ Handle FrameArray::AppendJSFrame(Handle in, Handle receiver, Handle function, Handle code, - int offset) { + int offset, int flags) { const int frame_count = in->FrameCount(); const int new_length = LengthFor(frame_count + 1); Handle array = EnsureSpace(in, new_length); @@ -10216,6 +10216,7 @@ Handle FrameArray::AppendJSFrame(Handle in, array->SetFunction(frame_count, *function); array->SetCode(frame_count, *code); array->SetOffset(frame_count, Smi::FromInt(offset)); + array->SetFlags(frame_count, Smi::FromInt(flags)); array->set(kFrameCountIndex, Smi::FromInt(frame_count + 1)); return array; } @@ -10225,7 +10226,7 @@ Handle FrameArray::AppendWasmFrame(Handle in, Handle wasm_object, int wasm_function_index, Handle code, - int offset) { + int offset, int flags) { const int frame_count = in->FrameCount(); const int new_length = LengthFor(frame_count + 1); Handle array = EnsureSpace(in, new_length); @@ -10233,6 +10234,7 @@ Handle FrameArray::AppendWasmFrame(Handle in, array->SetWasmFunctionIndex(frame_count, Smi::FromInt(wasm_function_index)); array->SetCode(frame_count, *code); array->SetOffset(frame_count, Smi::FromInt(offset)); + array->SetFlags(frame_count, Smi::FromInt(flags)); array->set(kFrameCountIndex, Smi::FromInt(frame_count + 1)); return array; } diff --git a/src/objects.h b/src/objects.h index 2d90acdb1d..23ac7cea55 100644 --- a/src/objects.h +++ b/src/objects.h @@ -2932,7 +2932,8 @@ class ArrayList : public FixedArray { V(Receiver, Object) \ V(Function, JSFunction) \ V(Code, AbstractCode) \ - V(Offset, Smi) + V(Offset, Smi) \ + V(Flags, Smi) // Container object for data collected during simple stack trace captures. class FrameArray : public FixedArray { @@ -2943,31 +2944,35 @@ class FrameArray : public FixedArray { FRAME_ARRAY_FIELD_LIST(DECLARE_FRAME_ARRAY_ACCESSORS) #undef DECLARE_FRAME_ARRAY_ACCESSORS - inline void SetSloppyFrameCount(int count); - inline int SloppyFrameCount() const; - inline bool IsWasmFrame(int frame_ix) const; inline int FrameCount() const; void ShrinkToFit(); + // Flags. + static const int kIsWasmFrame = 1 << 0; + static const int kIsStrict = 1 << 1; + static const int kForceConstructor = 1 << 2; + static Handle AppendJSFrame(Handle in, Handle receiver, Handle function, - Handle code, - int offset); + Handle code, int offset, + int flags); static Handle AppendWasmFrame(Handle in, Handle wasm_object, int wasm_function_index, Handle code, - int offset); + int offset, int flags); DECLARE_CAST(FrameArray) private: - // The underlying fixed array embodies a captured stack trace. The number of - // sloppy frames is stored at array[kFirstIndex]. Frame i occupies indices + // The underlying fixed array embodies a captured stack trace. Frame i + // occupies indices + // // kFirstIndex + 1 + [i * kElementsPerFrame, (i + 1) * kElementsPerFrame[, + // // with internal offsets as below: static const int kWasmObjectOffset = 0; @@ -2979,13 +2984,14 @@ class FrameArray : public FixedArray { static const int kCodeOffset = 2; static const int kOffsetOffset = 3; - static const int kElementsPerFrame = 4; + static const int kFlagsOffset = 4; + + static const int kElementsPerFrame = 5; // Array layout indices. static const int kFrameCountIndex = 0; - static const int kSloppyFramesIndex = 1; - static const int kFirstIndex = 2; + static const int kFirstIndex = 1; static int LengthFor(int frame_count) { return kFirstIndex + frame_count * kElementsPerFrame;