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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 // Miss: fall through. | 92 // Miss: fall through. |
93 __ bind(&miss); | 93 __ bind(&miss); |
94 } | 94 } |
95 | 95 |
96 | 96 |
97 // Helper function used to check that the dictionary doesn't contain | 97 // Helper function used to check that the dictionary doesn't contain |
98 // the property. This function may return false negatives, so miss_label | 98 // the property. This function may return false negatives, so miss_label |
99 // must always call a backup property check that is complete. | 99 // must always call a backup property check that is complete. |
100 // This function is safe to call if the receiver has fast properties. | 100 // This function is safe to call if the receiver has fast properties. |
101 // Name must be a symbol and receiver must be a heap object. | 101 // Name must be a symbol and receiver must be a heap object. |
102 MUST_USE_RESULT static MaybeObject* GenerateDictionaryNegativeLookup( | 102 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, |
| 103 Label* miss_label, |
| 104 Register receiver, |
| 105 Handle<String> name, |
| 106 Register scratch0, |
| 107 Register scratch1) { |
| 108 ASSERT(name->IsSymbol()); |
| 109 Counters* counters = masm->isolate()->counters(); |
| 110 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); |
| 111 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); |
| 112 |
| 113 Label done; |
| 114 |
| 115 const int kInterceptorOrAccessCheckNeededMask = |
| 116 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); |
| 117 |
| 118 // Bail out if the receiver has a named interceptor or requires access checks. |
| 119 Register map = scratch1; |
| 120 __ lw(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
| 121 __ lbu(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); |
| 122 __ And(scratch0, scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); |
| 123 __ Branch(miss_label, ne, scratch0, Operand(zero_reg)); |
| 124 |
| 125 // Check that receiver is a JSObject. |
| 126 __ lbu(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); |
| 127 __ Branch(miss_label, lt, scratch0, Operand(FIRST_SPEC_OBJECT_TYPE)); |
| 128 |
| 129 // Load properties array. |
| 130 Register properties = scratch0; |
| 131 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
| 132 // Check that the properties array is a dictionary. |
| 133 __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset)); |
| 134 Register tmp = properties; |
| 135 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); |
| 136 __ Branch(miss_label, ne, map, Operand(tmp)); |
| 137 |
| 138 // Restore the temporarily used register. |
| 139 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
| 140 |
| 141 |
| 142 StringDictionaryLookupStub::GenerateNegativeLookup(masm, |
| 143 miss_label, |
| 144 &done, |
| 145 receiver, |
| 146 properties, |
| 147 name, |
| 148 scratch1); |
| 149 __ bind(&done); |
| 150 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); |
| 151 } |
| 152 |
| 153 |
| 154 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 155 // handlified. |
| 156 MUST_USE_RESULT static MaybeObject* TryGenerateDictionaryNegativeLookup( |
103 MacroAssembler* masm, | 157 MacroAssembler* masm, |
104 Label* miss_label, | 158 Label* miss_label, |
105 Register receiver, | 159 Register receiver, |
106 String* name, | 160 String* name, |
107 Register scratch0, | 161 Register scratch0, |
108 Register scratch1) { | 162 Register scratch1) { |
109 ASSERT(name->IsSymbol()); | 163 ASSERT(name->IsSymbol()); |
110 Counters* counters = masm->isolate()->counters(); | 164 Counters* counters = masm->isolate()->counters(); |
111 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); | 165 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); |
112 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 166 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); |
(...skipping 20 matching lines...) Expand all Loading... |
133 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 187 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
134 // Check that the properties array is a dictionary. | 188 // Check that the properties array is a dictionary. |
135 __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset)); | 189 __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset)); |
136 Register tmp = properties; | 190 Register tmp = properties; |
137 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); | 191 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); |
138 __ Branch(miss_label, ne, map, Operand(tmp)); | 192 __ Branch(miss_label, ne, map, Operand(tmp)); |
139 | 193 |
140 // Restore the temporarily used register. | 194 // Restore the temporarily used register. |
141 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 195 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
142 | 196 |
143 MaybeObject* result = StringDictionaryLookupStub::GenerateNegativeLookup( | 197 MaybeObject* result = StringDictionaryLookupStub::TryGenerateNegativeLookup( |
144 masm, | 198 masm, |
145 miss_label, | 199 miss_label, |
146 &done, | 200 &done, |
147 receiver, | 201 receiver, |
148 properties, | 202 properties, |
149 name, | 203 name, |
150 scratch1); | 204 scratch1); |
151 if (result->IsFailure()) return result; | 205 if (result->IsFailure()) return result; |
152 | 206 |
153 __ bind(&done); | 207 __ bind(&done); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 __ li(prototype, Handle<Map>(function->initial_map())); | 308 __ li(prototype, Handle<Map>(function->initial_map())); |
255 // Load the prototype from the initial map. | 309 // Load the prototype from the initial map. |
256 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); | 310 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); |
257 } | 311 } |
258 | 312 |
259 | 313 |
260 // 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 |
261 // are loaded directly otherwise the property is loaded from the properties | 315 // are loaded directly otherwise the property is loaded from the properties |
262 // fixed array. | 316 // fixed array. |
263 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, | 317 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, |
264 Register dst, Register src, | 318 Register dst, |
265 JSObject* holder, int index) { | 319 Register src, |
| 320 Handle<JSObject> holder, |
| 321 int index) { |
266 // Adjust for the number of properties stored in the holder. | 322 // Adjust for the number of properties stored in the holder. |
267 index -= holder->map()->inobject_properties(); | 323 index -= holder->map()->inobject_properties(); |
268 if (index < 0) { | 324 if (index < 0) { |
269 // Get the property straight out of the holder. | 325 // Get the property straight out of the holder. |
270 int offset = holder->map()->instance_size() + (index * kPointerSize); | 326 int offset = holder->map()->instance_size() + (index * kPointerSize); |
271 __ lw(dst, FieldMemOperand(src, offset)); | 327 __ lw(dst, FieldMemOperand(src, offset)); |
272 } else { | 328 } else { |
273 // Calculate the offset into the properties array. | 329 // Calculate the offset into the properties array. |
274 int offset = index * kPointerSize + FixedArray::kHeaderSize; | 330 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
275 __ lw(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); | 331 __ lw(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 | 518 |
463 // Return the value (register v0). | 519 // Return the value (register v0). |
464 __ bind(&exit); | 520 __ bind(&exit); |
465 __ mov(v0, a0); | 521 __ mov(v0, a0); |
466 __ Ret(); | 522 __ Ret(); |
467 } | 523 } |
468 | 524 |
469 | 525 |
470 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { | 526 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { |
471 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); | 527 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); |
472 Code* code = NULL; | 528 Handle<Code> code = (kind == Code::LOAD_IC) |
473 if (kind == Code::LOAD_IC) { | 529 ? masm->isolate()->builtins()->LoadIC_Miss() |
474 code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss); | 530 : masm->isolate()->builtins()->KeyedLoadIC_Miss(); |
475 } else { | 531 __ Jump(code, RelocInfo::CODE_TARGET); |
476 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss); | |
477 } | |
478 | |
479 Handle<Code> ic(code); | |
480 __ Jump(ic, RelocInfo::CODE_TARGET); | |
481 } | 532 } |
482 | 533 |
483 | 534 |
484 static void GenerateCallFunction(MacroAssembler* masm, | 535 static void GenerateCallFunction(MacroAssembler* masm, |
485 Object* object, | 536 Handle<Object> object, |
486 const ParameterCount& arguments, | 537 const ParameterCount& arguments, |
487 Label* miss, | 538 Label* miss, |
488 Code::ExtraICState extra_ic_state) { | 539 Code::ExtraICState extra_ic_state) { |
489 // ----------- S t a t e ------------- | 540 // ----------- S t a t e ------------- |
490 // -- a0: receiver | 541 // -- a0: receiver |
491 // -- a1: function to call | 542 // -- a1: function to call |
492 // ----------------------------------- | 543 // ----------------------------------- |
493 // Check that the function really is a function. | 544 // Check that the function really is a function. |
494 __ JumpIfSmi(a1, miss); | 545 __ JumpIfSmi(a1, miss); |
495 __ GetObjectType(a1, a3, a3); | 546 __ GetObjectType(a1, a3, a3); |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 const ParameterCount& arguments_; | 922 const ParameterCount& arguments_; |
872 Register name_; | 923 Register name_; |
873 Code::ExtraICState extra_ic_state_; | 924 Code::ExtraICState extra_ic_state_; |
874 }; | 925 }; |
875 | 926 |
876 | 927 |
877 | 928 |
878 // Generate code to check that a global property cell is empty. Create | 929 // Generate code to check that a global property cell is empty. Create |
879 // the property cell at compilation time if no cell exists for the | 930 // the property cell at compilation time if no cell exists for the |
880 // property. | 931 // property. |
881 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( | 932 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
| 933 Handle<GlobalObject> global, |
| 934 Handle<String> name, |
| 935 Register scratch, |
| 936 Label* miss) { |
| 937 Handle<JSGlobalPropertyCell> cell = |
| 938 GlobalObject::EnsurePropertyCell(global, name); |
| 939 ASSERT(cell->value()->IsTheHole()); |
| 940 __ li(scratch, Operand(cell)); |
| 941 __ lw(scratch, |
| 942 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); |
| 943 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
| 944 __ Branch(miss, ne, scratch, Operand(at)); |
| 945 } |
| 946 |
| 947 |
| 948 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 949 // handlified. |
| 950 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCell( |
882 MacroAssembler* masm, | 951 MacroAssembler* masm, |
883 GlobalObject* global, | 952 GlobalObject* global, |
884 String* name, | 953 String* name, |
885 Register scratch, | 954 Register scratch, |
886 Label* miss) { | 955 Label* miss) { |
887 Object* probe; | 956 Object* probe; |
888 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); | 957 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); |
889 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 958 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
890 } | 959 } |
891 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | 960 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); |
892 ASSERT(cell->value()->IsTheHole()); | 961 ASSERT(cell->value()->IsTheHole()); |
893 __ li(scratch, Operand(Handle<Object>(cell))); | 962 __ li(scratch, Operand(Handle<Object>(cell))); |
894 __ lw(scratch, | 963 __ lw(scratch, |
895 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | 964 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); |
896 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 965 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
897 __ Branch(miss, ne, scratch, Operand(at)); | 966 __ Branch(miss, ne, scratch, Operand(at)); |
898 return cell; | 967 return cell; |
899 } | 968 } |
900 | 969 |
901 | 970 |
902 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 971 // Calls GenerateCheckPropertyCell for each global object in the prototype chain |
903 // from object to (but not including) holder. | 972 // from object to (but not including) holder. |
904 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells( | 973 static void GenerateCheckPropertyCells(MacroAssembler* masm, |
| 974 Handle<JSObject> object, |
| 975 Handle<JSObject> holder, |
| 976 Handle<String> name, |
| 977 Register scratch, |
| 978 Label* miss) { |
| 979 Handle<JSObject> current = object; |
| 980 while (!current.is_identical_to(holder)) { |
| 981 if (current->IsGlobalObject()) { |
| 982 GenerateCheckPropertyCell(masm, |
| 983 Handle<GlobalObject>::cast(current), |
| 984 name, |
| 985 scratch, |
| 986 miss); |
| 987 } |
| 988 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); |
| 989 } |
| 990 } |
| 991 |
| 992 |
| 993 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 994 // handlified. |
| 995 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCells( |
905 MacroAssembler* masm, | 996 MacroAssembler* masm, |
906 JSObject* object, | 997 JSObject* object, |
907 JSObject* holder, | 998 JSObject* holder, |
908 String* name, | 999 String* name, |
909 Register scratch, | 1000 Register scratch, |
910 Label* miss) { | 1001 Label* miss) { |
911 JSObject* current = object; | 1002 JSObject* current = object; |
912 while (current != holder) { | 1003 while (current != holder) { |
913 if (current->IsGlobalObject()) { | 1004 if (current->IsGlobalObject()) { |
914 // Returns a cell or a failure. | 1005 // Returns a cell or a failure. |
915 MaybeObject* result = GenerateCheckPropertyCell( | 1006 MaybeObject* result = TryGenerateCheckPropertyCell( |
916 masm, | 1007 masm, |
917 GlobalObject::cast(current), | 1008 GlobalObject::cast(current), |
918 name, | 1009 name, |
919 scratch, | 1010 scratch, |
920 miss); | 1011 miss); |
921 if (result->IsFailure()) return result; | 1012 if (result->IsFailure()) return result; |
922 } | 1013 } |
923 ASSERT(current->IsJSObject()); | 1014 ASSERT(current->IsJSObject()); |
924 current = JSObject::cast(current->GetPrototype()); | 1015 current = JSObject::cast(current->GetPrototype()); |
925 } | 1016 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1040 __ nor(scratch, scratch, scratch); | 1131 __ nor(scratch, scratch, scratch); |
1041 __ and_(hiword, hiword, scratch); | 1132 __ and_(hiword, hiword, scratch); |
1042 } | 1133 } |
1043 } | 1134 } |
1044 | 1135 |
1045 | 1136 |
1046 #undef __ | 1137 #undef __ |
1047 #define __ ACCESS_MASM(masm()) | 1138 #define __ ACCESS_MASM(masm()) |
1048 | 1139 |
1049 | 1140 |
| 1141 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
| 1142 Register object_reg, |
| 1143 Handle<JSObject> holder, |
| 1144 Register holder_reg, |
| 1145 Register scratch1, |
| 1146 Register scratch2, |
| 1147 Handle<String> name, |
| 1148 int save_at_depth, |
| 1149 Label* miss) { |
| 1150 // Make sure there's no overlap between holder and object registers. |
| 1151 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
| 1152 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
| 1153 && !scratch2.is(scratch1)); |
| 1154 |
| 1155 // Keep track of the current object in register reg. |
| 1156 Register reg = object_reg; |
| 1157 int depth = 0; |
| 1158 |
| 1159 if (save_at_depth == depth) { |
| 1160 __ sw(reg, MemOperand(sp)); |
| 1161 } |
| 1162 |
| 1163 // Check the maps in the prototype chain. |
| 1164 // Traverse the prototype chain from the object and do map checks. |
| 1165 Handle<JSObject> current = object; |
| 1166 while (!current.is_identical_to(holder)) { |
| 1167 ++depth; |
| 1168 |
| 1169 // Only global objects and objects that do not require access |
| 1170 // checks are allowed in stubs. |
| 1171 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
| 1172 |
| 1173 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); |
| 1174 if (!current->HasFastProperties() && |
| 1175 !current->IsJSGlobalObject() && |
| 1176 !current->IsJSGlobalProxy()) { |
| 1177 if (!name->IsSymbol()) { |
| 1178 name = factory()->LookupSymbol(name); |
| 1179 } |
| 1180 ASSERT(current->property_dictionary()->FindEntry(*name) == |
| 1181 StringDictionary::kNotFound); |
| 1182 |
| 1183 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
| 1184 scratch1, scratch2); |
| 1185 |
| 1186 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1187 reg = holder_reg; // From now on the object will be in holder_reg. |
| 1188 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
| 1189 } else { |
| 1190 Handle<Map> current_map(current->map()); |
| 1191 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1192 // Branch on the result of the map check. |
| 1193 __ Branch(miss, ne, scratch1, Operand(current_map)); |
| 1194 // Check access rights to the global object. This has to happen after |
| 1195 // the map check so that we know that the object is actually a global |
| 1196 // object. |
| 1197 if (current->IsJSGlobalProxy()) { |
| 1198 __ CheckAccessGlobalProxy(reg, scratch2, miss); |
| 1199 } |
| 1200 reg = holder_reg; // From now on the object will be in holder_reg. |
| 1201 |
| 1202 if (heap()->InNewSpace(*prototype)) { |
| 1203 // The prototype is in new space; we cannot store a reference to it |
| 1204 // in the code. Load it from the map. |
| 1205 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
| 1206 } else { |
| 1207 // The prototype is in old space; load it directly. |
| 1208 __ li(reg, Operand(prototype)); |
| 1209 } |
| 1210 } |
| 1211 |
| 1212 if (save_at_depth == depth) { |
| 1213 __ sw(reg, MemOperand(sp)); |
| 1214 } |
| 1215 |
| 1216 // Go to the next object in the prototype chain. |
| 1217 current = prototype; |
| 1218 } |
| 1219 |
| 1220 // Log the check depth. |
| 1221 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); |
| 1222 |
| 1223 // Check the holder map. |
| 1224 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1225 __ Branch(miss, ne, scratch1, Operand(Handle<Map>(current->map()))); |
| 1226 |
| 1227 // Perform security check for access to the global object. |
| 1228 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
| 1229 if (holder->IsJSGlobalProxy()) { |
| 1230 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
| 1231 } |
| 1232 |
| 1233 // If we've skipped any global objects, it's not enough to verify that |
| 1234 // their maps haven't changed. We also need to check that the property |
| 1235 // cell for the property is still empty. |
| 1236 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); |
| 1237 |
| 1238 // Return the register containing the holder. |
| 1239 return reg; |
| 1240 } |
| 1241 |
| 1242 |
1050 Register StubCompiler::CheckPrototypes(JSObject* object, | 1243 Register StubCompiler::CheckPrototypes(JSObject* object, |
1051 Register object_reg, | 1244 Register object_reg, |
1052 JSObject* holder, | 1245 JSObject* holder, |
1053 Register holder_reg, | 1246 Register holder_reg, |
1054 Register scratch1, | 1247 Register scratch1, |
1055 Register scratch2, | 1248 Register scratch2, |
1056 String* name, | 1249 String* name, |
1057 int save_at_depth, | 1250 int save_at_depth, |
1058 Label* miss) { | 1251 Label* miss) { |
1059 // Make sure there's no overlap between holder and object registers. | 1252 // Make sure there's no overlap between holder and object registers. |
(...skipping 29 matching lines...) Expand all Loading... |
1089 Object* lookup_result = NULL; // Initialization to please compiler. | 1282 Object* lookup_result = NULL; // Initialization to please compiler. |
1090 if (!maybe_lookup_result->ToObject(&lookup_result)) { | 1283 if (!maybe_lookup_result->ToObject(&lookup_result)) { |
1091 set_failure(Failure::cast(maybe_lookup_result)); | 1284 set_failure(Failure::cast(maybe_lookup_result)); |
1092 return reg; | 1285 return reg; |
1093 } | 1286 } |
1094 name = String::cast(lookup_result); | 1287 name = String::cast(lookup_result); |
1095 } | 1288 } |
1096 ASSERT(current->property_dictionary()->FindEntry(name) == | 1289 ASSERT(current->property_dictionary()->FindEntry(name) == |
1097 StringDictionary::kNotFound); | 1290 StringDictionary::kNotFound); |
1098 | 1291 |
1099 MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(), | 1292 MaybeObject* negative_lookup = |
1100 miss, | 1293 TryGenerateDictionaryNegativeLookup(masm(), |
1101 reg, | 1294 miss, |
1102 name, | 1295 reg, |
1103 scratch1, | 1296 name, |
1104 scratch2); | 1297 scratch1, |
| 1298 scratch2); |
| 1299 |
1105 if (negative_lookup->IsFailure()) { | 1300 if (negative_lookup->IsFailure()) { |
1106 set_failure(Failure::cast(negative_lookup)); | 1301 set_failure(Failure::cast(negative_lookup)); |
1107 return reg; | 1302 return reg; |
1108 } | 1303 } |
1109 | 1304 |
1110 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1305 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
1111 reg = holder_reg; // From now the object is in holder_reg. | 1306 reg = holder_reg; // From now the object is in holder_reg. |
1112 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 1307 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
1113 } else if (heap()->InNewSpace(prototype)) { | 1308 } else if (heap()->InNewSpace(prototype)) { |
1114 // Get the map of the current object. | 1309 // Get the map of the current object. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1159 // Check the holder map. | 1354 // Check the holder map. |
1160 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1355 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
1161 __ Branch(miss, ne, scratch1, Operand(Handle<Map>(current->map()))); | 1356 __ Branch(miss, ne, scratch1, Operand(Handle<Map>(current->map()))); |
1162 | 1357 |
1163 // Log the check depth. | 1358 // Log the check depth. |
1164 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); | 1359 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); |
1165 // Perform security check for access to the global object. | 1360 // Perform security check for access to the global object. |
1166 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1361 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
1167 if (holder->IsJSGlobalProxy()) { | 1362 if (holder->IsJSGlobalProxy()) { |
1168 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 1363 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
1169 }; | 1364 } |
1170 | 1365 |
1171 // If we've skipped any global objects, it's not enough to verify | 1366 // If we've skipped any global objects, it's not enough to verify |
1172 // that their maps haven't changed. We also need to check that the | 1367 // that their maps haven't changed. We also need to check that the |
1173 // property cell for the property is still empty. | 1368 // property cell for the property is still empty. |
1174 | 1369 |
1175 MaybeObject* result = GenerateCheckPropertyCells(masm(), | 1370 MaybeObject* result = TryGenerateCheckPropertyCells(masm(), |
1176 object, | 1371 object, |
1177 holder, | 1372 holder, |
1178 name, | 1373 name, |
1179 scratch1, | 1374 scratch1, |
1180 miss); | 1375 miss); |
1181 if (result->IsFailure()) set_failure(Failure::cast(result)); | 1376 if (result->IsFailure()) set_failure(Failure::cast(result)); |
1182 | 1377 |
1183 // Return the register containing the holder. | 1378 // Return the register containing the holder. |
1184 return reg; | 1379 return reg; |
1185 } | 1380 } |
1186 | 1381 |
1187 | 1382 |
1188 void StubCompiler::GenerateLoadField(JSObject* object, | 1383 void StubCompiler::GenerateLoadField(Handle<JSObject> object, |
1189 JSObject* holder, | 1384 Handle<JSObject> holder, |
1190 Register receiver, | 1385 Register receiver, |
1191 Register scratch1, | 1386 Register scratch1, |
1192 Register scratch2, | 1387 Register scratch2, |
1193 Register scratch3, | 1388 Register scratch3, |
1194 int index, | 1389 int index, |
1195 String* name, | 1390 Handle<String> name, |
1196 Label* miss) { | 1391 Label* miss) { |
1197 // Check that the receiver isn't a smi. | 1392 // Check that the receiver isn't a smi. |
1198 __ And(scratch1, receiver, Operand(kSmiTagMask)); | 1393 __ And(scratch1, receiver, Operand(kSmiTagMask)); |
1199 __ Branch(miss, eq, scratch1, Operand(zero_reg)); | 1394 __ Branch(miss, eq, scratch1, Operand(zero_reg)); |
1200 | 1395 |
1201 // Check that the maps haven't changed. | 1396 // Check that the maps haven't changed. |
1202 Register reg = | 1397 Register reg = CheckPrototypes( |
1203 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, | 1398 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
1204 name, miss); | |
1205 GenerateFastPropertyLoad(masm(), v0, reg, holder, index); | 1399 GenerateFastPropertyLoad(masm(), v0, reg, holder, index); |
1206 __ Ret(); | 1400 __ Ret(); |
1207 } | 1401 } |
1208 | 1402 |
1209 | 1403 |
1210 void StubCompiler::GenerateLoadConstant(JSObject* object, | 1404 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, |
1211 JSObject* holder, | 1405 Handle<JSObject> holder, |
1212 Register receiver, | 1406 Register receiver, |
1213 Register scratch1, | 1407 Register scratch1, |
1214 Register scratch2, | 1408 Register scratch2, |
1215 Register scratch3, | 1409 Register scratch3, |
1216 Object* value, | 1410 Handle<Object> value, |
1217 String* name, | 1411 Handle<String> name, |
1218 Label* miss) { | 1412 Label* miss) { |
1219 // Check that the receiver isn't a smi. | 1413 // Check that the receiver isn't a smi. |
1220 __ JumpIfSmi(receiver, miss, scratch1); | 1414 __ JumpIfSmi(receiver, miss, scratch1); |
1221 | 1415 |
1222 // Check that the maps haven't changed. | 1416 // Check that the maps haven't changed. |
1223 Register reg = | 1417 Register reg = |
1224 CheckPrototypes(object, receiver, holder, | 1418 CheckPrototypes(object, receiver, holder, |
1225 scratch1, scratch2, scratch3, name, miss); | 1419 scratch1, scratch2, scratch3, name, miss); |
1226 | 1420 |
1227 // Return the constant value. | 1421 // Return the constant value. |
1228 __ li(v0, Operand(Handle<Object>(value))); | 1422 __ li(v0, Operand(value)); |
1229 __ Ret(); | 1423 __ Ret(); |
1230 } | 1424 } |
1231 | 1425 |
1232 | 1426 |
1233 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, | 1427 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, |
1234 JSObject* holder, | 1428 JSObject* holder, |
1235 Register receiver, | 1429 Register receiver, |
1236 Register name_reg, | 1430 Register name_reg, |
1237 Register scratch1, | 1431 Register scratch1, |
1238 Register scratch2, | 1432 Register scratch2, |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1383 scratch2, | 1577 scratch2, |
1384 scratch3, | 1578 scratch3, |
1385 name, | 1579 name, |
1386 miss); | 1580 miss); |
1387 } | 1581 } |
1388 | 1582 |
1389 if (lookup->type() == FIELD) { | 1583 if (lookup->type() == FIELD) { |
1390 // We found FIELD property in prototype chain of interceptor's holder. | 1584 // We found FIELD property in prototype chain of interceptor's holder. |
1391 // Retrieve a field from field's holder. | 1585 // Retrieve a field from field's holder. |
1392 GenerateFastPropertyLoad(masm(), v0, holder_reg, | 1586 GenerateFastPropertyLoad(masm(), v0, holder_reg, |
1393 lookup->holder(), lookup->GetFieldIndex()); | 1587 Handle<JSObject>(lookup->holder()), |
| 1588 lookup->GetFieldIndex()); |
1394 __ Ret(); | 1589 __ Ret(); |
1395 } else { | 1590 } else { |
1396 // We found CALLBACKS property in prototype chain of interceptor's | 1591 // We found CALLBACKS property in prototype chain of interceptor's |
1397 // holder. | 1592 // holder. |
1398 ASSERT(lookup->type() == CALLBACKS); | 1593 ASSERT(lookup->type() == CALLBACKS); |
1399 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); | 1594 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); |
1400 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); | 1595 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); |
1401 ASSERT(callback != NULL); | 1596 ASSERT(callback != NULL); |
1402 ASSERT(callback->getter() != NULL); | 1597 ASSERT(callback->getter() != NULL); |
1403 | 1598 |
(...skipping 29 matching lines...) Expand all Loading... |
1433 PushInterceptorArguments(masm(), receiver, holder_reg, | 1628 PushInterceptorArguments(masm(), receiver, holder_reg, |
1434 name_reg, interceptor_holder); | 1629 name_reg, interceptor_holder); |
1435 | 1630 |
1436 ExternalReference ref = ExternalReference( | 1631 ExternalReference ref = ExternalReference( |
1437 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), masm()->isolate()); | 1632 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), masm()->isolate()); |
1438 __ TailCallExternalReference(ref, 5, 1); | 1633 __ TailCallExternalReference(ref, 5, 1); |
1439 } | 1634 } |
1440 } | 1635 } |
1441 | 1636 |
1442 | 1637 |
1443 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { | 1638 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { |
1444 if (kind_ == Code::KEYED_CALL_IC) { | 1639 if (kind_ == Code::KEYED_CALL_IC) { |
1445 __ Branch(miss, ne, a2, Operand(Handle<String>(name))); | 1640 __ Branch(miss, ne, a2, Operand(name)); |
1446 } | 1641 } |
1447 } | 1642 } |
1448 | 1643 |
1449 | 1644 |
1450 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, | 1645 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, |
1451 JSObject* holder, | 1646 JSObject* holder, |
1452 String* name, | 1647 String* name, |
1453 Label* miss) { | 1648 Label* miss) { |
1454 ASSERT(holder->IsGlobalObject()); | 1649 ASSERT(holder->IsGlobalObject()); |
1455 | 1650 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1492 // Check the shared function info. Make sure it hasn't changed. | 1687 // Check the shared function info. Make sure it hasn't changed. |
1493 __ li(a3, Handle<SharedFunctionInfo>(function->shared())); | 1688 __ li(a3, Handle<SharedFunctionInfo>(function->shared())); |
1494 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 1689 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
1495 __ Branch(miss, ne, t0, Operand(a3)); | 1690 __ Branch(miss, ne, t0, Operand(a3)); |
1496 } else { | 1691 } else { |
1497 __ Branch(miss, ne, a1, Operand(Handle<JSFunction>(function))); | 1692 __ Branch(miss, ne, a1, Operand(Handle<JSFunction>(function))); |
1498 } | 1693 } |
1499 } | 1694 } |
1500 | 1695 |
1501 | 1696 |
1502 MaybeObject* CallStubCompiler::GenerateMissBranch() { | 1697 void CallStubCompiler::GenerateMissBranch() { |
1503 MaybeObject* maybe_obj = | 1698 Handle<Code> code = |
1504 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | 1699 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), |
1505 kind_, | 1700 kind_, |
1506 extra_ic_state_); | 1701 extra_state_); |
| 1702 __ Jump(code, RelocInfo::CODE_TARGET); |
| 1703 } |
| 1704 |
| 1705 |
| 1706 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 1707 // handlified. |
| 1708 MaybeObject* CallStubCompiler::TryGenerateMissBranch() { |
| 1709 MaybeObject* maybe_obj = |
| 1710 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), |
| 1711 kind_, |
| 1712 extra_state_); |
1507 Object* obj; | 1713 Object* obj; |
1508 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1714 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1509 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1715 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
1510 return obj; | 1716 return obj; |
1511 } | 1717 } |
1512 | 1718 |
1513 | 1719 |
1514 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, | 1720 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
1515 JSObject* holder, | 1721 Handle<JSObject> holder, |
1516 int index, | 1722 int index, |
1517 String* name) { | 1723 Handle<String> name) { |
1518 // ----------- S t a t e ------------- | 1724 // ----------- S t a t e ------------- |
1519 // -- a2 : name | 1725 // -- a2 : name |
1520 // -- ra : return address | 1726 // -- ra : return address |
1521 // ----------------------------------- | 1727 // ----------------------------------- |
1522 Label miss; | 1728 Label miss; |
1523 | 1729 |
1524 GenerateNameCheck(name, &miss); | 1730 GenerateNameCheck(name, &miss); |
1525 | 1731 |
1526 const int argc = arguments().immediate(); | 1732 const int argc = arguments().immediate(); |
1527 | 1733 |
1528 // Get the receiver of the function from the stack into a0. | 1734 // Get the receiver of the function from the stack into a0. |
1529 __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 1735 __ lw(a0, MemOperand(sp, argc * kPointerSize)); |
1530 // Check that the receiver isn't a smi. | 1736 // Check that the receiver isn't a smi. |
1531 __ JumpIfSmi(a0, &miss, t0); | 1737 __ JumpIfSmi(a0, &miss, t0); |
1532 | 1738 |
1533 // Do the right check and compute the holder register. | 1739 // Do the right check and compute the holder register. |
1534 Register reg = CheckPrototypes(object, a0, holder, a1, a3, t0, name, &miss); | 1740 Register reg = CheckPrototypes(object, a0, holder, a1, a3, t0, name, &miss); |
1535 GenerateFastPropertyLoad(masm(), a1, reg, holder, index); | 1741 GenerateFastPropertyLoad(masm(), a1, reg, holder, index); |
1536 | 1742 |
1537 GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_); | 1743 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); |
1538 | 1744 |
1539 // Handle call cache miss. | 1745 // Handle call cache miss. |
1540 __ bind(&miss); | 1746 __ bind(&miss); |
1541 MaybeObject* maybe_result = GenerateMissBranch(); | 1747 GenerateMissBranch(); |
1542 if (maybe_result->IsFailure()) return maybe_result; | |
1543 | 1748 |
1544 // Return the generated code. | 1749 // Return the generated code. |
1545 return GetCode(FIELD, name); | 1750 return GetCode(FIELD, name); |
1546 } | 1751 } |
1547 | 1752 |
1548 | 1753 |
1549 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, | 1754 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, |
1550 JSObject* holder, | 1755 JSObject* holder, |
1551 JSGlobalPropertyCell* cell, | 1756 JSGlobalPropertyCell* cell, |
1552 JSFunction* function, | 1757 JSFunction* function, |
1553 String* name) { | 1758 String* name) { |
1554 // ----------- S t a t e ------------- | 1759 // ----------- S t a t e ------------- |
1555 // -- a2 : name | 1760 // -- a2 : name |
1556 // -- ra : return address | 1761 // -- ra : return address |
1557 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 1762 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
1558 // -- ... | 1763 // -- ... |
1559 // -- sp[argc * 4] : receiver | 1764 // -- sp[argc * 4] : receiver |
1560 // ----------------------------------- | 1765 // ----------------------------------- |
1561 | 1766 |
1562 // If object is not an array, bail out to regular call. | 1767 // If object is not an array, bail out to regular call. |
1563 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 1768 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); |
1564 | 1769 |
1565 Label miss; | 1770 Label miss; |
1566 | 1771 |
1567 GenerateNameCheck(name, &miss); | 1772 GenerateNameCheck(Handle<String>(name), &miss); |
1568 | 1773 |
1569 Register receiver = a1; | 1774 Register receiver = a1; |
1570 | 1775 |
1571 // Get the receiver from the stack. | 1776 // Get the receiver from the stack. |
1572 const int argc = arguments().immediate(); | 1777 const int argc = arguments().immediate(); |
1573 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 1778 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); |
1574 | 1779 |
1575 // Check that the receiver isn't a smi. | 1780 // Check that the receiver isn't a smi. |
1576 __ JumpIfSmi(receiver, &miss); | 1781 __ JumpIfSmi(receiver, &miss); |
1577 | 1782 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1633 __ Addu(end_elements, end_elements, kEndElementsOffset); | 1838 __ Addu(end_elements, end_elements, kEndElementsOffset); |
1634 __ sw(t0, MemOperand(end_elements)); | 1839 __ sw(t0, MemOperand(end_elements)); |
1635 | 1840 |
1636 // Check for a smi. | 1841 // Check for a smi. |
1637 __ Drop(argc + 1); | 1842 __ Drop(argc + 1); |
1638 __ Ret(); | 1843 __ Ret(); |
1639 | 1844 |
1640 __ bind(&with_write_barrier); | 1845 __ bind(&with_write_barrier); |
1641 | 1846 |
1642 __ lw(t2, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 1847 __ lw(t2, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
1643 __ CheckFastSmiOnlyElements(t2, t2, &call_builtin); | 1848 __ CheckFastObjectElements(t2, t2, &call_builtin); |
1644 | 1849 |
1645 // Save new length. | 1850 // Save new length. |
1646 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1851 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1647 | 1852 |
1648 // Push the element. | 1853 // Push the element. |
1649 // We may need a register containing the address end_elements below, | 1854 // We may need a register containing the address end_elements below, |
1650 // so write back the value in end_elements. | 1855 // so write back the value in end_elements. |
1651 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); | 1856 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); |
1652 __ Addu(end_elements, elements, end_elements); | 1857 __ Addu(end_elements, elements, end_elements); |
1653 __ Addu(end_elements, end_elements, kEndElementsOffset); | 1858 __ Addu(end_elements, end_elements, kEndElementsOffset); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1723 } | 1928 } |
1724 __ bind(&call_builtin); | 1929 __ bind(&call_builtin); |
1725 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, | 1930 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, |
1726 masm()->isolate()), | 1931 masm()->isolate()), |
1727 argc + 1, | 1932 argc + 1, |
1728 1); | 1933 1); |
1729 } | 1934 } |
1730 | 1935 |
1731 // Handle call cache miss. | 1936 // Handle call cache miss. |
1732 __ bind(&miss); | 1937 __ bind(&miss); |
1733 MaybeObject* maybe_result = GenerateMissBranch(); | 1938 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1734 if (maybe_result->IsFailure()) return maybe_result; | 1939 if (maybe_result->IsFailure()) return maybe_result; |
1735 | 1940 |
1736 // Return the generated code. | 1941 // Return the generated code. |
1737 return GetCode(function); | 1942 return TryGetCode(function); |
1738 } | 1943 } |
1739 | 1944 |
1740 | 1945 |
1741 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, | 1946 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, |
1742 JSObject* holder, | 1947 JSObject* holder, |
1743 JSGlobalPropertyCell* cell, | 1948 JSGlobalPropertyCell* cell, |
1744 JSFunction* function, | 1949 JSFunction* function, |
1745 String* name) { | 1950 String* name) { |
1746 // ----------- S t a t e ------------- | 1951 // ----------- S t a t e ------------- |
1747 // -- a2 : name | 1952 // -- a2 : name |
1748 // -- ra : return address | 1953 // -- ra : return address |
1749 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 1954 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
1750 // -- ... | 1955 // -- ... |
1751 // -- sp[argc * 4] : receiver | 1956 // -- sp[argc * 4] : receiver |
1752 // ----------------------------------- | 1957 // ----------------------------------- |
1753 | 1958 |
1754 // If object is not an array, bail out to regular call. | 1959 // If object is not an array, bail out to regular call. |
1755 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 1960 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); |
1756 | 1961 |
1757 Label miss, return_undefined, call_builtin; | 1962 Label miss, return_undefined, call_builtin; |
1758 | 1963 |
1759 Register receiver = a1; | 1964 Register receiver = a1; |
1760 Register elements = a3; | 1965 Register elements = a3; |
1761 | 1966 |
1762 GenerateNameCheck(name, &miss); | 1967 GenerateNameCheck(Handle<String>(name), &miss); |
1763 | 1968 |
1764 // Get the receiver from the stack. | 1969 // Get the receiver from the stack. |
1765 const int argc = arguments().immediate(); | 1970 const int argc = arguments().immediate(); |
1766 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 1971 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); |
1767 | 1972 |
1768 // Check that the receiver isn't a smi. | 1973 // Check that the receiver isn't a smi. |
1769 __ JumpIfSmi(receiver, &miss); | 1974 __ JumpIfSmi(receiver, &miss); |
1770 | 1975 |
1771 // Check that the maps haven't changed. | 1976 // Check that the maps haven't changed. |
1772 CheckPrototypes(JSObject::cast(object), | 1977 CheckPrototypes(JSObject::cast(object), |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1812 __ Ret(); | 2017 __ Ret(); |
1813 | 2018 |
1814 __ bind(&call_builtin); | 2019 __ bind(&call_builtin); |
1815 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop, | 2020 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop, |
1816 masm()->isolate()), | 2021 masm()->isolate()), |
1817 argc + 1, | 2022 argc + 1, |
1818 1); | 2023 1); |
1819 | 2024 |
1820 // Handle call cache miss. | 2025 // Handle call cache miss. |
1821 __ bind(&miss); | 2026 __ bind(&miss); |
1822 MaybeObject* maybe_result = GenerateMissBranch(); | 2027 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1823 if (maybe_result->IsFailure()) return maybe_result; | 2028 if (maybe_result->IsFailure()) return maybe_result; |
1824 | 2029 |
1825 // Return the generated code. | 2030 // Return the generated code. |
1826 return GetCode(function); | 2031 return TryGetCode(function); |
1827 } | 2032 } |
1828 | 2033 |
1829 | 2034 |
1830 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( | 2035 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( |
1831 Object* object, | 2036 Object* object, |
1832 JSObject* holder, | 2037 JSObject* holder, |
1833 JSGlobalPropertyCell* cell, | 2038 JSGlobalPropertyCell* cell, |
1834 JSFunction* function, | 2039 JSFunction* function, |
1835 String* name) { | 2040 String* name) { |
1836 // ----------- S t a t e ------------- | 2041 // ----------- S t a t e ------------- |
1837 // -- a2 : function name | 2042 // -- a2 : function name |
1838 // -- ra : return address | 2043 // -- ra : return address |
1839 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2044 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
1840 // -- ... | 2045 // -- ... |
1841 // -- sp[argc * 4] : receiver | 2046 // -- sp[argc * 4] : receiver |
1842 // ----------------------------------- | 2047 // ----------------------------------- |
1843 | 2048 |
1844 // If object is not a string, bail out to regular call. | 2049 // If object is not a string, bail out to regular call. |
1845 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); | 2050 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); |
1846 | 2051 |
1847 const int argc = arguments().immediate(); | 2052 const int argc = arguments().immediate(); |
1848 | 2053 |
1849 Label miss; | 2054 Label miss; |
1850 Label name_miss; | 2055 Label name_miss; |
1851 Label index_out_of_range; | 2056 Label index_out_of_range; |
1852 | 2057 |
1853 Label* index_out_of_range_label = &index_out_of_range; | 2058 Label* index_out_of_range_label = &index_out_of_range; |
1854 | 2059 |
1855 if (kind_ == Code::CALL_IC && | 2060 if (kind_ == Code::CALL_IC && |
1856 (CallICBase::StringStubState::decode(extra_ic_state_) == | 2061 (CallICBase::StringStubState::decode(extra_state_) == |
1857 DEFAULT_STRING_STUB)) { | 2062 DEFAULT_STRING_STUB)) { |
1858 index_out_of_range_label = &miss; | 2063 index_out_of_range_label = &miss; |
1859 } | 2064 } |
1860 | 2065 |
1861 GenerateNameCheck(name, &name_miss); | 2066 GenerateNameCheck(Handle<String>(name), &name_miss); |
1862 | 2067 |
1863 // Check that the maps starting from the prototype haven't changed. | 2068 // Check that the maps starting from the prototype haven't changed. |
1864 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2069 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1865 Context::STRING_FUNCTION_INDEX, | 2070 Context::STRING_FUNCTION_INDEX, |
1866 v0, | 2071 v0, |
1867 &miss); | 2072 &miss); |
1868 ASSERT(object != holder); | 2073 ASSERT(object != holder); |
1869 CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, | 2074 CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, |
1870 a1, a3, t0, name, &miss); | 2075 a1, a3, t0, name, &miss); |
1871 | 2076 |
(...skipping 27 matching lines...) Expand all Loading... |
1899 __ bind(&index_out_of_range); | 2104 __ bind(&index_out_of_range); |
1900 __ LoadRoot(v0, Heap::kNanValueRootIndex); | 2105 __ LoadRoot(v0, Heap::kNanValueRootIndex); |
1901 __ Drop(argc + 1); | 2106 __ Drop(argc + 1); |
1902 __ Ret(); | 2107 __ Ret(); |
1903 } | 2108 } |
1904 | 2109 |
1905 __ bind(&miss); | 2110 __ bind(&miss); |
1906 // Restore function name in a2. | 2111 // Restore function name in a2. |
1907 __ li(a2, Handle<String>(name)); | 2112 __ li(a2, Handle<String>(name)); |
1908 __ bind(&name_miss); | 2113 __ bind(&name_miss); |
1909 MaybeObject* maybe_result = GenerateMissBranch(); | 2114 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1910 if (maybe_result->IsFailure()) return maybe_result; | 2115 if (maybe_result->IsFailure()) return maybe_result; |
1911 | 2116 |
1912 // Return the generated code. | 2117 // Return the generated code. |
1913 return GetCode(function); | 2118 return TryGetCode(function); |
1914 } | 2119 } |
1915 | 2120 |
1916 | 2121 |
1917 MaybeObject* CallStubCompiler::CompileStringCharAtCall( | 2122 MaybeObject* CallStubCompiler::CompileStringCharAtCall( |
1918 Object* object, | 2123 Object* object, |
1919 JSObject* holder, | 2124 JSObject* holder, |
1920 JSGlobalPropertyCell* cell, | 2125 JSGlobalPropertyCell* cell, |
1921 JSFunction* function, | 2126 JSFunction* function, |
1922 String* name) { | 2127 String* name) { |
1923 // ----------- S t a t e ------------- | 2128 // ----------- S t a t e ------------- |
1924 // -- a2 : function name | 2129 // -- a2 : function name |
1925 // -- ra : return address | 2130 // -- ra : return address |
1926 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2131 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
1927 // -- ... | 2132 // -- ... |
1928 // -- sp[argc * 4] : receiver | 2133 // -- sp[argc * 4] : receiver |
1929 // ----------------------------------- | 2134 // ----------------------------------- |
1930 | 2135 |
1931 // If object is not a string, bail out to regular call. | 2136 // If object is not a string, bail out to regular call. |
1932 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); | 2137 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); |
1933 | 2138 |
1934 const int argc = arguments().immediate(); | 2139 const int argc = arguments().immediate(); |
1935 | 2140 |
1936 Label miss; | 2141 Label miss; |
1937 Label name_miss; | 2142 Label name_miss; |
1938 Label index_out_of_range; | 2143 Label index_out_of_range; |
1939 Label* index_out_of_range_label = &index_out_of_range; | 2144 Label* index_out_of_range_label = &index_out_of_range; |
1940 | 2145 |
1941 if (kind_ == Code::CALL_IC && | 2146 if (kind_ == Code::CALL_IC && |
1942 (CallICBase::StringStubState::decode(extra_ic_state_) == | 2147 (CallICBase::StringStubState::decode(extra_state_) == |
1943 DEFAULT_STRING_STUB)) { | 2148 DEFAULT_STRING_STUB)) { |
1944 index_out_of_range_label = &miss; | 2149 index_out_of_range_label = &miss; |
1945 } | 2150 } |
1946 | 2151 |
1947 GenerateNameCheck(name, &name_miss); | 2152 GenerateNameCheck(Handle<String>(name), &name_miss); |
1948 | 2153 |
1949 // Check that the maps starting from the prototype haven't changed. | 2154 // Check that the maps starting from the prototype haven't changed. |
1950 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2155 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1951 Context::STRING_FUNCTION_INDEX, | 2156 Context::STRING_FUNCTION_INDEX, |
1952 v0, | 2157 v0, |
1953 &miss); | 2158 &miss); |
1954 ASSERT(object != holder); | 2159 ASSERT(object != holder); |
1955 CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, | 2160 CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, |
1956 a1, a3, t0, name, &miss); | 2161 a1, a3, t0, name, &miss); |
1957 | 2162 |
(...skipping 29 matching lines...) Expand all Loading... |
1987 __ bind(&index_out_of_range); | 2192 __ bind(&index_out_of_range); |
1988 __ LoadRoot(v0, Heap::kEmptyStringRootIndex); | 2193 __ LoadRoot(v0, Heap::kEmptyStringRootIndex); |
1989 __ Drop(argc + 1); | 2194 __ Drop(argc + 1); |
1990 __ Ret(); | 2195 __ Ret(); |
1991 } | 2196 } |
1992 | 2197 |
1993 __ bind(&miss); | 2198 __ bind(&miss); |
1994 // Restore function name in a2. | 2199 // Restore function name in a2. |
1995 __ li(a2, Handle<String>(name)); | 2200 __ li(a2, Handle<String>(name)); |
1996 __ bind(&name_miss); | 2201 __ bind(&name_miss); |
1997 MaybeObject* maybe_result = GenerateMissBranch(); | 2202 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1998 if (maybe_result->IsFailure()) return maybe_result; | 2203 if (maybe_result->IsFailure()) return maybe_result; |
1999 | 2204 |
2000 // Return the generated code. | 2205 // Return the generated code. |
2001 return GetCode(function); | 2206 return TryGetCode(function); |
2002 } | 2207 } |
2003 | 2208 |
2004 | 2209 |
2005 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( | 2210 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( |
2006 Object* object, | 2211 Object* object, |
2007 JSObject* holder, | 2212 JSObject* holder, |
2008 JSGlobalPropertyCell* cell, | 2213 JSGlobalPropertyCell* cell, |
2009 JSFunction* function, | 2214 JSFunction* function, |
2010 String* name) { | 2215 String* name) { |
2011 // ----------- S t a t e ------------- | 2216 // ----------- S t a t e ------------- |
2012 // -- a2 : function name | 2217 // -- a2 : function name |
2013 // -- ra : return address | 2218 // -- ra : return address |
2014 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2219 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
2015 // -- ... | 2220 // -- ... |
2016 // -- sp[argc * 4] : receiver | 2221 // -- sp[argc * 4] : receiver |
2017 // ----------------------------------- | 2222 // ----------------------------------- |
2018 | 2223 |
2019 const int argc = arguments().immediate(); | 2224 const int argc = arguments().immediate(); |
2020 | 2225 |
2021 // If the object is not a JSObject or we got an unexpected number of | 2226 // If the object is not a JSObject or we got an unexpected number of |
2022 // arguments, bail out to the regular call. | 2227 // arguments, bail out to the regular call. |
2023 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2228 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
2024 | 2229 |
2025 Label miss; | 2230 Label miss; |
2026 GenerateNameCheck(name, &miss); | 2231 GenerateNameCheck(Handle<String>(name), &miss); |
2027 | 2232 |
2028 if (cell == NULL) { | 2233 if (cell == NULL) { |
2029 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 2234 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); |
2030 | 2235 |
2031 STATIC_ASSERT(kSmiTag == 0); | 2236 STATIC_ASSERT(kSmiTag == 0); |
2032 __ JumpIfSmi(a1, &miss); | 2237 __ JumpIfSmi(a1, &miss); |
2033 | 2238 |
2034 CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, | 2239 CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, |
2035 &miss); | 2240 &miss); |
2036 } else { | 2241 } else { |
(...skipping 22 matching lines...) Expand all Loading... |
2059 StubRuntimeCallHelper call_helper; | 2264 StubRuntimeCallHelper call_helper; |
2060 char_from_code_generator.GenerateSlow(masm(), call_helper); | 2265 char_from_code_generator.GenerateSlow(masm(), call_helper); |
2061 | 2266 |
2062 // Tail call the full function. We do not have to patch the receiver | 2267 // Tail call the full function. We do not have to patch the receiver |
2063 // because the function makes no use of it. | 2268 // because the function makes no use of it. |
2064 __ bind(&slow); | 2269 __ bind(&slow); |
2065 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2270 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
2066 | 2271 |
2067 __ bind(&miss); | 2272 __ bind(&miss); |
2068 // a2: function name. | 2273 // a2: function name. |
2069 MaybeObject* maybe_result = GenerateMissBranch(); | 2274 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2070 if (maybe_result->IsFailure()) return maybe_result; | 2275 if (maybe_result->IsFailure()) return maybe_result; |
2071 | 2276 |
2072 // Return the generated code. | 2277 // Return the generated code. |
2073 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2278 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
2074 } | 2279 } |
2075 | 2280 |
2076 | 2281 |
2077 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, | 2282 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, |
2078 JSObject* holder, | 2283 JSObject* holder, |
2079 JSGlobalPropertyCell* cell, | 2284 JSGlobalPropertyCell* cell, |
2080 JSFunction* function, | 2285 JSFunction* function, |
2081 String* name) { | 2286 String* name) { |
2082 // ----------- S t a t e ------------- | 2287 // ----------- S t a t e ------------- |
2083 // -- a2 : function name | 2288 // -- a2 : function name |
2084 // -- ra : return address | 2289 // -- ra : return address |
2085 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2290 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
2086 // -- ... | 2291 // -- ... |
2087 // -- sp[argc * 4] : receiver | 2292 // -- sp[argc * 4] : receiver |
2088 // ----------------------------------- | 2293 // ----------------------------------- |
2089 | 2294 |
2090 if (!CpuFeatures::IsSupported(FPU)) | 2295 if (!CpuFeatures::IsSupported(FPU)) |
2091 return heap()->undefined_value(); | 2296 return heap()->undefined_value(); |
2092 CpuFeatures::Scope scope_fpu(FPU); | 2297 CpuFeatures::Scope scope_fpu(FPU); |
2093 | 2298 |
2094 const int argc = arguments().immediate(); | 2299 const int argc = arguments().immediate(); |
2095 | 2300 |
2096 // If the object is not a JSObject or we got an unexpected number of | 2301 // If the object is not a JSObject or we got an unexpected number of |
2097 // arguments, bail out to the regular call. | 2302 // arguments, bail out to the regular call. |
2098 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2303 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
2099 | 2304 |
2100 Label miss, slow; | 2305 Label miss, slow; |
2101 GenerateNameCheck(name, &miss); | 2306 GenerateNameCheck(Handle<String>(name), &miss); |
2102 | 2307 |
2103 if (cell == NULL) { | 2308 if (cell == NULL) { |
2104 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 2309 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); |
2105 | 2310 |
2106 STATIC_ASSERT(kSmiTag == 0); | 2311 STATIC_ASSERT(kSmiTag == 0); |
2107 __ JumpIfSmi(a1, &miss); | 2312 __ JumpIfSmi(a1, &miss); |
2108 | 2313 |
2109 CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, | 2314 CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, |
2110 &miss); | 2315 &miss); |
2111 } else { | 2316 } else { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2193 // Restore FCSR and fall to slow case. | 2398 // Restore FCSR and fall to slow case. |
2194 __ ctc1(a3, FCSR); | 2399 __ ctc1(a3, FCSR); |
2195 | 2400 |
2196 __ bind(&slow); | 2401 __ bind(&slow); |
2197 // Tail call the full function. We do not have to patch the receiver | 2402 // Tail call the full function. We do not have to patch the receiver |
2198 // because the function makes no use of it. | 2403 // because the function makes no use of it. |
2199 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2404 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
2200 | 2405 |
2201 __ bind(&miss); | 2406 __ bind(&miss); |
2202 // a2: function name. | 2407 // a2: function name. |
2203 MaybeObject* obj = GenerateMissBranch(); | 2408 MaybeObject* obj = TryGenerateMissBranch(); |
2204 if (obj->IsFailure()) return obj; | 2409 if (obj->IsFailure()) return obj; |
2205 | 2410 |
2206 // Return the generated code. | 2411 // Return the generated code. |
2207 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2412 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
2208 } | 2413 } |
2209 | 2414 |
2210 | 2415 |
2211 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, | 2416 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, |
2212 JSObject* holder, | 2417 JSObject* holder, |
2213 JSGlobalPropertyCell* cell, | 2418 JSGlobalPropertyCell* cell, |
2214 JSFunction* function, | 2419 JSFunction* function, |
2215 String* name) { | 2420 String* name) { |
2216 // ----------- S t a t e ------------- | 2421 // ----------- S t a t e ------------- |
2217 // -- a2 : function name | 2422 // -- a2 : function name |
2218 // -- ra : return address | 2423 // -- ra : return address |
2219 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2424 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
2220 // -- ... | 2425 // -- ... |
2221 // -- sp[argc * 4] : receiver | 2426 // -- sp[argc * 4] : receiver |
2222 // ----------------------------------- | 2427 // ----------------------------------- |
2223 | 2428 |
2224 const int argc = arguments().immediate(); | 2429 const int argc = arguments().immediate(); |
2225 | 2430 |
2226 // If the object is not a JSObject or we got an unexpected number of | 2431 // If the object is not a JSObject or we got an unexpected number of |
2227 // arguments, bail out to the regular call. | 2432 // arguments, bail out to the regular call. |
2228 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2433 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
2229 | 2434 |
2230 Label miss; | 2435 Label miss; |
2231 GenerateNameCheck(name, &miss); | 2436 GenerateNameCheck(Handle<String>(name), &miss); |
2232 | 2437 |
2233 if (cell == NULL) { | 2438 if (cell == NULL) { |
2234 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 2439 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); |
2235 | 2440 |
2236 STATIC_ASSERT(kSmiTag == 0); | 2441 STATIC_ASSERT(kSmiTag == 0); |
2237 __ JumpIfSmi(a1, &miss); | 2442 __ JumpIfSmi(a1, &miss); |
2238 | 2443 |
2239 CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, | 2444 CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, |
2240 &miss); | 2445 &miss); |
2241 } else { | 2446 } else { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2295 __ Drop(argc + 1); | 2500 __ Drop(argc + 1); |
2296 __ Ret(); | 2501 __ Ret(); |
2297 | 2502 |
2298 // Tail call the full function. We do not have to patch the receiver | 2503 // Tail call the full function. We do not have to patch the receiver |
2299 // because the function makes no use of it. | 2504 // because the function makes no use of it. |
2300 __ bind(&slow); | 2505 __ bind(&slow); |
2301 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2506 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
2302 | 2507 |
2303 __ bind(&miss); | 2508 __ bind(&miss); |
2304 // a2: function name. | 2509 // a2: function name. |
2305 MaybeObject* maybe_result = GenerateMissBranch(); | 2510 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2306 if (maybe_result->IsFailure()) return maybe_result; | 2511 if (maybe_result->IsFailure()) return maybe_result; |
2307 | 2512 |
2308 // Return the generated code. | 2513 // Return the generated code. |
2309 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2514 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
2310 } | 2515 } |
2311 | 2516 |
2312 | 2517 |
2313 MaybeObject* CallStubCompiler::CompileFastApiCall( | 2518 MaybeObject* CallStubCompiler::CompileFastApiCall( |
2314 const CallOptimization& optimization, | 2519 const CallOptimization& optimization, |
2315 Object* object, | 2520 Object* object, |
2316 JSObject* holder, | 2521 JSObject* holder, |
2317 JSGlobalPropertyCell* cell, | 2522 JSGlobalPropertyCell* cell, |
2318 JSFunction* function, | 2523 JSFunction* function, |
2319 String* name) { | 2524 String* name) { |
2320 | 2525 |
2321 Counters* counters = isolate()->counters(); | 2526 Counters* counters = isolate()->counters(); |
2322 | 2527 |
2323 ASSERT(optimization.is_simple_api_call()); | 2528 ASSERT(optimization.is_simple_api_call()); |
2324 // Bail out if object is a global object as we don't want to | 2529 // Bail out if object is a global object as we don't want to |
2325 // repatch it to global receiver. | 2530 // repatch it to global receiver. |
2326 if (object->IsGlobalObject()) return heap()->undefined_value(); | 2531 if (object->IsGlobalObject()) return heap()->undefined_value(); |
2327 if (cell != NULL) return heap()->undefined_value(); | 2532 if (cell != NULL) return heap()->undefined_value(); |
2328 if (!object->IsJSObject()) return heap()->undefined_value(); | 2533 if (!object->IsJSObject()) return heap()->undefined_value(); |
2329 int depth = optimization.GetPrototypeDepthOfExpectedType( | 2534 int depth = optimization.GetPrototypeDepthOfExpectedType( |
2330 JSObject::cast(object), holder); | 2535 JSObject::cast(object), holder); |
2331 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); | 2536 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); |
2332 | 2537 |
2333 Label miss, miss_before_stack_reserved; | 2538 Label miss, miss_before_stack_reserved; |
2334 | 2539 |
2335 GenerateNameCheck(name, &miss_before_stack_reserved); | 2540 GenerateNameCheck(Handle<String>(name), &miss_before_stack_reserved); |
2336 | 2541 |
2337 // Get the receiver from the stack. | 2542 // Get the receiver from the stack. |
2338 const int argc = arguments().immediate(); | 2543 const int argc = arguments().immediate(); |
2339 __ lw(a1, MemOperand(sp, argc * kPointerSize)); | 2544 __ lw(a1, MemOperand(sp, argc * kPointerSize)); |
2340 | 2545 |
2341 // Check that the receiver isn't a smi. | 2546 // Check that the receiver isn't a smi. |
2342 __ JumpIfSmi(a1, &miss_before_stack_reserved); | 2547 __ JumpIfSmi(a1, &miss_before_stack_reserved); |
2343 | 2548 |
2344 __ IncrementCounter(counters->call_const(), 1, a0, a3); | 2549 __ IncrementCounter(counters->call_const(), 1, a0, a3); |
2345 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3); | 2550 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3); |
2346 | 2551 |
2347 ReserveSpaceForFastApiCall(masm(), a0); | 2552 ReserveSpaceForFastApiCall(masm(), a0); |
2348 | 2553 |
2349 // Check that the maps haven't changed and find a Holder as a side effect. | 2554 // Check that the maps haven't changed and find a Holder as a side effect. |
2350 CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, | 2555 CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, |
2351 depth, &miss); | 2556 depth, &miss); |
2352 | 2557 |
2353 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); | 2558 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); |
2354 if (result->IsFailure()) return result; | 2559 if (result->IsFailure()) return result; |
2355 | 2560 |
2356 __ bind(&miss); | 2561 __ bind(&miss); |
2357 FreeSpaceForFastApiCall(masm()); | 2562 FreeSpaceForFastApiCall(masm()); |
2358 | 2563 |
2359 __ bind(&miss_before_stack_reserved); | 2564 __ bind(&miss_before_stack_reserved); |
2360 MaybeObject* maybe_result = GenerateMissBranch(); | 2565 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2361 if (maybe_result->IsFailure()) return maybe_result; | 2566 if (maybe_result->IsFailure()) return maybe_result; |
2362 | 2567 |
2363 // Return the generated code. | 2568 // Return the generated code. |
2364 return GetCode(function); | 2569 return TryGetCode(function); |
2365 } | 2570 } |
2366 | 2571 |
2367 | 2572 |
2368 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, | 2573 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, |
2369 JSObject* holder, | 2574 JSObject* holder, |
2370 JSFunction* function, | 2575 JSFunction* function, |
2371 String* name, | 2576 String* name, |
2372 CheckType check) { | 2577 CheckType check) { |
2373 // ----------- S t a t e ------------- | 2578 // ----------- S t a t e ------------- |
2374 // -- a2 : name | 2579 // -- a2 : name |
2375 // -- ra : return address | 2580 // -- ra : return address |
2376 // ----------------------------------- | 2581 // ----------------------------------- |
2377 if (HasCustomCallGenerator(function)) { | 2582 if (HasCustomCallGenerator(function)) { |
2378 MaybeObject* maybe_result = CompileCustomCall( | 2583 MaybeObject* maybe_result = CompileCustomCall( |
2379 object, holder, NULL, function, name); | 2584 object, holder, NULL, function, name); |
2380 Object* result; | 2585 Object* result; |
2381 if (!maybe_result->ToObject(&result)) return maybe_result; | 2586 if (!maybe_result->ToObject(&result)) return maybe_result; |
2382 // Undefined means bail out to regular compiler. | 2587 // Undefined means bail out to regular compiler. |
2383 if (!result->IsUndefined()) return result; | 2588 if (!result->IsUndefined()) return result; |
2384 } | 2589 } |
2385 | 2590 |
2386 Label miss; | 2591 Label miss; |
2387 | 2592 |
2388 GenerateNameCheck(name, &miss); | 2593 GenerateNameCheck(Handle<String>(name), &miss); |
2389 | 2594 |
2390 // Get the receiver from the stack. | 2595 // Get the receiver from the stack. |
2391 const int argc = arguments().immediate(); | 2596 const int argc = arguments().immediate(); |
2392 __ lw(a1, MemOperand(sp, argc * kPointerSize)); | 2597 __ lw(a1, MemOperand(sp, argc * kPointerSize)); |
2393 | 2598 |
2394 // Check that the receiver isn't a smi. | 2599 // Check that the receiver isn't a smi. |
2395 if (check != NUMBER_CHECK) { | 2600 if (check != NUMBER_CHECK) { |
2396 __ And(t1, a1, Operand(kSmiTagMask)); | 2601 __ And(t1, a1, Operand(kSmiTagMask)); |
2397 __ Branch(&miss, eq, t1, Operand(zero_reg)); | 2602 __ Branch(&miss, eq, t1, Operand(zero_reg)); |
2398 } | 2603 } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2477 CheckPrototypes(JSObject::cast(object->GetPrototype()), a0, holder, a3, | 2682 CheckPrototypes(JSObject::cast(object->GetPrototype()), a0, holder, a3, |
2478 a1, t0, name, &miss); | 2683 a1, t0, name, &miss); |
2479 } | 2684 } |
2480 break; | 2685 break; |
2481 } | 2686 } |
2482 | 2687 |
2483 default: | 2688 default: |
2484 UNREACHABLE(); | 2689 UNREACHABLE(); |
2485 } | 2690 } |
2486 | 2691 |
2487 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2692 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
2488 ? CALL_AS_FUNCTION | 2693 ? CALL_AS_FUNCTION |
2489 : CALL_AS_METHOD; | 2694 : CALL_AS_METHOD; |
2490 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); | 2695 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); |
2491 | 2696 |
2492 // Handle call cache miss. | 2697 // Handle call cache miss. |
2493 __ bind(&miss); | 2698 __ bind(&miss); |
2494 | 2699 |
2495 MaybeObject* maybe_result = GenerateMissBranch(); | 2700 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2496 if (maybe_result->IsFailure()) return maybe_result; | 2701 if (maybe_result->IsFailure()) return maybe_result; |
2497 | 2702 |
2498 // Return the generated code. | 2703 // Return the generated code. |
2499 return GetCode(function); | 2704 return TryGetCode(function); |
2500 } | 2705 } |
2501 | 2706 |
2502 | 2707 |
2503 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, | 2708 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, |
2504 JSObject* holder, | 2709 JSObject* holder, |
2505 String* name) { | 2710 String* name) { |
2506 // ----------- S t a t e ------------- | 2711 // ----------- S t a t e ------------- |
2507 // -- a2 : name | 2712 // -- a2 : name |
2508 // -- ra : return address | 2713 // -- ra : return address |
2509 // ----------------------------------- | 2714 // ----------------------------------- |
2510 | 2715 |
2511 Label miss; | 2716 Label miss; |
2512 | 2717 |
2513 GenerateNameCheck(name, &miss); | 2718 GenerateNameCheck(Handle<String>(name), &miss); |
2514 | 2719 |
2515 // Get the number of arguments. | 2720 // Get the number of arguments. |
2516 const int argc = arguments().immediate(); | 2721 const int argc = arguments().immediate(); |
2517 | 2722 |
2518 LookupResult lookup; | 2723 LookupResult lookup(isolate()); |
2519 LookupPostInterceptor(holder, name, &lookup); | 2724 LookupPostInterceptor(holder, name, &lookup); |
2520 | 2725 |
2521 // Get the receiver from the stack. | 2726 // Get the receiver from the stack. |
2522 __ lw(a1, MemOperand(sp, argc * kPointerSize)); | 2727 __ lw(a1, MemOperand(sp, argc * kPointerSize)); |
2523 | 2728 |
2524 CallInterceptorCompiler compiler(this, arguments(), a2, extra_ic_state_); | 2729 CallInterceptorCompiler compiler(this, arguments(), a2, extra_state_); |
2525 MaybeObject* result = compiler.Compile(masm(), | 2730 MaybeObject* result = compiler.Compile(masm(), |
2526 object, | 2731 object, |
2527 holder, | 2732 holder, |
2528 name, | 2733 name, |
2529 &lookup, | 2734 &lookup, |
2530 a1, | 2735 a1, |
2531 a3, | 2736 a3, |
2532 t0, | 2737 t0, |
2533 a0, | 2738 a0, |
2534 &miss); | 2739 &miss); |
2535 if (result->IsFailure()) { | 2740 if (result->IsFailure()) { |
2536 return result; | 2741 return result; |
2537 } | 2742 } |
2538 | 2743 |
2539 // Move returned value, the function to call, to a1. | 2744 // Move returned value, the function to call, to a1. |
2540 __ mov(a1, v0); | 2745 __ mov(a1, v0); |
2541 // Restore receiver. | 2746 // Restore receiver. |
2542 __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 2747 __ lw(a0, MemOperand(sp, argc * kPointerSize)); |
2543 | 2748 |
2544 GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_); | 2749 GenerateCallFunction(masm(), Handle<Object>(object), arguments(), &miss, |
| 2750 extra_state_); |
2545 | 2751 |
2546 // Handle call cache miss. | 2752 // Handle call cache miss. |
2547 __ bind(&miss); | 2753 __ bind(&miss); |
2548 MaybeObject* maybe_result = GenerateMissBranch(); | 2754 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2549 if (maybe_result->IsFailure()) return maybe_result; | 2755 if (maybe_result->IsFailure()) return maybe_result; |
2550 | 2756 |
2551 // Return the generated code. | 2757 // Return the generated code. |
2552 return GetCode(INTERCEPTOR, name); | 2758 return TryGetCode(INTERCEPTOR, name); |
2553 } | 2759 } |
2554 | 2760 |
2555 | 2761 |
2556 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, | 2762 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, |
2557 GlobalObject* holder, | 2763 GlobalObject* holder, |
2558 JSGlobalPropertyCell* cell, | 2764 JSGlobalPropertyCell* cell, |
2559 JSFunction* function, | 2765 JSFunction* function, |
2560 String* name) { | 2766 String* name) { |
2561 // ----------- S t a t e ------------- | 2767 // ----------- S t a t e ------------- |
2562 // -- a2 : name | 2768 // -- a2 : name |
2563 // -- ra : return address | 2769 // -- ra : return address |
2564 // ----------------------------------- | 2770 // ----------------------------------- |
2565 | 2771 |
2566 if (HasCustomCallGenerator(function)) { | 2772 if (HasCustomCallGenerator(function)) { |
2567 MaybeObject* maybe_result = CompileCustomCall( | 2773 MaybeObject* maybe_result = CompileCustomCall( |
2568 object, holder, cell, function, name); | 2774 object, holder, cell, function, name); |
2569 Object* result; | 2775 Object* result; |
2570 if (!maybe_result->ToObject(&result)) return maybe_result; | 2776 if (!maybe_result->ToObject(&result)) return maybe_result; |
2571 // Undefined means bail out to regular compiler. | 2777 // Undefined means bail out to regular compiler. |
2572 if (!result->IsUndefined()) return result; | 2778 if (!result->IsUndefined()) return result; |
2573 } | 2779 } |
2574 | 2780 |
2575 Label miss; | 2781 Label miss; |
2576 | 2782 |
2577 GenerateNameCheck(name, &miss); | 2783 GenerateNameCheck(Handle<String>(name), &miss); |
2578 | 2784 |
2579 // Get the number of arguments. | 2785 // Get the number of arguments. |
2580 const int argc = arguments().immediate(); | 2786 const int argc = arguments().immediate(); |
2581 | 2787 |
2582 GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2788 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
2583 GenerateLoadFunctionFromCell(cell, function, &miss); | 2789 GenerateLoadFunctionFromCell(cell, function, &miss); |
2584 | 2790 |
2585 // Patch the receiver on the stack with the global proxy if | 2791 // Patch the receiver on the stack with the global proxy if |
2586 // necessary. | 2792 // necessary. |
2587 if (object->IsGlobalObject()) { | 2793 if (object->IsGlobalObject()) { |
2588 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); | 2794 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); |
2589 __ sw(a3, MemOperand(sp, argc * kPointerSize)); | 2795 __ sw(a3, MemOperand(sp, argc * kPointerSize)); |
2590 } | 2796 } |
2591 | 2797 |
2592 // Setup the context (function already in r1). | 2798 // Setup the context (function already in r1). |
2593 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 2799 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
2594 | 2800 |
2595 // Jump to the cached code (tail call). | 2801 // Jump to the cached code (tail call). |
2596 Counters* counters = masm()->isolate()->counters(); | 2802 Counters* counters = masm()->isolate()->counters(); |
2597 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); | 2803 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); |
2598 ASSERT(function->is_compiled()); | |
2599 Handle<Code> code(function->code()); | 2804 Handle<Code> code(function->code()); |
2600 ParameterCount expected(function->shared()->formal_parameter_count()); | 2805 ParameterCount expected(function->shared()->formal_parameter_count()); |
2601 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2806 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
2602 ? CALL_AS_FUNCTION | 2807 ? CALL_AS_FUNCTION |
2603 : CALL_AS_METHOD; | 2808 : CALL_AS_METHOD; |
2604 if (V8::UseCrankshaft()) { | 2809 // We call indirectly through the code field in the function to |
2605 // TODO(kasperl): For now, we always call indirectly through the | 2810 // allow recompilation to take effect without changing any of the |
2606 // code field in the function to allow recompilation to take effect | 2811 // call sites. |
2607 // without changing any of the call sites. | 2812 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
2608 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 2813 __ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION, |
2609 __ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION, | 2814 NullCallWrapper(), call_kind); |
2610 NullCallWrapper(), call_kind); | |
2611 } else { | |
2612 __ InvokeCode(code, expected, arguments(), RelocInfo::CODE_TARGET, | |
2613 JUMP_FUNCTION, call_kind); | |
2614 } | |
2615 | 2815 |
2616 // Handle call cache miss. | 2816 // Handle call cache miss. |
2617 __ bind(&miss); | 2817 __ bind(&miss); |
2618 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3); | 2818 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3); |
2619 MaybeObject* maybe_result = GenerateMissBranch(); | 2819 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2620 if (maybe_result->IsFailure()) return maybe_result; | 2820 if (maybe_result->IsFailure()) return maybe_result; |
2621 | 2821 |
2622 // Return the generated code. | 2822 // Return the generated code. |
2623 return GetCode(NORMAL, name); | 2823 return TryGetCode(NORMAL, name); |
2624 } | 2824 } |
2625 | 2825 |
2626 | 2826 |
2627 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, | 2827 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, |
2628 int index, | 2828 int index, |
2629 Map* transition, | 2829 Map* transition, |
2630 String* name) { | 2830 String* name) { |
2631 // ----------- S t a t e ------------- | 2831 // ----------- S t a t e ------------- |
2632 // -- a0 : value | 2832 // -- a0 : value |
2633 // -- a1 : receiver | 2833 // -- a1 : receiver |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2792 __ bind(&miss); | 2992 __ bind(&miss); |
2793 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, a1, a3); | 2993 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, a1, a3); |
2794 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); | 2994 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); |
2795 __ Jump(ic, RelocInfo::CODE_TARGET); | 2995 __ Jump(ic, RelocInfo::CODE_TARGET); |
2796 | 2996 |
2797 // Return the generated code. | 2997 // Return the generated code. |
2798 return GetCode(NORMAL, name); | 2998 return GetCode(NORMAL, name); |
2799 } | 2999 } |
2800 | 3000 |
2801 | 3001 |
2802 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, | 3002 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name, |
2803 JSObject* object, | 3003 Handle<JSObject> object, |
2804 JSObject* last) { | 3004 Handle<JSObject> last) { |
2805 // ----------- S t a t e ------------- | 3005 // ----------- S t a t e ------------- |
2806 // -- a0 : receiver | 3006 // -- a0 : receiver |
2807 // -- ra : return address | 3007 // -- ra : return address |
2808 // ----------------------------------- | 3008 // ----------------------------------- |
2809 Label miss; | 3009 Label miss; |
2810 | 3010 |
2811 // Check that the receiver is not a smi. | 3011 // Check that the receiver is not a smi. |
2812 __ JumpIfSmi(a0, &miss); | 3012 __ JumpIfSmi(a0, &miss); |
2813 | 3013 |
2814 // Check the maps of the full prototype chain. | 3014 // Check the maps of the full prototype chain. |
2815 CheckPrototypes(object, a0, last, a3, a1, t0, name, &miss); | 3015 CheckPrototypes(object, a0, last, a3, a1, t0, name, &miss); |
2816 | 3016 |
2817 // If the last object in the prototype chain is a global object, | 3017 // If the last object in the prototype chain is a global object, |
2818 // check that the global property cell is empty. | 3018 // check that the global property cell is empty. |
2819 if (last->IsGlobalObject()) { | 3019 if (last->IsGlobalObject()) { |
2820 MaybeObject* cell = GenerateCheckPropertyCell(masm(), | 3020 GenerateCheckPropertyCell( |
2821 GlobalObject::cast(last), | 3021 masm(), Handle<GlobalObject>::cast(last), name, a1, &miss); |
2822 name, | |
2823 a1, | |
2824 &miss); | |
2825 if (cell->IsFailure()) { | |
2826 miss.Unuse(); | |
2827 return cell; | |
2828 } | |
2829 } | 3022 } |
2830 | 3023 |
2831 // Return undefined if maps of the full prototype chain is still the same. | 3024 // Return undefined if maps of the full prototype chain is still the same. |
2832 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); | 3025 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); |
2833 __ Ret(); | 3026 __ Ret(); |
2834 | 3027 |
2835 __ bind(&miss); | 3028 __ bind(&miss); |
2836 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3029 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2837 | 3030 |
2838 // Return the generated code. | 3031 // Return the generated code. |
2839 return GetCode(NONEXISTENT, heap()->empty_string()); | 3032 return GetCode(NONEXISTENT, factory()->empty_string()); |
2840 } | 3033 } |
2841 | 3034 |
2842 | 3035 |
2843 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, | 3036 Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object, |
2844 JSObject* holder, | 3037 Handle<JSObject> holder, |
2845 int index, | 3038 int index, |
2846 String* name) { | 3039 Handle<String> name) { |
2847 // ----------- S t a t e ------------- | 3040 // ----------- S t a t e ------------- |
2848 // -- a0 : receiver | 3041 // -- a0 : receiver |
2849 // -- a2 : name | 3042 // -- a2 : name |
2850 // -- ra : return address | 3043 // -- ra : return address |
2851 // ----------------------------------- | 3044 // ----------------------------------- |
2852 Label miss; | 3045 Label miss; |
2853 | 3046 |
2854 __ mov(v0, a0); | 3047 __ mov(v0, a0); |
2855 | 3048 |
2856 GenerateLoadField(object, holder, v0, a3, a1, t0, index, name, &miss); | 3049 GenerateLoadField(object, holder, v0, a3, a1, t0, index, name, &miss); |
(...skipping 20 matching lines...) Expand all Loading... |
2877 callback, name, &miss); | 3070 callback, name, &miss); |
2878 if (result->IsFailure()) { | 3071 if (result->IsFailure()) { |
2879 miss.Unuse(); | 3072 miss.Unuse(); |
2880 return result; | 3073 return result; |
2881 } | 3074 } |
2882 | 3075 |
2883 __ bind(&miss); | 3076 __ bind(&miss); |
2884 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3077 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2885 | 3078 |
2886 // Return the generated code. | 3079 // Return the generated code. |
2887 return GetCode(CALLBACKS, name); | 3080 return TryGetCode(CALLBACKS, name); |
2888 } | 3081 } |
2889 | 3082 |
2890 | 3083 |
2891 MaybeObject* LoadStubCompiler::CompileLoadConstant(JSObject* object, | 3084 Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object, |
2892 JSObject* holder, | 3085 Handle<JSObject> holder, |
2893 Object* value, | 3086 Handle<Object> value, |
2894 String* name) { | 3087 Handle<String> name) { |
2895 // ----------- S t a t e ------------- | 3088 // ----------- S t a t e ------------- |
2896 // -- a0 : receiver | 3089 // -- a0 : receiver |
2897 // -- a2 : name | 3090 // -- a2 : name |
2898 // -- ra : return address | 3091 // -- ra : return address |
2899 // ----------------------------------- | 3092 // ----------------------------------- |
2900 Label miss; | 3093 Label miss; |
2901 | 3094 |
2902 GenerateLoadConstant(object, holder, a0, a3, a1, t0, value, name, &miss); | 3095 GenerateLoadConstant(object, holder, a0, a3, a1, t0, value, name, &miss); |
2903 __ bind(&miss); | 3096 __ bind(&miss); |
2904 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3097 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2905 | 3098 |
2906 // Return the generated code. | 3099 // Return the generated code. |
2907 return GetCode(CONSTANT_FUNCTION, name); | 3100 return GetCode(CONSTANT_FUNCTION, name); |
2908 } | 3101 } |
2909 | 3102 |
2910 | 3103 |
2911 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, | 3104 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, |
2912 JSObject* holder, | 3105 JSObject* holder, |
2913 String* name) { | 3106 String* name) { |
2914 // ----------- S t a t e ------------- | 3107 // ----------- S t a t e ------------- |
2915 // -- a0 : receiver | 3108 // -- a0 : receiver |
2916 // -- a2 : name | 3109 // -- a2 : name |
2917 // -- ra : return address | 3110 // -- ra : return address |
2918 // -- [sp] : receiver | 3111 // -- [sp] : receiver |
2919 // ----------------------------------- | 3112 // ----------------------------------- |
2920 Label miss; | 3113 Label miss; |
2921 | 3114 |
2922 LookupResult lookup; | 3115 LookupResult lookup(isolate()); |
2923 LookupPostInterceptor(holder, name, &lookup); | 3116 LookupPostInterceptor(holder, name, &lookup); |
2924 GenerateLoadInterceptor(object, | 3117 GenerateLoadInterceptor(object, |
2925 holder, | 3118 holder, |
2926 &lookup, | 3119 &lookup, |
2927 a0, | 3120 a0, |
2928 a2, | 3121 a2, |
2929 a3, | 3122 a3, |
2930 a1, | 3123 a1, |
2931 t0, | 3124 t0, |
2932 name, | 3125 name, |
2933 &miss); | 3126 &miss); |
2934 __ bind(&miss); | 3127 __ bind(&miss); |
2935 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3128 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2936 | 3129 |
2937 // Return the generated code. | 3130 // Return the generated code. |
2938 return GetCode(INTERCEPTOR, name); | 3131 return TryGetCode(INTERCEPTOR, name); |
2939 } | 3132 } |
2940 | 3133 |
2941 | 3134 |
2942 MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object, | 3135 MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object, |
2943 GlobalObject* holder, | 3136 GlobalObject* holder, |
2944 JSGlobalPropertyCell* cell, | 3137 JSGlobalPropertyCell* cell, |
2945 String* name, | 3138 String* name, |
2946 bool is_dont_delete) { | 3139 bool is_dont_delete) { |
2947 // ----------- S t a t e ------------- | 3140 // ----------- S t a t e ------------- |
2948 // -- a0 : receiver | 3141 // -- a0 : receiver |
(...skipping 26 matching lines...) Expand all Loading... |
2975 __ mov(v0, t0); | 3168 __ mov(v0, t0); |
2976 Counters* counters = masm()->isolate()->counters(); | 3169 Counters* counters = masm()->isolate()->counters(); |
2977 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); | 3170 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); |
2978 __ Ret(); | 3171 __ Ret(); |
2979 | 3172 |
2980 __ bind(&miss); | 3173 __ bind(&miss); |
2981 __ IncrementCounter(counters->named_load_global_stub_miss(), 1, a1, a3); | 3174 __ IncrementCounter(counters->named_load_global_stub_miss(), 1, a1, a3); |
2982 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3175 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2983 | 3176 |
2984 // Return the generated code. | 3177 // Return the generated code. |
2985 return GetCode(NORMAL, name); | 3178 return TryGetCode(NORMAL, name); |
2986 } | 3179 } |
2987 | 3180 |
2988 | 3181 |
2989 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, | 3182 Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name, |
2990 JSObject* receiver, | 3183 Handle<JSObject> receiver, |
2991 JSObject* holder, | 3184 Handle<JSObject> holder, |
2992 int index) { | 3185 int index) { |
2993 // ----------- S t a t e ------------- | 3186 // ----------- S t a t e ------------- |
2994 // -- ra : return address | 3187 // -- ra : return address |
2995 // -- a0 : key | 3188 // -- a0 : key |
2996 // -- a1 : receiver | 3189 // -- a1 : receiver |
2997 // ----------------------------------- | 3190 // ----------------------------------- |
2998 Label miss; | 3191 Label miss; |
2999 | 3192 |
3000 // Check the key is the cached one. | 3193 // Check the key is the cached one. |
3001 __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); | 3194 __ Branch(&miss, ne, a0, Operand(name)); |
3002 | 3195 |
3003 GenerateLoadField(receiver, holder, a1, a2, a3, t0, index, name, &miss); | 3196 GenerateLoadField(receiver, holder, a1, a2, a3, t0, index, name, &miss); |
3004 __ bind(&miss); | 3197 __ bind(&miss); |
3005 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3198 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3006 | 3199 |
3007 return GetCode(FIELD, name); | 3200 return GetCode(FIELD, name); |
3008 } | 3201 } |
3009 | 3202 |
3010 | 3203 |
3011 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( | 3204 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( |
(...skipping 14 matching lines...) Expand all Loading... |
3026 MaybeObject* result = GenerateLoadCallback(receiver, holder, a1, a0, a2, a3, | 3219 MaybeObject* result = GenerateLoadCallback(receiver, holder, a1, a0, a2, a3, |
3027 t0, callback, name, &miss); | 3220 t0, callback, name, &miss); |
3028 if (result->IsFailure()) { | 3221 if (result->IsFailure()) { |
3029 miss.Unuse(); | 3222 miss.Unuse(); |
3030 return result; | 3223 return result; |
3031 } | 3224 } |
3032 | 3225 |
3033 __ bind(&miss); | 3226 __ bind(&miss); |
3034 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3227 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3035 | 3228 |
3036 return GetCode(CALLBACKS, name); | 3229 return TryGetCode(CALLBACKS, name); |
3037 } | 3230 } |
3038 | 3231 |
3039 | 3232 |
3040 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, | 3233 Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant( |
3041 JSObject* receiver, | 3234 Handle<String> name, |
3042 JSObject* holder, | 3235 Handle<JSObject> receiver, |
3043 Object* value) { | 3236 Handle<JSObject> holder, |
| 3237 Handle<Object> value) { |
3044 // ----------- S t a t e ------------- | 3238 // ----------- S t a t e ------------- |
3045 // -- ra : return address | 3239 // -- ra : return address |
3046 // -- a0 : key | 3240 // -- a0 : key |
3047 // -- a1 : receiver | 3241 // -- a1 : receiver |
3048 // ----------------------------------- | 3242 // ----------------------------------- |
3049 Label miss; | 3243 Label miss; |
3050 | 3244 |
3051 // Check the key is the cached one. | 3245 // Check the key is the cached one. |
3052 __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); | 3246 __ Branch(&miss, ne, a0, Operand(name)); |
3053 | 3247 |
3054 GenerateLoadConstant(receiver, holder, a1, a2, a3, t0, value, name, &miss); | 3248 GenerateLoadConstant(receiver, holder, a1, a2, a3, t0, value, name, &miss); |
3055 __ bind(&miss); | 3249 __ bind(&miss); |
3056 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3250 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3057 | 3251 |
3058 // Return the generated code. | 3252 // Return the generated code. |
3059 return GetCode(CONSTANT_FUNCTION, name); | 3253 return GetCode(CONSTANT_FUNCTION, name); |
3060 } | 3254 } |
3061 | 3255 |
3062 | 3256 |
3063 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 3257 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, |
3064 JSObject* holder, | 3258 JSObject* holder, |
3065 String* name) { | 3259 String* name) { |
3066 // ----------- S t a t e ------------- | 3260 // ----------- S t a t e ------------- |
3067 // -- ra : return address | 3261 // -- ra : return address |
3068 // -- a0 : key | 3262 // -- a0 : key |
3069 // -- a1 : receiver | 3263 // -- a1 : receiver |
3070 // ----------------------------------- | 3264 // ----------------------------------- |
3071 Label miss; | 3265 Label miss; |
3072 | 3266 |
3073 // Check the key is the cached one. | 3267 // Check the key is the cached one. |
3074 __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); | 3268 __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); |
3075 | 3269 |
3076 LookupResult lookup; | 3270 LookupResult lookup(isolate()); |
3077 LookupPostInterceptor(holder, name, &lookup); | 3271 LookupPostInterceptor(holder, name, &lookup); |
3078 GenerateLoadInterceptor(receiver, | 3272 GenerateLoadInterceptor(receiver, |
3079 holder, | 3273 holder, |
3080 &lookup, | 3274 &lookup, |
3081 a1, | 3275 a1, |
3082 a0, | 3276 a0, |
3083 a2, | 3277 a2, |
3084 a3, | 3278 a3, |
3085 t0, | 3279 t0, |
3086 name, | 3280 name, |
3087 &miss); | 3281 &miss); |
3088 __ bind(&miss); | 3282 __ bind(&miss); |
3089 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3283 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3090 | 3284 |
3091 return GetCode(INTERCEPTOR, name); | 3285 return TryGetCode(INTERCEPTOR, name); |
3092 } | 3286 } |
3093 | 3287 |
3094 | 3288 |
3095 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | 3289 Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength( |
| 3290 Handle<String> name) { |
3096 // ----------- S t a t e ------------- | 3291 // ----------- S t a t e ------------- |
3097 // -- ra : return address | 3292 // -- ra : return address |
3098 // -- a0 : key | 3293 // -- a0 : key |
3099 // -- a1 : receiver | 3294 // -- a1 : receiver |
3100 // ----------------------------------- | 3295 // ----------------------------------- |
3101 Label miss; | 3296 Label miss; |
3102 | 3297 |
3103 // Check the key is the cached one. | 3298 // Check the key is the cached one. |
3104 __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); | 3299 __ Branch(&miss, ne, a0, Operand(name)); |
3105 | 3300 |
3106 GenerateLoadArrayLength(masm(), a1, a2, &miss); | 3301 GenerateLoadArrayLength(masm(), a1, a2, &miss); |
3107 __ bind(&miss); | 3302 __ bind(&miss); |
3108 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3303 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3109 | 3304 |
3110 return GetCode(CALLBACKS, name); | 3305 return GetCode(CALLBACKS, name); |
3111 } | 3306 } |
3112 | 3307 |
3113 | 3308 |
3114 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { | 3309 Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength( |
| 3310 Handle<String> name) { |
3115 // ----------- S t a t e ------------- | 3311 // ----------- S t a t e ------------- |
3116 // -- ra : return address | 3312 // -- ra : return address |
3117 // -- a0 : key | 3313 // -- a0 : key |
3118 // -- a1 : receiver | 3314 // -- a1 : receiver |
3119 // ----------------------------------- | 3315 // ----------------------------------- |
3120 Label miss; | 3316 Label miss; |
3121 | 3317 |
3122 Counters* counters = masm()->isolate()->counters(); | 3318 Counters* counters = masm()->isolate()->counters(); |
3123 __ IncrementCounter(counters->keyed_load_string_length(), 1, a2, a3); | 3319 __ IncrementCounter(counters->keyed_load_string_length(), 1, a2, a3); |
3124 | 3320 |
3125 // Check the key is the cached one. | 3321 // Check the key is the cached one. |
3126 __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); | 3322 __ Branch(&miss, ne, a0, Operand(name)); |
3127 | 3323 |
3128 GenerateLoadStringLength(masm(), a1, a2, a3, &miss, true); | 3324 GenerateLoadStringLength(masm(), a1, a2, a3, &miss, true); |
3129 __ bind(&miss); | 3325 __ bind(&miss); |
3130 __ DecrementCounter(counters->keyed_load_string_length(), 1, a2, a3); | 3326 __ DecrementCounter(counters->keyed_load_string_length(), 1, a2, a3); |
3131 | 3327 |
3132 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3328 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3133 | 3329 |
3134 return GetCode(CALLBACKS, name); | 3330 return GetCode(CALLBACKS, name); |
3135 } | 3331 } |
3136 | 3332 |
3137 | 3333 |
3138 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { | 3334 Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype( |
| 3335 Handle<String> name) { |
3139 // ----------- S t a t e ------------- | 3336 // ----------- S t a t e ------------- |
3140 // -- ra : return address | 3337 // -- ra : return address |
3141 // -- a0 : key | 3338 // -- a0 : key |
3142 // -- a1 : receiver | 3339 // -- a1 : receiver |
3143 // ----------------------------------- | 3340 // ----------------------------------- |
3144 Label miss; | 3341 Label miss; |
3145 | 3342 |
3146 Counters* counters = masm()->isolate()->counters(); | 3343 Counters* counters = masm()->isolate()->counters(); |
3147 __ IncrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3); | 3344 __ IncrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3); |
3148 | 3345 |
3149 // Check the name hasn't changed. | 3346 // Check the name hasn't changed. |
3150 __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); | 3347 __ Branch(&miss, ne, a0, Operand(name)); |
3151 | 3348 |
3152 GenerateLoadFunctionPrototype(masm(), a1, a2, a3, &miss); | 3349 GenerateLoadFunctionPrototype(masm(), a1, a2, a3, &miss); |
3153 __ bind(&miss); | 3350 __ bind(&miss); |
3154 __ DecrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3); | 3351 __ DecrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3); |
3155 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3352 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3156 | 3353 |
3157 return GetCode(CALLBACKS, name); | 3354 return GetCode(CALLBACKS, name); |
3158 } | 3355 } |
3159 | 3356 |
3160 | 3357 |
(...skipping 10 matching lines...) Expand all Loading... |
3171 __ DispatchMap(a1, | 3368 __ DispatchMap(a1, |
3172 a2, | 3369 a2, |
3173 Handle<Map>(receiver_map), | 3370 Handle<Map>(receiver_map), |
3174 Handle<Code>(stub), | 3371 Handle<Code>(stub), |
3175 DO_SMI_CHECK); | 3372 DO_SMI_CHECK); |
3176 | 3373 |
3177 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); | 3374 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); |
3178 __ Jump(ic, RelocInfo::CODE_TARGET); | 3375 __ Jump(ic, RelocInfo::CODE_TARGET); |
3179 | 3376 |
3180 // Return the generated code. | 3377 // Return the generated code. |
3181 return GetCode(NORMAL, NULL); | 3378 return TryGetCode(NORMAL, NULL); |
3182 } | 3379 } |
3183 | 3380 |
3184 | 3381 |
3185 MaybeObject* KeyedLoadStubCompiler::CompileLoadPolymorphic( | 3382 MaybeObject* KeyedLoadStubCompiler::CompileLoadPolymorphic( |
3186 MapList* receiver_maps, | 3383 MapList* receiver_maps, |
3187 CodeList* handler_ics) { | 3384 CodeList* handler_ics) { |
3188 // ----------- S t a t e ------------- | 3385 // ----------- S t a t e ------------- |
3189 // -- ra : return address | 3386 // -- ra : return address |
3190 // -- a0 : key | 3387 // -- a0 : key |
3191 // -- a1 : receiver | 3388 // -- a1 : receiver |
3192 // ----------------------------------- | 3389 // ----------------------------------- |
3193 Label miss; | 3390 Label miss; |
3194 __ JumpIfSmi(a1, &miss); | 3391 __ JumpIfSmi(a1, &miss); |
3195 | 3392 |
3196 int receiver_count = receiver_maps->length(); | 3393 int receiver_count = receiver_maps->length(); |
3197 __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); | 3394 __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); |
3198 for (int current = 0; current < receiver_count; ++current) { | 3395 for (int current = 0; current < receiver_count; ++current) { |
3199 Handle<Map> map(receiver_maps->at(current)); | 3396 Handle<Map> map(receiver_maps->at(current)); |
3200 Handle<Code> code(handler_ics->at(current)); | 3397 Handle<Code> code(handler_ics->at(current)); |
3201 __ Jump(code, RelocInfo::CODE_TARGET, eq, a2, Operand(map)); | 3398 __ Jump(code, RelocInfo::CODE_TARGET, eq, a2, Operand(map)); |
3202 } | 3399 } |
3203 | 3400 |
3204 __ bind(&miss); | 3401 __ bind(&miss); |
3205 Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss(); | 3402 Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss(); |
3206 __ Jump(miss_ic, RelocInfo::CODE_TARGET); | 3403 __ Jump(miss_ic, RelocInfo::CODE_TARGET); |
3207 | 3404 |
3208 // Return the generated code. | 3405 // Return the generated code. |
3209 return GetCode(NORMAL, NULL, MEGAMORPHIC); | 3406 return TryGetCode(NORMAL, NULL, MEGAMORPHIC); |
3210 } | 3407 } |
3211 | 3408 |
3212 | 3409 |
3213 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, | 3410 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, |
3214 int index, | 3411 int index, |
3215 Map* transition, | 3412 Map* transition, |
3216 String* name) { | 3413 String* name) { |
3217 // ----------- S t a t e ------------- | 3414 // ----------- S t a t e ------------- |
3218 // -- a0 : value | 3415 // -- a0 : value |
3219 // -- a1 : key | 3416 // -- a1 : key |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3292 | 3489 |
3293 int receiver_count = receiver_maps->length(); | 3490 int receiver_count = receiver_maps->length(); |
3294 __ lw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); | 3491 __ lw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); |
3295 for (int i = 0; i < receiver_count; ++i) { | 3492 for (int i = 0; i < receiver_count; ++i) { |
3296 Handle<Map> map(receiver_maps->at(i)); | 3493 Handle<Map> map(receiver_maps->at(i)); |
3297 Handle<Code> code(handler_stubs->at(i)); | 3494 Handle<Code> code(handler_stubs->at(i)); |
3298 if (transitioned_maps->at(i) == NULL) { | 3495 if (transitioned_maps->at(i) == NULL) { |
3299 __ Jump(code, RelocInfo::CODE_TARGET, eq, a3, Operand(map)); | 3496 __ Jump(code, RelocInfo::CODE_TARGET, eq, a3, Operand(map)); |
3300 } else { | 3497 } else { |
3301 Label next_map; | 3498 Label next_map; |
3302 __ Branch(&next_map, eq, a3, Operand(map)); | 3499 __ Branch(&next_map, ne, a3, Operand(map)); |
3303 __ li(t0, Operand(Handle<Map>(transitioned_maps->at(i)))); | 3500 __ li(a3, Operand(Handle<Map>(transitioned_maps->at(i)))); |
3304 __ Jump(code, RelocInfo::CODE_TARGET); | 3501 __ Jump(code, RelocInfo::CODE_TARGET); |
3305 __ bind(&next_map); | 3502 __ bind(&next_map); |
3306 } | 3503 } |
3307 } | 3504 } |
3308 | 3505 |
3309 __ bind(&miss); | 3506 __ bind(&miss); |
3310 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 3507 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
3311 __ Jump(miss_ic, RelocInfo::CODE_TARGET); | 3508 __ Jump(miss_ic, RelocInfo::CODE_TARGET); |
3312 | 3509 |
3313 // Return the generated code. | 3510 // Return the generated code. |
(...skipping 1216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4530 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 4727 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
4531 __ Jump(ic_miss, RelocInfo::CODE_TARGET); | 4728 __ Jump(ic_miss, RelocInfo::CODE_TARGET); |
4532 } | 4729 } |
4533 | 4730 |
4534 | 4731 |
4535 #undef __ | 4732 #undef __ |
4536 | 4733 |
4537 } } // namespace v8::internal | 4734 } } // namespace v8::internal |
4538 | 4735 |
4539 #endif // V8_TARGET_ARCH_MIPS | 4736 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |