OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 // The builtins object is special. It only changes when JavaScript | 368 // The builtins object is special. It only changes when JavaScript |
369 // builtins are loaded lazily. It is important to keep inline | 369 // builtins are loaded lazily. It is important to keep inline |
370 // caches for the builtins object monomorphic. Therefore, if we get | 370 // caches for the builtins object monomorphic. Therefore, if we get |
371 // an inline cache miss for the builtins object after lazily loading | 371 // an inline cache miss for the builtins object after lazily loading |
372 // JavaScript builtins, we return uninitialized as the state to | 372 // JavaScript builtins, we return uninitialized as the state to |
373 // force the inline cache back to monomorphic state. | 373 // force the inline cache back to monomorphic state. |
374 if (receiver->IsJSBuiltinsObject()) state_ = UNINITIALIZED; | 374 if (receiver->IsJSBuiltinsObject()) state_ = UNINITIALIZED; |
375 } | 375 } |
376 | 376 |
377 | 377 |
378 Failure* IC::TypeError(const char* type, | 378 MaybeHandle<Object> IC::TypeError(const char* type, |
379 Handle<Object> object, | 379 Handle<Object> object, |
380 Handle<Object> key) { | 380 Handle<Object> key) { |
381 HandleScope scope(isolate()); | 381 HandleScope scope(isolate()); |
382 Handle<Object> args[2] = { key, object }; | 382 Handle<Object> args[2] = { key, object }; |
383 Handle<Object> error = isolate()->factory()->NewTypeError( | 383 Handle<Object> error = isolate()->factory()->NewTypeError( |
384 type, HandleVector(args, 2)); | 384 type, HandleVector(args, 2)); |
385 return isolate()->Throw(*error); | 385 return isolate()->Throw<Object>(error); |
386 } | 386 } |
387 | 387 |
388 | 388 |
389 Failure* IC::ReferenceError(const char* type, Handle<String> name) { | 389 MaybeHandle<Object> IC::ReferenceError(const char* type, Handle<String> name) { |
390 HandleScope scope(isolate()); | 390 HandleScope scope(isolate()); |
391 Handle<Object> error = isolate()->factory()->NewReferenceError( | 391 Handle<Object> error = isolate()->factory()->NewReferenceError( |
392 type, HandleVector(&name, 1)); | 392 type, HandleVector(&name, 1)); |
393 return isolate()->Throw(*error); | 393 return isolate()->Throw<Object>(error); |
394 } | 394 } |
395 | 395 |
396 | 396 |
397 static int ComputeTypeInfoCountDelta(IC::State old_state, IC::State new_state) { | 397 static int ComputeTypeInfoCountDelta(IC::State old_state, IC::State new_state) { |
398 bool was_uninitialized = | 398 bool was_uninitialized = |
399 old_state == UNINITIALIZED || old_state == PREMONOMORPHIC; | 399 old_state == UNINITIALIZED || old_state == PREMONOMORPHIC; |
400 bool is_uninitialized = | 400 bool is_uninitialized = |
401 new_state == UNINITIALIZED || new_state == PREMONOMORPHIC; | 401 new_state == UNINITIALIZED || new_state == PREMONOMORPHIC; |
402 return (was_uninitialized && !is_uninitialized) ? 1 : | 402 return (was_uninitialized && !is_uninitialized) ? 1 : |
403 (!was_uninitialized && is_uninitialized) ? -1 : 0; | 403 (!was_uninitialized && is_uninitialized) ? -1 : 0; |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 | 565 |
566 static bool MigrateDeprecated(Handle<Object> object) { | 566 static bool MigrateDeprecated(Handle<Object> object) { |
567 if (!object->IsJSObject()) return false; | 567 if (!object->IsJSObject()) return false; |
568 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 568 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
569 if (!receiver->map()->is_deprecated()) return false; | 569 if (!receiver->map()->is_deprecated()) return false; |
570 JSObject::MigrateInstance(Handle<JSObject>::cast(object)); | 570 JSObject::MigrateInstance(Handle<JSObject>::cast(object)); |
571 return true; | 571 return true; |
572 } | 572 } |
573 | 573 |
574 | 574 |
575 MaybeObject* LoadIC::Load(Handle<Object> object, | 575 MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<String> name) { |
576 Handle<String> name) { | |
577 // If the object is undefined or null it's illegal to try to get any | 576 // If the object is undefined or null it's illegal to try to get any |
578 // of its properties; throw a TypeError in that case. | 577 // of its properties; throw a TypeError in that case. |
579 if (object->IsUndefined() || object->IsNull()) { | 578 if (object->IsUndefined() || object->IsNull()) { |
580 return TypeError("non_object_property_load", object, name); | 579 return TypeError("non_object_property_load", object, name); |
581 } | 580 } |
582 | 581 |
583 if (FLAG_use_ic) { | 582 if (FLAG_use_ic) { |
584 // Use specialized code for getting prototype of functions. | 583 // Use specialized code for getting prototype of functions. |
585 if (object->IsJSFunction() && | 584 if (object->IsJSFunction() && |
586 String::Equals(isolate()->factory()->prototype_string(), name) && | 585 String::Equals(isolate()->factory()->prototype_string(), name) && |
587 Handle<JSFunction>::cast(object)->should_have_prototype()) { | 586 Handle<JSFunction>::cast(object)->should_have_prototype()) { |
588 Handle<Code> stub; | 587 Handle<Code> stub; |
589 if (state() == UNINITIALIZED) { | 588 if (state() == UNINITIALIZED) { |
590 stub = pre_monomorphic_stub(); | 589 stub = pre_monomorphic_stub(); |
591 } else if (state() == PREMONOMORPHIC) { | 590 } else if (state() == PREMONOMORPHIC) { |
592 FunctionPrototypeStub function_prototype_stub(kind()); | 591 FunctionPrototypeStub function_prototype_stub(kind()); |
593 stub = function_prototype_stub.GetCode(isolate()); | 592 stub = function_prototype_stub.GetCode(isolate()); |
594 } else if (state() != MEGAMORPHIC) { | 593 } else if (state() != MEGAMORPHIC) { |
595 ASSERT(state() != GENERIC); | 594 ASSERT(state() != GENERIC); |
596 stub = megamorphic_stub(); | 595 stub = megamorphic_stub(); |
597 } | 596 } |
598 if (!stub.is_null()) { | 597 if (!stub.is_null()) { |
599 set_target(*stub); | 598 set_target(*stub); |
600 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); | 599 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); |
601 } | 600 } |
602 return *Accessors::FunctionGetPrototype(Handle<JSFunction>::cast(object)); | 601 return Accessors::FunctionGetPrototype(Handle<JSFunction>::cast(object)); |
603 } | 602 } |
604 } | 603 } |
605 | 604 |
606 // Check if the name is trivially convertible to an index and get | 605 // Check if the name is trivially convertible to an index and get |
607 // the element or char if so. | 606 // the element or char if so. |
608 uint32_t index; | 607 uint32_t index; |
609 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { | 608 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { |
610 // Rewrite to the generic keyed load stub. | 609 // Rewrite to the generic keyed load stub. |
611 if (FLAG_use_ic) set_target(*generic_stub()); | 610 if (FLAG_use_ic) set_target(*generic_stub()); |
612 Handle<Object> result; | 611 Handle<Object> result; |
613 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 612 ASSIGN_RETURN_ON_EXCEPTION( |
614 isolate(), result, | 613 isolate(), |
615 Runtime::GetElementOrCharAt(isolate(), object, index)); | 614 result, |
616 return *result; | 615 Runtime::GetElementOrCharAt(isolate(), object, index), |
| 616 Object); |
| 617 return result; |
617 } | 618 } |
618 | 619 |
619 bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic; | 620 bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic; |
620 | 621 |
621 // Named lookup in the object. | 622 // Named lookup in the object. |
622 LookupResult lookup(isolate()); | 623 LookupResult lookup(isolate()); |
623 LookupForRead(object, name, &lookup); | 624 LookupForRead(object, name, &lookup); |
624 | 625 |
625 // If we did not find a property, check if we need to throw an exception. | 626 // If we did not find a property, check if we need to throw an exception. |
626 if (!lookup.IsFound()) { | 627 if (!lookup.IsFound()) { |
627 if (IsUndeclaredGlobal(object)) { | 628 if (IsUndeclaredGlobal(object)) { |
628 return ReferenceError("not_defined", name); | 629 return ReferenceError("not_defined", name); |
629 } | 630 } |
630 LOG(isolate(), SuspectReadEvent(*name, *object)); | 631 LOG(isolate(), SuspectReadEvent(*name, *object)); |
631 } | 632 } |
632 | 633 |
633 // Update inline cache and stub cache. | 634 // Update inline cache and stub cache. |
634 if (use_ic) UpdateCaches(&lookup, object, name); | 635 if (use_ic) UpdateCaches(&lookup, object, name); |
635 | 636 |
636 PropertyAttributes attr; | 637 PropertyAttributes attr; |
637 // Get the property. | 638 // Get the property. |
638 Handle<Object> result; | 639 Handle<Object> result; |
639 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 640 ASSIGN_RETURN_ON_EXCEPTION( |
640 isolate(), result, | 641 isolate(), |
641 Object::GetProperty(object, object, &lookup, name, &attr)); | 642 result, |
| 643 Object::GetProperty(object, object, &lookup, name, &attr), |
| 644 Object); |
642 // If the property is not present, check if we need to throw an exception. | 645 // If the property is not present, check if we need to throw an exception. |
643 if ((lookup.IsInterceptor() || lookup.IsHandler()) && | 646 if ((lookup.IsInterceptor() || lookup.IsHandler()) && |
644 attr == ABSENT && IsUndeclaredGlobal(object)) { | 647 attr == ABSENT && IsUndeclaredGlobal(object)) { |
645 return ReferenceError("not_defined", name); | 648 return ReferenceError("not_defined", name); |
646 } | 649 } |
647 | 650 |
648 return *result; | 651 return result; |
649 } | 652 } |
650 | 653 |
651 | 654 |
652 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, | 655 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, |
653 Handle<Map> new_receiver_map) { | 656 Handle<Map> new_receiver_map) { |
654 ASSERT(!new_receiver_map.is_null()); | 657 ASSERT(!new_receiver_map.is_null()); |
655 for (int current = 0; current < receiver_maps->length(); ++current) { | 658 for (int current = 0; current < receiver_maps->length(); ++current) { |
656 if (!receiver_maps->at(current).is_null() && | 659 if (!receiver_maps->at(current).is_null() && |
657 receiver_maps->at(current).is_identical_to(new_receiver_map)) { | 660 receiver_maps->at(current).is_identical_to(new_receiver_map)) { |
658 return false; | 661 return false; |
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1114 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { | 1117 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { |
1115 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded"); | 1118 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded"); |
1116 return generic_stub(); | 1119 return generic_stub(); |
1117 } | 1120 } |
1118 | 1121 |
1119 return isolate()->stub_cache()->ComputeLoadElementPolymorphic( | 1122 return isolate()->stub_cache()->ComputeLoadElementPolymorphic( |
1120 &target_receiver_maps); | 1123 &target_receiver_maps); |
1121 } | 1124 } |
1122 | 1125 |
1123 | 1126 |
1124 MaybeObject* KeyedLoadIC::Load(Handle<Object> object, Handle<Object> key) { | 1127 MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object, |
| 1128 Handle<Object> key) { |
1125 if (MigrateDeprecated(object)) { | 1129 if (MigrateDeprecated(object)) { |
1126 Handle<Object> result; | 1130 Handle<Object> result; |
1127 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1131 ASSIGN_RETURN_ON_EXCEPTION( |
1128 isolate(), result, Runtime::GetObjectProperty(isolate(), object, key)); | 1132 isolate(), |
1129 return *result; | 1133 result, |
| 1134 Runtime::GetObjectProperty(isolate(), object, key), |
| 1135 Object); |
| 1136 return result; |
1130 } | 1137 } |
1131 | 1138 |
1132 MaybeObject* maybe_object = NULL; | 1139 Handle<Object> load_handle; |
1133 Handle<Code> stub = generic_stub(); | 1140 Handle<Code> stub = generic_stub(); |
1134 | 1141 |
1135 // Check for non-string values that can be converted into an | 1142 // Check for non-string values that can be converted into an |
1136 // internalized string directly or is representable as a smi. | 1143 // internalized string directly or is representable as a smi. |
1137 key = TryConvertKey(key, isolate()); | 1144 key = TryConvertKey(key, isolate()); |
1138 | 1145 |
1139 if (key->IsInternalizedString()) { | 1146 if (key->IsInternalizedString()) { |
1140 maybe_object = LoadIC::Load(object, Handle<String>::cast(key)); | 1147 ASSIGN_RETURN_ON_EXCEPTION( |
1141 if (maybe_object->IsFailure()) return maybe_object; | 1148 isolate(), |
| 1149 load_handle, |
| 1150 LoadIC::Load(object, Handle<String>::cast(key)), |
| 1151 Object); |
1142 } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) { | 1152 } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) { |
1143 if (object->IsString() && key->IsNumber()) { | 1153 if (object->IsString() && key->IsNumber()) { |
1144 if (state() == UNINITIALIZED) stub = string_stub(); | 1154 if (state() == UNINITIALIZED) stub = string_stub(); |
1145 } else if (object->IsJSObject()) { | 1155 } else if (object->IsJSObject()) { |
1146 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1156 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
1147 if (receiver->elements()->map() == | 1157 if (receiver->elements()->map() == |
1148 isolate()->heap()->sloppy_arguments_elements_map()) { | 1158 isolate()->heap()->sloppy_arguments_elements_map()) { |
1149 stub = sloppy_arguments_stub(); | 1159 stub = sloppy_arguments_stub(); |
1150 } else if (receiver->HasIndexedInterceptor()) { | 1160 } else if (receiver->HasIndexedInterceptor()) { |
1151 stub = indexed_interceptor_stub(); | 1161 stub = indexed_interceptor_stub(); |
1152 } else if (!key->ToSmi()->IsFailure() && | 1162 } else if (!key->ToSmi()->IsFailure() && |
1153 (!target().is_identical_to(sloppy_arguments_stub()))) { | 1163 (!target().is_identical_to(sloppy_arguments_stub()))) { |
1154 stub = LoadElementStub(receiver); | 1164 stub = LoadElementStub(receiver); |
1155 } | 1165 } |
1156 } | 1166 } |
1157 } | 1167 } |
1158 | 1168 |
1159 if (!is_target_set()) { | 1169 if (!is_target_set()) { |
1160 if (*stub == *generic_stub()) { | 1170 if (*stub == *generic_stub()) { |
1161 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic"); | 1171 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic"); |
1162 } | 1172 } |
1163 set_target(*stub); | 1173 set_target(*stub); |
1164 TRACE_IC("LoadIC", key); | 1174 TRACE_IC("LoadIC", key); |
1165 } | 1175 } |
1166 | 1176 |
1167 if (maybe_object != NULL) return maybe_object; | 1177 if (!load_handle.is_null()) return load_handle; |
1168 Handle<Object> result; | 1178 Handle<Object> result; |
1169 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1179 ASSIGN_RETURN_ON_EXCEPTION( |
1170 isolate(), result, Runtime::GetObjectProperty(isolate(), object, key)); | 1180 isolate(), |
1171 return *result; | 1181 result, |
| 1182 Runtime::GetObjectProperty(isolate(), object, key), |
| 1183 Object); |
| 1184 return result; |
1172 } | 1185 } |
1173 | 1186 |
1174 | 1187 |
1175 static bool LookupForWrite(Handle<JSObject> receiver, | 1188 static bool LookupForWrite(Handle<JSObject> receiver, |
1176 Handle<String> name, | 1189 Handle<String> name, |
1177 Handle<Object> value, | 1190 Handle<Object> value, |
1178 LookupResult* lookup, | 1191 LookupResult* lookup, |
1179 IC* ic) { | 1192 IC* ic) { |
1180 Handle<JSObject> holder = receiver; | 1193 Handle<JSObject> holder = receiver; |
1181 receiver->Lookup(*name, lookup); | 1194 receiver->Lookup(*name, lookup); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1228 // entirely by the migration above. | 1241 // entirely by the migration above. |
1229 receiver->map()->LookupTransition(*holder, *name, lookup); | 1242 receiver->map()->LookupTransition(*holder, *name, lookup); |
1230 if (!lookup->IsTransition()) return false; | 1243 if (!lookup->IsTransition()) return false; |
1231 return ic->TryMarkMonomorphicPrototypeFailure(name); | 1244 return ic->TryMarkMonomorphicPrototypeFailure(name); |
1232 } | 1245 } |
1233 | 1246 |
1234 return true; | 1247 return true; |
1235 } | 1248 } |
1236 | 1249 |
1237 | 1250 |
1238 MaybeObject* StoreIC::Store(Handle<Object> object, | 1251 MaybeHandle<Object> StoreIC::Store(Handle<Object> object, |
1239 Handle<String> name, | 1252 Handle<String> name, |
1240 Handle<Object> value, | 1253 Handle<Object> value, |
1241 JSReceiver::StoreFromKeyed store_mode) { | 1254 JSReceiver::StoreFromKeyed store_mode) { |
1242 if (MigrateDeprecated(object) || object->IsJSProxy()) { | 1255 if (MigrateDeprecated(object) || object->IsJSProxy()) { |
1243 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object); | 1256 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object); |
1244 Handle<Object> result; | 1257 Handle<Object> result; |
1245 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1258 ASSIGN_RETURN_ON_EXCEPTION( |
1246 isolate(), result, | 1259 isolate(), |
1247 JSReceiver::SetProperty(receiver, name, value, NONE, strict_mode())); | 1260 result, |
1248 return *result; | 1261 JSReceiver::SetProperty(receiver, name, value, NONE, strict_mode()), |
| 1262 Object); |
| 1263 return result; |
1249 } | 1264 } |
1250 | 1265 |
1251 // If the object is undefined or null it's illegal to try to set any | 1266 // If the object is undefined or null it's illegal to try to set any |
1252 // properties on it; throw a TypeError in that case. | 1267 // properties on it; throw a TypeError in that case. |
1253 if (object->IsUndefined() || object->IsNull()) { | 1268 if (object->IsUndefined() || object->IsNull()) { |
1254 return TypeError("non_object_property_store", object, name); | 1269 return TypeError("non_object_property_store", object, name); |
1255 } | 1270 } |
1256 | 1271 |
1257 // The length property of string values is read-only. Throw in strict mode. | 1272 // The length property of string values is read-only. Throw in strict mode. |
1258 if (strict_mode() == STRICT && object->IsString() && | 1273 if (strict_mode() == STRICT && object->IsString() && |
1259 String::Equals(isolate()->factory()->length_string(), name)) { | 1274 String::Equals(isolate()->factory()->length_string(), name)) { |
1260 return TypeError("strict_read_only_property", object, name); | 1275 return TypeError("strict_read_only_property", object, name); |
1261 } | 1276 } |
1262 | 1277 |
1263 // Ignore other stores where the receiver is not a JSObject. | 1278 // Ignore other stores where the receiver is not a JSObject. |
1264 // TODO(1475): Must check prototype chains of object wrappers. | 1279 // TODO(1475): Must check prototype chains of object wrappers. |
1265 if (!object->IsJSObject()) return *value; | 1280 if (!object->IsJSObject()) return value; |
1266 | 1281 |
1267 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1282 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
1268 | 1283 |
1269 // Check if the given name is an array index. | 1284 // Check if the given name is an array index. |
1270 uint32_t index; | 1285 uint32_t index; |
1271 if (name->AsArrayIndex(&index)) { | 1286 if (name->AsArrayIndex(&index)) { |
1272 Handle<Object> result; | 1287 Handle<Object> result; |
1273 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1288 ASSIGN_RETURN_ON_EXCEPTION( |
1274 isolate(), result, | 1289 isolate(), |
1275 JSObject::SetElement(receiver, index, value, NONE, strict_mode())); | 1290 result, |
1276 return *value; | 1291 JSObject::SetElement(receiver, index, value, NONE, strict_mode()), |
| 1292 Object); |
| 1293 return value; |
1277 } | 1294 } |
1278 | 1295 |
1279 // Observed objects are always modified through the runtime. | 1296 // Observed objects are always modified through the runtime. |
1280 if (receiver->map()->is_observed()) { | 1297 if (receiver->map()->is_observed()) { |
1281 Handle<Object> result; | 1298 Handle<Object> result; |
1282 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1299 ASSIGN_RETURN_ON_EXCEPTION( |
1283 isolate(), result, | 1300 isolate(), |
| 1301 result, |
1284 JSReceiver::SetProperty( | 1302 JSReceiver::SetProperty( |
1285 receiver, name, value, NONE, strict_mode(), store_mode)); | 1303 receiver, name, value, NONE, strict_mode(), store_mode), |
1286 return *result; | 1304 Object); |
| 1305 return result; |
1287 } | 1306 } |
1288 | 1307 |
1289 LookupResult lookup(isolate()); | 1308 LookupResult lookup(isolate()); |
1290 bool can_store = LookupForWrite(receiver, name, value, &lookup, this); | 1309 bool can_store = LookupForWrite(receiver, name, value, &lookup, this); |
1291 if (!can_store && | 1310 if (!can_store && |
1292 strict_mode() == STRICT && | 1311 strict_mode() == STRICT && |
1293 !(lookup.IsProperty() && lookup.IsReadOnly()) && | 1312 !(lookup.IsProperty() && lookup.IsReadOnly()) && |
1294 object->IsGlobalObject()) { | 1313 object->IsGlobalObject()) { |
1295 // Strict mode doesn't allow setting non-existent global property. | 1314 // Strict mode doesn't allow setting non-existent global property. |
1296 return ReferenceError("not_defined", name); | 1315 return ReferenceError("not_defined", name); |
1297 } | 1316 } |
1298 if (FLAG_use_ic) { | 1317 if (FLAG_use_ic) { |
1299 if (state() == UNINITIALIZED) { | 1318 if (state() == UNINITIALIZED) { |
1300 Handle<Code> stub = pre_monomorphic_stub(); | 1319 Handle<Code> stub = pre_monomorphic_stub(); |
1301 set_target(*stub); | 1320 set_target(*stub); |
1302 TRACE_IC("StoreIC", name); | 1321 TRACE_IC("StoreIC", name); |
1303 } else if (can_store) { | 1322 } else if (can_store) { |
1304 UpdateCaches(&lookup, receiver, name, value); | 1323 UpdateCaches(&lookup, receiver, name, value); |
1305 } else if (!name->IsCacheable(isolate()) || | 1324 } else if (!name->IsCacheable(isolate()) || |
1306 lookup.IsNormal() || | 1325 lookup.IsNormal() || |
1307 (lookup.IsField() && lookup.CanHoldValue(value))) { | 1326 (lookup.IsField() && lookup.CanHoldValue(value))) { |
1308 Handle<Code> stub = generic_stub(); | 1327 Handle<Code> stub = generic_stub(); |
1309 set_target(*stub); | 1328 set_target(*stub); |
1310 } | 1329 } |
1311 } | 1330 } |
1312 | 1331 |
1313 // Set the property. | 1332 // Set the property. |
1314 Handle<Object> result; | 1333 Handle<Object> result; |
1315 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1334 ASSIGN_RETURN_ON_EXCEPTION( |
1316 isolate(), result, | 1335 isolate(), |
| 1336 result, |
1317 JSReceiver::SetProperty( | 1337 JSReceiver::SetProperty( |
1318 receiver, name, value, NONE, strict_mode(), store_mode)); | 1338 receiver, name, value, NONE, strict_mode(), store_mode), |
1319 return *result; | 1339 Object); |
| 1340 return result; |
1320 } | 1341 } |
1321 | 1342 |
1322 | 1343 |
1323 Handle<Code> StoreIC::initialize_stub(Isolate* isolate, | 1344 Handle<Code> StoreIC::initialize_stub(Isolate* isolate, |
1324 StrictMode strict_mode) { | 1345 StrictMode strict_mode) { |
1325 ExtraICState extra_state = ComputeExtraICState(strict_mode); | 1346 ExtraICState extra_state = ComputeExtraICState(strict_mode); |
1326 Handle<Code> ic = isolate->stub_cache()->ComputeStore( | 1347 Handle<Code> ic = isolate->stub_cache()->ComputeStore( |
1327 UNINITIALIZED, extra_state); | 1348 UNINITIALIZED, extra_state); |
1328 return ic; | 1349 return ic; |
1329 } | 1350 } |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1700 Heap* heap = receiver->GetHeap(); | 1721 Heap* heap = receiver->GetHeap(); |
1701 if (receiver->elements()->map() == heap->fixed_cow_array_map()) { | 1722 if (receiver->elements()->map() == heap->fixed_cow_array_map()) { |
1702 return STORE_NO_TRANSITION_HANDLE_COW; | 1723 return STORE_NO_TRANSITION_HANDLE_COW; |
1703 } else { | 1724 } else { |
1704 return STANDARD_STORE; | 1725 return STANDARD_STORE; |
1705 } | 1726 } |
1706 } | 1727 } |
1707 } | 1728 } |
1708 | 1729 |
1709 | 1730 |
1710 MaybeObject* KeyedStoreIC::Store(Handle<Object> object, | 1731 MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object, |
1711 Handle<Object> key, | 1732 Handle<Object> key, |
1712 Handle<Object> value) { | 1733 Handle<Object> value) { |
1713 if (MigrateDeprecated(object)) { | 1734 if (MigrateDeprecated(object)) { |
1714 Handle<Object> result; | 1735 Handle<Object> result; |
1715 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1736 ASSIGN_RETURN_ON_EXCEPTION( |
1716 isolate(), result, | 1737 isolate(), |
| 1738 result, |
1717 Runtime::SetObjectProperty( | 1739 Runtime::SetObjectProperty( |
1718 isolate(), object, key, value, NONE, strict_mode())); | 1740 isolate(), object, key, value, NONE, strict_mode()), |
1719 return *result; | 1741 Object); |
| 1742 return result; |
1720 } | 1743 } |
1721 | 1744 |
1722 // Check for non-string values that can be converted into an | 1745 // Check for non-string values that can be converted into an |
1723 // internalized string directly or is representable as a smi. | 1746 // internalized string directly or is representable as a smi. |
1724 key = TryConvertKey(key, isolate()); | 1747 key = TryConvertKey(key, isolate()); |
1725 | 1748 |
1726 MaybeObject* maybe_object = NULL; | 1749 Handle<Object> store_handle; |
1727 Handle<Code> stub = generic_stub(); | 1750 Handle<Code> stub = generic_stub(); |
1728 | 1751 |
1729 if (key->IsInternalizedString()) { | 1752 if (key->IsInternalizedString()) { |
1730 maybe_object = StoreIC::Store(object, | 1753 ASSIGN_RETURN_ON_EXCEPTION( |
1731 Handle<String>::cast(key), | 1754 isolate(), |
1732 value, | 1755 store_handle, |
1733 JSReceiver::MAY_BE_STORE_FROM_KEYED); | 1756 StoreIC::Store(object, |
1734 if (maybe_object->IsFailure()) return maybe_object; | 1757 Handle<String>::cast(key), |
| 1758 value, |
| 1759 JSReceiver::MAY_BE_STORE_FROM_KEYED), |
| 1760 Object); |
1735 } else { | 1761 } else { |
1736 bool use_ic = FLAG_use_ic && | 1762 bool use_ic = FLAG_use_ic && |
1737 !object->IsStringWrapper() && | 1763 !object->IsStringWrapper() && |
1738 !object->IsAccessCheckNeeded() && | 1764 !object->IsAccessCheckNeeded() && |
1739 !object->IsJSGlobalProxy() && | 1765 !object->IsJSGlobalProxy() && |
1740 !(object->IsJSObject() && | 1766 !(object->IsJSObject() && |
1741 JSObject::cast(*object)->map()->is_observed()); | 1767 JSObject::cast(*object)->map()->is_observed()); |
1742 if (use_ic && !object->IsSmi()) { | 1768 if (use_ic && !object->IsSmi()) { |
1743 // Don't use ICs for maps of the objects in Array's prototype chain. We | 1769 // Don't use ICs for maps of the objects in Array's prototype chain. We |
1744 // expect to be able to trap element sets to objects with those maps in | 1770 // expect to be able to trap element sets to objects with those maps in |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1776 | 1802 |
1777 if (!is_target_set()) { | 1803 if (!is_target_set()) { |
1778 if (*stub == *generic_stub()) { | 1804 if (*stub == *generic_stub()) { |
1779 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic"); | 1805 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic"); |
1780 } | 1806 } |
1781 ASSERT(!stub.is_null()); | 1807 ASSERT(!stub.is_null()); |
1782 set_target(*stub); | 1808 set_target(*stub); |
1783 TRACE_IC("StoreIC", key); | 1809 TRACE_IC("StoreIC", key); |
1784 } | 1810 } |
1785 | 1811 |
1786 if (maybe_object) return maybe_object; | 1812 if (!store_handle.is_null()) return store_handle; |
1787 Handle<Object> result; | 1813 Handle<Object> result; |
1788 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1814 ASSIGN_RETURN_ON_EXCEPTION( |
1789 isolate(), result, | 1815 isolate(), |
| 1816 result, |
1790 Runtime::SetObjectProperty( | 1817 Runtime::SetObjectProperty( |
1791 isolate(), object, key, value, NONE, strict_mode())); | 1818 isolate(), object, key, value, NONE, strict_mode()), |
1792 return *result; | 1819 Object); |
| 1820 return result; |
1793 } | 1821 } |
1794 | 1822 |
1795 | 1823 |
1796 #undef TRACE_IC | 1824 #undef TRACE_IC |
1797 | 1825 |
1798 | 1826 |
1799 // ---------------------------------------------------------------------------- | 1827 // ---------------------------------------------------------------------------- |
1800 // Static IC stub generators. | 1828 // Static IC stub generators. |
1801 // | 1829 // |
1802 | 1830 |
1803 // Used from ic-<arch>.cc. | 1831 // Used from ic-<arch>.cc. |
1804 // Used from ic-<arch>.cc. | 1832 // Used from ic-<arch>.cc. |
1805 RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) { | 1833 RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) { |
1806 HandleScope scope(isolate); | 1834 HandleScope scope(isolate); |
1807 ASSERT(args.length() == 2); | 1835 ASSERT(args.length() == 2); |
1808 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); | 1836 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); |
1809 Handle<Object> receiver = args.at<Object>(0); | 1837 Handle<Object> receiver = args.at<Object>(0); |
1810 Handle<String> key = args.at<String>(1); | 1838 Handle<String> key = args.at<String>(1); |
1811 ic.UpdateState(receiver, key); | 1839 ic.UpdateState(receiver, key); |
1812 return ic.Load(receiver, key); | 1840 Handle<Object> result; |
| 1841 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |
| 1842 return *result; |
1813 } | 1843 } |
1814 | 1844 |
1815 | 1845 |
1816 // Used from ic-<arch>.cc | 1846 // Used from ic-<arch>.cc |
1817 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) { | 1847 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) { |
1818 HandleScope scope(isolate); | 1848 HandleScope scope(isolate); |
1819 ASSERT(args.length() == 2); | 1849 ASSERT(args.length() == 2); |
1820 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate); | 1850 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate); |
1821 Handle<Object> receiver = args.at<Object>(0); | 1851 Handle<Object> receiver = args.at<Object>(0); |
1822 Handle<Object> key = args.at<Object>(1); | 1852 Handle<Object> key = args.at<Object>(1); |
1823 ic.UpdateState(receiver, key); | 1853 ic.UpdateState(receiver, key); |
1824 return ic.Load(receiver, key); | 1854 Handle<Object> result; |
| 1855 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |
| 1856 return *result; |
1825 } | 1857 } |
1826 | 1858 |
1827 | 1859 |
1828 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure) { | 1860 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure) { |
1829 HandleScope scope(isolate); | 1861 HandleScope scope(isolate); |
1830 ASSERT(args.length() == 2); | 1862 ASSERT(args.length() == 2); |
1831 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate); | 1863 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate); |
1832 Handle<Object> receiver = args.at<Object>(0); | 1864 Handle<Object> receiver = args.at<Object>(0); |
1833 Handle<Object> key = args.at<Object>(1); | 1865 Handle<Object> key = args.at<Object>(1); |
1834 ic.UpdateState(receiver, key); | 1866 ic.UpdateState(receiver, key); |
1835 return ic.Load(receiver, key); | 1867 Handle<Object> result; |
| 1868 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |
| 1869 return *result; |
1836 } | 1870 } |
1837 | 1871 |
1838 | 1872 |
1839 // Used from ic-<arch>.cc. | 1873 // Used from ic-<arch>.cc. |
1840 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) { | 1874 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) { |
1841 HandleScope scope(isolate); | 1875 HandleScope scope(isolate); |
1842 ASSERT(args.length() == 3); | 1876 ASSERT(args.length() == 3); |
1843 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); | 1877 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); |
1844 Handle<Object> receiver = args.at<Object>(0); | 1878 Handle<Object> receiver = args.at<Object>(0); |
1845 Handle<String> key = args.at<String>(1); | 1879 Handle<String> key = args.at<String>(1); |
1846 ic.UpdateState(receiver, key); | 1880 ic.UpdateState(receiver, key); |
1847 return ic.Store(receiver, key, args.at<Object>(2)); | 1881 Handle<Object> result; |
| 1882 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 1883 isolate, |
| 1884 result, |
| 1885 ic.Store(receiver, key, args.at<Object>(2))); |
| 1886 return *result; |
1848 } | 1887 } |
1849 | 1888 |
1850 | 1889 |
1851 RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure) { | 1890 RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure) { |
1852 HandleScope scope(isolate); | 1891 HandleScope scope(isolate); |
1853 ASSERT(args.length() == 3); | 1892 ASSERT(args.length() == 3); |
1854 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate); | 1893 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate); |
1855 Handle<Object> receiver = args.at<Object>(0); | 1894 Handle<Object> receiver = args.at<Object>(0); |
1856 Handle<String> key = args.at<String>(1); | 1895 Handle<String> key = args.at<String>(1); |
1857 ic.UpdateState(receiver, key); | 1896 ic.UpdateState(receiver, key); |
1858 return ic.Store(receiver, key, args.at<Object>(2)); | 1897 Handle<Object> result; |
| 1898 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 1899 isolate, |
| 1900 result, |
| 1901 ic.Store(receiver, key, args.at<Object>(2))); |
| 1902 return *result; |
1859 } | 1903 } |
1860 | 1904 |
1861 | 1905 |
1862 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) { | 1906 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) { |
1863 HandleScope scope(isolate); | 1907 HandleScope scope(isolate); |
1864 | 1908 |
1865 ASSERT(args.length() == 2); | 1909 ASSERT(args.length() == 2); |
1866 Handle<JSArray> receiver = args.at<JSArray>(0); | 1910 Handle<JSArray> receiver = args.at<JSArray>(0); |
1867 Handle<Object> len = args.at<Object>(1); | 1911 Handle<Object> len = args.at<Object>(1); |
1868 | 1912 |
(...skipping 10 matching lines...) Expand all Loading... |
1879 RETURN_FAILURE_ON_EXCEPTION( | 1923 RETURN_FAILURE_ON_EXCEPTION( |
1880 isolate, JSArray::SetElementsLength(receiver, len)); | 1924 isolate, JSArray::SetElementsLength(receiver, len)); |
1881 return *len; | 1925 return *len; |
1882 } | 1926 } |
1883 | 1927 |
1884 | 1928 |
1885 // Extend storage is called in a store inline cache when | 1929 // Extend storage is called in a store inline cache when |
1886 // it is necessary to extend the properties array of a | 1930 // it is necessary to extend the properties array of a |
1887 // JSObject. | 1931 // JSObject. |
1888 RUNTIME_FUNCTION(MaybeObject*, SharedStoreIC_ExtendStorage) { | 1932 RUNTIME_FUNCTION(MaybeObject*, SharedStoreIC_ExtendStorage) { |
1889 SealHandleScope shs(isolate); | 1933 HandleScope shs(isolate); |
1890 ASSERT(args.length() == 3); | 1934 ASSERT(args.length() == 3); |
1891 | 1935 |
1892 // Convert the parameters | 1936 // Convert the parameters |
1893 JSObject* object = JSObject::cast(args[0]); | 1937 Handle<JSObject> object = args.at<JSObject>(0); |
1894 Map* transition = Map::cast(args[1]); | 1938 Handle<Map> transition = args.at<Map>(1); |
1895 Object* value = args[2]; | 1939 Handle<Object> value = args.at<Object>(2); |
1896 | 1940 |
1897 // Check the object has run out out property space. | 1941 // Check the object has run out out property space. |
1898 ASSERT(object->HasFastProperties()); | 1942 ASSERT(object->HasFastProperties()); |
1899 ASSERT(object->map()->unused_property_fields() == 0); | 1943 ASSERT(object->map()->unused_property_fields() == 0); |
1900 | 1944 |
1901 // Expand the properties array. | 1945 // Expand the properties array. |
1902 FixedArray* old_storage = object->properties(); | 1946 Handle<FixedArray> old_storage = handle(object->properties(), isolate); |
1903 int new_unused = transition->unused_property_fields(); | 1947 int new_unused = transition->unused_property_fields(); |
1904 int new_size = old_storage->length() + new_unused + 1; | 1948 int new_size = old_storage->length() + new_unused + 1; |
1905 Object* result; | |
1906 MaybeObject* maybe_result = old_storage->CopySize(new_size); | |
1907 if (!maybe_result->ToObject(&result)) return maybe_result; | |
1908 | 1949 |
1909 FixedArray* new_storage = FixedArray::cast(result); | 1950 Handle<FixedArray> new_storage = isolate->factory()->CopySizeFixedArray( |
| 1951 old_storage, new_size); |
1910 | 1952 |
1911 Object* to_store = value; | 1953 Handle<Object> to_store = value; |
1912 | 1954 |
1913 DescriptorArray* descriptors = transition->instance_descriptors(); | 1955 PropertyDetails details = transition->instance_descriptors()->GetDetails( |
1914 PropertyDetails details = descriptors->GetDetails(transition->LastAdded()); | 1956 transition->LastAdded()); |
1915 if (details.representation().IsDouble()) { | 1957 if (details.representation().IsDouble()) { |
1916 MaybeObject* maybe_storage = | 1958 to_store = isolate->factory()->NewHeapNumber(value->Number()); |
1917 isolate->heap()->AllocateHeapNumber(value->Number()); | |
1918 if (!maybe_storage->To(&to_store)) return maybe_storage; | |
1919 } | 1959 } |
1920 | 1960 |
1921 new_storage->set(old_storage->length(), to_store); | 1961 new_storage->set(old_storage->length(), *to_store); |
1922 | 1962 |
1923 // Set the new property value and do the map transition. | 1963 // Set the new property value and do the map transition. |
1924 object->set_properties(new_storage); | 1964 object->set_properties(*new_storage); |
1925 object->set_map(transition); | 1965 object->set_map(*transition); |
1926 | 1966 |
1927 // Return the stored value. | 1967 // Return the stored value. |
1928 return value; | 1968 return *value; |
1929 } | 1969 } |
1930 | 1970 |
1931 | 1971 |
1932 // Used from ic-<arch>.cc. | 1972 // Used from ic-<arch>.cc. |
1933 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) { | 1973 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) { |
1934 HandleScope scope(isolate); | 1974 HandleScope scope(isolate); |
1935 ASSERT(args.length() == 3); | 1975 ASSERT(args.length() == 3); |
1936 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); | 1976 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); |
1937 Handle<Object> receiver = args.at<Object>(0); | 1977 Handle<Object> receiver = args.at<Object>(0); |
1938 Handle<Object> key = args.at<Object>(1); | 1978 Handle<Object> key = args.at<Object>(1); |
1939 ic.UpdateState(receiver, key); | 1979 ic.UpdateState(receiver, key); |
1940 return ic.Store(receiver, key, args.at<Object>(2)); | 1980 Handle<Object> result; |
| 1981 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 1982 isolate, |
| 1983 result, |
| 1984 ic.Store(receiver, key, args.at<Object>(2))); |
| 1985 return *result; |
1941 } | 1986 } |
1942 | 1987 |
1943 | 1988 |
1944 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure) { | 1989 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure) { |
1945 HandleScope scope(isolate); | 1990 HandleScope scope(isolate); |
1946 ASSERT(args.length() == 3); | 1991 ASSERT(args.length() == 3); |
1947 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); | 1992 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); |
1948 Handle<Object> receiver = args.at<Object>(0); | 1993 Handle<Object> receiver = args.at<Object>(0); |
1949 Handle<Object> key = args.at<Object>(1); | 1994 Handle<Object> key = args.at<Object>(1); |
1950 ic.UpdateState(receiver, key); | 1995 ic.UpdateState(receiver, key); |
1951 return ic.Store(receiver, key, args.at<Object>(2)); | 1996 Handle<Object> result; |
| 1997 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 1998 isolate, |
| 1999 result, |
| 2000 ic.Store(receiver, key, args.at<Object>(2))); |
| 2001 return *result; |
1952 } | 2002 } |
1953 | 2003 |
1954 | 2004 |
1955 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Slow) { | 2005 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Slow) { |
1956 HandleScope scope(isolate); | 2006 HandleScope scope(isolate); |
1957 ASSERT(args.length() == 3); | 2007 ASSERT(args.length() == 3); |
1958 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); | 2008 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); |
1959 Handle<Object> object = args.at<Object>(0); | 2009 Handle<Object> object = args.at<Object>(0); |
1960 Handle<Object> key = args.at<Object>(1); | 2010 Handle<Object> key = args.at<Object>(1); |
1961 Handle<Object> value = args.at<Object>(2); | 2011 Handle<Object> value = args.at<Object>(2); |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2421 case INT32: return Type::Signed32(zone); | 2471 case INT32: return Type::Signed32(zone); |
2422 case NUMBER: return Type::Number(zone); | 2472 case NUMBER: return Type::Number(zone); |
2423 case STRING: return Type::String(zone); | 2473 case STRING: return Type::String(zone); |
2424 case GENERIC: return Type::Any(zone); | 2474 case GENERIC: return Type::Any(zone); |
2425 } | 2475 } |
2426 UNREACHABLE(); | 2476 UNREACHABLE(); |
2427 return NULL; | 2477 return NULL; |
2428 } | 2478 } |
2429 | 2479 |
2430 | 2480 |
2431 MaybeObject* BinaryOpIC::Transition(Handle<AllocationSite> allocation_site, | 2481 MaybeHandle<Object> BinaryOpIC::Transition( |
2432 Handle<Object> left, | 2482 Handle<AllocationSite> allocation_site, |
2433 Handle<Object> right) { | 2483 Handle<Object> left, |
| 2484 Handle<Object> right) { |
2434 State state(target()->extra_ic_state()); | 2485 State state(target()->extra_ic_state()); |
2435 | 2486 |
2436 // Compute the actual result using the builtin for the binary operation. | 2487 // Compute the actual result using the builtin for the binary operation. |
2437 Object* builtin = isolate()->js_builtins_object()->javascript_builtin( | 2488 Object* builtin = isolate()->js_builtins_object()->javascript_builtin( |
2438 TokenToJSBuiltin(state.op())); | 2489 TokenToJSBuiltin(state.op())); |
2439 Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate()); | 2490 Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate()); |
2440 Handle<Object> result; | 2491 Handle<Object> result; |
2441 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 2492 ASSIGN_RETURN_ON_EXCEPTION( |
2442 isolate(), result, | 2493 isolate(), |
2443 Execution::Call(isolate(), function, left, 1, &right)); | 2494 result, |
| 2495 Execution::Call(isolate(), function, left, 1, &right), |
| 2496 Object); |
2444 | 2497 |
2445 // Execution::Call can execute arbitrary JavaScript, hence potentially | 2498 // Execution::Call can execute arbitrary JavaScript, hence potentially |
2446 // update the state of this very IC, so we must update the stored state. | 2499 // update the state of this very IC, so we must update the stored state. |
2447 UpdateTarget(); | 2500 UpdateTarget(); |
2448 // Compute the new state. | 2501 // Compute the new state. |
2449 State old_state(target()->extra_ic_state()); | 2502 State old_state(target()->extra_ic_state()); |
2450 state.Update(left, right, result); | 2503 state.Update(left, right, result); |
2451 | 2504 |
2452 // Check if we have a string operation here. | 2505 // Check if we have a string operation here. |
2453 Handle<Code> target; | 2506 Handle<Code> target; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2491 PrintF("]\n"); | 2544 PrintF("]\n"); |
2492 } | 2545 } |
2493 | 2546 |
2494 // Patch the inlined smi code as necessary. | 2547 // Patch the inlined smi code as necessary. |
2495 if (!old_state.UseInlinedSmiCode() && state.UseInlinedSmiCode()) { | 2548 if (!old_state.UseInlinedSmiCode() && state.UseInlinedSmiCode()) { |
2496 PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK); | 2549 PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK); |
2497 } else if (old_state.UseInlinedSmiCode() && !state.UseInlinedSmiCode()) { | 2550 } else if (old_state.UseInlinedSmiCode() && !state.UseInlinedSmiCode()) { |
2498 PatchInlinedSmiCode(address(), DISABLE_INLINED_SMI_CHECK); | 2551 PatchInlinedSmiCode(address(), DISABLE_INLINED_SMI_CHECK); |
2499 } | 2552 } |
2500 | 2553 |
2501 return *result; | 2554 return result; |
2502 } | 2555 } |
2503 | 2556 |
2504 | 2557 |
2505 RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss) { | 2558 RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss) { |
2506 HandleScope scope(isolate); | 2559 HandleScope scope(isolate); |
2507 ASSERT_EQ(2, args.length()); | 2560 ASSERT_EQ(2, args.length()); |
2508 Handle<Object> left = args.at<Object>(BinaryOpICStub::kLeft); | 2561 Handle<Object> left = args.at<Object>(BinaryOpICStub::kLeft); |
2509 Handle<Object> right = args.at<Object>(BinaryOpICStub::kRight); | 2562 Handle<Object> right = args.at<Object>(BinaryOpICStub::kRight); |
2510 BinaryOpIC ic(isolate); | 2563 BinaryOpIC ic(isolate); |
2511 return ic.Transition(Handle<AllocationSite>::null(), left, right); | 2564 Handle<Object> result; |
| 2565 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 2566 isolate, |
| 2567 result, |
| 2568 ic.Transition(Handle<AllocationSite>::null(), left, right)); |
| 2569 return *result; |
2512 } | 2570 } |
2513 | 2571 |
2514 | 2572 |
2515 RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_MissWithAllocationSite) { | 2573 RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_MissWithAllocationSite) { |
2516 HandleScope scope(isolate); | 2574 HandleScope scope(isolate); |
2517 ASSERT_EQ(3, args.length()); | 2575 ASSERT_EQ(3, args.length()); |
2518 Handle<AllocationSite> allocation_site = args.at<AllocationSite>( | 2576 Handle<AllocationSite> allocation_site = args.at<AllocationSite>( |
2519 BinaryOpWithAllocationSiteStub::kAllocationSite); | 2577 BinaryOpWithAllocationSiteStub::kAllocationSite); |
2520 Handle<Object> left = args.at<Object>( | 2578 Handle<Object> left = args.at<Object>( |
2521 BinaryOpWithAllocationSiteStub::kLeft); | 2579 BinaryOpWithAllocationSiteStub::kLeft); |
2522 Handle<Object> right = args.at<Object>( | 2580 Handle<Object> right = args.at<Object>( |
2523 BinaryOpWithAllocationSiteStub::kRight); | 2581 BinaryOpWithAllocationSiteStub::kRight); |
2524 BinaryOpIC ic(isolate); | 2582 BinaryOpIC ic(isolate); |
2525 return ic.Transition(allocation_site, left, right); | 2583 Handle<Object> result; |
| 2584 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 2585 isolate, |
| 2586 result, |
| 2587 ic.Transition(allocation_site, left, right)); |
| 2588 return *result; |
2526 } | 2589 } |
2527 | 2590 |
2528 | 2591 |
2529 Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op) { | 2592 Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op) { |
2530 ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED); | 2593 ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED); |
2531 Code* code = NULL; | 2594 Code* code = NULL; |
2532 CHECK(stub.FindCodeInCache(&code, isolate)); | 2595 CHECK(stub.FindCodeInCache(&code, isolate)); |
2533 return code; | 2596 return code; |
2534 } | 2597 } |
2535 | 2598 |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2757 CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED); | 2820 CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED); |
2758 stub.ClearState(); | 2821 stub.ClearState(); |
2759 | 2822 |
2760 Code* code = NULL; | 2823 Code* code = NULL; |
2761 CHECK(stub.FindCodeInCache(&code, target->GetIsolate())); | 2824 CHECK(stub.FindCodeInCache(&code, target->GetIsolate())); |
2762 | 2825 |
2763 SetTargetAtAddress(address, code, constant_pool); | 2826 SetTargetAtAddress(address, code, constant_pool); |
2764 } | 2827 } |
2765 | 2828 |
2766 | 2829 |
2767 MaybeObject* CompareNilIC::DoCompareNilSlow(NilValue nil, | 2830 Handle<Object> CompareNilIC::DoCompareNilSlow(Isolate* isolate, |
2768 Handle<Object> object) { | 2831 NilValue nil, |
| 2832 Handle<Object> object) { |
2769 if (object->IsNull() || object->IsUndefined()) { | 2833 if (object->IsNull() || object->IsUndefined()) { |
2770 return Smi::FromInt(true); | 2834 return handle(Smi::FromInt(true), isolate); |
2771 } | 2835 } |
2772 return Smi::FromInt(object->IsUndetectableObject()); | 2836 return handle(Smi::FromInt(object->IsUndetectableObject()), isolate); |
2773 } | 2837 } |
2774 | 2838 |
2775 | 2839 |
2776 MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) { | 2840 Handle<Object> CompareNilIC::CompareNil(Handle<Object> object) { |
2777 ExtraICState extra_ic_state = target()->extra_ic_state(); | 2841 ExtraICState extra_ic_state = target()->extra_ic_state(); |
2778 | 2842 |
2779 CompareNilICStub stub(extra_ic_state); | 2843 CompareNilICStub stub(extra_ic_state); |
2780 | 2844 |
2781 // Extract the current supported types from the patched IC and calculate what | 2845 // Extract the current supported types from the patched IC and calculate what |
2782 // types must be supported as a result of the miss. | 2846 // types must be supported as a result of the miss. |
2783 bool already_monomorphic = stub.IsMonomorphic(); | 2847 bool already_monomorphic = stub.IsMonomorphic(); |
2784 | 2848 |
2785 stub.UpdateStatus(object); | 2849 stub.UpdateStatus(object); |
2786 | 2850 |
2787 NilValue nil = stub.GetNilValue(); | 2851 NilValue nil = stub.GetNilValue(); |
2788 | 2852 |
2789 // Find or create the specialized stub to support the new set of types. | 2853 // Find or create the specialized stub to support the new set of types. |
2790 Handle<Code> code; | 2854 Handle<Code> code; |
2791 if (stub.IsMonomorphic()) { | 2855 if (stub.IsMonomorphic()) { |
2792 Handle<Map> monomorphic_map(already_monomorphic && FirstTargetMap() != NULL | 2856 Handle<Map> monomorphic_map(already_monomorphic && FirstTargetMap() != NULL |
2793 ? FirstTargetMap() | 2857 ? FirstTargetMap() |
2794 : HeapObject::cast(*object)->map()); | 2858 : HeapObject::cast(*object)->map()); |
2795 code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub); | 2859 code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub); |
2796 } else { | 2860 } else { |
2797 code = stub.GetCode(isolate()); | 2861 code = stub.GetCode(isolate()); |
2798 } | 2862 } |
2799 set_target(*code); | 2863 set_target(*code); |
2800 return DoCompareNilSlow(nil, object); | 2864 return DoCompareNilSlow(isolate(), nil, object); |
2801 } | 2865 } |
2802 | 2866 |
2803 | 2867 |
2804 RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss) { | 2868 RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss) { |
2805 HandleScope scope(isolate); | 2869 HandleScope scope(isolate); |
2806 Handle<Object> object = args.at<Object>(0); | 2870 Handle<Object> object = args.at<Object>(0); |
2807 CompareNilIC ic(isolate); | 2871 CompareNilIC ic(isolate); |
2808 return ic.CompareNil(object); | 2872 return *ic.CompareNil(object); |
2809 } | 2873 } |
2810 | 2874 |
2811 | 2875 |
2812 RUNTIME_FUNCTION(MaybeObject*, Unreachable) { | 2876 RUNTIME_FUNCTION(MaybeObject*, Unreachable) { |
2813 UNREACHABLE(); | 2877 UNREACHABLE(); |
2814 CHECK(false); | 2878 CHECK(false); |
2815 return isolate->heap()->undefined_value(); | 2879 return isolate->heap()->undefined_value(); |
2816 } | 2880 } |
2817 | 2881 |
2818 | 2882 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2850 case Token::SHR: | 2914 case Token::SHR: |
2851 return Builtins::SHR; | 2915 return Builtins::SHR; |
2852 break; | 2916 break; |
2853 case Token::SHL: | 2917 case Token::SHL: |
2854 return Builtins::SHL; | 2918 return Builtins::SHL; |
2855 break; | 2919 break; |
2856 } | 2920 } |
2857 } | 2921 } |
2858 | 2922 |
2859 | 2923 |
2860 MaybeObject* ToBooleanIC::ToBoolean(Handle<Object> object) { | 2924 Handle<Object> ToBooleanIC::ToBoolean(Handle<Object> object) { |
2861 ToBooleanStub stub(target()->extra_ic_state()); | 2925 ToBooleanStub stub(target()->extra_ic_state()); |
2862 bool to_boolean_value = stub.UpdateStatus(object); | 2926 bool to_boolean_value = stub.UpdateStatus(object); |
2863 Handle<Code> code = stub.GetCode(isolate()); | 2927 Handle<Code> code = stub.GetCode(isolate()); |
2864 set_target(*code); | 2928 set_target(*code); |
2865 return Smi::FromInt(to_boolean_value ? 1 : 0); | 2929 return handle(Smi::FromInt(to_boolean_value ? 1 : 0), isolate()); |
2866 } | 2930 } |
2867 | 2931 |
2868 | 2932 |
2869 RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss) { | 2933 RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss) { |
2870 ASSERT(args.length() == 1); | 2934 ASSERT(args.length() == 1); |
2871 HandleScope scope(isolate); | 2935 HandleScope scope(isolate); |
2872 Handle<Object> object = args.at<Object>(0); | 2936 Handle<Object> object = args.at<Object>(0); |
2873 ToBooleanIC ic(isolate); | 2937 ToBooleanIC ic(isolate); |
2874 return ic.ToBoolean(object); | 2938 return *ic.ToBoolean(object); |
2875 } | 2939 } |
2876 | 2940 |
2877 | 2941 |
2878 static const Address IC_utilities[] = { | 2942 static const Address IC_utilities[] = { |
2879 #define ADDR(name) FUNCTION_ADDR(name), | 2943 #define ADDR(name) FUNCTION_ADDR(name), |
2880 IC_UTIL_LIST(ADDR) | 2944 IC_UTIL_LIST(ADDR) |
2881 NULL | 2945 NULL |
2882 #undef ADDR | 2946 #undef ADDR |
2883 }; | 2947 }; |
2884 | 2948 |
2885 | 2949 |
2886 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2950 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2887 return IC_utilities[id]; | 2951 return IC_utilities[id]; |
2888 } | 2952 } |
2889 | 2953 |
2890 | 2954 |
2891 } } // namespace v8::internal | 2955 } } // namespace v8::internal |
OLD | NEW |