Author: [email protected]
Date: Fri May  8 05:39:37 2009
New Revision: 1903

Modified:
    branches/bleeding_edge/src/objects.cc
    branches/bleeding_edge/src/objects.h
    branches/bleeding_edge/src/runtime.cc
    branches/bleeding_edge/test/cctest/test-api.cc

Log:
Fix intermittent crashes caused by unexpected GCs in
HasLocalProperty (bug introduced in r1882 et al.)
Review URL: http://codereview.chromium.org/115106

Modified: branches/bleeding_edge/src/objects.cc
==============================================================================
--- branches/bleeding_edge/src/objects.cc       (original)
+++ branches/bleeding_edge/src/objects.cc       Fri May  8 05:39:37 2009
@@ -5161,7 +5161,8 @@
    }

    // Only attempt to find the hidden properties in the local object and not
-  // in the prototype chain.
+  // in the prototype chain.  Note that HasLocalProperty() can cause a GC  
in
+  // the general case, but in this case we know it won't hit an  
interceptor.
    if (!this->HasLocalProperty(key)) {
      // Hidden properties object not found. Allocate a new hidden properties
      // object if requested. Otherwise return the undefined value.

Modified: branches/bleeding_edge/src/objects.h
==============================================================================
--- branches/bleeding_edge/src/objects.h        (original)
+++ branches/bleeding_edge/src/objects.h        Fri May  8 05:39:37 2009
@@ -1262,6 +1262,7 @@
      return GetPropertyAttribute(name) != ABSENT;
    }

+  // Can cause a GC if it hits an interceptor.
    bool HasLocalProperty(String* name) {
      return GetLocalPropertyAttribute(name) != ABSENT;
    }

Modified: branches/bleeding_edge/src/runtime.cc
==============================================================================
--- branches/bleeding_edge/src/runtime.cc       (original)
+++ branches/bleeding_edge/src/runtime.cc       Fri May  8 05:39:37 2009
@@ -2832,19 +2832,37 @@
  }


-static Object* HasLocalPropertyImplementation(Object* obj, String* key) {
+static Object* HasLocalPropertyImplementation(Handle<JSObject> object,
+                                              Handle<String> key) {
+  if (object->HasLocalProperty(*key)) return Heap::true_value();
+  // Handle hidden prototypes.  If there's a hidden prototype above this  
thing
+  // then we have to check it for properties, because they are supposed to
+  // look like they are on this object.
+  Handle<Object> proto(object->GetPrototype());
+  if (proto->IsJSObject() &&
+      Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) {
+    return HasLocalPropertyImplementation(Handle<JSObject>::cast(proto),  
key);
+  }
+  return Heap::false_value();
+}
+
+
+static Object* Runtime_HasLocalProperty(Arguments args) {
+  NoHandleAllocation ha;
+  ASSERT(args.length() == 2);
+  CONVERT_CHECKED(String, key, args[1]);
+
+  Object* obj = args[0];
    // Only JS objects can have properties.
    if (obj->IsJSObject()) {
      JSObject* object = JSObject::cast(obj);
-    if (object->HasLocalProperty(key)) return Heap::true_value();
-    // Handle hidden prototypes.  If there's a hidden prototype above this  
thing
-    // then we have to check it for properties, because they are supposed  
to
-    // look like they are on this object.
-    Object* proto = object->GetPrototype();
-    if (proto->IsJSObject() &&
-        JSObject::cast(proto)->map()->is_hidden_prototype()) {
-      return HasLocalPropertyImplementation(object->GetPrototype(), key);
-    }
+    // Fast case - no interceptors.
+    if (object->HasRealNamedProperty(key)) return Heap::true_value();
+    // Slow case.  Either it's not there or we have an interceptor.  We  
should
+    // have handles for this kind of deal.
+    HandleScope scope;
+    return HasLocalPropertyImplementation(Handle<JSObject>(object),
+                                          Handle<String>(key));
    } else if (obj->IsString()) {
      // Well, there is one exception:  Handle [] on strings.
      uint32_t index;
@@ -2855,15 +2873,6 @@
      }
    }
    return Heap::false_value();
-}
-
-
-static Object* Runtime_HasLocalProperty(Arguments args) {
-  NoHandleAllocation ha;
-  ASSERT(args.length() == 2);
-  CONVERT_CHECKED(String, key, args[1]);
-
-  return HasLocalPropertyImplementation(args[0], key);
  }



Modified: branches/bleeding_edge/test/cctest/test-api.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-api.cc      (original)
+++ branches/bleeding_edge/test/cctest/test-api.cc      Fri May  8 05:39:37 2009
@@ -4739,6 +4739,44 @@
  }


+static v8::Handle<Value> InterceptorHasOwnPropertyGetterGC(
+    Local<String> name,
+    const AccessorInfo& info) {
+  ApiTestFuzzer::Fuzz();
+  i::Heap::CollectAllGarbage();
+  return v8::Handle<Value>();
+}
+
+
+THREADED_TEST(InterceptorHasOwnPropertyCausingGC) {
+  v8::HandleScope scope;
+  LocalContext context;
+  Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+  Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate();
+   
instance_templ->SetNamedPropertyHandler(InterceptorHasOwnPropertyGetterGC);
+  Local<Function> function = fun_templ->GetFunction();
+  context->Global()->Set(v8_str("constructor"), function);
+  // Let's first make some stuff so we can be sure to get a good GC.
+  CompileRun(
+      "function makestr(size) {"
+      "  switch (size) {"
+      "    case 1: return 'f';"
+      "    case 2: return 'fo';"
+      "    case 3: return 'foo';"
+      "  }"
+      "  return makestr(size >> 1) + makestr((size + 1) >> 1);"
+      "}"
+      "var x = makestr(12345);"
+      "x = makestr(31415);"
+      "x = makestr(23456);");
+  v8::Handle<Value> value = CompileRun(
+      "var o = new constructor();"
+      "o.__proto__ = new String(x);"
+      "o.hasOwnProperty('ostehaps');");
+  CHECK_EQ(false, value->BooleanValue());
+}
+
+
  static v8::Handle<Value> InterceptorLoadICGetter(Local<String> name,
                                                   const AccessorInfo& info)  
{
    ApiTestFuzzer::Fuzz();

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

Reply via email to