Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(457)

Side by Side Diff: src/ic.cc

Issue 235453010: Handlification in ic.cc (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Patch One. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ic.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ic.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698