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:
jgruber 2016-08-24 08:40:56 -07:00 committed by Commit bot
parent fcc8399d39
commit eba4ae2357
5 changed files with 60 additions and 67 deletions

View File

@ -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.

View File

@ -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,

View File

@ -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 {

View File

@ -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;
}

View File

@ -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;