OLD | NEW |
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" |
11 #include "src/compiler/node-properties.h" | 11 #include "src/compiler/node-properties.h" |
12 #include "src/compiler/operator-properties.h" | 12 #include "src/compiler/operator-properties.h" |
| 13 #include "src/compiler/state-values-utils.h" |
13 #include "src/types.h" | 14 #include "src/types.h" |
14 | 15 |
15 namespace v8 { | 16 namespace v8 { |
16 namespace internal { | 17 namespace internal { |
17 namespace compiler { | 18 namespace compiler { |
18 | 19 |
19 // TODO(turbofan): js-typed-lowering improvements possible | 20 // TODO(turbofan): js-typed-lowering improvements possible |
20 // - immediately put in type bounds for all new nodes | 21 // - immediately put in type bounds for all new nodes |
21 // - relax effects from generic but not-side-effecting operations | 22 // - relax effects from generic but not-side-effecting operations |
22 | 23 |
23 | 24 |
24 JSTypedLowering::JSTypedLowering(Editor* editor, JSGraph* jsgraph, Zone* zone) | 25 JSTypedLowering::JSTypedLowering(Editor* editor, JSGraph* jsgraph, Zone* zone) |
25 : AdvancedReducer(editor), jsgraph_(jsgraph) { | 26 : AdvancedReducer(editor), jsgraph_(jsgraph) { |
26 for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) { | 27 for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) { |
27 double min = kMinInt / (1 << k); | 28 double min = kMinInt / (1 << k); |
28 double max = kMaxInt / (1 << k); | 29 double max = kMaxInt / (1 << k); |
29 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); | 30 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); |
30 } | 31 } |
31 } | 32 } |
32 | 33 |
33 | 34 |
34 // A helper class to construct inline allocations on the simplified operator | 35 // 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 | 36 // 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. | 37 // allocated object and also provides helpers for commonly allocated objects. |
37 class AllocationBuilder final { | 38 class AllocationBuilder final { |
38 public: | 39 public: |
39 AllocationBuilder(JSGraph* jsgraph, SimplifiedOperatorBuilder* simplified, | 40 AllocationBuilder(JSGraph* jsgraph, Node* effect, Node* control) |
40 Node* effect, Node* control) | |
41 : jsgraph_(jsgraph), | 41 : jsgraph_(jsgraph), |
42 simplified_(simplified), | |
43 allocation_(nullptr), | 42 allocation_(nullptr), |
44 effect_(effect), | 43 effect_(effect), |
45 control_(control) {} | 44 control_(control) {} |
46 | 45 |
47 // Primitive allocation of static size. | 46 // Primitive allocation of static size. |
48 void Allocate(int size) { | 47 void Allocate(int size) { |
49 effect_ = graph()->NewNode(jsgraph()->common()->BeginRegion(), effect_); | 48 effect_ = graph()->NewNode(common()->BeginRegion(), effect_); |
50 allocation_ = graph()->NewNode( | 49 allocation_ = graph()->NewNode( |
51 simplified()->Allocate(), jsgraph()->Constant(size), effect_, control_); | 50 simplified()->Allocate(), jsgraph()->Constant(size), effect_, control_); |
52 effect_ = allocation_; | 51 effect_ = allocation_; |
53 } | 52 } |
54 | 53 |
55 // Primitive store into a field. | 54 // Primitive store into a field. |
56 void Store(const FieldAccess& access, Node* value) { | 55 void Store(const FieldAccess& access, Node* value) { |
57 effect_ = graph()->NewNode(simplified()->StoreField(access), allocation_, | 56 effect_ = graph()->NewNode(simplified()->StoreField(access), allocation_, |
58 value, effect_, control_); | 57 value, effect_, control_); |
59 } | 58 } |
60 | 59 |
61 // Compound allocation of a FixedArray. | 60 // Compound allocation of a FixedArray. |
62 void AllocateArray(int length, Handle<Map> map) { | 61 void AllocateArray(int length, Handle<Map> map) { |
63 Allocate(FixedArray::SizeFor(length)); | 62 Allocate(FixedArray::SizeFor(length)); |
64 Store(AccessBuilder::ForMap(), map); | 63 Store(AccessBuilder::ForMap(), map); |
65 Store(AccessBuilder::ForFixedArrayLength(graph()->zone()), | 64 Store(AccessBuilder::ForFixedArrayLength(graph()->zone()), |
66 jsgraph()->Constant(length)); | 65 jsgraph()->Constant(length)); |
67 } | 66 } |
68 | 67 |
69 // Compound store of a constant into a field. | 68 // Compound store of a constant into a field. |
70 void Store(const FieldAccess& access, Handle<Object> value) { | 69 void Store(const FieldAccess& access, Handle<Object> value) { |
71 Store(access, jsgraph()->Constant(value)); | 70 Store(access, jsgraph()->Constant(value)); |
72 } | 71 } |
73 | 72 |
74 void Finish(Node* node) { | 73 void FinishAndChange(Node* node) { |
75 NodeProperties::SetType(allocation_, NodeProperties::GetType(node)); | 74 NodeProperties::SetType(allocation_, NodeProperties::GetType(node)); |
76 node->ReplaceInput(0, allocation_); | 75 node->ReplaceInput(0, allocation_); |
77 node->ReplaceInput(1, effect_); | 76 node->ReplaceInput(1, effect_); |
78 node->TrimInputCount(2); | 77 node->TrimInputCount(2); |
79 NodeProperties::ChangeOp(node, jsgraph()->common()->FinishRegion()); | 78 NodeProperties::ChangeOp(node, common()->FinishRegion()); |
| 79 } |
| 80 |
| 81 Node* Finish() { |
| 82 return graph()->NewNode(common()->FinishRegion(), allocation_, effect_); |
80 } | 83 } |
81 | 84 |
82 protected: | 85 protected: |
83 JSGraph* jsgraph() { return jsgraph_; } | 86 JSGraph* jsgraph() { return jsgraph_; } |
84 Graph* graph() { return jsgraph_->graph(); } | 87 Graph* graph() { return jsgraph_->graph(); } |
85 SimplifiedOperatorBuilder* simplified() { return simplified_; } | 88 CommonOperatorBuilder* common() { return jsgraph_->common(); } |
| 89 SimplifiedOperatorBuilder* simplified() { return jsgraph_->simplified(); } |
86 | 90 |
87 private: | 91 private: |
88 JSGraph* const jsgraph_; | 92 JSGraph* const jsgraph_; |
89 SimplifiedOperatorBuilder* simplified_; | |
90 Node* allocation_; | 93 Node* allocation_; |
91 Node* effect_; | 94 Node* effect_; |
92 Node* control_; | 95 Node* control_; |
93 }; | 96 }; |
94 | 97 |
95 | 98 |
96 // A helper class to simplify the process of reducing a single binop node with a | 99 // A helper class to simplify the process of reducing a single binop node with a |
97 // JSOperator. This class manages the rewriting of context, control, and effect | 100 // JSOperator. This class manages the rewriting of context, control, and effect |
98 // dependencies during lowering of a binop and contains numerous helper | 101 // dependencies during lowering of a binop and contains numerous helper |
99 // functions for matching the types of inputs to an operation. | 102 // functions for matching the types of inputs to an operation. |
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1152 Node* parameter_pointer = graph()->NewNode( | 1155 Node* parameter_pointer = graph()->NewNode( |
1153 machine()->IntAdd(), graph()->NewNode(machine()->LoadFramePointer()), | 1156 machine()->IntAdd(), graph()->NewNode(machine()->LoadFramePointer()), |
1154 jsgraph()->IntPtrConstant(offset)); | 1157 jsgraph()->IntPtrConstant(offset)); |
1155 node->InsertInput(graph()->zone(), 0, stub_code); | 1158 node->InsertInput(graph()->zone(), 0, stub_code); |
1156 node->InsertInput(graph()->zone(), 2, jsgraph()->Constant(parameter_count)); | 1159 node->InsertInput(graph()->zone(), 2, jsgraph()->Constant(parameter_count)); |
1157 node->InsertInput(graph()->zone(), 3, parameter_pointer); | 1160 node->InsertInput(graph()->zone(), 3, parameter_pointer); |
1158 NodeProperties::ChangeOp(node, new_op); | 1161 NodeProperties::ChangeOp(node, new_op); |
1159 return Changed(node); | 1162 return Changed(node); |
1160 } | 1163 } |
1161 | 1164 |
| 1165 // Use inline allocation for all unmapped arguments objects within inlined |
| 1166 // (i.e. non-outermost) frames, independent of the object size. |
| 1167 if (p.type() == CreateArgumentsParameters::kUnmappedArguments && |
| 1168 outer_state->opcode() == IrOpcode::kFrameState) { |
| 1169 Node* const effect = NodeProperties::GetEffectInput(node); |
| 1170 Node* const control = NodeProperties::GetControlInput(node); |
| 1171 Node* const context = NodeProperties::GetContextInput(node); |
| 1172 FrameStateInfo outer_state_info = OpParameter<FrameStateInfo>(outer_state); |
| 1173 // Choose the correct frame state and frame state info depending on whether |
| 1174 // there conceptually is an arguments adaptor frame in the call chain. |
| 1175 Node* const args_state = |
| 1176 outer_state_info.type() == FrameStateType::kArgumentsAdaptor |
| 1177 ? outer_state |
| 1178 : frame_state; |
| 1179 FrameStateInfo args_state_info = OpParameter<FrameStateInfo>(args_state); |
| 1180 // Prepare element backing store to be used by arguments object. |
| 1181 Node* const elements = AllocateArguments(effect, control, args_state); |
| 1182 // Load the arguments object map from the current native context. |
| 1183 Node* const load_global_object = graph()->NewNode( |
| 1184 simplified()->LoadField( |
| 1185 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)), |
| 1186 context, effect, control); |
| 1187 Node* const load_native_context = graph()->NewNode( |
| 1188 simplified()->LoadField(AccessBuilder::ForGlobalObjectNativeContext()), |
| 1189 load_global_object, effect, control); |
| 1190 Node* const load_arguments_map = graph()->NewNode( |
| 1191 simplified()->LoadField( |
| 1192 AccessBuilder::ForContextSlot(Context::STRICT_ARGUMENTS_MAP_INDEX)), |
| 1193 load_native_context, effect, control); |
| 1194 // Actually allocate and initialize the arguments object. |
| 1195 AllocationBuilder a(jsgraph(), effect, control); |
| 1196 Handle<Object> properties = factory()->empty_fixed_array(); |
| 1197 int length = args_state_info.parameter_count() - 1; // Minus receiver. |
| 1198 STATIC_ASSERT(Heap::kStrictArgumentsObjectSize == 4 * kPointerSize); |
| 1199 a.Allocate(Heap::kStrictArgumentsObjectSize); |
| 1200 a.Store(AccessBuilder::ForMap(), load_arguments_map); |
| 1201 a.Store(AccessBuilder::ForJSObjectProperties(), properties); |
| 1202 a.Store(AccessBuilder::ForJSObjectElements(), elements); |
| 1203 a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length)); |
| 1204 RelaxControls(node); |
| 1205 a.FinishAndChange(node); |
| 1206 return Changed(node); |
| 1207 } |
| 1208 |
1162 return NoChange(); | 1209 return NoChange(); |
1163 } | 1210 } |
1164 | 1211 |
1165 | 1212 |
1166 Reduction JSTypedLowering::ReduceJSCreateClosure(Node* node) { | 1213 Reduction JSTypedLowering::ReduceJSCreateClosure(Node* node) { |
1167 DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode()); | 1214 DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode()); |
1168 CreateClosureParameters const& p = CreateClosureParametersOf(node->op()); | 1215 CreateClosureParameters const& p = CreateClosureParametersOf(node->op()); |
1169 Handle<SharedFunctionInfo> shared = p.shared_info(); | 1216 Handle<SharedFunctionInfo> shared = p.shared_info(); |
1170 | 1217 |
1171 // Use the FastNewClosureStub that allocates in new space only for nested | 1218 // Use the FastNewClosureStub that allocates in new space only for nested |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1263 closure->opcode() != IrOpcode::kNumberConstant) { | 1310 closure->opcode() != IrOpcode::kNumberConstant) { |
1264 // JSCreateFunctionContext[slot_count < limit]](fun) | 1311 // JSCreateFunctionContext[slot_count < limit]](fun) |
1265 Node* const effect = NodeProperties::GetEffectInput(node); | 1312 Node* const effect = NodeProperties::GetEffectInput(node); |
1266 Node* const control = NodeProperties::GetControlInput(node); | 1313 Node* const control = NodeProperties::GetControlInput(node); |
1267 Node* const context = NodeProperties::GetContextInput(node); | 1314 Node* const context = NodeProperties::GetContextInput(node); |
1268 Node* const extension = jsgraph()->ZeroConstant(); | 1315 Node* const extension = jsgraph()->ZeroConstant(); |
1269 Node* const load = graph()->NewNode( | 1316 Node* const load = graph()->NewNode( |
1270 simplified()->LoadField( | 1317 simplified()->LoadField( |
1271 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)), | 1318 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)), |
1272 context, effect, control); | 1319 context, effect, control); |
1273 AllocationBuilder a(jsgraph(), simplified(), effect, control); | 1320 AllocationBuilder a(jsgraph(), effect, control); |
1274 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. | 1321 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. |
1275 int context_length = slot_count + Context::MIN_CONTEXT_SLOTS; | 1322 int context_length = slot_count + Context::MIN_CONTEXT_SLOTS; |
1276 a.AllocateArray(context_length, factory()->function_context_map()); | 1323 a.AllocateArray(context_length, factory()->function_context_map()); |
1277 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); | 1324 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); |
1278 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); | 1325 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); |
1279 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension); | 1326 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension); |
1280 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); | 1327 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); |
1281 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) { | 1328 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) { |
1282 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->UndefinedConstant()); | 1329 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->UndefinedConstant()); |
1283 } | 1330 } |
1284 RelaxControls(node); | 1331 RelaxControls(node); |
1285 a.Finish(node); | 1332 a.FinishAndChange(node); |
1286 return Changed(node); | 1333 return Changed(node); |
1287 } | 1334 } |
1288 | 1335 |
1289 // Use the FastNewContextStub only for function contexts up maximum size. | 1336 // Use the FastNewContextStub only for function contexts up maximum size. |
1290 if (slot_count <= FastNewContextStub::kMaximumSlots) { | 1337 if (slot_count <= FastNewContextStub::kMaximumSlots) { |
1291 Isolate* isolate = jsgraph()->isolate(); | 1338 Isolate* isolate = jsgraph()->isolate(); |
1292 Callable callable = CodeFactory::FastNewContext(isolate, slot_count); | 1339 Callable callable = CodeFactory::FastNewContext(isolate, slot_count); |
1293 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 1340 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
1294 isolate, graph()->zone(), callable.descriptor(), 0, | 1341 isolate, graph()->zone(), callable.descriptor(), 0, |
1295 CallDescriptor::kNoFlags); | 1342 CallDescriptor::kNoFlags); |
(...skipping 22 matching lines...) Expand all Loading... |
1318 if (input_type->Is(Type::Receiver()) && | 1365 if (input_type->Is(Type::Receiver()) && |
1319 closure->opcode() != IrOpcode::kNumberConstant) { | 1366 closure->opcode() != IrOpcode::kNumberConstant) { |
1320 // JSCreateWithContext(o:receiver, fun) | 1367 // JSCreateWithContext(o:receiver, fun) |
1321 Node* const effect = NodeProperties::GetEffectInput(node); | 1368 Node* const effect = NodeProperties::GetEffectInput(node); |
1322 Node* const control = NodeProperties::GetControlInput(node); | 1369 Node* const control = NodeProperties::GetControlInput(node); |
1323 Node* const context = NodeProperties::GetContextInput(node); | 1370 Node* const context = NodeProperties::GetContextInput(node); |
1324 Node* const load = graph()->NewNode( | 1371 Node* const load = graph()->NewNode( |
1325 simplified()->LoadField( | 1372 simplified()->LoadField( |
1326 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)), | 1373 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)), |
1327 context, effect, control); | 1374 context, effect, control); |
1328 AllocationBuilder a(jsgraph(), simplified(), effect, control); | 1375 AllocationBuilder a(jsgraph(), effect, control); |
1329 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. | 1376 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. |
1330 a.AllocateArray(Context::MIN_CONTEXT_SLOTS, factory()->with_context_map()); | 1377 a.AllocateArray(Context::MIN_CONTEXT_SLOTS, factory()->with_context_map()); |
1331 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); | 1378 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); |
1332 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); | 1379 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); |
1333 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), input); | 1380 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), input); |
1334 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); | 1381 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); |
1335 RelaxControls(node); | 1382 RelaxControls(node); |
1336 a.Finish(node); | 1383 a.FinishAndChange(node); |
1337 return Changed(node); | 1384 return Changed(node); |
1338 } | 1385 } |
1339 | 1386 |
1340 return NoChange(); | 1387 return NoChange(); |
1341 } | 1388 } |
1342 | 1389 |
1343 | 1390 |
1344 Reduction JSTypedLowering::ReduceJSCreateBlockContext(Node* node) { | 1391 Reduction JSTypedLowering::ReduceJSCreateBlockContext(Node* node) { |
1345 DCHECK_EQ(IrOpcode::kJSCreateBlockContext, node->opcode()); | 1392 DCHECK_EQ(IrOpcode::kJSCreateBlockContext, node->opcode()); |
1346 Handle<ScopeInfo> scope_info = OpParameter<Handle<ScopeInfo>>(node); | 1393 Handle<ScopeInfo> scope_info = OpParameter<Handle<ScopeInfo>>(node); |
1347 int context_length = scope_info->ContextLength(); | 1394 int context_length = scope_info->ContextLength(); |
1348 Node* const closure = NodeProperties::GetValueInput(node, 0); | 1395 Node* const closure = NodeProperties::GetValueInput(node, 0); |
1349 | 1396 |
1350 // The closure can be NumberConstant(0) if the closure is global code | 1397 // The closure can be NumberConstant(0) if the closure is global code |
1351 // (rather than a function). We exclude that case here. | 1398 // (rather than a function). We exclude that case here. |
1352 // TODO(jarin) Find a better way to check that the closure is a function. | 1399 // TODO(jarin) Find a better way to check that the closure is a function. |
1353 | 1400 |
1354 // Use inline allocation for block contexts up to a size limit. | 1401 // Use inline allocation for block contexts up to a size limit. |
1355 if (context_length < kBlockContextAllocationLimit && | 1402 if (context_length < kBlockContextAllocationLimit && |
1356 closure->opcode() != IrOpcode::kNumberConstant) { | 1403 closure->opcode() != IrOpcode::kNumberConstant) { |
1357 // JSCreateBlockContext[scope[length < limit]](fun) | 1404 // JSCreateBlockContext[scope[length < limit]](fun) |
1358 Node* const effect = NodeProperties::GetEffectInput(node); | 1405 Node* const effect = NodeProperties::GetEffectInput(node); |
1359 Node* const control = NodeProperties::GetControlInput(node); | 1406 Node* const control = NodeProperties::GetControlInput(node); |
1360 Node* const context = NodeProperties::GetContextInput(node); | 1407 Node* const context = NodeProperties::GetContextInput(node); |
1361 Node* const extension = jsgraph()->Constant(scope_info); | 1408 Node* const extension = jsgraph()->Constant(scope_info); |
1362 Node* const load = graph()->NewNode( | 1409 Node* const load = graph()->NewNode( |
1363 simplified()->LoadField( | 1410 simplified()->LoadField( |
1364 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)), | 1411 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)), |
1365 context, effect, control); | 1412 context, effect, control); |
1366 AllocationBuilder a(jsgraph(), simplified(), effect, control); | 1413 AllocationBuilder a(jsgraph(), effect, control); |
1367 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. | 1414 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. |
1368 a.AllocateArray(context_length, factory()->block_context_map()); | 1415 a.AllocateArray(context_length, factory()->block_context_map()); |
1369 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); | 1416 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); |
1370 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); | 1417 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); |
1371 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension); | 1418 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension); |
1372 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); | 1419 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); |
1373 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) { | 1420 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) { |
1374 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->TheHoleConstant()); | 1421 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->TheHoleConstant()); |
1375 } | 1422 } |
1376 RelaxControls(node); | 1423 RelaxControls(node); |
1377 a.Finish(node); | 1424 a.FinishAndChange(node); |
1378 return Changed(node); | 1425 return Changed(node); |
1379 } | 1426 } |
1380 | 1427 |
1381 return NoChange(); | 1428 return NoChange(); |
1382 } | 1429 } |
1383 | 1430 |
1384 | 1431 |
1385 Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) { | 1432 Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) { |
1386 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); | 1433 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); |
1387 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); | 1434 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1806 } | 1853 } |
1807 | 1854 |
1808 | 1855 |
1809 Node* JSTypedLowering::Word32Shl(Node* const lhs, int32_t const rhs) { | 1856 Node* JSTypedLowering::Word32Shl(Node* const lhs, int32_t const rhs) { |
1810 if (rhs == 0) return lhs; | 1857 if (rhs == 0) return lhs; |
1811 return graph()->NewNode(machine()->Word32Shl(), lhs, | 1858 return graph()->NewNode(machine()->Word32Shl(), lhs, |
1812 jsgraph()->Int32Constant(rhs)); | 1859 jsgraph()->Int32Constant(rhs)); |
1813 } | 1860 } |
1814 | 1861 |
1815 | 1862 |
| 1863 // Helper that allocates a FixedArray holding argument values recorded in the |
| 1864 // given {frame_state}. Serves as backing store for JSCreateArguments nodes. |
| 1865 Node* JSTypedLowering::AllocateArguments(Node* effect, Node* control, |
| 1866 Node* frame_state) { |
| 1867 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); |
| 1868 int length = state_info.parameter_count() - 1; // Minus receiver argument. |
| 1869 if (length == 0) return jsgraph()->Constant(factory()->empty_fixed_array()); |
| 1870 Node* const parameters = frame_state->InputAt(kFrameStateParametersInput); |
| 1871 StateValuesAccess parameters_access(parameters); |
| 1872 auto paratemers_it = ++parameters_access.begin(); |
| 1873 AllocationBuilder a(jsgraph(), effect, control); |
| 1874 a.AllocateArray(length, factory()->fixed_array_map()); |
| 1875 for (int i = 0; i < length; ++i, ++paratemers_it) { |
| 1876 a.Store(AccessBuilder::ForFixedArraySlot(i), (*paratemers_it).node); |
| 1877 } |
| 1878 return a.Finish(); |
| 1879 } |
| 1880 |
| 1881 |
1816 Factory* JSTypedLowering::factory() const { return jsgraph()->factory(); } | 1882 Factory* JSTypedLowering::factory() const { return jsgraph()->factory(); } |
1817 | 1883 |
1818 | 1884 |
1819 Graph* JSTypedLowering::graph() const { return jsgraph()->graph(); } | 1885 Graph* JSTypedLowering::graph() const { return jsgraph()->graph(); } |
1820 | 1886 |
1821 | 1887 |
1822 Isolate* JSTypedLowering::isolate() const { return jsgraph()->isolate(); } | 1888 Isolate* JSTypedLowering::isolate() const { return jsgraph()->isolate(); } |
1823 | 1889 |
1824 | 1890 |
1825 JSOperatorBuilder* JSTypedLowering::javascript() const { | 1891 JSOperatorBuilder* JSTypedLowering::javascript() const { |
(...skipping 11 matching lines...) Expand all Loading... |
1837 } | 1903 } |
1838 | 1904 |
1839 | 1905 |
1840 MachineOperatorBuilder* JSTypedLowering::machine() const { | 1906 MachineOperatorBuilder* JSTypedLowering::machine() const { |
1841 return jsgraph()->machine(); | 1907 return jsgraph()->machine(); |
1842 } | 1908 } |
1843 | 1909 |
1844 } // namespace compiler | 1910 } // namespace compiler |
1845 } // namespace internal | 1911 } // namespace internal |
1846 } // namespace v8 | 1912 } // namespace v8 |
OLD | NEW |