Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/x64/ic-x64.cc

Issue 8404030: Version 3.7.1 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | src/x64/lithium-codegen-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 694 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 __ JumpIfNotSmi(rax, &non_smi_value); 705 __ JumpIfNotSmi(rax, &non_smi_value);
706 // It's irrelevant whether array is smi-only or not when writing a smi. 706 // It's irrelevant whether array is smi-only or not when writing a smi.
707 __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize), 707 __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
708 rax); 708 rax);
709 __ ret(0); 709 __ ret(0);
710 710
711 __ bind(&non_smi_value); 711 __ bind(&non_smi_value);
712 // Writing a non-smi, check whether array allows non-smi elements. 712 // Writing a non-smi, check whether array allows non-smi elements.
713 // r9: receiver's map 713 // r9: receiver's map
714 __ CheckFastObjectElements(r9, &slow, Label::kNear); 714 __ CheckFastObjectElements(r9, &slow, Label::kNear);
715 __ lea(rcx, 715 __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
716 FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize)); 716 rax);
717 __ movq(Operand(rcx, 0), rax); 717 __ movq(rdx, rax); // Preserve the value which is returned.
718 __ movq(rdx, rax); 718 __ RecordWriteArray(
719 __ RecordWrite( 719 rbx, rdx, rcx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
720 rbx, rcx, rdx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
721 __ ret(0); 720 __ ret(0);
722 721
723 __ bind(&fast_double_with_map_check); 722 __ bind(&fast_double_with_map_check);
724 // Check for fast double array case. If this fails, call through to the 723 // Check for fast double array case. If this fails, call through to the
725 // runtime. 724 // runtime.
726 // rdi: elements array's map 725 // rdi: elements array's map
727 __ CompareRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex); 726 __ CompareRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
728 __ j(not_equal, &slow); 727 __ j(not_equal, &slow);
729 __ bind(&fast_double_without_map_check); 728 __ bind(&fast_double_without_map_check);
730 // If the value is a number, store it as a double in the FastDoubleElements 729 // If the value is a number, store it as a double in the FastDoubleElements
731 // array. 730 // array.
732 __ StoreNumberToDoubleElements(rax, rbx, rcx, xmm0, &slow); 731 __ StoreNumberToDoubleElements(rax, rbx, rcx, xmm0, &slow);
733 __ ret(0); 732 __ ret(0);
734 } 733 }
735 734
736 735
737 // The generated code does not accept smi keys. 736 // The generated code does not accept smi keys.
738 // The generated code falls through if both probes miss. 737 // The generated code falls through if both probes miss.
739 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, 738 void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm,
740 int argc, 739 int argc,
741 Code::Kind kind, 740 Code::Kind kind,
742 Code::ExtraICState extra_ic_state) { 741 Code::ExtraICState extra_state) {
743 // ----------- S t a t e ------------- 742 // ----------- S t a t e -------------
744 // rcx : function name 743 // rcx : function name
745 // rdx : receiver 744 // rdx : receiver
746 // ----------------------------------- 745 // -----------------------------------
747 Label number, non_number, non_string, boolean, probe, miss; 746 Label number, non_number, non_string, boolean, probe, miss;
748 747
749 // Probe the stub cache. 748 // Probe the stub cache.
750 Code::Flags flags = Code::ComputeFlags(kind, 749 Code::Flags flags = Code::ComputeFlags(kind,
751 MONOMORPHIC, 750 MONOMORPHIC,
752 extra_ic_state, 751 extra_state,
753 NORMAL, 752 NORMAL,
754 argc); 753 argc);
755 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx, 754 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx,
756 rax); 755 rax);
757 756
758 // If the stub cache probing failed, the receiver might be a value. 757 // If the stub cache probing failed, the receiver might be a value.
759 // For value objects, we use the map of the prototype objects for 758 // For value objects, we use the map of the prototype objects for
760 // the corresponding JSValue for the cache and that is what we need 759 // the corresponding JSValue for the cache and that is what we need
761 // to probe. 760 // to probe.
762 // 761 //
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 __ j(not_equal, miss); 814 __ j(not_equal, miss);
816 815
817 // Invoke the function. 816 // Invoke the function.
818 ParameterCount actual(argc); 817 ParameterCount actual(argc);
819 __ InvokeFunction(rdi, actual, JUMP_FUNCTION, 818 __ InvokeFunction(rdi, actual, JUMP_FUNCTION,
820 NullCallWrapper(), CALL_AS_METHOD); 819 NullCallWrapper(), CALL_AS_METHOD);
821 } 820 }
822 821
823 822
824 // The generated code falls through if the call should be handled by runtime. 823 // The generated code falls through if the call should be handled by runtime.
825 static void GenerateCallNormal(MacroAssembler* masm, int argc) { 824 void CallICBase::GenerateNormal(MacroAssembler* masm, int argc) {
826 // ----------- S t a t e ------------- 825 // ----------- S t a t e -------------
827 // rcx : function name 826 // rcx : function name
828 // rsp[0] : return address 827 // rsp[0] : return address
829 // rsp[8] : argument argc 828 // rsp[8] : argument argc
830 // rsp[16] : argument argc - 1 829 // rsp[16] : argument argc - 1
831 // ... 830 // ...
832 // rsp[argc * 8] : argument 1 831 // rsp[argc * 8] : argument 1
833 // rsp[(argc + 1) * 8] : argument 0 = receiver 832 // rsp[(argc + 1) * 8] : argument 0 = receiver
834 // ----------------------------------- 833 // -----------------------------------
835 Label miss; 834 Label miss;
836 835
837 // Get the receiver of the function from the stack. 836 // Get the receiver of the function from the stack.
838 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 837 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
839 838
840 GenerateStringDictionaryReceiverCheck(masm, rdx, rax, rbx, &miss); 839 GenerateStringDictionaryReceiverCheck(masm, rdx, rax, rbx, &miss);
841 840
842 // rax: elements 841 // rax: elements
843 // Search the dictionary placing the result in rdi. 842 // Search the dictionary placing the result in rdi.
844 GenerateDictionaryLoad(masm, &miss, rax, rcx, rbx, rdi, rdi); 843 GenerateDictionaryLoad(masm, &miss, rax, rcx, rbx, rdi, rdi);
845 844
846 GenerateFunctionTailCall(masm, argc, &miss); 845 GenerateFunctionTailCall(masm, argc, &miss);
847 846
848 __ bind(&miss); 847 __ bind(&miss);
849 } 848 }
850 849
851 850
852 static void GenerateCallMiss(MacroAssembler* masm, 851 void CallICBase::GenerateMiss(MacroAssembler* masm,
853 int argc, 852 int argc,
854 IC::UtilityId id, 853 IC::UtilityId id,
855 Code::ExtraICState extra_ic_state) { 854 Code::ExtraICState extra_state) {
856 // ----------- S t a t e ------------- 855 // ----------- S t a t e -------------
857 // rcx : function name 856 // rcx : function name
858 // rsp[0] : return address 857 // rsp[0] : return address
859 // rsp[8] : argument argc 858 // rsp[8] : argument argc
860 // rsp[16] : argument argc - 1 859 // rsp[16] : argument argc - 1
861 // ... 860 // ...
862 // rsp[argc * 8] : argument 1 861 // rsp[argc * 8] : argument 1
863 // rsp[(argc + 1) * 8] : argument 0 = receiver 862 // rsp[(argc + 1) * 8] : argument 0 = receiver
864 // ----------------------------------- 863 // -----------------------------------
865 864
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 __ j(not_equal, &invoke); 902 __ j(not_equal, &invoke);
904 903
905 // Patch the receiver on the stack. 904 // Patch the receiver on the stack.
906 __ bind(&global); 905 __ bind(&global);
907 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 906 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
908 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 907 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
909 __ bind(&invoke); 908 __ bind(&invoke);
910 } 909 }
911 910
912 // Invoke the function. 911 // Invoke the function.
913 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state) 912 CallKind call_kind = CallICBase::Contextual::decode(extra_state)
914 ? CALL_AS_FUNCTION 913 ? CALL_AS_FUNCTION
915 : CALL_AS_METHOD; 914 : CALL_AS_METHOD;
916 ParameterCount actual(argc); 915 ParameterCount actual(argc);
917 __ InvokeFunction(rdi, 916 __ InvokeFunction(rdi,
918 actual, 917 actual,
919 JUMP_FUNCTION, 918 JUMP_FUNCTION,
920 NullCallWrapper(), 919 NullCallWrapper(),
921 call_kind); 920 call_kind);
922 } 921 }
923 922
(...skipping 11 matching lines...) Expand all
935 // rsp[(argc + 1) * 8] : argument 0 = receiver 934 // rsp[(argc + 1) * 8] : argument 0 = receiver
936 // ----------------------------------- 935 // -----------------------------------
937 936
938 // Get the receiver of the function from the stack; 1 ~ return address. 937 // Get the receiver of the function from the stack; 1 ~ return address.
939 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 938 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
940 GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC, extra_ic_state); 939 GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC, extra_ic_state);
941 GenerateMiss(masm, argc, extra_ic_state); 940 GenerateMiss(masm, argc, extra_ic_state);
942 } 941 }
943 942
944 943
945 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) {
946 // ----------- S t a t e -------------
947 // rcx : function name
948 // rsp[0] : return address
949 // rsp[8] : argument argc
950 // rsp[16] : argument argc - 1
951 // ...
952 // rsp[argc * 8] : argument 1
953 // rsp[(argc + 1) * 8] : argument 0 = receiver
954 // -----------------------------------
955
956 GenerateCallNormal(masm, argc);
957 GenerateMiss(masm, argc, Code::kNoExtraICState);
958 }
959
960
961 void CallIC::GenerateMiss(MacroAssembler* masm,
962 int argc,
963 Code::ExtraICState extra_ic_state) {
964 // ----------- S t a t e -------------
965 // rcx : function name
966 // rsp[0] : return address
967 // rsp[8] : argument argc
968 // rsp[16] : argument argc - 1
969 // ...
970 // rsp[argc * 8] : argument 1
971 // rsp[(argc + 1) * 8] : argument 0 = receiver
972 // -----------------------------------
973
974 GenerateCallMiss(masm, argc, IC::kCallIC_Miss, extra_ic_state);
975 }
976
977
978 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { 944 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
979 // ----------- S t a t e ------------- 945 // ----------- S t a t e -------------
980 // rcx : function name 946 // rcx : function name
981 // rsp[0] : return address 947 // rsp[0] : return address
982 // rsp[8] : argument argc 948 // rsp[8] : argument argc
983 // rsp[16] : argument argc - 1 949 // rsp[16] : argument argc - 1
984 // ... 950 // ...
985 // rsp[argc * 8] : argument 1 951 // rsp[argc * 8] : argument 1
986 // rsp[(argc + 1) * 8] : argument 0 = receiver 952 // rsp[(argc + 1) * 8] : argument 0 = receiver
987 // ----------------------------------- 953 // -----------------------------------
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 // ... 1061 // ...
1096 // rsp[argc * 8] : argument 1 1062 // rsp[argc * 8] : argument 1
1097 // rsp[(argc + 1) * 8] : argument 0 = receiver 1063 // rsp[(argc + 1) * 8] : argument 0 = receiver
1098 // ----------------------------------- 1064 // -----------------------------------
1099 1065
1100 // Check if the name is a string. 1066 // Check if the name is a string.
1101 Label miss; 1067 Label miss;
1102 __ JumpIfSmi(rcx, &miss); 1068 __ JumpIfSmi(rcx, &miss);
1103 Condition cond = masm->IsObjectStringType(rcx, rax, rax); 1069 Condition cond = masm->IsObjectStringType(rcx, rax, rax);
1104 __ j(NegateCondition(cond), &miss); 1070 __ j(NegateCondition(cond), &miss);
1105 GenerateCallNormal(masm, argc); 1071 CallICBase::GenerateNormal(masm, argc);
1106 __ bind(&miss); 1072 __ bind(&miss);
1107 GenerateMiss(masm, argc); 1073 GenerateMiss(masm, argc);
1108 } 1074 }
1109 1075
1110 1076
1111 void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) {
1112 // ----------- S t a t e -------------
1113 // rcx : function name
1114 // rsp[0] : return address
1115 // rsp[8] : argument argc
1116 // rsp[16] : argument argc - 1
1117 // ...
1118 // rsp[argc * 8] : argument 1
1119 // rsp[(argc + 1) * 8] : argument 0 = receiver
1120 // -----------------------------------
1121
1122 GenerateCallMiss(masm, argc, IC::kKeyedCallIC_Miss, Code::kNoExtraICState);
1123 }
1124
1125
1126 static Operand GenerateMappedArgumentsLookup(MacroAssembler* masm, 1077 static Operand GenerateMappedArgumentsLookup(MacroAssembler* masm,
1127 Register object, 1078 Register object,
1128 Register key, 1079 Register key,
1129 Register scratch1, 1080 Register scratch1,
1130 Register scratch2, 1081 Register scratch2,
1131 Register scratch3, 1082 Register scratch3,
1132 Label* unmapped_case, 1083 Label* unmapped_case,
1133 Label* slow_case) { 1084 Label* slow_case) {
1134 Heap* heap = masm->isolate()->heap(); 1085 Heap* heap = masm->isolate()->heap();
1135 1086
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
1595 1546
1596 // Do tail-call to runtime routine. 1547 // Do tail-call to runtime routine.
1597 ExternalReference ref = force_generic 1548 ExternalReference ref = force_generic
1598 ? ExternalReference(IC_Utility(kKeyedStoreIC_MissForceGeneric), 1549 ? ExternalReference(IC_Utility(kKeyedStoreIC_MissForceGeneric),
1599 masm->isolate()) 1550 masm->isolate())
1600 : ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate()); 1551 : ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate());
1601 __ TailCallExternalReference(ref, 3, 1); 1552 __ TailCallExternalReference(ref, 3, 1);
1602 } 1553 }
1603 1554
1604 1555
1556 void KeyedStoreIC::GenerateTransitionElementsSmiToDouble(MacroAssembler* masm) {
1557 // ----------- S t a t e -------------
1558 // -- rbx : target map
1559 // -- rdx : receiver
1560 // -- rsp[0] : return address
1561 // -----------------------------------
1562 // Must return the modified receiver in eax.
1563 if (!FLAG_trace_elements_transitions) {
1564 Label fail;
1565 ElementsTransitionGenerator::GenerateSmiOnlyToDouble(masm, &fail);
1566 __ movq(rax, rdx);
1567 __ Ret();
1568 __ bind(&fail);
1569 }
1570
1571 __ pop(rbx);
1572 __ push(rdx);
1573 __ push(rbx); // return address
1574 __ TailCallRuntime(Runtime::kTransitionElementsSmiToDouble, 1, 1);
1575 }
1576
1577
1578 void KeyedStoreIC::GenerateTransitionElementsDoubleToObject(
1579 MacroAssembler* masm) {
1580 // ----------- S t a t e -------------
1581 // -- rbx : target map
1582 // -- rdx : receiver
1583 // -- rsp[0] : return address
1584 // -----------------------------------
1585 // Must return the modified receiver in eax.
1586 if (!FLAG_trace_elements_transitions) {
1587 Label fail;
1588 ElementsTransitionGenerator::GenerateDoubleToObject(masm, &fail);
1589 __ movq(rax, rdx);
1590 __ Ret();
1591 __ bind(&fail);
1592 }
1593
1594 __ pop(rbx);
1595 __ push(rdx);
1596 __ push(rbx); // return address
1597 __ TailCallRuntime(Runtime::kTransitionElementsDoubleToObject, 1, 1);
1598 }
1599
1600
1605 #undef __ 1601 #undef __
1606 1602
1607 1603
1608 Condition CompareIC::ComputeCondition(Token::Value op) { 1604 Condition CompareIC::ComputeCondition(Token::Value op) {
1609 switch (op) { 1605 switch (op) {
1610 case Token::EQ_STRICT: 1606 case Token::EQ_STRICT:
1611 case Token::EQ: 1607 case Token::EQ:
1612 return equal; 1608 return equal;
1613 case Token::LT: 1609 case Token::LT:
1614 return less; 1610 return less;
1615 case Token::GT: 1611 case Token::GT:
1616 // Reverse left and right operands to obtain ECMA-262 conversion order. 1612 return greater;
1617 return less;
1618 case Token::LTE: 1613 case Token::LTE:
1619 // Reverse left and right operands to obtain ECMA-262 conversion order. 1614 return less_equal;
1620 return greater_equal;
1621 case Token::GTE: 1615 case Token::GTE:
1622 return greater_equal; 1616 return greater_equal;
1623 default: 1617 default:
1624 UNREACHABLE(); 1618 UNREACHABLE();
1625 return no_condition; 1619 return no_condition;
1626 } 1620 }
1627 } 1621 }
1628 1622
1629 1623
1630 static bool HasInlinedSmiCode(Address address) { 1624 static bool HasInlinedSmiCode(Address address) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1697 Condition cc = *jmp_address == Assembler::kJncShortOpcode 1691 Condition cc = *jmp_address == Assembler::kJncShortOpcode
1698 ? not_zero 1692 ? not_zero
1699 : zero; 1693 : zero;
1700 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 1694 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1701 } 1695 }
1702 1696
1703 1697
1704 } } // namespace v8::internal 1698 } } // namespace v8::internal
1705 1699
1706 #endif // V8_TARGET_ARCH_X64 1700 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | src/x64/lithium-codegen-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698