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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
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 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
381 FixedArray::kHeaderSize); | 381 FixedArray::kHeaderSize); |
382 } | 382 } |
383 | 383 |
384 | 384 |
385 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 385 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { |
386 // ----------- S t a t e ------------- | 386 // ----------- S t a t e ------------- |
387 // -- ecx : key | 387 // -- ecx : key |
388 // -- edx : receiver | 388 // -- edx : receiver |
389 // -- esp[0] : return address | 389 // -- esp[0] : return address |
390 // ----------------------------------- | 390 // ----------------------------------- |
391 ASSERT(edx.is(ReceiverRegister())); | |
392 ASSERT(ecx.is(NameRegister())); | |
391 Label slow, check_name, index_smi, index_name, property_array_property; | 393 Label slow, check_name, index_smi, index_name, property_array_property; |
392 Label probe_dictionary, check_number_dictionary; | 394 Label probe_dictionary, check_number_dictionary; |
393 | 395 |
394 // Check that the key is a smi. | 396 // Check that the key is a smi. |
395 __ JumpIfNotSmi(ecx, &check_name); | 397 __ JumpIfNotSmi(ecx, &check_name); |
396 __ bind(&index_smi); | 398 __ bind(&index_smi); |
397 // Now the key is known to be a smi. This place is also jumped to from | 399 // Now the key is known to be a smi. This place is also jumped to from |
398 // where a numeric string is converted to a smi. | 400 // where a numeric string is converted to a smi. |
399 | 401 |
400 GenerateKeyedLoadReceiverCheck( | 402 GenerateKeyedLoadReceiverCheck( |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
559 __ jmp(&index_smi); | 561 __ jmp(&index_smi); |
560 } | 562 } |
561 | 563 |
562 | 564 |
563 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { | 565 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { |
564 // ----------- S t a t e ------------- | 566 // ----------- S t a t e ------------- |
565 // -- ecx : key (index) | 567 // -- ecx : key (index) |
566 // -- edx : receiver | 568 // -- edx : receiver |
567 // -- esp[0] : return address | 569 // -- esp[0] : return address |
568 // ----------------------------------- | 570 // ----------------------------------- |
571 ASSERT(edx.is(ReceiverRegister())); | |
572 ASSERT(ecx.is(NameRegister())); | |
569 Label miss; | 573 Label miss; |
570 | 574 |
571 Register receiver = edx; | 575 Register receiver = edx; |
Jakob Kummerow
2014/06/25 16:17:40
awww... come on!
mvstanton
2014/06/26 09:18:11
Haha! Okay I will try and do a little better :).
| |
572 Register index = ecx; | 576 Register index = ecx; |
573 Register scratch = ebx; | 577 Register scratch = ebx; |
574 Register result = eax; | 578 Register result = eax; |
575 | 579 |
576 StringCharAtGenerator char_at_generator(receiver, | 580 StringCharAtGenerator char_at_generator(receiver, |
577 index, | 581 index, |
578 scratch, | 582 scratch, |
579 result, | 583 result, |
580 &miss, // When not a string. | 584 &miss, // When not a string. |
581 &miss, // When not a number. | 585 &miss, // When not a number. |
582 &miss, // When index out of range. | 586 &miss, // When index out of range. |
583 STRING_INDEX_IS_ARRAY_INDEX); | 587 STRING_INDEX_IS_ARRAY_INDEX); |
584 char_at_generator.GenerateFast(masm); | 588 char_at_generator.GenerateFast(masm); |
585 __ ret(0); | 589 __ ret(0); |
586 | 590 |
587 StubRuntimeCallHelper call_helper; | 591 StubRuntimeCallHelper call_helper; |
588 char_at_generator.GenerateSlow(masm, call_helper); | 592 char_at_generator.GenerateSlow(masm, call_helper); |
589 | 593 |
590 __ bind(&miss); | 594 __ bind(&miss); |
591 GenerateMiss(masm); | 595 GenerateMiss(masm); |
592 } | 596 } |
593 | 597 |
594 | 598 |
595 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 599 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { |
596 // ----------- S t a t e ------------- | 600 // ----------- S t a t e ------------- |
597 // -- ecx : key | 601 // -- ecx : key |
598 // -- edx : receiver | 602 // -- edx : receiver |
599 // -- esp[0] : return address | 603 // -- esp[0] : return address |
600 // ----------------------------------- | 604 // ----------------------------------- |
605 ASSERT(edx.is(ReceiverRegister())); | |
606 ASSERT(ecx.is(NameRegister())); | |
601 Label slow; | 607 Label slow; |
602 | 608 |
603 // Check that the receiver isn't a smi. | 609 // Check that the receiver isn't a smi. |
604 __ JumpIfSmi(edx, &slow); | 610 __ JumpIfSmi(edx, &slow); |
605 | 611 |
606 // Check that the key is an array index, that is Uint32. | 612 // Check that the key is an array index, that is Uint32. |
607 __ test(ecx, Immediate(kSmiTagMask | kSmiSignMask)); | 613 __ test(ecx, Immediate(kSmiTagMask | kSmiSignMask)); |
608 __ j(not_zero, &slow); | 614 __ j(not_zero, &slow); |
609 | 615 |
610 // Get the map of the receiver. | 616 // Get the map of the receiver. |
(...skipping 22 matching lines...) Expand all Loading... | |
633 GenerateMiss(masm); | 639 GenerateMiss(masm); |
634 } | 640 } |
635 | 641 |
636 | 642 |
637 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { | 643 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { |
638 // ----------- S t a t e ------------- | 644 // ----------- S t a t e ------------- |
639 // -- ecx : key | 645 // -- ecx : key |
640 // -- edx : receiver | 646 // -- edx : receiver |
641 // -- esp[0] : return address | 647 // -- esp[0] : return address |
642 // ----------------------------------- | 648 // ----------------------------------- |
649 ASSERT(edx.is(ReceiverRegister())); | |
650 ASSERT(ecx.is(NameRegister())); | |
643 Label slow, notin; | 651 Label slow, notin; |
644 Factory* factory = masm->isolate()->factory(); | 652 Factory* factory = masm->isolate()->factory(); |
645 Operand mapped_location = | 653 Operand mapped_location = |
646 GenerateMappedArgumentsLookup(masm, edx, ecx, ebx, eax, ¬in, &slow); | 654 GenerateMappedArgumentsLookup(masm, edx, ecx, ebx, eax, ¬in, &slow); |
647 __ mov(eax, mapped_location); | 655 __ mov(eax, mapped_location); |
648 __ Ret(); | 656 __ Ret(); |
649 __ bind(¬in); | 657 __ bind(¬in); |
650 // The unmapped lookup expects that the parameter map is in ebx. | 658 // The unmapped lookup expects that the parameter map is in ebx. |
651 Operand unmapped_location = | 659 Operand unmapped_location = |
652 GenerateUnmappedArgumentsLookup(masm, ecx, ebx, eax, &slow); | 660 GenerateUnmappedArgumentsLookup(masm, ecx, ebx, eax, &slow); |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
923 &slow, kDontCheckMap, kIncrementLength); | 931 &slow, kDontCheckMap, kIncrementLength); |
924 } | 932 } |
925 | 933 |
926 | 934 |
927 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 935 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
928 // ----------- S t a t e ------------- | 936 // ----------- S t a t e ------------- |
929 // -- ecx : name | 937 // -- ecx : name |
930 // -- edx : receiver | 938 // -- edx : receiver |
931 // -- esp[0] : return address | 939 // -- esp[0] : return address |
932 // ----------------------------------- | 940 // ----------------------------------- |
941 ASSERT(edx.is(ReceiverRegister())); | |
942 ASSERT(ecx.is(NameRegister())); | |
933 | 943 |
934 // Probe the stub cache. | 944 // Probe the stub cache. |
935 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); | 945 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); |
936 masm->isolate()->stub_cache()->GenerateProbe( | 946 masm->isolate()->stub_cache()->GenerateProbe( |
937 masm, flags, edx, ecx, ebx, eax); | 947 masm, flags, edx, ecx, ebx, eax); |
938 | 948 |
939 // Cache miss: Jump to runtime. | 949 // Cache miss: Jump to runtime. |
940 GenerateMiss(masm); | 950 GenerateMiss(masm); |
941 } | 951 } |
942 | 952 |
943 | 953 |
944 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 954 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
945 // ----------- S t a t e ------------- | 955 // ----------- S t a t e ------------- |
946 // -- ecx : name | 956 // -- ecx : name |
947 // -- edx : receiver | 957 // -- edx : receiver |
948 // -- esp[0] : return address | 958 // -- esp[0] : return address |
949 // ----------------------------------- | 959 // ----------------------------------- |
960 ASSERT(edx.is(ReceiverRegister())); | |
961 ASSERT(ecx.is(NameRegister())); | |
962 | |
950 Label miss, slow; | 963 Label miss, slow; |
951 | 964 |
952 GenerateNameDictionaryReceiverCheck(masm, edx, eax, ebx, &miss); | 965 GenerateNameDictionaryReceiverCheck(masm, edx, eax, ebx, &miss); |
953 | 966 |
954 // eax: elements | 967 // eax: elements |
955 // Search the dictionary placing the result in eax. | 968 // Search the dictionary placing the result in eax. |
956 GenerateDictionaryLoad(masm, &slow, eax, ecx, edi, ebx, eax); | 969 GenerateDictionaryLoad(masm, &slow, eax, ecx, edi, ebx, eax); |
957 __ ret(0); | 970 __ ret(0); |
958 | 971 |
959 // Dictionary load failed, go slow (but don't miss). | 972 // Dictionary load failed, go slow (but don't miss). |
960 __ bind(&slow); | 973 __ bind(&slow); |
961 GenerateRuntimeGetProperty(masm); | 974 GenerateRuntimeGetProperty(masm); |
962 | 975 |
963 // Cache miss: Jump to runtime. | 976 // Cache miss: Jump to runtime. |
964 __ bind(&miss); | 977 __ bind(&miss); |
965 GenerateMiss(masm); | 978 GenerateMiss(masm); |
966 } | 979 } |
967 | 980 |
968 | 981 |
982 // A register that isn't one of the parameters to the load ic. | |
983 static const Register LoadIC_TempRegister() { return ebx; } | |
984 | |
985 | |
969 void LoadIC::GenerateMiss(MacroAssembler* masm) { | 986 void LoadIC::GenerateMiss(MacroAssembler* masm) { |
970 // ----------- S t a t e ------------- | 987 // ----------- S t a t e ------------------ |
971 // -- ecx : name | 988 // -- esp[0] : return address |
972 // -- edx : receiver | 989 // ---------------------------------------- |
973 // -- esp[0] : return address | |
974 // ----------------------------------- | |
975 | |
976 __ IncrementCounter(masm->isolate()->counters()->load_miss(), 1); | 990 __ IncrementCounter(masm->isolate()->counters()->load_miss(), 1); |
977 | 991 |
978 __ pop(ebx); | 992 __ pop(LoadIC_TempRegister()); |
979 __ push(edx); // receiver | 993 __ push(ReceiverRegister()); // receiver |
980 __ push(ecx); // name | 994 __ push(NameRegister()); // name |
981 __ push(ebx); // return address | 995 __ push(LoadIC_TempRegister()); // return address |
982 | 996 |
983 // Perform tail call to the entry. | 997 // Perform tail call to the entry. |
984 ExternalReference ref = | 998 ExternalReference ref = |
985 ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate()); | 999 ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate()); |
986 __ TailCallExternalReference(ref, 2, 1); | 1000 __ TailCallExternalReference(ref, 2, 1); |
987 } | 1001 } |
988 | 1002 |
989 | 1003 |
990 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 1004 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
991 // ----------- S t a t e ------------- | 1005 // ----------- S t a t e ------------------ |
992 // -- ecx : key | 1006 // -- esp[0] : return address |
993 // -- edx : receiver | 1007 // ---------------------------------------- |
994 // -- esp[0] : return address | 1008 __ pop(LoadIC_TempRegister()); |
995 // ----------------------------------- | 1009 __ push(ReceiverRegister()); // receiver |
996 | 1010 __ push(NameRegister()); // name |
997 __ pop(ebx); | 1011 __ push(LoadIC_TempRegister()); // return address |
998 __ push(edx); // receiver | |
999 __ push(ecx); // name | |
1000 __ push(ebx); // return address | |
1001 | 1012 |
1002 // Perform tail call to the entry. | 1013 // Perform tail call to the entry. |
1003 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); | 1014 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); |
1004 } | 1015 } |
1005 | 1016 |
1006 | 1017 |
1018 // A register that isn't one of the parameters to the load ic. | |
1019 static const Register KeyedLoadIC_TempRegister() { | |
1020 return LoadIC_TempRegister(); | |
1021 } | |
1022 | |
1023 | |
1007 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 1024 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
1008 // ----------- S t a t e ------------- | 1025 // ----------- S t a t e ------------------ |
1009 // -- ecx : key | 1026 // -- esp[0] : return address |
1010 // -- edx : receiver | 1027 // ---------------------------------------- |
1011 // -- esp[0] : return address | |
1012 // ----------------------------------- | |
1013 | |
1014 __ IncrementCounter(masm->isolate()->counters()->keyed_load_miss(), 1); | 1028 __ IncrementCounter(masm->isolate()->counters()->keyed_load_miss(), 1); |
1015 | 1029 |
1016 __ pop(ebx); | 1030 __ pop(KeyedLoadIC_TempRegister()); |
1017 __ push(edx); // receiver | 1031 __ push(ReceiverRegister()); // receiver |
1018 __ push(ecx); // name | 1032 __ push(NameRegister()); // name |
1019 __ push(ebx); // return address | 1033 __ push(KeyedLoadIC_TempRegister()); // return address |
1020 | 1034 |
1021 // Perform tail call to the entry. | 1035 // Perform tail call to the entry. |
1022 ExternalReference ref = | 1036 ExternalReference ref = |
1023 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); | 1037 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); |
1024 __ TailCallExternalReference(ref, 2, 1); | 1038 __ TailCallExternalReference(ref, 2, 1); |
1025 } | 1039 } |
1026 | 1040 |
1027 | 1041 |
1028 // IC register specifications | 1042 // IC register specifications |
1029 const Register LoadIC::ReceiverRegister() { return edx; } | 1043 const Register LoadIC::ReceiverRegister() { return edx; } |
1030 const Register LoadIC::NameRegister() { return ecx; } | 1044 const Register LoadIC::NameRegister() { return ecx; } |
1031 | 1045 |
1032 | 1046 |
1033 const Register KeyedLoadIC::ReceiverRegister() { | 1047 const Register KeyedLoadIC::ReceiverRegister() { |
1034 return LoadIC::ReceiverRegister(); | 1048 return LoadIC::ReceiverRegister(); |
1035 } | 1049 } |
1036 | 1050 |
1037 | 1051 |
1038 const Register KeyedLoadIC::NameRegister() { return LoadIC::NameRegister(); } | 1052 const Register KeyedLoadIC::NameRegister() { return LoadIC::NameRegister(); } |
1039 | 1053 |
1040 | 1054 |
1041 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 1055 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
1042 // ----------- S t a t e ------------- | 1056 // ----------- S t a t e ------------------ |
1043 // -- ecx : key | 1057 // -- esp[0] : return address |
1044 // -- edx : receiver | 1058 // ---------------------------------------- |
1045 // -- esp[0] : return address | 1059 __ pop(KeyedLoadIC_TempRegister()); |
1046 // ----------------------------------- | 1060 __ push(ReceiverRegister()); // receiver |
1047 | 1061 __ push(NameRegister()); // name |
1048 __ pop(ebx); | 1062 __ push(KeyedLoadIC_TempRegister()); // return address |
1049 __ push(edx); // receiver | |
1050 __ push(ecx); // name | |
1051 __ push(ebx); // return address | |
1052 | 1063 |
1053 // Perform tail call to the entry. | 1064 // Perform tail call to the entry. |
1054 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 1065 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
1055 } | 1066 } |
1056 | 1067 |
1057 | 1068 |
1058 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { | 1069 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { |
1059 // ----------- S t a t e ------------- | 1070 // ----------- S t a t e ------------- |
1060 // -- eax : value | 1071 // -- eax : value |
1061 // -- ecx : name | 1072 // -- ecx : name |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1294 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) | 1305 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) |
1295 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 1306 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
1296 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 1307 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
1297 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1308 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
1298 } | 1309 } |
1299 | 1310 |
1300 | 1311 |
1301 } } // namespace v8::internal | 1312 } } // namespace v8::internal |
1302 | 1313 |
1303 #endif // V8_TARGET_ARCH_IA32 | 1314 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |