From: mstarzinger@chromium.org Date: Fri, 13 Sep 2013 09:51:11 +0000 (+0000) Subject: Handlify JSObject::DeepCopy method. X-Git-Tag: upstream/4.7.83~12508 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=50b0567640ba4d78612ec46c2049d29ba4d1d5f3;p=platform%2Fupstream%2Fv8.git Handlify JSObject::DeepCopy method. R=verwaest@chromium.org Review URL: https://codereview.chromium.org/22934006 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16708 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/api.cc b/src/api.cc index 71a8f4a..5b41f92 100644 --- a/src/api.cc +++ b/src/api.cc @@ -3813,7 +3813,7 @@ Local v8::Object::Clone() { ENTER_V8(isolate); i::Handle self = Utils::OpenHandle(this); EXCEPTION_PREAMBLE(isolate); - i::Handle result = i::Copy(self); + i::Handle result = i::JSObject::Copy(self); has_pending_exception = result.is_null(); EXCEPTION_BAILOUT_CHECK(isolate, Local()); return Utils::ToLocal(result); @@ -6212,7 +6212,7 @@ Local Array::CloneElementAt(uint32_t index) { i::Handle paragon_handle(i::JSObject::cast(paragon)); EXCEPTION_PREAMBLE(isolate); ENTER_V8(isolate); - i::Handle result = i::Copy(paragon_handle); + i::Handle result = i::JSObject::Copy(paragon_handle); has_pending_exception = result.is_null(); EXCEPTION_BAILOUT_CHECK(isolate, Local()); return Utils::ToLocal(result); diff --git a/src/handles.cc b/src/handles.cc index b3704df..033fdab 100644 --- a/src/handles.cc +++ b/src/handles.cc @@ -294,21 +294,6 @@ Handle SubString(Handle str, } -Handle Copy(Handle obj) { - Isolate* isolate = obj->GetIsolate(); - CALL_HEAP_FUNCTION(isolate, - isolate->heap()->CopyJSObject(*obj), JSObject); -} - - -Handle DeepCopy(Handle obj) { - Isolate* isolate = obj->GetIsolate(); - CALL_HEAP_FUNCTION(isolate, - obj->DeepCopy(isolate), - JSObject); -} - - // Wrappers for scripts are kept alive and cached in weak global // handles referred from foreign objects held by the scripts as long as // they are used. When they are not used anymore, the garbage diff --git a/src/handles.h b/src/handles.h index c3e4dca..585f7b4 100644 --- a/src/handles.h +++ b/src/handles.h @@ -255,10 +255,6 @@ Handle GetProperty(Isolate* isolate, Handle LookupSingleCharacterStringFromCode(Isolate* isolate, uint32_t index); -Handle Copy(Handle obj); - -Handle DeepCopy(Handle obj); - Handle AddKeysFromJSArray(Handle, Handle array); diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 23c373f..c1b0ece 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -4172,8 +4172,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { IsFastLiteral(Handle::cast(boilerplate), kMaxFastLiteralDepth, &max_properties)) { - Handle boilerplate_object = - Handle::cast(boilerplate); + Handle boilerplate_object = Handle::cast(boilerplate); literal = BuildFastLiteral(boilerplate_object, Handle::null(), diff --git a/src/isolate.cc b/src/isolate.cc index 6fa496a..ceb8809 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -1087,7 +1087,7 @@ Failure* Isolate::StackOverflow() { Handle key = factory()->stack_overflow_string(); Handle boilerplate = Handle::cast(GetProperty(this, js_builtins_object(), key)); - Handle exception = Copy(boilerplate); + Handle exception = JSObject::Copy(boilerplate); DoThrow(*exception, NULL); // Get stack trace limit. diff --git a/src/objects.cc b/src/objects.cc index e37f6d1..87f8a1b 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -5635,71 +5635,78 @@ MUST_USE_RESULT MaybeObject* JSObject::SetObserved(Isolate* isolate) { } -MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) { - StackLimitCheck check(isolate); - if (check.HasOverflowed()) return isolate->StackOverflow(); +// TODO(mstarzinger): Temporary wrapper until handlified. +static Handle NewStorageFor(Isolate* isolate, + Handle object, + Representation representation) { + Heap* heap = isolate->heap(); + CALL_HEAP_FUNCTION(isolate, + object->AllocateNewStorageFor(heap, representation), + Object); +} - if (map()->is_deprecated()) { - MaybeObject* maybe_failure = MigrateInstance(); - if (maybe_failure->IsFailure()) return maybe_failure; + +Handle JSObject::Copy(Handle object) { + Isolate* isolate = object->GetIsolate(); + CALL_HEAP_FUNCTION(isolate, + isolate->heap()->CopyJSObject(*object), JSObject); +} + + +Handle JSObject::DeepCopy(Handle object) { + Isolate* isolate = object->GetIsolate(); + StackLimitCheck check(isolate); + if (check.HasOverflowed()) { + isolate->StackOverflow(); + return Handle::null(); } - Heap* heap = isolate->heap(); - Object* result; - { MaybeObject* maybe_result = heap->CopyJSObject(this); - if (!maybe_result->ToObject(&result)) return maybe_result; + if (object->map()->is_deprecated()) { + MigrateInstance(object); } - JSObject* copy = JSObject::cast(result); + + Handle copy = Copy(object); // Deep copy local properties. if (copy->HasFastProperties()) { - DescriptorArray* descriptors = copy->map()->instance_descriptors(); + Handle descriptors(copy->map()->instance_descriptors()); int limit = copy->map()->NumberOfOwnDescriptors(); for (int i = 0; i < limit; i++) { PropertyDetails details = descriptors->GetDetails(i); if (details.type() != FIELD) continue; int index = descriptors->GetFieldIndex(i); - Object* value = RawFastPropertyAt(index); + Handle value(object->RawFastPropertyAt(index), isolate); if (value->IsJSObject()) { - JSObject* js_object = JSObject::cast(value); - MaybeObject* maybe_copy = js_object->DeepCopy(isolate); - if (!maybe_copy->To(&value)) return maybe_copy; + value = DeepCopy(Handle::cast(value)); + RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle()); } else { Representation representation = details.representation(); - MaybeObject* maybe_storage = - value->AllocateNewStorageFor(heap, representation); - if (!maybe_storage->To(&value)) return maybe_storage; + value = NewStorageFor(isolate, value, representation); } - copy->FastPropertyAtPut(index, value); + copy->FastPropertyAtPut(index, *value); } } 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); + Handle names = + isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties()); + 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)); + Handle key_string(String::cast(names->get(i))); PropertyAttributes attributes = - copy->GetLocalPropertyAttribute(key_string); + 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(); + Handle value( + copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(), + isolate); 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; - } + Handle result = DeepCopy(Handle::cast(value)); + RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle()); + // Creating object copy for literals. No strict mode needed. + CHECK_NOT_EMPTY_HANDLE(isolate, SetProperty( + copy, key_string, result, NONE, kNonStrictMode)); } } } @@ -5712,8 +5719,8 @@ MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) { 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()) { + Handle elements(FixedArray::cast(copy->elements())); + if (elements->map() == isolate->heap()->fixed_cow_array_map()) { isolate->counters()->cow_arrays_created_runtime()->Increment(); #ifdef DEBUG for (int i = 0; i < elements->length(); i++) { @@ -5722,34 +5729,31 @@ MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) { #endif } else { for (int i = 0; i < elements->length(); i++) { - Object* value = elements->get(i); + Handle value(elements->get(i), isolate); 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); + Handle result = DeepCopy(Handle::cast(value)); + RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle()); + elements->set(i, *result); } } } break; } case DICTIONARY_ELEMENTS: { - SeededNumberDictionary* element_dictionary = copy->element_dictionary(); + Handle 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); + Handle value(element_dictionary->ValueAt(i), isolate); 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); + Handle result = DeepCopy(Handle::cast(value)); + RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle()); + element_dictionary->ValueAtPut(i, *result); } } } diff --git a/src/objects.h b/src/objects.h index d3593b6..2de98db 100644 --- a/src/objects.h +++ b/src/objects.h @@ -2630,8 +2630,9 @@ class JSObject: public JSReceiver { // Called the first time an object is observed with ES7 Object.observe. MUST_USE_RESULT MaybeObject* SetObserved(Isolate* isolate); - // Copy object - MUST_USE_RESULT MaybeObject* DeepCopy(Isolate* isolate); + // Copy object. + static Handle Copy(Handle object); + static Handle DeepCopy(Handle object); // Dispatched behavior. void JSObjectShortPrint(StringStream* accumulator); diff --git a/src/runtime.cc b/src/runtime.cc index c09fb1d..5f36af2 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -499,7 +499,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteral) { // Update the functions literal and return the boilerplate. literals->set(literals_index, *boilerplate); } - return JSObject::cast(*boilerplate)->DeepCopy(isolate); + + Handle copy = JSObject::DeepCopy(Handle::cast(boilerplate)); + RETURN_IF_EMPTY_HANDLE(isolate, copy); + return *copy; } @@ -564,8 +567,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteral) { literals_index, elements); RETURN_IF_EMPTY_HANDLE(isolate, site); - JSObject* boilerplate = JSObject::cast(site->transition_info()); - return boilerplate->DeepCopy(isolate); + Handle boilerplate(JSObject::cast(site->transition_info())); + Handle copy = JSObject::DeepCopy(boilerplate); + RETURN_IF_EMPTY_HANDLE(isolate, copy); + return *copy; } diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc index 9d74011..9e4e907 100644 --- a/test/cctest/test-heap.cc +++ b/test/cctest/test-heap.cc @@ -814,7 +814,7 @@ TEST(JSObjectCopy) { obj->SetElement(1, *second, NONE, kNonStrictMode)->ToObjectChecked(); // Make the clone. - Handle clone = Copy(obj); + Handle clone = JSObject::Copy(obj); CHECK(!clone.is_identical_to(obj)); CHECK_EQ(obj->GetElement(isolate, 0), clone->GetElement(isolate, 0));