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.