OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 } | 153 } |
154 } | 154 } |
155 } | 155 } |
156 | 156 |
157 // Deep copy local elements. | 157 // Deep copy local elements. |
158 // Pixel elements cannot be created using an object literal. | 158 // Pixel elements cannot be created using an object literal. |
159 ASSERT(!copy->HasPixelElements() && !copy->HasExternalArrayElements()); | 159 ASSERT(!copy->HasPixelElements() && !copy->HasExternalArrayElements()); |
160 switch (copy->GetElementsKind()) { | 160 switch (copy->GetElementsKind()) { |
161 case JSObject::FAST_ELEMENTS: { | 161 case JSObject::FAST_ELEMENTS: { |
162 FixedArray* elements = FixedArray::cast(copy->elements()); | 162 FixedArray* elements = FixedArray::cast(copy->elements()); |
163 for (int i = 0; i < elements->length(); i++) { | 163 if (elements->map() == Heap::fixed_cow_array_map()) { |
164 Object* value = elements->get(i); | 164 Counters::cow_arrays_created_runtime.Increment(); |
165 if (value->IsJSObject()) { | 165 #ifdef DEBUG |
166 JSObject* js_object = JSObject::cast(value); | 166 for (int i = 0; i < elements->length(); i++) { |
167 result = DeepCopyBoilerplate(js_object); | 167 ASSERT(!elements->get(i)->IsJSObject()); |
168 if (result->IsFailure()) return result; | 168 } |
169 elements->set(i, result); | 169 #endif |
| 170 } else { |
| 171 for (int i = 0; i < elements->length(); i++) { |
| 172 Object* value = elements->get(i); |
| 173 if (value->IsJSObject()) { |
| 174 JSObject* js_object = JSObject::cast(value); |
| 175 result = DeepCopyBoilerplate(js_object); |
| 176 if (result->IsFailure()) return result; |
| 177 elements->set(i, result); |
| 178 } |
170 } | 179 } |
171 } | 180 } |
172 break; | 181 break; |
173 } | 182 } |
174 case JSObject::DICTIONARY_ELEMENTS: { | 183 case JSObject::DICTIONARY_ELEMENTS: { |
175 NumberDictionary* element_dictionary = copy->element_dictionary(); | 184 NumberDictionary* element_dictionary = copy->element_dictionary(); |
176 int capacity = element_dictionary->Capacity(); | 185 int capacity = element_dictionary->Capacity(); |
177 for (int i = 0; i < capacity; i++) { | 186 for (int i = 0; i < capacity; i++) { |
178 Object* k = element_dictionary->KeyAt(i); | 187 Object* k = element_dictionary->KeyAt(i); |
179 if (element_dictionary->IsKey(k)) { | 188 if (element_dictionary->IsKey(k)) { |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 | 345 |
337 | 346 |
338 static Handle<Object> CreateArrayLiteralBoilerplate( | 347 static Handle<Object> CreateArrayLiteralBoilerplate( |
339 Handle<FixedArray> literals, | 348 Handle<FixedArray> literals, |
340 Handle<FixedArray> elements) { | 349 Handle<FixedArray> elements) { |
341 // Create the JSArray. | 350 // Create the JSArray. |
342 Handle<JSFunction> constructor( | 351 Handle<JSFunction> constructor( |
343 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); | 352 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); |
344 Handle<Object> object = Factory::NewJSObject(constructor); | 353 Handle<Object> object = Factory::NewJSObject(constructor); |
345 | 354 |
346 Handle<Object> copied_elements = Factory::CopyFixedArray(elements); | 355 const bool is_cow = (elements->map() == Heap::fixed_cow_array_map()); |
| 356 Handle<FixedArray> copied_elements = |
| 357 is_cow ? elements : Factory::CopyFixedArray(elements); |
347 | 358 |
348 Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements); | 359 Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements); |
349 for (int i = 0; i < content->length(); i++) { | 360 if (is_cow) { |
350 if (content->get(i)->IsFixedArray()) { | 361 #ifdef DEBUG |
351 // The value contains the constant_properties of a | 362 // Copy-on-write arrays must be shallow (and simple). |
352 // simple object literal. | 363 for (int i = 0; i < content->length(); i++) { |
353 Handle<FixedArray> fa(FixedArray::cast(content->get(i))); | 364 ASSERT(!content->get(i)->IsFixedArray()); |
354 Handle<Object> result = | 365 } |
355 CreateLiteralBoilerplate(literals, fa); | 366 #endif |
356 if (result.is_null()) return result; | 367 } else { |
357 content->set(i, *result); | 368 for (int i = 0; i < content->length(); i++) { |
| 369 if (content->get(i)->IsFixedArray()) { |
| 370 // The value contains the constant_properties of a |
| 371 // simple object literal. |
| 372 Handle<FixedArray> fa(FixedArray::cast(content->get(i))); |
| 373 Handle<Object> result = |
| 374 CreateLiteralBoilerplate(literals, fa); |
| 375 if (result.is_null()) return result; |
| 376 content->set(i, *result); |
| 377 } |
358 } | 378 } |
359 } | 379 } |
360 | 380 |
361 // Set the elements. | 381 // Set the elements. |
362 Handle<JSArray>::cast(object)->SetContent(*content); | 382 Handle<JSArray>::cast(object)->SetContent(*content); |
363 return object; | 383 return object; |
364 } | 384 } |
365 | 385 |
366 | 386 |
367 static Handle<Object> CreateLiteralBoilerplate( | 387 static Handle<Object> CreateLiteralBoilerplate( |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 CONVERT_ARG_CHECKED(FixedArray, elements, 2); | 496 CONVERT_ARG_CHECKED(FixedArray, elements, 2); |
477 | 497 |
478 // Check if boilerplate exists. If not, create it first. | 498 // Check if boilerplate exists. If not, create it first. |
479 Handle<Object> boilerplate(literals->get(literals_index)); | 499 Handle<Object> boilerplate(literals->get(literals_index)); |
480 if (*boilerplate == Heap::undefined_value()) { | 500 if (*boilerplate == Heap::undefined_value()) { |
481 boilerplate = CreateArrayLiteralBoilerplate(literals, elements); | 501 boilerplate = CreateArrayLiteralBoilerplate(literals, elements); |
482 if (boilerplate.is_null()) return Failure::Exception(); | 502 if (boilerplate.is_null()) return Failure::Exception(); |
483 // Update the functions literal and return the boilerplate. | 503 // Update the functions literal and return the boilerplate. |
484 literals->set(literals_index, *boilerplate); | 504 literals->set(literals_index, *boilerplate); |
485 } | 505 } |
| 506 if (JSObject::cast(*boilerplate)->elements()->map() == |
| 507 Heap::fixed_cow_array_map()) { |
| 508 Counters::cow_arrays_created_runtime.Increment(); |
| 509 } |
486 return Heap::CopyJSObject(JSObject::cast(*boilerplate)); | 510 return Heap::CopyJSObject(JSObject::cast(*boilerplate)); |
487 } | 511 } |
488 | 512 |
489 | 513 |
490 static Object* Runtime_CreateCatchExtensionObject(Arguments args) { | 514 static Object* Runtime_CreateCatchExtensionObject(Arguments args) { |
491 ASSERT(args.length() == 2); | 515 ASSERT(args.length() == 2); |
492 CONVERT_CHECKED(String, key, args[0]); | 516 CONVERT_CHECKED(String, key, args[0]); |
493 Object* value = args[1]; | 517 Object* value = args[1]; |
494 // Create a catch context extension object. | 518 // Create a catch context extension object. |
495 JSFunction* constructor = | 519 JSFunction* constructor = |
(...skipping 6196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6692 static Object* Runtime_DateYMDFromTime(Arguments args) { | 6716 static Object* Runtime_DateYMDFromTime(Arguments args) { |
6693 NoHandleAllocation ha; | 6717 NoHandleAllocation ha; |
6694 ASSERT(args.length() == 2); | 6718 ASSERT(args.length() == 2); |
6695 | 6719 |
6696 CONVERT_DOUBLE_CHECKED(t, args[0]); | 6720 CONVERT_DOUBLE_CHECKED(t, args[0]); |
6697 CONVERT_CHECKED(JSArray, res_array, args[1]); | 6721 CONVERT_CHECKED(JSArray, res_array, args[1]); |
6698 | 6722 |
6699 int year, month, day; | 6723 int year, month, day; |
6700 DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day); | 6724 DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day); |
6701 | 6725 |
6702 res_array->SetElement(0, Smi::FromInt(year)); | 6726 RUNTIME_ASSERT(res_array->elements()->map() == Heap::fixed_array_map()); |
6703 res_array->SetElement(1, Smi::FromInt(month)); | 6727 FixedArray* elms = FixedArray::cast(res_array->elements()); |
6704 res_array->SetElement(2, Smi::FromInt(day)); | 6728 RUNTIME_ASSERT(elms->length() == 3); |
| 6729 |
| 6730 elms->set(0, Smi::FromInt(year)); |
| 6731 elms->set(1, Smi::FromInt(month)); |
| 6732 elms->set(2, Smi::FromInt(day)); |
6705 | 6733 |
6706 return Heap::undefined_value(); | 6734 return Heap::undefined_value(); |
6707 } | 6735 } |
6708 | 6736 |
6709 | 6737 |
6710 static Object* Runtime_NewArgumentsFast(Arguments args) { | 6738 static Object* Runtime_NewArgumentsFast(Arguments args) { |
6711 NoHandleAllocation ha; | 6739 NoHandleAllocation ha; |
6712 ASSERT(args.length() == 3); | 6740 ASSERT(args.length() == 3); |
6713 | 6741 |
6714 JSFunction* callee = JSFunction::cast(args[0]); | 6742 JSFunction* callee = JSFunction::cast(args[0]); |
(...skipping 1335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8050 } | 8078 } |
8051 | 8079 |
8052 | 8080 |
8053 // Move contents of argument 0 (an array) to argument 1 (an array) | 8081 // Move contents of argument 0 (an array) to argument 1 (an array) |
8054 static Object* Runtime_MoveArrayContents(Arguments args) { | 8082 static Object* Runtime_MoveArrayContents(Arguments args) { |
8055 ASSERT(args.length() == 2); | 8083 ASSERT(args.length() == 2); |
8056 CONVERT_CHECKED(JSArray, from, args[0]); | 8084 CONVERT_CHECKED(JSArray, from, args[0]); |
8057 CONVERT_CHECKED(JSArray, to, args[1]); | 8085 CONVERT_CHECKED(JSArray, to, args[1]); |
8058 HeapObject* new_elements = from->elements(); | 8086 HeapObject* new_elements = from->elements(); |
8059 Object* new_map; | 8087 Object* new_map; |
8060 if (new_elements->map() == Heap::fixed_array_map()) { | 8088 if (new_elements->map() == Heap::fixed_array_map() || |
| 8089 new_elements->map() == Heap::fixed_cow_array_map()) { |
8061 new_map = to->map()->GetFastElementsMap(); | 8090 new_map = to->map()->GetFastElementsMap(); |
8062 } else { | 8091 } else { |
8063 new_map = to->map()->GetSlowElementsMap(); | 8092 new_map = to->map()->GetSlowElementsMap(); |
8064 } | 8093 } |
8065 if (new_map->IsFailure()) return new_map; | 8094 if (new_map->IsFailure()) return new_map; |
8066 to->set_map(Map::cast(new_map)); | 8095 to->set_map(Map::cast(new_map)); |
8067 to->set_elements(new_elements); | 8096 to->set_elements(new_elements); |
8068 to->set_length(from->length()); | 8097 to->set_length(from->length()); |
8069 Object* obj = from->ResetElements(); | 8098 Object* obj = from->ResetElements(); |
8070 if (obj->IsFailure()) return obj; | 8099 if (obj->IsFailure()) return obj; |
(...skipping 2550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10621 } else { | 10650 } else { |
10622 // Handle last resort GC and make sure to allow future allocations | 10651 // Handle last resort GC and make sure to allow future allocations |
10623 // to grow the heap without causing GCs (if possible). | 10652 // to grow the heap without causing GCs (if possible). |
10624 Counters::gc_last_resort_from_js.Increment(); | 10653 Counters::gc_last_resort_from_js.Increment(); |
10625 Heap::CollectAllGarbage(false); | 10654 Heap::CollectAllGarbage(false); |
10626 } | 10655 } |
10627 } | 10656 } |
10628 | 10657 |
10629 | 10658 |
10630 } } // namespace v8::internal | 10659 } } // namespace v8::internal |
OLD | NEW |