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_X64 | 7 #if V8_TARGET_ARCH_X64 |
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 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 | 250 |
251 __ bind(&unique); | 251 __ bind(&unique); |
252 } | 252 } |
253 | 253 |
254 | 254 |
255 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 255 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { |
256 // The return address is on the stack. | 256 // The return address is on the stack. |
257 Label slow, check_name, index_smi, index_name, property_array_property; | 257 Label slow, check_name, index_smi, index_name, property_array_property; |
258 Label probe_dictionary, check_number_dictionary; | 258 Label probe_dictionary, check_number_dictionary; |
259 | 259 |
260 Register receiver = ReceiverRegister(); | 260 Register receiver = LoadConvention::ReceiverRegister(); |
261 Register key = NameRegister(); | 261 Register key = LoadConvention::NameRegister(); |
262 DCHECK(receiver.is(rdx)); | 262 DCHECK(receiver.is(rdx)); |
263 DCHECK(key.is(rcx)); | 263 DCHECK(key.is(rcx)); |
264 | 264 |
265 // Check that the key is a smi. | 265 // Check that the key is a smi. |
266 __ JumpIfNotSmi(key, &check_name); | 266 __ JumpIfNotSmi(key, &check_name); |
267 __ bind(&index_smi); | 267 __ bind(&index_smi); |
268 // Now the key is known to be a smi. This place is also jumped to from below | 268 // Now the key is known to be a smi. This place is also jumped to from below |
269 // where a numeric string is converted to a smi. | 269 // where a numeric string is converted to a smi. |
270 | 270 |
271 GenerateKeyedLoadReceiverCheck(masm, receiver, rax, | 271 GenerateKeyedLoadReceiverCheck(masm, receiver, rax, |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 __ bind(&index_name); | 400 __ bind(&index_name); |
401 __ IndexFromHash(rbx, key); | 401 __ IndexFromHash(rbx, key); |
402 __ jmp(&index_smi); | 402 __ jmp(&index_smi); |
403 } | 403 } |
404 | 404 |
405 | 405 |
406 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { | 406 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { |
407 // Return address is on the stack. | 407 // Return address is on the stack. |
408 Label miss; | 408 Label miss; |
409 | 409 |
410 Register receiver = ReceiverRegister(); | 410 Register receiver = LoadConvention::ReceiverRegister(); |
411 Register index = NameRegister(); | 411 Register index = LoadConvention::NameRegister(); |
412 Register scratch = rbx; | 412 Register scratch = rbx; |
413 Register result = rax; | 413 Register result = rax; |
414 DCHECK(!scratch.is(receiver) && !scratch.is(index)); | 414 DCHECK(!scratch.is(receiver) && !scratch.is(index)); |
415 | 415 |
416 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, | 416 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, |
417 &miss, // When not a string. | 417 &miss, // When not a string. |
418 &miss, // When not a number. | 418 &miss, // When not a number. |
419 &miss, // When index out of range. | 419 &miss, // When index out of range. |
420 STRING_INDEX_IS_ARRAY_INDEX); | 420 STRING_INDEX_IS_ARRAY_INDEX); |
421 char_at_generator.GenerateFast(masm); | 421 char_at_generator.GenerateFast(masm); |
422 __ ret(0); | 422 __ ret(0); |
423 | 423 |
424 StubRuntimeCallHelper call_helper; | 424 StubRuntimeCallHelper call_helper; |
425 char_at_generator.GenerateSlow(masm, call_helper); | 425 char_at_generator.GenerateSlow(masm, call_helper); |
426 | 426 |
427 __ bind(&miss); | 427 __ bind(&miss); |
428 GenerateMiss(masm); | 428 GenerateMiss(masm); |
429 } | 429 } |
430 | 430 |
431 | 431 |
432 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 432 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { |
433 // Return address is on the stack. | 433 // Return address is on the stack. |
434 Label slow; | 434 Label slow; |
435 | 435 |
436 Register receiver = ReceiverRegister(); | 436 Register receiver = LoadConvention::ReceiverRegister(); |
437 Register key = NameRegister(); | 437 Register key = LoadConvention::NameRegister(); |
438 Register scratch = rax; | 438 Register scratch = rax; |
439 DCHECK(!scratch.is(receiver) && !scratch.is(key)); | 439 DCHECK(!scratch.is(receiver) && !scratch.is(key)); |
440 | 440 |
441 // Check that the receiver isn't a smi. | 441 // Check that the receiver isn't a smi. |
442 __ JumpIfSmi(receiver, &slow); | 442 __ JumpIfSmi(receiver, &slow); |
443 | 443 |
444 // Check that the key is an array index, that is Uint32. | 444 // Check that the key is an array index, that is Uint32. |
445 STATIC_ASSERT(kSmiValueSize <= 32); | 445 STATIC_ASSERT(kSmiValueSize <= 32); |
446 __ JumpUnlessNonNegativeSmi(key, &slow); | 446 __ JumpUnlessNonNegativeSmi(key, &slow); |
447 | 447 |
(...skipping 23 matching lines...) Expand all Loading... |
471 GenerateMiss(masm); | 471 GenerateMiss(masm); |
472 } | 472 } |
473 | 473 |
474 | 474 |
475 static void KeyedStoreGenerateGenericHelper( | 475 static void KeyedStoreGenerateGenericHelper( |
476 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, | 476 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, |
477 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) { | 477 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) { |
478 Label transition_smi_elements; | 478 Label transition_smi_elements; |
479 Label finish_object_store, non_double_value, transition_double_elements; | 479 Label finish_object_store, non_double_value, transition_double_elements; |
480 Label fast_double_without_map_check; | 480 Label fast_double_without_map_check; |
481 Register receiver = KeyedStoreIC::ReceiverRegister(); | 481 Register receiver = StoreConvention::ReceiverRegister(); |
482 Register key = KeyedStoreIC::NameRegister(); | 482 Register key = StoreConvention::NameRegister(); |
483 Register value = KeyedStoreIC::ValueRegister(); | 483 Register value = StoreConvention::ValueRegister(); |
484 DCHECK(receiver.is(rdx)); | 484 DCHECK(receiver.is(rdx)); |
485 DCHECK(key.is(rcx)); | 485 DCHECK(key.is(rcx)); |
486 DCHECK(value.is(rax)); | 486 DCHECK(value.is(rax)); |
487 // Fast case: Do the store, could be either Object or double. | 487 // Fast case: Do the store, could be either Object or double. |
488 __ bind(fast_object); | 488 __ bind(fast_object); |
489 // rbx: receiver's elements array (a FixedArray) | 489 // rbx: receiver's elements array (a FixedArray) |
490 // receiver is a JSArray. | 490 // receiver is a JSArray. |
491 // r9: map of receiver | 491 // r9: map of receiver |
492 if (check_map == kCheckMap) { | 492 if (check_map == kCheckMap) { |
493 __ movp(rdi, FieldOperand(rbx, HeapObject::kMapOffset)); | 493 __ movp(rdi, FieldOperand(rbx, HeapObject::kMapOffset)); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 __ jmp(&finish_object_store); | 608 __ jmp(&finish_object_store); |
609 } | 609 } |
610 | 610 |
611 | 611 |
612 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, | 612 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, |
613 StrictMode strict_mode) { | 613 StrictMode strict_mode) { |
614 // Return address is on the stack. | 614 // Return address is on the stack. |
615 Label slow, slow_with_tagged_index, fast_object, fast_object_grow; | 615 Label slow, slow_with_tagged_index, fast_object, fast_object_grow; |
616 Label fast_double, fast_double_grow; | 616 Label fast_double, fast_double_grow; |
617 Label array, extra, check_if_double_array; | 617 Label array, extra, check_if_double_array; |
618 Register receiver = ReceiverRegister(); | 618 Register receiver = StoreConvention::ReceiverRegister(); |
619 Register key = NameRegister(); | 619 Register key = StoreConvention::NameRegister(); |
620 DCHECK(receiver.is(rdx)); | 620 DCHECK(receiver.is(rdx)); |
621 DCHECK(key.is(rcx)); | 621 DCHECK(key.is(rcx)); |
622 | 622 |
623 // Check that the object isn't a smi. | 623 // Check that the object isn't a smi. |
624 __ JumpIfSmi(receiver, &slow_with_tagged_index); | 624 __ JumpIfSmi(receiver, &slow_with_tagged_index); |
625 // Get the map from the receiver. | 625 // Get the map from the receiver. |
626 __ movp(r9, FieldOperand(receiver, HeapObject::kMapOffset)); | 626 __ movp(r9, FieldOperand(receiver, HeapObject::kMapOffset)); |
627 // Check that the receiver does not require access checks and is not observed. | 627 // Check that the receiver does not require access checks and is not observed. |
628 // The generic stub does not perform map checks or handle observed objects. | 628 // The generic stub does not perform map checks or handle observed objects. |
629 __ testb(FieldOperand(r9, Map::kBitFieldOffset), | 629 __ testb(FieldOperand(r9, Map::kBitFieldOffset), |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 __ cmpp(key, scratch); | 760 __ cmpp(key, scratch); |
761 __ j(greater_equal, slow_case); | 761 __ j(greater_equal, slow_case); |
762 __ SmiToInteger64(scratch, key); | 762 __ SmiToInteger64(scratch, key); |
763 return FieldOperand(backing_store, scratch, times_pointer_size, | 763 return FieldOperand(backing_store, scratch, times_pointer_size, |
764 FixedArray::kHeaderSize); | 764 FixedArray::kHeaderSize); |
765 } | 765 } |
766 | 766 |
767 | 767 |
768 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { | 768 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { |
769 // The return address is on the stack. | 769 // The return address is on the stack. |
770 Register receiver = ReceiverRegister(); | 770 Register receiver = LoadConvention::ReceiverRegister(); |
771 Register key = NameRegister(); | 771 Register key = LoadConvention::NameRegister(); |
772 DCHECK(receiver.is(rdx)); | 772 DCHECK(receiver.is(rdx)); |
773 DCHECK(key.is(rcx)); | 773 DCHECK(key.is(rcx)); |
774 | 774 |
775 Label slow, notin; | 775 Label slow, notin; |
776 Operand mapped_location = GenerateMappedArgumentsLookup( | 776 Operand mapped_location = GenerateMappedArgumentsLookup( |
777 masm, receiver, key, rbx, rax, rdi, ¬in, &slow); | 777 masm, receiver, key, rbx, rax, rdi, ¬in, &slow); |
778 __ movp(rax, mapped_location); | 778 __ movp(rax, mapped_location); |
779 __ Ret(); | 779 __ Ret(); |
780 __ bind(¬in); | 780 __ bind(¬in); |
781 // The unmapped lookup expects that the parameter map is in rbx. | 781 // The unmapped lookup expects that the parameter map is in rbx. |
782 Operand unmapped_location = | 782 Operand unmapped_location = |
783 GenerateUnmappedArgumentsLookup(masm, key, rbx, rax, &slow); | 783 GenerateUnmappedArgumentsLookup(masm, key, rbx, rax, &slow); |
784 __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex); | 784 __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex); |
785 __ j(equal, &slow); | 785 __ j(equal, &slow); |
786 __ movp(rax, unmapped_location); | 786 __ movp(rax, unmapped_location); |
787 __ Ret(); | 787 __ Ret(); |
788 __ bind(&slow); | 788 __ bind(&slow); |
789 GenerateMiss(masm); | 789 GenerateMiss(masm); |
790 } | 790 } |
791 | 791 |
792 | 792 |
793 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { | 793 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { |
794 // The return address is on the stack. | 794 // The return address is on the stack. |
795 Label slow, notin; | 795 Label slow, notin; |
796 Register receiver = ReceiverRegister(); | 796 Register receiver = StoreConvention::ReceiverRegister(); |
797 Register name = NameRegister(); | 797 Register name = StoreConvention::NameRegister(); |
798 Register value = ValueRegister(); | 798 Register value = StoreConvention::ValueRegister(); |
799 DCHECK(receiver.is(rdx)); | 799 DCHECK(receiver.is(rdx)); |
800 DCHECK(name.is(rcx)); | 800 DCHECK(name.is(rcx)); |
801 DCHECK(value.is(rax)); | 801 DCHECK(value.is(rax)); |
802 | 802 |
803 Operand mapped_location = GenerateMappedArgumentsLookup( | 803 Operand mapped_location = GenerateMappedArgumentsLookup( |
804 masm, receiver, name, rbx, rdi, r8, ¬in, &slow); | 804 masm, receiver, name, rbx, rdi, r8, ¬in, &slow); |
805 __ movp(mapped_location, value); | 805 __ movp(mapped_location, value); |
806 __ leap(r9, mapped_location); | 806 __ leap(r9, mapped_location); |
807 __ movp(r8, value); | 807 __ movp(r8, value); |
808 __ RecordWrite(rbx, r9, r8, kDontSaveFPRegs, EMIT_REMEMBERED_SET, | 808 __ RecordWrite(rbx, r9, r8, kDontSaveFPRegs, EMIT_REMEMBERED_SET, |
809 INLINE_SMI_CHECK); | 809 INLINE_SMI_CHECK); |
810 __ Ret(); | 810 __ Ret(); |
811 __ bind(¬in); | 811 __ bind(¬in); |
812 // The unmapped lookup expects that the parameter map is in rbx. | 812 // The unmapped lookup expects that the parameter map is in rbx. |
813 Operand unmapped_location = | 813 Operand unmapped_location = |
814 GenerateUnmappedArgumentsLookup(masm, name, rbx, rdi, &slow); | 814 GenerateUnmappedArgumentsLookup(masm, name, rbx, rdi, &slow); |
815 __ movp(unmapped_location, value); | 815 __ movp(unmapped_location, value); |
816 __ leap(r9, unmapped_location); | 816 __ leap(r9, unmapped_location); |
817 __ movp(r8, value); | 817 __ movp(r8, value); |
818 __ RecordWrite(rbx, r9, r8, kDontSaveFPRegs, EMIT_REMEMBERED_SET, | 818 __ RecordWrite(rbx, r9, r8, kDontSaveFPRegs, EMIT_REMEMBERED_SET, |
819 INLINE_SMI_CHECK); | 819 INLINE_SMI_CHECK); |
820 __ Ret(); | 820 __ Ret(); |
821 __ bind(&slow); | 821 __ bind(&slow); |
822 GenerateMiss(masm); | 822 GenerateMiss(masm); |
823 } | 823 } |
824 | 824 |
825 | 825 |
826 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 826 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
827 // The return address is on the stack. | 827 // The return address is on the stack. |
828 Register receiver = ReceiverRegister(); | 828 Register receiver = LoadConvention::ReceiverRegister(); |
829 Register name = NameRegister(); | 829 Register name = LoadConvention::NameRegister(); |
830 DCHECK(receiver.is(rdx)); | 830 DCHECK(receiver.is(rdx)); |
831 DCHECK(name.is(rcx)); | 831 DCHECK(name.is(rcx)); |
832 | 832 |
833 // Probe the stub cache. | 833 // Probe the stub cache. |
834 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 834 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
835 Code::ComputeHandlerFlags(Code::LOAD_IC)); | 835 Code::ComputeHandlerFlags(Code::LOAD_IC)); |
836 masm->isolate()->stub_cache()->GenerateProbe(masm, flags, receiver, name, rbx, | 836 masm->isolate()->stub_cache()->GenerateProbe(masm, flags, receiver, name, rbx, |
837 rax); | 837 rax); |
838 | 838 |
839 GenerateMiss(masm); | 839 GenerateMiss(masm); |
840 } | 840 } |
841 | 841 |
842 | 842 |
843 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 843 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
844 Register dictionary = rax; | 844 Register dictionary = rax; |
845 DCHECK(!dictionary.is(ReceiverRegister())); | 845 DCHECK(!dictionary.is(LoadConvention::ReceiverRegister())); |
846 DCHECK(!dictionary.is(NameRegister())); | 846 DCHECK(!dictionary.is(LoadConvention::NameRegister())); |
847 | 847 |
848 Label slow; | 848 Label slow; |
849 | 849 |
850 __ movp(dictionary, | 850 __ movp(dictionary, FieldOperand(LoadConvention::ReceiverRegister(), |
851 FieldOperand(ReceiverRegister(), JSObject::kPropertiesOffset)); | 851 JSObject::kPropertiesOffset)); |
852 GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), rbx, rdi, | 852 GenerateDictionaryLoad(masm, &slow, dictionary, |
853 rax); | 853 LoadConvention::NameRegister(), rbx, rdi, rax); |
854 __ ret(0); | 854 __ ret(0); |
855 | 855 |
856 // Dictionary load failed, go slow (but don't miss). | 856 // Dictionary load failed, go slow (but don't miss). |
857 __ bind(&slow); | 857 __ bind(&slow); |
858 GenerateRuntimeGetProperty(masm); | 858 GenerateRuntimeGetProperty(masm); |
859 } | 859 } |
860 | 860 |
861 | 861 |
862 // A register that isn't one of the parameters to the load ic. | 862 // A register that isn't one of the parameters to the load ic. |
863 static const Register LoadIC_TempRegister() { return rbx; } | 863 static const Register LoadIC_TempRegister() { return rbx; } |
864 | 864 |
865 | 865 |
866 static const Register KeyedLoadIC_TempRegister() { return rbx; } | 866 static const Register KeyedLoadIC_TempRegister() { return rbx; } |
867 | 867 |
868 | 868 |
869 void LoadIC::GenerateMiss(MacroAssembler* masm) { | 869 void LoadIC::GenerateMiss(MacroAssembler* masm) { |
870 // The return address is on the stack. | 870 // The return address is on the stack. |
871 | 871 |
872 Counters* counters = masm->isolate()->counters(); | 872 Counters* counters = masm->isolate()->counters(); |
873 __ IncrementCounter(counters->load_miss(), 1); | 873 __ IncrementCounter(counters->load_miss(), 1); |
874 | 874 |
875 __ PopReturnAddressTo(LoadIC_TempRegister()); | 875 __ PopReturnAddressTo(LoadIC_TempRegister()); |
876 __ Push(ReceiverRegister()); // receiver | 876 __ Push(LoadConvention::ReceiverRegister()); // receiver |
877 __ Push(NameRegister()); // name | 877 __ Push(LoadConvention::NameRegister()); // name |
878 __ PushReturnAddressFrom(LoadIC_TempRegister()); | 878 __ PushReturnAddressFrom(LoadIC_TempRegister()); |
879 | 879 |
880 // Perform tail call to the entry. | 880 // Perform tail call to the entry. |
881 ExternalReference ref = | 881 ExternalReference ref = |
882 ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate()); | 882 ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate()); |
883 __ TailCallExternalReference(ref, 2, 1); | 883 __ TailCallExternalReference(ref, 2, 1); |
884 } | 884 } |
885 | 885 |
886 | 886 |
887 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 887 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
888 // The return address is on the stack. | 888 // The return address is on the stack. |
889 | 889 |
890 __ PopReturnAddressTo(LoadIC_TempRegister()); | 890 __ PopReturnAddressTo(LoadIC_TempRegister()); |
891 __ Push(ReceiverRegister()); // receiver | 891 __ Push(LoadConvention::ReceiverRegister()); // receiver |
892 __ Push(NameRegister()); // name | 892 __ Push(LoadConvention::NameRegister()); // name |
893 __ PushReturnAddressFrom(LoadIC_TempRegister()); | 893 __ PushReturnAddressFrom(LoadIC_TempRegister()); |
894 | 894 |
895 // Perform tail call to the entry. | 895 // Perform tail call to the entry. |
896 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); | 896 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); |
897 } | 897 } |
898 | 898 |
899 | 899 |
900 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 900 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
901 // The return address is on the stack. | 901 // The return address is on the stack. |
902 Counters* counters = masm->isolate()->counters(); | 902 Counters* counters = masm->isolate()->counters(); |
903 __ IncrementCounter(counters->keyed_load_miss(), 1); | 903 __ IncrementCounter(counters->keyed_load_miss(), 1); |
904 | 904 |
905 __ PopReturnAddressTo(KeyedLoadIC_TempRegister()); | 905 __ PopReturnAddressTo(KeyedLoadIC_TempRegister()); |
906 __ Push(ReceiverRegister()); // receiver | 906 __ Push(LoadConvention::ReceiverRegister()); // receiver |
907 __ Push(NameRegister()); // name | 907 __ Push(LoadConvention::NameRegister()); // name |
908 __ PushReturnAddressFrom(KeyedLoadIC_TempRegister()); | 908 __ PushReturnAddressFrom(KeyedLoadIC_TempRegister()); |
909 | 909 |
910 // Perform tail call to the entry. | 910 // Perform tail call to the entry. |
911 ExternalReference ref = | 911 ExternalReference ref = |
912 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); | 912 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); |
913 __ TailCallExternalReference(ref, 2, 1); | 913 __ TailCallExternalReference(ref, 2, 1); |
914 } | 914 } |
915 | 915 |
916 | 916 |
917 // IC register specifications | |
918 const Register LoadIC::ReceiverRegister() { return rdx; } | |
919 const Register LoadIC::NameRegister() { return rcx; } | |
920 | |
921 | |
922 const Register LoadIC::SlotRegister() { | |
923 DCHECK(FLAG_vector_ics); | |
924 return rax; | |
925 } | |
926 | |
927 | |
928 const Register LoadIC::VectorRegister() { | |
929 DCHECK(FLAG_vector_ics); | |
930 return rbx; | |
931 } | |
932 | |
933 | |
934 const Register StoreIC::ReceiverRegister() { return rdx; } | |
935 const Register StoreIC::NameRegister() { return rcx; } | |
936 const Register StoreIC::ValueRegister() { return rax; } | |
937 | |
938 | |
939 const Register KeyedStoreIC::MapRegister() { return rbx; } | |
940 | |
941 | |
942 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 917 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
943 // The return address is on the stack. | 918 // The return address is on the stack. |
944 | 919 |
945 __ PopReturnAddressTo(KeyedLoadIC_TempRegister()); | 920 __ PopReturnAddressTo(KeyedLoadIC_TempRegister()); |
946 __ Push(ReceiverRegister()); // receiver | 921 __ Push(LoadConvention::ReceiverRegister()); // receiver |
947 __ Push(NameRegister()); // name | 922 __ Push(LoadConvention::NameRegister()); // name |
948 __ PushReturnAddressFrom(KeyedLoadIC_TempRegister()); | 923 __ PushReturnAddressFrom(KeyedLoadIC_TempRegister()); |
949 | 924 |
950 // Perform tail call to the entry. | 925 // Perform tail call to the entry. |
951 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 926 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
952 } | 927 } |
953 | 928 |
954 | 929 |
955 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { | 930 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { |
956 // The return address is on the stack. | 931 // The return address is on the stack. |
957 | 932 |
958 // Get the receiver from the stack and probe the stub cache. | 933 // Get the receiver from the stack and probe the stub cache. |
959 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 934 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
960 Code::ComputeHandlerFlags(Code::STORE_IC)); | 935 Code::ComputeHandlerFlags(Code::STORE_IC)); |
961 masm->isolate()->stub_cache()->GenerateProbe(masm, flags, ReceiverRegister(), | 936 masm->isolate()->stub_cache()->GenerateProbe( |
962 NameRegister(), rbx, no_reg); | 937 masm, flags, StoreConvention::ReceiverRegister(), |
| 938 StoreConvention::NameRegister(), rbx, no_reg); |
963 | 939 |
964 // Cache miss: Jump to runtime. | 940 // Cache miss: Jump to runtime. |
965 GenerateMiss(masm); | 941 GenerateMiss(masm); |
966 } | 942 } |
967 | 943 |
968 | 944 |
969 static void StoreIC_PushArgs(MacroAssembler* masm) { | 945 static void StoreIC_PushArgs(MacroAssembler* masm) { |
970 Register receiver = StoreIC::ReceiverRegister(); | 946 Register receiver = StoreConvention::ReceiverRegister(); |
971 Register name = StoreIC::NameRegister(); | 947 Register name = StoreConvention::NameRegister(); |
972 Register value = StoreIC::ValueRegister(); | 948 Register value = StoreConvention::ValueRegister(); |
973 | 949 |
974 DCHECK(!rbx.is(receiver) && !rbx.is(name) && !rbx.is(value)); | 950 DCHECK(!rbx.is(receiver) && !rbx.is(name) && !rbx.is(value)); |
975 | 951 |
976 __ PopReturnAddressTo(rbx); | 952 __ PopReturnAddressTo(rbx); |
977 __ Push(receiver); | 953 __ Push(receiver); |
978 __ Push(name); | 954 __ Push(name); |
979 __ Push(value); | 955 __ Push(value); |
980 __ PushReturnAddressFrom(rbx); | 956 __ PushReturnAddressFrom(rbx); |
981 } | 957 } |
982 | 958 |
983 | 959 |
984 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 960 void StoreIC::GenerateMiss(MacroAssembler* masm) { |
985 // Return address is on the stack. | 961 // Return address is on the stack. |
986 StoreIC_PushArgs(masm); | 962 StoreIC_PushArgs(masm); |
987 | 963 |
988 // Perform tail call to the entry. | 964 // Perform tail call to the entry. |
989 ExternalReference ref = | 965 ExternalReference ref = |
990 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); | 966 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); |
991 __ TailCallExternalReference(ref, 3, 1); | 967 __ TailCallExternalReference(ref, 3, 1); |
992 } | 968 } |
993 | 969 |
994 | 970 |
995 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 971 void StoreIC::GenerateNormal(MacroAssembler* masm) { |
996 Register receiver = ReceiverRegister(); | 972 Register receiver = StoreConvention::ReceiverRegister(); |
997 Register name = NameRegister(); | 973 Register name = StoreConvention::NameRegister(); |
998 Register value = ValueRegister(); | 974 Register value = StoreConvention::ValueRegister(); |
999 Register dictionary = rbx; | 975 Register dictionary = rbx; |
1000 | 976 |
1001 Label miss; | 977 Label miss; |
1002 | 978 |
1003 __ movp(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 979 __ movp(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
1004 GenerateDictionaryStore(masm, &miss, dictionary, name, value, r8, r9); | 980 GenerateDictionaryStore(masm, &miss, dictionary, name, value, r8, r9); |
1005 Counters* counters = masm->isolate()->counters(); | 981 Counters* counters = masm->isolate()->counters(); |
1006 __ IncrementCounter(counters->store_normal_hit(), 1); | 982 __ IncrementCounter(counters->store_normal_hit(), 1); |
1007 __ ret(0); | 983 __ ret(0); |
1008 | 984 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1090 Condition cc = | 1066 Condition cc = |
1091 (check == ENABLE_INLINED_SMI_CHECK) | 1067 (check == ENABLE_INLINED_SMI_CHECK) |
1092 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 1068 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
1093 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 1069 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
1094 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1070 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
1095 } | 1071 } |
1096 } | 1072 } |
1097 } // namespace v8::internal | 1073 } // namespace v8::internal |
1098 | 1074 |
1099 #endif // V8_TARGET_ARCH_X64 | 1075 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |