OLD | NEW |
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 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 should_have_fast_elements, | 493 should_have_fast_elements, |
494 has_function_literal); | 494 has_function_literal); |
495 if (boilerplate.is_null()) return Failure::Exception(); | 495 if (boilerplate.is_null()) return Failure::Exception(); |
496 // Update the functions literal and return the boilerplate. | 496 // Update the functions literal and return the boilerplate. |
497 literals->set(literals_index, *boilerplate); | 497 literals->set(literals_index, *boilerplate); |
498 } | 498 } |
499 return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate)); | 499 return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate)); |
500 } | 500 } |
501 | 501 |
502 | 502 |
| 503 static Handle<AllocationSite> GetLiteralAllocationSite( |
| 504 Isolate* isolate, |
| 505 Handle<FixedArray> literals, |
| 506 int literals_index, |
| 507 Handle<FixedArray> elements) { |
| 508 // Check if boilerplate exists. If not, create it first. |
| 509 Handle<Object> literal_site(literals->get(literals_index), isolate); |
| 510 Handle<AllocationSite> site; |
| 511 if (*literal_site == isolate->heap()->undefined_value()) { |
| 512 ASSERT(*elements != isolate->heap()->empty_fixed_array()); |
| 513 Handle<Object> boilerplate = |
| 514 Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements); |
| 515 if (boilerplate.is_null()) return site; |
| 516 site = isolate->factory()->NewAllocationSite(); |
| 517 site->set_payload(*boilerplate); |
| 518 literals->set(literals_index, *site); |
| 519 } else { |
| 520 site = Handle<AllocationSite>::cast(literal_site); |
| 521 } |
| 522 |
| 523 return site; |
| 524 } |
| 525 |
| 526 |
503 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteral) { | 527 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteral) { |
504 HandleScope scope(isolate); | 528 HandleScope scope(isolate); |
505 ASSERT(args.length() == 3); | 529 ASSERT(args.length() == 3); |
506 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); | 530 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); |
507 CONVERT_SMI_ARG_CHECKED(literals_index, 1); | 531 CONVERT_SMI_ARG_CHECKED(literals_index, 1); |
508 CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2); | 532 CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2); |
509 | 533 |
510 // Check if boilerplate exists. If not, create it first. | 534 Handle<AllocationSite> site = GetLiteralAllocationSite(isolate, literals, |
511 Handle<Object> boilerplate(literals->get(literals_index), isolate); | 535 literals_index, elements); |
512 if (*boilerplate == isolate->heap()->undefined_value()) { | 536 if (site.is_null()) { |
513 ASSERT(*elements != isolate->heap()->empty_fixed_array()); | 537 return Failure::Exception(); |
514 boilerplate = | |
515 Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements); | |
516 if (boilerplate.is_null()) return Failure::Exception(); | |
517 // Update the functions literal and return the boilerplate. | |
518 literals->set(literals_index, *boilerplate); | |
519 } | 538 } |
520 return JSObject::cast(*boilerplate)->DeepCopy(isolate); | 539 |
| 540 JSObject* boilerplate = JSObject::cast(site->payload()); |
| 541 return boilerplate->DeepCopy(isolate); |
521 } | 542 } |
522 | 543 |
523 | 544 |
524 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralShallow) { | 545 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralShallow) { |
525 HandleScope scope(isolate); | 546 HandleScope scope(isolate); |
526 ASSERT(args.length() == 3); | 547 ASSERT(args.length() == 3); |
527 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); | 548 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); |
528 CONVERT_SMI_ARG_CHECKED(literals_index, 1); | 549 CONVERT_SMI_ARG_CHECKED(literals_index, 1); |
529 CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2); | 550 CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2); |
530 | 551 |
531 // Check if boilerplate exists. If not, create it first. | 552 Handle<AllocationSite> site = GetLiteralAllocationSite(isolate, literals, |
532 Handle<Object> boilerplate(literals->get(literals_index), isolate); | 553 literals_index, elements); |
533 if (*boilerplate == isolate->heap()->undefined_value()) { | 554 if (site.is_null()) { |
534 ASSERT(*elements != isolate->heap()->empty_fixed_array()); | 555 return Failure::Exception(); |
535 boilerplate = | |
536 Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements); | |
537 if (boilerplate.is_null()) return Failure::Exception(); | |
538 // Update the functions literal and return the boilerplate. | |
539 literals->set(literals_index, *boilerplate); | |
540 } | 556 } |
541 if (JSObject::cast(*boilerplate)->elements()->map() == | 557 |
| 558 JSObject* boilerplate = JSObject::cast(site->payload()); |
| 559 if (boilerplate->elements()->map() == |
542 isolate->heap()->fixed_cow_array_map()) { | 560 isolate->heap()->fixed_cow_array_map()) { |
543 isolate->counters()->cow_arrays_created_runtime()->Increment(); | 561 isolate->counters()->cow_arrays_created_runtime()->Increment(); |
544 } | 562 } |
545 | 563 |
546 JSObject* boilerplate_object = JSObject::cast(*boilerplate); | 564 AllocationSiteMode mode = AllocationSite::GetMode( |
547 AllocationSiteMode mode = AllocationSiteInfo::GetMode( | 565 boilerplate->GetElementsKind()); |
548 boilerplate_object->GetElementsKind()); | |
549 if (mode == TRACK_ALLOCATION_SITE) { | 566 if (mode == TRACK_ALLOCATION_SITE) { |
550 return isolate->heap()->CopyJSObjectWithAllocationSite(boilerplate_object); | 567 return isolate->heap()->CopyJSObjectWithAllocationSite( |
| 568 boilerplate, *site); |
551 } | 569 } |
552 | 570 |
553 return isolate->heap()->CopyJSObject(boilerplate_object); | 571 return isolate->heap()->CopyJSObject(boilerplate); |
554 } | 572 } |
555 | 573 |
556 | 574 |
557 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateSymbol) { | 575 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateSymbol) { |
558 HandleScope scope(isolate); | 576 HandleScope scope(isolate); |
559 ASSERT(args.length() == 1); | 577 ASSERT(args.length() == 1); |
560 Handle<Object> name(args[0], isolate); | 578 Handle<Object> name(args[0], isolate); |
561 RUNTIME_ASSERT(name->IsString() || name->IsUndefined()); | 579 RUNTIME_ASSERT(name->IsString() || name->IsUndefined()); |
562 Symbol* symbol; | 580 Symbol* symbol; |
563 MaybeObject* maybe = isolate->heap()->AllocateSymbol(); | 581 MaybeObject* maybe = isolate->heap()->AllocateSymbol(); |
(...skipping 4618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5182 | 5200 |
5183 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) { | 5201 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) { |
5184 HandleScope scope(isolate); | 5202 HandleScope scope(isolate); |
5185 RUNTIME_ASSERT(args.length() == 5); | 5203 RUNTIME_ASSERT(args.length() == 5); |
5186 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 5204 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
5187 CONVERT_SMI_ARG_CHECKED(store_index, 1); | 5205 CONVERT_SMI_ARG_CHECKED(store_index, 1); |
5188 Handle<Object> value = args.at<Object>(2); | 5206 Handle<Object> value = args.at<Object>(2); |
5189 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3); | 5207 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3); |
5190 CONVERT_SMI_ARG_CHECKED(literal_index, 4); | 5208 CONVERT_SMI_ARG_CHECKED(literal_index, 4); |
5191 | 5209 |
5192 Object* raw_boilerplate_object = literals->get(literal_index); | 5210 Object* raw_literal_cell = literals->get(literal_index); |
5193 Handle<JSArray> boilerplate_object(JSArray::cast(raw_boilerplate_object)); | 5211 JSArray* boilerplate = NULL; |
| 5212 if (raw_literal_cell->IsAllocationSite()) { |
| 5213 AllocationSite* site = AllocationSite::cast(raw_literal_cell); |
| 5214 boilerplate = JSArray::cast(site->payload()); |
| 5215 } else { |
| 5216 boilerplate = JSArray::cast(raw_literal_cell); |
| 5217 } |
| 5218 Handle<JSArray> boilerplate_object(boilerplate); |
5194 ElementsKind elements_kind = object->GetElementsKind(); | 5219 ElementsKind elements_kind = object->GetElementsKind(); |
5195 ASSERT(IsFastElementsKind(elements_kind)); | 5220 ASSERT(IsFastElementsKind(elements_kind)); |
5196 // Smis should never trigger transitions. | 5221 // Smis should never trigger transitions. |
5197 ASSERT(!value->IsSmi()); | 5222 ASSERT(!value->IsSmi()); |
5198 | 5223 |
5199 if (value->IsNumber()) { | 5224 if (value->IsNumber()) { |
5200 ASSERT(IsFastSmiElementsKind(elements_kind)); | 5225 ASSERT(IsFastSmiElementsKind(elements_kind)); |
5201 ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind) | 5226 ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind) |
5202 ? FAST_HOLEY_DOUBLE_ELEMENTS | 5227 ? FAST_HOLEY_DOUBLE_ELEMENTS |
5203 : FAST_DOUBLE_ELEMENTS; | 5228 : FAST_DOUBLE_ELEMENTS; |
(...skipping 8582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13786 } else { | 13811 } else { |
13787 // Non-smi length argument produces a dictionary | 13812 // Non-smi length argument produces a dictionary |
13788 can_use_type_feedback = false; | 13813 can_use_type_feedback = false; |
13789 } | 13814 } |
13790 } | 13815 } |
13791 | 13816 |
13792 JSArray* array; | 13817 JSArray* array; |
13793 MaybeObject* maybe_array; | 13818 MaybeObject* maybe_array; |
13794 if (!type_info.is_null() && | 13819 if (!type_info.is_null() && |
13795 *type_info != isolate->heap()->undefined_value() && | 13820 *type_info != isolate->heap()->undefined_value() && |
13796 Cell::cast(*type_info)->value()->IsSmi() && | 13821 Cell::cast(*type_info)->value()->IsAllocationSite() && |
13797 can_use_type_feedback) { | 13822 can_use_type_feedback) { |
13798 Cell* cell = Cell::cast(*type_info); | 13823 Handle<Cell> cell = Handle<Cell>::cast(type_info); |
13799 Smi* smi = Smi::cast(cell->value()); | 13824 Handle<AllocationSite> site = Handle<AllocationSite>( |
13800 ElementsKind to_kind = static_cast<ElementsKind>(smi->value()); | 13825 AllocationSite::cast(cell->value()), isolate); |
| 13826 ASSERT(!site->IsLiteralSite()); |
| 13827 ElementsKind to_kind = site->GetElementsKindPayload(); |
13801 if (holey && !IsFastHoleyElementsKind(to_kind)) { | 13828 if (holey && !IsFastHoleyElementsKind(to_kind)) { |
13802 to_kind = GetHoleyElementsKind(to_kind); | 13829 to_kind = GetHoleyElementsKind(to_kind); |
13803 // Update the allocation site info to reflect the advice alteration. | 13830 // Update the allocation site info to reflect the advice alteration. |
13804 cell->set_value(Smi::FromInt(to_kind)); | 13831 site->SetElementsKindPayload(to_kind); |
13805 } | 13832 } |
13806 | 13833 |
13807 maybe_array = isolate->heap()->AllocateJSObjectWithAllocationSite( | 13834 maybe_array = isolate->heap()->AllocateJSObjectWithAllocationSite( |
13808 *constructor, type_info); | 13835 *constructor, site); |
13809 if (!maybe_array->To(&array)) return maybe_array; | 13836 if (!maybe_array->To(&array)) return maybe_array; |
13810 } else { | 13837 } else { |
13811 maybe_array = isolate->heap()->AllocateJSObject(*constructor); | 13838 maybe_array = isolate->heap()->AllocateJSObject(*constructor); |
13812 if (!maybe_array->To(&array)) return maybe_array; | 13839 if (!maybe_array->To(&array)) return maybe_array; |
13813 // We might need to transition to holey | 13840 // We might need to transition to holey |
13814 ElementsKind kind = constructor->initial_map()->elements_kind(); | 13841 ElementsKind kind = constructor->initial_map()->elements_kind(); |
13815 if (holey && !IsFastHoleyElementsKind(kind)) { | 13842 if (holey && !IsFastHoleyElementsKind(kind)) { |
13816 kind = GetHoleyElementsKind(kind); | 13843 kind = GetHoleyElementsKind(kind); |
13817 maybe_array = array->TransitionElementsKind(kind); | 13844 maybe_array = array->TransitionElementsKind(kind); |
13818 if (maybe_array->IsFailure()) return maybe_array; | 13845 if (maybe_array->IsFailure()) return maybe_array; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13947 // Handle last resort GC and make sure to allow future allocations | 13974 // Handle last resort GC and make sure to allow future allocations |
13948 // to grow the heap without causing GCs (if possible). | 13975 // to grow the heap without causing GCs (if possible). |
13949 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13976 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13950 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13977 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13951 "Runtime::PerformGC"); | 13978 "Runtime::PerformGC"); |
13952 } | 13979 } |
13953 } | 13980 } |
13954 | 13981 |
13955 | 13982 |
13956 } } // namespace v8::internal | 13983 } } // namespace v8::internal |
OLD | NEW |