| 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 |