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

Side by Side Diff: src/ic.cc

Issue 23658047: Don't update ICs when the receiver has a deprecated map. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 3 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 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 int index = frame->ComputeExpressionsCount() - (argc + 1); 542 int index = frame->ComputeExpressionsCount() - (argc + 1);
543 frame->SetExpression(index, *isolate()->factory()->ToObject(object)); 543 frame->SetExpression(index, *isolate()->factory()->ToObject(object));
544 } 544 }
545 } 545 }
546 546
547 547
548 MaybeObject* CallICBase::LoadFunction(State state, 548 MaybeObject* CallICBase::LoadFunction(State state,
549 Code::ExtraICState extra_ic_state, 549 Code::ExtraICState extra_ic_state,
550 Handle<Object> object, 550 Handle<Object> object,
551 Handle<String> name) { 551 Handle<String> name) {
552 bool use_ic = FLAG_use_ic;
552 if (object->IsJSObject()) { 553 if (object->IsJSObject()) {
553 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 554 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
554 if (receiver->map()->is_deprecated()) { 555 if (receiver->map()->is_deprecated()) {
556 use_ic = false;
555 JSObject::MigrateInstance(receiver); 557 JSObject::MigrateInstance(receiver);
556 } 558 }
557 } 559 }
558 560
559 // If the object is undefined or null it's illegal to try to get any 561 // If the object is undefined or null it's illegal to try to get any
560 // of its properties; throw a TypeError in that case. 562 // of its properties; throw a TypeError in that case.
561 if (object->IsUndefined() || object->IsNull()) { 563 if (object->IsUndefined() || object->IsNull()) {
562 return TypeError("non_object_property_call", object, name); 564 return TypeError("non_object_property_call", object, name);
563 } 565 }
564 566
(...skipping 18 matching lines...) Expand all
583 585
584 if (!lookup.IsFound()) { 586 if (!lookup.IsFound()) {
585 // If the object does not have the requested property, check which 587 // If the object does not have the requested property, check which
586 // exception we need to throw. 588 // exception we need to throw.
587 return IsUndeclaredGlobal(object) 589 return IsUndeclaredGlobal(object)
588 ? ReferenceError("not_defined", name) 590 ? ReferenceError("not_defined", name)
589 : TypeError("undefined_method", object, name); 591 : TypeError("undefined_method", object, name);
590 } 592 }
591 593
592 // Lookup is valid: Update inline cache and stub cache. 594 // Lookup is valid: Update inline cache and stub cache.
593 if (FLAG_use_ic) { 595 if (use_ic) UpdateCaches(&lookup, state, extra_ic_state, object, name);
594 UpdateCaches(&lookup, state, extra_ic_state, object, name);
595 }
596 596
597 // Get the property. 597 // Get the property.
598 PropertyAttributes attr; 598 PropertyAttributes attr;
599 Handle<Object> result = 599 Handle<Object> result =
600 Object::GetProperty(object, object, &lookup, name, &attr); 600 Object::GetProperty(object, object, &lookup, name, &attr);
601 RETURN_IF_EMPTY_HANDLE(isolate(), result); 601 RETURN_IF_EMPTY_HANDLE(isolate(), result);
602 602
603 if (lookup.IsInterceptor() && attr == ABSENT) { 603 if (lookup.IsInterceptor() && attr == ABSENT) {
604 // If the object does not have the requested property, check which 604 // If the object does not have the requested property, check which
605 // exception we need to throw. 605 // exception we need to throw.
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 MaybeObject* KeyedCallIC::LoadFunction(State state, 812 MaybeObject* KeyedCallIC::LoadFunction(State state,
813 Handle<Object> object, 813 Handle<Object> object,
814 Handle<Object> key) { 814 Handle<Object> key) {
815 if (key->IsInternalizedString()) { 815 if (key->IsInternalizedString()) {
816 return CallICBase::LoadFunction(state, 816 return CallICBase::LoadFunction(state,
817 Code::kNoExtraICState, 817 Code::kNoExtraICState,
818 object, 818 object,
819 Handle<String>::cast(key)); 819 Handle<String>::cast(key));
820 } 820 }
821 821
822 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
822 if (object->IsJSObject()) { 823 if (object->IsJSObject()) {
823 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 824 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
824 if (receiver->map()->is_deprecated()) { 825 if (receiver->map()->is_deprecated()) {
826 use_ic = false;
825 JSObject::MigrateInstance(receiver); 827 JSObject::MigrateInstance(receiver);
826 } 828 }
827 } 829 }
828 830
829 if (object->IsUndefined() || object->IsNull()) { 831 if (object->IsUndefined() || object->IsNull()) {
830 return TypeError("non_object_property_call", object, key); 832 return TypeError("non_object_property_call", object, key);
831 } 833 }
832 834
833 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
834 ASSERT(!(use_ic && object->IsJSGlobalProxy())); 835 ASSERT(!(use_ic && object->IsJSGlobalProxy()));
835 836
836 if (use_ic && state != MEGAMORPHIC) { 837 if (use_ic && state != MEGAMORPHIC) {
837 int argc = target()->arguments_count(); 838 int argc = target()->arguments_count();
838 Handle<Code> stub = isolate()->stub_cache()->ComputeCallMegamorphic( 839 Handle<Code> stub = isolate()->stub_cache()->ComputeCallMegamorphic(
839 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); 840 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState);
840 if (object->IsJSObject()) { 841 if (object->IsJSObject()) {
841 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 842 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
842 if (receiver->elements()->map() == 843 if (receiver->elements()->map() ==
843 isolate()->heap()->non_strict_arguments_elements_map()) { 844 isolate()->heap()->non_strict_arguments_elements_map()) {
(...skipping 23 matching lines...) Expand all
867 868
868 MaybeObject* LoadIC::Load(State state, 869 MaybeObject* LoadIC::Load(State state,
869 Handle<Object> object, 870 Handle<Object> object,
870 Handle<String> name) { 871 Handle<String> name) {
871 // If the object is undefined or null it's illegal to try to get any 872 // If the object is undefined or null it's illegal to try to get any
872 // of its properties; throw a TypeError in that case. 873 // of its properties; throw a TypeError in that case.
873 if (object->IsUndefined() || object->IsNull()) { 874 if (object->IsUndefined() || object->IsNull()) {
874 return TypeError("non_object_property_load", object, name); 875 return TypeError("non_object_property_load", object, name);
875 } 876 }
876 877
877 if (FLAG_use_ic) { 878 bool use_ic = FLAG_use_ic;
879
880 if (use_ic) {
878 // Use specialized code for getting the length of strings and 881 // Use specialized code for getting the length of strings and
879 // string wrapper objects. The length property of string wrapper 882 // string wrapper objects. The length property of string wrapper
880 // objects is read-only and therefore always returns the length of 883 // objects is read-only and therefore always returns the length of
881 // the underlying string value. See ECMA-262 15.5.5.1. 884 // the underlying string value. See ECMA-262 15.5.5.1.
882 if (object->IsStringWrapper() && 885 if (object->IsStringWrapper() &&
883 name->Equals(isolate()->heap()->length_string())) { 886 name->Equals(isolate()->heap()->length_string())) {
884 Handle<Code> stub; 887 Handle<Code> stub;
885 if (state == UNINITIALIZED) { 888 if (state == UNINITIALIZED) {
886 stub = pre_monomorphic_stub(); 889 stub = pre_monomorphic_stub();
887 } else if (state == PREMONOMORPHIC || state == MONOMORPHIC) { 890 } else if (state == PREMONOMORPHIC || state == MONOMORPHIC) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 } 927 }
925 return *Accessors::FunctionGetPrototype(Handle<JSFunction>::cast(object)); 928 return *Accessors::FunctionGetPrototype(Handle<JSFunction>::cast(object));
926 } 929 }
927 } 930 }
928 931
929 // Check if the name is trivially convertible to an index and get 932 // Check if the name is trivially convertible to an index and get
930 // the element or char if so. 933 // the element or char if so.
931 uint32_t index; 934 uint32_t index;
932 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { 935 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) {
933 // Rewrite to the generic keyed load stub. 936 // Rewrite to the generic keyed load stub.
934 if (FLAG_use_ic) set_target(*generic_stub()); 937 if (use_ic) set_target(*generic_stub());
935 return Runtime::GetElementOrCharAtOrFail(isolate(), object, index); 938 return Runtime::GetElementOrCharAtOrFail(isolate(), object, index);
936 } 939 }
937 940
938 if (object->IsJSObject()) { 941 if (object->IsJSObject()) {
939 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 942 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
940 if (receiver->map()->is_deprecated()) { 943 if (receiver->map()->is_deprecated()) {
944 use_ic = false;
941 JSObject::MigrateInstance(receiver); 945 JSObject::MigrateInstance(receiver);
942 } 946 }
943 } 947 }
944 948
945 // Named lookup in the object. 949 // Named lookup in the object.
946 LookupResult lookup(isolate()); 950 LookupResult lookup(isolate());
947 LookupForRead(object, name, &lookup); 951 LookupForRead(object, name, &lookup);
948 952
949 // If we did not find a property, check if we need to throw an exception. 953 // If we did not find a property, check if we need to throw an exception.
950 if (!lookup.IsFound()) { 954 if (!lookup.IsFound()) {
951 if (IsUndeclaredGlobal(object)) { 955 if (IsUndeclaredGlobal(object)) {
952 return ReferenceError("not_defined", name); 956 return ReferenceError("not_defined", name);
953 } 957 }
954 LOG(isolate(), SuspectReadEvent(*name, *object)); 958 LOG(isolate(), SuspectReadEvent(*name, *object));
955 } 959 }
956 960
957 // Update inline cache and stub cache. 961 // Update inline cache and stub cache.
958 if (FLAG_use_ic) UpdateCaches(&lookup, state, object, name); 962 if (use_ic) UpdateCaches(&lookup, state, object, name);
959 963
960 PropertyAttributes attr; 964 PropertyAttributes attr;
961 if (lookup.IsInterceptor() || lookup.IsHandler()) { 965 if (lookup.IsInterceptor() || lookup.IsHandler()) {
962 // Get the property. 966 // Get the property.
963 Handle<Object> result = 967 Handle<Object> result =
964 Object::GetProperty(object, object, &lookup, name, &attr); 968 Object::GetProperty(object, object, &lookup, name, &attr);
965 RETURN_IF_EMPTY_HANDLE(isolate(), result); 969 RETURN_IF_EMPTY_HANDLE(isolate(), result);
966 // If the property is not present, check if we need to throw an 970 // If the property is not present, check if we need to throw an
967 // exception. 971 // exception.
968 if (attr == ABSENT && IsUndeclaredGlobal(object)) { 972 if (attr == ABSENT && IsUndeclaredGlobal(object)) {
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after
1496 if (use_ic) { 1500 if (use_ic) {
1497 Handle<Code> stub = generic_stub(); 1501 Handle<Code> stub = generic_stub();
1498 if (miss_mode != MISS_FORCE_GENERIC) { 1502 if (miss_mode != MISS_FORCE_GENERIC) {
1499 if (object->IsString() && key->IsNumber()) { 1503 if (object->IsString() && key->IsNumber()) {
1500 if (state == UNINITIALIZED) { 1504 if (state == UNINITIALIZED) {
1501 stub = string_stub(); 1505 stub = string_stub();
1502 } 1506 }
1503 } else if (object->IsJSObject()) { 1507 } else if (object->IsJSObject()) {
1504 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1508 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1505 if (receiver->map()->is_deprecated()) { 1509 if (receiver->map()->is_deprecated()) {
1510 use_ic = false;
1506 JSObject::MigrateInstance(receiver); 1511 JSObject::MigrateInstance(receiver);
1507 } 1512 }
1508 1513
1509 if (receiver->elements()->map() == 1514 if (receiver->elements()->map() ==
1510 isolate()->heap()->non_strict_arguments_elements_map()) { 1515 isolate()->heap()->non_strict_arguments_elements_map()) {
1511 stub = non_strict_arguments_stub(); 1516 stub = non_strict_arguments_stub();
1512 } else if (receiver->HasIndexedInterceptor()) { 1517 } else if (receiver->HasIndexedInterceptor()) {
1513 stub = indexed_interceptor_stub(); 1518 stub = indexed_interceptor_stub();
1514 } else if (!key->ToSmi()->IsFailure() && 1519 } else if (!key->ToSmi()->IsFailure() &&
1515 (target() != *non_strict_arguments_stub())) { 1520 (target() != *non_strict_arguments_stub())) {
1516 stub = LoadElementStub(receiver); 1521 stub = LoadElementStub(receiver);
1517 } 1522 }
1518 } 1523 }
1519 } else { 1524 } else {
1520 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "force generic"); 1525 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "force generic");
1521 } 1526 }
1522 ASSERT(!stub.is_null()); 1527 if (use_ic) {
1523 set_target(*stub); 1528 ASSERT(!stub.is_null());
1524 TRACE_IC("KeyedLoadIC", key, state, target()); 1529 set_target(*stub);
1530 TRACE_IC("KeyedLoadIC", key, state, target());
1531 }
1525 } 1532 }
1526 1533
1527 1534
1528 return Runtime::GetObjectPropertyOrFail(isolate(), object, key); 1535 return Runtime::GetObjectPropertyOrFail(isolate(), object, key);
1529 } 1536 }
1530 1537
1531 1538
1532 Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup, 1539 Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup,
1533 Handle<JSObject> receiver, 1540 Handle<JSObject> receiver,
1534 Handle<String> name) { 1541 Handle<String> name) {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1678 name->Equals(isolate()->heap()->length_string())) { 1685 name->Equals(isolate()->heap()->length_string())) {
1679 return TypeError("strict_read_only_property", object, name); 1686 return TypeError("strict_read_only_property", object, name);
1680 } 1687 }
1681 1688
1682 // Ignore other stores where the receiver is not a JSObject. 1689 // Ignore other stores where the receiver is not a JSObject.
1683 // TODO(1475): Must check prototype chains of object wrappers. 1690 // TODO(1475): Must check prototype chains of object wrappers.
1684 if (!object->IsJSObject()) return *value; 1691 if (!object->IsJSObject()) return *value;
1685 1692
1686 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1693 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1687 1694
1695 bool use_ic = FLAG_use_ic;
1688 if (receiver->map()->is_deprecated()) { 1696 if (receiver->map()->is_deprecated()) {
1697 use_ic = false;
1689 JSObject::MigrateInstance(receiver); 1698 JSObject::MigrateInstance(receiver);
1690 } 1699 }
1691 1700
1692 // Check if the given name is an array index. 1701 // Check if the given name is an array index.
1693 uint32_t index; 1702 uint32_t index;
1694 if (name->AsArrayIndex(&index)) { 1703 if (name->AsArrayIndex(&index)) {
1695 Handle<Object> result = 1704 Handle<Object> result =
1696 JSObject::SetElement(receiver, index, value, NONE, strict_mode); 1705 JSObject::SetElement(receiver, index, value, NONE, strict_mode);
1697 RETURN_IF_EMPTY_HANDLE(isolate(), result); 1706 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1698 return *value; 1707 return *value;
1699 } 1708 }
1700 1709
1701 // Observed objects are always modified through the runtime. 1710 // Observed objects are always modified through the runtime.
1702 if (FLAG_harmony_observation && receiver->map()->is_observed()) { 1711 if (FLAG_harmony_observation && receiver->map()->is_observed()) {
1703 return JSReceiver::SetPropertyOrFail( 1712 return JSReceiver::SetPropertyOrFail(
1704 receiver, name, value, NONE, strict_mode, store_mode); 1713 receiver, name, value, NONE, strict_mode, store_mode);
1705 } 1714 }
1706 1715
1707 // Use specialized code for setting the length of arrays with fast 1716 // Use specialized code for setting the length of arrays with fast
1708 // properties. Slow properties might indicate redefinition of the length 1717 // properties. Slow properties might indicate redefinition of the length
1709 // property. Note that when redefined using Object.freeze, it's possible 1718 // property. Note that when redefined using Object.freeze, it's possible
1710 // to have fast properties but a read-only length. 1719 // to have fast properties but a read-only length.
1711 if (FLAG_use_ic && 1720 if (use_ic &&
1712 receiver->IsJSArray() && 1721 receiver->IsJSArray() &&
1713 name->Equals(isolate()->heap()->length_string()) && 1722 name->Equals(isolate()->heap()->length_string()) &&
1714 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() && 1723 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() &&
1715 receiver->HasFastProperties() && 1724 receiver->HasFastProperties() &&
1716 !receiver->map()->is_frozen()) { 1725 !receiver->map()->is_frozen()) {
1717 Handle<Code> stub = 1726 Handle<Code> stub =
1718 StoreArrayLengthStub(kind(), strict_mode).GetCode(isolate()); 1727 StoreArrayLengthStub(kind(), strict_mode).GetCode(isolate());
1719 set_target(*stub); 1728 set_target(*stub);
1720 TRACE_IC("StoreIC", name, state, *stub); 1729 TRACE_IC("StoreIC", name, state, *stub);
1721 return JSReceiver::SetPropertyOrFail( 1730 return JSReceiver::SetPropertyOrFail(
1722 receiver, name, value, NONE, strict_mode, store_mode); 1731 receiver, name, value, NONE, strict_mode, store_mode);
1723 } 1732 }
1724 1733
1725 if (receiver->IsJSGlobalProxy()) { 1734 if (receiver->IsJSGlobalProxy()) {
1726 if (FLAG_use_ic && kind() != Code::KEYED_STORE_IC) { 1735 if (use_ic && kind() != Code::KEYED_STORE_IC) {
1727 // Generate a generic stub that goes to the runtime when we see a global 1736 // Generate a generic stub that goes to the runtime when we see a global
1728 // proxy as receiver. 1737 // proxy as receiver.
1729 Handle<Code> stub = (strict_mode == kStrictMode) 1738 Handle<Code> stub = (strict_mode == kStrictMode)
1730 ? global_proxy_stub_strict() 1739 ? global_proxy_stub_strict()
1731 : global_proxy_stub(); 1740 : global_proxy_stub();
1732 set_target(*stub); 1741 set_target(*stub);
1733 TRACE_IC("StoreIC", name, state, *stub); 1742 TRACE_IC("StoreIC", name, state, *stub);
1734 } 1743 }
1735 return JSReceiver::SetPropertyOrFail( 1744 return JSReceiver::SetPropertyOrFail(
1736 receiver, name, value, NONE, strict_mode, store_mode); 1745 receiver, name, value, NONE, strict_mode, store_mode);
1737 } 1746 }
1738 1747
1739 LookupResult lookup(isolate()); 1748 LookupResult lookup(isolate());
1740 bool can_store = LookupForWrite(receiver, name, value, &lookup, &state); 1749 bool can_store = LookupForWrite(receiver, name, value, &lookup, &state);
1741 if (!can_store && 1750 if (!can_store &&
1742 strict_mode == kStrictMode && 1751 strict_mode == kStrictMode &&
1743 !(lookup.IsProperty() && lookup.IsReadOnly()) && 1752 !(lookup.IsProperty() && lookup.IsReadOnly()) &&
1744 IsUndeclaredGlobal(object)) { 1753 IsUndeclaredGlobal(object)) {
1745 // Strict mode doesn't allow setting non-existent global property. 1754 // Strict mode doesn't allow setting non-existent global property.
1746 return ReferenceError("not_defined", name); 1755 return ReferenceError("not_defined", name);
1747 } 1756 }
1748 if (FLAG_use_ic) { 1757 if (use_ic) {
1749 if (state == UNINITIALIZED) { 1758 if (state == UNINITIALIZED) {
1750 Handle<Code> stub = (strict_mode == kStrictMode) 1759 Handle<Code> stub = (strict_mode == kStrictMode)
1751 ? pre_monomorphic_stub_strict() 1760 ? pre_monomorphic_stub_strict()
1752 : pre_monomorphic_stub(); 1761 : pre_monomorphic_stub();
1753 set_target(*stub); 1762 set_target(*stub);
1754 TRACE_IC("StoreIC", name, state, *stub); 1763 TRACE_IC("StoreIC", name, state, *stub);
1755 } else if (can_store) { 1764 } else if (can_store) {
1756 UpdateCaches(&lookup, state, strict_mode, receiver, name, value); 1765 UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
1757 } else if (!name->IsCacheable(isolate()) || 1766 } else if (!name->IsCacheable(isolate()) ||
1758 lookup.IsNormal() || 1767 lookup.IsNormal() ||
(...skipping 1381 matching lines...) Expand 10 before | Expand all | Expand 10 after
3140 #undef ADDR 3149 #undef ADDR
3141 }; 3150 };
3142 3151
3143 3152
3144 Address IC::AddressFromUtilityId(IC::UtilityId id) { 3153 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3145 return IC_utilities[id]; 3154 return IC_utilities[id];
3146 } 3155 }
3147 3156
3148 3157
3149 } } // namespace v8::internal 3158 } } // 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