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 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 __ IncrementCounter(counters->keyed_load_generic_symbol(), 1); | 485 __ IncrementCounter(counters->keyed_load_generic_symbol(), 1); |
484 __ ret(0); | 486 __ ret(0); |
485 | 487 |
486 __ bind(&index_name); | 488 __ bind(&index_name); |
487 __ IndexFromHash(rbx, rax); | 489 __ IndexFromHash(rbx, rax); |
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 // Return address is on the stack. |
494 // -- rax : key | |
495 // -- rdx : receiver | |
496 // -- rsp[0] : return address | |
497 // ----------------------------------- | |
498 Label miss; | 496 Label miss; |
499 | 497 |
500 Register receiver = rdx; | 498 Register receiver = ReceiverRegister(); |
501 Register index = rax; | 499 Register index = NameRegister(); |
502 Register scratch = rcx; | 500 Register scratch = rcx; |
503 Register result = rax; | 501 Register result = rax; |
| 502 ASSERT(!scratch.is(receiver) && !scratch.is(index)); |
504 | 503 |
505 StringCharAtGenerator char_at_generator(receiver, | 504 StringCharAtGenerator char_at_generator(receiver, |
506 index, | 505 index, |
507 scratch, | 506 scratch, |
508 result, | 507 result, |
509 &miss, // When not a string. | 508 &miss, // When not a string. |
510 &miss, // When not a number. | 509 &miss, // When not a number. |
511 &miss, // When index out of range. | 510 &miss, // When index out of range. |
512 STRING_INDEX_IS_ARRAY_INDEX); | 511 STRING_INDEX_IS_ARRAY_INDEX); |
513 char_at_generator.GenerateFast(masm); | 512 char_at_generator.GenerateFast(masm); |
514 __ ret(0); | 513 __ ret(0); |
515 | 514 |
516 StubRuntimeCallHelper call_helper; | 515 StubRuntimeCallHelper call_helper; |
517 char_at_generator.GenerateSlow(masm, call_helper); | 516 char_at_generator.GenerateSlow(masm, call_helper); |
518 | 517 |
519 __ bind(&miss); | 518 __ bind(&miss); |
520 GenerateMiss(masm); | 519 GenerateMiss(masm); |
521 } | 520 } |
522 | 521 |
523 | 522 |
524 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 523 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { |
525 // ----------- S t a t e ------------- | 524 // Return address is on the stack. |
526 // -- rax : key | |
527 // -- rdx : receiver | |
528 // -- rsp[0] : return address | |
529 // ----------------------------------- | |
530 Label slow; | 525 Label slow; |
531 | 526 |
| 527 Register receiver = ReceiverRegister(); |
| 528 Register key = NameRegister(); |
| 529 Register scratch = rcx; |
| 530 ASSERT(!scratch.is(receiver) && !scratch.is(key)); |
| 531 |
532 // Check that the receiver isn't a smi. | 532 // Check that the receiver isn't a smi. |
533 __ JumpIfSmi(rdx, &slow); | 533 __ JumpIfSmi(receiver, &slow); |
534 | 534 |
535 // Check that the key is an array index, that is Uint32. | 535 // Check that the key is an array index, that is Uint32. |
536 STATIC_ASSERT(kSmiValueSize <= 32); | 536 STATIC_ASSERT(kSmiValueSize <= 32); |
537 __ JumpUnlessNonNegativeSmi(rax, &slow); | 537 __ JumpUnlessNonNegativeSmi(key, &slow); |
538 | 538 |
539 // Get the map of the receiver. | 539 // Get the map of the receiver. |
540 __ movp(rcx, FieldOperand(rdx, HeapObject::kMapOffset)); | 540 __ movp(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); |
541 | 541 |
542 // Check that it has indexed interceptor and access checks | 542 // Check that it has indexed interceptor and access checks |
543 // are not enabled for this object. | 543 // are not enabled for this object. |
544 __ movb(rcx, FieldOperand(rcx, Map::kBitFieldOffset)); | 544 __ movb(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); |
545 __ andb(rcx, Immediate(kSlowCaseBitFieldMask)); | 545 __ andb(scratch, Immediate(kSlowCaseBitFieldMask)); |
546 __ cmpb(rcx, Immediate(1 << Map::kHasIndexedInterceptor)); | 546 __ cmpb(scratch, Immediate(1 << Map::kHasIndexedInterceptor)); |
547 __ j(not_zero, &slow); | 547 __ j(not_zero, &slow); |
548 | 548 |
549 // Everything is fine, call runtime. | 549 // Everything is fine, call runtime. |
550 __ PopReturnAddressTo(rcx); | 550 __ PopReturnAddressTo(scratch); |
551 __ Push(rdx); // receiver | 551 __ Push(receiver); // receiver |
552 __ Push(rax); // key | 552 __ Push(key); // key |
553 __ PushReturnAddressFrom(rcx); | 553 __ PushReturnAddressFrom(scratch); |
554 | 554 |
555 // Perform tail call to the entry. | 555 // Perform tail call to the entry. |
556 __ TailCallExternalReference( | 556 __ TailCallExternalReference( |
557 ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor), | 557 ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor), |
558 masm->isolate()), | 558 masm->isolate()), |
559 2, | 559 2, |
560 1); | 560 1); |
561 | 561 |
562 __ bind(&slow); | 562 __ bind(&slow); |
563 GenerateMiss(masm); | 563 GenerateMiss(masm); |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 FixedArray::kHeaderSize); | 885 FixedArray::kHeaderSize); |
886 } | 886 } |
887 | 887 |
888 | 888 |
889 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { | 889 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { |
890 // ----------- S t a t e ------------- | 890 // ----------- S t a t e ------------- |
891 // -- rax : key | 891 // -- rax : key |
892 // -- rdx : receiver | 892 // -- rdx : receiver |
893 // -- rsp[0] : return address | 893 // -- rsp[0] : return address |
894 // ----------------------------------- | 894 // ----------------------------------- |
| 895 ASSERT(rdx.is(ReceiverRegister())); |
| 896 ASSERT(rax.is(NameRegister())); |
895 Label slow, notin; | 897 Label slow, notin; |
896 Operand mapped_location = | 898 Operand mapped_location = |
897 GenerateMappedArgumentsLookup( | 899 GenerateMappedArgumentsLookup( |
898 masm, rdx, rax, rbx, rcx, rdi, ¬in, &slow); | 900 masm, rdx, rax, rbx, rcx, rdi, ¬in, &slow); |
899 __ movp(rax, mapped_location); | 901 __ movp(rax, mapped_location); |
900 __ Ret(); | 902 __ Ret(); |
901 __ bind(¬in); | 903 __ bind(¬in); |
902 // The unmapped lookup expects that the parameter map is in rbx. | 904 // The unmapped lookup expects that the parameter map is in rbx. |
903 Operand unmapped_location = | 905 Operand unmapped_location = |
904 GenerateUnmappedArgumentsLookup(masm, rax, rbx, rcx, &slow); | 906 GenerateUnmappedArgumentsLookup(masm, rax, rbx, rcx, &slow); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 GenerateMiss(masm); | 951 GenerateMiss(masm); |
950 } | 952 } |
951 | 953 |
952 | 954 |
953 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 955 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
954 // ----------- S t a t e ------------- | 956 // ----------- S t a t e ------------- |
955 // -- rax : receiver | 957 // -- rax : receiver |
956 // -- rcx : name | 958 // -- rcx : name |
957 // -- rsp[0] : return address | 959 // -- rsp[0] : return address |
958 // ----------------------------------- | 960 // ----------------------------------- |
| 961 ASSERT(rax.is(ReceiverRegister())); |
| 962 ASSERT(rcx.is(NameRegister())); |
959 | 963 |
960 // Probe the stub cache. | 964 // Probe the stub cache. |
961 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); | 965 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); |
962 masm->isolate()->stub_cache()->GenerateProbe( | 966 masm->isolate()->stub_cache()->GenerateProbe( |
963 masm, flags, rax, rcx, rbx, rdx); | 967 masm, flags, rax, rcx, rbx, rdx); |
964 | 968 |
965 GenerateMiss(masm); | 969 GenerateMiss(masm); |
966 } | 970 } |
967 | 971 |
968 | 972 |
969 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 973 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
970 // ----------- S t a t e ------------- | 974 // ----------- S t a t e ------------- |
971 // -- rax : receiver | 975 // -- rax : receiver |
972 // -- rcx : name | 976 // -- rcx : name |
973 // -- rsp[0] : return address | 977 // -- rsp[0] : return address |
974 // ----------------------------------- | 978 // ----------------------------------- |
| 979 ASSERT(rax.is(ReceiverRegister())); |
| 980 ASSERT(rcx.is(NameRegister())); |
975 Label miss, slow; | 981 Label miss, slow; |
976 | 982 |
977 GenerateNameDictionaryReceiverCheck(masm, rax, rdx, rbx, &miss); | 983 GenerateNameDictionaryReceiverCheck(masm, rax, rdx, rbx, &miss); |
978 | 984 |
979 // rdx: elements | 985 // rdx: elements |
980 // Search the dictionary placing the result in rax. | 986 // Search the dictionary placing the result in rax. |
981 GenerateDictionaryLoad(masm, &slow, rdx, rcx, rbx, rdi, rax); | 987 GenerateDictionaryLoad(masm, &slow, rdx, rcx, rbx, rdi, rax); |
982 __ ret(0); | 988 __ ret(0); |
983 | 989 |
984 // Dictionary load failed, go slow (but don't miss). | 990 // Dictionary load failed, go slow (but don't miss). |
985 __ bind(&slow); | 991 __ bind(&slow); |
986 GenerateRuntimeGetProperty(masm); | 992 GenerateRuntimeGetProperty(masm); |
987 | 993 |
988 // Cache miss: Jump to runtime. | 994 // Cache miss: Jump to runtime. |
989 __ bind(&miss); | 995 __ bind(&miss); |
990 GenerateMiss(masm); | 996 GenerateMiss(masm); |
991 } | 997 } |
992 | 998 |
993 | 999 |
| 1000 // A register that isn't one of the parameters to the load ic. |
| 1001 static const Register LoadIC_TempRegister() { return rbx; } |
| 1002 |
| 1003 |
| 1004 static const Register KeyedLoadIC_TempRegister() { |
| 1005 return rbx; |
| 1006 } |
| 1007 |
| 1008 |
994 void LoadIC::GenerateMiss(MacroAssembler* masm) { | 1009 void LoadIC::GenerateMiss(MacroAssembler* masm) { |
995 // ----------- S t a t e ------------- | 1010 // The return address is on the stack. |
996 // -- rax : receiver | |
997 // -- rcx : name | |
998 // -- rsp[0] : return address | |
999 // ----------------------------------- | |
1000 | 1011 |
1001 Counters* counters = masm->isolate()->counters(); | 1012 Counters* counters = masm->isolate()->counters(); |
1002 __ IncrementCounter(counters->load_miss(), 1); | 1013 __ IncrementCounter(counters->load_miss(), 1); |
1003 | 1014 |
1004 __ PopReturnAddressTo(rbx); | 1015 __ PopReturnAddressTo(LoadIC_TempRegister()); |
1005 __ Push(rax); // receiver | 1016 __ Push(ReceiverRegister()); // receiver |
1006 __ Push(rcx); // name | 1017 __ Push(NameRegister()); // name |
1007 __ PushReturnAddressFrom(rbx); | 1018 __ PushReturnAddressFrom(LoadIC_TempRegister()); |
1008 | 1019 |
1009 // Perform tail call to the entry. | 1020 // Perform tail call to the entry. |
1010 ExternalReference ref = | 1021 ExternalReference ref = |
1011 ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate()); | 1022 ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate()); |
1012 __ TailCallExternalReference(ref, 2, 1); | 1023 __ TailCallExternalReference(ref, 2, 1); |
1013 } | 1024 } |
1014 | 1025 |
1015 | 1026 |
1016 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 1027 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
1017 // ----------- S t a t e ------------- | 1028 // The return address is on the stack. |
1018 // -- rax : receiver | |
1019 // -- rcx : name | |
1020 // -- rsp[0] : return address | |
1021 // ----------------------------------- | |
1022 | 1029 |
1023 __ PopReturnAddressTo(rbx); | 1030 __ PopReturnAddressTo(LoadIC_TempRegister()); |
1024 __ Push(rax); // receiver | 1031 __ Push(ReceiverRegister()); // receiver |
1025 __ Push(rcx); // name | 1032 __ Push(NameRegister()); // name |
1026 __ PushReturnAddressFrom(rbx); | 1033 __ PushReturnAddressFrom(LoadIC_TempRegister()); |
1027 | 1034 |
1028 // Perform tail call to the entry. | 1035 // Perform tail call to the entry. |
1029 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); | 1036 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); |
1030 } | 1037 } |
1031 | 1038 |
1032 | 1039 |
1033 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 1040 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
1034 // ----------- S t a t e ------------- | 1041 // The return address is on the stack. |
1035 // -- rax : key | |
1036 // -- rdx : receiver | |
1037 // -- rsp[0] : return address | |
1038 // ----------------------------------- | |
1039 | |
1040 Counters* counters = masm->isolate()->counters(); | 1042 Counters* counters = masm->isolate()->counters(); |
1041 __ IncrementCounter(counters->keyed_load_miss(), 1); | 1043 __ IncrementCounter(counters->keyed_load_miss(), 1); |
1042 | 1044 |
1043 __ PopReturnAddressTo(rbx); | 1045 __ PopReturnAddressTo(KeyedLoadIC_TempRegister()); |
1044 __ Push(rdx); // receiver | 1046 __ Push(ReceiverRegister()); // receiver |
1045 __ Push(rax); // name | 1047 __ Push(NameRegister()); // name |
1046 __ PushReturnAddressFrom(rbx); | 1048 __ PushReturnAddressFrom(KeyedLoadIC_TempRegister()); |
1047 | 1049 |
1048 // Perform tail call to the entry. | 1050 // Perform tail call to the entry. |
1049 ExternalReference ref = | 1051 ExternalReference ref = |
1050 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); | 1052 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); |
1051 __ TailCallExternalReference(ref, 2, 1); | 1053 __ TailCallExternalReference(ref, 2, 1); |
1052 } | 1054 } |
1053 | 1055 |
1054 | 1056 |
1055 // IC register specifications | 1057 // IC register specifications |
1056 const Register LoadIC::ReceiverRegister() { return rax; } | 1058 const Register LoadIC::ReceiverRegister() { return rax; } |
1057 const Register LoadIC::NameRegister() { return rcx; } | 1059 const Register LoadIC::NameRegister() { return rcx; } |
1058 const Register KeyedLoadIC::ReceiverRegister() { return rdx; } | 1060 const Register KeyedLoadIC::ReceiverRegister() { return rdx; } |
1059 const Register KeyedLoadIC::NameRegister() { return rax; } | 1061 const Register KeyedLoadIC::NameRegister() { return rax; } |
1060 | 1062 |
1061 | 1063 |
1062 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 1064 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
1063 // ----------- S t a t e ------------- | 1065 // The return address is on the stack. |
1064 // -- rax : key | |
1065 // -- rdx : receiver | |
1066 // -- rsp[0] : return address | |
1067 // ----------------------------------- | |
1068 | 1066 |
1069 __ PopReturnAddressTo(rbx); | 1067 __ PopReturnAddressTo(KeyedLoadIC_TempRegister()); |
1070 __ Push(rdx); // receiver | 1068 __ Push(ReceiverRegister()); // receiver |
1071 __ Push(rax); // name | 1069 __ Push(NameRegister()); // name |
1072 __ PushReturnAddressFrom(rbx); | 1070 __ PushReturnAddressFrom(KeyedLoadIC_TempRegister()); |
1073 | 1071 |
1074 // Perform tail call to the entry. | 1072 // Perform tail call to the entry. |
1075 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 1073 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
1076 } | 1074 } |
1077 | 1075 |
1078 | 1076 |
1079 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { | 1077 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { |
1080 // ----------- S t a t e ------------- | 1078 // ----------- S t a t e ------------- |
1081 // -- rax : value | 1079 // -- rax : value |
1082 // -- rcx : name | 1080 // -- rcx : name |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1309 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) | 1307 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) |
1310 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 1308 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
1311 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 1309 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
1312 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1310 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
1313 } | 1311 } |
1314 | 1312 |
1315 | 1313 |
1316 } } // namespace v8::internal | 1314 } } // namespace v8::internal |
1317 | 1315 |
1318 #endif // V8_TARGET_ARCH_X64 | 1316 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |