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

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

Issue 1380113002: [turbofan] Call FastNewContextStub for function context. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comment. 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 1242 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/js-typed-lowering.h ('k') | test/unittests/compiler/js-context-relaxation-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698