| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 8 | 8 |
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/ic/ic.h" | 10 #include "src/ic/ic.h" |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 __ mov(unmapped_location, value); | 500 __ mov(unmapped_location, value); |
| 501 __ lea(edi, unmapped_location); | 501 __ lea(edi, unmapped_location); |
| 502 __ mov(edx, value); | 502 __ mov(edx, value); |
| 503 __ RecordWrite(ebx, edi, edx, kDontSaveFPRegs); | 503 __ RecordWrite(ebx, edi, edx, kDontSaveFPRegs); |
| 504 __ Ret(); | 504 __ Ret(); |
| 505 __ bind(&slow); | 505 __ bind(&slow); |
| 506 GenerateMiss(masm); | 506 GenerateMiss(masm); |
| 507 } | 507 } |
| 508 | 508 |
| 509 | 509 |
| 510 static void KeyedStoreGenerateGenericHelper( | 510 static void KeyedStoreGenerateMegamorphicHelper( |
| 511 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, | 511 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, |
| 512 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) { | 512 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) { |
| 513 Label transition_smi_elements; | 513 Label transition_smi_elements; |
| 514 Label finish_object_store, non_double_value, transition_double_elements; | 514 Label finish_object_store, non_double_value, transition_double_elements; |
| 515 Label fast_double_without_map_check; | 515 Label fast_double_without_map_check; |
| 516 Register receiver = StoreDescriptor::ReceiverRegister(); | 516 Register receiver = StoreDescriptor::ReceiverRegister(); |
| 517 Register key = StoreDescriptor::NameRegister(); | 517 Register key = StoreDescriptor::NameRegister(); |
| 518 Register value = StoreDescriptor::ValueRegister(); | 518 Register value = StoreDescriptor::ValueRegister(); |
| 519 DCHECK(receiver.is(edx)); | 519 DCHECK(receiver.is(edx)); |
| 520 DCHECK(key.is(ecx)); | 520 DCHECK(key.is(ecx)); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS, | 638 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS, |
| 639 ebx, edi, slow); | 639 ebx, edi, slow); |
| 640 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); | 640 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); |
| 641 ElementsTransitionGenerator::GenerateDoubleToObject(masm, receiver, key, | 641 ElementsTransitionGenerator::GenerateDoubleToObject(masm, receiver, key, |
| 642 value, ebx, mode, slow); | 642 value, ebx, mode, slow); |
| 643 __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset)); | 643 __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset)); |
| 644 __ jmp(&finish_object_store); | 644 __ jmp(&finish_object_store); |
| 645 } | 645 } |
| 646 | 646 |
| 647 | 647 |
| 648 void KeyedStoreIC::GenerateGeneric( | 648 void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm, |
| 649 MacroAssembler* masm, StrictMode strict_mode, | 649 StrictMode strict_mode) { |
| 650 KeyedStoreStubCacheRequirement handler_requirement) { | |
| 651 // Return address is on the stack. | 650 // Return address is on the stack. |
| 652 Label slow, fast_object, fast_object_grow; | 651 Label slow, fast_object, fast_object_grow; |
| 653 Label fast_double, fast_double_grow; | 652 Label fast_double, fast_double_grow; |
| 654 Label array, extra, check_if_double_array, maybe_name_key, miss; | 653 Label array, extra, check_if_double_array, maybe_name_key, miss; |
| 655 Register receiver = StoreDescriptor::ReceiverRegister(); | 654 Register receiver = StoreDescriptor::ReceiverRegister(); |
| 656 Register key = StoreDescriptor::NameRegister(); | 655 Register key = StoreDescriptor::NameRegister(); |
| 657 DCHECK(receiver.is(edx)); | 656 DCHECK(receiver.is(edx)); |
| 658 DCHECK(key.is(ecx)); | 657 DCHECK(key.is(ecx)); |
| 659 | 658 |
| 660 // Check that the object isn't a smi. | 659 // Check that the object isn't a smi. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 689 | 688 |
| 690 __ bind(&maybe_name_key); | 689 __ bind(&maybe_name_key); |
| 691 __ mov(ebx, FieldOperand(key, HeapObject::kMapOffset)); | 690 __ mov(ebx, FieldOperand(key, HeapObject::kMapOffset)); |
| 692 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); | 691 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
| 693 __ JumpIfNotUniqueNameInstanceType(ebx, &slow); | 692 __ JumpIfNotUniqueNameInstanceType(ebx, &slow); |
| 694 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 693 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
| 695 Code::ComputeHandlerFlags(Code::STORE_IC)); | 694 Code::ComputeHandlerFlags(Code::STORE_IC)); |
| 696 masm->isolate()->stub_cache()->GenerateProbe(masm, flags, false, receiver, | 695 masm->isolate()->stub_cache()->GenerateProbe(masm, flags, false, receiver, |
| 697 key, ebx, no_reg); | 696 key, ebx, no_reg); |
| 698 // Cache miss. | 697 // Cache miss. |
| 699 if (handler_requirement == kCallRuntimeOnMissingHandler) { | 698 __ jmp(&miss); |
| 700 __ jmp(&slow); | |
| 701 } else { | |
| 702 DCHECK(handler_requirement == kMissOnMissingHandler); | |
| 703 __ jmp(&miss); | |
| 704 } | |
| 705 | 699 |
| 706 // Extra capacity case: Check if there is extra capacity to | 700 // Extra capacity case: Check if there is extra capacity to |
| 707 // perform the store and update the length. Used for adding one | 701 // perform the store and update the length. Used for adding one |
| 708 // element to the array by writing to array[array.length]. | 702 // element to the array by writing to array[array.length]. |
| 709 __ bind(&extra); | 703 __ bind(&extra); |
| 710 // receiver is a JSArray. | 704 // receiver is a JSArray. |
| 711 // key is a smi. | 705 // key is a smi. |
| 712 // ebx: receiver->elements, a FixedArray | 706 // ebx: receiver->elements, a FixedArray |
| 713 // edi: receiver map | 707 // edi: receiver map |
| 714 // flags: compare (key, receiver.length()) | 708 // flags: compare (key, receiver.length()) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 733 // receiver is a JSArray. | 727 // receiver is a JSArray. |
| 734 // key is a smi. | 728 // key is a smi. |
| 735 // edi: receiver map | 729 // edi: receiver map |
| 736 __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset)); | 730 __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset)); |
| 737 | 731 |
| 738 // Check the key against the length in the array and fall through to the | 732 // Check the key against the length in the array and fall through to the |
| 739 // common store code. | 733 // common store code. |
| 740 __ cmp(key, FieldOperand(receiver, JSArray::kLengthOffset)); // Compare smis. | 734 __ cmp(key, FieldOperand(receiver, JSArray::kLengthOffset)); // Compare smis. |
| 741 __ j(above_equal, &extra); | 735 __ j(above_equal, &extra); |
| 742 | 736 |
| 743 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, &slow, | 737 KeyedStoreGenerateMegamorphicHelper(masm, &fast_object, &fast_double, &slow, |
| 744 kCheckMap, kDontIncrementLength); | 738 kCheckMap, kDontIncrementLength); |
| 745 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, | 739 KeyedStoreGenerateMegamorphicHelper(masm, &fast_object_grow, |
| 746 &slow, kDontCheckMap, kIncrementLength); | 740 &fast_double_grow, &slow, kDontCheckMap, |
| 741 kIncrementLength); |
| 747 | 742 |
| 748 if (handler_requirement == kMissOnMissingHandler) { | 743 __ bind(&miss); |
| 749 __ bind(&miss); | 744 GenerateMiss(masm); |
| 750 GenerateMiss(masm); | |
| 751 } | |
| 752 } | 745 } |
| 753 | 746 |
| 754 | 747 |
| 755 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 748 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
| 756 Register dictionary = eax; | 749 Register dictionary = eax; |
| 757 DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister())); | 750 DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister())); |
| 758 DCHECK(!dictionary.is(LoadDescriptor::NameRegister())); | 751 DCHECK(!dictionary.is(LoadDescriptor::NameRegister())); |
| 759 | 752 |
| 760 Label slow; | 753 Label slow; |
| 761 | 754 |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 971 Condition cc = | 964 Condition cc = |
| 972 (check == ENABLE_INLINED_SMI_CHECK) | 965 (check == ENABLE_INLINED_SMI_CHECK) |
| 973 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 966 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
| 974 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 967 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
| 975 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 968 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
| 976 } | 969 } |
| 977 } | 970 } |
| 978 } // namespace v8::internal | 971 } // namespace v8::internal |
| 979 | 972 |
| 980 #endif // V8_TARGET_ARCH_IA32 | 973 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |