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

Side by Side Diff: src/compiler/js-native-context-specialization.cc

Issue 2619773002: [turbofan] Use feedback from StoreDataPropertyInLiteral. (Closed)
Patch Set: Delete comment. Created 3 years, 11 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
« no previous file with comments | « src/compiler/bytecode-graph-builder.cc ('k') | src/compiler/verifier.cc » ('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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/js-native-context-specialization.h" 5 #include "src/compiler/js-native-context-specialization.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/compilation-dependencies.h" 9 #include "src/compilation-dependencies.h"
10 #include "src/compiler/access-builder.h" 10 #include "src/compiler/access-builder.h"
(...skipping 949 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 } 960 }
961 961
962 JSNativeContextSpecialization::ValueEffectControl 962 JSNativeContextSpecialization::ValueEffectControl
963 JSNativeContextSpecialization::BuildPropertyAccess( 963 JSNativeContextSpecialization::BuildPropertyAccess(
964 Node* receiver, Node* value, Node* context, Node* frame_state, Node* effect, 964 Node* receiver, Node* value, Node* context, Node* frame_state, Node* effect,
965 Node* control, Handle<Name> name, PropertyAccessInfo const& access_info, 965 Node* control, Handle<Name> name, PropertyAccessInfo const& access_info,
966 AccessMode access_mode, LanguageMode language_mode, 966 AccessMode access_mode, LanguageMode language_mode,
967 Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot) { 967 Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot) {
968 // Determine actual holder and perform prototype chain checks. 968 // Determine actual holder and perform prototype chain checks.
969 Handle<JSObject> holder; 969 Handle<JSObject> holder;
970 if (access_info.holder().ToHandle(&holder)) { 970 if (access_info.holder().ToHandle(&holder) &&
Benedikt Meurer 2017/01/10 08:25:55 There should never be a holder for kStoreInLiteral
Franzi 2017/01/10 10:54:02 OK. Done.
971 access_mode != AccessMode::kStoreInLiteral) {
971 AssumePrototypesStable(access_info.receiver_maps(), holder); 972 AssumePrototypesStable(access_info.receiver_maps(), holder);
972 } 973 }
973 974
974 // Generate the actual property access. 975 // Generate the actual property access.
975 if (access_info.IsNotFound()) { 976 if (access_info.IsNotFound()) {
976 DCHECK_EQ(AccessMode::kLoad, access_mode); 977 DCHECK_EQ(AccessMode::kLoad, access_mode);
977 value = jsgraph()->UndefinedConstant(); 978 value = jsgraph()->UndefinedConstant();
978 } else if (access_info.IsDataConstant()) { 979 } else if (access_info.IsDataConstant()) {
979 Node* constant_value = jsgraph()->Constant(access_info.constant()); 980 Node* constant_value = jsgraph()->Constant(access_info.constant());
980 if (access_mode == AccessMode::kStore) { 981 if (access_mode == AccessMode::kStore) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1021 } else { 1022 } else {
1022 value = effect = graph()->NewNode( 1023 value = effect = graph()->NewNode(
1023 javascript()->CallFunction( 1024 javascript()->CallFunction(
1024 2, 0.0f, VectorSlotPair(), 1025 2, 0.0f, VectorSlotPair(),
1025 ConvertReceiverMode::kNotNullOrUndefined), 1026 ConvertReceiverMode::kNotNullOrUndefined),
1026 target, receiver, context, frame_state0, effect, control); 1027 target, receiver, context, frame_state0, effect, control);
1027 control = graph()->NewNode(common()->IfSuccess(), value); 1028 control = graph()->NewNode(common()->IfSuccess(), value);
1028 } 1029 }
1029 break; 1030 break;
1030 } 1031 }
1032 case AccessMode::kStoreInLiteral:
1031 case AccessMode::kStore: { 1033 case AccessMode::kStore: {
1032 // We need a FrameState for the setter stub to restore the correct 1034 // We need a FrameState for the setter stub to restore the correct
1033 // context and return the appropriate value to fullcodegen. 1035 // context and return the appropriate value to fullcodegen.
1034 FrameStateFunctionInfo const* frame_info0 = 1036 FrameStateFunctionInfo const* frame_info0 =
1035 common()->CreateFrameStateFunctionInfo(FrameStateType::kSetterStub, 1037 common()->CreateFrameStateFunctionInfo(FrameStateType::kSetterStub,
1036 2, 0, shared_info); 1038 2, 0, shared_info);
1037 Node* frame_state0 = graph()->NewNode( 1039 Node* frame_state0 = graph()->NewNode(
1038 common()->FrameState(BailoutId::None(), 1040 common()->FrameState(BailoutId::None(),
1039 OutputFrameStateCombine::Ignore(), 1041 OutputFrameStateCombine::Ignore(),
1040 frame_info0), 1042 frame_info0),
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
1251 value = effect = control = 1253 value = effect = control =
1252 graph()->NewNode(common()->Call(desc), arraysize(inputs), inputs); 1254 graph()->NewNode(common()->Call(desc), arraysize(inputs), inputs);
1253 control = graph()->NewNode(common()->IfSuccess(), control); 1255 control = graph()->NewNode(common()->IfSuccess(), control);
1254 } 1256 }
1255 1257
1256 return ValueEffectControl(value, effect, control); 1258 return ValueEffectControl(value, effect, control);
1257 } 1259 }
1258 1260
1259 Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral( 1261 Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral(
1260 Node* node) { 1262 Node* node) {
1261 // TODO(franzih): Use feedback 1263 DCHECK_EQ(IrOpcode::kJSStoreDataPropertyInLiteral, node->opcode());
1262 return NoChange(); 1264
1265 // If deoptimization is disabled, we cannot optimize.
1266 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
1267
1268 DataPropertyParameters const& p = DataPropertyParametersOf(node->op());
1269
1270 if (!p.feedback().IsValid()) return NoChange();
1271
1272 StoreDataPropertyInLiteralICNexus nexus(p.feedback().vector(),
1273 p.feedback().slot());
1274 if (nexus.IsUninitialized()) {
1275 return NoChange();
1276 }
1277
1278 if (nexus.ic_state() == MEGAMORPHIC) {
1279 return NoChange();
1280 }
1281
1282 DCHECK_EQ(MONOMORPHIC, nexus.ic_state());
1283
1284 Handle<Map> receiver_map(nexus.FindFirstMap(), isolate());
1285 Handle<Name> cached_name =
1286 handle(Name::cast(nexus.GetFeedbackExtra()), isolate());
1287
1288 PropertyAccessInfo access_info;
1289 AccessInfoFactory access_info_factory(dependencies(), native_context(),
1290 graph()->zone());
1291 if (!access_info_factory.ComputePropertyAccessInfo(
1292 receiver_map, cached_name, AccessMode::kStoreInLiteral,
1293 &access_info)) {
1294 return NoChange();
1295 }
1296
1297 DCHECK_EQ(1, access_info.receiver_maps().size());
Benedikt Meurer 2017/01/10 08:25:55 This check doesn't need to be here.
Franzi 2017/01/10 10:54:01 Oops, left-over debugging stuff. Deleted.
1298
1299 if (access_info.IsGeneric()) {
1300 return NoChange();
1301 }
1302
1303 Node* receiver = NodeProperties::GetValueInput(node, 0);
1304 Node* effect = NodeProperties::GetEffectInput(node);
1305 Node* control = NodeProperties::GetControlInput(node);
1306
1307 // Monomorphic property access.
1308 receiver = BuildCheckHeapObject(receiver, &effect, control);
1309
1310 effect = BuildCheckMaps(receiver, effect, control, MapList{receiver_map});
Benedikt Meurer 2017/01/10 08:25:54 You can use access_info.receiver_maps() here inste
Franzi 2017/01/10 10:54:01 Done. Changed the other uses of MapList{} as well.
1311
1312 // Ensure that {name} matches the cached name.
1313 Node* name = NodeProperties::GetValueInput(node, 1);
1314 Node* check = graph()->NewNode(simplified()->ReferenceEqual(), name,
1315 jsgraph()->HeapConstant(cached_name));
1316 effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control);
1317
1318 Node* value = NodeProperties::GetValueInput(node, 2);
1319 Node* context = NodeProperties::GetContextInput(node);
1320 Node* frame_state_lazy = NodeProperties::GetFrameStateInput(node);
1321
1322 // Generate the actual property access.
1323 ValueEffectControl continuation = BuildPropertyAccess(
1324 receiver, value, context, frame_state_lazy, effect, control, cached_name,
1325 access_info, AccessMode::kStoreInLiteral, LanguageMode::SLOPPY,
1326 p.feedback().vector(), p.feedback().slot());
1327 value = continuation.value();
1328 effect = continuation.effect();
1329 control = continuation.control();
1330
1331 ReplaceWithValue(node, value, effect, control);
1332 return Replace(value);
1263 } 1333 }
1264 1334
1265 namespace { 1335 namespace {
1266 1336
1267 ExternalArrayType GetArrayTypeFromElementsKind(ElementsKind kind) { 1337 ExternalArrayType GetArrayTypeFromElementsKind(ElementsKind kind) {
1268 switch (kind) { 1338 switch (kind) {
1269 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 1339 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
1270 case TYPE##_ELEMENTS: \ 1340 case TYPE##_ELEMENTS: \
1271 return kExternal##Type##Array; 1341 return kExternal##Type##Array;
1272 TYPED_ARRAYS(TYPED_ARRAY_CASE) 1342 TYPED_ARRAYS(TYPED_ARRAY_CASE)
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1374 // Access the actual element. 1444 // Access the actual element.
1375 ExternalArrayType external_array_type = 1445 ExternalArrayType external_array_type =
1376 GetArrayTypeFromElementsKind(elements_kind); 1446 GetArrayTypeFromElementsKind(elements_kind);
1377 switch (access_mode) { 1447 switch (access_mode) {
1378 case AccessMode::kLoad: { 1448 case AccessMode::kLoad: {
1379 value = effect = graph()->NewNode( 1449 value = effect = graph()->NewNode(
1380 simplified()->LoadTypedElement(external_array_type), buffer, 1450 simplified()->LoadTypedElement(external_array_type), buffer,
1381 base_pointer, external_pointer, index, effect, control); 1451 base_pointer, external_pointer, index, effect, control);
1382 break; 1452 break;
1383 } 1453 }
1454 case AccessMode::kStoreInLiteral:
1384 case AccessMode::kStore: { 1455 case AccessMode::kStore: {
1385 // Ensure that the {value} is actually a Number. 1456 // Ensure that the {value} is actually a Number.
1386 value = effect = graph()->NewNode(simplified()->CheckNumber(), value, 1457 value = effect = graph()->NewNode(simplified()->CheckNumber(), value,
1387 effect, control); 1458 effect, control);
1388 1459
1389 // Introduce the appropriate truncation for {value}. Currently we 1460 // Introduce the appropriate truncation for {value}. Currently we
1390 // only need to do this for ClamedUint8Array {receiver}s, as the 1461 // only need to do this for ClamedUint8Array {receiver}s, as the
1391 // other truncations are implicit in the StoreTypedElement, but we 1462 // other truncations are implicit in the StoreTypedElement, but we
1392 // might want to change that at some point. 1463 // might want to change that at some point.
1393 if (external_array_type == kExternalUint8ClampedArray) { 1464 if (external_array_type == kExternalUint8ClampedArray) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1429 break; 1500 break;
1430 } 1501 }
1431 } 1502 }
1432 } else { 1503 } else {
1433 // Load the elements for the {receiver}. 1504 // Load the elements for the {receiver}.
1434 Node* elements = effect = graph()->NewNode( 1505 Node* elements = effect = graph()->NewNode(
1435 simplified()->LoadField(AccessBuilder::ForJSObjectElements()), receiver, 1506 simplified()->LoadField(AccessBuilder::ForJSObjectElements()), receiver,
1436 effect, control); 1507 effect, control);
1437 1508
1438 // Don't try to store to a copy-on-write backing store. 1509 // Don't try to store to a copy-on-write backing store.
1439 if (access_mode == AccessMode::kStore && 1510 if ((access_mode == AccessMode::kStore ||
1511 access_mode == AccessMode::kStoreInLiteral) &&
Benedikt Meurer 2017/01/10 08:25:54 This doesn't make sense. We never do a store in li
Franzi 2017/01/10 10:54:01 OK, also added a DCHECK to beginning of the functi
1440 IsFastSmiOrObjectElementsKind(elements_kind) && 1512 IsFastSmiOrObjectElementsKind(elements_kind) &&
1441 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 1513 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
1442 effect = graph()->NewNode(simplified()->CheckMaps(ZoneHandleSet<Map>( 1514 effect = graph()->NewNode(simplified()->CheckMaps(ZoneHandleSet<Map>(
1443 factory()->fixed_array_map())), 1515 factory()->fixed_array_map())),
1444 elements, effect, control); 1516 elements, effect, control);
1445 } 1517 }
1446 1518
1447 // Check if the {receiver} is a JSArray. 1519 // Check if the {receiver} is a JSArray.
1448 bool receiver_is_jsarray = HasOnlyJSArrayMaps(receiver_maps); 1520 bool receiver_is_jsarray = HasOnlyJSArrayMaps(receiver_maps);
1449 1521
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
1839 return jsgraph()->javascript(); 1911 return jsgraph()->javascript();
1840 } 1912 }
1841 1913
1842 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { 1914 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const {
1843 return jsgraph()->simplified(); 1915 return jsgraph()->simplified();
1844 } 1916 }
1845 1917
1846 } // namespace compiler 1918 } // namespace compiler
1847 } // namespace internal 1919 } // namespace internal
1848 } // namespace v8 1920 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/bytecode-graph-builder.cc ('k') | src/compiler/verifier.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698