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

Side by Side Diff: src/ic.cc

Issue 17162002: Version 3.19.17. (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 7 years, 6 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') | src/lithium.h » ('j') | 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 918 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 929
930 // If we did not find a property, check if we need to throw an exception. 930 // If we did not find a property, check if we need to throw an exception.
931 if (!lookup.IsFound()) { 931 if (!lookup.IsFound()) {
932 if (IsUndeclaredGlobal(object)) { 932 if (IsUndeclaredGlobal(object)) {
933 return ReferenceError("not_defined", name); 933 return ReferenceError("not_defined", name);
934 } 934 }
935 LOG(isolate(), SuspectReadEvent(*name, *object)); 935 LOG(isolate(), SuspectReadEvent(*name, *object));
936 } 936 }
937 937
938 // Update inline cache and stub cache. 938 // Update inline cache and stub cache.
939 if (FLAG_use_ic) UpdateCaches(&lookup, state, object, name); 939 if (FLAG_use_ic) {
940 if (!object->IsJSObject()) {
941 // TODO(jkummerow): It would be nice to support non-JSObjects in
942 // UpdateCaches, then we wouldn't need to go generic here.
943 set_target(*generic_stub());
944 } else {
945 UpdateCaches(&lookup, state, object, name);
946 }
947 }
940 948
941 PropertyAttributes attr; 949 PropertyAttributes attr;
942 if (lookup.IsInterceptor() || lookup.IsHandler()) { 950 if (lookup.IsInterceptor() || lookup.IsHandler()) {
943 // Get the property. 951 // Get the property.
944 Handle<Object> result = 952 Handle<Object> result =
945 Object::GetProperty(object, object, &lookup, name, &attr); 953 Object::GetProperty(object, object, &lookup, name, &attr);
946 RETURN_IF_EMPTY_HANDLE(isolate(), result); 954 RETURN_IF_EMPTY_HANDLE(isolate(), result);
947 // If the property is not present, check if we need to throw an 955 // If the property is not present, check if we need to throw an
948 // exception. 956 // exception.
949 if (attr == ABSENT && IsUndeclaredGlobal(object)) { 957 if (attr == ABSENT && IsUndeclaredGlobal(object)) {
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1189 break; 1197 break;
1190 } 1198 }
1191 } 1199 }
1192 1200
1193 1201
1194 void LoadIC::UpdateCaches(LookupResult* lookup, 1202 void LoadIC::UpdateCaches(LookupResult* lookup,
1195 State state, 1203 State state,
1196 Handle<Object> object, 1204 Handle<Object> object,
1197 Handle<String> name) { 1205 Handle<String> name) {
1198 // Bail out if the result is not cacheable. 1206 // Bail out if the result is not cacheable.
1199 if (!lookup->IsCacheable()) { 1207 if (!lookup->IsCacheable()) return;
1200 set_target(*generic_stub());
1201 return;
1202 }
1203 1208
1204 // TODO(jkummerow): It would be nice to support non-JSObjects in 1209 // Loading properties from values is not common, so don't try to
1205 // UpdateCaches, then we wouldn't need to go generic here. 1210 // deal with non-JS objects here.
1206 if (!object->IsJSObject()) { 1211 if (!object->IsJSObject()) return;
1207 set_target(*generic_stub());
1208 return;
1209 }
1210 1212
1211 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1213 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1212 Handle<Code> code; 1214 Handle<Code> code;
1213 if (state == UNINITIALIZED) { 1215 if (state == UNINITIALIZED) {
1214 // This is the first time we execute this inline cache. 1216 // This is the first time we execute this inline cache.
1215 // Set the target to the pre monomorphic stub to delay 1217 // Set the target to the pre monomorphic stub to delay
1216 // setting the monomorphic state. 1218 // setting the monomorphic state.
1217 code = pre_monomorphic_stub(); 1219 code = pre_monomorphic_stub();
1218 } else { 1220 } else {
1219 code = ComputeLoadHandler(lookup, receiver, name); 1221 code = ComputeLoadHandler(lookup, receiver, name);
1220 if (code.is_null()) { 1222 if (code.is_null()) return;
1221 set_target(*generic_stub());
1222 return;
1223 }
1224 } 1223 }
1225 1224
1226 PatchCache(state, kNonStrictMode, receiver, name, code); 1225 PatchCache(state, kNonStrictMode, receiver, name, code);
1227 TRACE_IC("LoadIC", name, state, target()); 1226 TRACE_IC("LoadIC", name, state, target());
1228 } 1227 }
1229 1228
1230 1229
1231 void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) { 1230 void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) {
1232 // Cache code holding map should be consistent with 1231 // Cache code holding map should be consistent with
1233 // GenerateMonomorphicCacheProbe. 1232 // GenerateMonomorphicCacheProbe.
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
1634 LookupResult lookup(isolate()); 1633 LookupResult lookup(isolate());
1635 if (LookupForWrite(receiver, name, value, &lookup, &state)) { 1634 if (LookupForWrite(receiver, name, value, &lookup, &state)) {
1636 if (FLAG_use_ic) { 1635 if (FLAG_use_ic) {
1637 UpdateCaches(&lookup, state, strict_mode, receiver, name, value); 1636 UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
1638 } 1637 }
1639 } else if (strict_mode == kStrictMode && 1638 } else if (strict_mode == kStrictMode &&
1640 !(lookup.IsProperty() && lookup.IsReadOnly()) && 1639 !(lookup.IsProperty() && lookup.IsReadOnly()) &&
1641 IsUndeclaredGlobal(object)) { 1640 IsUndeclaredGlobal(object)) {
1642 // Strict mode doesn't allow setting non-existent global property. 1641 // Strict mode doesn't allow setting non-existent global property.
1643 return ReferenceError("not_defined", name); 1642 return ReferenceError("not_defined", name);
1644 } else if (FLAG_use_ic &&
1645 (lookup.IsNormal() ||
1646 (lookup.IsField() && lookup.CanHoldValue(value)))) {
1647 Handle<Code> stub = strict_mode == kStrictMode
1648 ? generic_stub_strict() : generic_stub();
1649 set_target(*stub);
1650 } 1643 }
1651 1644
1652 // Set the property. 1645 // Set the property.
1653 return JSReceiver::SetPropertyOrFail( 1646 return JSReceiver::SetPropertyOrFail(
1654 receiver, name, value, NONE, strict_mode, store_mode); 1647 receiver, name, value, NONE, strict_mode, store_mode);
1655 } 1648 }
1656 1649
1657 1650
1658 void StoreIC::UpdateCaches(LookupResult* lookup, 1651 void StoreIC::UpdateCaches(LookupResult* lookup,
1659 State state, 1652 State state,
1660 StrictModeFlag strict_mode, 1653 StrictModeFlag strict_mode,
1661 Handle<JSObject> receiver, 1654 Handle<JSObject> receiver,
1662 Handle<String> name, 1655 Handle<String> name,
1663 Handle<Object> value) { 1656 Handle<Object> value) {
1664 ASSERT(!receiver->IsJSGlobalProxy()); 1657 ASSERT(!receiver->IsJSGlobalProxy());
1665 ASSERT(lookup->IsFound()); 1658 ASSERT(lookup->IsFound());
1666 1659
1667 // These are not cacheable, so we never see such LookupResults here. 1660 // These are not cacheable, so we never see such LookupResults here.
1668 ASSERT(!lookup->IsHandler()); 1661 ASSERT(!lookup->IsHandler());
1669 1662
1670 Handle<Code> code = ComputeStoreMonomorphic( 1663 Handle<Code> code =
1671 lookup, strict_mode, receiver, name); 1664 ComputeStoreMonomorphic(lookup, strict_mode, receiver, name);
1672 if (code.is_null()) { 1665 if (code.is_null()) return;
1673 Handle<Code> stub = strict_mode == kStrictMode
1674 ? generic_stub_strict() : generic_stub();
1675 set_target(*stub);
1676 return;
1677 }
1678 1666
1679 PatchCache(state, strict_mode, receiver, name, code); 1667 PatchCache(state, strict_mode, receiver, name, code);
1680 TRACE_IC("StoreIC", name, state, target()); 1668 TRACE_IC("StoreIC", name, state, target());
1681 } 1669 }
1682 1670
1683 1671
1684 Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup, 1672 Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
1685 StrictModeFlag strict_mode, 1673 StrictModeFlag strict_mode,
1686 Handle<JSObject> receiver, 1674 Handle<JSObject> receiver,
1687 Handle<String> name) { 1675 Handle<String> name) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1738 case TRANSITION: { 1726 case TRANSITION: {
1739 // Explicitly pass in the receiver map since LookupForWrite may have 1727 // Explicitly pass in the receiver map since LookupForWrite may have
1740 // stored something else than the receiver in the holder. 1728 // stored something else than the receiver in the holder.
1741 Handle<Map> transition( 1729 Handle<Map> transition(
1742 lookup->GetTransitionTarget(receiver->map()), isolate()); 1730 lookup->GetTransitionTarget(receiver->map()), isolate());
1743 int descriptor = transition->LastAdded(); 1731 int descriptor = transition->LastAdded();
1744 1732
1745 DescriptorArray* target_descriptors = transition->instance_descriptors(); 1733 DescriptorArray* target_descriptors = transition->instance_descriptors();
1746 PropertyDetails details = target_descriptors->GetDetails(descriptor); 1734 PropertyDetails details = target_descriptors->GetDetails(descriptor);
1747 1735
1748 if (details.type() == CALLBACKS || details.attributes() != NONE) break; 1736 if (details.type() != FIELD || details.attributes() != NONE) break;
1749 1737
1750 return isolate()->stub_cache()->ComputeStoreTransition( 1738 return isolate()->stub_cache()->ComputeStoreTransition(
1751 name, receiver, lookup, transition, strict_mode); 1739 name, receiver, lookup, transition, strict_mode);
1752 } 1740 }
1753 case NONEXISTENT: 1741 case NONEXISTENT:
1754 case HANDLER: 1742 case HANDLER:
1755 UNREACHABLE(); 1743 UNREACHABLE();
1756 break; 1744 break;
1757 } 1745 }
1758 return Handle<Code>::null(); 1746 return Handle<Code>::null();
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
2104 case TRANSITION: { 2092 case TRANSITION: {
2105 // Explicitly pass in the receiver map since LookupForWrite may have 2093 // Explicitly pass in the receiver map since LookupForWrite may have
2106 // stored something else than the receiver in the holder. 2094 // stored something else than the receiver in the holder.
2107 Handle<Map> transition( 2095 Handle<Map> transition(
2108 lookup->GetTransitionTarget(receiver->map()), isolate()); 2096 lookup->GetTransitionTarget(receiver->map()), isolate());
2109 int descriptor = transition->LastAdded(); 2097 int descriptor = transition->LastAdded();
2110 2098
2111 DescriptorArray* target_descriptors = transition->instance_descriptors(); 2099 DescriptorArray* target_descriptors = transition->instance_descriptors();
2112 PropertyDetails details = target_descriptors->GetDetails(descriptor); 2100 PropertyDetails details = target_descriptors->GetDetails(descriptor);
2113 2101
2114 if (details.type() != CALLBACKS && details.attributes() == NONE) { 2102 if (details.type() == FIELD && details.attributes() == NONE) {
2115 return isolate()->stub_cache()->ComputeKeyedStoreTransition( 2103 return isolate()->stub_cache()->ComputeKeyedStoreTransition(
2116 name, receiver, lookup, transition, strict_mode); 2104 name, receiver, lookup, transition, strict_mode);
2117 } 2105 }
2118 // fall through. 2106 // fall through.
2119 } 2107 }
2120 case NORMAL: 2108 case NORMAL:
2121 case CONSTANT_FUNCTION: 2109 case CONSTANT_FUNCTION:
2122 case CALLBACKS: 2110 case CALLBACKS:
2123 case INTERCEPTOR: 2111 case INTERCEPTOR:
2124 // Always rewrite to the generic case so that we do not 2112 // Always rewrite to the generic case so that we do not
(...skipping 939 matching lines...) Expand 10 before | Expand all | Expand 10 after
3064 #undef ADDR 3052 #undef ADDR
3065 }; 3053 };
3066 3054
3067 3055
3068 Address IC::AddressFromUtilityId(IC::UtilityId id) { 3056 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3069 return IC_utilities[id]; 3057 return IC_utilities[id];
3070 } 3058 }
3071 3059
3072 3060
3073 } } // namespace v8::internal 3061 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/lithium.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698