When redefining accessor properties, defensively copy AccessorPairs.
authorsvenpanne@chromium.org <svenpanne@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 23 Feb 2012 12:12:28 +0000 (12:12 +0000)
committersvenpanne@chromium.org <svenpanne@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 23 Feb 2012 12:12:28 +0000 (12:12 +0000)
The previous code relied on the tricky global invariant that there is no map
sharing when accessor properties are involved (or in other words: that
TransformToFastProperties is dumb enough :-). Although this is not a real
problem with the current code, this assumption breaks when map sharing in fast
mode is enabled, so we defensively copy an AccessorPair.

Review URL: https://chromiumcodereview.appspot.com/9430048

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10810 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/objects.cc

index 17d2bc8..17ef8df 100644 (file)
@@ -4471,9 +4471,14 @@ MaybeObject* JSObject::DefinePropertyAccessor(String* name,
       Object* obj = result.GetCallbackObject();
       // Need to preserve old getters/setters.
       if (obj->IsAccessorPair()) {
-        AccessorPair::cast(obj)->set(is_getter, fun);
+        AccessorPair* copy;
+        { MaybeObject* maybe_copy =
+              AccessorPair::cast(obj)->CopyWithoutTransitions();
+          if (!maybe_copy->To(&copy)) return maybe_copy;
+        }
+        copy->set(is_getter, fun);
         // Use set to update attributes.
-        { MaybeObject* maybe_ok = SetPropertyCallback(name, obj, attributes);
+        { MaybeObject* maybe_ok = SetPropertyCallback(name, copy, attributes);
           if (maybe_ok->IsFailure()) return maybe_ok;
         }
         return GetHeap()->undefined_value();