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