Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Unified Diff: src/isolate.cc

Issue 2252783007: Revert of Use a custom Struct for stack trace storage (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/heap-symbols.h ('k') | src/messages.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/isolate.cc
diff --git a/src/isolate.cc b/src/isolate.cc
index a40a297c9587756b323f402dd2f89ec744be43fa..859d91381b1c290b2b14a9523656739a82bef2e7 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -357,16 +357,21 @@
break;
}
encountered_strict_function_ = false;
+ sloppy_frames_ = 0;
}
// The stack trace API should not expose receivers and function
// objects on frames deeper than the top-most one with a strict mode
- // function.
- bool IsStrictFrame(JSFunction* fun) {
+ // function. The number of sloppy frames is stored as first element in
+ // the result array.
+ void CountSloppyFrames(JSFunction* fun) {
if (!encountered_strict_function_) {
- encountered_strict_function_ = is_strict(fun->shared()->language_mode());
- }
- return encountered_strict_function_;
+ if (is_strict(fun->shared()->language_mode())) {
+ encountered_strict_function_ = true;
+ } else {
+ sloppy_frames_++;
+ }
+ }
}
// Determines whether the given stack frame should be displayed in a stack
@@ -375,6 +380,8 @@
return ShouldIncludeFrame(fun) && IsNotInNativeScript(fun) &&
IsInSameSecurityContext(fun);
}
+
+ int sloppy_frames() const { return sloppy_frames_; }
private:
// This mechanism excludes a number of uninteresting frames from the stack
@@ -421,6 +428,7 @@
const Handle<Object> caller_;
bool skip_next_frame_;
+ int sloppy_frames_;
bool encountered_strict_function_;
};
@@ -433,38 +441,34 @@
? Handle<Object>::cast(isolate->factory()->undefined_value())
: in;
}
-
-bool GetStackTraceLimit(Isolate* isolate, int* result) {
- Handle<JSObject> error = isolate->error_function();
- Handle<String> stackTraceLimit =
- isolate->factory()->InternalizeUtf8String("stackTraceLimit");
- DCHECK(!stackTraceLimit.is_null());
-
- Handle<Object> stack_trace_limit =
- JSReceiver::GetDataProperty(error, stackTraceLimit);
- if (!stack_trace_limit->IsNumber()) return false;
-
- // Ensure that limit is not negative.
- *result = Max(FastD2IChecked(stack_trace_limit->Number()), 0);
- return true;
-}
-
-} // namespace
+}
Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object,
FrameSkipMode mode,
Handle<Object> caller) {
DisallowJavascriptExecution no_js(this);
- int limit;
- if (!GetStackTraceLimit(this, &limit)) return factory()->undefined_value();
+ // Get stack trace limit.
+ Handle<JSObject> error = error_function();
+ Handle<String> stackTraceLimit =
+ factory()->InternalizeUtf8String("stackTraceLimit");
+ DCHECK(!stackTraceLimit.is_null());
+ Handle<Object> stack_trace_limit =
+ JSReceiver::GetDataProperty(error, stackTraceLimit);
+ if (!stack_trace_limit->IsNumber()) return factory()->undefined_value();
+ int limit = FastD2IChecked(stack_trace_limit->Number());
+ limit = Max(limit, 0); // Ensure that limit is not negative.
int initial_size = Min(limit, 10);
- Handle<FixedArray> elements = factory()->NewFixedArrayWithHoles(initial_size);
-
- int cursor = 0;
+ Handle<FixedArray> elements =
+ factory()->NewFixedArrayWithHoles(initial_size * 4 + 1);
+
StackTraceHelper helper(this, mode, caller);
- for (StackFrameIterator iter(this); !iter.done() && cursor < limit;
+
+ // First element is reserved to store the number of sloppy frames.
+ int cursor = 1;
+ int frames_seen = 0;
+ for (StackFrameIterator iter(this); !iter.done() && frames_seen < limit;
iter.Advance()) {
StackFrame* frame = iter.frame();
@@ -483,33 +487,26 @@
// 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.
- if (Code::cast(*abstract_code)->is_construct_stub()) {
- force_constructor = true;
+ Code* code = Code::cast(*abstract_code);
+ if (code->is_construct_stub()) {
+ recv = handle(heap()->call_site_constructor_symbol(), this);
}
}
-
- int flags = 0;
- if (helper.IsStrictFrame(*fun)) flags |= StackTraceFrame::kIsStrict;
- if (force_constructor) flags |= StackTraceFrame::kForceConstructor;
-
- Handle<StackTraceFrame> callsite = factory()->NewStackTraceFrame();
- callsite->set_flags(flags);
- callsite->set_receiver(*TheHoleToUndefined(this, recv));
- callsite->set_function(*fun);
- callsite->set_abstract_code(*abstract_code);
- callsite->set_offset(offset);
-
- elements = MaybeGrow(this, elements, cursor, cursor + 1);
- elements->set(cursor++, *callsite);
+ Handle<Smi> offset(Smi::FromInt(frames[i].code_offset()), this);
+
+ elements = MaybeGrow(this, elements, cursor, cursor + 4);
+ elements->set(cursor++, *TheHoleToUndefined(this, recv));
+ elements->set(cursor++, *fun);
+ elements->set(cursor++, *abstract_code);
+ elements->set(cursor++, *offset);
+ frames_seen++;
}
} break;
@@ -519,26 +516,27 @@
// Filter out internal frames that we do not want to show.
if (!helper.IsVisibleInStackTrace(*fun)) continue;
-
- Handle<Object> recv = handle(exit_frame->receiver(), this);
+ helper.CountSloppyFrames(*fun);
+
Handle<Code> code = handle(exit_frame->LookupCode(), this);
- const int offset =
+ int offset =
static_cast<int>(exit_frame->pc() - code->instruction_start());
- int flags = 0;
- if (helper.IsStrictFrame(*fun)) flags |= StackTraceFrame::kIsStrict;
- if (exit_frame->IsConstructor())
- flags |= StackTraceFrame::kForceConstructor;
-
- Handle<StackTraceFrame> callsite = factory()->NewStackTraceFrame();
- callsite->set_flags(flags);
- callsite->set_receiver(*recv);
- callsite->set_function(*fun);
- callsite->set_abstract_code(AbstractCode::cast(*code));
- callsite->set_offset(offset);
-
- elements = MaybeGrow(this, elements, cursor, cursor + 1);
- elements->set(cursor++, *callsite);
+ // 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);
+ }
+
+ elements = MaybeGrow(this, elements, cursor, cursor + 4);
+ elements->set(cursor++, *recv);
+ elements->set(cursor++, *fun);
+ elements->set(cursor++, *code);
+ elements->set(cursor++, Smi::FromInt(offset));
+ frames_seen++;
} break;
case StackFrame::WASM: {
@@ -546,34 +544,24 @@
Code* code = wasm_frame->unchecked_code();
Handle<AbstractCode> abstract_code =
Handle<AbstractCode>(AbstractCode::cast(code), this);
- const int offset =
+ int offset =
static_cast<int>(wasm_frame->pc() - code->instruction_start());
-
- // TODO(wasm): The wasm object returned by the WasmFrame should always
- // be a wasm object.
- DCHECK(wasm::IsWasmObject(wasm_frame->wasm_obj()) ||
- wasm_frame->wasm_obj()->IsUndefined(this));
-
- Handle<StackTraceFrame> callsite = factory()->NewStackTraceFrame();
- callsite->set_flags(StackTraceFrame::kIsWasmFrame);
- callsite->set_wasm_object(wasm_frame->wasm_obj());
- callsite->set_wasm_function_index(wasm_frame->function_index());
- callsite->set_abstract_code(*abstract_code);
- callsite->set_offset(offset);
-
- elements = MaybeGrow(this, elements, cursor, cursor + 1);
- elements->set(cursor++, *callsite);
+ elements = MaybeGrow(this, elements, cursor, cursor + 4);
+ elements->set(cursor++, wasm_frame->wasm_obj());
+ elements->set(cursor++, Smi::FromInt(wasm_frame->function_index()));
+ elements->set(cursor++, *abstract_code);
+ elements->set(cursor++, Smi::FromInt(offset));
+ frames_seen++;
} break;
default:
break;
}
}
-
+ elements->set(0, Smi::FromInt(helper.sloppy_frames()));
elements->Shrink(cursor);
Handle<JSArray> result = factory()->NewJSArrayWithElements(elements);
result->set_length(Smi::FromInt(cursor));
-
// TODO(yangguo): Queue this structured stack trace for preprocessing on GC.
return result;
}
@@ -781,6 +769,19 @@
Handle<String> eval_key_;
Handle<String> constructor_key_;
};
+
+
+int PositionFromStackTrace(Handle<FixedArray> elements, int index) {
+ DisallowHeapAllocation no_gc;
+ Object* maybe_code = elements->get(index + 2);
+ if (maybe_code->IsSmi()) {
+ return Smi::cast(maybe_code)->value();
+ } else {
+ AbstractCode* abstract_code = AbstractCode::cast(maybe_code);
+ int code_offset = Smi::cast(elements->get(index + 3))->value();
+ return abstract_code->SourcePosition(code_offset);
+ }
+}
Handle<JSArray> Isolate::CaptureCurrentStackTrace(
int frame_limit, StackTrace::StackTraceOptions options) {
@@ -1426,26 +1427,36 @@
void Isolate::PrintCurrentStackTrace(FILE* out) {
- for (StackTraceFrameIterator it(this); !it.done(); it.Advance()) {
- if (!it.is_javascript()) continue;
-
+ StackTraceFrameIterator it(this);
+ while (!it.done()) {
HandleScope scope(this);
- JavaScriptFrame* frame = it.javascript_frame();
-
// Find code position if recorded in relocation info.
- AbstractCode* abstract_code = AbstractCode::cast(frame->LookupCode());
- const int code_offset =
- static_cast<int>(frame->pc() - abstract_code->instruction_start());
-
- Handle<StackTraceFrame> st_frame = factory()->NewStackTraceFrame();
-
- st_frame->set_receiver(frame->receiver());
- st_frame->set_function(frame->function());
- st_frame->set_abstract_code(abstract_code);
- st_frame->set_offset(code_offset);
-
+ StandardFrame* frame = it.frame();
+ AbstractCode* abstract_code;
+ int code_offset;
+ if (frame->is_interpreted()) {
+ InterpretedFrame* iframe = reinterpret_cast<InterpretedFrame*>(frame);
+ abstract_code = AbstractCode::cast(iframe->GetBytecodeArray());
+ code_offset = iframe->GetBytecodeOffset();
+ } else {
+ DCHECK(frame->is_java_script() || frame->is_wasm());
+ Code* code = frame->LookupCode();
+ abstract_code = AbstractCode::cast(code);
+ code_offset = static_cast<int>(frame->pc() - code->instruction_start());
+ }
+ int pos = abstract_code->SourcePosition(code_offset);
+ JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame);
+ Handle<Object> pos_obj(Smi::FromInt(pos), this);
+ // Fetch function and receiver.
+ Handle<JSFunction> fun(js_frame->function(), this);
+ Handle<Object> recv(js_frame->receiver(), this);
+ // Advance to the next JavaScript frame and determine if the
+ // current frame is the top-level frame.
+ it.Advance();
+ Handle<Object> is_top_level = factory()->ToBoolean(it.done());
// Generate and print stack trace line.
- Handle<String> line = st_frame->ToString();
+ Handle<String> line =
+ Execution::GetStackTraceLine(recv, fun, pos_obj, is_top_level);
if (line->length() > 0) {
line->PrintOn(out);
PrintF(out, "\n");
@@ -1514,24 +1525,21 @@
Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property);
Handle<FixedArray> elements(FixedArray::cast(simple_stack_trace->elements()));
- const int elements_limit = Smi::cast(simple_stack_trace->length())->value();
-
- for (int i = 0; i < elements_limit; i++) {
- DCHECK(elements->get(i)->IsStackTraceFrame());
- Handle<StackTraceFrame> frame(StackTraceFrame::cast(elements->get(i)));
-
- if (frame->IsWasmFrame()) {
+ int elements_limit = Smi::cast(simple_stack_trace->length())->value();
+
+ for (int i = 1; i < elements_limit; i += 4) {
+ Handle<Object> fun_obj = handle(elements->get(i + 1), this);
+ if (fun_obj->IsSmi()) {
// TODO(clemensh): handle wasm frames
return false;
}
-
- Handle<JSFunction> fun = handle(frame->function());
+ Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj);
if (!fun->shared()->IsSubjectToDebugging()) continue;
Object* script = fun->shared()->script();
if (script->IsScript() &&
!(Script::cast(script)->source()->IsUndefined(this))) {
- const int pos = frame->GetPosition();
+ int pos = PositionFromStackTrace(elements, i);
Handle<Script> casted_script(Script::cast(script));
*target = MessageLocation(casted_script, pos, pos + 1);
return true;
« no previous file with comments | « src/heap-symbols.h ('k') | src/messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698