| 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 |