Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 j// Copyright 2012 the V8 project authors. All rights reserved. |
|
Jakob Kummerow
2012/01/23 17:16:55
nit: superfluous "j" (does this compile?)
danno
2012/01/26 21:32:34
Done.
| |
| 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 421 // constant function properties. | 421 // constant function properties. |
| 422 if (should_transform && !has_function_literal) { | 422 if (should_transform && !has_function_literal) { |
| 423 JSObject::TransformToFastProperties( | 423 JSObject::TransformToFastProperties( |
| 424 boilerplate, boilerplate->map()->unused_property_fields()); | 424 boilerplate, boilerplate->map()->unused_property_fields()); |
| 425 } | 425 } |
| 426 | 426 |
| 427 return boilerplate; | 427 return boilerplate; |
| 428 } | 428 } |
| 429 | 429 |
| 430 | 430 |
| 431 MaybeObject* TransitionElements(Handle<Object> object, | |
| 432 ElementsKind to_kind, | |
| 433 Isolate* isolate) { | |
| 434 HandleScope scope(isolate); | |
| 435 if (!object->IsJSObject()) return isolate->ThrowIllegalOperation(); | |
| 436 ElementsKind from_kind = | |
| 437 Handle<JSObject>::cast(object)->map()->elements_kind(); | |
| 438 if (Map::IsValidElementsTransition(from_kind, to_kind)) { | |
| 439 Handle<Object> result = JSObject::TransitionElementsKind( | |
| 440 Handle<JSObject>::cast(object), to_kind); | |
| 441 if (result.is_null()) return isolate->ThrowIllegalOperation(); | |
| 442 return *result; | |
| 443 } | |
| 444 return isolate->ThrowIllegalOperation(); | |
| 445 } | |
| 446 | |
| 447 | |
| 431 static const int kSmiOnlyLiteralMinimumLength = 1024; | 448 static const int kSmiOnlyLiteralMinimumLength = 1024; |
| 432 | 449 |
| 433 | 450 |
| 434 Handle<Object> Runtime::CreateArrayLiteralBoilerplate( | 451 Handle<Object> Runtime::CreateArrayLiteralBoilerplate( |
| 435 Isolate* isolate, | 452 Isolate* isolate, |
| 436 Handle<FixedArray> literals, | 453 Handle<FixedArray> literals, |
| 437 Handle<FixedArray> elements) { | 454 Handle<FixedArray> elements) { |
| 438 // Create the JSArray. | 455 // Create the JSArray. |
| 439 Handle<JSFunction> constructor( | 456 Handle<JSFunction> constructor( |
| 440 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); | 457 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); |
| 441 Handle<JSArray> object = | 458 Handle<JSArray> object = |
| 442 Handle<JSArray>::cast(isolate->factory()->NewJSObject(constructor)); | 459 Handle<JSArray>::cast(isolate->factory()->NewJSObject(constructor)); |
| 443 | 460 |
| 444 ElementsKind constant_elements_kind = | 461 ElementsKind constant_elements_kind = |
| 445 static_cast<ElementsKind>(Smi::cast(elements->get(0))->value()); | 462 static_cast<ElementsKind>(Smi::cast(elements->get(0))->value()); |
| 446 Handle<FixedArrayBase> constant_elements_values( | 463 Handle<FixedArrayBase> constant_elements_values( |
| 447 FixedArrayBase::cast(elements->get(1))); | 464 FixedArrayBase::cast(elements->get(1))); |
| 448 | 465 |
| 449 ASSERT(FLAG_smi_only_arrays || constant_elements_kind == FAST_ELEMENTS || | 466 Context* global_context = isolate->context()->global_context(); |
| 450 constant_elements_kind == FAST_SMI_ONLY_ELEMENTS); | 467 if (constant_elements_kind == FAST_SMI_ONLY_ELEMENTS) { |
| 451 bool allow_literal_kind_transition = FLAG_smi_only_arrays && | 468 object->set_map(Map::cast(global_context->smi_js_array_map())); |
| 452 constant_elements_kind > object->GetElementsKind(); | 469 } else if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) { |
| 453 | 470 object->set_map(Map::cast(global_context->double_js_array_map())); |
| 454 if (!FLAG_smi_only_arrays && | 471 } else { |
| 455 constant_elements_values->length() > kSmiOnlyLiteralMinimumLength && | 472 object->set_map(Map::cast(global_context->object_js_array_map())); |
| 456 constant_elements_kind != object->GetElementsKind()) { | |
| 457 allow_literal_kind_transition = true; | |
| 458 } | |
| 459 | |
| 460 // If the ElementsKind of the constant values of the array literal are less | |
| 461 // specific than the ElementsKind of the boilerplate array object, change the | |
| 462 // boilerplate array object's map to reflect that kind. | |
| 463 if (allow_literal_kind_transition) { | |
| 464 Handle<Map> transitioned_array_map = | |
| 465 isolate->factory()->GetElementsTransitionMap(object, | |
| 466 constant_elements_kind); | |
| 467 object->set_map(*transitioned_array_map); | |
| 468 } | 473 } |
| 469 | 474 |
| 470 Handle<FixedArrayBase> copied_elements_values; | 475 Handle<FixedArrayBase> copied_elements_values; |
| 471 if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) { | 476 if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) { |
| 472 ASSERT(FLAG_smi_only_arrays); | 477 ASSERT(FLAG_smi_only_arrays); |
| 473 copied_elements_values = isolate->factory()->CopyFixedDoubleArray( | 478 copied_elements_values = isolate->factory()->CopyFixedDoubleArray( |
| 474 Handle<FixedDoubleArray>::cast(constant_elements_values)); | 479 Handle<FixedDoubleArray>::cast(constant_elements_values)); |
| 475 } else { | 480 } else { |
| 476 ASSERT(constant_elements_kind == FAST_SMI_ONLY_ELEMENTS || | 481 ASSERT(constant_elements_kind == FAST_SMI_ONLY_ELEMENTS || |
| 477 constant_elements_kind == FAST_ELEMENTS); | 482 constant_elements_kind == FAST_ELEMENTS); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 502 Handle<Object> result = | 507 Handle<Object> result = |
| 503 CreateLiteralBoilerplate(isolate, literals, fa); | 508 CreateLiteralBoilerplate(isolate, literals, fa); |
| 504 if (result.is_null()) return result; | 509 if (result.is_null()) return result; |
| 505 fixed_array_values_copy->set(i, *result); | 510 fixed_array_values_copy->set(i, *result); |
| 506 } | 511 } |
| 507 } | 512 } |
| 508 } | 513 } |
| 509 } | 514 } |
| 510 object->set_elements(*copied_elements_values); | 515 object->set_elements(*copied_elements_values); |
| 511 object->set_length(Smi::FromInt(copied_elements_values->length())); | 516 object->set_length(Smi::FromInt(copied_elements_values->length())); |
| 517 | |
| 518 // If the ElementsKind of the constant values of the array literal are less | |
|
Jakob Kummerow
2012/01/23 17:16:55
This comment is confusing. Suggestion:
"Ensure tha
danno
2012/01/26 21:32:34
Done.
| |
| 519 // specific than the ElementsKind of the boilerplate array object, change | |
| 520 // the boilerplate array object's map to reflect that kind. | |
| 521 if (!FLAG_smi_only_arrays && | |
| 522 constant_elements_values->length() < kSmiOnlyLiteralMinimumLength) { | |
| 523 if (object->GetElementsKind() != FAST_ELEMENTS) { | |
| 524 CHECK(!TransitionElements(object, FAST_ELEMENTS, isolate)->IsFailure()); | |
| 525 } | |
| 526 } | |
| 527 | |
| 512 return object; | 528 return object; |
| 513 } | 529 } |
| 514 | 530 |
| 515 | 531 |
| 516 static Handle<Object> CreateLiteralBoilerplate( | 532 static Handle<Object> CreateLiteralBoilerplate( |
| 517 Isolate* isolate, | 533 Isolate* isolate, |
| 518 Handle<FixedArray> literals, | 534 Handle<FixedArray> literals, |
| 519 Handle<FixedArray> array) { | 535 Handle<FixedArray> array) { |
| 520 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); | 536 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); |
| 521 const bool kHasNoFunctionLiteral = false; | 537 const bool kHasNoFunctionLiteral = false; |
| (...skipping 3673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4195 NoHandleAllocation ha; | 4211 NoHandleAllocation ha; |
| 4196 ASSERT(args.length() == 2); | 4212 ASSERT(args.length() == 2); |
| 4197 | 4213 |
| 4198 Handle<Object> object = args.at<Object>(0); | 4214 Handle<Object> object = args.at<Object>(0); |
| 4199 Handle<Object> key = args.at<Object>(1); | 4215 Handle<Object> key = args.at<Object>(1); |
| 4200 | 4216 |
| 4201 return Runtime::GetObjectProperty(isolate, object, key); | 4217 return Runtime::GetObjectProperty(isolate, object, key); |
| 4202 } | 4218 } |
| 4203 | 4219 |
| 4204 | 4220 |
| 4205 MaybeObject* TransitionElements(Handle<Object> object, | |
| 4206 ElementsKind to_kind, | |
| 4207 Isolate* isolate) { | |
| 4208 HandleScope scope(isolate); | |
| 4209 if (!object->IsJSObject()) return isolate->ThrowIllegalOperation(); | |
| 4210 ElementsKind from_kind = | |
| 4211 Handle<JSObject>::cast(object)->map()->elements_kind(); | |
| 4212 if (Map::IsValidElementsTransition(from_kind, to_kind)) { | |
| 4213 Handle<Object> result = JSObject::TransitionElementsKind( | |
| 4214 Handle<JSObject>::cast(object), to_kind); | |
| 4215 if (result.is_null()) return isolate->ThrowIllegalOperation(); | |
| 4216 return *result; | |
| 4217 } | |
| 4218 return isolate->ThrowIllegalOperation(); | |
| 4219 } | |
| 4220 | |
| 4221 | |
| 4222 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. | 4221 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. |
| 4223 RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) { | 4222 RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) { |
| 4224 NoHandleAllocation ha; | 4223 NoHandleAllocation ha; |
| 4225 ASSERT(args.length() == 2); | 4224 ASSERT(args.length() == 2); |
| 4226 | 4225 |
| 4227 // Fast cases for getting named properties of the receiver JSObject | 4226 // Fast cases for getting named properties of the receiver JSObject |
| 4228 // itself. | 4227 // itself. |
| 4229 // | 4228 // |
| 4230 // The global proxy objects has to be excluded since LocalLookup on | 4229 // The global proxy objects has to be excluded since LocalLookup on |
| 4231 // the global proxy object can return a valid result even though the | 4230 // the global proxy object can return a valid result even though the |
| (...skipping 5992 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10224 ElementsKind elements_kind; | 10223 ElementsKind elements_kind; |
| 10225 if (new_elements->map() == isolate->heap()->fixed_array_map() || | 10224 if (new_elements->map() == isolate->heap()->fixed_array_map() || |
| 10226 new_elements->map() == isolate->heap()->fixed_cow_array_map()) { | 10225 new_elements->map() == isolate->heap()->fixed_cow_array_map()) { |
| 10227 elements_kind = FAST_ELEMENTS; | 10226 elements_kind = FAST_ELEMENTS; |
| 10228 } else if (new_elements->map() == | 10227 } else if (new_elements->map() == |
| 10229 isolate->heap()->fixed_double_array_map()) { | 10228 isolate->heap()->fixed_double_array_map()) { |
| 10230 elements_kind = FAST_DOUBLE_ELEMENTS; | 10229 elements_kind = FAST_DOUBLE_ELEMENTS; |
| 10231 } else { | 10230 } else { |
| 10232 elements_kind = DICTIONARY_ELEMENTS; | 10231 elements_kind = DICTIONARY_ELEMENTS; |
| 10233 } | 10232 } |
| 10234 maybe_new_map = to->GetElementsTransitionMap(elements_kind); | 10233 maybe_new_map = to->GetElementsTransitionMap(isolate, elements_kind); |
| 10235 Object* new_map; | 10234 Object* new_map; |
| 10236 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 10235 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 10237 to->set_map(Map::cast(new_map)); | 10236 to->set_map(Map::cast(new_map)); |
| 10238 to->set_elements(new_elements); | 10237 to->set_elements(new_elements); |
| 10239 to->set_length(from->length()); | 10238 to->set_length(from->length()); |
| 10240 Object* obj; | 10239 Object* obj; |
| 10241 { MaybeObject* maybe_obj = from->ResetElements(); | 10240 { MaybeObject* maybe_obj = from->ResetElements(); |
| 10242 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 10241 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 10243 } | 10242 } |
| 10244 from->set_length(Smi::FromInt(0)); | 10243 from->set_length(Smi::FromInt(0)); |
| (...skipping 3390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13635 } else { | 13634 } else { |
| 13636 // Handle last resort GC and make sure to allow future allocations | 13635 // Handle last resort GC and make sure to allow future allocations |
| 13637 // to grow the heap without causing GCs (if possible). | 13636 // to grow the heap without causing GCs (if possible). |
| 13638 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13637 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13639 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); | 13638 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 13640 } | 13639 } |
| 13641 } | 13640 } |
| 13642 | 13641 |
| 13643 | 13642 |
| 13644 } } // namespace v8::internal | 13643 } } // namespace v8::internal |
| OLD | NEW |