Reviewers: Yang,

Message:
Hi Yang, here is the visitor I was talking about.
Thanks,
--Michael

Description:
Use a walking visitor to traverse JSObject structure. The purpose is to prepare for more complex context-dependent walks of the structure, needed for allocation site and pretenuring work. Different visitors can be created that annotate the
object in various ways.

BUG=

Please review this at https://codereview.chromium.org/25025002/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+83, -13 lines):
  M src/objects.cc


Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 1399e33ffab4acb74f42abd63ad646747b9b61cc..ddf02ff3ed7ef4eeab93c7d0ce43bf3afd08a789 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -5583,7 +5583,56 @@ Handle<JSObject> JSObject::Copy(Handle<JSObject> object) {
 }


-Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) {
+class JSObjectWalkVisitor {
+ public:
+  explicit JSObjectWalkVisitor() {}
+  virtual ~JSObjectWalkVisitor() {}
+
+  Handle<JSObject> Visit(Handle<JSObject> object) {
+    return StructureWalk(object, this);
+  }
+
+  // Returns true if the visitor is a copying visitor.
+  virtual bool is_copying() = 0;
+
+ protected:
+  Handle<JSObject> StructureWalk(Handle<JSObject> object,
+                                 JSObjectWalkVisitor* visitor);
+
+  // The returned handle should point to a new object if the visitor is a
+  // copying visitor, otherwise it should be the same as the input object.
+  virtual Handle<JSObject> VisitObject(Handle<JSObject> object) = 0;
+
+  // The returned handle should point to a new value if the visitor is a
+  // copying visitor, otherwise it should be the same as the input value.
+  virtual Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object,
+ Handle<JSObject> value) = 0;
+};
+
+
+class JSObjectCopyVisitor: public JSObjectWalkVisitor {
+ public:
+  explicit JSObjectCopyVisitor() {}
+
+  virtual bool is_copying() V8_OVERRIDE { return true; }
+
+ protected:
+ virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE {
+    return JSObject::Copy(object);
+  }
+
+  virtual Handle<JSObject> VisitElementOrProperty(
+      Handle<JSObject> object,
+      Handle<JSObject> value) V8_OVERRIDE {
+    return StructureWalk(value, this);
+  }
+};
+
+
+Handle<JSObject> JSObjectWalkVisitor::StructureWalk(
+    Handle<JSObject> object,
+    JSObjectWalkVisitor* visitor) {
+  bool is_copying = visitor->is_copying();
   Isolate* isolate = object->GetIsolate();
   StackLimitCheck check(isolate);
   if (check.HasOverflowed()) {
@@ -5592,10 +5641,11 @@ Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) {
   }

   if (object->map()->is_deprecated()) {
-    MigrateInstance(object);
+    JSObject::MigrateInstance(object);
   }

-  Handle<JSObject> copy = Copy(object);
+  Handle<JSObject> copy = visitor->VisitObject(object);
+  ASSERT(visitor->is_copying() || copy.is_identical_to(object));

   HandleScope scope(isolate);

@@ -5609,13 +5659,16 @@ Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) {
       int index = descriptors->GetFieldIndex(i);
       Handle<Object> value(object->RawFastPropertyAt(index), isolate);
       if (value->IsJSObject()) {
-        value = DeepCopy(Handle<JSObject>::cast(value));
+        value = visitor->VisitElementOrProperty(copy,
+ Handle<JSObject>::cast(value));
         RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<JSObject>());
       } else {
         Representation representation = details.representation();
         value = NewStorageFor(isolate, value, representation);
       }
-      copy->FastPropertyAtPut(index, *value);
+      if (is_copying) {
+        copy->FastPropertyAtPut(index, *value);
+      }
     }
   } else {
     Handle<FixedArray> names =
@@ -5634,11 +5687,14 @@ Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) {
           copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(),
           isolate);
       if (value->IsJSObject()) {
-        Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value));
+        Handle<JSObject> result = visitor->VisitElementOrProperty(
+            copy, Handle<JSObject>::cast(value));
         RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
-        // Creating object copy for literals. No strict mode needed.
-        CHECK_NOT_EMPTY_HANDLE(isolate, SetProperty(
-            copy, key_string, result, NONE, kNonStrictMode));
+        if (is_copying) {
+          // Creating object copy for literals. No strict mode needed.
+          CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty(
+              copy, key_string, result, NONE, kNonStrictMode));
+        }
       }
     }
   }
@@ -5666,9 +5722,12 @@ Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) {
                  value->IsTheHole() ||
                  (IsFastObjectElementsKind(copy->GetElementsKind())));
           if (value->IsJSObject()) {
- Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value));
+            Handle<JSObject> result = visitor->VisitElementOrProperty(
+                copy, Handle<JSObject>::cast(value));
RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
-            elements->set(i, *result);
+            if (is_copying) {
+              elements->set(i, *result);
+            }
           }
         }
       }
@@ -5683,9 +5742,12 @@ Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) {
         if (element_dictionary->IsKey(k)) {
           Handle<Object> value(element_dictionary->ValueAt(i), isolate);
           if (value->IsJSObject()) {
- Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value));
+            Handle<JSObject> result = visitor->VisitElementOrProperty(
+                copy, Handle<JSObject>::cast(value));
RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
-            element_dictionary->ValueAtPut(i, *result);
+            if (is_copying) {
+              element_dictionary->ValueAtPut(i, *result);
+            }
           }
         }
       }
@@ -5712,6 +5774,14 @@ Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) {
 }


+Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) {
+  JSObjectCopyVisitor v;
+  Handle<JSObject> copy = v.Visit(object);
+  ASSERT(v.is_copying() && !copy.is_identical_to(object));
+  return copy;
+}
+
+
 // Tests for the fast common case for property enumeration:
 // - This object and all prototypes has an enum cache (which means that
 //   it is no proxy, has no interceptors and needs no access checks).


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to