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

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

Issue 2362173003: [turbofan] Improve representation selection for Smi checking. (Closed)
Patch Set: Address comments Created 4 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
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | src/compiler/opcodes.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 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 // Monormorphic string access (ignoring the fact that there are multiple 161 // Monormorphic string access (ignoring the fact that there are multiple
162 // String maps). 162 // String maps).
163 receiver = effect = graph()->NewNode(simplified()->CheckString(), 163 receiver = effect = graph()->NewNode(simplified()->CheckString(),
164 receiver, effect, control); 164 receiver, effect, control);
165 } else if (HasOnlyNumberMaps(access_info.receiver_maps())) { 165 } else if (HasOnlyNumberMaps(access_info.receiver_maps())) {
166 // Monomorphic number access (we also deal with Smis here). 166 // Monomorphic number access (we also deal with Smis here).
167 receiver = effect = graph()->NewNode(simplified()->CheckNumber(), 167 receiver = effect = graph()->NewNode(simplified()->CheckNumber(),
168 receiver, effect, control); 168 receiver, effect, control);
169 } else { 169 } else {
170 // Monomorphic property access. 170 // Monomorphic property access.
171 effect = BuildCheckTaggedPointer(receiver, effect, control); 171 effect = BuildCheckHeapObject(receiver, effect, control);
172 effect = BuildCheckMaps(receiver, effect, control, 172 effect = BuildCheckMaps(receiver, effect, control,
173 access_info.receiver_maps()); 173 access_info.receiver_maps());
174 } 174 }
175 175
176 // Generate the actual property access. 176 // Generate the actual property access.
177 ValueEffectControl continuation = BuildPropertyAccess( 177 ValueEffectControl continuation = BuildPropertyAccess(
178 receiver, value, context, frame_state_lazy, effect, control, name, 178 receiver, value, context, frame_state_lazy, effect, control, name,
179 native_context, access_info, access_mode); 179 native_context, access_info, access_mode);
180 value = continuation.value(); 180 value = continuation.value();
181 effect = continuation.effect(); 181 effect = continuation.effect();
(...skipping 17 matching lines...) Expand all
199 // Ensure that {receiver} is a heap object. 199 // Ensure that {receiver} is a heap object.
200 Node* receiverissmi_control = nullptr; 200 Node* receiverissmi_control = nullptr;
201 Node* receiverissmi_effect = effect; 201 Node* receiverissmi_effect = effect;
202 if (receiverissmi_possible) { 202 if (receiverissmi_possible) {
203 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver); 203 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver);
204 Node* branch = graph()->NewNode(common()->Branch(), check, control); 204 Node* branch = graph()->NewNode(common()->Branch(), check, control);
205 control = graph()->NewNode(common()->IfFalse(), branch); 205 control = graph()->NewNode(common()->IfFalse(), branch);
206 receiverissmi_control = graph()->NewNode(common()->IfTrue(), branch); 206 receiverissmi_control = graph()->NewNode(common()->IfTrue(), branch);
207 receiverissmi_effect = effect; 207 receiverissmi_effect = effect;
208 } else { 208 } else {
209 effect = BuildCheckTaggedPointer(receiver, effect, control); 209 effect = BuildCheckHeapObject(receiver, effect, control);
210 } 210 }
211 211
212 // Load the {receiver} map. The resulting effect is the dominating effect 212 // Load the {receiver} map. The resulting effect is the dominating effect
213 // for all (polymorphic) branches. 213 // for all (polymorphic) branches.
214 Node* receiver_map = effect = 214 Node* receiver_map = effect =
215 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), 215 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
216 receiver, effect, control); 216 receiver, effect, control);
217 217
218 // Generate code for the various different property access patterns. 218 // Generate code for the various different property access patterns.
219 Node* fallthrough_control = control; 219 Node* fallthrough_control = control;
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 } 503 }
504 } 504 }
505 505
506 // Install dependencies on the relevant prototype maps. 506 // Install dependencies on the relevant prototype maps.
507 for (Handle<Map> prototype_map : prototype_maps) { 507 for (Handle<Map> prototype_map : prototype_maps) {
508 dependencies()->AssumeMapStable(prototype_map); 508 dependencies()->AssumeMapStable(prototype_map);
509 } 509 }
510 } 510 }
511 511
512 // Ensure that {receiver} is a heap object. 512 // Ensure that {receiver} is a heap object.
513 effect = BuildCheckTaggedPointer(receiver, effect, control); 513 effect = BuildCheckHeapObject(receiver, effect, control);
514 514
515 // Check for the monomorphic case. 515 // Check for the monomorphic case.
516 if (access_infos.size() == 1) { 516 if (access_infos.size() == 1) {
517 ElementAccessInfo access_info = access_infos.front(); 517 ElementAccessInfo access_info = access_infos.front();
518 518
519 // Perform possible elements kind transitions. 519 // Perform possible elements kind transitions.
520 for (auto transition : access_info.transitions()) { 520 for (auto transition : access_info.transitions()) {
521 Handle<Map> const transition_source = transition.first; 521 Handle<Map> const transition_source = transition.first;
522 Handle<Map> const transition_target = transition.second; 522 Handle<Map> const transition_target = transition.second;
523 effect = graph()->NewNode( 523 effect = graph()->NewNode(
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 graph()->NewNode(simplified()->LoadField(storage_access), 964 graph()->NewNode(simplified()->LoadField(storage_access),
965 storage, effect, control); 965 storage, effect, control);
966 field_access.offset = HeapNumber::kValueOffset; 966 field_access.offset = HeapNumber::kValueOffset;
967 field_access.name = MaybeHandle<Name>(); 967 field_access.name = MaybeHandle<Name>();
968 field_access.machine_type = MachineType::Float64(); 968 field_access.machine_type = MachineType::Float64();
969 } 969 }
970 } 970 }
971 break; 971 break;
972 } 972 }
973 case MachineRepresentation::kTaggedSigned: { 973 case MachineRepresentation::kTaggedSigned: {
974 value = effect = graph()->NewNode(simplified()->CheckTaggedSigned(), 974 value = effect = graph()->NewNode(simplified()->CheckSmi(), value,
975 value, effect, control); 975 effect, control);
976 field_access.write_barrier_kind = kNoWriteBarrier; 976 field_access.write_barrier_kind = kNoWriteBarrier;
977 break; 977 break;
978 } 978 }
979 case MachineRepresentation::kTaggedPointer: { 979 case MachineRepresentation::kTaggedPointer: {
980 // Ensure that {value} is a HeapObject. 980 // Ensure that {value} is a HeapObject.
981 value = effect = graph()->NewNode(simplified()->CheckTaggedPointer(), 981 value = effect = graph()->NewNode(simplified()->CheckHeapObject(),
982 value, effect, control); 982 value, effect, control);
983 Handle<Map> field_map; 983 Handle<Map> field_map;
984 if (access_info.field_map().ToHandle(&field_map)) { 984 if (access_info.field_map().ToHandle(&field_map)) {
985 // Emit a map check for the value. 985 // Emit a map check for the value.
986 effect = graph()->NewNode(simplified()->CheckMaps(1), value, 986 effect = graph()->NewNode(simplified()->CheckMaps(1), value,
987 jsgraph()->HeapConstant(field_map), 987 jsgraph()->HeapConstant(field_map),
988 effect, control); 988 effect, control);
989 } 989 }
990 field_access.write_barrier_kind = kPointerWriteBarrier; 990 field_access.write_barrier_kind = kPointerWriteBarrier;
991 break; 991 break;
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 if (CanTreatHoleAsUndefined(receiver_maps, native_context)) { 1236 if (CanTreatHoleAsUndefined(receiver_maps, native_context)) {
1237 // Return the signaling NaN hole directly if all uses are truncating. 1237 // Return the signaling NaN hole directly if all uses are truncating.
1238 mode = CheckFloat64HoleMode::kAllowReturnHole; 1238 mode = CheckFloat64HoleMode::kAllowReturnHole;
1239 } 1239 }
1240 value = effect = graph()->NewNode(simplified()->CheckFloat64Hole(mode), 1240 value = effect = graph()->NewNode(simplified()->CheckFloat64Hole(mode),
1241 value, effect, control); 1241 value, effect, control);
1242 } 1242 }
1243 } else { 1243 } else {
1244 DCHECK_EQ(AccessMode::kStore, access_mode); 1244 DCHECK_EQ(AccessMode::kStore, access_mode);
1245 if (IsFastSmiElementsKind(elements_kind)) { 1245 if (IsFastSmiElementsKind(elements_kind)) {
1246 value = effect = graph()->NewNode(simplified()->CheckTaggedSigned(), 1246 value = effect =
1247 value, effect, control); 1247 graph()->NewNode(simplified()->CheckSmi(), value, effect, control);
1248 } else if (IsFastDoubleElementsKind(elements_kind)) { 1248 } else if (IsFastDoubleElementsKind(elements_kind)) {
1249 value = effect = graph()->NewNode(simplified()->CheckNumber(), value, 1249 value = effect = graph()->NewNode(simplified()->CheckNumber(), value,
1250 effect, control); 1250 effect, control);
1251 // Make sure we do not store signalling NaNs into double arrays. 1251 // Make sure we do not store signalling NaNs into double arrays.
1252 value = graph()->NewNode(simplified()->NumberSilenceNaN(), value); 1252 value = graph()->NewNode(simplified()->NumberSilenceNaN(), value);
1253 } 1253 }
1254 1254
1255 // Ensure that copy-on-write backing store is writable. 1255 // Ensure that copy-on-write backing store is writable.
1256 if (IsFastSmiOrObjectElementsKind(elements_kind) && 1256 if (IsFastSmiOrObjectElementsKind(elements_kind) &&
1257 store_mode == STORE_NO_TRANSITION_HANDLE_COW) { 1257 store_mode == STORE_NO_TRANSITION_HANDLE_COW) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1308 inputs[0] = receiver; 1308 inputs[0] = receiver;
1309 for (int i = 0; i < map_input_count; ++i) { 1309 for (int i = 0; i < map_input_count; ++i) {
1310 inputs[1 + i] = jsgraph()->HeapConstant(maps[i]); 1310 inputs[1 + i] = jsgraph()->HeapConstant(maps[i]);
1311 } 1311 }
1312 inputs[input_count - 2] = effect; 1312 inputs[input_count - 2] = effect;
1313 inputs[input_count - 1] = control; 1313 inputs[input_count - 1] = control;
1314 return graph()->NewNode(simplified()->CheckMaps(map_input_count), input_count, 1314 return graph()->NewNode(simplified()->CheckMaps(map_input_count), input_count,
1315 inputs); 1315 inputs);
1316 } 1316 }
1317 1317
1318 Node* JSNativeContextSpecialization::BuildCheckTaggedPointer(Node* receiver, 1318 Node* JSNativeContextSpecialization::BuildCheckHeapObject(Node* receiver,
1319 Node* effect, 1319 Node* effect,
1320 Node* control) { 1320 Node* control) {
1321 switch (receiver->opcode()) { 1321 switch (receiver->opcode()) {
1322 case IrOpcode::kHeapConstant: 1322 case IrOpcode::kHeapConstant:
1323 case IrOpcode::kJSCreate: 1323 case IrOpcode::kJSCreate:
1324 case IrOpcode::kJSCreateArguments: 1324 case IrOpcode::kJSCreateArguments:
1325 case IrOpcode::kJSCreateArray: 1325 case IrOpcode::kJSCreateArray:
1326 case IrOpcode::kJSCreateClosure: 1326 case IrOpcode::kJSCreateClosure:
1327 case IrOpcode::kJSCreateIterResultObject: 1327 case IrOpcode::kJSCreateIterResultObject:
1328 case IrOpcode::kJSCreateLiteralArray: 1328 case IrOpcode::kJSCreateLiteralArray:
1329 case IrOpcode::kJSCreateLiteralObject: 1329 case IrOpcode::kJSCreateLiteralObject:
1330 case IrOpcode::kJSCreateLiteralRegExp: 1330 case IrOpcode::kJSCreateLiteralRegExp:
1331 case IrOpcode::kJSConvertReceiver: 1331 case IrOpcode::kJSConvertReceiver:
1332 case IrOpcode::kJSToName: 1332 case IrOpcode::kJSToName:
1333 case IrOpcode::kJSToString: 1333 case IrOpcode::kJSToString:
1334 case IrOpcode::kJSToObject: 1334 case IrOpcode::kJSToObject:
1335 case IrOpcode::kJSTypeOf: { 1335 case IrOpcode::kJSTypeOf: {
1336 return effect; 1336 return effect;
1337 } 1337 }
1338 default: { 1338 default: {
1339 return graph()->NewNode(simplified()->CheckTaggedPointer(), receiver, 1339 return graph()->NewNode(simplified()->CheckHeapObject(), receiver, effect,
1340 effect, control); 1340 control);
1341 } 1341 }
1342 } 1342 }
1343 } 1343 }
1344 1344
1345 void JSNativeContextSpecialization::AssumePrototypesStable( 1345 void JSNativeContextSpecialization::AssumePrototypesStable(
1346 std::vector<Handle<Map>> const& receiver_maps, 1346 std::vector<Handle<Map>> const& receiver_maps,
1347 Handle<Context> native_context, Handle<JSObject> holder) { 1347 Handle<Context> native_context, Handle<JSObject> holder) {
1348 // Determine actual holder and perform prototype chain checks. 1348 // Determine actual holder and perform prototype chain checks.
1349 for (auto map : receiver_maps) { 1349 for (auto map : receiver_maps) {
1350 // Perform the implicit ToObject for primitives here. 1350 // Perform the implicit ToObject for primitives here.
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1515 } 1515 }
1516 1516
1517 1517
1518 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { 1518 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const {
1519 return jsgraph()->simplified(); 1519 return jsgraph()->simplified();
1520 } 1520 }
1521 1521
1522 } // namespace compiler 1522 } // namespace compiler
1523 } // namespace internal 1523 } // namespace internal
1524 } // namespace v8 1524 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | src/compiler/opcodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698