Revision: 9676
Author:   [email protected]
Date:     Tue Oct 18 04:18:55 2011
Log:      Make the GC aware of JSReceiver pointers in LookupResults.

The LookupResult utility class is used in handlified code, but it can
contain a raw pointer to the lookup's holder object.  Create a per-thread
stack of live LookupResults and iterate all the live ones on GC.

[email protected],[email protected]
BUG=
TEST=

Review URL: http://codereview.chromium.org/8341009
http://code.google.com/p/v8/source/detail?r=9676

Modified:
 /branches/bleeding_edge/src/api.cc
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/arm/stub-cache-arm.cc
 /branches/bleeding_edge/src/ast.cc
 /branches/bleeding_edge/src/bootstrapper.cc
 /branches/bleeding_edge/src/hydrogen-instructions.cc
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
 /branches/bleeding_edge/src/ic.cc
 /branches/bleeding_edge/src/isolate.cc
 /branches/bleeding_edge/src/isolate.h
 /branches/bleeding_edge/src/mips/stub-cache-mips.cc
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/profile-generator.cc
 /branches/bleeding_edge/src/property.cc
 /branches/bleeding_edge/src/property.h
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/stub-cache-x64.cc

=======================================
--- /branches/bleeding_edge/src/api.cc  Mon Oct 17 06:27:57 2011
+++ /branches/bleeding_edge/src/api.cc  Tue Oct 18 04:18:55 2011
@@ -3110,7 +3110,7 @@
   ENTER_V8(isolate);
   i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
-  i::LookupResult lookup;
+  i::LookupResult lookup(isolate);
   self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
   return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
 }
@@ -3123,7 +3123,7 @@
   ENTER_V8(isolate);
   i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
-  i::LookupResult lookup;
+  i::LookupResult lookup(isolate);
   self_obj->LookupRealNamedProperty(*key_obj, &lookup);
   return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
 }
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Mon Oct 17 00:43:40 2011 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Oct 18 04:18:55 2011
@@ -2320,7 +2320,7 @@
                                                Register object,
                                                Handle<Map> type,
                                                Handle<String> name) {
-  LookupResult lookup;
+  LookupResult lookup(isolate());
   type->LookupInDescriptors(NULL, *name, &lookup);
   ASSERT(lookup.IsProperty() &&
          (lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION));
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Tue Oct 11 09:02:45 2011 +++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Tue Oct 18 04:18:55 2011
@@ -2504,7 +2504,7 @@
   // Get the number of arguments.
   const int argc = arguments().immediate();

-  LookupResult lookup;
+  LookupResult lookup(isolate());
   LookupPostInterceptor(holder, name, &lookup);

   // Get the receiver from the stack.
@@ -2908,7 +2908,7 @@
   // -----------------------------------
   Label miss;

-  LookupResult lookup;
+  LookupResult lookup(isolate());
   LookupPostInterceptor(holder, name, &lookup);
   GenerateLoadInterceptor(object,
                           holder,
@@ -3066,7 +3066,7 @@
   __ cmp(r0, Operand(Handle<String>(name)));
   __ b(ne, &miss);

-  LookupResult lookup;
+  LookupResult lookup(isolate());
   LookupPostInterceptor(holder, name, &lookup);
   GenerateLoadInterceptor(receiver,
                           holder,
=======================================
--- /branches/bleeding_edge/src/ast.cc  Mon Oct 17 02:29:37 2011
+++ /branches/bleeding_edge/src/ast.cc  Tue Oct 18 04:18:55 2011
@@ -720,7 +720,7 @@
     holder_ = Handle<JSObject>::null();
   }
   while (true) {
-    LookupResult lookup;
+    LookupResult lookup(type->GetIsolate());
     type->LookupInDescriptors(NULL, *name, &lookup);
     // If the function wasn't found directly in the map, we start
     // looking upwards through the prototype chain.
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Mon Oct  3 04:13:20 2011
+++ /branches/bleeding_edge/src/bootstrapper.cc Tue Oct 18 04:18:55 2011
@@ -1065,7 +1065,7 @@
                             DONT_ENUM);

 #ifdef DEBUG
-    LookupResult lookup;
+    LookupResult lookup(isolate);
     result->LocalLookup(heap->callee_symbol(), &lookup);
     ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
     ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsCalleeIndex);
@@ -1162,7 +1162,7 @@
                             DONT_ENUM);

 #ifdef DEBUG
