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 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 } else { | 531 } else { |
476 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss); | 532 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss); |
477 } | 533 } |
478 | 534 |
479 Handle<Code> ic(code); | 535 Handle<Code> ic(code); |
480 __ Jump(ic, RelocInfo::CODE_TARGET); | 536 __ Jump(ic, RelocInfo::CODE_TARGET); |
481 } | 537 } |
482 | 538 |
483 | 539 |
484 static void GenerateCallFunction(MacroAssembler* masm, | 540 static void GenerateCallFunction(MacroAssembler* masm, |
485 Object* object, | 541 Handle<Object> object, |
486 const ParameterCount& arguments, | 542 const ParameterCount& arguments, |
487 Label* miss, | 543 Label* miss, |
488 Code::ExtraICState extra_ic_state) { | 544 Code::ExtraICState extra_ic_state) { |
489 // ----------- S t a t e ------------- | 545 // ----------- S t a t e ------------- |
490 // -- a0: receiver | 546 // -- a0: receiver |
491 // -- a1: function to call | 547 // -- a1: function to call |
492 // ----------------------------------- | 548 // ----------------------------------- |
493 // Check that the function really is a function. | 549 // Check that the function really is a function. |
494 __ JumpIfSmi(a1, miss); | 550 __ JumpIfSmi(a1, miss); |
495 __ GetObjectType(a1, a3, a3); | 551 __ GetObjectType(a1, a3, a3); |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 const ParameterCount& arguments_; | 927 const ParameterCount& arguments_; |
872 Register name_; | 928 Register name_; |
873 Code::ExtraICState extra_ic_state_; | 929 Code::ExtraICState extra_ic_state_; |
874 }; | 930 }; |
875 | 931 |
876 | 932 |
877 | 933 |
878 // Generate code to check that a global property cell is empty. Create | 934 // 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 | 935 // the property cell at compilation time if no cell exists for the |
880 // property. | 936 // property. |
881 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( | 937 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
| 938 Handle<GlobalObject> global, |
| 939 Handle<String> name, |
| 940 Register scratch, |
| 941 Label* miss) { |
| 942 Handle<JSGlobalPropertyCell> cell = |
| 943 GlobalObject::EnsurePropertyCell(global, name); |
| 944 ASSERT(cell->value()->IsTheHole()); |
| 945 __ li(scratch, Operand(cell)); |
| 946 __ lw(scratch, |
| 947 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); |
| 948 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
| 949 __ Branch(miss, ne, scratch, Operand(at)); |
| 950 } |
| 951 |
| 952 |
| 953 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 954 // handlified. |
| 955 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCell( |
882 MacroAssembler* masm, | 956 MacroAssembler* masm, |
883 GlobalObject* global, | 957 GlobalObject* global, |
884 String* name, | 958 String* name, |
885 Register scratch, | 959 Register scratch, |
886 Label* miss) { | 960 Label* miss) { |
887 Object* probe; | 961 Object* probe; |
888 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); | 962 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); |
889 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 963 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
890 } | 964 } |
891 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | 965 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); |
892 ASSERT(cell->value()->IsTheHole()); | 966 ASSERT(cell->value()->IsTheHole()); |
893 __ li(scratch, Operand(Handle<Object>(cell))); | 967 __ li(scratch, Operand(Handle<Object>(cell))); |
894 __ lw(scratch, | 968 __ lw(scratch, |
895 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | 969 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); |
896 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 970 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
897 __ Branch(miss, ne, scratch, Operand(at)); | 971 __ Branch(miss, ne, scratch, Operand(at)); |
898 return cell; | 972 return cell; |
899 } | 973 } |
900 | 974 |
901 | 975 |
902 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 976 // Calls GenerateCheckPropertyCell for each global object in the prototype chain |
903 // from object to (but not including) holder. | 977 // from object to (but not including) holder. |
904 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells( | 978 static void GenerateCheckPropertyCells(MacroAssembler* masm, |
| 979 Handle<JSObject> object, |
| 980 Handle<JSObject> holder, |
| 981 Handle<String> name, |
| 982 Register scratch, |
| 983 Label* miss) { |
| 984 Handle<JSObject> current = object; |
| 985 while (!current.is_identical_to(holder)) { |
| 986 if (current->IsGlobalObject()) { |
| 987 GenerateCheckPropertyCell(masm, |
| 988 Handle<GlobalObject>::cast(current), |
| 989 name, |
| 990 scratch, |
| 991 miss); |
| 992 } |
| 993 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); |
| 994 } |
| 995 } |
| 996 |
| 997 |
| 998 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 999 // handlified. |
| 1000 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCells( |
905 MacroAssembler* masm, | 1001 MacroAssembler* masm, |
906 JSObject* object, | 1002 JSObject* object, |
907 JSObject* holder, | 1003 JSObject* holder, |
908 String* name, | 1004 String* name, |
909 Register scratch, | 1005 Register scratch, |
910 Label* miss) { | 1006 Label* miss) { |
911 JSObject* current = object; | 1007 JSObject* current = object; |
912 while (current != holder) { | 1008 while (current != holder) { |
913 if (current->IsGlobalObject()) { | 1009 if (current->IsGlobalObject()) { |
914 // Returns a cell or a failure. | 1010 // Returns a cell or a failure. |
915 MaybeObject* result = GenerateCheckPropertyCell( | 1011 MaybeObject* result = TryGenerateCheckPropertyCell( |
916 masm, | 1012 masm, |
917 GlobalObject::cast(current), | 1013 GlobalObject::cast(current), |
918 name, | 1014 name, |
919 scratch, | 1015 scratch, |
920 miss); | 1016 miss); |
921 if (result->IsFailure()) return result; | 1017 if (result->IsFailure()) return result; |
922 } | 1018 } |
923 ASSERT(current->IsJSObject()); | 1019 ASSERT(current->IsJSObject()); |
924 current = JSObject::cast(current->GetPrototype()); | 1020 current = JSObject::cast(current->GetPrototype()); |
925 } | 1021 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1040 __ nor(scratch, scratch, scratch); | 1136 __ nor(scratch, scratch, scratch); |
1041 __ and_(hiword, hiword, scratch); | 1137 __ and_(hiword, hiword, scratch); |
1042 } | 1138 } |
1043 } | 1139 } |
1044 | 1140 |
1045 | 1141 |
1046 #undef __ | 1142 #undef __ |
1047 #define __ ACCESS_MASM(masm()) | 1143 #define __ ACCESS_MASM(masm()) |
1048 | 1144 |
1049 | 1145 |
| 1146 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
| 1147 Register object_reg, |
| 1148 Handle<JSObject> holder, |
| 1149 Register holder_reg, |
| 1150 Register scratch1, |
| 1151 Register scratch2, |
| 1152 Handle<String> name, |
| 1153 int save_at_depth, |
| 1154 Label* miss) { |
| 1155 // Make sure there's no overlap between holder and object registers. |
| 1156 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
| 1157 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
| 1158 && !scratch2.is(scratch1)); |
| 1159 |
| 1160 // Keep track of the current object in register reg. |
| 1161 Register reg = object_reg; |
| 1162 int depth = 0; |
| 1163 |
| 1164 if (save_at_depth == depth) { |
| 1165 __ sw(reg, MemOperand(sp)); |
| 1166 } |
| 1167 |
| 1168 // Check the maps in the prototype chain. |
| 1169 // Traverse the prototype chain from the object and do map checks. |
| 1170 Handle<JSObject> current = object; |
| 1171 while (!current.is_identical_to(holder)) { |
| 1172 ++depth; |
| 1173 |
| 1174 // Only global objects and objects that do not require access |
| 1175 // checks are allowed in stubs. |
| 1176 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
| 1177 |
| 1178 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); |
| 1179 if (!current->HasFastProperties() && |
| 1180 !current->IsJSGlobalObject() && |
| 1181 !current->IsJSGlobalProxy()) { |
| 1182 if (!name->IsSymbol()) { |
| 1183 name = factory()->LookupSymbol(name); |
| 1184 } |
| 1185 ASSERT(current->property_dictionary()->FindEntry(*name) == |
| 1186 StringDictionary::kNotFound); |
| 1187 |
| 1188 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
| 1189 scratch1, scratch2); |
| 1190 |
| 1191 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1192 reg = holder_reg; // From now on the object will be in holder_reg. |
| 1193 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
| 1194 } else { |
| 1195 Handle<Map> current_map(current->map()); |
| 1196 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1197 // Branch on the result of the map check. |
| 1198 __ Branch(miss, ne, scratch1, Operand(current_map)); |
| 1199 // Check access rights to the global object. This has to happen after |
| 1200 // the map check so that we know that the object is actually a global |
| 1201 // object. |
| 1202 if (current->IsJSGlobalProxy()) { |
| 1203 __ CheckAccessGlobalProxy(reg, scratch2, miss); |
| 1204 } |
| 1205 reg = holder_reg; // From now on the object will be in holder_reg. |
| 1206 |
| 1207 if (heap()->InNewSpace(*prototype)) { |
| 1208 // The prototype is in new space; we cannot store a reference to it |
| 1209 // in the code. Load it from the map. |
| 1210 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
| 1211 } else { |
| 1212 // The prototype is in old space; load it directly. |
| 1213 __ li(reg, Operand(prototype)); |
| 1214 } |
| 1215 } |
| 1216 |
| 1217 if (save_at_depth == depth) { |
| 1218 __ sw(reg, MemOperand(sp)); |
| 1219 } |
| 1220 |
| 1221 // Go to the next object in the prototype chain. |
| 1222 current = prototype; |
| 1223 } |
| 1224 |
| 1225 // Log the check depth. |
| 1226 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); |
| 1227 |
| 1228 // Check the holder map. |
| 1229 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1230 __ Branch(miss, ne, scratch1, Operand(Handle<Map>(current->map()))); |
| 1231 |
| 1232 // Perform security check for access to the global object. |
| 1233 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
| 1234 if (holder->IsJSGlobalProxy()) { |
| 1235 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
| 1236 } |
| 1237 |
| 1238 // If we've skipped any global objects, it's not enough to verify that |
| 1239 // their maps haven't changed. We also need to check that the property |
| 1240 // cell for the property is still empty. |
| 1241 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); |
| 1242 |
| 1243 // Return the register containing the holder. |
| 1244 return reg; |
| 1245 } |
| 1246 |
| 1247 |
1050 Register StubCompiler::CheckPrototypes(JSObject* object, | 1248 Register StubCompiler::CheckPrototypes(JSObject* object, |
1051 Register object_reg, | 1249 Register object_reg, |
1052 JSObject* holder, | 1250 JSObject* holder, |
1053 Register holder_reg, | 1251 Register holder_reg, |
1054 Register scratch1, | 1252 Register scratch1, |
1055 Register scratch2, | 1253 Register scratch2, |
1056 String* name, | 1254 String* name, |
1057 int save_at_depth, | 1255 int save_at_depth, |
1058 Label* miss) { | 1256 Label* miss) { |
1059 // Make sure there's no overlap between holder and object registers. | 1257 // 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. | 1287 Object* lookup_result = NULL; // Initialization to please compiler. |
1090 if (!maybe_lookup_result->ToObject(&lookup_result)) { | 1288 if (!maybe_lookup_result->ToObject(&lookup_result)) { |
1091 set_failure(Failure::cast(maybe_lookup_result)); | 1289 set_failure(Failure::cast(maybe_lookup_result)); |
1092 return reg; | 1290 return reg; |
1093 } | 1291 } |
1094 name = String::cast(lookup_result); | 1292 name = String::cast(lookup_result); |
1095 } | 1293 } |
1096 ASSERT(current->property_dictionary()->FindEntry(name) == | 1294 ASSERT(current->property_dictionary()->FindEntry(name) == |
1097 StringDictionary::kNotFound); | 1295 StringDictionary::kNotFound); |
1098 | 1296 |
1099 MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(), | 1297 MaybeObject* negative_lookup = |
1100 miss, | 1298 TryGenerateDictionaryNegativeLookup(masm(), |
1101 reg, | 1299 miss, |
1102 name, | 1300 reg, |
1103 scratch1, | 1301 name, |
1104 scratch2); | 1302 scratch1, |
| 1303 scratch2); |
| 1304 |
1105 if (negative_lookup->IsFailure()) { | 1305 if (negative_lookup->IsFailure()) { |
1106 set_failure(Failure::cast(negative_lookup)); | 1306 set_failure(Failure::cast(negative_lookup)); |
1107 return reg; | 1307 return reg; |
1108 } | 1308 } |
1109 | 1309 |
1110 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1310 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
1111 reg = holder_reg; // From now the object is in holder_reg. | 1311 reg = holder_reg; // From now the object is in holder_reg. |
1112 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 1312 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
1113 } else if (heap()->InNewSpace(prototype)) { | 1313 } else if (heap()->InNewSpace(prototype)) { |
1114 // Get the map of the current object. | 1314 // 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. | 1359 // Check the holder map. |
1160 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1360 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
1161 __ Branch(miss, ne, scratch1, Operand(Handle<Map>(current->map()))); | 1361 __ Branch(miss, ne, scratch1, Operand(Handle<Map>(current->map()))); |
1162 | 1362 |
1163 // Log the check depth. | 1363 // Log the check depth. |
1164 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); | 1364 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); |
1165 // Perform security check for access to the global object. | 1365 // Perform security check for access to the global object. |
1166 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1366 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
1167 if (holder->IsJSGlobalProxy()) { | 1367 if (holder->IsJSGlobalProxy()) { |
1168 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 1368 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
1169 }; | 1369 } |
1170 | 1370 |
1171 // If we've skipped any global objects, it's not enough to verify | 1371 // 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 | 1372 // that their maps haven't changed. We also need to check that the |
1173 // property cell for the property is still empty. | 1373 // property cell for the property is still empty. |
1174 | 1374 |
1175 MaybeObject* result = GenerateCheckPropertyCells(masm(), | 1375 MaybeObject* result = TryGenerateCheckPropertyCells(masm(), |
1176 object, | 1376 object, |
1177 holder, | 1377 holder, |
1178 name, | 1378 name, |
1179 scratch1, | 1379 scratch1, |
1180 miss); | 1380 miss); |
1181 if (result->IsFailure()) set_failure(Failure::cast(result)); | 1381 if (result->IsFailure()) set_failure(Failure::cast(result)); |
1182 | 1382 |
1183 // Return the register containing the holder. | 1383 // Return the register containing the holder. |
1184 return reg; | 1384 return reg; |
1185 } | 1385 } |
1186 | 1386 |
1187 | 1387 |
1188 void StubCompiler::GenerateLoadField(JSObject* object, | 1388 void StubCompiler::GenerateLoadField(JSObject* object, |
1189 JSObject* holder, | 1389 JSObject* holder, |
1190 Register receiver, | 1390 Register receiver, |
1191 Register scratch1, | 1391 Register scratch1, |
1192 Register scratch2, | 1392 Register scratch2, |
1193 Register scratch3, | 1393 Register scratch3, |
1194 int index, | 1394 int index, |
1195 String* name, | 1395 String* name, |
1196 Label* miss) { | 1396 Label* miss) { |
1197 // Check that the receiver isn't a smi. | 1397 // Check that the receiver isn't a smi. |
1198 __ And(scratch1, receiver, Operand(kSmiTagMask)); | 1398 __ And(scratch1, receiver, Operand(kSmiTagMask)); |
1199 __ Branch(miss, eq, scratch1, Operand(zero_reg)); | 1399 __ Branch(miss, eq, scratch1, Operand(zero_reg)); |
1200 | 1400 |
1201 // Check that the maps haven't changed. | 1401 // Check that the maps haven't changed. |
1202 Register reg = | 1402 Register reg = |
1203 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, | 1403 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, |
1204 name, miss); | 1404 name, miss); |
1205 GenerateFastPropertyLoad(masm(), v0, reg, holder, index); | 1405 GenerateFastPropertyLoad(masm(), v0, reg, Handle<JSObject>(holder), index); |
1206 __ Ret(); | 1406 __ Ret(); |
1207 } | 1407 } |
1208 | 1408 |
1209 | 1409 |
1210 void StubCompiler::GenerateLoadConstant(JSObject* object, | 1410 void StubCompiler::GenerateLoadConstant(JSObject* object, |
1211 JSObject* holder, | 1411 JSObject* holder, |
1212 Register receiver, | 1412 Register receiver, |
1213 Register scratch1, | 1413 Register scratch1, |
1214 Register scratch2, | 1414 Register scratch2, |
1215 Register scratch3, | 1415 Register scratch3, |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1383 scratch2, | 1583 scratch2, |
1384 scratch3, | 1584 scratch3, |
1385 name, | 1585 name, |
1386 miss); | 1586 miss); |
1387 } | 1587 } |
1388 | 1588 |
1389 if (lookup->type() == FIELD) { | 1589 if (lookup->type() == FIELD) { |
1390 // We found FIELD property in prototype chain of interceptor's holder. | 1590 // We found FIELD property in prototype chain of interceptor's holder. |
1391 // Retrieve a field from field's holder. | 1591 // Retrieve a field from field's holder. |
1392 GenerateFastPropertyLoad(masm(), v0, holder_reg, | 1592 GenerateFastPropertyLoad(masm(), v0, holder_reg, |
1393 lookup->holder(), lookup->GetFieldIndex()); | 1593 Handle<JSObject>(lookup->holder()), |
| 1594 lookup->GetFieldIndex()); |
1394 __ Ret(); | 1595 __ Ret(); |
1395 } else { | 1596 } else { |
1396 // We found CALLBACKS property in prototype chain of interceptor's | 1597 // We found CALLBACKS property in prototype chain of interceptor's |
1397 // holder. | 1598 // holder. |
1398 ASSERT(lookup->type() == CALLBACKS); | 1599 ASSERT(lookup->type() == CALLBACKS); |
1399 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); | 1600 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); |
1400 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); | 1601 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); |
1401 ASSERT(callback != NULL); | 1602 ASSERT(callback != NULL); |
1402 ASSERT(callback->getter() != NULL); | 1603 ASSERT(callback->getter() != NULL); |
1403 | 1604 |
(...skipping 29 matching lines...) Expand all Loading... |
1433 PushInterceptorArguments(masm(), receiver, holder_reg, | 1634 PushInterceptorArguments(masm(), receiver, holder_reg, |
1434 name_reg, interceptor_holder); | 1635 name_reg, interceptor_holder); |
1435 | 1636 |
1436 ExternalReference ref = ExternalReference( | 1637 ExternalReference ref = ExternalReference( |
1437 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), masm()->isolate()); | 1638 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), masm()->isolate()); |
1438 __ TailCallExternalReference(ref, 5, 1); | 1639 __ TailCallExternalReference(ref, 5, 1); |
1439 } | 1640 } |
1440 } | 1641 } |
1441 | 1642 |
1442 | 1643 |
1443 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { | 1644 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { |
1444 if (kind_ == Code::KEYED_CALL_IC) { | 1645 if (kind_ == Code::KEYED_CALL_IC) { |
1445 __ Branch(miss, ne, a2, Operand(Handle<String>(name))); | 1646 __ Branch(miss, ne, a2, Operand(name)); |
1446 } | 1647 } |
1447 } | 1648 } |
1448 | 1649 |
1449 | 1650 |
1450 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, | 1651 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, |
1451 JSObject* holder, | 1652 JSObject* holder, |
1452 String* name, | 1653 String* name, |
1453 Label* miss) { | 1654 Label* miss) { |
1454 ASSERT(holder->IsGlobalObject()); | 1655 ASSERT(holder->IsGlobalObject()); |
1455 | 1656 |
(...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. | 1693 // Check the shared function info. Make sure it hasn't changed. |
1493 __ li(a3, Handle<SharedFunctionInfo>(function->shared())); | 1694 __ li(a3, Handle<SharedFunctionInfo>(function->shared())); |
1494 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 1695 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
1495 __ Branch(miss, ne, t0, Operand(a3)); | 1696 __ Branch(miss, ne, t0, Operand(a3)); |
1496 } else { | 1697 } else { |
1497 __ Branch(miss, ne, a1, Operand(Handle<JSFunction>(function))); | 1698 __ Branch(miss, ne, a1, Operand(Handle<JSFunction>(function))); |
1498 } | 1699 } |
1499 } | 1700 } |
1500 | 1701 |
1501 | 1702 |
1502 MaybeObject* CallStubCompiler::GenerateMissBranch() { | 1703 void CallStubCompiler::GenerateMissBranch() { |
| 1704 Handle<Code> code = |
| 1705 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), |
| 1706 kind_, |
| 1707 extra_state_); |
| 1708 __ Jump(code, RelocInfo::CODE_TARGET); |
| 1709 } |
| 1710 |
| 1711 |
| 1712 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 1713 // handlified. |
| 1714 MaybeObject* CallStubCompiler::TryGenerateMissBranch() { |
1503 MaybeObject* maybe_obj = | 1715 MaybeObject* maybe_obj = |
1504 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), | 1716 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), |
1505 kind_, | 1717 kind_, |
1506 extra_state_); | 1718 extra_state_); |
1507 Object* obj; | 1719 Object* obj; |
1508 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1720 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1509 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1721 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
1510 return obj; | 1722 return obj; |
1511 } | 1723 } |
1512 | 1724 |
1513 | 1725 |
1514 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, | 1726 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
1515 JSObject* holder, | 1727 Handle<JSObject> holder, |
1516 int index, | 1728 int index, |
1517 String* name) { | 1729 Handle<String> name) { |
1518 // ----------- S t a t e ------------- | 1730 // ----------- S t a t e ------------- |
1519 // -- a2 : name | 1731 // -- a2 : name |
1520 // -- ra : return address | 1732 // -- ra : return address |
1521 // ----------------------------------- | 1733 // ----------------------------------- |
1522 Label miss; | 1734 Label miss; |
1523 | 1735 |
1524 GenerateNameCheck(name, &miss); | 1736 GenerateNameCheck(name, &miss); |
1525 | 1737 |
1526 const int argc = arguments().immediate(); | 1738 const int argc = arguments().immediate(); |
1527 | 1739 |
1528 // Get the receiver of the function from the stack into a0. | 1740 // Get the receiver of the function from the stack into a0. |
1529 __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 1741 __ lw(a0, MemOperand(sp, argc * kPointerSize)); |
1530 // Check that the receiver isn't a smi. | 1742 // Check that the receiver isn't a smi. |
1531 __ JumpIfSmi(a0, &miss, t0); | 1743 __ JumpIfSmi(a0, &miss, t0); |
1532 | 1744 |
1533 // Do the right check and compute the holder register. | 1745 // Do the right check and compute the holder register. |
1534 Register reg = CheckPrototypes(object, a0, holder, a1, a3, t0, name, &miss); | 1746 Register reg = CheckPrototypes(object, a0, holder, a1, a3, t0, name, &miss); |
1535 GenerateFastPropertyLoad(masm(), a1, reg, holder, index); | 1747 GenerateFastPropertyLoad(masm(), a1, reg, holder, index); |
1536 | 1748 |
1537 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 1749 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); |
1538 | 1750 |
1539 // Handle call cache miss. | 1751 // Handle call cache miss. |
1540 __ bind(&miss); | 1752 __ bind(&miss); |
1541 MaybeObject* maybe_result = GenerateMissBranch(); | 1753 GenerateMissBranch(); |
1542 if (maybe_result->IsFailure()) return maybe_result; | |
1543 | 1754 |
1544 // Return the generated code. | 1755 // Return the generated code. |
1545 return GetCode(FIELD, name); | 1756 return GetCode(FIELD, name); |
1546 } | 1757 } |
1547 | 1758 |
1548 | 1759 |
1549 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, | 1760 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, |
1550 JSObject* holder, | 1761 JSObject* holder, |
1551 JSGlobalPropertyCell* cell, | 1762 JSGlobalPropertyCell* cell, |
1552 JSFunction* function, | 1763 JSFunction* function, |
1553 String* name) { | 1764 String* name) { |
1554 // ----------- S t a t e ------------- | 1765 // ----------- S t a t e ------------- |
1555 // -- a2 : name | 1766 // -- a2 : name |
1556 // -- ra : return address | 1767 // -- ra : return address |
1557 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 1768 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
1558 // -- ... | 1769 // -- ... |
1559 // -- sp[argc * 4] : receiver | 1770 // -- sp[argc * 4] : receiver |
1560 // ----------------------------------- | 1771 // ----------------------------------- |
1561 | 1772 |
1562 // If object is not an array, bail out to regular call. | 1773 // If object is not an array, bail out to regular call. |
1563 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 1774 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); |
1564 | 1775 |
1565 Label miss; | 1776 Label miss; |
1566 | 1777 |
1567 GenerateNameCheck(name, &miss); | 1778 GenerateNameCheck(Handle<String>(name), &miss); |
1568 | 1779 |
1569 Register receiver = a1; | 1780 Register receiver = a1; |
1570 | 1781 |
1571 // Get the receiver from the stack. | 1782 // Get the receiver from the stack. |
1572 const int argc = arguments().immediate(); | 1783 const int argc = arguments().immediate(); |
1573 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 1784 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); |
1574 | 1785 |
1575 // Check that the receiver isn't a smi. | 1786 // Check that the receiver isn't a smi. |
1576 __ JumpIfSmi(receiver, &miss); | 1787 __ JumpIfSmi(receiver, &miss); |
1577 | 1788 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1723 } | 1934 } |
1724 __ bind(&call_builtin); | 1935 __ bind(&call_builtin); |
1725 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, | 1936 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, |
1726 masm()->isolate()), | 1937 masm()->isolate()), |
1727 argc + 1, | 1938 argc + 1, |
1728 1); | 1939 1); |
1729 } | 1940 } |
1730 | 1941 |
1731 // Handle call cache miss. | 1942 // Handle call cache miss. |
1732 __ bind(&miss); | 1943 __ bind(&miss); |
1733 MaybeObject* maybe_result = GenerateMissBranch(); | 1944 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1734 if (maybe_result->IsFailure()) return maybe_result; | 1945 if (maybe_result->IsFailure()) return maybe_result; |
1735 | 1946 |
1736 // Return the generated code. | 1947 // Return the generated code. |
1737 return GetCode(function); | 1948 return TryGetCode(function); |
1738 } | 1949 } |
1739 | 1950 |
1740 | 1951 |
1741 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, | 1952 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, |
1742 JSObject* holder, | 1953 JSObject* holder, |
1743 JSGlobalPropertyCell* cell, | 1954 JSGlobalPropertyCell* cell, |
1744 JSFunction* function, | 1955 JSFunction* function, |
1745 String* name) { | 1956 String* name) { |
1746 // ----------- S t a t e ------------- | 1957 // ----------- S t a t e ------------- |
1747 // -- a2 : name | 1958 // -- a2 : name |
1748 // -- ra : return address | 1959 // -- ra : return address |
1749 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 1960 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
1750 // -- ... | 1961 // -- ... |
1751 // -- sp[argc * 4] : receiver | 1962 // -- sp[argc * 4] : receiver |
1752 // ----------------------------------- | 1963 // ----------------------------------- |
1753 | 1964 |
1754 // If object is not an array, bail out to regular call. | 1965 // If object is not an array, bail out to regular call. |
1755 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 1966 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); |
1756 | 1967 |
1757 Label miss, return_undefined, call_builtin; | 1968 Label miss, return_undefined, call_builtin; |
1758 | 1969 |
1759 Register receiver = a1; | 1970 Register receiver = a1; |
1760 Register elements = a3; | 1971 Register elements = a3; |
1761 | 1972 |
1762 GenerateNameCheck(name, &miss); | 1973 GenerateNameCheck(Handle<String>(name), &miss); |
1763 | 1974 |
1764 // Get the receiver from the stack. | 1975 // Get the receiver from the stack. |
1765 const int argc = arguments().immediate(); | 1976 const int argc = arguments().immediate(); |
1766 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 1977 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); |
1767 | 1978 |
1768 // Check that the receiver isn't a smi. | 1979 // Check that the receiver isn't a smi. |
1769 __ JumpIfSmi(receiver, &miss); | 1980 __ JumpIfSmi(receiver, &miss); |
1770 | 1981 |
1771 // Check that the maps haven't changed. | 1982 // Check that the maps haven't changed. |
1772 CheckPrototypes(JSObject::cast(object), | 1983 CheckPrototypes(JSObject::cast(object), |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1812 __ Ret(); | 2023 __ Ret(); |
1813 | 2024 |
1814 __ bind(&call_builtin); | 2025 __ bind(&call_builtin); |
1815 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop, | 2026 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop, |
1816 masm()->isolate()), | 2027 masm()->isolate()), |
1817 argc + 1, | 2028 argc + 1, |
1818 1); | 2029 1); |
1819 | 2030 |
1820 // Handle call cache miss. | 2031 // Handle call cache miss. |
1821 __ bind(&miss); | 2032 __ bind(&miss); |
1822 MaybeObject* maybe_result = GenerateMissBranch(); | 2033 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1823 if (maybe_result->IsFailure()) return maybe_result; | 2034 if (maybe_result->IsFailure()) return maybe_result; |
1824 | 2035 |
1825 // Return the generated code. | 2036 // Return the generated code. |
1826 return GetCode(function); | 2037 return TryGetCode(function); |
1827 } | 2038 } |
1828 | 2039 |
1829 | 2040 |
1830 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( | 2041 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( |
1831 Object* object, | 2042 Object* object, |
1832 JSObject* holder, | 2043 JSObject* holder, |
1833 JSGlobalPropertyCell* cell, | 2044 JSGlobalPropertyCell* cell, |
1834 JSFunction* function, | 2045 JSFunction* function, |
1835 String* name) { | 2046 String* name) { |
1836 // ----------- S t a t e ------------- | 2047 // ----------- S t a t e ------------- |
(...skipping 14 matching lines...) Expand all Loading... |
1851 Label index_out_of_range; | 2062 Label index_out_of_range; |
1852 | 2063 |
1853 Label* index_out_of_range_label = &index_out_of_range; | 2064 Label* index_out_of_range_label = &index_out_of_range; |
1854 | 2065 |
1855 if (kind_ == Code::CALL_IC && | 2066 if (kind_ == Code::CALL_IC && |
1856 (CallICBase::StringStubState::decode(extra_state_) == | 2067 (CallICBase::StringStubState::decode(extra_state_) == |
1857 DEFAULT_STRING_STUB)) { | 2068 DEFAULT_STRING_STUB)) { |
1858 index_out_of_range_label = &miss; | 2069 index_out_of_range_label = &miss; |
1859 } | 2070 } |
1860 | 2071 |
1861 GenerateNameCheck(name, &name_miss); | 2072 GenerateNameCheck(Handle<String>(name), &name_miss); |
1862 | 2073 |
1863 // Check that the maps starting from the prototype haven't changed. | 2074 // Check that the maps starting from the prototype haven't changed. |
1864 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2075 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1865 Context::STRING_FUNCTION_INDEX, | 2076 Context::STRING_FUNCTION_INDEX, |
1866 v0, | 2077 v0, |
1867 &miss); | 2078 &miss); |
1868 ASSERT(object != holder); | 2079 ASSERT(object != holder); |
1869 CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, | 2080 CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, |
1870 a1, a3, t0, name, &miss); | 2081 a1, a3, t0, name, &miss); |
1871 | 2082 |
(...skipping 27 matching lines...) Expand all Loading... |
1899 __ bind(&index_out_of_range); | 2110 __ bind(&index_out_of_range); |
1900 __ LoadRoot(v0, Heap::kNanValueRootIndex); | 2111 __ LoadRoot(v0, Heap::kNanValueRootIndex); |
1901 __ Drop(argc + 1); | 2112 __ Drop(argc + 1); |
1902 __ Ret(); | 2113 __ Ret(); |
1903 } | 2114 } |
1904 | 2115 |
1905 __ bind(&miss); | 2116 __ bind(&miss); |
1906 // Restore function name in a2. | 2117 // Restore function name in a2. |
1907 __ li(a2, Handle<String>(name)); | 2118 __ li(a2, Handle<String>(name)); |
1908 __ bind(&name_miss); | 2119 __ bind(&name_miss); |
1909 MaybeObject* maybe_result = GenerateMissBranch(); | 2120 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1910 if (maybe_result->IsFailure()) return maybe_result; | 2121 if (maybe_result->IsFailure()) return maybe_result; |
1911 | 2122 |
1912 // Return the generated code. | 2123 // Return the generated code. |
1913 return GetCode(function); | 2124 return TryGetCode(function); |
1914 } | 2125 } |
1915 | 2126 |
1916 | 2127 |
1917 MaybeObject* CallStubCompiler::CompileStringCharAtCall( | 2128 MaybeObject* CallStubCompiler::CompileStringCharAtCall( |
1918 Object* object, | 2129 Object* object, |
1919 JSObject* holder, | 2130 JSObject* holder, |
1920 JSGlobalPropertyCell* cell, | 2131 JSGlobalPropertyCell* cell, |
1921 JSFunction* function, | 2132 JSFunction* function, |
1922 String* name) { | 2133 String* name) { |
1923 // ----------- S t a t e ------------- | 2134 // ----------- S t a t e ------------- |
(...skipping 13 matching lines...) Expand all Loading... |
1937 Label name_miss; | 2148 Label name_miss; |
1938 Label index_out_of_range; | 2149 Label index_out_of_range; |
1939 Label* index_out_of_range_label = &index_out_of_range; | 2150 Label* index_out_of_range_label = &index_out_of_range; |
1940 | 2151 |
1941 if (kind_ == Code::CALL_IC && | 2152 if (kind_ == Code::CALL_IC && |
1942 (CallICBase::StringStubState::decode(extra_state_) == | 2153 (CallICBase::StringStubState::decode(extra_state_) == |
1943 DEFAULT_STRING_STUB)) { | 2154 DEFAULT_STRING_STUB)) { |
1944 index_out_of_range_label = &miss; | 2155 index_out_of_range_label = &miss; |
1945 } | 2156 } |
1946 | 2157 |
1947 GenerateNameCheck(name, &name_miss); | 2158 GenerateNameCheck(Handle<String>(name), &name_miss); |
1948 | 2159 |
1949 // Check that the maps starting from the prototype haven't changed. | 2160 // Check that the maps starting from the prototype haven't changed. |
1950 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2161 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1951 Context::STRING_FUNCTION_INDEX, | 2162 Context::STRING_FUNCTION_INDEX, |
1952 v0, | 2163 v0, |
1953 &miss); | 2164 &miss); |
1954 ASSERT(object != holder); | 2165 ASSERT(object != holder); |
1955 CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, | 2166 CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, |
1956 a1, a3, t0, name, &miss); | 2167 a1, a3, t0, name, &miss); |
1957 | 2168 |
(...skipping 29 matching lines...) Expand all Loading... |
1987 __ bind(&index_out_of_range); | 2198 __ bind(&index_out_of_range); |
1988 __ LoadRoot(v0, Heap::kEmptyStringRootIndex); | 2199 __ LoadRoot(v0, Heap::kEmptyStringRootIndex); |
1989 __ Drop(argc + 1); | 2200 __ Drop(argc + 1); |
1990 __ Ret(); | 2201 __ Ret(); |
1991 } | 2202 } |
1992 | 2203 |
1993 __ bind(&miss); | 2204 __ bind(&miss); |
1994 // Restore function name in a2. | 2205 // Restore function name in a2. |
1995 __ li(a2, Handle<String>(name)); | 2206 __ li(a2, Handle<String>(name)); |
1996 __ bind(&name_miss); | 2207 __ bind(&name_miss); |
1997 MaybeObject* maybe_result = GenerateMissBranch(); | 2208 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1998 if (maybe_result->IsFailure()) return maybe_result; | 2209 if (maybe_result->IsFailure()) return maybe_result; |
1999 | 2210 |
2000 // Return the generated code. | 2211 // Return the generated code. |
2001 return GetCode(function); | 2212 return TryGetCode(function); |
2002 } | 2213 } |
2003 | 2214 |
2004 | 2215 |
2005 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( | 2216 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( |
2006 Object* object, | 2217 Object* object, |
2007 JSObject* holder, | 2218 JSObject* holder, |
2008 JSGlobalPropertyCell* cell, | 2219 JSGlobalPropertyCell* cell, |
2009 JSFunction* function, | 2220 JSFunction* function, |
2010 String* name) { | 2221 String* name) { |
2011 // ----------- S t a t e ------------- | 2222 // ----------- S t a t e ------------- |
2012 // -- a2 : function name | 2223 // -- a2 : function name |
2013 // -- ra : return address | 2224 // -- ra : return address |
2014 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2225 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
2015 // -- ... | 2226 // -- ... |
2016 // -- sp[argc * 4] : receiver | 2227 // -- sp[argc * 4] : receiver |
2017 // ----------------------------------- | 2228 // ----------------------------------- |
2018 | 2229 |
2019 const int argc = arguments().immediate(); | 2230 const int argc = arguments().immediate(); |
2020 | 2231 |
2021 // If the object is not a JSObject or we got an unexpected number of | 2232 // If the object is not a JSObject or we got an unexpected number of |
2022 // arguments, bail out to the regular call. | 2233 // arguments, bail out to the regular call. |
2023 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2234 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
2024 | 2235 |
2025 Label miss; | 2236 Label miss; |
2026 GenerateNameCheck(name, &miss); | 2237 GenerateNameCheck(Handle<String>(name), &miss); |
2027 | 2238 |
2028 if (cell == NULL) { | 2239 if (cell == NULL) { |
2029 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 2240 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); |
2030 | 2241 |
2031 STATIC_ASSERT(kSmiTag == 0); | 2242 STATIC_ASSERT(kSmiTag == 0); |
2032 __ JumpIfSmi(a1, &miss); | 2243 __ JumpIfSmi(a1, &miss); |
2033 | 2244 |
2034 CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, | 2245 CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, |
2035 &miss); | 2246 &miss); |
2036 } else { | 2247 } else { |
(...skipping 22 matching lines...) Expand all Loading... |
2059 StubRuntimeCallHelper call_helper; | 2270 StubRuntimeCallHelper call_helper; |
2060 char_from_code_generator.GenerateSlow(masm(), call_helper); | 2271 char_from_code_generator.GenerateSlow(masm(), call_helper); |
2061 | 2272 |
2062 // Tail call the full function. We do not have to patch the receiver | 2273 // Tail call the full function. We do not have to patch the receiver |
2063 // because the function makes no use of it. | 2274 // because the function makes no use of it. |
2064 __ bind(&slow); | 2275 __ bind(&slow); |
2065 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2276 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
2066 | 2277 |
2067 __ bind(&miss); | 2278 __ bind(&miss); |
2068 // a2: function name. | 2279 // a2: function name. |
2069 MaybeObject* maybe_result = GenerateMissBranch(); | 2280 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2070 if (maybe_result->IsFailure()) return maybe_result; | 2281 if (maybe_result->IsFailure()) return maybe_result; |
2071 | 2282 |
2072 // Return the generated code. | 2283 // Return the generated code. |
2073 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2284 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
2074 } | 2285 } |
2075 | 2286 |
2076 | 2287 |
2077 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, | 2288 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, |
2078 JSObject* holder, | 2289 JSObject* holder, |
2079 JSGlobalPropertyCell* cell, | 2290 JSGlobalPropertyCell* cell, |
2080 JSFunction* function, | 2291 JSFunction* function, |
2081 String* name) { | 2292 String* name) { |
2082 // ----------- S t a t e ------------- | 2293 // ----------- S t a t e ------------- |
2083 // -- a2 : function name | 2294 // -- a2 : function name |
2084 // -- ra : return address | 2295 // -- ra : return address |
2085 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2296 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
2086 // -- ... | 2297 // -- ... |
2087 // -- sp[argc * 4] : receiver | 2298 // -- sp[argc * 4] : receiver |
2088 // ----------------------------------- | 2299 // ----------------------------------- |
2089 | 2300 |
2090 if (!CpuFeatures::IsSupported(FPU)) | 2301 if (!CpuFeatures::IsSupported(FPU)) |
2091 return heap()->undefined_value(); | 2302 return heap()->undefined_value(); |
2092 CpuFeatures::Scope scope_fpu(FPU); | 2303 CpuFeatures::Scope scope_fpu(FPU); |
2093 | 2304 |
2094 const int argc = arguments().immediate(); | 2305 const int argc = arguments().immediate(); |
2095 | 2306 |
2096 // If the object is not a JSObject or we got an unexpected number of | 2307 // If the object is not a JSObject or we got an unexpected number of |
2097 // arguments, bail out to the regular call. | 2308 // arguments, bail out to the regular call. |
2098 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2309 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
2099 | 2310 |
2100 Label miss, slow; | 2311 Label miss, slow; |
2101 GenerateNameCheck(name, &miss); | 2312 GenerateNameCheck(Handle<String>(name), &miss); |
2102 | 2313 |
2103 if (cell == NULL) { | 2314 if (cell == NULL) { |
2104 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 2315 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); |
2105 | 2316 |
2106 STATIC_ASSERT(kSmiTag == 0); | 2317 STATIC_ASSERT(kSmiTag == 0); |
2107 __ JumpIfSmi(a1, &miss); | 2318 __ JumpIfSmi(a1, &miss); |
2108 | 2319 |
2109 CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, | 2320 CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, |
2110 &miss); | 2321 &miss); |
2111 } else { | 2322 } else { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2193 // Restore FCSR and fall to slow case. | 2404 // Restore FCSR and fall to slow case. |
2194 __ ctc1(a3, FCSR); | 2405 __ ctc1(a3, FCSR); |
2195 | 2406 |
2196 __ bind(&slow); | 2407 __ bind(&slow); |
2197 // Tail call the full function. We do not have to patch the receiver | 2408 // Tail call the full function. We do not have to patch the receiver |
2198 // because the function makes no use of it. | 2409 // because the function makes no use of it. |
2199 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2410 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
2200 | 2411 |
2201 __ bind(&miss); | 2412 __ bind(&miss); |
2202 // a2: function name. | 2413 // a2: function name. |
2203 MaybeObject* obj = GenerateMissBranch(); | 2414 MaybeObject* obj = TryGenerateMissBranch(); |
2204 if (obj->IsFailure()) return obj; | 2415 if (obj->IsFailure()) return obj; |
2205 | 2416 |
2206 // Return the generated code. | 2417 // Return the generated code. |
2207 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2418 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
2208 } | 2419 } |
2209 | 2420 |
2210 | 2421 |
2211 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, | 2422 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, |
2212 JSObject* holder, | 2423 JSObject* holder, |
2213 JSGlobalPropertyCell* cell, | 2424 JSGlobalPropertyCell* cell, |
2214 JSFunction* function, | 2425 JSFunction* function, |
2215 String* name) { | 2426 String* name) { |
2216 // ----------- S t a t e ------------- | 2427 // ----------- S t a t e ------------- |
2217 // -- a2 : function name | 2428 // -- a2 : function name |
2218 // -- ra : return address | 2429 // -- ra : return address |
2219 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2430 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
2220 // -- ... | 2431 // -- ... |
2221 // -- sp[argc * 4] : receiver | 2432 // -- sp[argc * 4] : receiver |
2222 // ----------------------------------- | 2433 // ----------------------------------- |
2223 | 2434 |
2224 const int argc = arguments().immediate(); | 2435 const int argc = arguments().immediate(); |
2225 | 2436 |
2226 // If the object is not a JSObject or we got an unexpected number of | 2437 // If the object is not a JSObject or we got an unexpected number of |
2227 // arguments, bail out to the regular call. | 2438 // arguments, bail out to the regular call. |
2228 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2439 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
2229 | 2440 |
2230 Label miss; | 2441 Label miss; |
2231 GenerateNameCheck(name, &miss); | 2442 GenerateNameCheck(Handle<String>(name), &miss); |
2232 | 2443 |
2233 if (cell == NULL) { | 2444 if (cell == NULL) { |
2234 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 2445 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); |
2235 | 2446 |
2236 STATIC_ASSERT(kSmiTag == 0); | 2447 STATIC_ASSERT(kSmiTag == 0); |
2237 __ JumpIfSmi(a1, &miss); | 2448 __ JumpIfSmi(a1, &miss); |
2238 | 2449 |
2239 CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, | 2450 CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, |
2240 &miss); | 2451 &miss); |
2241 } else { | 2452 } else { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2295 __ Drop(argc + 1); | 2506 __ Drop(argc + 1); |
2296 __ Ret(); | 2507 __ Ret(); |
2297 | 2508 |
2298 // Tail call the full function. We do not have to patch the receiver | 2509 // Tail call the full function. We do not have to patch the receiver |
2299 // because the function makes no use of it. | 2510 // because the function makes no use of it. |
2300 __ bind(&slow); | 2511 __ bind(&slow); |
2301 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2512 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
2302 | 2513 |
2303 __ bind(&miss); | 2514 __ bind(&miss); |
2304 // a2: function name. | 2515 // a2: function name. |
2305 MaybeObject* maybe_result = GenerateMissBranch(); | 2516 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2306 if (maybe_result->IsFailure()) return maybe_result; | 2517 if (maybe_result->IsFailure()) return maybe_result; |
2307 | 2518 |
2308 // Return the generated code. | 2519 // Return the generated code. |
2309 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2520 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
2310 } | 2521 } |
2311 | 2522 |
2312 | 2523 |
2313 MaybeObject* CallStubCompiler::CompileFastApiCall( | 2524 MaybeObject* CallStubCompiler::CompileFastApiCall( |
2314 const CallOptimization& optimization, | 2525 const CallOptimization& optimization, |
2315 Object* object, | 2526 Object* object, |
2316 JSObject* holder, | 2527 JSObject* holder, |
2317 JSGlobalPropertyCell* cell, | 2528 JSGlobalPropertyCell* cell, |
2318 JSFunction* function, | 2529 JSFunction* function, |
2319 String* name) { | 2530 String* name) { |
2320 | 2531 |
2321 Counters* counters = isolate()->counters(); | 2532 Counters* counters = isolate()->counters(); |
2322 | 2533 |
2323 ASSERT(optimization.is_simple_api_call()); | 2534 ASSERT(optimization.is_simple_api_call()); |
2324 // Bail out if object is a global object as we don't want to | 2535 // Bail out if object is a global object as we don't want to |
2325 // repatch it to global receiver. | 2536 // repatch it to global receiver. |
2326 if (object->IsGlobalObject()) return heap()->undefined_value(); | 2537 if (object->IsGlobalObject()) return heap()->undefined_value(); |
2327 if (cell != NULL) return heap()->undefined_value(); | 2538 if (cell != NULL) return heap()->undefined_value(); |
2328 if (!object->IsJSObject()) return heap()->undefined_value(); | 2539 if (!object->IsJSObject()) return heap()->undefined_value(); |
2329 int depth = optimization.GetPrototypeDepthOfExpectedType( | 2540 int depth = optimization.GetPrototypeDepthOfExpectedType( |
2330 JSObject::cast(object), holder); | 2541 JSObject::cast(object), holder); |
2331 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); | 2542 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); |
2332 | 2543 |
2333 Label miss, miss_before_stack_reserved; | 2544 Label miss, miss_before_stack_reserved; |
2334 | 2545 |
2335 GenerateNameCheck(name, &miss_before_stack_reserved); | 2546 GenerateNameCheck(Handle<String>(name), &miss_before_stack_reserved); |
2336 | 2547 |
2337 // Get the receiver from the stack. | 2548 // Get the receiver from the stack. |
2338 const int argc = arguments().immediate(); | 2549 const int argc = arguments().immediate(); |
2339 __ lw(a1, MemOperand(sp, argc * kPointerSize)); | 2550 __ lw(a1, MemOperand(sp, argc * kPointerSize)); |
2340 | 2551 |
2341 // Check that the receiver isn't a smi. | 2552 // Check that the receiver isn't a smi. |
2342 __ JumpIfSmi(a1, &miss_before_stack_reserved); | 2553 __ JumpIfSmi(a1, &miss_before_stack_reserved); |
2343 | 2554 |
2344 __ IncrementCounter(counters->call_const(), 1, a0, a3); | 2555 __ IncrementCounter(counters->call_const(), 1, a0, a3); |
2345 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3); | 2556 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3); |
2346 | 2557 |
2347 ReserveSpaceForFastApiCall(masm(), a0); | 2558 ReserveSpaceForFastApiCall(masm(), a0); |
2348 | 2559 |
2349 // Check that the maps haven't changed and find a Holder as a side effect. | 2560 // 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, | 2561 CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, |
2351 depth, &miss); | 2562 depth, &miss); |
2352 | 2563 |
2353 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); | 2564 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); |
2354 if (result->IsFailure()) return result; | 2565 if (result->IsFailure()) return result; |
2355 | 2566 |
2356 __ bind(&miss); | 2567 __ bind(&miss); |
2357 FreeSpaceForFastApiCall(masm()); | 2568 FreeSpaceForFastApiCall(masm()); |
2358 | 2569 |
2359 __ bind(&miss_before_stack_reserved); | 2570 __ bind(&miss_before_stack_reserved); |
2360 MaybeObject* maybe_result = GenerateMissBranch(); | 2571 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2361 if (maybe_result->IsFailure()) return maybe_result; | 2572 if (maybe_result->IsFailure()) return maybe_result; |
2362 | 2573 |
2363 // Return the generated code. | 2574 // Return the generated code. |
2364 return GetCode(function); | 2575 return TryGetCode(function); |
2365 } | 2576 } |
2366 | 2577 |
2367 | 2578 |
2368 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, | 2579 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, |
2369 JSObject* holder, | 2580 JSObject* holder, |
2370 JSFunction* function, | 2581 JSFunction* function, |
2371 String* name, | 2582 String* name, |
2372 CheckType check) { | 2583 CheckType check) { |
2373 // ----------- S t a t e ------------- | 2584 // ----------- S t a t e ------------- |
2374 // -- a2 : name | 2585 // -- a2 : name |
2375 // -- ra : return address | 2586 // -- ra : return address |
2376 // ----------------------------------- | 2587 // ----------------------------------- |
2377 if (HasCustomCallGenerator(function)) { | 2588 if (HasCustomCallGenerator(function)) { |
2378 MaybeObject* maybe_result = CompileCustomCall( | 2589 MaybeObject* maybe_result = CompileCustomCall( |
2379 object, holder, NULL, function, name); | 2590 object, holder, NULL, function, name); |
2380 Object* result; | 2591 Object* result; |
2381 if (!maybe_result->ToObject(&result)) return maybe_result; | 2592 if (!maybe_result->ToObject(&result)) return maybe_result; |
2382 // Undefined means bail out to regular compiler. | 2593 // Undefined means bail out to regular compiler. |
2383 if (!result->IsUndefined()) return result; | 2594 if (!result->IsUndefined()) return result; |
2384 } | 2595 } |
2385 | 2596 |
2386 Label miss; | 2597 Label miss; |
2387 | 2598 |
2388 GenerateNameCheck(name, &miss); | 2599 GenerateNameCheck(Handle<String>(name), &miss); |
2389 | 2600 |
2390 // Get the receiver from the stack. | 2601 // Get the receiver from the stack. |
2391 const int argc = arguments().immediate(); | 2602 const int argc = arguments().immediate(); |
2392 __ lw(a1, MemOperand(sp, argc * kPointerSize)); | 2603 __ lw(a1, MemOperand(sp, argc * kPointerSize)); |
2393 | 2604 |
2394 // Check that the receiver isn't a smi. | 2605 // Check that the receiver isn't a smi. |
2395 if (check != NUMBER_CHECK) { | 2606 if (check != NUMBER_CHECK) { |
2396 __ And(t1, a1, Operand(kSmiTagMask)); | 2607 __ And(t1, a1, Operand(kSmiTagMask)); |
2397 __ Branch(&miss, eq, t1, Operand(zero_reg)); | 2608 __ Branch(&miss, eq, t1, Operand(zero_reg)); |
2398 } | 2609 } |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2485 } | 2696 } |
2486 | 2697 |
2487 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2698 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
2488 ? CALL_AS_FUNCTION | 2699 ? CALL_AS_FUNCTION |
2489 : CALL_AS_METHOD; | 2700 : CALL_AS_METHOD; |
2490 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); | 2701 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); |
2491 | 2702 |
2492 // Handle call cache miss. | 2703 // Handle call cache miss. |
2493 __ bind(&miss); | 2704 __ bind(&miss); |
2494 | 2705 |
2495 MaybeObject* maybe_result = GenerateMissBranch(); | 2706 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2496 if (maybe_result->IsFailure()) return maybe_result; | 2707 if (maybe_result->IsFailure()) return maybe_result; |
2497 | 2708 |
2498 // Return the generated code. | 2709 // Return the generated code. |
2499 return GetCode(function); | 2710 return TryGetCode(function); |
2500 } | 2711 } |
2501 | 2712 |
2502 | 2713 |
2503 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, | 2714 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, |
2504 JSObject* holder, | 2715 JSObject* holder, |
2505 String* name) { | 2716 String* name) { |
2506 // ----------- S t a t e ------------- | 2717 // ----------- S t a t e ------------- |
2507 // -- a2 : name | 2718 // -- a2 : name |
2508 // -- ra : return address | 2719 // -- ra : return address |
2509 // ----------------------------------- | 2720 // ----------------------------------- |
2510 | 2721 |
2511 Label miss; | 2722 Label miss; |
2512 | 2723 |
2513 GenerateNameCheck(name, &miss); | 2724 GenerateNameCheck(Handle<String>(name), &miss); |
2514 | 2725 |
2515 // Get the number of arguments. | 2726 // Get the number of arguments. |
2516 const int argc = arguments().immediate(); | 2727 const int argc = arguments().immediate(); |
2517 | 2728 |
2518 LookupResult lookup(isolate()); | 2729 LookupResult lookup(isolate()); |
2519 LookupPostInterceptor(holder, name, &lookup); | 2730 LookupPostInterceptor(holder, name, &lookup); |
2520 | 2731 |
2521 // Get the receiver from the stack. | 2732 // Get the receiver from the stack. |
2522 __ lw(a1, MemOperand(sp, argc * kPointerSize)); | 2733 __ lw(a1, MemOperand(sp, argc * kPointerSize)); |
2523 | 2734 |
(...skipping 10 matching lines...) Expand all Loading... |
2534 &miss); | 2745 &miss); |
2535 if (result->IsFailure()) { | 2746 if (result->IsFailure()) { |
2536 return result; | 2747 return result; |
2537 } | 2748 } |
2538 | 2749 |
2539 // Move returned value, the function to call, to a1. | 2750 // Move returned value, the function to call, to a1. |
2540 __ mov(a1, v0); | 2751 __ mov(a1, v0); |
2541 // Restore receiver. | 2752 // Restore receiver. |
2542 __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 2753 __ lw(a0, MemOperand(sp, argc * kPointerSize)); |
2543 | 2754 |
2544 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 2755 GenerateCallFunction(masm(), Handle<Object>(object), arguments(), &miss, |
| 2756 extra_state_); |
2545 | 2757 |
2546 // Handle call cache miss. | 2758 // Handle call cache miss. |
2547 __ bind(&miss); | 2759 __ bind(&miss); |
2548 MaybeObject* maybe_result = GenerateMissBranch(); | 2760 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2549 if (maybe_result->IsFailure()) return maybe_result; | 2761 if (maybe_result->IsFailure()) return maybe_result; |
2550 | 2762 |
2551 // Return the generated code. | 2763 // Return the generated code. |
2552 return GetCode(INTERCEPTOR, name); | 2764 return TryGetCode(INTERCEPTOR, name); |
2553 } | 2765 } |
2554 | 2766 |
2555 | 2767 |
2556 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, | 2768 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, |
2557 GlobalObject* holder, | 2769 GlobalObject* holder, |
2558 JSGlobalPropertyCell* cell, | 2770 JSGlobalPropertyCell* cell, |
2559 JSFunction* function, | 2771 JSFunction* function, |
2560 String* name) { | 2772 String* name) { |
2561 // ----------- S t a t e ------------- | 2773 // ----------- S t a t e ------------- |
2562 // -- a2 : name | 2774 // -- a2 : name |
2563 // -- ra : return address | 2775 // -- ra : return address |
2564 // ----------------------------------- | 2776 // ----------------------------------- |
2565 | 2777 |
2566 if (HasCustomCallGenerator(function)) { | 2778 if (HasCustomCallGenerator(function)) { |
2567 MaybeObject* maybe_result = CompileCustomCall( | 2779 MaybeObject* maybe_result = CompileCustomCall( |
2568 object, holder, cell, function, name); | 2780 object, holder, cell, function, name); |
2569 Object* result; | 2781 Object* result; |
2570 if (!maybe_result->ToObject(&result)) return maybe_result; | 2782 if (!maybe_result->ToObject(&result)) return maybe_result; |
2571 // Undefined means bail out to regular compiler. | 2783 // Undefined means bail out to regular compiler. |
2572 if (!result->IsUndefined()) return result; | 2784 if (!result->IsUndefined()) return result; |
2573 } | 2785 } |
2574 | 2786 |
2575 Label miss; | 2787 Label miss; |
2576 | 2788 |
2577 GenerateNameCheck(name, &miss); | 2789 GenerateNameCheck(Handle<String>(name), &miss); |
2578 | 2790 |
2579 // Get the number of arguments. | 2791 // Get the number of arguments. |
2580 const int argc = arguments().immediate(); | 2792 const int argc = arguments().immediate(); |
2581 | 2793 |
2582 GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2794 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
2583 GenerateLoadFunctionFromCell(cell, function, &miss); | 2795 GenerateLoadFunctionFromCell(cell, function, &miss); |
2584 | 2796 |
2585 // Patch the receiver on the stack with the global proxy if | 2797 // Patch the receiver on the stack with the global proxy if |
2586 // necessary. | 2798 // necessary. |
2587 if (object->IsGlobalObject()) { | 2799 if (object->IsGlobalObject()) { |
(...skipping 15 matching lines...) Expand all Loading... |
2603 // We call indirectly through the code field in the function to | 2815 // We call indirectly through the code field in the function to |
2604 // allow recompilation to take effect without changing any of the | 2816 // allow recompilation to take effect without changing any of the |
2605 // call sites. | 2817 // call sites. |
2606 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 2818 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
2607 __ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION, | 2819 __ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION, |
2608 NullCallWrapper(), call_kind); | 2820 NullCallWrapper(), call_kind); |
2609 | 2821 |
2610 // Handle call cache miss. | 2822 // Handle call cache miss. |
2611 __ bind(&miss); | 2823 __ bind(&miss); |
2612 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3); | 2824 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3); |
2613 MaybeObject* maybe_result = GenerateMissBranch(); | 2825 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2614 if (maybe_result->IsFailure()) return maybe_result; | 2826 if (maybe_result->IsFailure()) return maybe_result; |
2615 | 2827 |
2616 // Return the generated code. | 2828 // Return the generated code. |
2617 return GetCode(NORMAL, name); | 2829 return TryGetCode(NORMAL, name); |
2618 } | 2830 } |
2619 | 2831 |
2620 | 2832 |
2621 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, | 2833 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, |
2622 int index, | 2834 int index, |
2623 Map* transition, | 2835 Map* transition, |
2624 String* name) { | 2836 String* name) { |
2625 // ----------- S t a t e ------------- | 2837 // ----------- S t a t e ------------- |
2626 // -- a0 : value | 2838 // -- a0 : value |
2627 // -- a1 : receiver | 2839 // -- a1 : receiver |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2804 | 3016 |
2805 // Check that the receiver is not a smi. | 3017 // Check that the receiver is not a smi. |
2806 __ JumpIfSmi(a0, &miss); | 3018 __ JumpIfSmi(a0, &miss); |
2807 | 3019 |
2808 // Check the maps of the full prototype chain. | 3020 // Check the maps of the full prototype chain. |
2809 CheckPrototypes(object, a0, last, a3, a1, t0, name, &miss); | 3021 CheckPrototypes(object, a0, last, a3, a1, t0, name, &miss); |
2810 | 3022 |
2811 // If the last object in the prototype chain is a global object, | 3023 // If the last object in the prototype chain is a global object, |
2812 // check that the global property cell is empty. | 3024 // check that the global property cell is empty. |
2813 if (last->IsGlobalObject()) { | 3025 if (last->IsGlobalObject()) { |
2814 MaybeObject* cell = GenerateCheckPropertyCell(masm(), | 3026 MaybeObject* cell = TryGenerateCheckPropertyCell(masm(), |
2815 GlobalObject::cast(last), | 3027 GlobalObject::cast(last), |
2816 name, | 3028 name, |
2817 a1, | 3029 a1, |
2818 &miss); | 3030 &miss); |
2819 if (cell->IsFailure()) { | 3031 if (cell->IsFailure()) { |
2820 miss.Unuse(); | 3032 miss.Unuse(); |
2821 return cell; | 3033 return cell; |
2822 } | 3034 } |
2823 } | 3035 } |
2824 | 3036 |
2825 // Return undefined if maps of the full prototype chain is still the same. | 3037 // Return undefined if maps of the full prototype chain is still the same. |
2826 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); | 3038 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); |
2827 __ Ret(); | 3039 __ Ret(); |
2828 | 3040 |
(...skipping 1695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4524 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 4736 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
4525 __ Jump(ic_miss, RelocInfo::CODE_TARGET); | 4737 __ Jump(ic_miss, RelocInfo::CODE_TARGET); |
4526 } | 4738 } |
4527 | 4739 |
4528 | 4740 |
4529 #undef __ | 4741 #undef __ |
4530 | 4742 |
4531 } } // namespace v8::internal | 4743 } } // namespace v8::internal |
4532 | 4744 |
4533 #endif // V8_TARGET_ARCH_MIPS | 4745 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |