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

Side by Side Diff: src/compiler/js-typed-lowering.cc

Issue 1399423002: [turbofan] Introduce node regions for protection from scheduling. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Tweaks Created 5 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
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/code-factory.h" 5 #include "src/code-factory.h"
6 #include "src/compiler/access-builder.h" 6 #include "src/compiler/access-builder.h"
7 #include "src/compiler/js-graph.h" 7 #include "src/compiler/js-graph.h"
8 #include "src/compiler/js-typed-lowering.h" 8 #include "src/compiler/js-typed-lowering.h"
9 #include "src/compiler/linkage.h" 9 #include "src/compiler/linkage.h"
10 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/node-matchers.h"
(...skipping 19 matching lines...) Expand all
30 } 30 }
31 } 31 }
32 32
33 33
34 // A helper class to construct inline allocations on the simplified operator 34 // A helper class to construct inline allocations on the simplified operator
35 // level. This keeps track of the effect chain for initial stores on a newly 35 // level. This keeps track of the effect chain for initial stores on a newly
36 // allocated object and also provides helpers for commonly allocated objects. 36 // allocated object and also provides helpers for commonly allocated objects.
37 class AllocationBuilder final { 37 class AllocationBuilder final {
38 public: 38 public:
39 AllocationBuilder(JSGraph* jsgraph, SimplifiedOperatorBuilder* simplified, 39 AllocationBuilder(JSGraph* jsgraph, SimplifiedOperatorBuilder* simplified,
40 Node* effect, Node* control) 40 Node* node, Node* effect, Node* control)
41 : jsgraph_(jsgraph), 41 : jsgraph_(jsgraph),
42 simplified_(simplified), 42 simplified_(simplified),
43 allocation_(nullptr), 43 allocation_(nullptr),
44 node_(node),
44 effect_(effect), 45 effect_(effect),
45 control_(control) {} 46 control_(control) {}
46 47
48 ~AllocationBuilder() {
49 // Make sure we are finished.
50 DCHECK_EQ(IrOpcode::kFinishRegion, node_->opcode());
51 }
52
47 // Primitive allocation of static size. 53 // Primitive allocation of static size.
48 void Allocate(int size) { 54 void Allocate(int size) {
55 effect_ = graph()->NewNode(jsgraph()->common()->BeginRegion(), effect_);
49 allocation_ = graph()->NewNode( 56 allocation_ = graph()->NewNode(
50 simplified()->Allocate(), jsgraph()->Constant(size), effect_, control_); 57 simplified()->Allocate(), jsgraph()->Constant(size), effect_, control_);
51 effect_ = allocation_; 58 effect_ = allocation_;
52 } 59 }
53 60
54 // Primitive store into a field. 61 // Primitive store into a field.
55 void Store(const FieldAccess& access, Node* value) { 62 void Store(const FieldAccess& access, Node* value) {
56 effect_ = graph()->NewNode(simplified()->StoreField(access), allocation_, 63 effect_ = graph()->NewNode(simplified()->StoreField(access), allocation_,
57 value, effect_, control_); 64 value, effect_, control_);
58 } 65 }
59 66
60 // Compound allocation of a FixedArray. 67 // Compound allocation of a FixedArray.
61 void AllocateArray(int length, Handle<Map> map) { 68 void AllocateArray(int length, Handle<Map> map) {
62 Allocate(FixedArray::SizeFor(length)); 69 Allocate(FixedArray::SizeFor(length));
63 Store(AccessBuilder::ForMap(), map); 70 Store(AccessBuilder::ForMap(), map);
64 Store(AccessBuilder::ForFixedArrayLength(graph()->zone()), 71 Store(AccessBuilder::ForFixedArrayLength(graph()->zone()),
65 jsgraph()->Constant(length)); 72 jsgraph()->Constant(length));
66 } 73 }
67 74
68 // Compound store of a constant into a field. 75 // Compound store of a constant into a field.
69 void Store(const FieldAccess& access, Handle<Object> value) { 76 void Store(const FieldAccess& access, Handle<Object> value) {
70 Store(access, jsgraph()->Constant(value)); 77 Store(access, jsgraph()->Constant(value));
71 } 78 }
72 79
73 Node* allocation() const { return allocation_; } 80 void Finish() {
Benedikt Meurer 2015/10/13 19:12:09 Nit: I think this helper should return the Reducti
Jarin 2015/10/14 06:37:20 Ack. I will leave the decision to Michi, I do not
74 Node* effect() const { return effect_; } 81 NodeProperties::SetType(allocation_, NodeProperties::GetType(node_));
82 node_->ReplaceInput(0, allocation_);
83 node_->ReplaceInput(1, effect_);
84 node_->TrimInputCount(2);
85 NodeProperties::ChangeOp(node_, jsgraph()->common()->FinishRegion());
86 }
75 87
76 protected: 88 protected:
77 JSGraph* jsgraph() { return jsgraph_; } 89 JSGraph* jsgraph() { return jsgraph_; }
78 Graph* graph() { return jsgraph_->graph(); } 90 Graph* graph() { return jsgraph_->graph(); }
79 SimplifiedOperatorBuilder* simplified() { return simplified_; } 91 SimplifiedOperatorBuilder* simplified() { return simplified_; }
80 92
81 private: 93 private:
82 JSGraph* const jsgraph_; 94 JSGraph* const jsgraph_;
83 SimplifiedOperatorBuilder* simplified_; 95 SimplifiedOperatorBuilder* simplified_;
84 Node* allocation_; 96 Node* allocation_;
97 Node* node_;
85 Node* effect_; 98 Node* effect_;
86 Node* control_; 99 Node* control_;
87 }; 100 };
88 101
89 102
90 // A helper class to simplify the process of reducing a single binop node with a 103 // A helper class to simplify the process of reducing a single binop node with a
91 // JSOperator. This class manages the rewriting of context, control, and effect 104 // JSOperator. This class manages the rewriting of context, control, and effect
92 // dependencies during lowering of a binop and contains numerous helper 105 // dependencies during lowering of a binop and contains numerous helper
93 // functions for matching the types of inputs to an operation. 106 // functions for matching the types of inputs to an operation.
94 class JSBinopReduction final { 107 class JSBinopReduction final {
(...skipping 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1256 // JSCreateFunctionContext[slot_count < limit]](fun) 1269 // JSCreateFunctionContext[slot_count < limit]](fun)
1257 Node* const effect = NodeProperties::GetEffectInput(node); 1270 Node* const effect = NodeProperties::GetEffectInput(node);
1258 Node* const control = NodeProperties::GetControlInput(node); 1271 Node* const control = NodeProperties::GetControlInput(node);
1259 Node* const closure = NodeProperties::GetValueInput(node, 0); 1272 Node* const closure = NodeProperties::GetValueInput(node, 0);
1260 Node* const context = NodeProperties::GetContextInput(node); 1273 Node* const context = NodeProperties::GetContextInput(node);
1261 Node* const extension = jsgraph()->ZeroConstant(); 1274 Node* const extension = jsgraph()->ZeroConstant();
1262 Node* const load = graph()->NewNode( 1275 Node* const load = graph()->NewNode(
1263 simplified()->LoadField( 1276 simplified()->LoadField(
1264 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)), 1277 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)),
1265 context, effect, control); 1278 context, effect, control);
1266 AllocationBuilder a(jsgraph(), simplified(), effect, control); 1279 RelaxControls(node);
1280 AllocationBuilder a(jsgraph(), simplified(), node, effect, control);
1267 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. 1281 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered.
1268 int context_length = slot_count + Context::MIN_CONTEXT_SLOTS; 1282 int context_length = slot_count + Context::MIN_CONTEXT_SLOTS;
1269 a.AllocateArray(context_length, factory()->function_context_map()); 1283 a.AllocateArray(context_length, factory()->function_context_map());
1270 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); 1284 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure);
1271 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); 1285 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
1272 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension); 1286 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
1273 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); 1287 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load);
1274 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) { 1288 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) {
1275 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->TheHoleConstant()); 1289 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->TheHoleConstant());
1276 } 1290 }
1277 // TODO(mstarzinger): We could mutate {node} into the allocation instead. 1291 a.Finish();
1278 NodeProperties::SetType(a.allocation(), NodeProperties::GetType(node));
1279 ReplaceWithValue(node, node, a.effect());
1280 node->ReplaceInput(0, a.allocation());
1281 node->ReplaceInput(1, a.effect());
1282 node->TrimInputCount(2);
1283 NodeProperties::ChangeOp(node, common()->Finish(1));
1284 return Changed(node); 1292 return Changed(node);
1285 } 1293 }
1286 1294
1287 // Use the FastNewContextStub only for function contexts up maximum size. 1295 // Use the FastNewContextStub only for function contexts up maximum size.
1288 if (slot_count <= FastNewContextStub::kMaximumSlots) { 1296 if (slot_count <= FastNewContextStub::kMaximumSlots) {
1289 Isolate* isolate = jsgraph()->isolate(); 1297 Isolate* isolate = jsgraph()->isolate();
1290 Callable callable = CodeFactory::FastNewContext(isolate, slot_count); 1298 Callable callable = CodeFactory::FastNewContext(isolate, slot_count);
1291 CallDescriptor* desc = Linkage::GetStubCallDescriptor( 1299 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
1292 isolate, graph()->zone(), callable.descriptor(), 0, 1300 isolate, graph()->zone(), callable.descriptor(), 0,
1293 CallDescriptor::kNoFlags); 1301 CallDescriptor::kNoFlags);
(...skipping 17 matching lines...) Expand all
1311 if (FLAG_turbo_allocate && input_type->Is(Type::Receiver())) { 1319 if (FLAG_turbo_allocate && input_type->Is(Type::Receiver())) {
1312 // JSCreateWithContext(o:receiver, fun) 1320 // JSCreateWithContext(o:receiver, fun)
1313 Node* const effect = NodeProperties::GetEffectInput(node); 1321 Node* const effect = NodeProperties::GetEffectInput(node);
1314 Node* const control = NodeProperties::GetControlInput(node); 1322 Node* const control = NodeProperties::GetControlInput(node);
1315 Node* const closure = NodeProperties::GetValueInput(node, 1); 1323 Node* const closure = NodeProperties::GetValueInput(node, 1);
1316 Node* const context = NodeProperties::GetContextInput(node); 1324 Node* const context = NodeProperties::GetContextInput(node);
1317 Node* const load = graph()->NewNode( 1325 Node* const load = graph()->NewNode(
1318 simplified()->LoadField( 1326 simplified()->LoadField(
1319 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)), 1327 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)),
1320 context, effect, control); 1328 context, effect, control);
1321 AllocationBuilder a(jsgraph(), simplified(), effect, control); 1329 RelaxControls(node);
1330 AllocationBuilder a(jsgraph(), simplified(), node, effect, control);
1322 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. 1331 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered.
1323 a.AllocateArray(Context::MIN_CONTEXT_SLOTS, factory()->with_context_map()); 1332 a.AllocateArray(Context::MIN_CONTEXT_SLOTS, factory()->with_context_map());
1324 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); 1333 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure);
1325 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); 1334 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
1326 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), input); 1335 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), input);
1327 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); 1336 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load);
1328 // TODO(mstarzinger): We could mutate {node} into the allocation instead. 1337 a.Finish();
1329 NodeProperties::SetType(a.allocation(), NodeProperties::GetType(node));
1330 ReplaceWithValue(node, node, a.effect());
1331 node->ReplaceInput(0, a.allocation());
1332 node->ReplaceInput(1, a.effect());
1333 node->TrimInputCount(2);
1334 NodeProperties::ChangeOp(node, common()->Finish(1));
1335 return Changed(node); 1338 return Changed(node);
1336 } 1339 }
1337 1340
1338 return NoChange(); 1341 return NoChange();
1339 } 1342 }
1340 1343
1341 1344
1342 Reduction JSTypedLowering::ReduceJSCreateBlockContext(Node* node) { 1345 Reduction JSTypedLowering::ReduceJSCreateBlockContext(Node* node) {
1343 DCHECK_EQ(IrOpcode::kJSCreateBlockContext, node->opcode()); 1346 DCHECK_EQ(IrOpcode::kJSCreateBlockContext, node->opcode());
1344 Handle<ScopeInfo> scope_info = OpParameter<Handle<ScopeInfo>>(node); 1347 Handle<ScopeInfo> scope_info = OpParameter<Handle<ScopeInfo>>(node);
1345 int context_length = scope_info->ContextLength(); 1348 int context_length = scope_info->ContextLength();
1346 1349
1347 // Use inline allocation for block contexts up to a size limit. 1350 // Use inline allocation for block contexts up to a size limit.
1348 if (FLAG_turbo_allocate && context_length < kBlockContextAllocationLimit) { 1351 if (FLAG_turbo_allocate && context_length < kBlockContextAllocationLimit) {
1349 // JSCreateBlockContext[scope[length < limit]](fun) 1352 // JSCreateBlockContext[scope[length < limit]](fun)
1350 Node* const effect = NodeProperties::GetEffectInput(node); 1353 Node* const effect = NodeProperties::GetEffectInput(node);
1351 Node* const control = NodeProperties::GetControlInput(node); 1354 Node* const control = NodeProperties::GetControlInput(node);
1352 Node* const closure = NodeProperties::GetValueInput(node, 1); 1355 Node* const closure = NodeProperties::GetValueInput(node, 1);
1353 Node* const context = NodeProperties::GetContextInput(node); 1356 Node* const context = NodeProperties::GetContextInput(node);
1354 Node* const extension = jsgraph()->Constant(scope_info); 1357 Node* const extension = jsgraph()->Constant(scope_info);
1355 Node* const load = graph()->NewNode( 1358 Node* const load = graph()->NewNode(
1356 simplified()->LoadField( 1359 simplified()->LoadField(
1357 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)), 1360 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)),
1358 context, effect, control); 1361 context, effect, control);
1359 AllocationBuilder a(jsgraph(), simplified(), effect, control); 1362 RelaxControls(node);
1363 AllocationBuilder a(jsgraph(), simplified(), node, effect, control);
1360 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. 1364 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered.
1361 a.AllocateArray(context_length, factory()->block_context_map()); 1365 a.AllocateArray(context_length, factory()->block_context_map());
1362 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); 1366 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure);
1363 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); 1367 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
1364 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension); 1368 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
1365 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); 1369 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load);
1366 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) { 1370 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) {
1367 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->TheHoleConstant()); 1371 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->TheHoleConstant());
1368 } 1372 }
1369 // TODO(mstarzinger): We could mutate {node} into the allocation instead. 1373 a.Finish();
1370 NodeProperties::SetType(a.allocation(), NodeProperties::GetType(node));
1371 ReplaceWithValue(node, node, a.effect());
1372 node->ReplaceInput(0, a.allocation());
1373 node->ReplaceInput(1, a.effect());
1374 node->TrimInputCount(2);
1375 NodeProperties::ChangeOp(node, common()->Finish(1));
1376 return Changed(node); 1374 return Changed(node);
1377 } 1375 }
1378 1376
1379 return NoChange(); 1377 return NoChange();
1380 } 1378 }
1381 1379
1382 1380
1383 Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) { 1381 Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) {
1384 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); 1382 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode());
1385 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); 1383 CallFunctionParameters const& p = CallFunctionParametersOf(node->op());
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
1830 } 1828 }
1831 1829
1832 1830
1833 MachineOperatorBuilder* JSTypedLowering::machine() const { 1831 MachineOperatorBuilder* JSTypedLowering::machine() const {
1834 return jsgraph()->machine(); 1832 return jsgraph()->machine();
1835 } 1833 }
1836 1834
1837 } // namespace compiler 1835 } // namespace compiler
1838 } // namespace internal 1836 } // namespace internal
1839 } // namespace v8 1837 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698