Avoid TLS accesses in Object::Lookup and Object::GetPrototype.
authorsvenpanne@chromium.org <svenpanne@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 27 Feb 2013 13:22:29 +0000 (13:22 +0000)
committersvenpanne@chromium.org <svenpanne@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 27 Feb 2013 13:22:29 +0000 (13:22 +0000)
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

19 files changed:
src/accessors.cc
src/api.cc
src/arm/stub-cache-arm.cc
src/builtins.cc
src/handles.cc
src/hydrogen.cc
src/ia32/stub-cache-ia32.cc
src/ic-inl.h
src/ic.cc
src/ic.h
src/isolate.cc
src/mips/stub-cache-mips.cc
src/objects.cc
src/objects.h
src/property.h
src/runtime.cc
src/string-stream.cc
src/stub-cache.cc
src/x64/stub-cache-x64.cc

index 942009a..3dcf422 100644 (file)
@@ -42,8 +42,8 @@ namespace internal {
 
 
 template <class C>
-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<C>(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<JSArray>(object);
+  JSArray* holder = FindInstanceOf<JSArray>(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<JSFunction>(object);
-  if (function == NULL) return heap->undefined_value();
+  Isolate* isolate = Isolate::Current();
+  JSFunction* function = FindInstanceOf<JSFunction>(isolate, object);
+  if (function == NULL) return isolate->heap()->undefined_value();
   while (!function->should_have_prototype()) {
-    function = FindInstanceOf<JSFunction>(function->GetPrototype());
+    function = FindInstanceOf<JSFunction>(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<JSFunction>(object);
+  JSFunction* function_raw = FindInstanceOf<JSFunction>(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<JSFunction>(object);
+  Isolate* isolate = Isolate::Current();
+  JSFunction* function = FindInstanceOf<JSFunction>(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<JSFunction> 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<JSFunction>(object);
-  return holder == NULL ? HEAP->undefined_value() : holder->shared()->name();
+  Isolate* isolate = Isolate::Current();
+  JSFunction* holder = FindInstanceOf<JSFunction>(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<JSFunction>(object);
+  JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
   if (holder == NULL) return isolate->heap()->undefined_value();
   Handle<JSFunction> 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<JSFunction>(object);
+  JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
   if (holder == NULL) return isolate->heap()->undefined_value();
   if (holder->shared()->native()) return isolate->heap()->null_value();
   Handle<JSFunction> 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<JSObject> receiver(receiver_raw);
   Handle<Object> value(value_raw, isolate);
-  Handle<Object> old_value(GetPrototypeSkipHiddenPrototypes(*receiver),
+  Handle<Object> old_value(GetPrototypeSkipHiddenPrototypes(isolate, *receiver),
                            isolate);
 
   MaybeObject* result = receiver->SetPrototype(*value, kSkipHiddenPrototypes);
   Handle<Object> hresult;
   if (!result->ToHandle(&hresult, isolate)) return result;
 
-  Handle<Object> new_value(GetPrototypeSkipHiddenPrototypes(*receiver),
+  Handle<Object> new_value(GetPrototypeSkipHiddenPrototypes(isolate, *receiver),
                            isolate);
   if (!new_value->SameValue(*old_value)) {
     JSObject::EnqueueChangeRecord(receiver, "prototype",
index 1860e50..430524d 100644 (file)
@@ -2959,7 +2959,7 @@ Local<Value> v8::Object::GetPrototype() {
              return Local<v8::Value>());
   ENTER_V8(isolate);
   i::Handle<i::Object> self = Utils::OpenHandle(this);
-  i::Handle<i::Object> result(self->GetPrototype(), isolate);
+  i::Handle<i::Object> result(self->GetPrototype(isolate), isolate);
   return Utils::ToLocal(result);
 }
 
index b652fc0..f979513 100644 (file)
@@ -1945,8 +1945,9 @@ Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
                                             r0,
                                             &miss);
   ASSERT(!object.is_identical_to(holder));
-  CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
-                  r0, holder, r1, r3, r4, name, &miss);
+  CheckPrototypes(
+      Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
+      r0, holder, r1, r3, r4, name, &miss);
 
   Register receiver = r1;
   Register index = r4;
@@ -2025,8 +2026,9 @@ Handle<Code> CallStubCompiler::CompileStringCharAtCall(
                                             r0,
                                             &miss);
   ASSERT(!object.is_identical_to(holder));
-  CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
-                  r0, holder, r1, r3, r4, name, &miss);
+  CheckPrototypes(
+      Handle<JSObject>(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> object,
       GenerateDirectLoadGlobalFunctionPrototype(
           masm(), Context::STRING_FUNCTION_INDEX, r0, &miss);
       CheckPrototypes(
-          Handle<JSObject>(JSObject::cast(object->GetPrototype())),
+          Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
           r0, holder, r3, r1, r4, name, &miss);
       break;
 
@@ -2505,7 +2507,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
       GenerateDirectLoadGlobalFunctionPrototype(
           masm(), Context::NUMBER_FUNCTION_INDEX, r0, &miss);
       CheckPrototypes(
-          Handle<JSObject>(JSObject::cast(object->GetPrototype())),
+          Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
           r0, holder, r3, r1, r4, name, &miss);
       break;
     }
@@ -2523,7 +2525,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
       GenerateDirectLoadGlobalFunctionPrototype(
           masm(), Context::BOOLEAN_FUNCTION_INDEX, r0, &miss);
       CheckPrototypes(
-          Handle<JSObject>(JSObject::cast(object->GetPrototype())),
+          Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
           r0, holder, r3, r1, r4, name, &miss);
       break;
     }
index e404b51..279594e 100644 (file)
@@ -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);
index 9429334..5de9b6c 100644 (file)
@@ -647,7 +647,7 @@ Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSReceiver> object,
   // Only collect keys if access is permitted.
   for (Handle<Object> p = object;
        *p != isolate->heap()->null_value();
-       p = Handle<Object>(p->GetPrototype(), isolate)) {
+       p = Handle<Object>(p->GetPrototype(isolate), isolate)) {
     if (p->IsJSProxy()) {
       Handle<JSProxy> proxy(JSProxy::cast(*p), isolate);
       Handle<Object> args[] = { proxy };
index 73287f4..ae94084 100644 (file)
@@ -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(
index 4b1cb5b..d7c4186 100644 (file)
@@ -1874,8 +1874,9 @@ Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
                                             eax,
                                             &miss);
   ASSERT(!object.is_identical_to(holder));
-  CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
-                  eax, holder, ebx, edx, edi, name, &miss);
+  CheckPrototypes(
+      Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
+      eax, holder, ebx, edx, edi, name, &miss);
 
   Register receiver = ebx;
   Register index = edi;
@@ -1957,8 +1958,9 @@ Handle<Code> CallStubCompiler::CompileStringCharAtCall(
                                             eax,
                                             &miss);
   ASSERT(!object.is_identical_to(holder));
-  CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
-                  eax, holder, ebx, edx, edi, name, &miss);
+  CheckPrototypes(
+      Handle<JSObject>(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> object,
       GenerateDirectLoadGlobalFunctionPrototype(
           masm(), Context::STRING_FUNCTION_INDEX, eax, &miss);
       CheckPrototypes(
-          Handle<JSObject>(JSObject::cast(object->GetPrototype())),
+          Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
           eax, holder, ebx, edx, edi, name, &miss);
       break;
 
@@ -2437,7 +2439,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
       GenerateDirectLoadGlobalFunctionPrototype(
           masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss);
       CheckPrototypes(
-          Handle<JSObject>(JSObject::cast(object->GetPrototype())),
+          Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
           eax, holder, ebx, edx, edi, name, &miss);
       break;
     }
@@ -2453,7 +2455,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
       GenerateDirectLoadGlobalFunctionPrototype(
           masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss);
       CheckPrototypes(
-          Handle<JSObject>(JSObject::cast(object->GetPrototype())),
+          Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
           eax, holder, ebx, edx, edi, name, &miss);
       break;
     }
index 77f409a..11ab710 100644 (file)
@@ -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);
 }
index ee46961..c15b76f 100644 (file)
--- 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<JSObject> cache_object = object->IsJSObject()
           ? Handle<JSObject>::cast(object)
-          : Handle<JSObject>(JSObject::cast(object->GetPrototype()));
+          : Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate())));
       // Update the stub cache.
       UpdateMegamorphicCache(cache_object->map(), *name, *code);
       break;
index 2e7367a..79c1baf 100644 (file)
--- 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:
index 49a3dcc..e69743b 100644 (file)
@@ -1192,7 +1192,7 @@ bool Isolate::IsErrorObject(Handle<Object> 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;
index 24474cf..649751f 100644 (file)
@@ -1946,8 +1946,9 @@ Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
                                             v0,
                                             &miss);
   ASSERT(!object.is_identical_to(holder));
-  CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
-                  v0, holder, a1, a3, t0, name, &miss);
+  CheckPrototypes(
+      Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
+      v0, holder, a1, a3, t0, name, &miss);
 
   Register receiver = a1;
   Register index = t1;
@@ -2026,8 +2027,9 @@ Handle<Code> CallStubCompiler::CompileStringCharAtCall(
                                             v0,
                                             &miss);
   ASSERT(!object.is_identical_to(holder));
-  CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
-                  v0, holder, a1, a3, t0, name, &miss);
+  CheckPrototypes(
+      Handle<JSObject>(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> object,
       GenerateDirectLoadGlobalFunctionPrototype(
           masm(), Context::STRING_FUNCTION_INDEX, a0, &miss);
       CheckPrototypes(
-          Handle<JSObject>(JSObject::cast(object->GetPrototype())),
+          Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
           a0, holder, a3, a1, t0, name, &miss);
       break;
 
@@ -2498,7 +2500,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
       GenerateDirectLoadGlobalFunctionPrototype(
           masm(), Context::NUMBER_FUNCTION_INDEX, a0, &miss);
       CheckPrototypes(
-          Handle<JSObject>(JSObject::cast(object->GetPrototype())),
+          Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
           a0, holder, a3, a1, t0, name, &miss);
       break;
     }
@@ -2514,7 +2516,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
       GenerateDirectLoadGlobalFunctionPrototype(
           masm(), Context::BOOLEAN_FUNCTION_INDEX, a0, &miss);
       CheckPrototypes(
-          Handle<JSObject>(JSObject::cast(object->GetPrototype())),
+          Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
           a0, holder, a3, a1, t0, name, &miss);
       break;
     }
