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}
This commit is contained in:
parent
fcc8399d39
commit
eba4ae2357
@ -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<Object> caller_;
|
||||
bool skip_next_frame_;
|
||||
|
||||
int sloppy_frames_;
|
||||
bool encountered_strict_function_;
|
||||
};
|
||||
|
||||
@ -475,23 +468,27 @@ Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object,
|
||||
|
||||
// Filter out internal frames that we do not want to show.
|
||||
if (!helper.IsVisibleInStackTrace(*fun)) continue;
|
||||
helper.CountSloppyFrames(*fun);
|
||||
|
||||
Handle<Object> recv = frames[i].receiver();
|
||||
Handle<AbstractCode> 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<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object,
|
||||
|
||||
// Filter out internal frames that we do not want to show.
|
||||
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 =
|
||||
static_cast<int>(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<Object> 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<AbstractCode>::cast(code), offset);
|
||||
elements = FrameArray::AppendJSFrame(elements, recv, fun,
|
||||
Handle<AbstractCode>::cast(code),
|
||||
offset, flags);
|
||||
} break;
|
||||
|
||||
case StackFrame::WASM: {
|
||||
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();
|
||||
Code* code = wasm_frame->unchecked_code();
|
||||
Handle<AbstractCode> abstract_code =
|
||||
Handle<AbstractCode>(AbstractCode::cast(code), this);
|
||||
Handle<AbstractCode> abstract_code(AbstractCode::cast(code), this);
|
||||
const int offset =
|
||||
static_cast<int>(wasm_frame->pc() - code->instruction_start());
|
||||
|
||||
@ -536,7 +528,8 @@ Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> 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<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object,
|
||||
}
|
||||
}
|
||||
|
||||
elements->SetSloppyFrameCount(helper.sloppy_frames());
|
||||
elements->ShrinkToFit();
|
||||
|
||||
// TODO(yangguo): Queue this structured stack trace for preprocessing on GC.
|
||||
|
@ -499,15 +499,13 @@ MaybeHandle<FixedArray> GetStackFrames(Isolate* isolate,
|
||||
|
||||
const int frame_count = elems->FrameCount();
|
||||
|
||||
int sloppy_frames = elems->SloppyFrameCount();
|
||||
|
||||
Handle<FixedArray> frames = isolate->factory()->NewFixedArray(frame_count);
|
||||
for (int i = 0; i < frame_count; i++) {
|
||||
const int flags = elems->Flags(i)->value();
|
||||
Handle<AbstractCode> code(elems->Code(i), isolate);
|
||||
Handle<Smi> pc(elems->Offset(i), isolate);
|
||||
|
||||
sloppy_frames--;
|
||||
Handle<Object> strict = isolate->factory()->ToBoolean(sloppy_frames < 0);
|
||||
Handle<Object> strict =
|
||||
isolate->factory()->ToBoolean(flags & FrameArray::kIsStrict);
|
||||
|
||||
if (elems->IsWasmFrame(i)) {
|
||||
Handle<Object> wasm_obj(elems->WasmObject(i), isolate);
|
||||
@ -531,6 +529,10 @@ MaybeHandle<FixedArray> GetStackFrames(Isolate* isolate,
|
||||
Handle<Object> pos(Smi::FromInt(code->SourcePosition(pc->value())),
|
||||
isolate);
|
||||
|
||||
if (flags & FrameArray::kForceConstructor) {
|
||||
recv = handle(isolate->heap()->call_site_constructor_symbol());
|
||||
}
|
||||
|
||||
Handle<Object> callsite;
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, callsite,
|
||||
|
@ -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 {
|
||||
|
@ -10208,7 +10208,7 @@ Handle<FrameArray> FrameArray::AppendJSFrame(Handle<FrameArray> in,
|
||||
Handle<Object> receiver,
|
||||
Handle<JSFunction> function,
|
||||
Handle<AbstractCode> code,
|
||||
int offset) {
|
||||
int offset, int flags) {
|
||||
const int frame_count = in->FrameCount();
|
||||
const int new_length = LengthFor(frame_count + 1);
|
||||
Handle<FrameArray> array = EnsureSpace(in, new_length);
|
||||
@ -10216,6 +10216,7 @@ Handle<FrameArray> FrameArray::AppendJSFrame(Handle<FrameArray> 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> FrameArray::AppendWasmFrame(Handle<FrameArray> in,
|
||||
Handle<Object> wasm_object,
|
||||
int wasm_function_index,
|
||||
Handle<AbstractCode> code,
|
||||
int offset) {
|
||||
int offset, int flags) {
|
||||
const int frame_count = in->FrameCount();
|
||||
const int new_length = LengthFor(frame_count + 1);
|
||||
Handle<FrameArray> array = EnsureSpace(in, new_length);
|
||||
@ -10233,6 +10234,7 @@ Handle<FrameArray> FrameArray::AppendWasmFrame(Handle<FrameArray> 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;
|
||||
}
|
||||
|
@ -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<FrameArray> AppendJSFrame(Handle<FrameArray> in,
|
||||
Handle<Object> receiver,
|
||||
Handle<JSFunction> function,
|
||||
Handle<AbstractCode> code,
|
||||
int offset);
|
||||
Handle<AbstractCode> code, int offset,
|
||||
int flags);
|
||||
static Handle<FrameArray> AppendWasmFrame(Handle<FrameArray> in,
|
||||
Handle<Object> wasm_object,
|
||||
int wasm_function_index,
|
||||
Handle<AbstractCode> 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;
|
||||
|
Loading…
Reference in New Issue
Block a user