From c26d100b104efee097200d23e871a20c90251f64 Mon Sep 17 00:00:00 2001 From: "svenpanne@chromium.org" Date: Wed, 27 Feb 2013 13:22:29 +0000 Subject: [PATCH] Avoid TLS accesses in Object::Lookup and Object::GetPrototype. Both methods were among the top causes for TLS accesses. BUG=v8:2487 Review URL: https://codereview.chromium.org/12319144 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13759 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/accessors.cc | 48 ++++++++++++++++++-------------- src/api.cc | 2 +- src/arm/stub-cache-arm.cc | 16 ++++++----- src/builtins.cc | 2 +- src/handles.cc | 2 +- src/hydrogen.cc | 6 ++-- src/ia32/stub-cache-ia32.cc | 16 ++++++----- src/ic-inl.h | 7 +++-- src/ic.cc | 7 +++-- src/ic.h | 3 +- src/isolate.cc | 2 +- src/mips/stub-cache-mips.cc | 16 ++++++----- src/objects.cc | 68 ++++++++++++++++++++++++--------------------- src/objects.h | 2 +- src/property.h | 8 ++++-- src/runtime.cc | 15 +++++----- src/string-stream.cc | 8 ++++-- src/stub-cache.cc | 42 ++++++++++++++++++---------- src/x64/stub-cache-x64.cc | 16 ++++++----- 19 files changed, 166 insertions(+), 120 deletions(-) diff --git a/src/accessors.cc b/src/accessors.cc index 942009a8..3dcf422 100644 --- a/src/accessors.cc +++ b/src/accessors.cc @@ -42,8 +42,8 @@ namespace internal { template -static C* FindInstanceOf(Object* obj) { - for (Object* cur = obj; !cur->IsNull(); cur = cur->GetPrototype()) { +static C* FindInstanceOf(Isolate* isolate, Object* obj) { + for (Object* cur = obj; !cur->IsNull(); cur = cur->GetPrototype(isolate)) { if (Is(cur)) return C::cast(cur); } return NULL; @@ -77,7 +77,7 @@ MaybeObject* Accessors::ReadOnlySetAccessor(JSObject*, Object* value, void*) { MaybeObject* Accessors::ArrayGetLength(Object* object, void*) { // Traverse the prototype chain until we reach an array. - JSArray* holder = FindInstanceOf(object); + JSArray* holder = FindInstanceOf(Isolate::Current(), object); return holder == NULL ? Smi::FromInt(0) : holder->length(); } @@ -442,18 +442,19 @@ const AccessorDescriptor Accessors::ScriptEvalFromFunctionName = { MaybeObject* Accessors::FunctionGetPrototype(Object* object, void*) { - Heap* heap = Isolate::Current()->heap(); - JSFunction* function = FindInstanceOf(object); - if (function == NULL) return heap->undefined_value(); + Isolate* isolate = Isolate::Current(); + JSFunction* function = FindInstanceOf(isolate, object); + if (function == NULL) return isolate->heap()->undefined_value(); while (!function->should_have_prototype()) { - function = FindInstanceOf(function->GetPrototype()); + function = FindInstanceOf(isolate, function->GetPrototype()); // There has to be one because we hit the getter. ASSERT(function != NULL); } if (!function->has_prototype()) { Object* prototype; - { MaybeObject* maybe_prototype = heap->AllocateFunctionPrototype(function); + { MaybeObject* maybe_prototype + = isolate->heap()->AllocateFunctionPrototype(function); if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype; } Object* result; @@ -470,7 +471,7 @@ MaybeObject* Accessors::FunctionSetPrototype(JSObject* object, void*) { Isolate* isolate = object->GetIsolate(); Heap* heap = isolate->heap(); - JSFunction* function_raw = FindInstanceOf(object); + JSFunction* function_raw = FindInstanceOf(isolate, object); if (function_raw == NULL) return heap->undefined_value(); if (!function_raw->should_have_prototype()) { // Since we hit this accessor, object will have no prototype property. @@ -522,7 +523,8 @@ const AccessorDescriptor Accessors::FunctionPrototype = { MaybeObject* Accessors::FunctionGetLength(Object* object, void*) { - JSFunction* function = FindInstanceOf(object); + Isolate* isolate = Isolate::Current(); + JSFunction* function = FindInstanceOf(isolate, object); if (function == NULL) return Smi::FromInt(0); // Check if already compiled. if (function->shared()->is_compiled()) { @@ -530,7 +532,7 @@ MaybeObject* Accessors::FunctionGetLength(Object* object, void*) { } // If the function isn't compiled yet, the length is not computed correctly // yet. Compile it now and return the right length. - HandleScope scope(function->GetIsolate()); + HandleScope scope(isolate); Handle handle(function); if (JSFunction::CompileLazy(handle, KEEP_EXCEPTION)) { return Smi::FromInt(handle->shared()->length()); @@ -552,8 +554,11 @@ const AccessorDescriptor Accessors::FunctionLength = { MaybeObject* Accessors::FunctionGetName(Object* object, void*) { - JSFunction* holder = FindInstanceOf(object); - return holder == NULL ? HEAP->undefined_value() : holder->shared()->name(); + Isolate* isolate = Isolate::Current(); + JSFunction* holder = FindInstanceOf(isolate, object); + return holder == NULL + ? isolate->heap()->undefined_value() + : holder->shared()->name(); } @@ -599,7 +604,7 @@ static MaybeObject* ConstructArgumentsObjectForInlinedFunction( MaybeObject* Accessors::FunctionGetArguments(Object* object, void*) { Isolate* isolate = Isolate::Current(); HandleScope scope(isolate); - JSFunction* holder = FindInstanceOf(object); + JSFunction* holder = FindInstanceOf(isolate, object); if (holder == NULL) return isolate->heap()->undefined_value(); Handle function(holder, isolate); @@ -723,7 +728,7 @@ MaybeObject* Accessors::FunctionGetCaller(Object* object, void*) { Isolate* isolate = Isolate::Current(); HandleScope scope(isolate); AssertNoAllocation no_alloc; - JSFunction* holder = FindInstanceOf(object); + JSFunction* holder = FindInstanceOf(isolate, object); if (holder == NULL) return isolate->heap()->undefined_value(); if (holder->shared()->native()) return isolate->heap()->null_value(); Handle function(holder, isolate); @@ -782,18 +787,19 @@ const AccessorDescriptor Accessors::FunctionCaller = { // -static inline Object* GetPrototypeSkipHiddenPrototypes(Object* receiver) { - Object* current = receiver->GetPrototype(); +static inline Object* GetPrototypeSkipHiddenPrototypes(Isolate* isolate, + Object* receiver) { + Object* current = receiver->GetPrototype(isolate); while (current->IsJSObject() && JSObject::cast(current)->map()->is_hidden_prototype()) { - current = current->GetPrototype(); + current = current->GetPrototype(isolate); } return current; } MaybeObject* Accessors::ObjectGetPrototype(Object* receiver, void*) { - return GetPrototypeSkipHiddenPrototypes(receiver); + return GetPrototypeSkipHiddenPrototypes(Isolate::Current(), receiver); } @@ -809,14 +815,14 @@ MaybeObject* Accessors::ObjectSetPrototype(JSObject* receiver_raw, HandleScope scope(isolate); Handle receiver(receiver_raw); Handle value(value_raw, isolate); - Handle old_value(GetPrototypeSkipHiddenPrototypes(*receiver), + Handle old_value(GetPrototypeSkipHiddenPrototypes(isolate, *receiver), isolate); MaybeObject* result = receiver->SetPrototype(*value, kSkipHiddenPrototypes); Handle hresult; if (!result->ToHandle(&hresult, isolate)) return result; - Handle new_value(GetPrototypeSkipHiddenPrototypes(*receiver), + Handle new_value(GetPrototypeSkipHiddenPrototypes(isolate, *receiver), isolate); if (!new_value->SameValue(*old_value)) { JSObject::EnqueueChangeRecord(receiver, "prototype", diff --git a/src/api.cc b/src/api.cc index 1860e50..430524d 100644 --- a/src/api.cc +++ b/src/api.cc @@ -2959,7 +2959,7 @@ Local v8::Object::GetPrototype() { return Local()); ENTER_V8(isolate); i::Handle self = Utils::OpenHandle(this); - i::Handle result(self->GetPrototype(), isolate); + i::Handle result(self->GetPrototype(isolate), isolate); return Utils::ToLocal(result); } diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index b652fc0..f979513 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -1945,8 +1945,9 @@ Handle CallStubCompiler::CompileStringCharCodeAtCall( r0, &miss); ASSERT(!object.is_identical_to(holder)); - CheckPrototypes(Handle(JSObject::cast(object->GetPrototype())), - r0, holder, r1, r3, r4, name, &miss); + CheckPrototypes( + Handle(JSObject::cast(object->GetPrototype(isolate()))), + r0, holder, r1, r3, r4, name, &miss); Register receiver = r1; Register index = r4; @@ -2025,8 +2026,9 @@ Handle CallStubCompiler::CompileStringCharAtCall( r0, &miss); ASSERT(!object.is_identical_to(holder)); - CheckPrototypes(Handle(JSObject::cast(object->GetPrototype())), - r0, holder, r1, r3, r4, name, &miss); + CheckPrototypes( + Handle(JSObject::cast(object->GetPrototype(isolate()))), + r0, holder, r1, r3, r4, name, &miss); Register receiver = r0; Register index = r4; @@ -2490,7 +2492,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle object, GenerateDirectLoadGlobalFunctionPrototype( masm(), Context::STRING_FUNCTION_INDEX, r0, &miss); CheckPrototypes( - Handle(JSObject::cast(object->GetPrototype())), + Handle(JSObject::cast(object->GetPrototype(isolate()))), r0, holder, r3, r1, r4, name, &miss); break; @@ -2505,7 +2507,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle object, GenerateDirectLoadGlobalFunctionPrototype( masm(), Context::NUMBER_FUNCTION_INDEX, r0, &miss); CheckPrototypes( - Handle(JSObject::cast(object->GetPrototype())), + Handle(JSObject::cast(object->GetPrototype(isolate()))), r0, holder, r3, r1, r4, name, &miss); break; } @@ -2523,7 +2525,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle object, GenerateDirectLoadGlobalFunctionPrototype( masm(), Context::BOOLEAN_FUNCTION_INDEX, r0, &miss); CheckPrototypes( - Handle(JSObject::cast(object->GetPrototype())), + Handle(JSObject::cast(object->GetPrototype(isolate()))), r0, holder, r3, r1, r4, name, &miss); break; } diff --git a/src/builtins.cc b/src/builtins.cc index e404b51..279594e 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -1222,7 +1222,7 @@ static inline Object* FindHidden(Heap* heap, Object* object, FunctionTemplateInfo* type) { if (object->IsInstanceOf(type)) return object; - Object* proto = object->GetPrototype(); + Object* proto = object->GetPrototype(heap->isolate()); if (proto->IsJSObject() && JSObject::cast(proto)->map()->is_hidden_prototype()) { return FindHidden(heap, proto, type); diff --git a/src/handles.cc b/src/handles.cc index 9429334..5de9b6c 100644 --- a/src/handles.cc +++ b/src/handles.cc @@ -647,7 +647,7 @@ Handle GetKeysInFixedArrayFor(Handle object, // Only collect keys if access is permitted. for (Handle p = object; *p != isolate->heap()->null_value(); - p = Handle(p->GetPrototype(), isolate)) { + p = Handle(p->GetPrototype(isolate), isolate)) { if (p->IsJSProxy()) { Handle proxy(JSProxy::cast(*p), isolate); Handle args[] = { proxy }; diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 73287f4..ae94084 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -5989,8 +5989,10 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( proto = proto_result.holder(); } else { // Otherwise, find the top prototype. - while (proto->GetPrototype()->IsJSObject()) proto = proto->GetPrototype(); - ASSERT(proto->GetPrototype()->IsNull()); + while (proto->GetPrototype(isolate())->IsJSObject()) { + proto = proto->GetPrototype(isolate()); + } + ASSERT(proto->GetPrototype(isolate())->IsNull()); } ASSERT(proto->IsJSObject()); AddInstruction(new(zone()) HCheckPrototypeMaps( diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index 4b1cb5b..d7c4186 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -1874,8 +1874,9 @@ Handle CallStubCompiler::CompileStringCharCodeAtCall( eax, &miss); ASSERT(!object.is_identical_to(holder)); - CheckPrototypes(Handle(JSObject::cast(object->GetPrototype())), - eax, holder, ebx, edx, edi, name, &miss); + CheckPrototypes( + Handle(JSObject::cast(object->GetPrototype(isolate()))), + eax, holder, ebx, edx, edi, name, &miss); Register receiver = ebx; Register index = edi; @@ -1957,8 +1958,9 @@ Handle CallStubCompiler::CompileStringCharAtCall( eax, &miss); ASSERT(!object.is_identical_to(holder)); - CheckPrototypes(Handle(JSObject::cast(object->GetPrototype())), - eax, holder, ebx, edx, edi, name, &miss); + CheckPrototypes( + Handle(JSObject::cast(object->GetPrototype(isolate()))), + eax, holder, ebx, edx, edi, name, &miss); Register receiver = eax; Register index = edi; @@ -2422,7 +2424,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle object, GenerateDirectLoadGlobalFunctionPrototype( masm(), Context::STRING_FUNCTION_INDEX, eax, &miss); CheckPrototypes( - Handle(JSObject::cast(object->GetPrototype())), + Handle(JSObject::cast(object->GetPrototype(isolate()))), eax, holder, ebx, edx, edi, name, &miss); break; @@ -2437,7 +2439,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle object, GenerateDirectLoadGlobalFunctionPrototype( masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss); CheckPrototypes( - Handle(JSObject::cast(object->GetPrototype())), + Handle(JSObject::cast(object->GetPrototype(isolate()))), eax, holder, ebx, edx, edi, name, &miss); break; } @@ -2453,7 +2455,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle object, GenerateDirectLoadGlobalFunctionPrototype( masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss); CheckPrototypes( - Handle(JSObject::cast(object->GetPrototype())), + Handle(JSObject::cast(object->GetPrototype(isolate()))), eax, holder, ebx, edx, edi, name, &miss); break; } diff --git a/src/ic-inl.h b/src/ic-inl.h index 77f409a..11ab710 100644 --- a/src/ic-inl.h +++ b/src/ic-inl.h @@ -129,8 +129,11 @@ InlineCacheHolderFlag IC::GetCodeCacheForObject(JSObject* object, } -JSObject* IC::GetCodeCacheHolder(Object* object, InlineCacheHolderFlag holder) { - Object* map_owner = (holder == OWN_MAP ? object : object->GetPrototype()); +JSObject* IC::GetCodeCacheHolder(Isolate* isolate, + Object* object, + InlineCacheHolderFlag holder) { + Object* map_owner = + holder == OWN_MAP ? object : object->GetPrototype(isolate); ASSERT(map_owner->IsJSObject()); return JSObject::cast(map_owner); } diff --git a/src/ic.cc b/src/ic.cc index ee46961..c15b76f 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -174,16 +174,17 @@ static bool TryRemoveInvalidPrototypeDependentStub(Code* target, InlineCacheHolderFlag cache_holder = Code::ExtractCacheHolderFromFlags(target->flags()); + Isolate* isolate = target->GetIsolate(); if (cache_holder == OWN_MAP && !receiver->IsJSObject()) { // The stub was generated for JSObject but called for non-JSObject. // IC::GetCodeCacheHolder is not applicable. return false; } else if (cache_holder == PROTOTYPE_MAP && - receiver->GetPrototype()->IsNull()) { + receiver->GetPrototype(isolate)->IsNull()) { // IC::GetCodeCacheHolder is not applicable. return false; } - Map* map = IC::GetCodeCacheHolder(receiver, cache_holder)->map(); + Map* map = IC::GetCodeCacheHolder(isolate, receiver, cache_holder)->map(); // Decide whether the inline cache failed because of changes to the // receiver itself or changes to one of its prototypes. @@ -734,7 +735,7 @@ void CallICBase::UpdateCaches(LookupResult* lookup, // GenerateMonomorphicCacheProbe. It is not the map which holds the stub. Handle cache_object = object->IsJSObject() ? Handle::cast(object) - : Handle(JSObject::cast(object->GetPrototype())); + : Handle(JSObject::cast(object->GetPrototype(isolate()))); // Update the stub cache. UpdateMegamorphicCache(cache_object->map(), *name, *code); break; diff --git a/src/ic.h b/src/ic.h index 2e7367a..79c1baf 100644 --- a/src/ic.h +++ b/src/ic.h @@ -129,7 +129,8 @@ class IC { JSObject* holder); static inline InlineCacheHolderFlag GetCodeCacheForObject(JSObject* object, JSObject* holder); - static inline JSObject* GetCodeCacheHolder(Object* object, + static inline JSObject* GetCodeCacheHolder(Isolate* isolate, + Object* object, InlineCacheHolderFlag holder); protected: diff --git a/src/isolate.cc b/src/isolate.cc index 49a3dcc..e69743b 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -1192,7 +1192,7 @@ bool Isolate::IsErrorObject(Handle obj) { js_builtins_object()->GetPropertyNoExceptionThrown(error_key); for (Object* prototype = *obj; !prototype->IsNull(); - prototype = prototype->GetPrototype()) { + prototype = prototype->GetPrototype(this)) { if (!prototype->IsJSObject()) return false; if (JSObject::cast(prototype)->map()->constructor() == error_constructor) { return true; diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc index 24474cf..649751f 100644 --- a/src/mips/stub-cache-mips.cc +++ b/src/mips/stub-cache-mips.cc @@ -1946,8 +1946,9 @@ Handle CallStubCompiler::CompileStringCharCodeAtCall( v0, &miss); ASSERT(!object.is_identical_to(holder)); - CheckPrototypes(Handle(JSObject::cast(object->GetPrototype())), - v0, holder, a1, a3, t0, name, &miss); + CheckPrototypes( + Handle(JSObject::cast(object->GetPrototype(isolate()))), + v0, holder, a1, a3, t0, name, &miss); Register receiver = a1; Register index = t1; @@ -2026,8 +2027,9 @@ Handle CallStubCompiler::CompileStringCharAtCall( v0, &miss); ASSERT(!object.is_identical_to(holder)); - CheckPrototypes(Handle(JSObject::cast(object->GetPrototype())), - v0, holder, a1, a3, t0, name, &miss); + CheckPrototypes( + Handle(JSObject::cast(object->GetPrototype(isolate()))), + v0, holder, a1, a3, t0, name, &miss); Register receiver = v0; Register index = t1; @@ -2483,7 +2485,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle object, GenerateDirectLoadGlobalFunctionPrototype( masm(), Context::STRING_FUNCTION_INDEX, a0, &miss); CheckPrototypes( - Handle(JSObject::cast(object->GetPrototype())), + Handle(JSObject::cast(object->GetPrototype(isolate()))), a0, holder, a3, a1, t0, name, &miss); break; @@ -2498,7 +2500,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle object, GenerateDirectLoadGlobalFunctionPrototype( masm(), Context::NUMBER_FUNCTION_INDEX, a0, &miss); CheckPrototypes( - Handle(JSObject::cast(object->GetPrototype())), + Handle(JSObject::cast(object->GetPrototype(isolate()))), a0, holder, a3, a1, t0, name, &miss); break; } @@ -2514,7 +2516,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle object, GenerateDirectLoadGlobalFunctionPrototype( masm(), Context::BOOLEAN_FUNCTION_INDEX, a0, &miss); CheckPrototypes( - Handle(JSObject::cast(object->GetPrototype())), + Handle(JSObject::cast(object->GetPrototype(isolate()))), a0, holder, a3, a1, t0, name, &miss); break; } diff --git a/src/objects.cc b/src/objects.cc index 5f83f73..8be7be3 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -135,7 +135,7 @@ void Object::Lookup(String* name, LookupResult* result) { if (IsJSReceiver()) { holder = this; } else { - Context* native_context = Isolate::Current()->context()->native_context(); + Context* native_context = result->isolate()->context()->native_context(); if (IsNumber()) { holder = native_context->number_function()->instance_prototype(); } else if (IsString()) { @@ -613,7 +613,8 @@ MaybeObject* Object::GetProperty(Object* receiver, // Make sure that the top context does not change when doing // callbacks or interceptor calls. AssertNoContextChange ncc; - Heap* heap = name->GetHeap(); + Isolate* isolate = name->GetIsolate(); + Heap* heap = isolate->heap(); // Traverse the prototype chain from the current object (this) to // the holder and check for access rights. This avoids traversing the @@ -626,8 +627,10 @@ MaybeObject* Object::GetProperty(Object* receiver, Object* last = result->IsProperty() ? result->holder() : Object::cast(heap->null_value()); - ASSERT(this != this->GetPrototype()); - for (Object* current = this; true; current = current->GetPrototype()) { + ASSERT(this != this->GetPrototype(isolate)); + for (Object* current = this; + true; + current = current->GetPrototype(isolate)) { if (current->IsAccessCheckNeeded()) { // Check if we're allowed to read from the current object. Note // that even though we may not actually end up loading the named @@ -687,18 +690,18 @@ MaybeObject* Object::GetProperty(Object* receiver, MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { - Heap* heap = IsSmi() - ? Isolate::Current()->heap() - : HeapObject::cast(this)->GetHeap(); + Isolate* isolate = IsSmi() + ? Isolate::Current() + : HeapObject::cast(this)->GetIsolate(); + Heap* heap = isolate->heap(); Object* holder = this; // Iterate up the prototype chain until an element is found or the null // prototype is encountered. for (holder = this; holder != heap->null_value(); - holder = holder->GetPrototype()) { + holder = holder->GetPrototype(isolate)) { if (!holder->IsJSObject()) { - Isolate* isolate = heap->isolate(); Context* native_context = isolate->context()->native_context(); if (holder->IsNumber()) { holder = native_context->number_function()->instance_prototype(); @@ -744,10 +747,9 @@ MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { } -Object* Object::GetPrototype() { +Object* Object::GetPrototype(Isolate* isolate) { if (IsSmi()) { - Heap* heap = Isolate::Current()->heap(); - Context* context = heap->isolate()->context()->native_context(); + Context* context = isolate->context()->native_context(); return context->number_function()->instance_prototype(); } @@ -758,8 +760,7 @@ Object* Object::GetPrototype() { if (heap_object->IsJSReceiver()) { return heap_object->map()->prototype(); } - Heap* heap = heap_object->GetHeap(); - Context* context = heap->isolate()->context()->native_context(); + Context* context = isolate->context()->native_context(); if (heap_object->IsHeapNumber()) { return context->number_function()->instance_prototype(); @@ -770,7 +771,7 @@ Object* Object::GetPrototype() { if (heap_object->IsBoolean()) { return context->boolean_function()->instance_prototype(); } else { - return heap->null_value(); + return isolate->heap()->null_value(); } } @@ -2100,10 +2101,10 @@ MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( Heap* heap = GetHeap(); for (Object* pt = GetPrototype(); pt != heap->null_value(); - pt = pt->GetPrototype()) { + pt = pt->GetPrototype(GetIsolate())) { if (pt->IsJSProxy()) { String* name; - MaybeObject* maybe = GetHeap()->Uint32ToString(index); + MaybeObject* maybe = heap->Uint32ToString(index); if (!maybe->To(&name)) { *found = true; // Force abort return maybe; @@ -2503,10 +2504,11 @@ void JSObject::LookupRealNamedProperty(String* name, LookupResult* result) { void JSObject::LookupRealNamedPropertyInPrototypes(String* name, LookupResult* result) { - Heap* heap = GetHeap(); + Isolate* isolate = GetIsolate(); + Heap* heap = isolate->heap(); for (Object* pt = GetPrototype(); pt != heap->null_value(); - pt = pt->GetPrototype()) { + pt = pt->GetPrototype(isolate)) { if (pt->IsJSProxy()) { return result->HandlerResult(JSProxy::cast(pt)); } @@ -8149,13 +8151,14 @@ bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) { return false; } - Heap* heap = GetHeap(); + Isolate* isolate = GetIsolate(); + Heap* heap = isolate->heap(); // Traverse the proposed prototype chain looking for properties of the // same names as are set by the inline constructor. for (Object* obj = prototype; obj != heap->null_value(); - obj = obj->GetPrototype()) { + obj = obj->GetPrototype(isolate)) { JSReceiver* receiver = JSReceiver::cast(obj); for (int i = 0; i < this_property_assignments_count(); i++) { LookupResult result(heap->isolate()); @@ -9611,7 +9614,8 @@ MaybeObject* JSReceiver::SetPrototype(Object* value, int size = Size(); #endif - Heap* heap = GetHeap(); + Isolate* isolate = GetIsolate(); + Heap* heap = isolate->heap(); // Silently ignore the change if value is not a JSObject or null. // SpiderMonkey behaves this way. if (!value->IsJSReceiver() && !value->IsNull()) return value; @@ -9625,22 +9629,24 @@ MaybeObject* JSReceiver::SetPrototype(Object* value, // or [[Extensible]] must not violate the invariants defined in the preceding // paragraph. if (!this->map()->is_extensible()) { - HandleScope scope(heap->isolate()); - Handle handle(this, heap->isolate()); - return heap->isolate()->Throw( - *FACTORY->NewTypeError("non_extensible_proto", - HandleVector(&handle, 1))); + HandleScope scope(isolate); + Handle handle(this, isolate); + return isolate->Throw( + *isolate->factory()->NewTypeError("non_extensible_proto", + HandleVector(&handle, 1))); } // Before we can set the prototype we need to be sure // prototype cycles are prevented. // It is sufficient to validate that the receiver is not in the new prototype // chain. - for (Object* pt = value; pt != heap->null_value(); pt = pt->GetPrototype()) { + for (Object* pt = value; + pt != heap->null_value(); + pt = pt->GetPrototype(isolate)) { if (JSReceiver::cast(pt) == this) { // Cycle detected. - HandleScope scope(heap->isolate()); - return heap->isolate()->Throw( + HandleScope scope(isolate); + return isolate->Throw( *FACTORY->NewError("cyclic_proto", HandleVector(NULL, 0))); } } @@ -9654,7 +9660,7 @@ MaybeObject* JSReceiver::SetPrototype(Object* value, while (current_proto->IsJSObject() && JSReceiver::cast(current_proto)->map()->is_hidden_prototype()) { real_receiver = JSReceiver::cast(current_proto); - current_proto = current_proto->GetPrototype(); + current_proto = current_proto->GetPrototype(isolate); } } diff --git a/src/objects.h b/src/objects.h index f2407f8..914a245 100644 --- a/src/objects.h +++ b/src/objects.h @@ -1019,7 +1019,7 @@ class Object : public MaybeObject { uint32_t index); // Return the object's prototype (might be Heap::null_value()). - Object* GetPrototype(); + Object* GetPrototype(Isolate* isolate); // Returns the permanent hash code associated with this object depending on // the actual object type. Might return a failure in case no hash was diff --git a/src/property.h b/src/property.h index e79c87e..0500e57 100644 --- a/src/property.h +++ b/src/property.h @@ -183,10 +183,12 @@ class LookupResult BASE_EMBEDDED { } ~LookupResult() { - ASSERT(isolate_->top_lookup_result() == this); - isolate_->SetTopLookupResult(next_); + ASSERT(isolate()->top_lookup_result() == this); + isolate()->SetTopLookupResult(next_); } + Isolate* isolate() const { return isolate_; } + void DescriptorResult(JSObject* holder, PropertyDetails details, int number) { lookup_type_ = DESCRIPTOR_TYPE; holder_ = holder; @@ -342,7 +344,7 @@ class LookupResult BASE_EMBEDDED { case INTERCEPTOR: case TRANSITION: case NONEXISTENT: - return Isolate::Current()->heap()->the_hole_value(); + return isolate()->heap()->the_hole_value(); } UNREACHABLE(); return NULL; diff --git a/src/runtime.cc b/src/runtime.cc index 6dc514d..b64f461 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -959,7 +959,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) { isolate->ReportFailedAccessCheck(JSObject::cast(obj), v8::ACCESS_GET); return isolate->heap()->undefined_value(); } - obj = obj->GetPrototype(); + obj = obj->GetPrototype(isolate); } while (obj->IsJSObject() && JSObject::cast(obj)->map()->is_hidden_prototype()); return obj; @@ -973,7 +973,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) { Object* O = args[0]; Object* V = args[1]; while (true) { - Object* prototype = V->GetPrototype(); + Object* prototype = V->GetPrototype(isolate); if (prototype->IsNull()) return isolate->heap()->false_value(); if (O == prototype) return isolate->heap()->true_value(); V = prototype; @@ -3899,7 +3899,7 @@ MaybeObject* Runtime::GetElementOrCharAt(Isolate* isolate, } if (object->IsString() || object->IsNumber() || object->IsBoolean()) { - return object->GetPrototype()->GetElement(index); + return object->GetPrototype(isolate)->GetElement(index); } return object->GetElement(index); @@ -12039,7 +12039,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { // Skip the global proxy as it has no properties and always delegates to the // real global object. if (result->IsJSGlobalProxy()) { - result = Handle(JSObject::cast(result->GetPrototype())); + result = Handle(JSObject::cast(result->GetPrototype(isolate))); } return *result; @@ -12153,7 +12153,8 @@ static int DebugReferencedBy(HeapIterator* iterator, Object* instance_filter, int max_references, FixedArray* instances, int instances_size, JSFunction* arguments_function) { - NoHandleAllocation ha(target->GetIsolate()); + Isolate* isolate = target->GetIsolate(); + NoHandleAllocation ha(isolate); AssertNoAllocation no_alloc; // Iterate the heap. @@ -12179,7 +12180,7 @@ static int DebugReferencedBy(HeapIterator* iterator, if (!instance_filter->IsUndefined()) { Object* V = obj; while (true) { - Object* prototype = V->GetPrototype(); + Object* prototype = V->GetPrototype(isolate); if (prototype->IsNull()) { break; } @@ -13249,7 +13250,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_UnwrapGlobalProxy) { ASSERT(args.length() == 1); Object* object = args[0]; if (object->IsJSGlobalProxy()) { - object = object->GetPrototype(); + object = object->GetPrototype(isolate); if (object->IsNull()) return isolate->heap()->undefined_value(); } return object; diff --git a/src/string-stream.cc b/src/string-stream.cc index fc07d94..9510254 100644 --- a/src/string-stream.cc +++ b/src/string-stream.cc @@ -533,11 +533,13 @@ void StringStream::PrintFunction(Object* f, Object* receiver, Code** code) { void StringStream::PrintPrototype(JSFunction* fun, Object* receiver) { Object* name = fun->shared()->name(); bool print_name = false; - Heap* heap = HEAP; - for (Object* p = receiver; p != heap->null_value(); p = p->GetPrototype()) { + Isolate* isolate = fun->GetIsolate(); + for (Object* p = receiver; + p != isolate->heap()->null_value(); + p = p->GetPrototype(isolate)) { if (p->IsJSObject()) { Object* key = JSObject::cast(p)->SlowReverseLookup(fun); - if (key != heap->undefined_value()) { + if (key != isolate->heap()->undefined_value()) { if (!name->IsString() || !key->IsString() || !String::cast(name)->Equals(String::cast(key))) { diff --git a/src/stub-cache.cc b/src/stub-cache.cc index a2a1930..9d11a2b 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -147,7 +147,8 @@ Handle StubCache::ComputeLoadField(Handle name, PropertyIndex field) { InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*receiver, *holder); - Handle map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); + Handle map_holder( + IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder)); Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::FIELD); Handle probe(map_holder->map()->FindInCodeCache(*name, flags), isolate_); @@ -170,7 +171,8 @@ Handle StubCache::ComputeLoadCallback( ASSERT(v8::ToCData
(callback->getter()) != 0); InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*receiver, *holder); - Handle map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); + Handle map_holder( + IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder)); Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CALLBACKS); Handle probe(map_holder->map()->FindInCodeCache(*name, flags), @@ -193,7 +195,8 @@ Handle StubCache::ComputeLoadViaGetter(Handle name, Handle getter) { InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*receiver, *holder); - Handle map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); + Handle map_holder( + IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder)); Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CALLBACKS); Handle probe(map_holder->map()->FindInCodeCache(*name, flags), @@ -216,7 +219,8 @@ Handle StubCache::ComputeLoadConstant(Handle name, Handle value) { InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*receiver, *holder); - Handle map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); + Handle map_holder( + IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder)); Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CONSTANT_FUNCTION); Handle probe(map_holder->map()->FindInCodeCache(*name, flags), @@ -238,7 +242,8 @@ Handle StubCache::ComputeLoadInterceptor(Handle name, Handle holder) { InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*receiver, *holder); - Handle map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); + Handle map_holder( + IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder)); Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::INTERCEPTOR); Handle probe(map_holder->map()->FindInCodeCache(*name, flags), @@ -267,7 +272,8 @@ Handle StubCache::ComputeLoadGlobal(Handle name, bool is_dont_delete) { InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*receiver, *holder); - Handle map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); + Handle map_holder( + IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder)); Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::NORMAL); Handle probe(map_holder->map()->FindInCodeCache(*name, flags), @@ -290,7 +296,8 @@ Handle StubCache::ComputeKeyedLoadField(Handle name, PropertyIndex field) { InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*receiver, *holder); - Handle map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); + Handle map_holder( + IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder)); Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::FIELD); Handle probe(map_holder->map()->FindInCodeCache(*name, flags), @@ -312,7 +319,8 @@ Handle StubCache::ComputeKeyedLoadConstant(Handle name, Handle value) { InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*receiver, *holder); - Handle map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); + Handle map_holder( + IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder)); Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CONSTANT_FUNCTION); Handle probe(map_holder->map()->FindInCodeCache(*name, flags), @@ -334,7 +342,8 @@ Handle StubCache::ComputeKeyedLoadInterceptor(Handle name, Handle holder) { InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*receiver, *holder); - Handle map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); + Handle map_holder( + IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder)); Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::INTERCEPTOR); Handle probe(map_holder->map()->FindInCodeCache(*name, flags), @@ -357,7 +366,8 @@ Handle StubCache::ComputeKeyedLoadCallback( Handle callback) { InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*receiver, *holder); - Handle map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); + Handle map_holder( + IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder)); Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CALLBACKS); Handle probe(map_holder->map()->FindInCodeCache(*name, flags), @@ -568,7 +578,8 @@ Handle StubCache::ComputeCallConstant(int argc, // Compute the check type and the map. InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object, *holder); - Handle map_holder(IC::GetCodeCacheHolder(*object, cache_holder)); + Handle map_holder( + IC::GetCodeCacheHolder(isolate_, *object, cache_holder)); // Compute check type based on receiver/holder. CheckType check = RECEIVER_MAP_CHECK; @@ -618,7 +629,8 @@ Handle StubCache::ComputeCallField(int argc, // Compute the check type and the map. InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object, *holder); - Handle map_holder(IC::GetCodeCacheHolder(*object, cache_holder)); + Handle map_holder( + IC::GetCodeCacheHolder(isolate_, *object, cache_holder)); // TODO(1233596): We cannot do receiver map check for non-JS objects // because they may be represented as immediates without a @@ -656,7 +668,8 @@ Handle StubCache::ComputeCallInterceptor(int argc, // Compute the check type and the map. InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object, *holder); - Handle map_holder(IC::GetCodeCacheHolder(*object, cache_holder)); + Handle map_holder( + IC::GetCodeCacheHolder(isolate_, *object, cache_holder)); // TODO(1233596): We cannot do receiver map check for non-JS objects // because they may be represented as immediates without a @@ -695,7 +708,8 @@ Handle StubCache::ComputeCallGlobal(int argc, Handle function) { InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*receiver, *holder); - Handle map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); + Handle map_holder( + IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder)); Code::Flags flags = Code::ComputeMonomorphicFlags(kind, Code::NORMAL, extra_state, cache_holder, argc); diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index c6e1877..1d9e3bc 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -1827,8 +1827,9 @@ Handle CallStubCompiler::CompileStringCharCodeAtCall( rax, &miss); ASSERT(!object.is_identical_to(holder)); - CheckPrototypes(Handle(JSObject::cast(object->GetPrototype())), - rax, holder, rbx, rdx, rdi, name, &miss); + CheckPrototypes( + Handle(JSObject::cast(object->GetPrototype(isolate()))), + rax, holder, rbx, rdx, rdi, name, &miss); Register receiver = rbx; Register index = rdi; @@ -1905,8 +1906,9 @@ Handle CallStubCompiler::CompileStringCharAtCall( rax, &miss); ASSERT(!object.is_identical_to(holder)); - CheckPrototypes(Handle(JSObject::cast(object->GetPrototype())), - rax, holder, rbx, rdx, rdi, name, &miss); + CheckPrototypes( + Handle(JSObject::cast(object->GetPrototype(isolate()))), + rax, holder, rbx, rdx, rdi, name, &miss); Register receiver = rax; Register index = rdi; @@ -2245,7 +2247,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle object, GenerateDirectLoadGlobalFunctionPrototype( masm(), Context::STRING_FUNCTION_INDEX, rax, &miss); CheckPrototypes( - Handle(JSObject::cast(object->GetPrototype())), + Handle(JSObject::cast(object->GetPrototype(isolate()))), rax, holder, rbx, rdx, rdi, name, &miss); break; @@ -2260,7 +2262,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle object, GenerateDirectLoadGlobalFunctionPrototype( masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss); CheckPrototypes( - Handle(JSObject::cast(object->GetPrototype())), + Handle(JSObject::cast(object->GetPrototype(isolate()))), rax, holder, rbx, rdx, rdi, name, &miss); break; } @@ -2276,7 +2278,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle object, GenerateDirectLoadGlobalFunctionPrototype( masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, &miss); CheckPrototypes( - Handle(JSObject::cast(object->GetPrototype())), + Handle(JSObject::cast(object->GetPrototype(isolate()))), rax, holder, rbx, rdx, rdi, name, &miss); break; } -- 2.7.4