| 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 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 return FieldOperand(backing_store, key, times_half_pointer_size, | 303 return FieldOperand(backing_store, key, times_half_pointer_size, |
| 304 FixedArray::kHeaderSize); | 304 FixedArray::kHeaderSize); |
| 305 } | 305 } |
| 306 | 306 |
| 307 | 307 |
| 308 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 308 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { |
| 309 // The return address is on the stack. | 309 // The return address is on the stack. |
| 310 Label slow, check_name, index_smi, index_name, property_array_property; | 310 Label slow, check_name, index_smi, index_name, property_array_property; |
| 311 Label probe_dictionary, check_number_dictionary; | 311 Label probe_dictionary, check_number_dictionary; |
| 312 | 312 |
| 313 Register receiver = ReceiverRegister(); | 313 Register receiver = LoadConvention::ReceiverRegister(); |
| 314 Register key = NameRegister(); | 314 Register key = LoadConvention::NameRegister(); |
| 315 DCHECK(receiver.is(edx)); | 315 DCHECK(receiver.is(edx)); |
| 316 DCHECK(key.is(ecx)); | 316 DCHECK(key.is(ecx)); |
| 317 | 317 |
| 318 // Check that the key is a smi. | 318 // Check that the key is a smi. |
| 319 __ JumpIfNotSmi(key, &check_name); | 319 __ JumpIfNotSmi(key, &check_name); |
| 320 __ bind(&index_smi); | 320 __ bind(&index_smi); |
| 321 // Now the key is known to be a smi. This place is also jumped to from | 321 // Now the key is known to be a smi. This place is also jumped to from |
| 322 // where a numeric string is converted to a smi. | 322 // where a numeric string is converted to a smi. |
| 323 | 323 |
| 324 GenerateKeyedLoadReceiverCheck(masm, receiver, eax, | 324 GenerateKeyedLoadReceiverCheck(masm, receiver, eax, |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 __ IndexFromHash(ebx, key); | 473 __ IndexFromHash(ebx, key); |
| 474 // Now jump to the place where smi keys are handled. | 474 // Now jump to the place where smi keys are handled. |
| 475 __ jmp(&index_smi); | 475 __ jmp(&index_smi); |
| 476 } | 476 } |
| 477 | 477 |
| 478 | 478 |
| 479 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { | 479 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { |
| 480 // Return address is on the stack. | 480 // Return address is on the stack. |
| 481 Label miss; | 481 Label miss; |
| 482 | 482 |
| 483 Register receiver = ReceiverRegister(); | 483 Register receiver = LoadConvention::ReceiverRegister(); |
| 484 Register index = NameRegister(); | 484 Register index = LoadConvention::NameRegister(); |
| 485 Register scratch = ebx; | 485 Register scratch = ebx; |
| 486 DCHECK(!scratch.is(receiver) && !scratch.is(index)); | 486 DCHECK(!scratch.is(receiver) && !scratch.is(index)); |
| 487 Register result = eax; | 487 Register result = eax; |
| 488 DCHECK(!result.is(scratch)); | 488 DCHECK(!result.is(scratch)); |
| 489 | 489 |
| 490 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, | 490 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, |
| 491 &miss, // When not a string. | 491 &miss, // When not a string. |
| 492 &miss, // When not a number. | 492 &miss, // When not a number. |
| 493 &miss, // When index out of range. | 493 &miss, // When index out of range. |
| 494 STRING_INDEX_IS_ARRAY_INDEX); | 494 STRING_INDEX_IS_ARRAY_INDEX); |
| 495 char_at_generator.GenerateFast(masm); | 495 char_at_generator.GenerateFast(masm); |
| 496 __ ret(0); | 496 __ ret(0); |
| 497 | 497 |
| 498 StubRuntimeCallHelper call_helper; | 498 StubRuntimeCallHelper call_helper; |
| 499 char_at_generator.GenerateSlow(masm, call_helper); | 499 char_at_generator.GenerateSlow(masm, call_helper); |
| 500 | 500 |
| 501 __ bind(&miss); | 501 __ bind(&miss); |
| 502 GenerateMiss(masm); | 502 GenerateMiss(masm); |
| 503 } | 503 } |
| 504 | 504 |
| 505 | 505 |
| 506 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 506 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { |
| 507 // Return address is on the stack. | 507 // Return address is on the stack. |
| 508 Label slow; | 508 Label slow; |
| 509 | 509 |
| 510 Register receiver = ReceiverRegister(); | 510 Register receiver = LoadConvention::ReceiverRegister(); |
| 511 Register key = NameRegister(); | 511 Register key = LoadConvention::NameRegister(); |
| 512 Register scratch = eax; | 512 Register scratch = eax; |
| 513 DCHECK(!scratch.is(receiver) && !scratch.is(key)); | 513 DCHECK(!scratch.is(receiver) && !scratch.is(key)); |
| 514 | 514 |
| 515 // Check that the receiver isn't a smi. | 515 // Check that the receiver isn't a smi. |
| 516 __ JumpIfSmi(receiver, &slow); | 516 __ JumpIfSmi(receiver, &slow); |
| 517 | 517 |
| 518 // Check that the key is an array index, that is Uint32. | 518 // Check that the key is an array index, that is Uint32. |
| 519 __ test(key, Immediate(kSmiTagMask | kSmiSignMask)); | 519 __ test(key, Immediate(kSmiTagMask | kSmiSignMask)); |
| 520 __ j(not_zero, &slow); | 520 __ j(not_zero, &slow); |
| 521 | 521 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 540 IC_Utility(kLoadElementWithInterceptor), masm->isolate()); | 540 IC_Utility(kLoadElementWithInterceptor), masm->isolate()); |
| 541 __ TailCallExternalReference(ref, 2, 1); | 541 __ TailCallExternalReference(ref, 2, 1); |
| 542 | 542 |
| 543 __ bind(&slow); | 543 __ bind(&slow); |
| 544 GenerateMiss(masm); | 544 GenerateMiss(masm); |
| 545 } | 545 } |
| 546 | 546 |
| 547 | 547 |
| 548 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { | 548 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { |
| 549 // The return address is on the stack. | 549 // The return address is on the stack. |
| 550 Register receiver = ReceiverRegister(); | 550 Register receiver = LoadConvention::ReceiverRegister(); |
| 551 Register key = NameRegister(); | 551 Register key = LoadConvention::NameRegister(); |
| 552 DCHECK(receiver.is(edx)); | 552 DCHECK(receiver.is(edx)); |
| 553 DCHECK(key.is(ecx)); | 553 DCHECK(key.is(ecx)); |
| 554 | 554 |
| 555 Label slow, notin; | 555 Label slow, notin; |
| 556 Factory* factory = masm->isolate()->factory(); | 556 Factory* factory = masm->isolate()->factory(); |
| 557 Operand mapped_location = GenerateMappedArgumentsLookup( | 557 Operand mapped_location = GenerateMappedArgumentsLookup( |
| 558 masm, receiver, key, ebx, eax, ¬in, &slow); | 558 masm, receiver, key, ebx, eax, ¬in, &slow); |
| 559 __ mov(eax, mapped_location); | 559 __ mov(eax, mapped_location); |
| 560 __ Ret(); | 560 __ Ret(); |
| 561 __ bind(¬in); | 561 __ bind(¬in); |
| 562 // The unmapped lookup expects that the parameter map is in ebx. | 562 // The unmapped lookup expects that the parameter map is in ebx. |
| 563 Operand unmapped_location = | 563 Operand unmapped_location = |
| 564 GenerateUnmappedArgumentsLookup(masm, key, ebx, eax, &slow); | 564 GenerateUnmappedArgumentsLookup(masm, key, ebx, eax, &slow); |
| 565 __ cmp(unmapped_location, factory->the_hole_value()); | 565 __ cmp(unmapped_location, factory->the_hole_value()); |
| 566 __ j(equal, &slow); | 566 __ j(equal, &slow); |
| 567 __ mov(eax, unmapped_location); | 567 __ mov(eax, unmapped_location); |
| 568 __ Ret(); | 568 __ Ret(); |
| 569 __ bind(&slow); | 569 __ bind(&slow); |
| 570 GenerateMiss(masm); | 570 GenerateMiss(masm); |
| 571 } | 571 } |
| 572 | 572 |
| 573 | 573 |
| 574 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { | 574 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { |
| 575 // Return address is on the stack. | 575 // Return address is on the stack. |
| 576 Label slow, notin; | 576 Label slow, notin; |
| 577 Register receiver = ReceiverRegister(); | 577 Register receiver = StoreConvention::ReceiverRegister(); |
| 578 Register name = NameRegister(); | 578 Register name = StoreConvention::NameRegister(); |
| 579 Register value = ValueRegister(); | 579 Register value = StoreConvention::ValueRegister(); |
| 580 DCHECK(receiver.is(edx)); | 580 DCHECK(receiver.is(edx)); |
| 581 DCHECK(name.is(ecx)); | 581 DCHECK(name.is(ecx)); |
| 582 DCHECK(value.is(eax)); | 582 DCHECK(value.is(eax)); |
| 583 | 583 |
| 584 Operand mapped_location = GenerateMappedArgumentsLookup( | 584 Operand mapped_location = GenerateMappedArgumentsLookup( |
| 585 masm, receiver, name, ebx, edi, ¬in, &slow); | 585 masm, receiver, name, ebx, edi, ¬in, &slow); |
| 586 __ mov(mapped_location, value); | 586 __ mov(mapped_location, value); |
| 587 __ lea(ecx, mapped_location); | 587 __ lea(ecx, mapped_location); |
| 588 __ mov(edx, value); | 588 __ mov(edx, value); |
| 589 __ RecordWrite(ebx, ecx, edx, kDontSaveFPRegs); | 589 __ RecordWrite(ebx, ecx, edx, kDontSaveFPRegs); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 601 GenerateMiss(masm); | 601 GenerateMiss(masm); |
| 602 } | 602 } |
| 603 | 603 |
| 604 | 604 |
| 605 static void KeyedStoreGenerateGenericHelper( | 605 static void KeyedStoreGenerateGenericHelper( |
| 606 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, | 606 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, |
| 607 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) { | 607 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) { |
| 608 Label transition_smi_elements; | 608 Label transition_smi_elements; |
| 609 Label finish_object_store, non_double_value, transition_double_elements; | 609 Label finish_object_store, non_double_value, transition_double_elements; |
| 610 Label fast_double_without_map_check; | 610 Label fast_double_without_map_check; |
| 611 Register receiver = KeyedStoreIC::ReceiverRegister(); | 611 Register receiver = StoreConvention::ReceiverRegister(); |
| 612 Register key = KeyedStoreIC::NameRegister(); | 612 Register key = StoreConvention::NameRegister(); |
| 613 Register value = KeyedStoreIC::ValueRegister(); | 613 Register value = StoreConvention::ValueRegister(); |
| 614 DCHECK(receiver.is(edx)); | 614 DCHECK(receiver.is(edx)); |
| 615 DCHECK(key.is(ecx)); | 615 DCHECK(key.is(ecx)); |
| 616 DCHECK(value.is(eax)); | 616 DCHECK(value.is(eax)); |
| 617 // key is a smi. | 617 // key is a smi. |
| 618 // ebx: FixedArray receiver->elements | 618 // ebx: FixedArray receiver->elements |
| 619 // edi: receiver map | 619 // edi: receiver map |
| 620 // Fast case: Do the store, could either Object or double. | 620 // Fast case: Do the store, could either Object or double. |
| 621 __ bind(fast_object); | 621 __ bind(fast_object); |
| 622 if (check_map == kCheckMap) { | 622 if (check_map == kCheckMap) { |
| 623 __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset)); | 623 __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset)); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 739 __ jmp(&finish_object_store); | 739 __ jmp(&finish_object_store); |
| 740 } | 740 } |
| 741 | 741 |
| 742 | 742 |
| 743 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, | 743 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, |
| 744 StrictMode strict_mode) { | 744 StrictMode strict_mode) { |
| 745 // Return address is on the stack. | 745 // Return address is on the stack. |
| 746 Label slow, fast_object, fast_object_grow; | 746 Label slow, fast_object, fast_object_grow; |
| 747 Label fast_double, fast_double_grow; | 747 Label fast_double, fast_double_grow; |
| 748 Label array, extra, check_if_double_array; | 748 Label array, extra, check_if_double_array; |
| 749 Register receiver = ReceiverRegister(); | 749 Register receiver = StoreConvention::ReceiverRegister(); |
| 750 Register key = NameRegister(); | 750 Register key = StoreConvention::NameRegister(); |
| 751 DCHECK(receiver.is(edx)); | 751 DCHECK(receiver.is(edx)); |
| 752 DCHECK(key.is(ecx)); | 752 DCHECK(key.is(ecx)); |
| 753 | 753 |
| 754 // Check that the object isn't a smi. | 754 // Check that the object isn't a smi. |
| 755 __ JumpIfSmi(receiver, &slow); | 755 __ JumpIfSmi(receiver, &slow); |
| 756 // Get the map from the receiver. | 756 // Get the map from the receiver. |
| 757 __ mov(edi, FieldOperand(receiver, HeapObject::kMapOffset)); | 757 __ mov(edi, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 758 // Check that the receiver does not require access checks and is not observed. | 758 // Check that the receiver does not require access checks and is not observed. |
| 759 // The generic stub does not perform map checks or handle observed objects. | 759 // The generic stub does not perform map checks or handle observed objects. |
| 760 __ test_b(FieldOperand(edi, Map::kBitFieldOffset), | 760 __ test_b(FieldOperand(edi, Map::kBitFieldOffset), |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 | 819 |
| 820 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, &slow, | 820 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, &slow, |
| 821 kCheckMap, kDontIncrementLength); | 821 kCheckMap, kDontIncrementLength); |
| 822 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, | 822 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, |
| 823 &slow, kDontCheckMap, kIncrementLength); | 823 &slow, kDontCheckMap, kIncrementLength); |
| 824 } | 824 } |
| 825 | 825 |
| 826 | 826 |
| 827 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 827 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
| 828 // The return address is on the stack. | 828 // The return address is on the stack. |
| 829 Register receiver = ReceiverRegister(); | 829 Register receiver = LoadConvention::ReceiverRegister(); |
| 830 Register name = NameRegister(); | 830 Register name = LoadConvention::NameRegister(); |
| 831 DCHECK(receiver.is(edx)); | 831 DCHECK(receiver.is(edx)); |
| 832 DCHECK(name.is(ecx)); | 832 DCHECK(name.is(ecx)); |
| 833 | 833 |
| 834 // Probe the stub cache. | 834 // Probe the stub cache. |
| 835 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 835 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
| 836 Code::ComputeHandlerFlags(Code::LOAD_IC)); | 836 Code::ComputeHandlerFlags(Code::LOAD_IC)); |
| 837 masm->isolate()->stub_cache()->GenerateProbe(masm, flags, receiver, name, ebx, | 837 masm->isolate()->stub_cache()->GenerateProbe(masm, flags, receiver, name, ebx, |
| 838 eax); | 838 eax); |
| 839 | 839 |
| 840 // Cache miss: Jump to runtime. | 840 // Cache miss: Jump to runtime. |
| 841 GenerateMiss(masm); | 841 GenerateMiss(masm); |
| 842 } | 842 } |
| 843 | 843 |
| 844 | 844 |
| 845 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 845 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
| 846 Register dictionary = eax; | 846 Register dictionary = eax; |
| 847 DCHECK(!dictionary.is(ReceiverRegister())); | 847 DCHECK(!dictionary.is(LoadConvention::ReceiverRegister())); |
| 848 DCHECK(!dictionary.is(NameRegister())); | 848 DCHECK(!dictionary.is(LoadConvention::NameRegister())); |
| 849 | 849 |
| 850 Label slow; | 850 Label slow; |
| 851 | 851 |
| 852 __ mov(dictionary, | 852 __ mov(dictionary, FieldOperand(LoadConvention::ReceiverRegister(), |
| 853 FieldOperand(ReceiverRegister(), JSObject::kPropertiesOffset)); | 853 JSObject::kPropertiesOffset)); |
| 854 GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), edi, ebx, | 854 GenerateDictionaryLoad(masm, &slow, dictionary, |
| 855 eax); | 855 LoadConvention::NameRegister(), edi, ebx, eax); |
| 856 __ ret(0); | 856 __ ret(0); |
| 857 | 857 |
| 858 // Dictionary load failed, go slow (but don't miss). | 858 // Dictionary load failed, go slow (but don't miss). |
| 859 __ bind(&slow); | 859 __ bind(&slow); |
| 860 GenerateRuntimeGetProperty(masm); | 860 GenerateRuntimeGetProperty(masm); |
| 861 } | 861 } |
| 862 | 862 |
| 863 | 863 |
| 864 static void LoadIC_PushArgs(MacroAssembler* masm) { | 864 static void LoadIC_PushArgs(MacroAssembler* masm) { |
| 865 Register receiver = LoadIC::ReceiverRegister(); | 865 Register receiver = LoadConvention::ReceiverRegister(); |
| 866 Register name = LoadIC::NameRegister(); | 866 Register name = LoadConvention::NameRegister(); |
| 867 DCHECK(!ebx.is(receiver) && !ebx.is(name)); | 867 DCHECK(!ebx.is(receiver) && !ebx.is(name)); |
| 868 | 868 |
| 869 __ pop(ebx); | 869 __ pop(ebx); |
| 870 __ push(receiver); | 870 __ push(receiver); |
| 871 __ push(name); | 871 __ push(name); |
| 872 __ push(ebx); | 872 __ push(ebx); |
| 873 } | 873 } |
| 874 | 874 |
| 875 | 875 |
| 876 void LoadIC::GenerateMiss(MacroAssembler* masm) { | 876 void LoadIC::GenerateMiss(MacroAssembler* masm) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 901 | 901 |
| 902 LoadIC_PushArgs(masm); | 902 LoadIC_PushArgs(masm); |
| 903 | 903 |
| 904 // Perform tail call to the entry. | 904 // Perform tail call to the entry. |
| 905 ExternalReference ref = | 905 ExternalReference ref = |
| 906 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); | 906 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); |
| 907 __ TailCallExternalReference(ref, 2, 1); | 907 __ TailCallExternalReference(ref, 2, 1); |
| 908 } | 908 } |
| 909 | 909 |
| 910 | 910 |
| 911 // IC register specifications | |
| 912 const Register LoadIC::ReceiverRegister() { return edx; } | |
| 913 const Register LoadIC::NameRegister() { return ecx; } | |
| 914 | |
| 915 | |
| 916 const Register LoadIC::SlotRegister() { | |
| 917 DCHECK(FLAG_vector_ics); | |
| 918 return eax; | |
| 919 } | |
| 920 | |
| 921 | |
| 922 const Register LoadIC::VectorRegister() { | |
| 923 DCHECK(FLAG_vector_ics); | |
| 924 return ebx; | |
| 925 } | |
| 926 | |
| 927 | |
| 928 const Register StoreIC::ReceiverRegister() { return edx; } | |
| 929 const Register StoreIC::NameRegister() { return ecx; } | |
| 930 const Register StoreIC::ValueRegister() { return eax; } | |
| 931 | |
| 932 | |
| 933 const Register KeyedStoreIC::MapRegister() { return ebx; } | |
| 934 | |
| 935 | |
| 936 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 911 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
| 937 // Return address is on the stack. | 912 // Return address is on the stack. |
| 938 LoadIC_PushArgs(masm); | 913 LoadIC_PushArgs(masm); |
| 939 | 914 |
| 940 // Perform tail call to the entry. | 915 // Perform tail call to the entry. |
| 941 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 916 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
| 942 } | 917 } |
| 943 | 918 |
| 944 | 919 |
| 945 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { | 920 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { |
| 946 // Return address is on the stack. | 921 // Return address is on the stack. |
| 947 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 922 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
| 948 Code::ComputeHandlerFlags(Code::STORE_IC)); | 923 Code::ComputeHandlerFlags(Code::STORE_IC)); |
| 949 masm->isolate()->stub_cache()->GenerateProbe(masm, flags, ReceiverRegister(), | 924 masm->isolate()->stub_cache()->GenerateProbe( |
| 950 NameRegister(), ebx, no_reg); | 925 masm, flags, StoreConvention::ReceiverRegister(), |
| 926 StoreConvention::NameRegister(), ebx, no_reg); |
| 951 | 927 |
| 952 // Cache miss: Jump to runtime. | 928 // Cache miss: Jump to runtime. |
| 953 GenerateMiss(masm); | 929 GenerateMiss(masm); |
| 954 } | 930 } |
| 955 | 931 |
| 956 | 932 |
| 957 static void StoreIC_PushArgs(MacroAssembler* masm) { | 933 static void StoreIC_PushArgs(MacroAssembler* masm) { |
| 958 Register receiver = StoreIC::ReceiverRegister(); | 934 Register receiver = StoreConvention::ReceiverRegister(); |
| 959 Register name = StoreIC::NameRegister(); | 935 Register name = StoreConvention::NameRegister(); |
| 960 Register value = StoreIC::ValueRegister(); | 936 Register value = StoreConvention::ValueRegister(); |
| 961 | 937 |
| 962 DCHECK(!ebx.is(receiver) && !ebx.is(name) && !ebx.is(value)); | 938 DCHECK(!ebx.is(receiver) && !ebx.is(name) && !ebx.is(value)); |
| 963 | 939 |
| 964 __ pop(ebx); | 940 __ pop(ebx); |
| 965 __ push(receiver); | 941 __ push(receiver); |
| 966 __ push(name); | 942 __ push(name); |
| 967 __ push(value); | 943 __ push(value); |
| 968 __ push(ebx); | 944 __ push(ebx); |
| 969 } | 945 } |
| 970 | 946 |
| 971 | 947 |
| 972 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 948 void StoreIC::GenerateMiss(MacroAssembler* masm) { |
| 973 // Return address is on the stack. | 949 // Return address is on the stack. |
| 974 StoreIC_PushArgs(masm); | 950 StoreIC_PushArgs(masm); |
| 975 | 951 |
| 976 // Perform tail call to the entry. | 952 // Perform tail call to the entry. |
| 977 ExternalReference ref = | 953 ExternalReference ref = |
| 978 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); | 954 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); |
| 979 __ TailCallExternalReference(ref, 3, 1); | 955 __ TailCallExternalReference(ref, 3, 1); |
| 980 } | 956 } |
| 981 | 957 |
| 982 | 958 |
| 983 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 959 void StoreIC::GenerateNormal(MacroAssembler* masm) { |
| 984 Label restore_miss; | 960 Label restore_miss; |
| 985 Register receiver = ReceiverRegister(); | 961 Register receiver = StoreConvention::ReceiverRegister(); |
| 986 Register name = NameRegister(); | 962 Register name = StoreConvention::NameRegister(); |
| 987 Register value = ValueRegister(); | 963 Register value = StoreConvention::ValueRegister(); |
| 988 Register dictionary = ebx; | 964 Register dictionary = ebx; |
| 989 | 965 |
| 990 __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 966 __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
| 991 | 967 |
| 992 // A lot of registers are needed for storing to slow case | 968 // A lot of registers are needed for storing to slow case |
| 993 // objects. Push and restore receiver but rely on | 969 // objects. Push and restore receiver but rely on |
| 994 // GenerateDictionaryStore preserving the value and name. | 970 // GenerateDictionaryStore preserving the value and name. |
| 995 __ push(receiver); | 971 __ push(receiver); |
| 996 GenerateDictionaryStore(masm, &restore_miss, dictionary, name, value, | 972 GenerateDictionaryStore(masm, &restore_miss, dictionary, name, value, |
| 997 receiver, edi); | 973 receiver, edi); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1085 Condition cc = | 1061 Condition cc = |
| 1086 (check == ENABLE_INLINED_SMI_CHECK) | 1062 (check == ENABLE_INLINED_SMI_CHECK) |
| 1087 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 1063 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
| 1088 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 1064 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
| 1089 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1065 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
| 1090 } | 1066 } |
| 1091 } | 1067 } |
| 1092 } // namespace v8::internal | 1068 } // namespace v8::internal |
| 1093 | 1069 |
| 1094 #endif // V8_TARGET_ARCH_IA32 | 1070 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |