Chromium Code Reviews| 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 |