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-inl.h" | 10 #include "src/ic-inl.h" |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 } | 325 } |
326 | 326 |
327 | 327 |
328 | 328 |
329 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 329 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { |
330 // ----------- S t a t e ------------- | 330 // ----------- S t a t e ------------- |
331 // -- rax : key | 331 // -- rax : key |
332 // -- rdx : receiver | 332 // -- rdx : receiver |
333 // -- rsp[0] : return address | 333 // -- rsp[0] : return address |
334 // ----------------------------------- | 334 // ----------------------------------- |
| 335 ASSERT(rdx.is(ReceiverRegister())); |
| 336 ASSERT(rax.is(NameRegister())); |
335 Label slow, check_name, index_smi, index_name, property_array_property; | 337 Label slow, check_name, index_smi, index_name, property_array_property; |
336 Label probe_dictionary, check_number_dictionary; | 338 Label probe_dictionary, check_number_dictionary; |
337 | 339 |
338 // Check that the key is a smi. | 340 // Check that the key is a smi. |
339 __ JumpIfNotSmi(rax, &check_name); | 341 __ JumpIfNotSmi(rax, &check_name); |
340 __ bind(&index_smi); | 342 __ bind(&index_smi); |
341 // Now the key is known to be a smi. This place is also jumped to from below | 343 // Now the key is known to be a smi. This place is also jumped to from below |
342 // where a numeric string is converted to a smi. | 344 // where a numeric string is converted to a smi. |
343 | 345 |
344 GenerateKeyedLoadReceiverCheck( | 346 GenerateKeyedLoadReceiverCheck( |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 __ jmp(&index_smi); | 490 __ jmp(&index_smi); |
489 } | 491 } |
490 | 492 |
491 | 493 |
492 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { | 494 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { |
493 // ----------- S t a t e ------------- | 495 // ----------- S t a t e ------------- |
494 // -- rax : key | 496 // -- rax : key |
495 // -- rdx : receiver | 497 // -- rdx : receiver |
496 // -- rsp[0] : return address | 498 // -- rsp[0] : return address |
497 // ----------------------------------- | 499 // ----------------------------------- |
| 500 ASSERT(rdx.is(ReceiverRegister())); |
| 501 ASSERT(rax.is(NameRegister())); |
498 Label miss; | 502 Label miss; |
499 | 503 |
500 Register receiver = rdx; | 504 Register receiver = rdx; |
501 Register index = rax; | 505 Register index = rax; |
502 Register scratch = rcx; | 506 Register scratch = rcx; |
503 Register result = rax; | 507 Register result = rax; |
504 | 508 |
505 StringCharAtGenerator char_at_generator(receiver, | 509 StringCharAtGenerator char_at_generator(receiver, |
506 index, | 510 index, |
507 scratch, | 511 scratch, |
(...skipping 12 matching lines...) Expand all Loading... |
520 GenerateMiss(masm); | 524 GenerateMiss(masm); |
521 } | 525 } |
522 | 526 |
523 | 527 |
524 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 528 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { |
525 // ----------- S t a t e ------------- | 529 // ----------- S t a t e ------------- |
526 // -- rax : key | 530 // -- rax : key |
527 // -- rdx : receiver | 531 // -- rdx : receiver |
528 // -- rsp[0] : return address | 532 // -- rsp[0] : return address |
529 // ----------------------------------- | 533 // ----------------------------------- |
| 534 ASSERT(rdx.is(ReceiverRegister())); |
| 535 ASSERT(rax.is(NameRegister())); |
530 Label slow; | 536 Label slow; |
531 | 537 |
532 // Check that the receiver isn't a smi. | 538 // Check that the receiver isn't a smi. |
533 __ JumpIfSmi(rdx, &slow); | 539 __ JumpIfSmi(rdx, &slow); |
534 | 540 |
535 // Check that the key is an array index, that is Uint32. | 541 // Check that the key is an array index, that is Uint32. |
536 STATIC_ASSERT(kSmiValueSize <= 32); | 542 STATIC_ASSERT(kSmiValueSize <= 32); |
537 __ JumpUnlessNonNegativeSmi(rax, &slow); | 543 __ JumpUnlessNonNegativeSmi(rax, &slow); |
538 | 544 |
539 // Get the map of the receiver. | 545 // Get the map of the receiver. |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 FixedArray::kHeaderSize); | 891 FixedArray::kHeaderSize); |
886 } | 892 } |
887 | 893 |
888 | 894 |
889 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { | 895 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { |
890 // ----------- S t a t e ------------- | 896 // ----------- S t a t e ------------- |
891 // -- rax : key | 897 // -- rax : key |
892 // -- rdx : receiver | 898 // -- rdx : receiver |
893 // -- rsp[0] : return address | 899 // -- rsp[0] : return address |
894 // ----------------------------------- | 900 // ----------------------------------- |
| 901 ASSERT(rdx.is(ReceiverRegister())); |
| 902 ASSERT(rax.is(NameRegister())); |
895 Label slow, notin; | 903 Label slow, notin; |
896 Operand mapped_location = | 904 Operand mapped_location = |
897 GenerateMappedArgumentsLookup( | 905 GenerateMappedArgumentsLookup( |
898 masm, rdx, rax, rbx, rcx, rdi, ¬in, &slow); | 906 masm, rdx, rax, rbx, rcx, rdi, ¬in, &slow); |
899 __ movp(rax, mapped_location); | 907 __ movp(rax, mapped_location); |
900 __ Ret(); | 908 __ Ret(); |
901 __ bind(¬in); | 909 __ bind(¬in); |
902 // The unmapped lookup expects that the parameter map is in rbx. | 910 // The unmapped lookup expects that the parameter map is in rbx. |
903 Operand unmapped_location = | 911 Operand unmapped_location = |
904 GenerateUnmappedArgumentsLookup(masm, rax, rbx, rcx, &slow); | 912 GenerateUnmappedArgumentsLookup(masm, rax, rbx, rcx, &slow); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 GenerateMiss(masm); | 957 GenerateMiss(masm); |
950 } | 958 } |
951 | 959 |
952 | 960 |
953 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 961 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
954 // ----------- S t a t e ------------- | 962 // ----------- S t a t e ------------- |
955 // -- rax : receiver | 963 // -- rax : receiver |
956 // -- rcx : name | 964 // -- rcx : name |
957 // -- rsp[0] : return address | 965 // -- rsp[0] : return address |
958 // ----------------------------------- | 966 // ----------------------------------- |
| 967 ASSERT(rax.is(ReceiverRegister())); |
| 968 ASSERT(rcx.is(NameRegister())); |
959 | 969 |
960 // Probe the stub cache. | 970 // Probe the stub cache. |
961 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); | 971 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); |
962 masm->isolate()->stub_cache()->GenerateProbe( | 972 masm->isolate()->stub_cache()->GenerateProbe( |
963 masm, flags, rax, rcx, rbx, rdx); | 973 masm, flags, rax, rcx, rbx, rdx); |
964 | 974 |
965 GenerateMiss(masm); | 975 GenerateMiss(masm); |
966 } | 976 } |
967 | 977 |
968 | 978 |
969 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 979 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
970 // ----------- S t a t e ------------- | 980 // ----------- S t a t e ------------- |
971 // -- rax : receiver | 981 // -- rax : receiver |
972 // -- rcx : name | 982 // -- rcx : name |
973 // -- rsp[0] : return address | 983 // -- rsp[0] : return address |
974 // ----------------------------------- | 984 // ----------------------------------- |
| 985 ASSERT(rax.is(ReceiverRegister())); |
| 986 ASSERT(rcx.is(NameRegister())); |
975 Label miss, slow; | 987 Label miss, slow; |
976 | 988 |
977 GenerateNameDictionaryReceiverCheck(masm, rax, rdx, rbx, &miss); | 989 GenerateNameDictionaryReceiverCheck(masm, rax, rdx, rbx, &miss); |
978 | 990 |
979 // rdx: elements | 991 // rdx: elements |
980 // Search the dictionary placing the result in rax. | 992 // Search the dictionary placing the result in rax. |
981 GenerateDictionaryLoad(masm, &slow, rdx, rcx, rbx, rdi, rax); | 993 GenerateDictionaryLoad(masm, &slow, rdx, rcx, rbx, rdi, rax); |
982 __ ret(0); | 994 __ ret(0); |
983 | 995 |
984 // Dictionary load failed, go slow (but don't miss). | 996 // Dictionary load failed, go slow (but don't miss). |
985 __ bind(&slow); | 997 __ bind(&slow); |
986 GenerateRuntimeGetProperty(masm); | 998 GenerateRuntimeGetProperty(masm); |
987 | 999 |
988 // Cache miss: Jump to runtime. | 1000 // Cache miss: Jump to runtime. |
989 __ bind(&miss); | 1001 __ bind(&miss); |
990 GenerateMiss(masm); | 1002 GenerateMiss(masm); |
991 } | 1003 } |
992 | 1004 |
993 | 1005 |
| 1006 // A register that isn't one of the parameters to the load ic. |
| 1007 static const Register LoadIC_TempRegister() { return rbx; } |
| 1008 |
| 1009 |
994 void LoadIC::GenerateMiss(MacroAssembler* masm) { | 1010 void LoadIC::GenerateMiss(MacroAssembler* masm) { |
995 // ----------- S t a t e ------------- | 1011 // ----------- S t a t e ------------- |
996 // -- rax : receiver | |
997 // -- rcx : name | |
998 // -- rsp[0] : return address | 1012 // -- rsp[0] : return address |
999 // ----------------------------------- | 1013 // ----------------------------------- |
1000 | 1014 |
1001 Counters* counters = masm->isolate()->counters(); | 1015 Counters* counters = masm->isolate()->counters(); |
1002 __ IncrementCounter(counters->load_miss(), 1); | 1016 __ IncrementCounter(counters->load_miss(), 1); |
1003 | 1017 |
1004 __ PopReturnAddressTo(rbx); | 1018 __ PopReturnAddressTo(LoadIC_TempRegister()); |
1005 __ Push(rax); // receiver | 1019 __ Push(ReceiverRegister()); // receiver |
1006 __ Push(rcx); // name | 1020 __ Push(NameRegister()); // name |
1007 __ PushReturnAddressFrom(rbx); | 1021 __ PushReturnAddressFrom(LoadIC_TempRegister()); |
1008 | 1022 |
1009 // Perform tail call to the entry. | 1023 // Perform tail call to the entry. |
1010 ExternalReference ref = | 1024 ExternalReference ref = |
1011 ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate()); | 1025 ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate()); |
1012 __ TailCallExternalReference(ref, 2, 1); | 1026 __ TailCallExternalReference(ref, 2, 1); |
1013 } | 1027 } |
1014 | 1028 |
1015 | 1029 |
1016 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 1030 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
1017 // ----------- S t a t e ------------- | 1031 // ----------- S t a t e ------------- |
1018 // -- rax : receiver | |
1019 // -- rcx : name | |
1020 // -- rsp[0] : return address | 1032 // -- rsp[0] : return address |
1021 // ----------------------------------- | 1033 // ----------------------------------- |
1022 | 1034 |
1023 __ PopReturnAddressTo(rbx); | 1035 __ PopReturnAddressTo(LoadIC_TempRegister()); |
1024 __ Push(rax); // receiver | 1036 __ Push(ReceiverRegister()); // receiver |
1025 __ Push(rcx); // name | 1037 __ Push(NameRegister()); // name |
1026 __ PushReturnAddressFrom(rbx); | 1038 __ PushReturnAddressFrom(LoadIC_TempRegister()); |
1027 | 1039 |
1028 // Perform tail call to the entry. | 1040 // Perform tail call to the entry. |
1029 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); | 1041 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); |
1030 } | 1042 } |
1031 | 1043 |
1032 | 1044 |
| 1045 static const Register KeyedLoadIC_TempRegister() { |
| 1046 return rbx; |
| 1047 } |
| 1048 |
| 1049 |
1033 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 1050 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
1034 // ----------- S t a t e ------------- | 1051 // ----------- S t a t e ------------- |
1035 // -- rax : key | |
1036 // -- rdx : receiver | |
1037 // -- rsp[0] : return address | 1052 // -- rsp[0] : return address |
1038 // ----------------------------------- | 1053 // ----------------------------------- |
1039 | 1054 |
1040 Counters* counters = masm->isolate()->counters(); | 1055 Counters* counters = masm->isolate()->counters(); |
1041 __ IncrementCounter(counters->keyed_load_miss(), 1); | 1056 __ IncrementCounter(counters->keyed_load_miss(), 1); |
1042 | 1057 |
1043 __ PopReturnAddressTo(rbx); | 1058 __ PopReturnAddressTo(KeyedLoadIC_TempRegister()); |
1044 __ Push(rdx); // receiver | 1059 __ Push(ReceiverRegister()); // receiver |
1045 __ Push(rax); // name | 1060 __ Push(NameRegister()); // name |
1046 __ PushReturnAddressFrom(rbx); | 1061 __ PushReturnAddressFrom(KeyedLoadIC_TempRegister()); |
1047 | 1062 |
1048 // Perform tail call to the entry. | 1063 // Perform tail call to the entry. |
1049 ExternalReference ref = | 1064 ExternalReference ref = |
1050 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); | 1065 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); |
1051 __ TailCallExternalReference(ref, 2, 1); | 1066 __ TailCallExternalReference(ref, 2, 1); |
1052 } | 1067 } |
1053 | 1068 |
1054 | 1069 |
1055 // IC register specifications | 1070 // IC register specifications |
1056 const Register LoadIC::ReceiverRegister() { return rax; } | 1071 const Register LoadIC::ReceiverRegister() { return rax; } |
1057 const Register LoadIC::NameRegister() { return rcx; } | 1072 const Register LoadIC::NameRegister() { return rcx; } |
1058 const Register KeyedLoadIC::ReceiverRegister() { return rdx; } | 1073 const Register KeyedLoadIC::ReceiverRegister() { return rdx; } |
1059 const Register KeyedLoadIC::NameRegister() { return rax; } | 1074 const Register KeyedLoadIC::NameRegister() { return rax; } |
1060 | 1075 |
1061 | 1076 |
1062 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 1077 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
1063 // ----------- S t a t e ------------- | 1078 // ----------- S t a t e ------------- |
1064 // -- rax : key | |
1065 // -- rdx : receiver | |
1066 // -- rsp[0] : return address | 1079 // -- rsp[0] : return address |
1067 // ----------------------------------- | 1080 // ----------------------------------- |
1068 | 1081 |
1069 __ PopReturnAddressTo(rbx); | 1082 __ PopReturnAddressTo(KeyedLoadIC_TempRegister()); |
1070 __ Push(rdx); // receiver | 1083 __ Push(ReceiverRegister()); // receiver |
1071 __ Push(rax); // name | 1084 __ Push(NameRegister()); // name |
1072 __ PushReturnAddressFrom(rbx); | 1085 __ PushReturnAddressFrom(KeyedLoadIC_TempRegister()); |
1073 | 1086 |
1074 // Perform tail call to the entry. | 1087 // Perform tail call to the entry. |
1075 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 1088 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
1076 } | 1089 } |
1077 | 1090 |
1078 | 1091 |
1079 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { | 1092 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { |
1080 // ----------- S t a t e ------------- | 1093 // ----------- S t a t e ------------- |
1081 // -- rax : value | 1094 // -- rax : value |
1082 // -- rcx : name | 1095 // -- rcx : name |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1309 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) | 1322 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) |
1310 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 1323 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
1311 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 1324 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
1312 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1325 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
1313 } | 1326 } |
1314 | 1327 |
1315 | 1328 |
1316 } } // namespace v8::internal | 1329 } } // namespace v8::internal |
1317 | 1330 |
1318 #endif // V8_TARGET_ARCH_X64 | 1331 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |