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" |
(...skipping 1242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1253 node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(flags)); | 1253 node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(flags)); |
1254 node->InsertInput(graph()->zone(), 0, stub_code); | 1254 node->InsertInput(graph()->zone(), 0, stub_code); |
1255 NodeProperties::ChangeOp(node, new_op); | 1255 NodeProperties::ChangeOp(node, new_op); |
1256 return Changed(node); | 1256 return Changed(node); |
1257 } | 1257 } |
1258 | 1258 |
1259 return NoChange(); | 1259 return NoChange(); |
1260 } | 1260 } |
1261 | 1261 |
1262 | 1262 |
| 1263 Reduction JSTypedLowering::ReduceJSCreateFunctionContext(Node* node) { |
| 1264 DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, node->opcode()); |
| 1265 int slot_count = OpParameter<int>(node->op()); |
| 1266 |
| 1267 // Use inline allocation for function contexts up to a size limit. |
| 1268 if (FLAG_turbo_allocate && slot_count < kFunctionContextAllocationLimit) { |
| 1269 // JSCreateFunctionContext[slot_count < limit]](fun) |
| 1270 Node* const effect = NodeProperties::GetEffectInput(node); |
| 1271 Node* const control = NodeProperties::GetControlInput(node); |
| 1272 Node* const closure = NodeProperties::GetValueInput(node, 0); |
| 1273 Node* const context = NodeProperties::GetContextInput(node); |
| 1274 Node* const extension = jsgraph()->ZeroConstant(); |
| 1275 Node* const load = graph()->NewNode( |
| 1276 simplified()->LoadField( |
| 1277 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)), |
| 1278 context, effect, control); |
| 1279 AllocationBuilder a(jsgraph(), simplified(), effect, control); |
| 1280 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. |
| 1281 int context_length = slot_count + Context::MIN_CONTEXT_SLOTS; |
| 1282 a.AllocateArray(context_length, factory()->function_context_map()); |
| 1283 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); |
| 1284 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); |
| 1285 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension); |
| 1286 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); |
| 1287 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) { |
| 1288 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->TheHoleConstant()); |
| 1289 } |
| 1290 // TODO(mstarzinger): We could mutate {node} into the allocation instead. |
| 1291 NodeProperties::SetType(a.allocation(), NodeProperties::GetType(node)); |
| 1292 ReplaceWithValue(node, node, a.effect()); |
| 1293 node->ReplaceInput(0, a.allocation()); |
| 1294 node->ReplaceInput(1, a.effect()); |
| 1295 node->TrimInputCount(2); |
| 1296 NodeProperties::ChangeOp(node, common()->Finish(1)); |
| 1297 return Changed(node); |
| 1298 } |
| 1299 |
| 1300 // Use the FastNewContextStub only for function contexts up maximum size. |
| 1301 if (slot_count <= FastNewContextStub::kMaximumSlots) { |
| 1302 Isolate* isolate = jsgraph()->isolate(); |
| 1303 Callable callable = CodeFactory::FastNewContext(isolate, slot_count); |
| 1304 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 1305 isolate, graph()->zone(), callable.descriptor(), 0, |
| 1306 CallDescriptor::kNoFlags); |
| 1307 const Operator* new_op = common()->Call(desc); |
| 1308 Node* stub_code = jsgraph()->HeapConstant(callable.code()); |
| 1309 node->InsertInput(graph()->zone(), 0, stub_code); |
| 1310 NodeProperties::ChangeOp(node, new_op); |
| 1311 return Changed(node); |
| 1312 } |
| 1313 |
| 1314 return NoChange(); |
| 1315 } |
| 1316 |
| 1317 |
1263 Reduction JSTypedLowering::ReduceJSCreateWithContext(Node* node) { | 1318 Reduction JSTypedLowering::ReduceJSCreateWithContext(Node* node) { |
1264 DCHECK_EQ(IrOpcode::kJSCreateWithContext, node->opcode()); | 1319 DCHECK_EQ(IrOpcode::kJSCreateWithContext, node->opcode()); |
1265 Node* const input = NodeProperties::GetValueInput(node, 0); | 1320 Node* const input = NodeProperties::GetValueInput(node, 0); |
1266 Type* input_type = NodeProperties::GetType(input); | 1321 Type* input_type = NodeProperties::GetType(input); |
| 1322 |
| 1323 // Use inline allocation for with contexts for regular objects. |
1267 if (FLAG_turbo_allocate && input_type->Is(Type::Receiver())) { | 1324 if (FLAG_turbo_allocate && input_type->Is(Type::Receiver())) { |
1268 // JSCreateWithContext(o:receiver, f) | 1325 // JSCreateWithContext(o:receiver, fun) |
1269 Node* const effect = NodeProperties::GetEffectInput(node); | 1326 Node* const effect = NodeProperties::GetEffectInput(node); |
1270 Node* const control = NodeProperties::GetControlInput(node); | 1327 Node* const control = NodeProperties::GetControlInput(node); |
1271 Node* const closure = NodeProperties::GetValueInput(node, 1); | 1328 Node* const closure = NodeProperties::GetValueInput(node, 1); |
1272 Node* const context = NodeProperties::GetContextInput(node); | 1329 Node* const context = NodeProperties::GetContextInput(node); |
1273 Node* const load = graph()->NewNode( | 1330 Node* const load = graph()->NewNode( |
1274 simplified()->LoadField( | 1331 simplified()->LoadField( |
1275 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)), | 1332 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)), |
1276 context, effect, control); | 1333 context, effect, control); |
1277 AllocationBuilder a(jsgraph(), simplified(), effect, control); | 1334 AllocationBuilder a(jsgraph(), simplified(), effect, control); |
1278 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. | 1335 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. |
1279 a.AllocateArray(Context::MIN_CONTEXT_SLOTS, factory()->with_context_map()); | 1336 a.AllocateArray(Context::MIN_CONTEXT_SLOTS, factory()->with_context_map()); |
1280 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); | 1337 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); |
1281 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); | 1338 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); |
1282 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), input); | 1339 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), input); |
1283 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); | 1340 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); |
1284 // TODO(mstarzinger): We could mutate {node} into the allocation instead. | 1341 // TODO(mstarzinger): We could mutate {node} into the allocation instead. |
1285 NodeProperties::SetType(a.allocation(), NodeProperties::GetType(node)); | 1342 NodeProperties::SetType(a.allocation(), NodeProperties::GetType(node)); |
1286 ReplaceWithValue(node, node, a.effect()); | 1343 ReplaceWithValue(node, node, a.effect()); |
1287 node->ReplaceInput(0, a.allocation()); | 1344 node->ReplaceInput(0, a.allocation()); |
1288 node->ReplaceInput(1, a.effect()); | 1345 node->ReplaceInput(1, a.effect()); |
1289 node->TrimInputCount(2); | 1346 node->TrimInputCount(2); |
1290 NodeProperties::ChangeOp(node, common()->Finish(1)); | 1347 NodeProperties::ChangeOp(node, common()->Finish(1)); |
1291 return Changed(node); | 1348 return Changed(node); |
1292 } | 1349 } |
| 1350 |
1293 return NoChange(); | 1351 return NoChange(); |
1294 } | 1352 } |
1295 | 1353 |
1296 | 1354 |
1297 Reduction JSTypedLowering::ReduceJSCreateBlockContext(Node* node) { | 1355 Reduction JSTypedLowering::ReduceJSCreateBlockContext(Node* node) { |
1298 DCHECK_EQ(IrOpcode::kJSCreateBlockContext, node->opcode()); | 1356 DCHECK_EQ(IrOpcode::kJSCreateBlockContext, node->opcode()); |
1299 Handle<ScopeInfo> scope_info = OpParameter<Handle<ScopeInfo>>(node); | 1357 Handle<ScopeInfo> scope_info = OpParameter<Handle<ScopeInfo>>(node); |
1300 int context_length = scope_info->ContextLength(); | 1358 int context_length = scope_info->ContextLength(); |
| 1359 |
| 1360 // Use inline allocation for block contexts up to a size limit. |
1301 if (FLAG_turbo_allocate && context_length < kBlockContextAllocationLimit) { | 1361 if (FLAG_turbo_allocate && context_length < kBlockContextAllocationLimit) { |
1302 // JSCreateBlockContext(s:scope[length < limit], f) | 1362 // JSCreateBlockContext[scope[length < limit]](fun) |
1303 Node* const effect = NodeProperties::GetEffectInput(node); | 1363 Node* const effect = NodeProperties::GetEffectInput(node); |
1304 Node* const control = NodeProperties::GetControlInput(node); | 1364 Node* const control = NodeProperties::GetControlInput(node); |
1305 Node* const closure = NodeProperties::GetValueInput(node, 1); | 1365 Node* const closure = NodeProperties::GetValueInput(node, 1); |
1306 Node* const context = NodeProperties::GetContextInput(node); | 1366 Node* const context = NodeProperties::GetContextInput(node); |
1307 Node* const extension = jsgraph()->Constant(scope_info); | 1367 Node* const extension = jsgraph()->Constant(scope_info); |
1308 Node* const load = graph()->NewNode( | 1368 Node* const load = graph()->NewNode( |
1309 simplified()->LoadField( | 1369 simplified()->LoadField( |
1310 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)), | 1370 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)), |
1311 context, effect, control); | 1371 context, effect, control); |
1312 AllocationBuilder a(jsgraph(), simplified(), effect, control); | 1372 AllocationBuilder a(jsgraph(), simplified(), effect, control); |
1313 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. | 1373 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. |
1314 a.AllocateArray(context_length, factory()->block_context_map()); | 1374 a.AllocateArray(context_length, factory()->block_context_map()); |
1315 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); | 1375 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); |
1316 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); | 1376 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); |
1317 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension); | 1377 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension); |
1318 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); | 1378 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); |
1319 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) { | 1379 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) { |
1320 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->TheHoleConstant()); | 1380 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->TheHoleConstant()); |
1321 } | 1381 } |
1322 // TODO(mstarzinger): We could mutate {node} into the allocation instead. | 1382 // TODO(mstarzinger): We could mutate {node} into the allocation instead. |
1323 NodeProperties::SetType(a.allocation(), NodeProperties::GetType(node)); | 1383 NodeProperties::SetType(a.allocation(), NodeProperties::GetType(node)); |
1324 ReplaceWithValue(node, node, a.effect()); | 1384 ReplaceWithValue(node, node, a.effect()); |
1325 node->ReplaceInput(0, a.allocation()); | 1385 node->ReplaceInput(0, a.allocation()); |
1326 node->ReplaceInput(1, a.effect()); | 1386 node->ReplaceInput(1, a.effect()); |
1327 node->TrimInputCount(2); | 1387 node->TrimInputCount(2); |
1328 NodeProperties::ChangeOp(node, common()->Finish(1)); | 1388 NodeProperties::ChangeOp(node, common()->Finish(1)); |
1329 return Changed(node); | 1389 return Changed(node); |
1330 } | 1390 } |
| 1391 |
1331 return NoChange(); | 1392 return NoChange(); |
1332 } | 1393 } |
1333 | 1394 |
1334 | 1395 |
1335 Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) { | 1396 Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) { |
1336 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); | 1397 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); |
1337 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); | 1398 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); |
1338 int const arity = static_cast<int>(p.arity() - 2); | 1399 int const arity = static_cast<int>(p.arity() - 2); |
1339 Node* const function = NodeProperties::GetValueInput(node, 0); | 1400 Node* const function = NodeProperties::GetValueInput(node, 0); |
1340 Type* const function_type = NodeProperties::GetType(function); | 1401 Type* const function_type = NodeProperties::GetType(function); |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1728 case IrOpcode::kJSLoadDynamicContext: | 1789 case IrOpcode::kJSLoadDynamicContext: |
1729 return ReduceJSLoadDynamicContext(node); | 1790 return ReduceJSLoadDynamicContext(node); |
1730 case IrOpcode::kJSCreateArguments: | 1791 case IrOpcode::kJSCreateArguments: |
1731 return ReduceJSCreateArguments(node); | 1792 return ReduceJSCreateArguments(node); |
1732 case IrOpcode::kJSCreateClosure: | 1793 case IrOpcode::kJSCreateClosure: |
1733 return ReduceJSCreateClosure(node); | 1794 return ReduceJSCreateClosure(node); |
1734 case IrOpcode::kJSCreateLiteralArray: | 1795 case IrOpcode::kJSCreateLiteralArray: |
1735 return ReduceJSCreateLiteralArray(node); | 1796 return ReduceJSCreateLiteralArray(node); |
1736 case IrOpcode::kJSCreateLiteralObject: | 1797 case IrOpcode::kJSCreateLiteralObject: |
1737 return ReduceJSCreateLiteralObject(node); | 1798 return ReduceJSCreateLiteralObject(node); |
| 1799 case IrOpcode::kJSCreateFunctionContext: |
| 1800 return ReduceJSCreateFunctionContext(node); |
1738 case IrOpcode::kJSCreateWithContext: | 1801 case IrOpcode::kJSCreateWithContext: |
1739 return ReduceJSCreateWithContext(node); | 1802 return ReduceJSCreateWithContext(node); |
1740 case IrOpcode::kJSCreateBlockContext: | 1803 case IrOpcode::kJSCreateBlockContext: |
1741 return ReduceJSCreateBlockContext(node); | 1804 return ReduceJSCreateBlockContext(node); |
1742 case IrOpcode::kJSCallFunction: | 1805 case IrOpcode::kJSCallFunction: |
1743 return ReduceJSCallFunction(node); | 1806 return ReduceJSCallFunction(node); |
1744 case IrOpcode::kJSForInDone: | 1807 case IrOpcode::kJSForInDone: |
1745 return ReduceJSForInDone(node); | 1808 return ReduceJSForInDone(node); |
1746 case IrOpcode::kJSForInNext: | 1809 case IrOpcode::kJSForInNext: |
1747 return ReduceJSForInNext(node); | 1810 return ReduceJSForInNext(node); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1782 } | 1845 } |
1783 | 1846 |
1784 | 1847 |
1785 MachineOperatorBuilder* JSTypedLowering::machine() const { | 1848 MachineOperatorBuilder* JSTypedLowering::machine() const { |
1786 return jsgraph()->machine(); | 1849 return jsgraph()->machine(); |
1787 } | 1850 } |
1788 | 1851 |
1789 } // namespace compiler | 1852 } // namespace compiler |
1790 } // namespace internal | 1853 } // namespace internal |
1791 } // namespace v8 | 1854 } // namespace v8 |
OLD | NEW |