| 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 |