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

Unified Diff: src/objects.cc

Issue 13527005: Move DeepCopy of JSObject from runtime to object. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 9 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 | « src/objects.h ('k') | src/runtime.cc » ('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 a3163eb619c6d76ff18ab33db93ded19414542c3..f3e7471c07b74a43421ae1c90f110d9374211ec5 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -4689,6 +4689,145 @@ MaybeObject* JSObject::PreventExtensions() {
}
+MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) {
+ StackLimitCheck check(isolate);
+ if (check.HasOverflowed()) return isolate->StackOverflow();
+
+ Heap* heap = isolate->heap();
+ Object* result;
+ { MaybeObject* maybe_result = heap->CopyJSObject(this);
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ }
+ JSObject* copy = JSObject::cast(result);
+
+ // Deep copy local properties.
+ if (copy->HasFastProperties()) {
+ FixedArray* properties = copy->properties();
+ for (int i = 0; i < properties->length(); i++) {
+ Object* value = properties->get(i);
+ if (value->IsJSObject()) {
+ JSObject* js_object = JSObject::cast(value);
+ { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ }
+ properties->set(i, result);
+ }
+ }
+ int nof = copy->map()->inobject_properties();
+ for (int i = 0; i < nof; i++) {
+ Object* value = copy->InObjectPropertyAt(i);
+ if (value->IsJSObject()) {
+ JSObject* js_object = JSObject::cast(value);
+ { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ }
+ copy->InObjectPropertyAtPut(i, result);
+ }
+ }
+ } else {
+ { MaybeObject* maybe_result =
+ heap->AllocateFixedArray(copy->NumberOfLocalProperties());
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ }
+ FixedArray* names = FixedArray::cast(result);
+ copy->GetLocalPropertyNames(names, 0);
+ for (int i = 0; i < names->length(); i++) {
+ ASSERT(names->get(i)->IsString());
+ String* key_string = String::cast(names->get(i));
+ PropertyAttributes attributes =
+ copy->GetLocalPropertyAttribute(key_string);
+ // Only deep copy fields from the object literal expression.
+ // In particular, don't try to copy the length attribute of
+ // an array.
+ if (attributes != NONE) continue;
+ Object* value =
+ copy->GetProperty(key_string, &attributes)->ToObjectUnchecked();
+ if (value->IsJSObject()) {
+ JSObject* js_object = JSObject::cast(value);
+ { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ }
+ { MaybeObject* maybe_result =
+ // Creating object copy for literals. No strict mode needed.
+ copy->SetProperty(key_string, result, NONE, kNonStrictMode);
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ }
+ }
+ }
+ }
+
+ // Deep copy local elements.
+ // Pixel elements cannot be created using an object literal.
+ ASSERT(!copy->HasExternalArrayElements());
+ switch (copy->GetElementsKind()) {
+ case FAST_SMI_ELEMENTS:
+ case FAST_ELEMENTS:
+ case FAST_HOLEY_SMI_ELEMENTS:
+ case FAST_HOLEY_ELEMENTS: {
+ FixedArray* elements = FixedArray::cast(copy->elements());
+ if (elements->map() == heap->fixed_cow_array_map()) {
+ isolate->counters()->cow_arrays_created_runtime()->Increment();
+#ifdef DEBUG
+ for (int i = 0; i < elements->length(); i++) {
+ ASSERT(!elements->get(i)->IsJSObject());
+ }
+#endif
+ } else {
+ for (int i = 0; i < elements->length(); i++) {
+ Object* value = elements->get(i);
+ ASSERT(value->IsSmi() ||
+ value->IsTheHole() ||
+ (IsFastObjectElementsKind(copy->GetElementsKind())));
+ if (value->IsJSObject()) {
+ JSObject* js_object = JSObject::cast(value);
+ { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ }
+ elements->set(i, result);
+ }
+ }
+ }
+ break;
+ }
+ case DICTIONARY_ELEMENTS: {
+ SeededNumberDictionary* element_dictionary = copy->element_dictionary();
+ int capacity = element_dictionary->Capacity();
+ for (int i = 0; i < capacity; i++) {
+ Object* k = element_dictionary->KeyAt(i);
+ if (element_dictionary->IsKey(k)) {
+ Object* value = element_dictionary->ValueAt(i);
+ if (value->IsJSObject()) {
+ JSObject* js_object = JSObject::cast(value);
+ { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ }
+ element_dictionary->ValueAtPut(i, result);
+ }
+ }
+ }
+ break;
+ }
+ case NON_STRICT_ARGUMENTS_ELEMENTS:
+ UNIMPLEMENTED();
+ break;
+ case EXTERNAL_PIXEL_ELEMENTS:
+ case EXTERNAL_BYTE_ELEMENTS:
+ case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+ case EXTERNAL_SHORT_ELEMENTS:
+ case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
+ case EXTERNAL_INT_ELEMENTS:
+ case EXTERNAL_UNSIGNED_INT_ELEMENTS:
+ case EXTERNAL_FLOAT_ELEMENTS:
+ case EXTERNAL_DOUBLE_ELEMENTS:
+ case FAST_DOUBLE_ELEMENTS:
+ case FAST_HOLEY_DOUBLE_ELEMENTS:
+ // No contained objects, nothing to do.
+ break;
+ }
+ 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 | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698