index 5f83f73..8be7be3 100644 (file)
@@ -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<String>(&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<Object> handle(this, heap->isolate());
-    return heap->isolate()->Throw(
-        *FACTORY->NewTypeError("non_extensible_proto",
-                               HandleVector<Object>(&handle, 1)));
+    HandleScope scope(isolate);
+    Handle<Object> handle(this, isolate);
+    return isolate->Throw(
+        *isolate->factory()->NewTypeError("non_extensible_proto",
+                                          HandleVector<Object>(&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<Object>(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);
     }
   }
 
index f2407f8..914a245 100644 (file)
@@ -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
index e79c87e..0500e57 100644 (file)
@@ -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;
index 6dc514d..b64f461 100644 (file)
@@ -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>(JSObject::cast(result->GetPrototype()));
+    result = Handle<JSObject>(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;
index fc07d94..9510254 100644 (file)
@@ -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))) {
index a2a1930..9d11a2b 100644 (file)
@@ -147,7 +147,8 @@ Handle<Code> StubCache::ComputeLoadField(Handle<String> name,
                                          PropertyIndex field) {
   InlineCacheHolderFlag cache_holder =
       IC::GetCodeCacheForObject(*receiver, *holder);
-  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
+  Handle<JSObject> map_holder(
+      IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
   Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::FIELD);
   Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
                        isolate_);
@@ -170,7 +171,8 @@ Handle<Code> StubCache::ComputeLoadCallback(
   ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
   InlineCacheHolderFlag cache_holder =
       IC::GetCodeCacheForObject(*receiver, *holder);
-  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
+  Handle<JSObject> map_holder(
+      IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
   Code::Flags flags =
       Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CALLBACKS);
   Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@@ -193,7 +195,8 @@ Handle<Code> StubCache::ComputeLoadViaGetter(Handle<String> name,
                                              Handle<JSFunction> getter) {
   InlineCacheHolderFlag cache_holder =
       IC::GetCodeCacheForObject(*receiver, *holder);
-  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
+  Handle<JSObject> map_holder(
+      IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
   Code::Flags flags =
       Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CALLBACKS);
   Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@@ -216,7 +219,8 @@ Handle<Code> StubCache::ComputeLoadConstant(Handle<String> name,
                                             Handle<JSFunction> value) {
   InlineCacheHolderFlag cache_holder =
       IC::GetCodeCacheForObject(*receiver, *holder);
-  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
+  Handle<JSObject> map_holder(
+      IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
   Code::Flags flags =
       Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CONSTANT_FUNCTION);
   Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@@ -238,7 +242,8 @@ Handle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name,
                                                Handle<JSObject> holder) {
   InlineCacheHolderFlag cache_holder =
       IC::GetCodeCacheForObject(*receiver, *holder);
-  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
+  Handle<JSObject> map_holder(
+      IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
   Code::Flags flags =
       Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::INTERCEPTOR);
   Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@@ -267,7 +272,8 @@ Handle<Code> StubCache::ComputeLoadGlobal(Handle<String> name,
                                           bool is_dont_delete) {
   InlineCacheHolderFlag cache_holder =
       IC::GetCodeCacheForObject(*receiver, *holder);
-  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
+  Handle<JSObject> map_holder(
+      IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
   Code::Flags flags =
       Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::NORMAL);
   Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@@ -290,7 +296,8 @@ Handle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name,
                                               PropertyIndex field) {
   InlineCacheHolderFlag cache_holder =
       IC::GetCodeCacheForObject(*receiver, *holder);
-  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
+  Handle<JSObject> map_holder(
+      IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
   Code::Flags flags =
       Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::FIELD);
   Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@@ -312,7 +319,8 @@ Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<String> name,
                                                  Handle<JSFunction> value) {
   InlineCacheHolderFlag cache_holder =
       IC::GetCodeCacheForObject(*receiver, *holder);
-  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
+  Handle<JSObject> map_holder(
+      IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
   Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC,
                                                     Code::CONSTANT_FUNCTION);
   Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@@ -334,7 +342,8 @@ Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<String> name,
                                                     Handle<JSObject> holder) {
   InlineCacheHolderFlag cache_holder =
       IC::GetCodeCacheForObject(*receiver, *holder);
-  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
+  Handle<JSObject> map_holder(
+      IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
   Code::Flags flags =
       Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::INTERCEPTOR);
   Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@@ -357,7 +366,8 @@ Handle<Code> StubCache::ComputeKeyedLoadCallback(
     Handle<ExecutableAccessorInfo> callback) {
   InlineCacheHolderFlag cache_holder =
       IC::GetCodeCacheForObject(*receiver, *holder);
-  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
+  Handle<JSObject> map_holder(
+      IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
   Code::Flags flags =
       Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CALLBACKS);
   Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@@ -568,7 +578,8 @@ Handle<Code> StubCache::ComputeCallConstant(int argc,
   // Compute the check type and the map.
   InlineCacheHolderFlag cache_holder =
       IC::GetCodeCacheForObject(*object, *holder);
-  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder));
+  Handle<JSObject> 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<Code> StubCache::ComputeCallField(int argc,
   // Compute the check type and the map.
   InlineCacheHolderFlag cache_holder =
       IC::GetCodeCacheForObject(*object, *holder);
-  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder));
+  Handle<JSObject> 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<Code> StubCache::ComputeCallInterceptor(int argc,
   // Compute the check type and the map.
   InlineCacheHolderFlag cache_holder =
       IC::GetCodeCacheForObject(*object, *holder);
-  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder));
+  Handle<JSObject> 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<Code> StubCache::ComputeCallGlobal(int argc,
                                           Handle<JSFunction> function) {
   InlineCacheHolderFlag cache_holder =
       IC::GetCodeCacheForObject(*receiver, *holder);
-  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
+  Handle<JSObject> map_holder(
+      IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
   Code::Flags flags =
       Code::ComputeMonomorphicFlags(kind, Code::NORMAL, extra_state,
                                     cache_holder, argc);
index c6e1877..1d9e3bc 100644 (file)
@@ -1827,8 +1827,9 @@ Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
                                             rax,
                                             &miss);
   ASSERT(!object.is_identical_to(holder));
-  CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
-                  rax, holder, rbx, rdx, rdi, name, &miss);
+  CheckPrototypes(
+      Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
+      rax, holder, rbx, rdx, rdi, name, &miss);
 
   Register receiver = rbx;
   Register index = rdi;
@@ -1905,8 +1906,9 @@ Handle<Code> CallStubCompiler::CompileStringCharAtCall(
                                             rax,
                                             &miss);
   ASSERT(!object.is_identical_to(holder));
-  CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
-                  rax, holder, rbx, rdx, rdi, name, &miss);
+  CheckPrototypes(
+      Handle<JSObject>(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> object,
       GenerateDirectLoadGlobalFunctionPrototype(
           masm(), Context::STRING_FUNCTION_INDEX, rax, &miss);
       CheckPrototypes(
-          Handle<JSObject>(JSObject::cast(object->GetPrototype())),
+          Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
           rax, holder, rbx, rdx, rdi, name, &miss);
       break;
 
@@ -2260,7 +2262,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
       GenerateDirectLoadGlobalFunctionPrototype(
           masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss);
       CheckPrototypes(
-          Handle<JSObject>(JSObject::cast(object->GetPrototype())),
+          Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
           rax, holder, rbx, rdx, rdi, name, &miss);
       break;
     }
@@ -2276,7 +2278,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
       GenerateDirectLoadGlobalFunctionPrototype(
           masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, &miss);
       CheckPrototypes(
-          Handle<JSObject>(JSObject::cast(object->GetPrototype())),
+          Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
           rax, holder, rbx, rdx, rdi, name, &miss);
       break;
     }