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 17 matching lines...) Expand all Loading... |
28 // type: holds the receiver instance type on entry. | 28 // type: holds the receiver instance type on entry. |
29 __ cmp(type, JS_GLOBAL_OBJECT_TYPE); | 29 __ cmp(type, JS_GLOBAL_OBJECT_TYPE); |
30 __ j(equal, global_object); | 30 __ j(equal, global_object); |
31 __ cmp(type, JS_BUILTINS_OBJECT_TYPE); | 31 __ cmp(type, JS_BUILTINS_OBJECT_TYPE); |
32 __ j(equal, global_object); | 32 __ j(equal, global_object); |
33 __ cmp(type, JS_GLOBAL_PROXY_TYPE); | 33 __ cmp(type, JS_GLOBAL_PROXY_TYPE); |
34 __ j(equal, global_object); | 34 __ j(equal, global_object); |
35 } | 35 } |
36 | 36 |
37 | 37 |
38 // Generated code falls through if the receiver is a regular non-global | |
39 // JS object with slow properties and no interceptors. | |
40 static void GenerateNameDictionaryReceiverCheck(MacroAssembler* masm, | |
41 Register receiver, | |
42 Register r0, | |
43 Register r1, | |
44 Label* miss) { | |
45 // Register usage: | |
46 // receiver: holds the receiver on entry and is unchanged. | |
47 // r0: used to hold receiver instance type. | |
48 // Holds the property dictionary on fall through. | |
49 // r1: used to hold receivers map. | |
50 | |
51 // Check that the receiver isn't a smi. | |
52 __ JumpIfSmi(receiver, miss); | |
53 | |
54 // Check that the receiver is a valid JS object. | |
55 __ mov(r1, FieldOperand(receiver, HeapObject::kMapOffset)); | |
56 __ movzx_b(r0, FieldOperand(r1, Map::kInstanceTypeOffset)); | |
57 __ cmp(r0, FIRST_SPEC_OBJECT_TYPE); | |
58 __ j(below, miss); | |
59 | |
60 // If this assert fails, we have to check upper bound too. | |
61 STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE); | |
62 | |
63 GenerateGlobalInstanceTypeCheck(masm, r0, miss); | |
64 | |
65 // Check for non-global object that requires access check. | |
66 __ test_b(FieldOperand(r1, Map::kBitFieldOffset), | |
67 (1 << Map::kIsAccessCheckNeeded) | | |
68 (1 << Map::kHasNamedInterceptor)); | |
69 __ j(not_zero, miss); | |
70 | |
71 __ mov(r0, FieldOperand(receiver, JSObject::kPropertiesOffset)); | |
72 __ CheckMap(r0, masm->isolate()->factory()->hash_table_map(), miss, | |
73 DONT_DO_SMI_CHECK); | |
74 } | |
75 | |
76 | |
77 // Helper function used to load a property from a dictionary backing | 38 // Helper function used to load a property from a dictionary backing |
78 // storage. This function may fail to load a property even though it is | 39 // storage. This function may fail to load a property even though it is |
79 // in the dictionary, so code at miss_label must always call a backup | 40 // in the dictionary, so code at miss_label must always call a backup |
80 // property load that is complete. This function is safe to call if | 41 // property load that is complete. This function is safe to call if |
81 // name is not internalized, and will jump to the miss_label in that | 42 // name is not internalized, and will jump to the miss_label in that |
82 // case. The generated code assumes that the receiver has slow | 43 // case. The generated code assumes that the receiver has slow |
83 // properties, is not a global object and does not have interceptors. | 44 // properties, is not a global object and does not have interceptors. |
84 static void GenerateDictionaryLoad(MacroAssembler* masm, | 45 static void GenerateDictionaryLoad(MacroAssembler* masm, |
85 Label* miss_label, | 46 Label* miss_label, |
86 Register elements, | 47 Register elements, |
(...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
933 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); | 894 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); |
934 masm->isolate()->stub_cache()->GenerateProbe( | 895 masm->isolate()->stub_cache()->GenerateProbe( |
935 masm, flags, receiver, name, ebx, eax); | 896 masm, flags, receiver, name, ebx, eax); |
936 | 897 |
937 // Cache miss: Jump to runtime. | 898 // Cache miss: Jump to runtime. |
938 GenerateMiss(masm); | 899 GenerateMiss(masm); |
939 } | 900 } |
940 | 901 |
941 | 902 |
942 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 903 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
943 // ----------- S t a t e ------------- | 904 Register dictionary = eax; |
944 // -- ecx : name | 905 ASSERT(!dictionary.is(ReceiverRegister())); |
945 // -- edx : receiver | 906 ASSERT(!dictionary.is(NameRegister())); |
946 // -- esp[0] : return address | |
947 // ----------------------------------- | |
948 ASSERT(edx.is(ReceiverRegister())); | |
949 ASSERT(ecx.is(NameRegister())); | |
950 | 907 |
951 Label miss, slow; | 908 Label slow; |
952 | 909 |
953 GenerateNameDictionaryReceiverCheck(masm, edx, eax, ebx, &miss); | 910 __ mov(dictionary, |
954 | 911 FieldOperand(ReceiverRegister(), JSObject::kPropertiesOffset)); |
955 // eax: elements | 912 GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), edi, ebx, |
956 // Search the dictionary placing the result in eax. | 913 eax); |
957 GenerateDictionaryLoad(masm, &slow, eax, ecx, edi, ebx, eax); | |
958 __ ret(0); | 914 __ ret(0); |
959 | 915 |
960 // Dictionary load failed, go slow (but don't miss). | 916 // Dictionary load failed, go slow (but don't miss). |
961 __ bind(&slow); | 917 __ bind(&slow); |
962 GenerateRuntimeGetProperty(masm); | 918 GenerateRuntimeGetProperty(masm); |
963 | |
964 // Cache miss: Jump to runtime. | |
965 __ bind(&miss); | |
966 GenerateMiss(masm); | |
967 } | 919 } |
968 | 920 |
969 | 921 |
970 static void LoadIC_PushArgs(MacroAssembler* masm) { | 922 static void LoadIC_PushArgs(MacroAssembler* masm) { |
971 Register receiver = LoadIC::ReceiverRegister(); | 923 Register receiver = LoadIC::ReceiverRegister(); |
972 Register name = LoadIC::NameRegister(); | 924 Register name = LoadIC::NameRegister(); |
973 ASSERT(!ebx.is(receiver) && !ebx.is(name)); | 925 ASSERT(!ebx.is(receiver) && !ebx.is(name)); |
974 | 926 |
975 __ pop(ebx); | 927 __ pop(ebx); |
976 __ push(receiver); | 928 __ push(receiver); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1080 StoreIC_PushArgs(masm); | 1032 StoreIC_PushArgs(masm); |
1081 | 1033 |
1082 // Perform tail call to the entry. | 1034 // Perform tail call to the entry. |
1083 ExternalReference ref = | 1035 ExternalReference ref = |
1084 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); | 1036 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); |
1085 __ TailCallExternalReference(ref, 3, 1); | 1037 __ TailCallExternalReference(ref, 3, 1); |
1086 } | 1038 } |
1087 | 1039 |
1088 | 1040 |
1089 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 1041 void StoreIC::GenerateNormal(MacroAssembler* masm) { |
1090 // Return address is on the stack. | 1042 Label restore_miss; |
1091 Label miss, restore_miss; | |
1092 Register receiver = ReceiverRegister(); | 1043 Register receiver = ReceiverRegister(); |
1093 Register name = NameRegister(); | 1044 Register name = NameRegister(); |
1094 Register value = ValueRegister(); | 1045 Register value = ValueRegister(); |
| 1046 Register dictionary = ebx; |
1095 | 1047 |
1096 GenerateNameDictionaryReceiverCheck(masm, receiver, ebx, edi, &miss); | 1048 __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
1097 | 1049 |
1098 // A lot of registers are needed for storing to slow case | 1050 // A lot of registers are needed for storing to slow case |
1099 // objects. Push and restore receiver but rely on | 1051 // objects. Push and restore receiver but rely on |
1100 // GenerateDictionaryStore preserving the value and name. | 1052 // GenerateDictionaryStore preserving the value and name. |
1101 __ push(receiver); | 1053 __ push(receiver); |
1102 GenerateDictionaryStore(masm, &restore_miss, ebx, name, value, receiver, edi); | 1054 GenerateDictionaryStore(masm, &restore_miss, dictionary, name, value, |
| 1055 receiver, edi); |
1103 __ Drop(1); | 1056 __ Drop(1); |
1104 Counters* counters = masm->isolate()->counters(); | 1057 Counters* counters = masm->isolate()->counters(); |
1105 __ IncrementCounter(counters->store_normal_hit(), 1); | 1058 __ IncrementCounter(counters->store_normal_hit(), 1); |
1106 __ ret(0); | 1059 __ ret(0); |
1107 | 1060 |
1108 __ bind(&restore_miss); | 1061 __ bind(&restore_miss); |
1109 __ pop(receiver); | 1062 __ pop(receiver); |
1110 | |
1111 __ bind(&miss); | |
1112 __ IncrementCounter(counters->store_normal_miss(), 1); | 1063 __ IncrementCounter(counters->store_normal_miss(), 1); |
1113 GenerateMiss(masm); | 1064 GenerateMiss(masm); |
1114 } | 1065 } |
1115 | 1066 |
1116 | 1067 |
1117 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, | 1068 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, |
1118 StrictMode strict_mode) { | 1069 StrictMode strict_mode) { |
1119 // Return address is on the stack. | 1070 // Return address is on the stack. |
1120 ASSERT(!ebx.is(ReceiverRegister()) && !ebx.is(NameRegister()) && | 1071 ASSERT(!ebx.is(ReceiverRegister()) && !ebx.is(NameRegister()) && |
1121 !ebx.is(ValueRegister())); | 1072 !ebx.is(ValueRegister())); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1246 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) | 1197 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) |
1247 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 1198 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
1248 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 1199 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
1249 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1200 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
1250 } | 1201 } |
1251 | 1202 |
1252 | 1203 |
1253 } } // namespace v8::internal | 1204 } } // namespace v8::internal |
1254 | 1205 |
1255 #endif // V8_TARGET_ARCH_IA32 | 1206 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |