Index: src/isolate.cc |
diff --git a/src/isolate.cc b/src/isolate.cc |
index 624f2a8d93be453c855f272ef982d08cb69d7cf8..17d5746b74ae2e82f0d678fc705632aea545285a 100644 |
--- a/src/isolate.cc |
+++ b/src/isolate.cc |
@@ -315,21 +315,7 @@ void Isolate::PushStackTraceAndDie(unsigned int magic, void* ptr1, void* ptr2, |
base::OS::Abort(); |
} |
-static Handle<FixedArray> MaybeGrow(Isolate* isolate, |
- Handle<FixedArray> elements, |
- int cur_position, int new_size) { |
- if (new_size > elements->length()) { |
- int new_capacity = JSObject::NewElementsCapacity(elements->length()); |
- Handle<FixedArray> new_elements = |
- isolate->factory()->NewFixedArrayWithHoles(new_capacity); |
- for (int i = 0; i < cur_position; i++) { |
- new_elements->set(i, elements->get(i)); |
- } |
- elements = new_elements; |
- } |
- DCHECK(new_size <= elements->length()); |
- return elements; |
-} |
+namespace { |
class StackTraceHelper { |
public: |
@@ -435,8 +421,6 @@ class StackTraceHelper { |
bool encountered_strict_function_; |
}; |
-namespace { |
- |
// TODO(jgruber): Fix all cases in which frames give us a hole value (e.g. the |
// receiver in RegExp constructor frames. |
Handle<Object> TheHoleToUndefined(Isolate* isolate, Handle<Object> in) { |
@@ -444,7 +428,8 @@ Handle<Object> TheHoleToUndefined(Isolate* isolate, Handle<Object> in) { |
? Handle<Object>::cast(isolate->factory()->undefined_value()) |
: in; |
} |
-} |
+ |
+} // namespace |
Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object, |
FrameSkipMode mode, |
@@ -463,13 +448,10 @@ Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object, |
limit = Max(limit, 0); // Ensure that limit is not negative. |
int initial_size = Min(limit, 10); |
- Handle<FixedArray> elements = |
- factory()->NewFixedArrayWithHoles(initial_size * 4 + 1); |
+ Handle<FrameArray> elements = FrameArray::Allocate(this, initial_size); |
StackTraceHelper helper(this, mode, caller); |
- // First element is reserved to store the number of sloppy frames. |
- int cursor = 1; |
int frames_seen = 0; |
Toon Verwaest
2016/08/23 13:14:08
Perhaps we should just encapsulate frames_seen as
jgruber
2016/08/23 15:32:13
Done.
|
for (StackFrameIterator iter(this); !iter.done() && frames_seen < limit; |
iter.Advance()) { |
@@ -502,13 +484,11 @@ Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object, |
recv = handle(heap()->call_site_constructor_symbol(), this); |
} |
} |
- Handle<Smi> offset(Smi::FromInt(frames[i].code_offset()), this); |
+ const int offset = frames[i].code_offset(); |
- 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); |
+ elements = FrameArray::AppendJSFrame(elements, frames_seen, |
+ TheHoleToUndefined(this, recv), |
+ fun, abstract_code, offset); |
frames_seen++; |
} |
} break; |
@@ -534,26 +514,30 @@ Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object, |
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)); |
+ elements = |
+ FrameArray::AppendJSFrame(elements, frames_seen, recv, fun, |
+ Handle<AbstractCode>::cast(code), offset); |
frames_seen++; |
} break; |
case StackFrame::WASM: { |
WasmFrame* wasm_frame = WasmFrame::cast(frame); |
+ Handle<Object> wasm_object = handle(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); |
- int offset = |
+ const int offset = |
static_cast<int>(wasm_frame->pc() - code->instruction_start()); |
- 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)); |
+ |
+ // TODO(wasm): The wasm object returned by the WasmFrame should always |
+ // be a wasm object. |
+ DCHECK(wasm::IsWasmObject(*wasm_object) || |
+ wasm_object->IsUndefined(this)); |
+ |
+ elements = FrameArray::AppendWasmFrame(elements, frames_seen, |
+ wasm_object, wasm_function_index, |
+ abstract_code, offset); |
frames_seen++; |
} break; |
@@ -562,9 +546,13 @@ Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object, |
} |
} |
elements->set(0, Smi::FromInt(helper.sloppy_frames())); |
- elements->Shrink(cursor); |
+ |
+ const int elements_length = FrameArray::LengthFor(frames_seen); |
Toon Verwaest
2016/08/23 13:14:08
What about elements->Shrink(frames_seen) to avoid
jgruber
2016/08/23 15:32:13
Done.
|
+ elements->Shrink(elements_length); |
+ |
Handle<JSArray> result = factory()->NewJSArrayWithElements(elements); |
- result->set_length(Smi::FromInt(cursor)); |
+ result->set_length(Smi::FromInt(elements_length)); |
+ |
// TODO(yangguo): Queue this structured stack trace for preprocessing on GC. |
return result; |
} |
@@ -773,19 +761,6 @@ class CaptureStackTraceHelper { |
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) { |
DisallowJavascriptExecution no_js(this); |
@@ -1531,22 +1506,25 @@ bool Isolate::ComputeLocationFromStackTrace(MessageLocation* target, |
if (!property->IsJSArray()) return false; |
Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property); |
- Handle<FixedArray> elements(FixedArray::cast(simple_stack_trace->elements())); |
- int elements_limit = Smi::cast(simple_stack_trace->length())->value(); |
+ Handle<FrameArray> elements(FrameArray::cast(simple_stack_trace->elements())); |
- for (int i = 1; i < elements_limit; i += 4) { |
- Handle<Object> fun_obj = handle(elements->get(i + 1), this); |
- if (fun_obj->IsSmi()) { |
+ const int frame_count = elements->FrameCount(); |
+ for (int i = 0; i < frame_count; i++) { |
+ if (elements->IsWasmFrame(i)) { |
// TODO(clemensh): handle wasm frames |
return false; |
} |
- Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj); |
+ |
+ Handle<JSFunction> fun = handle(elements->Function(i), this); |
if (!fun->shared()->IsSubjectToDebugging()) continue; |
Object* script = fun->shared()->script(); |
if (script->IsScript() && |
!(Script::cast(script)->source()->IsUndefined(this))) { |
- int pos = PositionFromStackTrace(elements, i); |
+ AbstractCode* abstract_code = elements->Code(i); |
+ const int code_offset = elements->Offset(i)->value(); |
+ const int pos = abstract_code->SourcePosition(code_offset); |
+ |
Handle<Script> casted_script(Script::cast(script)); |
*target = MessageLocation(casted_script, pos, pos + 1); |
return true; |