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

Side by Side Diff: src/ic.cc

Issue 25529002: Cleanup map deprecation handling in the ICs (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comment Created 7 years, 2 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 | « no previous file | 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 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 // Change the receiver to the result of calling ToObject on it. 532 // Change the receiver to the result of calling ToObject on it.
533 const int argc = this->target()->arguments_count(); 533 const int argc = this->target()->arguments_count();
534 StackFrameLocator locator(isolate()); 534 StackFrameLocator locator(isolate());
535 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); 535 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
536 int index = frame->ComputeExpressionsCount() - (argc + 1); 536 int index = frame->ComputeExpressionsCount() - (argc + 1);
537 frame->SetExpression(index, *isolate()->factory()->ToObject(object)); 537 frame->SetExpression(index, *isolate()->factory()->ToObject(object));
538 } 538 }
539 } 539 }
540 540
541 541
542 static bool MigrateDeprecated(Handle<Object> object) {
543 if (!object->IsJSObject()) return false;
544 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
545 if (!receiver->map()->is_deprecated()) return false;
546 JSObject::MigrateInstance(Handle<JSObject>::cast(object));
547 return true;
548 }
549
550
542 MaybeObject* CallICBase::LoadFunction(Handle<Object> object, 551 MaybeObject* CallICBase::LoadFunction(Handle<Object> object,
543 Handle<String> name) { 552 Handle<String> name) {
544 bool use_ic = FLAG_use_ic; 553 bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic;
545 if (object->IsJSObject()) {
546 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
547 if (receiver->map()->is_deprecated()) {
548 use_ic = false;
549 JSObject::MigrateInstance(receiver);
550 }
551 }
552 554
553 // If the object is undefined or null it's illegal to try to get any 555 // If the object is undefined or null it's illegal to try to get any
554 // of its properties; throw a TypeError in that case. 556 // of its properties; throw a TypeError in that case.
555 if (object->IsUndefined() || object->IsNull()) { 557 if (object->IsUndefined() || object->IsNull()) {
556 return TypeError("non_object_property_call", object, name); 558 return TypeError("non_object_property_call", object, name);
557 } 559 }
558 560
559 // Check if the name is trivially convertible to an index and get 561 // Check if the name is trivially convertible to an index and get
560 // the element if so. 562 // the element if so.
561 uint32_t index; 563 uint32_t index;
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", name, target()); 791 TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", name, target());
790 } 792 }
791 793
792 794
793 MaybeObject* KeyedCallIC::LoadFunction(Handle<Object> object, 795 MaybeObject* KeyedCallIC::LoadFunction(Handle<Object> object,
794 Handle<Object> key) { 796 Handle<Object> key) {
795 if (key->IsInternalizedString()) { 797 if (key->IsInternalizedString()) {
796 return CallICBase::LoadFunction(object, Handle<String>::cast(key)); 798 return CallICBase::LoadFunction(object, Handle<String>::cast(key));
797 } 799 }
798 800
799 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
800 if (object->IsJSObject()) {
801 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
802 if (receiver->map()->is_deprecated()) {
803 use_ic = false;
804 JSObject::MigrateInstance(receiver);
805 }
806 }
807
808 if (object->IsUndefined() || object->IsNull()) { 801 if (object->IsUndefined() || object->IsNull()) {
809 return TypeError("non_object_property_call", object, key); 802 return TypeError("non_object_property_call", object, key);
810 } 803 }
811 804
812 ASSERT(!(use_ic && object->IsJSGlobalProxy())); 805 bool use_ic = MigrateDeprecated(object)
806 ? false : FLAG_use_ic && !object->IsAccessCheckNeeded();
813 807
814 if (use_ic && state() != MEGAMORPHIC) { 808 if (use_ic && state() != MEGAMORPHIC) {
809 ASSERT(!object->IsJSGlobalProxy());
815 int argc = target()->arguments_count(); 810 int argc = target()->arguments_count();
816 Handle<Code> stub = isolate()->stub_cache()->ComputeCallMegamorphic( 811 Handle<Code> stub = isolate()->stub_cache()->ComputeCallMegamorphic(
817 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); 812 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState);
818 if (object->IsJSObject()) { 813 if (object->IsJSObject()) {
819 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 814 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
820 if (receiver->elements()->map() == 815 if (receiver->elements()->map() ==
821 isolate()->heap()->non_strict_arguments_elements_map()) { 816 isolate()->heap()->non_strict_arguments_elements_map()) {
822 stub = isolate()->stub_cache()->ComputeCallArguments(argc); 817 stub = isolate()->stub_cache()->ComputeCallArguments(argc);
823 } 818 }
824 } 819 }
(...skipping 19 matching lines...) Expand all
844 839
845 840
846 MaybeObject* LoadIC::Load(Handle<Object> object, 841 MaybeObject* LoadIC::Load(Handle<Object> object,
847 Handle<String> name) { 842 Handle<String> name) {
848 // If the object is undefined or null it's illegal to try to get any 843 // If the object is undefined or null it's illegal to try to get any
849 // of its properties; throw a TypeError in that case. 844 // of its properties; throw a TypeError in that case.
850 if (object->IsUndefined() || object->IsNull()) { 845 if (object->IsUndefined() || object->IsNull()) {
851 return TypeError("non_object_property_load", object, name); 846 return TypeError("non_object_property_load", object, name);
852 } 847 }
853 848
854 bool use_ic = FLAG_use_ic; 849 if (FLAG_use_ic) {
855
856 if (use_ic) {
857 // Use specialized code for getting the length of strings and 850 // Use specialized code for getting the length of strings and
858 // string wrapper objects. The length property of string wrapper 851 // string wrapper objects. The length property of string wrapper
859 // objects is read-only and therefore always returns the length of 852 // objects is read-only and therefore always returns the length of
860 // the underlying string value. See ECMA-262 15.5.5.1. 853 // the underlying string value. See ECMA-262 15.5.5.1.
861 if (object->IsStringWrapper() && 854 if (object->IsStringWrapper() &&
862 name->Equals(isolate()->heap()->length_string())) { 855 name->Equals(isolate()->heap()->length_string())) {
863 Handle<Code> stub; 856 Handle<Code> stub;
864 if (state() == UNINITIALIZED) { 857 if (state() == UNINITIALIZED) {
865 stub = pre_monomorphic_stub(); 858 stub = pre_monomorphic_stub();
866 } else if (state() == PREMONOMORPHIC || state() == MONOMORPHIC) { 859 } else if (state() == PREMONOMORPHIC || state() == MONOMORPHIC) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 } 896 }
904 return *Accessors::FunctionGetPrototype(Handle<JSFunction>::cast(object)); 897 return *Accessors::FunctionGetPrototype(Handle<JSFunction>::cast(object));
905 } 898 }
906 } 899 }
907 900
908 // Check if the name is trivially convertible to an index and get 901 // Check if the name is trivially convertible to an index and get
909 // the element or char if so. 902 // the element or char if so.
910 uint32_t index; 903 uint32_t index;
911 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { 904 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) {
912 // Rewrite to the generic keyed load stub. 905 // Rewrite to the generic keyed load stub.
913 if (use_ic) set_target(*generic_stub()); 906 if (FLAG_use_ic) set_target(*generic_stub());
914 return Runtime::GetElementOrCharAtOrFail(isolate(), object, index); 907 return Runtime::GetElementOrCharAtOrFail(isolate(), object, index);
915 } 908 }
916 909
917 if (object->IsJSObject()) { 910 bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic;
918 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
919 if (receiver->map()->is_deprecated()) {
920 use_ic = false;
921 JSObject::MigrateInstance(receiver);
922 }
923 }
924 911
925 // Named lookup in the object. 912 // Named lookup in the object.
926 LookupResult lookup(isolate()); 913 LookupResult lookup(isolate());
927 LookupForRead(object, name, &lookup); 914 LookupForRead(object, name, &lookup);
928 915
929 // If we did not find a property, check if we need to throw an exception. 916 // If we did not find a property, check if we need to throw an exception.
930 if (!lookup.IsFound()) { 917 if (!lookup.IsFound()) {
931 if (IsUndeclaredGlobal(object)) { 918 if (IsUndeclaredGlobal(object)) {
932 return ReferenceError("not_defined", name); 919 return ReferenceError("not_defined", name);
933 } 920 }
934 LOG(isolate(), SuspectReadEvent(*name, *object)); 921 LOG(isolate(), SuspectReadEvent(*name, *object));
935 } 922 }
936 923
937 // Update inline cache and stub cache. 924 // Update inline cache and stub cache.
938 if (use_ic) UpdateCaches(&lookup, object, name); 925 if (use_ic) UpdateCaches(&lookup, object, name);
939 926
940 PropertyAttributes attr; 927 PropertyAttributes attr;
941 if (lookup.IsInterceptor() || lookup.IsHandler()) { 928 // Get the property.
942 // Get the property. 929 Handle<Object> result =
943 Handle<Object> result = 930 Object::GetProperty(object, object, &lookup, name, &attr);
944 Object::GetProperty(object, object, &lookup, name, &attr); 931 RETURN_IF_EMPTY_HANDLE(isolate(), result);
945 RETURN_IF_EMPTY_HANDLE(isolate(), result); 932 // If the property is not present, check if we need to throw an
946 // If the property is not present, check if we need to throw an 933 // exception.
947 // exception. 934 if ((lookup.IsInterceptor() || lookup.IsHandler()) &&
948 if (attr == ABSENT && IsUndeclaredGlobal(object)) { 935 attr == ABSENT && IsUndeclaredGlobal(object)) {
949 return ReferenceError("not_defined", name); 936 return ReferenceError("not_defined", name);
950 }
951 return *result;
952 } 937 }
953 938 return *result;
954 // Get the property.
955 return Object::GetPropertyOrFail(object, object, &lookup, name, &attr);
956 } 939 }
957 940
958 941
959 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, 942 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
960 Handle<Map> new_receiver_map) { 943 Handle<Map> new_receiver_map) {
961 ASSERT(!new_receiver_map.is_null()); 944 ASSERT(!new_receiver_map.is_null());
962 for (int current = 0; current < receiver_maps->length(); ++current) { 945 for (int current = 0; current < receiver_maps->length(); ++current) {
963 if (!receiver_maps->at(current).is_null() && 946 if (!receiver_maps->at(current).is_null() &&
964 receiver_maps->at(current).is_identical_to(new_receiver_map)) { 947 receiver_maps->at(current).is_identical_to(new_receiver_map)) {
965 return false; 948 return false;
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
1342 } 1325 }
1343 1326
1344 return isolate()->stub_cache()->ComputeLoadElementPolymorphic( 1327 return isolate()->stub_cache()->ComputeLoadElementPolymorphic(
1345 &target_receiver_maps); 1328 &target_receiver_maps);
1346 } 1329 }
1347 1330
1348 1331
1349 MaybeObject* KeyedLoadIC::Load(Handle<Object> object, 1332 MaybeObject* KeyedLoadIC::Load(Handle<Object> object,
1350 Handle<Object> key, 1333 Handle<Object> key,
1351 ICMissMode miss_mode) { 1334 ICMissMode miss_mode) {
1335 if (MigrateDeprecated(object)) {
1336 return Runtime::GetObjectPropertyOrFail(isolate(), object, key);
1337 }
1338
1352 // Check for values that can be converted into an internalized string directly 1339 // Check for values that can be converted into an internalized string directly
1353 // or is representable as a smi. 1340 // or is representable as a smi.
1354 key = TryConvertKey(key, isolate()); 1341 key = TryConvertKey(key, isolate());
1355 1342
1356 if (key->IsInternalizedString()) { 1343 if (key->IsInternalizedString()) {
1357 return LoadIC::Load(object, Handle<String>::cast(key)); 1344 return LoadIC::Load(object, Handle<String>::cast(key));
1358 } 1345 }
1359 1346
1360 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); 1347 if (FLAG_use_ic && !object->IsAccessCheckNeeded()) {
1361 ASSERT(!(use_ic && object->IsJSGlobalProxy())); 1348 ASSERT(!object->IsJSGlobalProxy());
1349 Handle<Code> stub = generic_stub();
1350 if (miss_mode == MISS_FORCE_GENERIC) {
1351 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "force generic");
1352 } else if (object->IsString() && key->IsNumber()) {
1353 if (state() == UNINITIALIZED) stub = string_stub();
1354 } else if (object->IsJSObject()) {
1355 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1356 if (receiver->elements()->map() ==
1357 isolate()->heap()->non_strict_arguments_elements_map()) {
1358 stub = non_strict_arguments_stub();
1359 } else if (receiver->HasIndexedInterceptor()) {
1360 stub = indexed_interceptor_stub();
1361 } else if (!key->ToSmi()->IsFailure() &&
1362 (!target().is_identical_to(non_strict_arguments_stub()))) {
1363 stub = LoadElementStub(receiver);
1364 }
1365 }
1362 1366
1363 if (use_ic) { 1367 ASSERT(!stub.is_null());
1364 Handle<Code> stub = generic_stub(); 1368 set_target(*stub);
1365 if (miss_mode != MISS_FORCE_GENERIC) { 1369 TRACE_IC("KeyedLoadIC", key, target());
1366 if (object->IsString() && key->IsNumber()) {
1367 if (state() == UNINITIALIZED) {
1368 stub = string_stub();
1369 }
1370 } else if (object->IsJSObject()) {
1371 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1372 if (receiver->map()->is_deprecated()) {
1373 use_ic = false;
1374 JSObject::MigrateInstance(receiver);
1375 }
1376
1377 if (receiver->elements()->map() ==
1378 isolate()->heap()->non_strict_arguments_elements_map()) {
1379 stub = non_strict_arguments_stub();
1380 } else if (receiver->HasIndexedInterceptor()) {
1381 stub = indexed_interceptor_stub();
1382 } else if (!key->ToSmi()->IsFailure() &&
1383 (!target().is_identical_to(non_strict_arguments_stub()))) {
1384 stub = LoadElementStub(receiver);
1385 }
1386 }
1387 } else {
1388 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "force generic");
1389 }
1390 if (use_ic) {
1391 ASSERT(!stub.is_null());
1392 set_target(*stub);
1393 TRACE_IC("KeyedLoadIC", key, target());
1394 }
1395 } 1370 }
1396 1371
1397 1372
1398 return Runtime::GetObjectPropertyOrFail(isolate(), object, key); 1373 return Runtime::GetObjectPropertyOrFail(isolate(), object, key);
1399 } 1374 }
1400 1375
1401 1376
1402 Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup, 1377 Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup,
1403 Handle<JSObject> receiver, 1378 Handle<JSObject> receiver,
1404 Handle<String> name) { 1379 Handle<String> name) {
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1520 ic->MarkMonomorphicPrototypeFailure(); 1495 ic->MarkMonomorphicPrototypeFailure();
1521 } 1496 }
1522 return true; 1497 return true;
1523 } 1498 }
1524 1499
1525 1500
1526 MaybeObject* StoreIC::Store(Handle<Object> object, 1501 MaybeObject* StoreIC::Store(Handle<Object> object,
1527 Handle<String> name, 1502 Handle<String> name,
1528 Handle<Object> value, 1503 Handle<Object> value,
1529 JSReceiver::StoreFromKeyed store_mode) { 1504 JSReceiver::StoreFromKeyed store_mode) {
1530 // Handle proxies. 1505 if (MigrateDeprecated(object) || object->IsJSProxy()) {
1531 if (object->IsJSProxy()) {
1532 Handle<Object> result = JSReceiver::SetProperty( 1506 Handle<Object> result = JSReceiver::SetProperty(
1533 Handle<JSReceiver>::cast(object), name, value, NONE, strict_mode()); 1507 Handle<JSReceiver>::cast(object), name, value, NONE, strict_mode());
1534 RETURN_IF_EMPTY_HANDLE(isolate(), result); 1508 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1535 return *result; 1509 return *result;
1536 } 1510 }
1537 1511
1538 // If the object is undefined or null it's illegal to try to set any 1512 // If the object is undefined or null it's illegal to try to set any
1539 // properties on it; throw a TypeError in that case. 1513 // properties on it; throw a TypeError in that case.
1540 if (object->IsUndefined() || object->IsNull()) { 1514 if (object->IsUndefined() || object->IsNull()) {
1541 return TypeError("non_object_property_store", object, name); 1515 return TypeError("non_object_property_store", object, name);
1542 } 1516 }
1543 1517
1544 // The length property of string values is read-only. Throw in strict mode. 1518 // The length property of string values is read-only. Throw in strict mode.
1545 if (strict_mode() == kStrictMode && object->IsString() && 1519 if (strict_mode() == kStrictMode && object->IsString() &&
1546 name->Equals(isolate()->heap()->length_string())) { 1520 name->Equals(isolate()->heap()->length_string())) {
1547 return TypeError("strict_read_only_property", object, name); 1521 return TypeError("strict_read_only_property", object, name);
1548 } 1522 }
1549 1523
1550 // Ignore other stores where the receiver is not a JSObject. 1524 // Ignore other stores where the receiver is not a JSObject.
1551 // TODO(1475): Must check prototype chains of object wrappers. 1525 // TODO(1475): Must check prototype chains of object wrappers.
1552 if (!object->IsJSObject()) return *value; 1526 if (!object->IsJSObject()) return *value;
1553 1527
1554 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1528 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1555 1529
1556 bool use_ic = FLAG_use_ic;
1557 if (receiver->map()->is_deprecated()) {
1558 use_ic = false;
1559 JSObject::MigrateInstance(receiver);
1560 }
1561
1562 // Check if the given name is an array index. 1530 // Check if the given name is an array index.
1563 uint32_t index; 1531 uint32_t index;
1564 if (name->AsArrayIndex(&index)) { 1532 if (name->AsArrayIndex(&index)) {
1565 Handle<Object> result = 1533 Handle<Object> result =
1566 JSObject::SetElement(receiver, index, value, NONE, strict_mode()); 1534 JSObject::SetElement(receiver, index, value, NONE, strict_mode());
1567 RETURN_IF_EMPTY_HANDLE(isolate(), result); 1535 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1568 return *value; 1536 return *value;
1569 } 1537 }
1570 1538
1571 // Observed objects are always modified through the runtime. 1539 // Observed objects are always modified through the runtime.
1572 if (FLAG_harmony_observation && receiver->map()->is_observed()) { 1540 if (FLAG_harmony_observation && receiver->map()->is_observed()) {
1573 Handle<Object> result = JSReceiver::SetProperty( 1541 Handle<Object> result = JSReceiver::SetProperty(
1574 receiver, name, value, NONE, strict_mode(), store_mode); 1542 receiver, name, value, NONE, strict_mode(), store_mode);
1575 RETURN_IF_EMPTY_HANDLE(isolate(), result); 1543 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1576 return *result; 1544 return *result;
1577 } 1545 }
1578 1546
1579 // Use specialized code for setting the length of arrays with fast 1547 // Use specialized code for setting the length of arrays with fast
1580 // properties. Slow properties might indicate redefinition of the length 1548 // properties. Slow properties might indicate redefinition of the length
1581 // property. Note that when redefined using Object.freeze, it's possible 1549 // property. Note that when redefined using Object.freeze, it's possible
1582 // to have fast properties but a read-only length. 1550 // to have fast properties but a read-only length.
1583 if (use_ic && 1551 if (FLAG_use_ic &&
1584 receiver->IsJSArray() && 1552 receiver->IsJSArray() &&
1585 name->Equals(isolate()->heap()->length_string()) && 1553 name->Equals(isolate()->heap()->length_string()) &&
1586 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() && 1554 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() &&
1587 receiver->HasFastProperties() && 1555 receiver->HasFastProperties() &&
1588 !receiver->map()->is_frozen()) { 1556 !receiver->map()->is_frozen()) {
1589 Handle<Code> stub = 1557 Handle<Code> stub =
1590 StoreArrayLengthStub(kind(), strict_mode()).GetCode(isolate()); 1558 StoreArrayLengthStub(kind(), strict_mode()).GetCode(isolate());
1591 set_target(*stub); 1559 set_target(*stub);
1592 TRACE_IC("StoreIC", name, stub); 1560 TRACE_IC("StoreIC", name, stub);
1593 Handle<Object> result = JSReceiver::SetProperty( 1561 Handle<Object> result = JSReceiver::SetProperty(
1594 receiver, name, value, NONE, strict_mode(), store_mode); 1562 receiver, name, value, NONE, strict_mode(), store_mode);
1595 RETURN_IF_EMPTY_HANDLE(isolate(), result); 1563 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1596 return *result; 1564 return *result;
1597 } 1565 }
1598 1566
1599 if (receiver->IsJSGlobalProxy()) { 1567 if (receiver->IsJSGlobalProxy()) {
1600 if (use_ic && kind() != Code::KEYED_STORE_IC) { 1568 if (FLAG_use_ic && kind() != Code::KEYED_STORE_IC) {
1601 // Generate a generic stub that goes to the runtime when we see a global 1569 // Generate a generic stub that goes to the runtime when we see a global
1602 // proxy as receiver. 1570 // proxy as receiver.
1603 Handle<Code> stub = global_proxy_stub(); 1571 Handle<Code> stub = global_proxy_stub();
1604 set_target(*stub); 1572 set_target(*stub);
1605 TRACE_IC("StoreIC", name, stub); 1573 TRACE_IC("StoreIC", name, stub);
1606 } 1574 }
1607 Handle<Object> result = JSReceiver::SetProperty( 1575 Handle<Object> result = JSReceiver::SetProperty(
1608 receiver, name, value, NONE, strict_mode(), store_mode); 1576 receiver, name, value, NONE, strict_mode(), store_mode);
1609 RETURN_IF_EMPTY_HANDLE(isolate(), result); 1577 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1610 return *result; 1578 return *result;
1611 } 1579 }
1612 1580
1613 LookupResult lookup(isolate()); 1581 LookupResult lookup(isolate());
1614 bool can_store = LookupForWrite(receiver, name, value, &lookup, this); 1582 bool can_store = LookupForWrite(receiver, name, value, &lookup, this);
1615 if (!can_store && 1583 if (!can_store &&
1616 strict_mode() == kStrictMode && 1584 strict_mode() == kStrictMode &&
1617 !(lookup.IsProperty() && lookup.IsReadOnly()) && 1585 !(lookup.IsProperty() && lookup.IsReadOnly()) &&
1618 IsUndeclaredGlobal(object)) { 1586 IsUndeclaredGlobal(object)) {
1619 // Strict mode doesn't allow setting non-existent global property. 1587 // Strict mode doesn't allow setting non-existent global property.
1620 return ReferenceError("not_defined", name); 1588 return ReferenceError("not_defined", name);
1621 } 1589 }
1622 if (use_ic) { 1590 if (FLAG_use_ic) {
1623 if (state() == UNINITIALIZED) { 1591 if (state() == UNINITIALIZED) {
1624 Handle<Code> stub = pre_monomorphic_stub(); 1592 Handle<Code> stub = pre_monomorphic_stub();
1625 set_target(*stub); 1593 set_target(*stub);
1626 TRACE_IC("StoreIC", name, stub); 1594 TRACE_IC("StoreIC", name, stub);
1627 } else if (can_store) { 1595 } else if (can_store) {
1628 UpdateCaches(&lookup, receiver, name, value); 1596 UpdateCaches(&lookup, receiver, name, value);
1629 } else if (!name->IsCacheable(isolate()) || 1597 } else if (!name->IsCacheable(isolate()) ||
1630 lookup.IsNormal() || 1598 lookup.IsNormal() ||
1631 (lookup.IsField() && lookup.CanHoldValue(value))) { 1599 (lookup.IsField() && lookup.CanHoldValue(value))) {
1632 Handle<Code> stub = generic_stub(); 1600 Handle<Code> stub = generic_stub();
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
1987 return STANDARD_STORE; 1955 return STANDARD_STORE;
1988 } 1956 }
1989 } 1957 }
1990 } 1958 }
1991 1959
1992 1960
1993 MaybeObject* KeyedStoreIC::Store(Handle<Object> object, 1961 MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
1994 Handle<Object> key, 1962 Handle<Object> key,
1995 Handle<Object> value, 1963 Handle<Object> value,
1996 ICMissMode miss_mode) { 1964 ICMissMode miss_mode) {
1965 if (MigrateDeprecated(object)) {
1966 return Runtime::SetObjectPropertyOrFail(
1967 isolate(), object , key, value, NONE, strict_mode());
1968 }
1969
1997 // Check for values that can be converted into an internalized string directly 1970 // Check for values that can be converted into an internalized string directly
1998 // or is representable as a smi. 1971 // or is representable as a smi.
1999 key = TryConvertKey(key, isolate()); 1972 key = TryConvertKey(key, isolate());
2000 1973
2001 if (key->IsInternalizedString()) { 1974 if (key->IsInternalizedString()) {
2002 return StoreIC::Store(object, 1975 return StoreIC::Store(object,
2003 Handle<String>::cast(key), 1976 Handle<String>::cast(key),
2004 value, 1977 value,
2005 JSReceiver::MAY_BE_STORE_FROM_KEYED); 1978 JSReceiver::MAY_BE_STORE_FROM_KEYED);
2006 } 1979 }
2007 1980
2008 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded() && 1981 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded() &&
2009 !(FLAG_harmony_observation && object->IsJSObject() && 1982 !(FLAG_harmony_observation && object->IsJSObject() &&
2010 JSObject::cast(*object)->map()->is_observed()); 1983 JSObject::cast(*object)->map()->is_observed());
2011 if (use_ic && !object->IsSmi()) { 1984 if (use_ic && !object->IsSmi()) {
2012 // Don't use ICs for maps of the objects in Array's prototype chain. We 1985 // Don't use ICs for maps of the objects in Array's prototype chain. We
2013 // expect to be able to trap element sets to objects with those maps in the 1986 // expect to be able to trap element sets to objects with those maps in the
2014 // runtime to enable optimization of element hole access. 1987 // runtime to enable optimization of element hole access.
2015 Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object); 1988 Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
2016 if (heap_object->map()->IsMapInArrayPrototypeChain()) use_ic = false; 1989 if (heap_object->map()->IsMapInArrayPrototypeChain()) use_ic = false;
2017 } 1990 }
2018 ASSERT(!(use_ic && object->IsJSGlobalProxy()));
2019 1991
2020 if (use_ic) { 1992 if (use_ic) {
1993 ASSERT(!object->IsJSGlobalProxy());
1994
2021 Handle<Code> stub = generic_stub(); 1995 Handle<Code> stub = generic_stub();
2022 if (miss_mode != MISS_FORCE_GENERIC) { 1996 if (miss_mode != MISS_FORCE_GENERIC) {
2023 if (object->IsJSObject()) { 1997 if (object->IsJSObject()) {
2024 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1998 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
2025 if (receiver->map()->is_deprecated()) {
2026 JSObject::MigrateInstance(receiver);
2027 }
2028 bool key_is_smi_like = key->IsSmi() || !key->ToSmi()->IsFailure(); 1999 bool key_is_smi_like = key->IsSmi() || !key->ToSmi()->IsFailure();
2029 if (receiver->elements()->map() == 2000 if (receiver->elements()->map() ==
2030 isolate()->heap()->non_strict_arguments_elements_map()) { 2001 isolate()->heap()->non_strict_arguments_elements_map()) {
2031 stub = non_strict_arguments_stub(); 2002 stub = non_strict_arguments_stub();
2032 } else if (key_is_smi_like && 2003 } else if (key_is_smi_like &&
2033 (!target().is_identical_to(non_strict_arguments_stub()))) { 2004 (!target().is_identical_to(non_strict_arguments_stub()))) {
2034 KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value); 2005 KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value);
2035 stub = StoreElementStub(receiver, store_mode); 2006 stub = StoreElementStub(receiver, store_mode);
2036 } else { 2007 } else {
2037 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "key not a number"); 2008 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "key not a number");
(...skipping 929 matching lines...) Expand 10 before | Expand all | Expand 10 after
2967 #undef ADDR 2938 #undef ADDR
2968 }; 2939 };
2969 2940
2970 2941
2971 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2942 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2972 return IC_utilities[id]; 2943 return IC_utilities[id];
2973 } 2944 }
2974 2945
2975 2946
2976 } } // namespace v8::internal 2947 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698