OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
88 // Miss: fall through. | 88 // Miss: fall through. |
89 __ bind(&miss); | 89 __ bind(&miss); |
90 } | 90 } |
91 | 91 |
92 | 92 |
93 // Helper function used to check that the dictionary doesn't contain | 93 // Helper function used to check that the dictionary doesn't contain |
94 // the property. This function may return false negatives, so miss_label | 94 // the property. This function may return false negatives, so miss_label |
95 // must always call a backup property check that is complete. | 95 // must always call a backup property check that is complete. |
96 // This function is safe to call if the receiver has fast properties. | 96 // This function is safe to call if the receiver has fast properties. |
97 // Name must be a symbol and receiver must be a heap object. | 97 // Name must be a symbol and receiver must be a heap object. |
98 MUST_USE_RESULT static MaybeObject* GenerateDictionaryNegativeLookup( | 98 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, |
99 Label* miss_label, | |
100 Register receiver, | |
101 Handle<String> name, | |
102 Register scratch0, | |
103 Register scratch1) { | |
104 ASSERT(name->IsSymbol()); | |
105 Counters* counters = masm->isolate()->counters(); | |
106 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); | |
107 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | |
108 | |
109 Label done; | |
110 | |
111 const int kInterceptorOrAccessCheckNeededMask = | |
112 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | |
113 | |
114 // Bail out if the receiver has a named interceptor or requires access checks. | |
115 Register map = scratch1; | |
116 __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | |
117 __ ldrb(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); | |
118 __ tst(scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); | |
119 __ b(ne, miss_label); | |
120 | |
121 // Check that receiver is a JSObject. | |
122 __ ldrb(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); | |
123 __ cmp(scratch0, Operand(FIRST_SPEC_OBJECT_TYPE)); | |
124 __ b(lt, miss_label); | |
125 | |
126 // Load properties array. | |
127 Register properties = scratch0; | |
128 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | |
129 // Check that the properties array is a dictionary. | |
130 __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset)); | |
131 Register tmp = properties; | |
132 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); | |
133 __ cmp(map, tmp); | |
134 __ b(ne, miss_label); | |
135 | |
136 // Restore the temporarily used register. | |
137 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | |
138 | |
139 | |
140 StringDictionaryLookupStub::GenerateNegativeLookup(masm, | |
Kevin Millikin (Chromium)
2011/10/24 15:55:12
This is the only change from the original.
| |
141 miss_label, | |
142 &done, | |
143 receiver, | |
144 properties, | |
145 name, | |
146 scratch1); | |
147 __ bind(&done); | |
148 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | |
149 } | |
150 | |
151 | |
152 // TODO(kmillikin): Eliminate this function when the stub cache is fully | |
153 // handlified. | |
154 MUST_USE_RESULT static MaybeObject* TryGenerateDictionaryNegativeLookup( | |
99 MacroAssembler* masm, | 155 MacroAssembler* masm, |
100 Label* miss_label, | 156 Label* miss_label, |
101 Register receiver, | 157 Register receiver, |
102 String* name, | 158 String* name, |
103 Register scratch0, | 159 Register scratch0, |
104 Register scratch1) { | 160 Register scratch1) { |
105 ASSERT(name->IsSymbol()); | 161 ASSERT(name->IsSymbol()); |
106 Counters* counters = masm->isolate()->counters(); | 162 Counters* counters = masm->isolate()->counters(); |
107 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); | 163 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); |
108 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 164 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); |
(...skipping 22 matching lines...) Expand all Loading... | |
131 __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset)); | 187 __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset)); |
132 Register tmp = properties; | 188 Register tmp = properties; |
133 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); | 189 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); |
134 __ cmp(map, tmp); | 190 __ cmp(map, tmp); |
135 __ b(ne, miss_label); | 191 __ b(ne, miss_label); |
136 | 192 |
137 // Restore the temporarily used register. | 193 // Restore the temporarily used register. |
138 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 194 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
139 | 195 |
140 | 196 |
141 MaybeObject* result = StringDictionaryLookupStub::GenerateNegativeLookup( | 197 MaybeObject* result = StringDictionaryLookupStub::TryGenerateNegativeLookup( |
142 masm, | 198 masm, |
143 miss_label, | 199 miss_label, |
144 &done, | 200 &done, |
145 receiver, | 201 receiver, |
146 properties, | 202 properties, |
147 name, | 203 name, |
148 scratch1); | 204 scratch1); |
149 if (result->IsFailure()) return result; | 205 if (result->IsFailure()) return result; |
150 | 206 |
151 __ bind(&done); | 207 __ bind(&done); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
252 __ Move(prototype, Handle<Map>(function->initial_map())); | 308 __ Move(prototype, Handle<Map>(function->initial_map())); |
253 // Load the prototype from the initial map. | 309 // Load the prototype from the initial map. |
254 __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); | 310 __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); |
255 } | 311 } |
256 | 312 |
257 | 313 |
258 // Load a fast property out of a holder object (src). In-object properties | 314 // Load a fast property out of a holder object (src). In-object properties |
259 // are loaded directly otherwise the property is loaded from the properties | 315 // are loaded directly otherwise the property is loaded from the properties |
260 // fixed array. | 316 // fixed array. |
261 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, | 317 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, |
262 Register dst, Register src, | 318 Register dst, |
263 JSObject* holder, int index) { | 319 Register src, |
320 Handle<JSObject> holder, | |
321 int index) { | |
264 // Adjust for the number of properties stored in the holder. | 322 // Adjust for the number of properties stored in the holder. |
265 index -= holder->map()->inobject_properties(); | 323 index -= holder->map()->inobject_properties(); |
266 if (index < 0) { | 324 if (index < 0) { |
267 // Get the property straight out of the holder. | 325 // Get the property straight out of the holder. |
268 int offset = holder->map()->instance_size() + (index * kPointerSize); | 326 int offset = holder->map()->instance_size() + (index * kPointerSize); |
269 __ ldr(dst, FieldMemOperand(src, offset)); | 327 __ ldr(dst, FieldMemOperand(src, offset)); |
270 } else { | 328 } else { |
271 // Calculate the offset into the properties array. | 329 // Calculate the offset into the properties array. |
272 int offset = index * kPointerSize + FixedArray::kHeaderSize; | 330 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
273 __ ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); | 331 __ ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
473 } else { | 531 } else { |
474 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss); | 532 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss); |
475 } | 533 } |
476 | 534 |
477 Handle<Code> ic(code); | 535 Handle<Code> ic(code); |
478 __ Jump(ic, RelocInfo::CODE_TARGET); | 536 __ Jump(ic, RelocInfo::CODE_TARGET); |
479 } | 537 } |
480 | 538 |
481 | 539 |
482 static void GenerateCallFunction(MacroAssembler* masm, | 540 static void GenerateCallFunction(MacroAssembler* masm, |
483 Object* object, | 541 Handle<Object> object, |
484 const ParameterCount& arguments, | 542 const ParameterCount& arguments, |
485 Label* miss, | 543 Label* miss, |
486 Code::ExtraICState extra_ic_state) { | 544 Code::ExtraICState extra_ic_state) { |
487 // ----------- S t a t e ------------- | 545 // ----------- S t a t e ------------- |
488 // -- r0: receiver | 546 // -- r0: receiver |
489 // -- r1: function to call | 547 // -- r1: function to call |
490 // ----------------------------------- | 548 // ----------------------------------- |
491 | 549 |
492 // Check that the function really is a function. | 550 // Check that the function really is a function. |
493 __ JumpIfSmi(r1, miss); | 551 __ JumpIfSmi(r1, miss); |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
861 StubCompiler* stub_compiler_; | 919 StubCompiler* stub_compiler_; |
862 const ParameterCount& arguments_; | 920 const ParameterCount& arguments_; |
863 Register name_; | 921 Register name_; |
864 Code::ExtraICState extra_ic_state_; | 922 Code::ExtraICState extra_ic_state_; |
865 }; | 923 }; |
866 | 924 |
867 | 925 |
868 // Generate code to check that a global property cell is empty. Create | 926 // Generate code to check that a global property cell is empty. Create |
869 // the property cell at compilation time if no cell exists for the | 927 // the property cell at compilation time if no cell exists for the |
870 // property. | 928 // property. |
871 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( | 929 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
930 Handle<GlobalObject> global, | |
931 Handle<String> name, | |
932 Register scratch, | |
933 Label* miss) { | |
934 Handle<JSGlobalPropertyCell> cell = | |
935 GlobalObject::EnsurePropertyCell(global, name); | |
936 ASSERT(cell->value()->IsTheHole()); | |
937 __ mov(scratch, Operand(cell)); | |
938 __ ldr(scratch, | |
939 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | |
940 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | |
941 __ cmp(scratch, ip); | |
942 __ b(ne, miss); | |
943 } | |
944 | |
945 | |
946 // TODO(kmillikin): Eliminate this function when the stub cache is fully | |
947 // handlified. | |
948 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCell( | |
872 MacroAssembler* masm, | 949 MacroAssembler* masm, |
873 GlobalObject* global, | 950 GlobalObject* global, |
874 String* name, | 951 String* name, |
875 Register scratch, | 952 Register scratch, |
876 Label* miss) { | 953 Label* miss) { |
877 Object* probe; | 954 Object* probe; |
878 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); | 955 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); |
879 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 956 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
880 } | 957 } |
881 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | 958 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); |
882 ASSERT(cell->value()->IsTheHole()); | 959 ASSERT(cell->value()->IsTheHole()); |
883 __ mov(scratch, Operand(Handle<Object>(cell))); | 960 __ mov(scratch, Operand(Handle<Object>(cell))); |
884 __ ldr(scratch, | 961 __ ldr(scratch, |
885 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | 962 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); |
886 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 963 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
887 __ cmp(scratch, ip); | 964 __ cmp(scratch, ip); |
888 __ b(ne, miss); | 965 __ b(ne, miss); |
889 return cell; | 966 return cell; |
890 } | 967 } |
891 | 968 |
969 | |
892 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 970 // Calls GenerateCheckPropertyCell for each global object in the prototype chain |
893 // from object to (but not including) holder. | 971 // from object to (but not including) holder. |
894 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells( | 972 static void GenerateCheckPropertyCells(MacroAssembler* masm, |
973 Handle<JSObject> object, | |
974 Handle<JSObject> holder, | |
975 Handle<String> name, | |
976 Register scratch, | |
977 Label* miss) { | |
978 Handle<JSObject> current = object; | |
979 while (!current.is_identical_to(holder)) { | |
980 if (current->IsGlobalObject()) { | |
981 GenerateCheckPropertyCell(masm, | |
982 Handle<GlobalObject>::cast(current), | |
983 name, | |
984 scratch, | |
985 miss); | |
986 } | |
987 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); | |
988 } | |
989 } | |
990 | |
991 | |
992 // TODO(kmillikin): Eliminate this function when the stub cache is fully | |
993 // handlified. | |
994 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCells( | |
895 MacroAssembler* masm, | 995 MacroAssembler* masm, |
896 JSObject* object, | 996 JSObject* object, |
897 JSObject* holder, | 997 JSObject* holder, |
898 String* name, | 998 String* name, |
899 Register scratch, | 999 Register scratch, |
900 Label* miss) { | 1000 Label* miss) { |
901 JSObject* current = object; | 1001 JSObject* current = object; |
902 while (current != holder) { | 1002 while (current != holder) { |
903 if (current->IsGlobalObject()) { | 1003 if (current->IsGlobalObject()) { |
904 // Returns a cell or a failure. | 1004 // Returns a cell or a failure. |
905 MaybeObject* result = GenerateCheckPropertyCell( | 1005 MaybeObject* result = TryGenerateCheckPropertyCell( |
906 masm, | 1006 masm, |
907 GlobalObject::cast(current), | 1007 GlobalObject::cast(current), |
908 name, | 1008 name, |
909 scratch, | 1009 scratch, |
910 miss); | 1010 miss); |
911 if (result->IsFailure()) return result; | 1011 if (result->IsFailure()) return result; |
912 } | 1012 } |
913 ASSERT(current->IsJSObject()); | 1013 ASSERT(current->IsJSObject()); |
914 current = JSObject::cast(current->GetPrototype()); | 1014 current = JSObject::cast(current->GetPrototype()); |
915 } | 1015 } |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1020 if (!(biased_exponent & 1)) { | 1120 if (!(biased_exponent & 1)) { |
1021 __ bic(hiword, hiword, Operand(1 << HeapNumber::kExponentShift)); | 1121 __ bic(hiword, hiword, Operand(1 << HeapNumber::kExponentShift)); |
1022 } | 1122 } |
1023 } | 1123 } |
1024 | 1124 |
1025 | 1125 |
1026 #undef __ | 1126 #undef __ |
1027 #define __ ACCESS_MASM(masm()) | 1127 #define __ ACCESS_MASM(masm()) |
1028 | 1128 |
1029 | 1129 |
1130 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | |
1131 Register object_reg, | |
1132 Handle<JSObject> holder, | |
1133 Register holder_reg, | |
1134 Register scratch1, | |
1135 Register scratch2, | |
1136 Handle<String> name, | |
1137 int save_at_depth, | |
1138 Label* miss) { | |
1139 // Make sure there's no overlap between holder and object registers. | |
1140 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | |
1141 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | |
1142 && !scratch2.is(scratch1)); | |
1143 | |
1144 // Keep track of the current object in register reg. | |
1145 Register reg = object_reg; | |
1146 int depth = 0; | |
1147 | |
1148 if (save_at_depth == depth) { | |
1149 __ str(reg, MemOperand(sp)); | |
1150 } | |
1151 | |
1152 // Check the maps in the prototype chain. | |
1153 // Traverse the prototype chain from the object and do map checks. | |
1154 Handle<JSObject> current = object; | |
1155 while (!current.is_identical_to(holder)) { | |
1156 ++depth; | |
1157 | |
1158 // Only global objects and objects that do not require access | |
1159 // checks are allowed in stubs. | |
1160 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | |
1161 | |
1162 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); | |
1163 if (!current->HasFastProperties() && | |
1164 !current->IsJSGlobalObject() && | |
1165 !current->IsJSGlobalProxy()) { | |
1166 if (!name->IsSymbol()) { | |
1167 name = factory()->LookupSymbol(name); | |
1168 } | |
1169 ASSERT(current->property_dictionary()->FindEntry(*name) == | |
1170 StringDictionary::kNotFound); | |
1171 | |
1172 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | |
1173 scratch1, scratch2); | |
1174 | |
1175 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | |
1176 reg = holder_reg; // From now on the object will be in holder_reg. | |
1177 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | |
1178 } else { | |
1179 Handle<Map> current_map(current->map()); | |
1180 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | |
1181 __ cmp(scratch1, Operand(current_map)); | |
1182 // Branch on the result of the map check. | |
1183 __ b(ne, miss); | |
1184 // Check access rights to the global object. This has to happen after | |
1185 // the map check so that we know that the object is actually a global | |
1186 // object. | |
1187 if (current->IsJSGlobalProxy()) { | |
1188 __ CheckAccessGlobalProxy(reg, scratch2, miss); | |
1189 } | |
1190 reg = holder_reg; // From now on the object will be in holder_reg. | |
1191 | |
1192 if (heap()->InNewSpace(*prototype)) { | |
1193 // The prototype is in new space; we cannot store a reference to it | |
1194 // in the code. Load it from the map. | |
1195 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | |
1196 } else { | |
1197 // The prototype is in old space; load it directly. | |
1198 __ mov(reg, Operand(prototype)); | |
1199 } | |
1200 } | |
1201 | |
1202 if (save_at_depth == depth) { | |
1203 __ str(reg, MemOperand(sp)); | |
1204 } | |
1205 | |
1206 // Go to the next object in the prototype chain. | |
1207 current = prototype; | |
1208 } | |
1209 | |
1210 // Log the check depth. | |
1211 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); | |
1212 | |
1213 // Check the holder map. | |
1214 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | |
1215 __ cmp(scratch1, Operand(Handle<Map>(current->map()))); | |
1216 __ b(ne, miss); | |
1217 | |
1218 // Perform security check for access to the global object. | |
1219 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | |
1220 if (holder->IsJSGlobalProxy()) { | |
1221 __ CheckAccessGlobalProxy(reg, scratch1, miss); | |
1222 } | |
1223 | |
1224 // If we've skipped any global objects, it's not enough to verify that | |
1225 // their maps haven't changed. We also need to check that the property | |
1226 // cell for the property is still empty. | |
1227 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); | |
1228 | |
1229 // Return the register containing the holder. | |
1230 return reg; | |
1231 } | |
1232 | |
1233 | |
1234 // TODO(kmillikin): Eliminate this function when the stub cache is fully | |
1235 // handlified. | |
1030 Register StubCompiler::CheckPrototypes(JSObject* object, | 1236 Register StubCompiler::CheckPrototypes(JSObject* object, |
1031 Register object_reg, | 1237 Register object_reg, |
1032 JSObject* holder, | 1238 JSObject* holder, |
1033 Register holder_reg, | 1239 Register holder_reg, |
1034 Register scratch1, | 1240 Register scratch1, |
1035 Register scratch2, | 1241 Register scratch2, |
1036 String* name, | 1242 String* name, |
1037 int save_at_depth, | 1243 int save_at_depth, |
1038 Label* miss) { | 1244 Label* miss) { |
1039 // Make sure there's no overlap between holder and object registers. | 1245 // Make sure there's no overlap between holder and object registers. |
(...skipping 29 matching lines...) Expand all Loading... | |
1069 Object* lookup_result = NULL; // Initialization to please compiler. | 1275 Object* lookup_result = NULL; // Initialization to please compiler. |
1070 if (!maybe_lookup_result->ToObject(&lookup_result)) { | 1276 if (!maybe_lookup_result->ToObject(&lookup_result)) { |
1071 set_failure(Failure::cast(maybe_lookup_result)); | 1277 set_failure(Failure::cast(maybe_lookup_result)); |
1072 return reg; | 1278 return reg; |
1073 } | 1279 } |
1074 name = String::cast(lookup_result); | 1280 name = String::cast(lookup_result); |
1075 } | 1281 } |
1076 ASSERT(current->property_dictionary()->FindEntry(name) == | 1282 ASSERT(current->property_dictionary()->FindEntry(name) == |
1077 StringDictionary::kNotFound); | 1283 StringDictionary::kNotFound); |
1078 | 1284 |
1079 MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(), | 1285 MaybeObject* negative_lookup = |
1080 miss, | 1286 TryGenerateDictionaryNegativeLookup(masm(), |
1081 reg, | 1287 miss, |
1082 name, | 1288 reg, |
1083 scratch1, | 1289 name, |
1084 scratch2); | 1290 scratch1, |
1291 scratch2); | |
1085 if (negative_lookup->IsFailure()) { | 1292 if (negative_lookup->IsFailure()) { |
1086 set_failure(Failure::cast(negative_lookup)); | 1293 set_failure(Failure::cast(negative_lookup)); |
1087 return reg; | 1294 return reg; |
1088 } | 1295 } |
1089 | 1296 |
1090 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1297 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
1091 reg = holder_reg; // from now the object is in holder_reg | 1298 reg = holder_reg; // from now the object is in holder_reg |
1092 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 1299 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
1093 } else if (heap()->InNewSpace(prototype)) { | 1300 } else if (heap()->InNewSpace(prototype)) { |
1094 // Get the map of the current object. | 1301 // Get the map of the current object. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1143 __ cmp(scratch1, Operand(Handle<Map>(current->map()))); | 1350 __ cmp(scratch1, Operand(Handle<Map>(current->map()))); |
1144 __ b(ne, miss); | 1351 __ b(ne, miss); |
1145 | 1352 |
1146 // Log the check depth. | 1353 // Log the check depth. |
1147 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); | 1354 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); |
1148 | 1355 |
1149 // Perform security check for access to the global object. | 1356 // Perform security check for access to the global object. |
1150 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1357 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
1151 if (holder->IsJSGlobalProxy()) { | 1358 if (holder->IsJSGlobalProxy()) { |
1152 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 1359 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
1153 }; | 1360 } |
1154 | 1361 |
1155 // If we've skipped any global objects, it's not enough to verify | 1362 // If we've skipped any global objects, it's not enough to verify |
1156 // that their maps haven't changed. We also need to check that the | 1363 // that their maps haven't changed. We also need to check that the |
1157 // property cell for the property is still empty. | 1364 // property cell for the property is still empty. |
1158 MaybeObject* result = GenerateCheckPropertyCells(masm(), | 1365 MaybeObject* result = TryGenerateCheckPropertyCells(masm(), |
1159 object, | 1366 object, |
1160 holder, | 1367 holder, |
1161 name, | 1368 name, |
1162 scratch1, | 1369 scratch1, |
1163 miss); | 1370 miss); |
1164 if (result->IsFailure()) set_failure(Failure::cast(result)); | 1371 if (result->IsFailure()) set_failure(Failure::cast(result)); |
1165 | 1372 |
1166 // Return the register containing the holder. | 1373 // Return the register containing the holder. |
1167 return reg; | 1374 return reg; |
1168 } | 1375 } |
1169 | 1376 |
1170 | 1377 |
1171 void StubCompiler::GenerateLoadField(JSObject* object, | 1378 void StubCompiler::GenerateLoadField(JSObject* object, |
1172 JSObject* holder, | 1379 JSObject* holder, |
1173 Register receiver, | 1380 Register receiver, |
1174 Register scratch1, | 1381 Register scratch1, |
1175 Register scratch2, | 1382 Register scratch2, |
1176 Register scratch3, | 1383 Register scratch3, |
1177 int index, | 1384 int index, |
1178 String* name, | 1385 String* name, |
1179 Label* miss) { | 1386 Label* miss) { |
1180 // Check that the receiver isn't a smi. | 1387 // Check that the receiver isn't a smi. |
1181 __ JumpIfSmi(receiver, miss); | 1388 __ JumpIfSmi(receiver, miss); |
1182 | 1389 |
1183 // Check that the maps haven't changed. | 1390 // Check that the maps haven't changed. |
1184 Register reg = | 1391 Register reg = |
1185 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, | 1392 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, |
1186 name, miss); | 1393 name, miss); |
1187 GenerateFastPropertyLoad(masm(), r0, reg, holder, index); | 1394 GenerateFastPropertyLoad(masm(), r0, reg, Handle<JSObject>(holder), index); |
1188 __ Ret(); | 1395 __ Ret(); |
1189 } | 1396 } |
1190 | 1397 |
1191 | 1398 |
1192 void StubCompiler::GenerateLoadConstant(JSObject* object, | 1399 void StubCompiler::GenerateLoadConstant(JSObject* object, |
1193 JSObject* holder, | 1400 JSObject* holder, |
1194 Register receiver, | 1401 Register receiver, |
1195 Register scratch1, | 1402 Register scratch1, |
1196 Register scratch2, | 1403 Register scratch2, |
1197 Register scratch3, | 1404 Register scratch3, |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1358 scratch2, | 1565 scratch2, |
1359 scratch3, | 1566 scratch3, |
1360 name, | 1567 name, |
1361 miss); | 1568 miss); |
1362 } | 1569 } |
1363 | 1570 |
1364 if (lookup->type() == FIELD) { | 1571 if (lookup->type() == FIELD) { |
1365 // We found FIELD property in prototype chain of interceptor's holder. | 1572 // We found FIELD property in prototype chain of interceptor's holder. |
1366 // Retrieve a field from field's holder. | 1573 // Retrieve a field from field's holder. |
1367 GenerateFastPropertyLoad(masm(), r0, holder_reg, | 1574 GenerateFastPropertyLoad(masm(), r0, holder_reg, |
1368 lookup->holder(), lookup->GetFieldIndex()); | 1575 Handle<JSObject>(lookup->holder()), |
1576 lookup->GetFieldIndex()); | |
1369 __ Ret(); | 1577 __ Ret(); |
1370 } else { | 1578 } else { |
1371 // We found CALLBACKS property in prototype chain of interceptor's | 1579 // We found CALLBACKS property in prototype chain of interceptor's |
1372 // holder. | 1580 // holder. |
1373 ASSERT(lookup->type() == CALLBACKS); | 1581 ASSERT(lookup->type() == CALLBACKS); |
1374 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); | 1582 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); |
1375 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); | 1583 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); |
1376 ASSERT(callback != NULL); | 1584 ASSERT(callback != NULL); |
1377 ASSERT(callback->getter() != NULL); | 1585 ASSERT(callback->getter() != NULL); |
1378 | 1586 |
(...skipping 30 matching lines...) Expand all Loading... | |
1409 name_reg, interceptor_holder); | 1617 name_reg, interceptor_holder); |
1410 | 1618 |
1411 ExternalReference ref = | 1619 ExternalReference ref = |
1412 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), | 1620 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), |
1413 masm()->isolate()); | 1621 masm()->isolate()); |
1414 __ TailCallExternalReference(ref, 5, 1); | 1622 __ TailCallExternalReference(ref, 5, 1); |
1415 } | 1623 } |
1416 } | 1624 } |
1417 | 1625 |
1418 | 1626 |
1419 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { | 1627 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { |
1420 if (kind_ == Code::KEYED_CALL_IC) { | 1628 if (kind_ == Code::KEYED_CALL_IC) { |
1421 __ cmp(r2, Operand(Handle<String>(name))); | 1629 __ cmp(r2, Operand(name)); |
1422 __ b(ne, miss); | 1630 __ b(ne, miss); |
1423 } | 1631 } |
1424 } | 1632 } |
1425 | 1633 |
1426 | 1634 |
1427 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, | 1635 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, |
1428 JSObject* holder, | 1636 JSObject* holder, |
1429 String* name, | 1637 String* name, |
1430 Label* miss) { | 1638 Label* miss) { |
1431 ASSERT(holder->IsGlobalObject()); | 1639 ASSERT(holder->IsGlobalObject()); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1471 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 1679 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
1472 __ cmp(r4, r3); | 1680 __ cmp(r4, r3); |
1473 __ b(ne, miss); | 1681 __ b(ne, miss); |
1474 } else { | 1682 } else { |
1475 __ cmp(r1, Operand(Handle<JSFunction>(function))); | 1683 __ cmp(r1, Operand(Handle<JSFunction>(function))); |
1476 __ b(ne, miss); | 1684 __ b(ne, miss); |
1477 } | 1685 } |
1478 } | 1686 } |
1479 | 1687 |
1480 | 1688 |
1481 MaybeObject* CallStubCompiler::GenerateMissBranch() { | 1689 void CallStubCompiler::GenerateMissBranch() { |
1690 Handle<Code> code = | |
1691 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | |
1692 kind_, | |
1693 extra_state_); | |
1694 __ Jump(code, RelocInfo::CODE_TARGET); | |
1695 } | |
1696 | |
1697 | |
1698 // TODO(kmillikin): Eliminate this function when the stub cache is fully | |
1699 // handlified. | |
1700 MaybeObject* CallStubCompiler::TryGenerateMissBranch() { | |
1482 MaybeObject* maybe_obj = | 1701 MaybeObject* maybe_obj = |
1483 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), | 1702 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), |
1484 kind_, | 1703 kind_, |
1485 extra_state_); | 1704 extra_state_); |
1486 Object* obj; | 1705 Object* obj; |
1487 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1706 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1488 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1707 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
1489 return obj; | 1708 return obj; |
1490 } | 1709 } |
1491 | 1710 |
1492 | 1711 |
1493 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, | 1712 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
Kevin Millikin (Chromium)
2011/10/24 15:55:12
This function is the only stub compiler one that w
| |
1494 JSObject* holder, | 1713 Handle<JSObject> holder, |
1495 int index, | 1714 int index, |
1496 String* name) { | 1715 Handle<String> name) { |
1497 // ----------- S t a t e ------------- | 1716 // ----------- S t a t e ------------- |
1498 // -- r2 : name | 1717 // -- r2 : name |
1499 // -- lr : return address | 1718 // -- lr : return address |
1500 // ----------------------------------- | 1719 // ----------------------------------- |
1501 Label miss; | 1720 Label miss; |
1502 | 1721 |
1503 GenerateNameCheck(name, &miss); | 1722 GenerateNameCheck(name, &miss); |
1504 | 1723 |
1505 const int argc = arguments().immediate(); | 1724 const int argc = arguments().immediate(); |
1506 | 1725 |
1507 // Get the receiver of the function from the stack into r0. | 1726 // Get the receiver of the function from the stack into r0. |
1508 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 1727 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
1509 // Check that the receiver isn't a smi. | 1728 // Check that the receiver isn't a smi. |
1510 __ JumpIfSmi(r0, &miss); | 1729 __ JumpIfSmi(r0, &miss); |
1511 | 1730 |
1512 // Do the right check and compute the holder register. | 1731 // Do the right check and compute the holder register. |
1513 Register reg = CheckPrototypes(object, r0, holder, r1, r3, r4, name, &miss); | 1732 Register reg = CheckPrototypes(object, r0, holder, r1, r3, r4, name, &miss); |
1514 GenerateFastPropertyLoad(masm(), r1, reg, holder, index); | 1733 GenerateFastPropertyLoad(masm(), r1, reg, holder, index); |
1515 | 1734 |
1516 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 1735 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); |
1517 | 1736 |
1518 // Handle call cache miss. | 1737 // Handle call cache miss. |
1519 __ bind(&miss); | 1738 __ bind(&miss); |
1520 MaybeObject* maybe_result = GenerateMissBranch(); | 1739 GenerateMissBranch(); |
1521 if (maybe_result->IsFailure()) return maybe_result; | |
1522 | 1740 |
1523 // Return the generated code. | 1741 // Return the generated code. |
1524 return GetCode(FIELD, name); | 1742 return GetCode(FIELD, name); |
1525 } | 1743 } |
1526 | 1744 |
1527 | 1745 |
1528 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, | 1746 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, |
1529 JSObject* holder, | 1747 JSObject* holder, |
1530 JSGlobalPropertyCell* cell, | 1748 JSGlobalPropertyCell* cell, |
1531 JSFunction* function, | 1749 JSFunction* function, |
1532 String* name) { | 1750 String* name) { |
1533 // ----------- S t a t e ------------- | 1751 // ----------- S t a t e ------------- |
1534 // -- r2 : name | 1752 // -- r2 : name |
1535 // -- lr : return address | 1753 // -- lr : return address |
1536 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 1754 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
1537 // -- ... | 1755 // -- ... |
1538 // -- sp[argc * 4] : receiver | 1756 // -- sp[argc * 4] : receiver |
1539 // ----------------------------------- | 1757 // ----------------------------------- |
1540 | 1758 |
1541 // If object is not an array, bail out to regular call. | 1759 // If object is not an array, bail out to regular call. |
1542 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 1760 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); |
1543 | 1761 |
1544 Label miss; | 1762 Label miss; |
1545 | 1763 |
1546 GenerateNameCheck(name, &miss); | 1764 GenerateNameCheck(Handle<String>(name), &miss); |
1547 | 1765 |
1548 Register receiver = r1; | 1766 Register receiver = r1; |
1549 | 1767 |
1550 // Get the receiver from the stack | 1768 // Get the receiver from the stack |
1551 const int argc = arguments().immediate(); | 1769 const int argc = arguments().immediate(); |
1552 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | 1770 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
1553 | 1771 |
1554 // Check that the receiver isn't a smi. | 1772 // Check that the receiver isn't a smi. |
1555 __ JumpIfSmi(receiver, &miss); | 1773 __ JumpIfSmi(receiver, &miss); |
1556 | 1774 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1702 } | 1920 } |
1703 __ bind(&call_builtin); | 1921 __ bind(&call_builtin); |
1704 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, | 1922 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, |
1705 masm()->isolate()), | 1923 masm()->isolate()), |
1706 argc + 1, | 1924 argc + 1, |
1707 1); | 1925 1); |
1708 } | 1926 } |
1709 | 1927 |
1710 // Handle call cache miss. | 1928 // Handle call cache miss. |
1711 __ bind(&miss); | 1929 __ bind(&miss); |
1712 MaybeObject* maybe_result = GenerateMissBranch(); | 1930 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1713 if (maybe_result->IsFailure()) return maybe_result; | 1931 if (maybe_result->IsFailure()) return maybe_result; |
1714 | 1932 |
1715 // Return the generated code. | 1933 // Return the generated code. |
1716 return GetCode(function); | 1934 return TryGetCode(function); |
1717 } | 1935 } |
1718 | 1936 |
1719 | 1937 |
1720 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, | 1938 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, |
1721 JSObject* holder, | 1939 JSObject* holder, |
1722 JSGlobalPropertyCell* cell, | 1940 JSGlobalPropertyCell* cell, |
1723 JSFunction* function, | 1941 JSFunction* function, |
1724 String* name) { | 1942 String* name) { |
1725 // ----------- S t a t e ------------- | 1943 // ----------- S t a t e ------------- |
1726 // -- r2 : name | 1944 // -- r2 : name |
1727 // -- lr : return address | 1945 // -- lr : return address |
1728 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 1946 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
1729 // -- ... | 1947 // -- ... |
1730 // -- sp[argc * 4] : receiver | 1948 // -- sp[argc * 4] : receiver |
1731 // ----------------------------------- | 1949 // ----------------------------------- |
1732 | 1950 |
1733 // If object is not an array, bail out to regular call. | 1951 // If object is not an array, bail out to regular call. |
1734 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 1952 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); |
1735 | 1953 |
1736 Label miss, return_undefined, call_builtin; | 1954 Label miss, return_undefined, call_builtin; |
1737 | 1955 |
1738 Register receiver = r1; | 1956 Register receiver = r1; |
1739 Register elements = r3; | 1957 Register elements = r3; |
1740 | 1958 |
1741 GenerateNameCheck(name, &miss); | 1959 GenerateNameCheck(Handle<String>(name), &miss); |
1742 | 1960 |
1743 // Get the receiver from the stack | 1961 // Get the receiver from the stack |
1744 const int argc = arguments().immediate(); | 1962 const int argc = arguments().immediate(); |
1745 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | 1963 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
1746 | 1964 |
1747 // Check that the receiver isn't a smi. | 1965 // Check that the receiver isn't a smi. |
1748 __ JumpIfSmi(receiver, &miss); | 1966 __ JumpIfSmi(receiver, &miss); |
1749 | 1967 |
1750 // Check that the maps haven't changed. | 1968 // Check that the maps haven't changed. |
1751 CheckPrototypes(JSObject::cast(object), | 1969 CheckPrototypes(JSObject::cast(object), |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1791 __ Ret(); | 2009 __ Ret(); |
1792 | 2010 |
1793 __ bind(&call_builtin); | 2011 __ bind(&call_builtin); |
1794 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop, | 2012 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop, |
1795 masm()->isolate()), | 2013 masm()->isolate()), |
1796 argc + 1, | 2014 argc + 1, |
1797 1); | 2015 1); |
1798 | 2016 |
1799 // Handle call cache miss. | 2017 // Handle call cache miss. |
1800 __ bind(&miss); | 2018 __ bind(&miss); |
1801 MaybeObject* maybe_result = GenerateMissBranch(); | 2019 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1802 if (maybe_result->IsFailure()) return maybe_result; | 2020 if (maybe_result->IsFailure()) return maybe_result; |
1803 | 2021 |
1804 // Return the generated code. | 2022 // Return the generated code. |
1805 return GetCode(function); | 2023 return TryGetCode(function); |
1806 } | 2024 } |
1807 | 2025 |
1808 | 2026 |
1809 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( | 2027 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( |
1810 Object* object, | 2028 Object* object, |
1811 JSObject* holder, | 2029 JSObject* holder, |
1812 JSGlobalPropertyCell* cell, | 2030 JSGlobalPropertyCell* cell, |
1813 JSFunction* function, | 2031 JSFunction* function, |
1814 String* name) { | 2032 String* name) { |
1815 // ----------- S t a t e ------------- | 2033 // ----------- S t a t e ------------- |
(...skipping 13 matching lines...) Expand all Loading... | |
1829 Label name_miss; | 2047 Label name_miss; |
1830 Label index_out_of_range; | 2048 Label index_out_of_range; |
1831 Label* index_out_of_range_label = &index_out_of_range; | 2049 Label* index_out_of_range_label = &index_out_of_range; |
1832 | 2050 |
1833 if (kind_ == Code::CALL_IC && | 2051 if (kind_ == Code::CALL_IC && |
1834 (CallICBase::StringStubState::decode(extra_state_) == | 2052 (CallICBase::StringStubState::decode(extra_state_) == |
1835 DEFAULT_STRING_STUB)) { | 2053 DEFAULT_STRING_STUB)) { |
1836 index_out_of_range_label = &miss; | 2054 index_out_of_range_label = &miss; |
1837 } | 2055 } |
1838 | 2056 |
1839 GenerateNameCheck(name, &name_miss); | 2057 GenerateNameCheck(Handle<String>(name), &name_miss); |
1840 | 2058 |
1841 // Check that the maps starting from the prototype haven't changed. | 2059 // Check that the maps starting from the prototype haven't changed. |
1842 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2060 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1843 Context::STRING_FUNCTION_INDEX, | 2061 Context::STRING_FUNCTION_INDEX, |
1844 r0, | 2062 r0, |
1845 &miss); | 2063 &miss); |
1846 ASSERT(object != holder); | 2064 ASSERT(object != holder); |
1847 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, | 2065 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, |
1848 r1, r3, r4, name, &miss); | 2066 r1, r3, r4, name, &miss); |
1849 | 2067 |
(...skipping 27 matching lines...) Expand all Loading... | |
1877 __ bind(&index_out_of_range); | 2095 __ bind(&index_out_of_range); |
1878 __ LoadRoot(r0, Heap::kNanValueRootIndex); | 2096 __ LoadRoot(r0, Heap::kNanValueRootIndex); |
1879 __ Drop(argc + 1); | 2097 __ Drop(argc + 1); |
1880 __ Ret(); | 2098 __ Ret(); |
1881 } | 2099 } |
1882 | 2100 |
1883 __ bind(&miss); | 2101 __ bind(&miss); |
1884 // Restore function name in r2. | 2102 // Restore function name in r2. |
1885 __ Move(r2, Handle<String>(name)); | 2103 __ Move(r2, Handle<String>(name)); |
1886 __ bind(&name_miss); | 2104 __ bind(&name_miss); |
1887 MaybeObject* maybe_result = GenerateMissBranch(); | 2105 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1888 if (maybe_result->IsFailure()) return maybe_result; | 2106 if (maybe_result->IsFailure()) return maybe_result; |
1889 | 2107 |
1890 // Return the generated code. | 2108 // Return the generated code. |
1891 return GetCode(function); | 2109 return TryGetCode(function); |
1892 } | 2110 } |
1893 | 2111 |
1894 | 2112 |
1895 MaybeObject* CallStubCompiler::CompileStringCharAtCall( | 2113 MaybeObject* CallStubCompiler::CompileStringCharAtCall( |
1896 Object* object, | 2114 Object* object, |
1897 JSObject* holder, | 2115 JSObject* holder, |
1898 JSGlobalPropertyCell* cell, | 2116 JSGlobalPropertyCell* cell, |
1899 JSFunction* function, | 2117 JSFunction* function, |
1900 String* name) { | 2118 String* name) { |
1901 // ----------- S t a t e ------------- | 2119 // ----------- S t a t e ------------- |
(...skipping 13 matching lines...) Expand all Loading... | |
1915 Label name_miss; | 2133 Label name_miss; |
1916 Label index_out_of_range; | 2134 Label index_out_of_range; |
1917 Label* index_out_of_range_label = &index_out_of_range; | 2135 Label* index_out_of_range_label = &index_out_of_range; |
1918 | 2136 |
1919 if (kind_ == Code::CALL_IC && | 2137 if (kind_ == Code::CALL_IC && |
1920 (CallICBase::StringStubState::decode(extra_state_) == | 2138 (CallICBase::StringStubState::decode(extra_state_) == |
1921 DEFAULT_STRING_STUB)) { | 2139 DEFAULT_STRING_STUB)) { |
1922 index_out_of_range_label = &miss; | 2140 index_out_of_range_label = &miss; |
1923 } | 2141 } |
1924 | 2142 |
1925 GenerateNameCheck(name, &name_miss); | 2143 GenerateNameCheck(Handle<String>(name), &name_miss); |
1926 | 2144 |
1927 // Check that the maps starting from the prototype haven't changed. | 2145 // Check that the maps starting from the prototype haven't changed. |
1928 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2146 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1929 Context::STRING_FUNCTION_INDEX, | 2147 Context::STRING_FUNCTION_INDEX, |
1930 r0, | 2148 r0, |
1931 &miss); | 2149 &miss); |
1932 ASSERT(object != holder); | 2150 ASSERT(object != holder); |
1933 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, | 2151 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, |
1934 r1, r3, r4, name, &miss); | 2152 r1, r3, r4, name, &miss); |
1935 | 2153 |
(...skipping 29 matching lines...) Expand all Loading... | |
1965 __ bind(&index_out_of_range); | 2183 __ bind(&index_out_of_range); |
1966 __ LoadRoot(r0, Heap::kEmptyStringRootIndex); | 2184 __ LoadRoot(r0, Heap::kEmptyStringRootIndex); |
1967 __ Drop(argc + 1); | 2185 __ Drop(argc + 1); |
1968 __ Ret(); | 2186 __ Ret(); |
1969 } | 2187 } |
1970 | 2188 |
1971 __ bind(&miss); | 2189 __ bind(&miss); |
1972 // Restore function name in r2. | 2190 // Restore function name in r2. |
1973 __ Move(r2, Handle<String>(name)); | 2191 __ Move(r2, Handle<String>(name)); |
1974 __ bind(&name_miss); | 2192 __ bind(&name_miss); |
1975 MaybeObject* maybe_result = GenerateMissBranch(); | 2193 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1976 if (maybe_result->IsFailure()) return maybe_result; | 2194 if (maybe_result->IsFailure()) return maybe_result; |
1977 | 2195 |
1978 // Return the generated code. | 2196 // Return the generated code. |
1979 return GetCode(function); | 2197 return TryGetCode(function); |
1980 } | 2198 } |
1981 | 2199 |
1982 | 2200 |
1983 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( | 2201 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( |
1984 Object* object, | 2202 Object* object, |
1985 JSObject* holder, | 2203 JSObject* holder, |
1986 JSGlobalPropertyCell* cell, | 2204 JSGlobalPropertyCell* cell, |
1987 JSFunction* function, | 2205 JSFunction* function, |
1988 String* name) { | 2206 String* name) { |
1989 // ----------- S t a t e ------------- | 2207 // ----------- S t a t e ------------- |
1990 // -- r2 : function name | 2208 // -- r2 : function name |
1991 // -- lr : return address | 2209 // -- lr : return address |
1992 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2210 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
1993 // -- ... | 2211 // -- ... |
1994 // -- sp[argc * 4] : receiver | 2212 // -- sp[argc * 4] : receiver |
1995 // ----------------------------------- | 2213 // ----------------------------------- |
1996 | 2214 |
1997 const int argc = arguments().immediate(); | 2215 const int argc = arguments().immediate(); |
1998 | 2216 |
1999 // If the object is not a JSObject or we got an unexpected number of | 2217 // If the object is not a JSObject or we got an unexpected number of |
2000 // arguments, bail out to the regular call. | 2218 // arguments, bail out to the regular call. |
2001 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2219 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
2002 | 2220 |
2003 Label miss; | 2221 Label miss; |
2004 GenerateNameCheck(name, &miss); | 2222 GenerateNameCheck(Handle<String>(name), &miss); |
2005 | 2223 |
2006 if (cell == NULL) { | 2224 if (cell == NULL) { |
2007 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); | 2225 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); |
2008 | 2226 |
2009 STATIC_ASSERT(kSmiTag == 0); | 2227 STATIC_ASSERT(kSmiTag == 0); |
2010 __ JumpIfSmi(r1, &miss); | 2228 __ JumpIfSmi(r1, &miss); |
2011 | 2229 |
2012 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, | 2230 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
2013 &miss); | 2231 &miss); |
2014 } else { | 2232 } else { |
(...skipping 22 matching lines...) Expand all Loading... | |
2037 StubRuntimeCallHelper call_helper; | 2255 StubRuntimeCallHelper call_helper; |
2038 char_from_code_generator.GenerateSlow(masm(), call_helper); | 2256 char_from_code_generator.GenerateSlow(masm(), call_helper); |
2039 | 2257 |
2040 // Tail call the full function. We do not have to patch the receiver | 2258 // Tail call the full function. We do not have to patch the receiver |
2041 // because the function makes no use of it. | 2259 // because the function makes no use of it. |
2042 __ bind(&slow); | 2260 __ bind(&slow); |
2043 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2261 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
2044 | 2262 |
2045 __ bind(&miss); | 2263 __ bind(&miss); |
2046 // r2: function name. | 2264 // r2: function name. |
2047 MaybeObject* maybe_result = GenerateMissBranch(); | 2265 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2048 if (maybe_result->IsFailure()) return maybe_result; | 2266 if (maybe_result->IsFailure()) return maybe_result; |
2049 | 2267 |
2050 // Return the generated code. | 2268 // Return the generated code. |
2051 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2269 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
2052 } | 2270 } |
2053 | 2271 |
2054 | 2272 |
2055 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, | 2273 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, |
2056 JSObject* holder, | 2274 JSObject* holder, |
2057 JSGlobalPropertyCell* cell, | 2275 JSGlobalPropertyCell* cell, |
2058 JSFunction* function, | 2276 JSFunction* function, |
2059 String* name) { | 2277 String* name) { |
2060 // ----------- S t a t e ------------- | 2278 // ----------- S t a t e ------------- |
2061 // -- r2 : function name | 2279 // -- r2 : function name |
2062 // -- lr : return address | 2280 // -- lr : return address |
2063 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2281 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
2064 // -- ... | 2282 // -- ... |
2065 // -- sp[argc * 4] : receiver | 2283 // -- sp[argc * 4] : receiver |
2066 // ----------------------------------- | 2284 // ----------------------------------- |
2067 | 2285 |
2068 if (!CpuFeatures::IsSupported(VFP3)) { | 2286 if (!CpuFeatures::IsSupported(VFP3)) { |
2069 return heap()->undefined_value(); | 2287 return heap()->undefined_value(); |
2070 } | 2288 } |
2071 | 2289 |
2072 CpuFeatures::Scope scope_vfp3(VFP3); | 2290 CpuFeatures::Scope scope_vfp3(VFP3); |
2073 | 2291 |
2074 const int argc = arguments().immediate(); | 2292 const int argc = arguments().immediate(); |
2075 | 2293 |
2076 // If the object is not a JSObject or we got an unexpected number of | 2294 // If the object is not a JSObject or we got an unexpected number of |
2077 // arguments, bail out to the regular call. | 2295 // arguments, bail out to the regular call. |
2078 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2296 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
2079 | 2297 |
2080 Label miss, slow; | 2298 Label miss, slow; |
2081 GenerateNameCheck(name, &miss); | 2299 GenerateNameCheck(Handle<String>(name), &miss); |
2082 | 2300 |
2083 if (cell == NULL) { | 2301 if (cell == NULL) { |
2084 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); | 2302 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); |
2085 | 2303 |
2086 STATIC_ASSERT(kSmiTag == 0); | 2304 STATIC_ASSERT(kSmiTag == 0); |
2087 __ JumpIfSmi(r1, &miss); | 2305 __ JumpIfSmi(r1, &miss); |
2088 | 2306 |
2089 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, | 2307 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
2090 &miss); | 2308 &miss); |
2091 } else { | 2309 } else { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2185 // Restore FPCSR and fall to slow case. | 2403 // Restore FPCSR and fall to slow case. |
2186 __ vmsr(r3); | 2404 __ vmsr(r3); |
2187 | 2405 |
2188 __ bind(&slow); | 2406 __ bind(&slow); |
2189 // Tail call the full function. We do not have to patch the receiver | 2407 // Tail call the full function. We do not have to patch the receiver |
2190 // because the function makes no use of it. | 2408 // because the function makes no use of it. |
2191 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2409 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
2192 | 2410 |
2193 __ bind(&miss); | 2411 __ bind(&miss); |
2194 // r2: function name. | 2412 // r2: function name. |
2195 MaybeObject* maybe_result = GenerateMissBranch(); | 2413 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2196 if (maybe_result->IsFailure()) return maybe_result; | 2414 if (maybe_result->IsFailure()) return maybe_result; |
2197 | 2415 |
2198 // Return the generated code. | 2416 // Return the generated code. |
2199 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2417 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
2200 } | 2418 } |
2201 | 2419 |
2202 | 2420 |
2203 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, | 2421 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, |
2204 JSObject* holder, | 2422 JSObject* holder, |
2205 JSGlobalPropertyCell* cell, | 2423 JSGlobalPropertyCell* cell, |
2206 JSFunction* function, | 2424 JSFunction* function, |
2207 String* name) { | 2425 String* name) { |
2208 // ----------- S t a t e ------------- | 2426 // ----------- S t a t e ------------- |
2209 // -- r2 : function name | 2427 // -- r2 : function name |
2210 // -- lr : return address | 2428 // -- lr : return address |
2211 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2429 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
2212 // -- ... | 2430 // -- ... |
2213 // -- sp[argc * 4] : receiver | 2431 // -- sp[argc * 4] : receiver |
2214 // ----------------------------------- | 2432 // ----------------------------------- |
2215 | 2433 |
2216 const int argc = arguments().immediate(); | 2434 const int argc = arguments().immediate(); |
2217 | 2435 |
2218 // If the object is not a JSObject or we got an unexpected number of | 2436 // If the object is not a JSObject or we got an unexpected number of |
2219 // arguments, bail out to the regular call. | 2437 // arguments, bail out to the regular call. |
2220 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2438 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
2221 | 2439 |
2222 Label miss; | 2440 Label miss; |
2223 GenerateNameCheck(name, &miss); | 2441 GenerateNameCheck(Handle<String>(name), &miss); |
2224 | 2442 |
2225 if (cell == NULL) { | 2443 if (cell == NULL) { |
2226 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); | 2444 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); |
2227 | 2445 |
2228 STATIC_ASSERT(kSmiTag == 0); | 2446 STATIC_ASSERT(kSmiTag == 0); |
2229 __ JumpIfSmi(r1, &miss); | 2447 __ JumpIfSmi(r1, &miss); |
2230 | 2448 |
2231 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, | 2449 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
2232 &miss); | 2450 &miss); |
2233 } else { | 2451 } else { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2286 __ Drop(argc + 1); | 2504 __ Drop(argc + 1); |
2287 __ Ret(); | 2505 __ Ret(); |
2288 | 2506 |
2289 // Tail call the full function. We do not have to patch the receiver | 2507 // Tail call the full function. We do not have to patch the receiver |
2290 // because the function makes no use of it. | 2508 // because the function makes no use of it. |
2291 __ bind(&slow); | 2509 __ bind(&slow); |
2292 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2510 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
2293 | 2511 |
2294 __ bind(&miss); | 2512 __ bind(&miss); |
2295 // r2: function name. | 2513 // r2: function name. |
2296 MaybeObject* maybe_result = GenerateMissBranch(); | 2514 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2297 if (maybe_result->IsFailure()) return maybe_result; | 2515 if (maybe_result->IsFailure()) return maybe_result; |
2298 | 2516 |
2299 // Return the generated code. | 2517 // Return the generated code. |
2300 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2518 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
2301 } | 2519 } |
2302 | 2520 |
2303 | 2521 |
2304 MaybeObject* CallStubCompiler::CompileFastApiCall( | 2522 MaybeObject* CallStubCompiler::CompileFastApiCall( |
2305 const CallOptimization& optimization, | 2523 const CallOptimization& optimization, |
2306 Object* object, | 2524 Object* object, |
2307 JSObject* holder, | 2525 JSObject* holder, |
2308 JSGlobalPropertyCell* cell, | 2526 JSGlobalPropertyCell* cell, |
2309 JSFunction* function, | 2527 JSFunction* function, |
2310 String* name) { | 2528 String* name) { |
2311 Counters* counters = isolate()->counters(); | 2529 Counters* counters = isolate()->counters(); |
2312 | 2530 |
2313 ASSERT(optimization.is_simple_api_call()); | 2531 ASSERT(optimization.is_simple_api_call()); |
2314 // Bail out if object is a global object as we don't want to | 2532 // Bail out if object is a global object as we don't want to |
2315 // repatch it to global receiver. | 2533 // repatch it to global receiver. |
2316 if (object->IsGlobalObject()) return heap()->undefined_value(); | 2534 if (object->IsGlobalObject()) return heap()->undefined_value(); |
2317 if (cell != NULL) return heap()->undefined_value(); | 2535 if (cell != NULL) return heap()->undefined_value(); |
2318 if (!object->IsJSObject()) return heap()->undefined_value(); | 2536 if (!object->IsJSObject()) return heap()->undefined_value(); |
2319 int depth = optimization.GetPrototypeDepthOfExpectedType( | 2537 int depth = optimization.GetPrototypeDepthOfExpectedType( |
2320 JSObject::cast(object), holder); | 2538 JSObject::cast(object), holder); |
2321 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); | 2539 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); |
2322 | 2540 |
2323 Label miss, miss_before_stack_reserved; | 2541 Label miss, miss_before_stack_reserved; |
2324 | 2542 |
2325 GenerateNameCheck(name, &miss_before_stack_reserved); | 2543 GenerateNameCheck(Handle<String>(name), &miss_before_stack_reserved); |
2326 | 2544 |
2327 // Get the receiver from the stack. | 2545 // Get the receiver from the stack. |
2328 const int argc = arguments().immediate(); | 2546 const int argc = arguments().immediate(); |
2329 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2547 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
2330 | 2548 |
2331 // Check that the receiver isn't a smi. | 2549 // Check that the receiver isn't a smi. |
2332 __ JumpIfSmi(r1, &miss_before_stack_reserved); | 2550 __ JumpIfSmi(r1, &miss_before_stack_reserved); |
2333 | 2551 |
2334 __ IncrementCounter(counters->call_const(), 1, r0, r3); | 2552 __ IncrementCounter(counters->call_const(), 1, r0, r3); |
2335 __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3); | 2553 __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3); |
2336 | 2554 |
2337 ReserveSpaceForFastApiCall(masm(), r0); | 2555 ReserveSpaceForFastApiCall(masm(), r0); |
2338 | 2556 |
2339 // Check that the maps haven't changed and find a Holder as a side effect. | 2557 // Check that the maps haven't changed and find a Holder as a side effect. |
2340 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, | 2558 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
2341 depth, &miss); | 2559 depth, &miss); |
2342 | 2560 |
2343 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); | 2561 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); |
2344 if (result->IsFailure()) return result; | 2562 if (result->IsFailure()) return result; |
2345 | 2563 |
2346 __ bind(&miss); | 2564 __ bind(&miss); |
2347 FreeSpaceForFastApiCall(masm()); | 2565 FreeSpaceForFastApiCall(masm()); |
2348 | 2566 |
2349 __ bind(&miss_before_stack_reserved); | 2567 __ bind(&miss_before_stack_reserved); |
2350 MaybeObject* maybe_result = GenerateMissBranch(); | 2568 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2351 if (maybe_result->IsFailure()) return maybe_result; | 2569 if (maybe_result->IsFailure()) return maybe_result; |
2352 | 2570 |
2353 // Return the generated code. | 2571 // Return the generated code. |
2354 return GetCode(function); | 2572 return TryGetCode(function); |
2355 } | 2573 } |
2356 | 2574 |
2357 | 2575 |
2358 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, | 2576 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, |
2359 JSObject* holder, | 2577 JSObject* holder, |
2360 JSFunction* function, | 2578 JSFunction* function, |
2361 String* name, | 2579 String* name, |
2362 CheckType check) { | 2580 CheckType check) { |
2363 // ----------- S t a t e ------------- | 2581 // ----------- S t a t e ------------- |
2364 // -- r2 : name | 2582 // -- r2 : name |
2365 // -- lr : return address | 2583 // -- lr : return address |
2366 // ----------------------------------- | 2584 // ----------------------------------- |
2367 if (HasCustomCallGenerator(function)) { | 2585 if (HasCustomCallGenerator(function)) { |
2368 MaybeObject* maybe_result = CompileCustomCall( | 2586 MaybeObject* maybe_result = CompileCustomCall( |
2369 object, holder, NULL, function, name); | 2587 object, holder, NULL, function, name); |
2370 Object* result; | 2588 Object* result; |
2371 if (!maybe_result->ToObject(&result)) return maybe_result; | 2589 if (!maybe_result->ToObject(&result)) return maybe_result; |
2372 // undefined means bail out to regular compiler. | 2590 // undefined means bail out to regular compiler. |
2373 if (!result->IsUndefined()) return result; | 2591 if (!result->IsUndefined()) return result; |
2374 } | 2592 } |
2375 | 2593 |
2376 Label miss; | 2594 Label miss; |
2377 | 2595 |
2378 GenerateNameCheck(name, &miss); | 2596 GenerateNameCheck(Handle<String>(name), &miss); |
2379 | 2597 |
2380 // Get the receiver from the stack | 2598 // Get the receiver from the stack |
2381 const int argc = arguments().immediate(); | 2599 const int argc = arguments().immediate(); |
2382 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2600 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
2383 | 2601 |
2384 // Check that the receiver isn't a smi. | 2602 // Check that the receiver isn't a smi. |
2385 if (check != NUMBER_CHECK) { | 2603 if (check != NUMBER_CHECK) { |
2386 __ JumpIfSmi(r1, &miss); | 2604 __ JumpIfSmi(r1, &miss); |
2387 } | 2605 } |
2388 | 2606 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2474 UNREACHABLE(); | 2692 UNREACHABLE(); |
2475 } | 2693 } |
2476 | 2694 |
2477 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2695 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
2478 ? CALL_AS_FUNCTION | 2696 ? CALL_AS_FUNCTION |
2479 : CALL_AS_METHOD; | 2697 : CALL_AS_METHOD; |
2480 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); | 2698 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); |
2481 | 2699 |
2482 // Handle call cache miss. | 2700 // Handle call cache miss. |
2483 __ bind(&miss); | 2701 __ bind(&miss); |
2484 MaybeObject* maybe_result = GenerateMissBranch(); | 2702 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2485 if (maybe_result->IsFailure()) return maybe_result; | 2703 if (maybe_result->IsFailure()) return maybe_result; |
2486 | 2704 |
2487 // Return the generated code. | 2705 // Return the generated code. |
2488 return GetCode(function); | 2706 return TryGetCode(function); |
2489 } | 2707 } |
2490 | 2708 |
2491 | 2709 |
2492 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, | 2710 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, |
2493 JSObject* holder, | 2711 JSObject* holder, |
2494 String* name) { | 2712 String* name) { |
2495 // ----------- S t a t e ------------- | 2713 // ----------- S t a t e ------------- |
2496 // -- r2 : name | 2714 // -- r2 : name |
2497 // -- lr : return address | 2715 // -- lr : return address |
2498 // ----------------------------------- | 2716 // ----------------------------------- |
2499 | 2717 |
2500 Label miss; | 2718 Label miss; |
2501 | 2719 |
2502 GenerateNameCheck(name, &miss); | 2720 GenerateNameCheck(Handle<String>(name), &miss); |
2503 | 2721 |
2504 // Get the number of arguments. | 2722 // Get the number of arguments. |
2505 const int argc = arguments().immediate(); | 2723 const int argc = arguments().immediate(); |
2506 | 2724 |
2507 LookupResult lookup(isolate()); | 2725 LookupResult lookup(isolate()); |
2508 LookupPostInterceptor(holder, name, &lookup); | 2726 LookupPostInterceptor(holder, name, &lookup); |
2509 | 2727 |
2510 // Get the receiver from the stack. | 2728 // Get the receiver from the stack. |
2511 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2729 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
2512 | 2730 |
(...skipping 10 matching lines...) Expand all Loading... | |
2523 &miss); | 2741 &miss); |
2524 if (result->IsFailure()) { | 2742 if (result->IsFailure()) { |
2525 return result; | 2743 return result; |
2526 } | 2744 } |
2527 | 2745 |
2528 // Move returned value, the function to call, to r1. | 2746 // Move returned value, the function to call, to r1. |
2529 __ mov(r1, r0); | 2747 __ mov(r1, r0); |
2530 // Restore receiver. | 2748 // Restore receiver. |
2531 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 2749 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
2532 | 2750 |
2533 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 2751 GenerateCallFunction(masm(), Handle<Object>(object), arguments(), &miss, |
2752 extra_state_); | |
2534 | 2753 |
2535 // Handle call cache miss. | 2754 // Handle call cache miss. |
2536 __ bind(&miss); | 2755 __ bind(&miss); |
2537 MaybeObject* maybe_result = GenerateMissBranch(); | 2756 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2538 if (maybe_result->IsFailure()) return maybe_result; | 2757 if (maybe_result->IsFailure()) return maybe_result; |
2539 | 2758 |
2540 // Return the generated code. | 2759 // Return the generated code. |
2541 return GetCode(INTERCEPTOR, name); | 2760 return TryGetCode(INTERCEPTOR, name); |
2542 } | 2761 } |
2543 | 2762 |
2544 | 2763 |
2545 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, | 2764 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, |
2546 GlobalObject* holder, | 2765 GlobalObject* holder, |
2547 JSGlobalPropertyCell* cell, | 2766 JSGlobalPropertyCell* cell, |
2548 JSFunction* function, | 2767 JSFunction* function, |
2549 String* name) { | 2768 String* name) { |
2550 // ----------- S t a t e ------------- | 2769 // ----------- S t a t e ------------- |
2551 // -- r2 : name | 2770 // -- r2 : name |
2552 // -- lr : return address | 2771 // -- lr : return address |
2553 // ----------------------------------- | 2772 // ----------------------------------- |
2554 | 2773 |
2555 if (HasCustomCallGenerator(function)) { | 2774 if (HasCustomCallGenerator(function)) { |
2556 MaybeObject* maybe_result = CompileCustomCall( | 2775 MaybeObject* maybe_result = CompileCustomCall( |
2557 object, holder, cell, function, name); | 2776 object, holder, cell, function, name); |
2558 Object* result; | 2777 Object* result; |
2559 if (!maybe_result->ToObject(&result)) return maybe_result; | 2778 if (!maybe_result->ToObject(&result)) return maybe_result; |
2560 // undefined means bail out to regular compiler. | 2779 // undefined means bail out to regular compiler. |
2561 if (!result->IsUndefined()) return result; | 2780 if (!result->IsUndefined()) return result; |
2562 } | 2781 } |
2563 | 2782 |
2564 Label miss; | 2783 Label miss; |
2565 | 2784 |
2566 GenerateNameCheck(name, &miss); | 2785 GenerateNameCheck(Handle<String>(name), &miss); |
2567 | 2786 |
2568 // Get the number of arguments. | 2787 // Get the number of arguments. |
2569 const int argc = arguments().immediate(); | 2788 const int argc = arguments().immediate(); |
2570 | 2789 |
2571 GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2790 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
2572 | 2791 |
2573 GenerateLoadFunctionFromCell(cell, function, &miss); | 2792 GenerateLoadFunctionFromCell(cell, function, &miss); |
2574 | 2793 |
2575 // Patch the receiver on the stack with the global proxy if | 2794 // Patch the receiver on the stack with the global proxy if |
2576 // necessary. | 2795 // necessary. |
(...skipping 16 matching lines...) Expand all Loading... | |
2593 // We call indirectly through the code field in the function to | 2812 // We call indirectly through the code field in the function to |
2594 // allow recompilation to take effect without changing any of the | 2813 // allow recompilation to take effect without changing any of the |
2595 // call sites. | 2814 // call sites. |
2596 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | 2815 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
2597 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION, | 2816 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION, |
2598 NullCallWrapper(), call_kind); | 2817 NullCallWrapper(), call_kind); |
2599 | 2818 |
2600 // Handle call cache miss. | 2819 // Handle call cache miss. |
2601 __ bind(&miss); | 2820 __ bind(&miss); |
2602 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3); | 2821 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3); |
2603 MaybeObject* maybe_result = GenerateMissBranch(); | 2822 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2604 if (maybe_result->IsFailure()) return maybe_result; | 2823 if (maybe_result->IsFailure()) return maybe_result; |
2605 | 2824 |
2606 // Return the generated code. | 2825 // Return the generated code. |
2607 return GetCode(NORMAL, name); | 2826 return TryGetCode(NORMAL, name); |
2608 } | 2827 } |
2609 | 2828 |
2610 | 2829 |
2611 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, | 2830 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, |
2612 int index, | 2831 int index, |
2613 Map* transition, | 2832 Map* transition, |
2614 String* name) { | 2833 String* name) { |
2615 // ----------- S t a t e ------------- | 2834 // ----------- S t a t e ------------- |
2616 // -- r0 : value | 2835 // -- r0 : value |
2617 // -- r1 : receiver | 2836 // -- r1 : receiver |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2795 | 3014 |
2796 // Check that receiver is not a smi. | 3015 // Check that receiver is not a smi. |
2797 __ JumpIfSmi(r0, &miss); | 3016 __ JumpIfSmi(r0, &miss); |
2798 | 3017 |
2799 // Check the maps of the full prototype chain. | 3018 // Check the maps of the full prototype chain. |
2800 CheckPrototypes(object, r0, last, r3, r1, r4, name, &miss); | 3019 CheckPrototypes(object, r0, last, r3, r1, r4, name, &miss); |
2801 | 3020 |
2802 // If the last object in the prototype chain is a global object, | 3021 // If the last object in the prototype chain is a global object, |
2803 // check that the global property cell is empty. | 3022 // check that the global property cell is empty. |
2804 if (last->IsGlobalObject()) { | 3023 if (last->IsGlobalObject()) { |
2805 MaybeObject* cell = GenerateCheckPropertyCell(masm(), | 3024 MaybeObject* cell = TryGenerateCheckPropertyCell(masm(), |
2806 GlobalObject::cast(last), | 3025 GlobalObject::cast(last), |
2807 name, | 3026 name, |
2808 r1, | 3027 r1, |
2809 &miss); | 3028 &miss); |
2810 if (cell->IsFailure()) { | 3029 if (cell->IsFailure()) { |
2811 miss.Unuse(); | 3030 miss.Unuse(); |
2812 return cell; | 3031 return cell; |
2813 } | 3032 } |
2814 } | 3033 } |
2815 | 3034 |
2816 // Return undefined if maps of the full prototype chain are still the | 3035 // Return undefined if maps of the full prototype chain are still the |
2817 // same and no global property with this name contains a value. | 3036 // same and no global property with this name contains a value. |
2818 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 3037 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
2819 __ Ret(); | 3038 __ Ret(); |
(...skipping 1634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4454 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 4673 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
4455 __ Jump(ic_miss, RelocInfo::CODE_TARGET); | 4674 __ Jump(ic_miss, RelocInfo::CODE_TARGET); |
4456 } | 4675 } |
4457 | 4676 |
4458 | 4677 |
4459 #undef __ | 4678 #undef __ |
4460 | 4679 |
4461 } } // namespace v8::internal | 4680 } } // namespace v8::internal |
4462 | 4681 |
4463 #endif // V8_TARGET_ARCH_ARM | 4682 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |