| Index: src/heap.cc
|
| diff --git a/src/heap.cc b/src/heap.cc
|
| index 66512931698aa582f80a6fd39b60b50ec4095f04..ec98ca5267aa3f113f33b47ed83ff8b553c9d015 100644
|
| --- a/src/heap.cc
|
| +++ b/src/heap.cc
|
| @@ -7293,36 +7293,41 @@ void ErrorObjectList::DeferredFormatStackTrace(Isolate* isolate) {
|
| int budget = kBudgetPerGC;
|
| for (int i = 0; i < list_.length(); i++) {
|
| Object* object = list_[i];
|
| - // Skip possible holes in the list.
|
| - if (object->IsTheHole()) continue;
|
| - if (isolate->heap()->InNewSpace(object) || budget == 0) {
|
| - list_[write_index++] = object;
|
| - continue;
|
| + JSFunction* getter_fun;
|
| +
|
| + { AssertNoAllocation assert;
|
| + // Skip possible holes in the list.
|
| + if (object->IsTheHole()) continue;
|
| + if (isolate->heap()->InNewSpace(object) || budget == 0) {
|
| + list_[write_index++] = object;
|
| + continue;
|
| + }
|
| +
|
| + // Check whether the stack property is backed by the original getter.
|
| + LookupResult lookup(isolate);
|
| + JSObject::cast(object)->LocalLookupRealNamedProperty(*stack_key, &lookup);
|
| + if (!lookup.IsFound() || lookup.type() != CALLBACKS) continue;
|
| + Object* callback = lookup.GetCallbackObject();
|
| + if (!callback->IsAccessorPair()) continue;
|
| + Object* getter_obj = AccessorPair::cast(callback)->getter();
|
| + if (!getter_obj->IsJSFunction()) continue;
|
| + getter_fun = JSFunction::cast(getter_obj);
|
| + String* key = isolate->heap()->hidden_stack_trace_symbol();
|
| + if (key != getter_fun->GetHiddenProperty(key)) continue;
|
| }
|
|
|
| - // Fire the stack property getter, if it is the original marked getter.
|
| - LookupResult lookup(isolate);
|
| - JSObject::cast(object)->LocalLookupRealNamedProperty(*stack_key, &lookup);
|
| - if (!lookup.IsFound() || lookup.type() != CALLBACKS) continue;
|
| - Object* callback = lookup.GetCallbackObject();
|
| - if (!callback->IsAccessorPair()) continue;
|
| - Object* getter_obj = AccessorPair::cast(callback)->getter();
|
| - if (!getter_obj->IsJSFunction()) continue;
|
| - JSFunction* getter_fun = JSFunction::cast(getter_obj);
|
| - String* key = isolate->heap()->hidden_stack_trace_symbol();
|
| - if (key != getter_fun->GetHiddenProperty(key)) continue;
|
| budget--;
|
| + HandleScope scope(isolate);
|
| bool has_exception = false;
|
| - Execution::Call(Handle<Object>(getter_fun, isolate),
|
| - Handle<Object>(object, isolate),
|
| - 0,
|
| - NULL,
|
| - &has_exception);
|
| + Handle<Object> object_handle(object, isolate);
|
| + Handle<Object> getter_handle(getter_fun, isolate);
|
| + Execution::Call(getter_handle, object_handle, 0, NULL, &has_exception);
|
| if (has_exception) {
|
| // Hit an exception (most likely a stack overflow).
|
| // Wrap up this pass and retry after another GC.
|
| isolate->clear_pending_exception();
|
| - list_[write_index++] = object;
|
| + // We use the handle since calling the getter might have caused a GC.
|
| + list_[write_index++] = *object_handle;
|
| budget = 0;
|
| }
|
| }
|
|
|