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

Side by Side Diff: src/runtime.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, 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 // and store it in a LanguageMode variable with the given name. 132 // and store it in a LanguageMode variable with the given name.
133 #define CONVERT_LANGUAGE_MODE_ARG(name, index) \ 133 #define CONVERT_LANGUAGE_MODE_ARG(name, index) \
134 ASSERT(args[index]->IsSmi()); \ 134 ASSERT(args[index]->IsSmi()); \
135 ASSERT(args.smi_at(index) == CLASSIC_MODE || \ 135 ASSERT(args.smi_at(index) == CLASSIC_MODE || \
136 args.smi_at(index) == STRICT_MODE || \ 136 args.smi_at(index) == STRICT_MODE || \
137 args.smi_at(index) == EXTENDED_MODE); \ 137 args.smi_at(index) == EXTENDED_MODE); \
138 LanguageMode name = \ 138 LanguageMode name = \
139 static_cast<LanguageMode>(args.smi_at(index)); 139 static_cast<LanguageMode>(args.smi_at(index));
140 140
141 141
142 MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate,
143 JSObject* boilerplate) {
144 StackLimitCheck check(isolate);
145 if (check.HasOverflowed()) return isolate->StackOverflow();
146
147 Heap* heap = isolate->heap();
148 Object* result;
149 { MaybeObject* maybe_result = heap->CopyJSObject(boilerplate);
150 if (!maybe_result->ToObject(&result)) return maybe_result;
151 }
152 JSObject* copy = JSObject::cast(result);
153
154 // Deep copy local properties.
155 if (copy->HasFastProperties()) {
156 FixedArray* properties = copy->properties();
157 for (int i = 0; i < properties->length(); i++) {
158 Object* value = properties->get(i);
159 if (value->IsJSObject()) {
160 JSObject* js_object = JSObject::cast(value);
161 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, js_object);
162 if (!maybe_result->ToObject(&result)) return maybe_result;
163 }
164 properties->set(i, result);
165 }
166 }
167 int nof = copy->map()->inobject_properties();
168 for (int i = 0; i < nof; i++) {
169 Object* value = copy->InObjectPropertyAt(i);
170 if (value->IsJSObject()) {
171 JSObject* js_object = JSObject::cast(value);
172 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, js_object);
173 if (!maybe_result->ToObject(&result)) return maybe_result;
174 }
175 copy->InObjectPropertyAtPut(i, result);
176 }
177 }
178 } else {
179 { MaybeObject* maybe_result =
180 heap->AllocateFixedArray(copy->NumberOfLocalProperties());
181 if (!maybe_result->ToObject(&result)) return maybe_result;
182 }
183 FixedArray* names = FixedArray::cast(result);
184 copy->GetLocalPropertyNames(names, 0);
185 for (int i = 0; i < names->length(); i++) {
186 ASSERT(names->get(i)->IsString());
187 String* key_string = String::cast(names->get(i));
188 PropertyAttributes attributes =
189 copy->GetLocalPropertyAttribute(key_string);
190 // Only deep copy fields from the object literal expression.
191 // In particular, don't try to copy the length attribute of
192 // an array.
193 if (attributes != NONE) continue;
194 Object* value =
195 copy->GetProperty(key_string, &attributes)->ToObjectUnchecked();
196 if (value->IsJSObject()) {
197 JSObject* js_object = JSObject::cast(value);
198 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, js_object);
199 if (!maybe_result->ToObject(&result)) return maybe_result;
200 }
201 { MaybeObject* maybe_result =
202 // Creating object copy for literals. No strict mode needed.
203 copy->SetProperty(key_string, result, NONE, kNonStrictMode);
204 if (!maybe_result->ToObject(&result)) return maybe_result;
205 }
206 }
207 }
208 }
209
210 // Deep copy local elements.
211 // Pixel elements cannot be created using an object literal.
212 ASSERT(!copy->HasExternalArrayElements());
213 switch (copy->GetElementsKind()) {
214 case FAST_SMI_ELEMENTS:
215 case FAST_ELEMENTS:
216 case FAST_HOLEY_SMI_ELEMENTS:
217 case FAST_HOLEY_ELEMENTS: {
218 FixedArray* elements = FixedArray::cast(copy->elements());
219 if (elements->map() == heap->fixed_cow_array_map()) {
220 isolate->counters()->cow_arrays_created_runtime()->Increment();
221 #ifdef DEBUG
222 for (int i = 0; i < elements->length(); i++) {
223 ASSERT(!elements->get(i)->IsJSObject());
224 }
225 #endif
226 } else {
227 for (int i = 0; i < elements->length(); i++) {
228 Object* value = elements->get(i);
229 ASSERT(value->IsSmi() ||
230 value->IsTheHole() ||
231 (IsFastObjectElementsKind(copy->GetElementsKind())));
232 if (value->IsJSObject()) {
233 JSObject* js_object = JSObject::cast(value);
234 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate,
235 js_object);
236 if (!maybe_result->ToObject(&result)) return maybe_result;
237 }
238 elements->set(i, result);
239 }
240 }
241 }
242 break;
243 }
244 case DICTIONARY_ELEMENTS: {
245 SeededNumberDictionary* element_dictionary = copy->element_dictionary();
246 int capacity = element_dictionary->Capacity();
247 for (int i = 0; i < capacity; i++) {
248 Object* k = element_dictionary->KeyAt(i);
249 if (element_dictionary->IsKey(k)) {
250 Object* value = element_dictionary->ValueAt(i);
251 if (value->IsJSObject()) {
252 JSObject* js_object = JSObject::cast(value);
253 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate,
254 js_object);
255 if (!maybe_result->ToObject(&result)) return maybe_result;
256 }
257 element_dictionary->ValueAtPut(i, result);
258 }
259 }
260 }
261 break;
262 }
263 case NON_STRICT_ARGUMENTS_ELEMENTS:
264 UNIMPLEMENTED();
265 break;
266 case EXTERNAL_PIXEL_ELEMENTS:
267 case EXTERNAL_BYTE_ELEMENTS:
268 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
269 case EXTERNAL_SHORT_ELEMENTS:
270 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
271 case EXTERNAL_INT_ELEMENTS:
272 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
273 case EXTERNAL_FLOAT_ELEMENTS:
274 case EXTERNAL_DOUBLE_ELEMENTS:
275 case FAST_DOUBLE_ELEMENTS:
276 case FAST_HOLEY_DOUBLE_ELEMENTS:
277 // No contained objects, nothing to do.
278 break;
279 }
280 return copy;
281 }
282
283
284 static Handle<Map> ComputeObjectLiteralMap( 142 static Handle<Map> ComputeObjectLiteralMap(
285 Handle<Context> context, 143 Handle<Context> context,
286 Handle<FixedArray> constant_properties, 144 Handle<FixedArray> constant_properties,
287 bool* is_result_from_cache) { 145 bool* is_result_from_cache) {
288 Isolate* isolate = context->GetIsolate(); 146 Isolate* isolate = context->GetIsolate();
289 int properties_length = constant_properties->length(); 147 int properties_length = constant_properties->length();
290 int number_of_properties = properties_length / 2; 148 int number_of_properties = properties_length / 2;
291 // Check that there are only internal strings and array indices among keys. 149 // Check that there are only internal strings and array indices among keys.
292 int number_of_string_keys = 0; 150 int number_of_string_keys = 0;
293 for (int p = 0; p != properties_length; p += 2) { 151 for (int p = 0; p != properties_length; p += 2) {
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 if (*boilerplate == isolate->heap()->undefined_value()) { 450 if (*boilerplate == isolate->heap()->undefined_value()) {
593 boilerplate = CreateObjectLiteralBoilerplate(isolate, 451 boilerplate = CreateObjectLiteralBoilerplate(isolate,
594 literals, 452 literals,
595 constant_properties, 453 constant_properties,
596 should_have_fast_elements, 454 should_have_fast_elements,
597 has_function_literal); 455 has_function_literal);
598 if (boilerplate.is_null()) return Failure::Exception(); 456 if (boilerplate.is_null()) return Failure::Exception();
599 // Update the functions literal and return the boilerplate. 457 // Update the functions literal and return the boilerplate.
600 literals->set(literals_index, *boilerplate); 458 literals->set(literals_index, *boilerplate);
601 } 459 }
602 return DeepCopyBoilerplate(isolate, JSObject::cast(*boilerplate)); 460 return JSObject::cast(*boilerplate)->DeepCopy(isolate);
603 } 461 }
604 462
605 463
606 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteralShallow) { 464 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteralShallow) {
607 HandleScope scope(isolate); 465 HandleScope scope(isolate);
608 ASSERT(args.length() == 4); 466 ASSERT(args.length() == 4);
609 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); 467 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
610 CONVERT_SMI_ARG_CHECKED(literals_index, 1); 468 CONVERT_SMI_ARG_CHECKED(literals_index, 1);
611 CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2); 469 CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
612 CONVERT_SMI_ARG_CHECKED(flags, 3); 470 CONVERT_SMI_ARG_CHECKED(flags, 3);
(...skipping 26 matching lines...) Expand all
639 // Check if boilerplate exists. If not, create it first. 497 // Check if boilerplate exists. If not, create it first.
640 Handle<Object> boilerplate(literals->get(literals_index), isolate); 498 Handle<Object> boilerplate(literals->get(literals_index), isolate);
641 if (*boilerplate == isolate->heap()->undefined_value()) { 499 if (*boilerplate == isolate->heap()->undefined_value()) {
642 ASSERT(*elements != isolate->heap()->empty_fixed_array()); 500 ASSERT(*elements != isolate->heap()->empty_fixed_array());
643 boilerplate = 501 boilerplate =
644 Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements); 502 Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements);
645 if (boilerplate.is_null()) return Failure::Exception(); 503 if (boilerplate.is_null()) return Failure::Exception();
646 // Update the functions literal and return the boilerplate. 504 // Update the functions literal and return the boilerplate.
647 literals->set(literals_index, *boilerplate); 505 literals->set(literals_index, *boilerplate);
648 } 506 }
649 return DeepCopyBoilerplate(isolate, JSObject::cast(*boilerplate)); 507 return JSObject::cast(*boilerplate)->DeepCopy(isolate);
650 } 508 }
651 509
652 510
653 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralShallow) { 511 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralShallow) {
654 HandleScope scope(isolate); 512 HandleScope scope(isolate);
655 ASSERT(args.length() == 3); 513 ASSERT(args.length() == 3);
656 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); 514 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
657 CONVERT_SMI_ARG_CHECKED(literals_index, 1); 515 CONVERT_SMI_ARG_CHECKED(literals_index, 1);
658 CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2); 516 CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
659 517
(...skipping 12491 matching lines...) Expand 10 before | Expand all | Expand 10 after
13151 // Handle last resort GC and make sure to allow future allocations 13009 // Handle last resort GC and make sure to allow future allocations
13152 // to grow the heap without causing GCs (if possible). 13010 // to grow the heap without causing GCs (if possible).
13153 isolate->counters()->gc_last_resort_from_js()->Increment(); 13011 isolate->counters()->gc_last_resort_from_js()->Increment();
13154 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13012 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13155 "Runtime::PerformGC"); 13013 "Runtime::PerformGC");
13156 } 13014 }
13157 } 13015 }
13158 13016
13159 13017
13160 } } // namespace v8::internal 13018 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698