-    LookupResult lookup;
+    LookupResult lookup(isolate);
     result->LocalLookup(heap->length_symbol(), &lookup);
     ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
     ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
@@ -2088,7 +2088,7 @@
           break;
         }
         case CALLBACKS: {
-          LookupResult result;
+          LookupResult result(isolate());
           to->LocalLookup(descs->GetKey(i), &result);
           // If the property is already there we skip it
           if (result.IsProperty()) continue;
@@ -2126,7 +2126,7 @@
       if (properties->IsKey(raw_key)) {
         ASSERT(raw_key->IsString());
         // If the property is already there we skip it.
-        LookupResult result;
+        LookupResult result(isolate());
         to->LocalLookup(String::cast(raw_key), &result);
         if (result.IsProperty()) continue;
         // Set the property.
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Mon Oct 17 00:52:20 2011 +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Tue Oct 18 04:18:55 2011
@@ -1390,7 +1390,7 @@
        i < types->length() && types_.length() < kMaxLoadPolymorphism;
        ++i) {
     Handle<Map> map = types->at(i);
-    LookupResult lookup;
+    LookupResult lookup(map->GetIsolate());
     map->LookupInDescriptors(NULL, *name, &lookup);
     if (lookup.IsProperty()) {
       switch (lookup.type()) {
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Fri Oct 14 08:02:19 2011
+++ /branches/bleeding_edge/src/hydrogen.cc     Tue Oct 18 04:18:55 2011
@@ -3156,7 +3156,7 @@
         return ast_context()->ReturnInstruction(instr, expr->id());
       }

-      LookupResult lookup;
+      LookupResult lookup(isolate());
       GlobalPropertyAccess type =
           LookupGlobalProperty(variable, &lookup, false);

@@ -3471,7 +3471,7 @@
   Handle<String> name = Handle<String>::cast(key->handle());
   ASSERT(!name.is_null());

-  LookupResult lookup;
+  LookupResult lookup(isolate());
   SmallMapList* types = expr->GetReceiverTypes();
   bool is_monomorphic = expr->IsMonomorphic() &&
       ComputeStoredField(types->first(), name, &lookup);
@@ -3495,7 +3495,7 @@
   HBasicBlock* join = NULL;
for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
     Handle<Map> map = types->at(i);
-    LookupResult lookup;
+    LookupResult lookup(isolate());
     if (ComputeStoredField(map, name, &lookup)) {
       if (count == 0) {
AddInstruction(new(zone()) HCheckNonSmi(object)); // Only needed once.
@@ -3578,7 +3578,7 @@
     ASSERT(!name.is_null());

     SmallMapList* types = expr->GetReceiverTypes();
-    LookupResult lookup;
+    LookupResult lookup(isolate());

     if (expr->IsMonomorphic()) {
       instr = BuildStoreNamed(object, value, expr);
@@ -3623,7 +3623,7 @@
                                                    HValue* value,
                                                    int position,
                                                    int ast_id) {
-  LookupResult lookup;
+  LookupResult lookup(isolate());
   GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true);
   if (type == kUseCell) {
     Handle<GlobalObject> global(info()->global_object());
@@ -3938,7 +3938,7 @@
                                             Property* expr,
                                             Handle<Map> map,
                                             Handle<String> name) {
-  LookupResult lookup;
+  LookupResult lookup(isolate());
   map->LookupInDescriptors(NULL, *name, &lookup);
   if (lookup.IsProperty() && lookup.type() == FIELD) {
     return BuildLoadNamedField(obj,
@@ -5012,7 +5012,7 @@
// If there is a global property cell for the name at compile time and // access check is not enabled we assume that the function will not change
       // and generate optimized code for calling the function.
-      LookupResult lookup;
+      LookupResult lookup(isolate());
GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false);
       if (type == kUseCell &&
           !info()->global_object()->IsAccessCheckNeeded()) {
@@ -5869,7 +5869,7 @@
         !info()->global_object()->IsAccessCheckNeeded()) {
       Handle<String> name = proxy->name();
       Handle<GlobalObject> global(info()->global_object());
-      LookupResult lookup;
+      LookupResult lookup(isolate());
       global->Lookup(*name, &lookup);
       if (lookup.IsProperty() &&
           lookup.type() == NORMAL &&
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Mon Oct 17 00:43:40 2011 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Oct 18 04:18:55 2011
@@ -2185,7 +2185,7 @@
                                                Register object,
                                                Handle<Map> type,
                                                Handle<String> name) {
-  LookupResult lookup;
+  LookupResult lookup(isolate());
   type->LookupInDescriptors(NULL, *name, &lookup);
   ASSERT(lookup.IsProperty() &&
          (lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION));
=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Tue Oct 11 09:02:45 2011 +++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Tue Oct 18 04:18:55 2011
@@ -2372,7 +2372,7 @@
   // Get the number of arguments.
   const int argc = arguments().immediate();

-  LookupResult lookup;
+  LookupResult lookup(isolate());
   LookupPostInterceptor(holder, name, &lookup);

   // Get the receiver from the stack.
@@ -2914,7 +2914,7 @@
   // -----------------------------------
   Label miss;

-  LookupResult lookup;
+  LookupResult lookup(isolate());
   LookupPostInterceptor(holder, name, &lookup);

   // TODO(368): Compile in the whole chain: all the interceptors in
@@ -3102,7 +3102,7 @@
   __ cmp(eax, Immediate(Handle<String>(name)));
   __ j(not_equal, &miss);

-  LookupResult lookup;
+  LookupResult lookup(isolate());
   LookupPostInterceptor(holder, name, &lookup);
   GenerateLoadInterceptor(receiver,
                           holder,
=======================================
--- /branches/bleeding_edge/src/ic.cc   Thu Oct 13 08:55:57 2011
+++ /branches/bleeding_edge/src/ic.cc   Tue Oct 18 04:18:55 2011
@@ -483,7 +483,7 @@
   }

   // Lookup the property in the object.
-  LookupResult lookup;
+  LookupResult lookup(isolate());
   LookupForRead(*object, *name, &lookup);

   if (!lookup.IsProperty()) {
@@ -935,7 +935,7 @@
   if (name->AsArrayIndex(&index)) return object->GetElement(index);

   // Named lookup in the object.
-  LookupResult lookup;
+  LookupResult lookup(isolate());
   LookupForRead(*object, *name, &lookup);

   // If we did not find a property, check if we need to throw an exception.
@@ -1203,7 +1203,7 @@
     }

     // Named lookup.
-    LookupResult lookup;
+    LookupResult lookup(isolate());
     LookupForRead(*object, *name, &lookup);

// If we did not find a property, check if we need to throw an exception.
@@ -1435,7 +1435,7 @@

   // Lookup the property locally in the receiver.
   if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) {
-    LookupResult lookup;
+    LookupResult lookup(isolate());

     if (LookupForWrite(*receiver, *name, &lookup)) {
       // Generate a stub for this store.
@@ -1849,7 +1849,7 @@
     }

     // Lookup the property locally in the receiver.
-    LookupResult lookup;
+    LookupResult lookup(isolate());
     receiver->LocalLookup(*name, &lookup);

     // Update inline cache and stub cache.
=======================================
--- /branches/bleeding_edge/src/isolate.cc      Mon Oct 10 02:21:48 2011
+++ /branches/bleeding_edge/src/isolate.cc      Tue Oct 18 04:18:55 2011
@@ -98,6 +98,7 @@
   failed_access_check_callback_ = NULL;
   save_context_ = NULL;
   catcher_ = NULL;
+  top_lookup_result_ = NULL;

   // These members are re-initialized later after deserialization
   // is complete.
@@ -480,6 +481,9 @@
   for (StackFrameIterator it(this, thread); !it.done(); it.Advance()) {
     it.frame()->Iterate(v);
   }
+
+  // Iterate pointers in live lookup results.
+  thread->top_lookup_result_->Iterate(v);
 }


=======================================
--- /branches/bleeding_edge/src/isolate.h       Mon Oct  3 04:13:20 2011
+++ /branches/bleeding_edge/src/isolate.h       Tue Oct 18 04:18:55 2011
@@ -255,6 +255,9 @@
   // Call back function to report unsafe JS accesses.
   v8::FailedAccessCheckCallback failed_access_check_callback_;

+  // Head of the list of live LookupResults.
+  LookupResult* top_lookup_result_;
+
   // Whether out of memory exceptions should be ignored.
   bool ignore_out_of_memory_;

@@ -994,6 +997,13 @@

   void SetData(void* data) { embedder_data_ = data; }
   void* GetData() { return embedder_data_; }
+
+  LookupResult* top_lookup_result() {
+    return thread_local_top_.top_lookup_result_;
+  }
+  void SetTopLookupResult(LookupResult* top) {
+    thread_local_top_.top_lookup_result_ = top;
+  }

  private:
   Isolate();
=======================================
--- /branches/bleeding_edge/src/mips/stub-cache-mips.cc Thu Oct 13 01:00:10 2011 +++ /branches/bleeding_edge/src/mips/stub-cache-mips.cc Tue Oct 18 04:18:55 2011
@@ -2515,7 +2515,7 @@
   // Get the number of arguments.
   const int argc = arguments().immediate();

-  LookupResult lookup;
+  LookupResult lookup(isolate());
   LookupPostInterceptor(holder, name, &lookup);

   // Get the receiver from the stack.
@@ -2919,7 +2919,7 @@
   // -----------------------------------
   Label miss;

-  LookupResult lookup;
+  LookupResult lookup(isolate());
   LookupPostInterceptor(holder, name, &lookup);
   GenerateLoadInterceptor(object,
                           holder,
@@ -3073,7 +3073,7 @@
   // Check the key is the cached one.
   __ Branch(&miss, ne, a0, Operand(Handle<String>(name)));

-  LookupResult lookup;
+  LookupResult lookup(isolate());
   LookupPostInterceptor(holder, name, &lookup);
   GenerateLoadInterceptor(receiver,
                           holder,
=======================================
--- /branches/bleeding_edge/src/objects.cc      Mon Oct 17 05:48:31 2011
+++ /branches/bleeding_edge/src/objects.cc      Tue Oct 18 04:18:55 2011
@@ -154,7 +154,7 @@
 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver,
                                              String* name,
PropertyAttributes* attributes) {
-  LookupResult result;
+  LookupResult result(name->GetIsolate());
   Lookup(name, &result);
   MaybeObject* value = GetProperty(receiver, &result, name, attributes);
   ASSERT(*attributes <= ABSENT);
@@ -310,7 +310,7 @@
       case FIELD:
       case CONSTANT_FUNCTION: {
         // Search ALL_CAN_READ accessors in prototype chain.
-        LookupResult r;
+        LookupResult r(GetIsolate());
         result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
         if (r.IsProperty()) {
           return GetPropertyWithFailedAccessCheck(receiver,
@@ -323,7 +323,7 @@
       case INTERCEPTOR: {
         // If the object has an interceptor, try real named properties.
         // No access check in GetPropertyAttributeWithInterceptor.
-        LookupResult r;
+        LookupResult r(GetIsolate());
         result->holder()->LookupRealNamedProperty(name, &r);
         if (r.IsProperty()) {
           return GetPropertyWithFailedAccessCheck(receiver,
@@ -370,7 +370,7 @@
       case CONSTANT_FUNCTION: {
         if (!continue_search) break;
         // Search ALL_CAN_READ accessors in prototype chain.
-        LookupResult r;
+        LookupResult r(GetIsolate());
         result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
         if (r.IsProperty()) {
           return GetPropertyAttributeWithFailedAccessCheck(receiver,
@@ -384,7 +384,7 @@
       case INTERCEPTOR: {
         // If the object has an interceptor, try real named properties.
         // No access check in GetPropertyAttributeWithInterceptor.
-        LookupResult r;
+        LookupResult r(GetIsolate());
         if (continue_search) {
           result->holder()->LookupRealNamedProperty(name, &r);
         } else {
@@ -404,7 +404,7 @@
     }
   }

-  GetHeap()->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
+  GetIsolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
   return ABSENT;
 }

@@ -1658,7 +1658,7 @@
     PropertyAttributes attributes,
     StrictModeFlag strict_mode) {
   // Check local property, ignore interceptor.
-  LookupResult result;
+  LookupResult result(GetIsolate());
   LocalLookupRealNamedProperty(name, &result);
   if (result.IsFound()) {
     // An existing property, a map transition or a null descriptor was
@@ -1840,7 +1840,7 @@
                                      Object* value,
                                      PropertyAttributes attributes,
                                      StrictModeFlag strict_mode) {
-  LookupResult result;
+  LookupResult result(GetIsolate());
   LocalLookup(name, &result);
   return SetProperty(&result, name, value, attributes, strict_mode);
 }
@@ -2006,9 +2006,9 @@
     PropertyAttributes attributes,
     bool* found,
     StrictModeFlag strict_mode) {
-  LookupResult result;
-  LookupCallbackSetterInPrototypes(name, &result);
   Heap* heap = GetHeap();
+  LookupResult result(heap->isolate());
+  LookupCallbackSetterInPrototypes(name, &result);
   if (result.IsFound()) {
     *found = true;
     if (result.type() == CALLBACKS) {
@@ -2020,7 +2020,7 @@
     } else if (result.type() == HANDLER) {
// We could not find a local property so let's check whether there is an
       // accessor that wants to handle the property.
-      LookupResult accessor_result;
+      LookupResult accessor_result(heap->isolate());
       LookupCallbackSetterInPrototypes(name, &accessor_result);
       if (accessor_result.IsFound()) {
         if (accessor_result.type() == CALLBACKS) {
@@ -2423,7 +2423,7 @@
         case INTERCEPTOR: {
// Try lookup real named properties. Note that only property can be // set is callbacks marked as ALL_CAN_WRITE on the prototype chain.
-          LookupResult r;
+          LookupResult r(GetIsolate());
           LookupRealNamedProperty(name, &r);
           if (r.IsProperty()) {
             return SetPropertyWithFailedAccessCheck(&r,
@@ -2441,10 +2441,10 @@
     }
   }

-  Heap* heap = GetHeap();
-  HandleScope scope(heap->isolate());
+  Isolate* isolate = GetIsolate();
+  HandleScope scope(isolate);
   Handle<Object> value_handle(value);
-  heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET);
+  isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET);
   return *value_handle;
 }

@@ -2865,12 +2865,12 @@
   // Make sure that the top context does not change when doing callbacks or
   // interceptor calls.
   AssertNoContextChange ncc;
-  LookupResult result;
+  Isolate* isolate = GetIsolate();
+  LookupResult result(isolate);
   LocalLookup(name, &result);
   // Check access rights if needed.
   if (IsAccessCheckNeeded()) {
-    Heap* heap = GetHeap();
-    if (!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) {
+    if (!isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) {
       return SetPropertyWithFailedAccessCheck(&result,
                                               name,
                                               value,
@@ -2941,7 +2941,7 @@
       String* name,
       bool continue_search) {
   // Check local property, ignore interceptor.
-  LookupResult result;
+  LookupResult result(GetIsolate());
   LocalLookupRealNamedProperty(name, &result);
   if (result.IsProperty()) return result.GetAttributes();

@@ -3017,7 +3017,7 @@
         ? NONE : ABSENT;
   }
   // Named property.
-  LookupResult result;
+  LookupResult result(GetIsolate());
   Lookup(key, &result);
   return GetPropertyAttribute(receiver, &result, key, true);
 }
@@ -3066,7 +3066,7 @@
     return ABSENT;
   }
   // Named property.
-  LookupResult result;
+  LookupResult result(GetIsolate());
   LocalLookup(name, &result);
   return GetPropertyAttribute(this, &result, name, false);
 }
@@ -3573,7 +3573,7 @@
 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name,
                                                      DeleteMode mode) {
   // Check local property, ignore interceptor.
-  LookupResult result;
+  LookupResult result(GetIsolate());
   LocalLookupRealNamedProperty(name, &result);
   if (!result.IsProperty()) return GetHeap()->true_value();

@@ -3722,7 +3722,7 @@
   if (name->AsArrayIndex(&index)) {
     return DeleteElement(index, mode);
   } else {
-    LookupResult result;
+    LookupResult result(isolate);
     LocalLookup(name, &result);
     if (!result.IsProperty()) return isolate->heap()->true_value();
     // Ignore attributes if forcing a deletion.
@@ -4152,7 +4152,7 @@
     }
   } else {
     // Lookup the name.
-    LookupResult result;
+    LookupResult result(heap->isolate());
     LocalLookup(name, &result);
     if (result.IsProperty()) {
       if (result.IsReadOnly()) return heap->undefined_value();
@@ -4182,8 +4182,8 @@


 bool JSObject::CanSetCallback(String* name) {
-  ASSERT(!IsAccessCheckNeeded()
- || Isolate::Current()->MayNamedAccess(this, name, v8::ACCESS_SET));
+  ASSERT(!IsAccessCheckNeeded() ||
+         GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET));

   // Check if there is an API defined callback object which prohibits
   // callback overwriting in this object or it's prototype chain.
@@ -4191,7 +4191,7 @@
   // certain accessors such as window.location should not be allowed
   // to be overwritten because allowing overwriting could potentially
   // cause security problems.
-  LookupResult callback_result;
+  LookupResult callback_result(GetIsolate());
   LookupCallback(name, &callback_result);
   if (callback_result.IsProperty()) {
     Object* obj = callback_result.GetCallbackObject();
@@ -4388,7 +4388,7 @@
     }
   } else {
     // Lookup the name.
-    LookupResult result;
+    LookupResult result(isolate);
     LocalLookup(name, &result);
     // ES5 forbids turning a property into an accessor if it's not
// configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5).
@@ -4446,7 +4446,7 @@
     for (Object* obj = this;
          obj != heap->null_value();
          obj = JSObject::cast(obj)->GetPrototype()) {
-      LookupResult result;
+      LookupResult result(heap->isolate());
       JSObject::cast(obj)->LocalLookup(name, &result);
       if (result.IsProperty()) {
         if (result.IsReadOnly()) return heap->undefined_value();
@@ -7088,7 +7088,7 @@
        obj = obj->GetPrototype()) {
     JSObject* js_object = JSObject::cast(obj);
     for (int i = 0; i < this_property_assignments_count(); i++) {
-      LookupResult result;
+      LookupResult result(heap->isolate());
       String* name = GetThisPropertyAssignmentName(i);
       js_object->LocalLookupRealNamedProperty(name, &result);
       if (result.IsProperty() && result.type() == CALLBACKS) {
@@ -9634,7 +9634,7 @@
     String* name,
     PropertyAttributes* attributes) {
   // Check local property in holder, ignore interceptor.
-  LookupResult result;
+  LookupResult result(GetIsolate());
   LocalLookupRealNamedProperty(name, &result);
   if (result.IsProperty()) {
     return GetProperty(receiver, &result, name, attributes);
@@ -9652,7 +9652,7 @@
     String* name,
     PropertyAttributes* attributes) {
   // Check local property in holder, ignore interceptor.
-  LookupResult result;
+  LookupResult result(GetIsolate());
   LocalLookupRealNamedProperty(name, &result);
   if (result.IsProperty()) {
     return GetProperty(receiver, &result, name, attributes);
@@ -9703,15 +9703,15 @@

 bool JSObject::HasRealNamedProperty(String* key) {
   // Check access rights if needed.
+  Isolate* isolate = GetIsolate();
   if (IsAccessCheckNeeded()) {
-    Heap* heap = GetHeap();
-    if (!heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) {
-      heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
+    if (!isolate->MayNamedAccess(this, key, v8::ACCESS_HAS)) {
+      isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
       return false;
     }
   }

-  LookupResult result;
+  LookupResult result(isolate);
   LocalLookupRealNamedProperty(key, &result);
   return result.IsProperty() && (result.type() != INTERCEPTOR);
 }
@@ -9780,15 +9780,15 @@

 bool JSObject::HasRealNamedCallbackProperty(String* key) {
   // Check access rights if needed.
+  Isolate* isolate = GetIsolate();
   if (IsAccessCheckNeeded()) {
-    Heap* heap = GetHeap();
-    if (!heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) {
-      heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
+    if (!isolate->MayNamedAccess(this, key, v8::ACCESS_HAS)) {
+      isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
       return false;
     }
   }

-  LookupResult result;
+  LookupResult result(isolate);
   LocalLookupRealNamedProperty(key, &result);
   return result.IsProperty() && (result.type() == CALLBACKS);
 }
=======================================
--- /branches/bleeding_edge/src/profile-generator.cc Mon Oct 17 05:44:16 2011 +++ /branches/bleeding_edge/src/profile-generator.cc Tue Oct 18 04:18:55 2011
@@ -2166,15 +2166,16 @@


 String* V8HeapExplorer::GetConstructorName(JSObject* object) {
-  if (object->IsJSFunction()) return HEAP->closure_symbol();
+  Heap* heap = object->GetHeap();
+  if (object->IsJSFunction()) return heap->closure_symbol();
   String* constructor_name = object->constructor_name();
-  if (constructor_name == HEAP->Object_symbol()) {
+  if (constructor_name == heap->Object_symbol()) {
     // Look up an immediate "constructor" property, if it is a function,
     // return its name. This is for instances of binding objects, which
     // have prototype constructor type "Object".
     Object* constructor_prop = NULL;
-    LookupResult result;
- object->LocalLookupRealNamedProperty(HEAP->constructor_symbol(), &result);
+    LookupResult result(heap->isolate());
+ object->LocalLookupRealNamedProperty(heap->constructor_symbol(), &result);
     if (result.IsProperty()) {
       constructor_prop = result.GetLazyValue();
     }
=======================================
--- /branches/bleeding_edge/src/property.cc     Fri Sep  9 07:47:37 2011
+++ /branches/bleeding_edge/src/property.cc     Tue Oct 18 04:18:55 2011
@@ -31,6 +31,15 @@
 namespace internal {


+void LookupResult::Iterate(ObjectVisitor* visitor) {
+  LookupResult* current = this;  // Could be NULL.
+  while (current != NULL) {
+    visitor->VisitPointer(BitCast<Object**>(&current->holder_));
+    current = current->next_;
+  }
+}
+
+
 #ifdef OBJECT_PRINT
 void LookupResult::Print(FILE* out) {
   if (!IsFound()) {
=======================================
--- /branches/bleeding_edge/src/property.h      Fri Sep 23 08:09:00 2011
+++ /branches/bleeding_edge/src/property.h      Tue Oct 18 04:18:55 2011
@@ -164,10 +164,20 @@

 class LookupResult BASE_EMBEDDED {
  public:
-  LookupResult()
-      : lookup_type_(NOT_FOUND),
+  explicit LookupResult(Isolate* isolate)
+      : isolate_(isolate),
+        next_(isolate->top_lookup_result()),
+        lookup_type_(NOT_FOUND),
+        holder_(NULL),
         cacheable_(true),
-        details_(NONE, NORMAL) {}
+        details_(NONE, NORMAL) {
+    isolate->SetTopLookupResult(this);
+  }
+
+  ~LookupResult() {
+    ASSERT(isolate_->top_lookup_result() == this);
+    isolate_->SetTopLookupResult(next_);
+  }

void DescriptorResult(JSObject* holder, PropertyDetails details, int number) {
     lookup_type_ = DESCRIPTOR_TYPE;
@@ -215,6 +225,7 @@

   void NotFound() {
     lookup_type_ = NOT_FOUND;
+    holder_ = NULL;
   }

   JSObject* holder() {
@@ -345,8 +356,13 @@
     ASSERT(lookup_type_ == DICTIONARY_TYPE);
     return holder()->GetNormalizedProperty(this);
   }
+
+  void Iterate(ObjectVisitor* visitor);

  private:
+  Isolate* isolate_;
+  LookupResult* next_;
+
   // Where did we find the result;
   enum {
     NOT_FOUND,
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Tue Oct 18 01:46:46 2011
+++ /branches/bleeding_edge/src/runtime.cc      Tue Oct 18 04:18:55 2011
@@ -961,7 +961,7 @@
   HandleScope scope(isolate);
Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
   Handle<JSArray> desc = isolate->factory()->NewJSArrayWithElements(elms);
-  LookupResult result;
+  LookupResult result(isolate);
   CONVERT_ARG_CHECKED(JSObject, obj, 0);
   CONVERT_ARG_CHECKED(String, name, 1);

@@ -1240,7 +1240,7 @@
     if (value->IsUndefined() || is_const_property) {
       // Lookup the property in the global object, and don't set the
       // value of the variable if the property is already there.
-      LookupResult lookup;
+      LookupResult lookup(isolate);
       global->Lookup(*name, &lookup);
       if (lookup.IsProperty()) {
         // We found an existing property. Unless it was an interceptor
@@ -1267,7 +1267,7 @@
       value = function;
     }

-    LookupResult lookup;
+    LookupResult lookup(isolate);
     global->LocalLookup(*name, &lookup);

     // Compute the property attributes. According to ECMA-262, section
@@ -1399,7 +1399,7 @@
     // not real JSObjects.
     if (initial_value->IsTheHole() &&
         !object->IsJSContextExtensionObject()) {
-      LookupResult lookup;
+      LookupResult lookup(isolate);
       object->Lookup(*name, &lookup);
       if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) {
         return ThrowRedeclarationError(isolate, "const", name);
@@ -1443,7 +1443,7 @@
   // Note that objects can have hidden prototypes, so we need to traverse
   // the whole chain of hidden prototypes to do a 'local' lookup.
   Object* object = global;
-  LookupResult lookup;
+  LookupResult lookup(isolate);
   while (object->IsJSObject() &&
          JSObject::cast(object)->map()->is_hidden_prototype()) {
     JSObject* raw_holder = JSObject::cast(object);
@@ -1497,7 +1497,7 @@
   // add it as a local property even in case of callbacks in the
   // prototype chain (this rules out using SetProperty).
   // We use SetLocalPropertyIgnoreAttributes instead
-  LookupResult lookup;
+  LookupResult lookup(isolate);
   global->LocalLookup(*name, &lookup);
   if (!lookup.IsProperty()) {
     return global->SetLocalPropertyIgnoreAttributes(*name,
@@ -1614,7 +1614,7 @@
     // This is the property that was introduced by the const declaration.
     // Set it if it hasn't been set before.  NOTE: We cannot use
     // GetProperty() to get the current value as it 'unholes' the value.
-    LookupResult lookup;
+    LookupResult lookup(isolate);
     object->LocalLookupRealNamedProperty(*name, &lookup);
     ASSERT(lookup.IsProperty());  // the property was declared
     ASSERT(lookup.IsReadOnly());  // and it was declared as read-only
@@ -4135,7 +4135,7 @@
return value->IsTheHole() ? isolate->heap()->undefined_value() : value;
       }
// Lookup cache miss. Perform lookup and update the cache if appropriate.
-      LookupResult result;
+      LookupResult result(isolate);
       receiver->LocalLookup(key, &result);
       if (result.IsProperty() && result.type() == FIELD) {
         int offset = result.GetFieldIndex();
@@ -4190,7 +4190,7 @@
   int unchecked = flag_attr->value();
RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   RUNTIME_ASSERT(!obj->IsNull());
-  LookupResult result;
+  LookupResult result(isolate);
   obj->LocalLookupRealNamedProperty(name, &result);

   PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
@@ -4274,7 +4274,7 @@
     return *obj_value;
   }

-  LookupResult result;
+  LookupResult result(isolate);
   js_object->LocalLookupRealNamedProperty(*name, &result);

   // To be compatible with safari we do not change the value on API objects
@@ -10361,7 +10361,7 @@
   // Try local lookup on each of the objects.
   Handle<JSObject> jsproto = obj;
   for (int i = 0; i < length; i++) {
-    LookupResult result;
+    LookupResult result(isolate);
     jsproto->LocalLookup(*name, &result);
     if (result.IsProperty()) {
       // LookupResult is not GC safe as it holds raw object pointers.
@@ -10418,7 +10418,7 @@
   CONVERT_ARG_CHECKED(JSObject, obj, 0);
   CONVERT_ARG_CHECKED(String, name, 1);

-  LookupResult result;
+  LookupResult result(isolate);
   obj->Lookup(*name, &result);
   if (result.IsProperty()) {
return DebugLookupResultValue(isolate->heap(), *obj, *name, &result, NULL);
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Mon Oct 17 00:43:40 2011 +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Oct 18 04:18:55 2011
@@ -2129,7 +2129,7 @@
                                                Register object,
                                                Handle<Map> type,
                                                Handle<String> name) {
-  LookupResult lookup;
+  LookupResult lookup(isolate());
   type->LookupInDescriptors(NULL, *name, &lookup);
   ASSERT(lookup.IsProperty() &&
          (lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION));
=======================================
--- /branches/bleeding_edge/src/x64/stub-cache-x64.cc Wed Oct 12 09:00:59 2011 +++ /branches/bleeding_edge/src/x64/stub-cache-x64.cc Tue Oct 18 04:18:55 2011
@@ -2221,7 +2221,7 @@
   // Get the number of arguments.
   const int argc = arguments().immediate();

-  LookupResult lookup;
+  LookupResult lookup(isolate());
   LookupPostInterceptor(holder, name, &lookup);

   // Get the receiver from the stack.
@@ -2765,7 +2765,7 @@
   // -----------------------------------
   Label miss;

-  LookupResult lookup;
+  LookupResult lookup(isolate());
   LookupPostInterceptor(holder, name, &lookup);

   // TODO(368): Compile in the whole chain: all the interceptors in
@@ -2949,7 +2949,7 @@
   __ Cmp(rax, Handle<String>(name));
   __ j(not_equal, &miss);

-  LookupResult lookup;
+  LookupResult lookup(isolate());
   LookupPostInterceptor(holder, name, &lookup);
   GenerateLoadInterceptor(receiver,
                           holder,

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to