Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(221)

Unified Diff: src/objects.cc

Issue 25025002: Use a walking visitor to traverse JSObject structure. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Missed a spot! Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | test/mjsunit/big-array-literal.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 1399e33ffab4acb74f42abd63ad646747b9b61cc..6ca8bdf4fd0bba1f18df887d5f7798eb5ea577d8 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -5583,7 +5583,53 @@ 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);
+ }
+
+ // Returns true if the visitor is a copying visitor.
+ virtual bool is_copying() = 0;
+
+ protected:
+ Handle<JSObject> StructureWalk(Handle<JSObject> object);
+
+ // 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);
+ }
+};
+
+
+Handle<JSObject> JSObjectWalkVisitor::StructureWalk(Handle<JSObject> object) {
+ bool copying = is_copying();
Isolate* isolate = object->GetIsolate();
StackLimitCheck check(isolate);
if (check.HasOverflowed()) {
@@ -5592,10 +5638,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 = VisitObject(object);
+ ASSERT(copying || copy.is_identical_to(object));
HandleScope scope(isolate);
@@ -5609,13 +5656,15 @@ 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 = 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 (copying) {
+ copy->FastPropertyAtPut(index, *value);
+ }
}
} else {
Handle<FixedArray> names =
@@ -5634,11 +5683,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 = 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 (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 +5718,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 = VisitElementOrProperty(
+ copy, Handle<JSObject>::cast(value));
RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
- elements->set(i, *result);
+ if (copying) {
+ elements->set(i, *result);
+ }
}
}
}
@@ -5683,9 +5738,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 = VisitElementOrProperty(
+ copy, Handle<JSObject>::cast(value));
RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
- element_dictionary->ValueAtPut(i, *result);
+ if (copying) {
+ element_dictionary->ValueAtPut(i, *result);
+ }
}
}
}
@@ -5712,6 +5770,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).
« no previous file with comments | « no previous file | test/mjsunit/big-array-literal.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698