Commit eba4ae23 authored by jgruber's avatar jgruber Committed by Commit bot

Add flags to FrameArray

This makes some information passed implicitly (e.g. the ForceConstructor
flag used to be a special symbol passed as the receiver) explicit.

BUG=

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