OLD | NEW |
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 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 __ j(zero, &check_number_dictionary); | 572 __ j(zero, &check_number_dictionary); |
573 | 573 |
574 GenerateFastArrayLoad(masm, | 574 GenerateFastArrayLoad(masm, |
575 rdx, | 575 rdx, |
576 rax, | 576 rax, |
577 rcx, | 577 rcx, |
578 rbx, | 578 rbx, |
579 rax, | 579 rax, |
580 NULL, | 580 NULL, |
581 &slow); | 581 &slow); |
582 __ IncrementCounter(&Counters::keyed_load_generic_smi, 1); | 582 __ IncrementCounter(COUNTERS->keyed_load_generic_smi(), 1); |
583 __ ret(0); | 583 __ ret(0); |
584 | 584 |
585 __ bind(&check_number_dictionary); | 585 __ bind(&check_number_dictionary); |
586 __ SmiToInteger32(rbx, rax); | 586 __ SmiToInteger32(rbx, rax); |
587 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); | 587 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); |
588 | 588 |
589 // Check whether the elements is a number dictionary. | 589 // Check whether the elements is a number dictionary. |
590 // rdx: receiver | 590 // rdx: receiver |
591 // rax: key | 591 // rax: key |
592 // rbx: key as untagged int32 | 592 // rbx: key as untagged int32 |
593 // rcx: elements | 593 // rcx: elements |
594 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset), | 594 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset), |
595 Heap::kHashTableMapRootIndex); | 595 Heap::kHashTableMapRootIndex); |
596 __ j(not_equal, &slow); | 596 __ j(not_equal, &slow); |
597 GenerateNumberDictionaryLoad(masm, &slow, rcx, rax, rbx, r9, rdi, rax); | 597 GenerateNumberDictionaryLoad(masm, &slow, rcx, rax, rbx, r9, rdi, rax); |
598 __ ret(0); | 598 __ ret(0); |
599 | 599 |
600 __ bind(&slow); | 600 __ bind(&slow); |
601 // Slow case: Jump to runtime. | 601 // Slow case: Jump to runtime. |
602 // rdx: receiver | 602 // rdx: receiver |
603 // rax: key | 603 // rax: key |
604 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1); | 604 __ IncrementCounter(COUNTERS->keyed_load_generic_slow(), 1); |
605 GenerateRuntimeGetProperty(masm); | 605 GenerateRuntimeGetProperty(masm); |
606 | 606 |
607 __ bind(&check_string); | 607 __ bind(&check_string); |
608 GenerateKeyStringCheck(masm, rax, rcx, rbx, &index_string, &slow); | 608 GenerateKeyStringCheck(masm, rax, rcx, rbx, &index_string, &slow); |
609 | 609 |
610 GenerateKeyedLoadReceiverCheck( | 610 GenerateKeyedLoadReceiverCheck( |
611 masm, rdx, rcx, Map::kHasNamedInterceptor, &slow); | 611 masm, rdx, rcx, Map::kHasNamedInterceptor, &slow); |
612 | 612 |
613 // If the receiver is a fast-case object, check the keyed lookup | 613 // If the receiver is a fast-case object, check the keyed lookup |
614 // cache. Otherwise probe the dictionary leaving result in rcx. | 614 // cache. Otherwise probe the dictionary leaving result in rcx. |
(...skipping 30 matching lines...) Expand all Loading... |
645 __ movq(kScratchRegister, cache_field_offsets); | 645 __ movq(kScratchRegister, cache_field_offsets); |
646 __ movl(rdi, Operand(kScratchRegister, rcx, times_4, 0)); | 646 __ movl(rdi, Operand(kScratchRegister, rcx, times_4, 0)); |
647 __ movzxbq(rcx, FieldOperand(rbx, Map::kInObjectPropertiesOffset)); | 647 __ movzxbq(rcx, FieldOperand(rbx, Map::kInObjectPropertiesOffset)); |
648 __ subq(rdi, rcx); | 648 __ subq(rdi, rcx); |
649 __ j(above_equal, &property_array_property); | 649 __ j(above_equal, &property_array_property); |
650 | 650 |
651 // Load in-object property. | 651 // Load in-object property. |
652 __ movzxbq(rcx, FieldOperand(rbx, Map::kInstanceSizeOffset)); | 652 __ movzxbq(rcx, FieldOperand(rbx, Map::kInstanceSizeOffset)); |
653 __ addq(rcx, rdi); | 653 __ addq(rcx, rdi); |
654 __ movq(rax, FieldOperand(rdx, rcx, times_pointer_size, 0)); | 654 __ movq(rax, FieldOperand(rdx, rcx, times_pointer_size, 0)); |
655 __ IncrementCounter(&Counters::keyed_load_generic_lookup_cache, 1); | 655 __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1); |
656 __ ret(0); | 656 __ ret(0); |
657 | 657 |
658 // Load property array property. | 658 // Load property array property. |
659 __ bind(&property_array_property); | 659 __ bind(&property_array_property); |
660 __ movq(rax, FieldOperand(rdx, JSObject::kPropertiesOffset)); | 660 __ movq(rax, FieldOperand(rdx, JSObject::kPropertiesOffset)); |
661 __ movq(rax, FieldOperand(rax, rdi, times_pointer_size, | 661 __ movq(rax, FieldOperand(rax, rdi, times_pointer_size, |
662 FixedArray::kHeaderSize)); | 662 FixedArray::kHeaderSize)); |
663 __ IncrementCounter(&Counters::keyed_load_generic_lookup_cache, 1); | 663 __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1); |
664 __ ret(0); | 664 __ ret(0); |
665 | 665 |
666 // Do a quick inline probe of the receiver's dictionary, if it | 666 // Do a quick inline probe of the receiver's dictionary, if it |
667 // exists. | 667 // exists. |
668 __ bind(&probe_dictionary); | 668 __ bind(&probe_dictionary); |
669 // rdx: receiver | 669 // rdx: receiver |
670 // rax: key | 670 // rax: key |
671 // rbx: elements | 671 // rbx: elements |
672 | 672 |
673 __ movq(rcx, FieldOperand(rdx, JSObject::kMapOffset)); | 673 __ movq(rcx, FieldOperand(rdx, JSObject::kMapOffset)); |
674 __ movb(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset)); | 674 __ movb(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset)); |
675 GenerateGlobalInstanceTypeCheck(masm, rcx, &slow); | 675 GenerateGlobalInstanceTypeCheck(masm, rcx, &slow); |
676 | 676 |
677 GenerateDictionaryLoad(masm, &slow, rbx, rax, rcx, rdi, rax); | 677 GenerateDictionaryLoad(masm, &slow, rbx, rax, rcx, rdi, rax); |
678 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1); | 678 __ IncrementCounter(COUNTERS->keyed_load_generic_symbol(), 1); |
679 __ ret(0); | 679 __ ret(0); |
680 | 680 |
681 __ bind(&index_string); | 681 __ bind(&index_string); |
682 __ IndexFromHash(rbx, rax); | 682 __ IndexFromHash(rbx, rax); |
683 __ jmp(&index_smi); | 683 __ jmp(&index_smi); |
684 } | 684 } |
685 | 685 |
686 | 686 |
687 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { | 687 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { |
688 // ----------- S t a t e ------------- | 688 // ----------- S t a t e ------------- |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 // ----------------------------------- | 873 // ----------------------------------- |
874 Label number, non_number, non_string, boolean, probe, miss; | 874 Label number, non_number, non_string, boolean, probe, miss; |
875 | 875 |
876 // Probe the stub cache. | 876 // Probe the stub cache. |
877 Code::Flags flags = Code::ComputeFlags(kind, | 877 Code::Flags flags = Code::ComputeFlags(kind, |
878 NOT_IN_LOOP, | 878 NOT_IN_LOOP, |
879 MONOMORPHIC, | 879 MONOMORPHIC, |
880 Code::kNoExtraICState, | 880 Code::kNoExtraICState, |
881 NORMAL, | 881 NORMAL, |
882 argc); | 882 argc); |
883 StubCache::GenerateProbe(masm, flags, rdx, rcx, rbx, rax); | 883 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx, |
| 884 rax); |
884 | 885 |
885 // If the stub cache probing failed, the receiver might be a value. | 886 // If the stub cache probing failed, the receiver might be a value. |
886 // For value objects, we use the map of the prototype objects for | 887 // For value objects, we use the map of the prototype objects for |
887 // the corresponding JSValue for the cache and that is what we need | 888 // the corresponding JSValue for the cache and that is what we need |
888 // to probe. | 889 // to probe. |
889 // | 890 // |
890 // Check for number. | 891 // Check for number. |
891 __ JumpIfSmi(rdx, &number); | 892 __ JumpIfSmi(rdx, &number); |
892 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rbx); | 893 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rbx); |
893 __ j(not_equal, &non_number); | 894 __ j(not_equal, &non_number); |
(...skipping 15 matching lines...) Expand all Loading... |
909 __ CompareRoot(rdx, Heap::kTrueValueRootIndex); | 910 __ CompareRoot(rdx, Heap::kTrueValueRootIndex); |
910 __ j(equal, &boolean); | 911 __ j(equal, &boolean); |
911 __ CompareRoot(rdx, Heap::kFalseValueRootIndex); | 912 __ CompareRoot(rdx, Heap::kFalseValueRootIndex); |
912 __ j(not_equal, &miss); | 913 __ j(not_equal, &miss); |
913 __ bind(&boolean); | 914 __ bind(&boolean); |
914 StubCompiler::GenerateLoadGlobalFunctionPrototype( | 915 StubCompiler::GenerateLoadGlobalFunctionPrototype( |
915 masm, Context::BOOLEAN_FUNCTION_INDEX, rdx); | 916 masm, Context::BOOLEAN_FUNCTION_INDEX, rdx); |
916 | 917 |
917 // Probe the stub cache for the value object. | 918 // Probe the stub cache for the value object. |
918 __ bind(&probe); | 919 __ bind(&probe); |
919 StubCache::GenerateProbe(masm, flags, rdx, rcx, rbx, no_reg); | 920 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx, |
| 921 no_reg); |
920 | 922 |
921 __ bind(&miss); | 923 __ bind(&miss); |
922 } | 924 } |
923 | 925 |
924 | 926 |
925 static void GenerateFunctionTailCall(MacroAssembler* masm, | 927 static void GenerateFunctionTailCall(MacroAssembler* masm, |
926 int argc, | 928 int argc, |
927 Label* miss) { | 929 Label* miss) { |
928 // ----------- S t a t e ------------- | 930 // ----------- S t a t e ------------- |
929 // rcx : function name | 931 // rcx : function name |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
979 // rcx : function name | 981 // rcx : function name |
980 // rsp[0] : return address | 982 // rsp[0] : return address |
981 // rsp[8] : argument argc | 983 // rsp[8] : argument argc |
982 // rsp[16] : argument argc - 1 | 984 // rsp[16] : argument argc - 1 |
983 // ... | 985 // ... |
984 // rsp[argc * 8] : argument 1 | 986 // rsp[argc * 8] : argument 1 |
985 // rsp[(argc + 1) * 8] : argument 0 = receiver | 987 // rsp[(argc + 1) * 8] : argument 0 = receiver |
986 // ----------------------------------- | 988 // ----------------------------------- |
987 | 989 |
988 if (id == IC::kCallIC_Miss) { | 990 if (id == IC::kCallIC_Miss) { |
989 __ IncrementCounter(&Counters::call_miss, 1); | 991 __ IncrementCounter(COUNTERS->call_miss(), 1); |
990 } else { | 992 } else { |
991 __ IncrementCounter(&Counters::keyed_call_miss, 1); | 993 __ IncrementCounter(COUNTERS->keyed_call_miss(), 1); |
992 } | 994 } |
993 | 995 |
994 // Get the receiver of the function from the stack; 1 ~ return address. | 996 // Get the receiver of the function from the stack; 1 ~ return address. |
995 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 997 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
996 | 998 |
997 // Enter an internal frame. | 999 // Enter an internal frame. |
998 __ EnterInternalFrame(); | 1000 __ EnterInternalFrame(); |
999 | 1001 |
1000 // Push the receiver and the name of the function. | 1002 // Push the receiver and the name of the function. |
1001 __ push(rdx); | 1003 __ push(rdx); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1107 | 1109 |
1108 __ bind(&index_smi); | 1110 __ bind(&index_smi); |
1109 // Now the key is known to be a smi. This place is also jumped to from below | 1111 // Now the key is known to be a smi. This place is also jumped to from below |
1110 // where a numeric string is converted to a smi. | 1112 // where a numeric string is converted to a smi. |
1111 | 1113 |
1112 GenerateKeyedLoadReceiverCheck( | 1114 GenerateKeyedLoadReceiverCheck( |
1113 masm, rdx, rax, Map::kHasIndexedInterceptor, &slow_call); | 1115 masm, rdx, rax, Map::kHasIndexedInterceptor, &slow_call); |
1114 | 1116 |
1115 GenerateFastArrayLoad( | 1117 GenerateFastArrayLoad( |
1116 masm, rdx, rcx, rax, rbx, rdi, &check_number_dictionary, &slow_load); | 1118 masm, rdx, rcx, rax, rbx, rdi, &check_number_dictionary, &slow_load); |
1117 __ IncrementCounter(&Counters::keyed_call_generic_smi_fast, 1); | 1119 __ IncrementCounter(COUNTERS->keyed_call_generic_smi_fast(), 1); |
1118 | 1120 |
1119 __ bind(&do_call); | 1121 __ bind(&do_call); |
1120 // receiver in rdx is not used after this point. | 1122 // receiver in rdx is not used after this point. |
1121 // rcx: key | 1123 // rcx: key |
1122 // rdi: function | 1124 // rdi: function |
1123 GenerateFunctionTailCall(masm, argc, &slow_call); | 1125 GenerateFunctionTailCall(masm, argc, &slow_call); |
1124 | 1126 |
1125 __ bind(&check_number_dictionary); | 1127 __ bind(&check_number_dictionary); |
1126 // rax: elements | 1128 // rax: elements |
1127 // rcx: smi key | 1129 // rcx: smi key |
1128 // Check whether the elements is a number dictionary. | 1130 // Check whether the elements is a number dictionary. |
1129 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), | 1131 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), |
1130 Heap::kHashTableMapRootIndex); | 1132 Heap::kHashTableMapRootIndex); |
1131 __ j(not_equal, &slow_load); | 1133 __ j(not_equal, &slow_load); |
1132 __ SmiToInteger32(rbx, rcx); | 1134 __ SmiToInteger32(rbx, rcx); |
1133 // ebx: untagged index | 1135 // ebx: untagged index |
1134 GenerateNumberDictionaryLoad(masm, &slow_load, rax, rcx, rbx, r9, rdi, rdi); | 1136 GenerateNumberDictionaryLoad(masm, &slow_load, rax, rcx, rbx, r9, rdi, rdi); |
1135 __ IncrementCounter(&Counters::keyed_call_generic_smi_dict, 1); | 1137 __ IncrementCounter(COUNTERS->keyed_call_generic_smi_dict(), 1); |
1136 __ jmp(&do_call); | 1138 __ jmp(&do_call); |
1137 | 1139 |
1138 __ bind(&slow_load); | 1140 __ bind(&slow_load); |
1139 // This branch is taken when calling KeyedCallIC_Miss is neither required | 1141 // This branch is taken when calling KeyedCallIC_Miss is neither required |
1140 // nor beneficial. | 1142 // nor beneficial. |
1141 __ IncrementCounter(&Counters::keyed_call_generic_slow_load, 1); | 1143 __ IncrementCounter(COUNTERS->keyed_call_generic_slow_load(), 1); |
1142 __ EnterInternalFrame(); | 1144 __ EnterInternalFrame(); |
1143 __ push(rcx); // save the key | 1145 __ push(rcx); // save the key |
1144 __ push(rdx); // pass the receiver | 1146 __ push(rdx); // pass the receiver |
1145 __ push(rcx); // pass the key | 1147 __ push(rcx); // pass the key |
1146 __ CallRuntime(Runtime::kKeyedGetProperty, 2); | 1148 __ CallRuntime(Runtime::kKeyedGetProperty, 2); |
1147 __ pop(rcx); // restore the key | 1149 __ pop(rcx); // restore the key |
1148 __ LeaveInternalFrame(); | 1150 __ LeaveInternalFrame(); |
1149 __ movq(rdi, rax); | 1151 __ movq(rdi, rax); |
1150 __ jmp(&do_call); | 1152 __ jmp(&do_call); |
1151 | 1153 |
1152 __ bind(&check_string); | 1154 __ bind(&check_string); |
1153 GenerateKeyStringCheck(masm, rcx, rax, rbx, &index_string, &slow_call); | 1155 GenerateKeyStringCheck(masm, rcx, rax, rbx, &index_string, &slow_call); |
1154 | 1156 |
1155 // The key is known to be a symbol. | 1157 // The key is known to be a symbol. |
1156 // If the receiver is a regular JS object with slow properties then do | 1158 // If the receiver is a regular JS object with slow properties then do |
1157 // a quick inline probe of the receiver's dictionary. | 1159 // a quick inline probe of the receiver's dictionary. |
1158 // Otherwise do the monomorphic cache probe. | 1160 // Otherwise do the monomorphic cache probe. |
1159 GenerateKeyedLoadReceiverCheck( | 1161 GenerateKeyedLoadReceiverCheck( |
1160 masm, rdx, rax, Map::kHasNamedInterceptor, &lookup_monomorphic_cache); | 1162 masm, rdx, rax, Map::kHasNamedInterceptor, &lookup_monomorphic_cache); |
1161 | 1163 |
1162 __ movq(rbx, FieldOperand(rdx, JSObject::kPropertiesOffset)); | 1164 __ movq(rbx, FieldOperand(rdx, JSObject::kPropertiesOffset)); |
1163 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), | 1165 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), |
1164 Heap::kHashTableMapRootIndex); | 1166 Heap::kHashTableMapRootIndex); |
1165 __ j(not_equal, &lookup_monomorphic_cache); | 1167 __ j(not_equal, &lookup_monomorphic_cache); |
1166 | 1168 |
1167 GenerateDictionaryLoad(masm, &slow_load, rbx, rcx, rax, rdi, rdi); | 1169 GenerateDictionaryLoad(masm, &slow_load, rbx, rcx, rax, rdi, rdi); |
1168 __ IncrementCounter(&Counters::keyed_call_generic_lookup_dict, 1); | 1170 __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_dict(), 1); |
1169 __ jmp(&do_call); | 1171 __ jmp(&do_call); |
1170 | 1172 |
1171 __ bind(&lookup_monomorphic_cache); | 1173 __ bind(&lookup_monomorphic_cache); |
1172 __ IncrementCounter(&Counters::keyed_call_generic_lookup_cache, 1); | 1174 __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_cache(), 1); |
1173 GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC); | 1175 GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC); |
1174 // Fall through on miss. | 1176 // Fall through on miss. |
1175 | 1177 |
1176 __ bind(&slow_call); | 1178 __ bind(&slow_call); |
1177 // This branch is taken if: | 1179 // This branch is taken if: |
1178 // - the receiver requires boxing or access check, | 1180 // - the receiver requires boxing or access check, |
1179 // - the key is neither smi nor symbol, | 1181 // - the key is neither smi nor symbol, |
1180 // - the value loaded is not a function, | 1182 // - the value loaded is not a function, |
1181 // - there is hope that the runtime will create a monomorphic call stub | 1183 // - there is hope that the runtime will create a monomorphic call stub |
1182 // that will get fetched next time. | 1184 // that will get fetched next time. |
1183 __ IncrementCounter(&Counters::keyed_call_generic_slow, 1); | 1185 __ IncrementCounter(COUNTERS->keyed_call_generic_slow(), 1); |
1184 GenerateMiss(masm, argc); | 1186 GenerateMiss(masm, argc); |
1185 | 1187 |
1186 __ bind(&index_string); | 1188 __ bind(&index_string); |
1187 __ IndexFromHash(rbx, rcx); | 1189 __ IndexFromHash(rbx, rcx); |
1188 // Now jump to the place where smi keys are handled. | 1190 // Now jump to the place where smi keys are handled. |
1189 __ jmp(&index_smi); | 1191 __ jmp(&index_smi); |
1190 } | 1192 } |
1191 | 1193 |
1192 | 1194 |
1193 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { | 1195 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1231 // ----------- S t a t e ------------- | 1233 // ----------- S t a t e ------------- |
1232 // -- rax : receiver | 1234 // -- rax : receiver |
1233 // -- rcx : name | 1235 // -- rcx : name |
1234 // -- rsp[0] : return address | 1236 // -- rsp[0] : return address |
1235 // ----------------------------------- | 1237 // ----------------------------------- |
1236 | 1238 |
1237 // Probe the stub cache. | 1239 // Probe the stub cache. |
1238 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, | 1240 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, |
1239 NOT_IN_LOOP, | 1241 NOT_IN_LOOP, |
1240 MONOMORPHIC); | 1242 MONOMORPHIC); |
1241 StubCache::GenerateProbe(masm, flags, rax, rcx, rbx, rdx); | 1243 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rax, rcx, rbx, |
| 1244 rdx); |
1242 | 1245 |
1243 // Cache miss: Jump to runtime. | 1246 // Cache miss: Jump to runtime. |
1244 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); | 1247 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); |
1245 } | 1248 } |
1246 | 1249 |
1247 | 1250 |
1248 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 1251 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
1249 // ----------- S t a t e ------------- | 1252 // ----------- S t a t e ------------- |
1250 // -- rax : receiver | 1253 // -- rax : receiver |
1251 // -- rcx : name | 1254 // -- rcx : name |
(...skipping 14 matching lines...) Expand all Loading... |
1266 } | 1269 } |
1267 | 1270 |
1268 | 1271 |
1269 void LoadIC::GenerateMiss(MacroAssembler* masm) { | 1272 void LoadIC::GenerateMiss(MacroAssembler* masm) { |
1270 // ----------- S t a t e ------------- | 1273 // ----------- S t a t e ------------- |
1271 // -- rax : receiver | 1274 // -- rax : receiver |
1272 // -- rcx : name | 1275 // -- rcx : name |
1273 // -- rsp[0] : return address | 1276 // -- rsp[0] : return address |
1274 // ----------------------------------- | 1277 // ----------------------------------- |
1275 | 1278 |
1276 __ IncrementCounter(&Counters::load_miss, 1); | 1279 __ IncrementCounter(COUNTERS->load_miss(), 1); |
1277 | 1280 |
1278 __ pop(rbx); | 1281 __ pop(rbx); |
1279 __ push(rax); // receiver | 1282 __ push(rax); // receiver |
1280 __ push(rcx); // name | 1283 __ push(rcx); // name |
1281 __ push(rbx); // return address | 1284 __ push(rbx); // return address |
1282 | 1285 |
1283 // Perform tail call to the entry. | 1286 // Perform tail call to the entry. |
1284 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss)); | 1287 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss)); |
1285 __ TailCallExternalReference(ref, 2, 1); | 1288 __ TailCallExternalReference(ref, 2, 1); |
1286 } | 1289 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1349 *(reinterpret_cast<Object**>(map_address)) = map; | 1352 *(reinterpret_cast<Object**>(map_address)) = map; |
1350 | 1353 |
1351 // Patch the offset in the store instruction. The offset is in the | 1354 // Patch the offset in the store instruction. The offset is in the |
1352 // last 4 bytes of a 7 byte register-to-memory move instruction. | 1355 // last 4 bytes of a 7 byte register-to-memory move instruction. |
1353 Address offset_address = | 1356 Address offset_address = |
1354 map_check_address + StoreIC::kOffsetToStoreInstruction + 3; | 1357 map_check_address + StoreIC::kOffsetToStoreInstruction + 3; |
1355 // The offset should have initial value (kMaxInt - 1), cleared value | 1358 // The offset should have initial value (kMaxInt - 1), cleared value |
1356 // (-1) or we should be clearing the inlined version. | 1359 // (-1) or we should be clearing the inlined version. |
1357 ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt - 1 || | 1360 ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt - 1 || |
1358 *reinterpret_cast<int*>(offset_address) == -1 || | 1361 *reinterpret_cast<int*>(offset_address) == -1 || |
1359 (offset == 0 && map == Heap::null_value())); | 1362 (offset == 0 && map == HEAP->null_value())); |
1360 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag; | 1363 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag; |
1361 | 1364 |
1362 // Patch the offset in the write-barrier code. The offset is the | 1365 // Patch the offset in the write-barrier code. The offset is the |
1363 // last 4 bytes of a 7 byte lea instruction. | 1366 // last 4 bytes of a 7 byte lea instruction. |
1364 offset_address = map_check_address + delta_to_record_write + 3; | 1367 offset_address = map_check_address + delta_to_record_write + 3; |
1365 // The offset should have initial value (kMaxInt), cleared value | 1368 // The offset should have initial value (kMaxInt), cleared value |
1366 // (-1) or we should be clearing the inlined version. | 1369 // (-1) or we should be clearing the inlined version. |
1367 ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt || | 1370 ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt || |
1368 *reinterpret_cast<int*>(offset_address) == -1 || | 1371 *reinterpret_cast<int*>(offset_address) == -1 || |
1369 (offset == 0 && map == Heap::null_value())); | 1372 (offset == 0 && map == HEAP->null_value())); |
1370 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag; | 1373 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag; |
1371 | 1374 |
1372 return true; | 1375 return true; |
1373 } | 1376 } |
1374 | 1377 |
1375 | 1378 |
1376 static bool PatchInlinedMapCheck(Address address, Object* map) { | 1379 static bool PatchInlinedMapCheck(Address address, Object* map) { |
1377 if (V8::UseCrankshaft()) return false; | 1380 if (V8::UseCrankshaft()) return false; |
1378 | 1381 |
1379 // Arguments are address of start of call sequence that called | 1382 // Arguments are address of start of call sequence that called |
(...skipping 30 matching lines...) Expand all Loading... |
1410 } | 1413 } |
1411 | 1414 |
1412 | 1415 |
1413 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 1416 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
1414 // ----------- S t a t e ------------- | 1417 // ----------- S t a t e ------------- |
1415 // -- rax : key | 1418 // -- rax : key |
1416 // -- rdx : receiver | 1419 // -- rdx : receiver |
1417 // -- rsp[0] : return address | 1420 // -- rsp[0] : return address |
1418 // ----------------------------------- | 1421 // ----------------------------------- |
1419 | 1422 |
1420 __ IncrementCounter(&Counters::keyed_load_miss, 1); | 1423 __ IncrementCounter(COUNTERS->keyed_load_miss(), 1); |
1421 | 1424 |
1422 __ pop(rbx); | 1425 __ pop(rbx); |
1423 __ push(rdx); // receiver | 1426 __ push(rdx); // receiver |
1424 __ push(rax); // name | 1427 __ push(rax); // name |
1425 __ push(rbx); // return address | 1428 __ push(rbx); // return address |
1426 | 1429 |
1427 // Perform tail call to the entry. | 1430 // Perform tail call to the entry. |
1428 ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss)); | 1431 ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss)); |
1429 __ TailCallExternalReference(ref, 2, 1); | 1432 __ TailCallExternalReference(ref, 2, 1); |
1430 } | 1433 } |
(...skipping 23 matching lines...) Expand all Loading... |
1454 // -- rcx : name | 1457 // -- rcx : name |
1455 // -- rdx : receiver | 1458 // -- rdx : receiver |
1456 // -- rsp[0] : return address | 1459 // -- rsp[0] : return address |
1457 // ----------------------------------- | 1460 // ----------------------------------- |
1458 | 1461 |
1459 // Get the receiver from the stack and probe the stub cache. | 1462 // Get the receiver from the stack and probe the stub cache. |
1460 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, | 1463 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, |
1461 NOT_IN_LOOP, | 1464 NOT_IN_LOOP, |
1462 MONOMORPHIC, | 1465 MONOMORPHIC, |
1463 strict_mode); | 1466 strict_mode); |
1464 StubCache::GenerateProbe(masm, flags, rdx, rcx, rbx, no_reg); | 1467 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx, |
| 1468 no_reg); |
1465 | 1469 |
1466 // Cache miss: Jump to runtime. | 1470 // Cache miss: Jump to runtime. |
1467 GenerateMiss(masm); | 1471 GenerateMiss(masm); |
1468 } | 1472 } |
1469 | 1473 |
1470 | 1474 |
1471 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 1475 void StoreIC::GenerateMiss(MacroAssembler* masm) { |
1472 // ----------- S t a t e ------------- | 1476 // ----------- S t a t e ------------- |
1473 // -- rax : value | 1477 // -- rax : value |
1474 // -- rcx : name | 1478 // -- rcx : name |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1551 // -- rcx : name | 1555 // -- rcx : name |
1552 // -- rdx : receiver | 1556 // -- rdx : receiver |
1553 // -- rsp[0] : return address | 1557 // -- rsp[0] : return address |
1554 // ----------------------------------- | 1558 // ----------------------------------- |
1555 | 1559 |
1556 Label miss; | 1560 Label miss; |
1557 | 1561 |
1558 GenerateStringDictionaryReceiverCheck(masm, rdx, rbx, rdi, &miss); | 1562 GenerateStringDictionaryReceiverCheck(masm, rdx, rbx, rdi, &miss); |
1559 | 1563 |
1560 GenerateDictionaryStore(masm, &miss, rbx, rcx, rax, r8, r9); | 1564 GenerateDictionaryStore(masm, &miss, rbx, rcx, rax, r8, r9); |
1561 __ IncrementCounter(&Counters::store_normal_hit, 1); | 1565 __ IncrementCounter(COUNTERS->store_normal_hit(), 1); |
1562 __ ret(0); | 1566 __ ret(0); |
1563 | 1567 |
1564 __ bind(&miss); | 1568 __ bind(&miss); |
1565 __ IncrementCounter(&Counters::store_normal_miss, 1); | 1569 __ IncrementCounter(COUNTERS->store_normal_miss(), 1); |
1566 GenerateMiss(masm); | 1570 GenerateMiss(masm); |
1567 } | 1571 } |
1568 | 1572 |
1569 | 1573 |
1570 void StoreIC::GenerateGlobalProxy(MacroAssembler* masm, | 1574 void StoreIC::GenerateGlobalProxy(MacroAssembler* masm, |
1571 StrictModeFlag strict_mode) { | 1575 StrictModeFlag strict_mode) { |
1572 // ----------- S t a t e ------------- | 1576 // ----------- S t a t e ------------- |
1573 // -- rax : value | 1577 // -- rax : value |
1574 // -- rcx : name | 1578 // -- rcx : name |
1575 // -- rdx : receiver | 1579 // -- rdx : receiver |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1725 Condition cc = *jmp_address == Assembler::kJncShortOpcode | 1729 Condition cc = *jmp_address == Assembler::kJncShortOpcode |
1726 ? not_zero | 1730 ? not_zero |
1727 : zero; | 1731 : zero; |
1728 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1732 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
1729 } | 1733 } |
1730 | 1734 |
1731 | 1735 |
1732 } } // namespace v8::internal | 1736 } } // namespace v8::internal |
1733 | 1737 |
1734 #endif // V8_TARGET_ARCH_X64 | 1738 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |