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

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

Issue 1676883002: [runtime] Optimize and unify rest parameters. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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/compilation-dependencies.h" 6 #include "src/compilation-dependencies.h"
7 #include "src/compiler/access-builder.h" 7 #include "src/compiler/access-builder.h"
8 #include "src/compiler/js-graph.h" 8 #include "src/compiler/js-graph.h"
9 #include "src/compiler/js-typed-lowering.h" 9 #include "src/compiler/js-typed-lowering.h"
10 #include "src/compiler/linkage.h" 10 #include "src/compiler/linkage.h"
(...skipping 1499 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 return outer_state_info.type() == FrameStateType::kArgumentsAdaptor 1510 return outer_state_info.type() == FrameStateType::kArgumentsAdaptor
1511 ? outer_state 1511 ? outer_state
1512 : frame_state; 1512 : frame_state;
1513 } 1513 }
1514 1514
1515 } // namespace 1515 } // namespace
1516 1516
1517 1517
1518 Reduction JSTypedLowering::ReduceJSCreateArguments(Node* node) { 1518 Reduction JSTypedLowering::ReduceJSCreateArguments(Node* node) {
1519 DCHECK_EQ(IrOpcode::kJSCreateArguments, node->opcode()); 1519 DCHECK_EQ(IrOpcode::kJSCreateArguments, node->opcode());
1520 CreateArgumentsParameters const& p = CreateArgumentsParametersOf(node->op()); 1520 CreateArgumentsType type = CreateArgumentsTypeOf(node->op());
1521 Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0); 1521 Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0);
1522 Node* const outer_state = frame_state->InputAt(kFrameStateOuterStateInput); 1522 Node* const outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
1523 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); 1523 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
1524 1524
1525 // Use the ArgumentsAccessStub for materializing both mapped and unmapped 1525 // Use the ArgumentsAccessStub for materializing both mapped and unmapped
1526 // arguments object, but only for non-inlined (i.e. outermost) frames. 1526 // arguments object, but only for non-inlined (i.e. outermost) frames.
1527 if (outer_state->opcode() != IrOpcode::kFrameState) { 1527 if (outer_state->opcode() != IrOpcode::kFrameState) {
1528 Isolate* isolate = jsgraph()->isolate(); 1528 if (type != CreateArgumentsType::kRestParameter) {
1529 int parameter_count = state_info.parameter_count() - 1; 1529 // TODO(bmeurer): Cleanup this mess at some point.
1530 int parameter_offset = parameter_count * kPointerSize; 1530 Isolate* isolate = jsgraph()->isolate();
1531 int offset = StandardFrameConstants::kCallerSPOffset + parameter_offset; 1531 int parameter_count = state_info.parameter_count() - 1;
1532 Node* parameter_pointer = graph()->NewNode( 1532 int parameter_offset = parameter_count * kPointerSize;
1533 machine()->IntAdd(), graph()->NewNode(machine()->LoadFramePointer()), 1533 int offset = StandardFrameConstants::kCallerSPOffset + parameter_offset;
1534 jsgraph()->IntPtrConstant(offset)); 1534 Node* parameter_pointer = graph()->NewNode(
1535 1535 machine()->IntAdd(), graph()->NewNode(machine()->LoadFramePointer()),
1536 if (p.type() != CreateArgumentsParameters::kRestArray) { 1536 jsgraph()->IntPtrConstant(offset));
1537 Handle<SharedFunctionInfo> shared; 1537 Handle<SharedFunctionInfo> shared;
1538 if (!state_info.shared_info().ToHandle(&shared)) return NoChange(); 1538 if (!state_info.shared_info().ToHandle(&shared)) return NoChange();
1539 bool unmapped = p.type() == CreateArgumentsParameters::kUnmappedArguments; 1539 bool unmapped = type == CreateArgumentsType::kUnmappedArguments;
1540 Callable callable = CodeFactory::ArgumentsAccess( 1540 Callable callable = CodeFactory::ArgumentsAccess(
1541 isolate, unmapped, shared->has_duplicate_parameters()); 1541 isolate, unmapped, shared->has_duplicate_parameters());
1542 CallDescriptor* desc = Linkage::GetStubCallDescriptor( 1542 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
1543 isolate, graph()->zone(), callable.descriptor(), 0, 1543 isolate, graph()->zone(), callable.descriptor(), 0,
1544 CallDescriptor::kNeedsFrameState); 1544 CallDescriptor::kNeedsFrameState);
1545 const Operator* new_op = common()->Call(desc); 1545 const Operator* new_op = common()->Call(desc);
1546 Node* stub_code = jsgraph()->HeapConstant(callable.code()); 1546 Node* stub_code = jsgraph()->HeapConstant(callable.code());
1547 node->InsertInput(graph()->zone(), 0, stub_code); 1547 node->InsertInput(graph()->zone(), 0, stub_code);
1548 node->InsertInput(graph()->zone(), 2, 1548 node->InsertInput(graph()->zone(), 2,
1549 jsgraph()->Constant(parameter_count)); 1549 jsgraph()->Constant(parameter_count));
1550 node->InsertInput(graph()->zone(), 3, parameter_pointer); 1550 node->InsertInput(graph()->zone(), 3, parameter_pointer);
1551 NodeProperties::ChangeOp(node, new_op); 1551 NodeProperties::ChangeOp(node, new_op);
1552 return Changed(node); 1552 return Changed(node);
1553 } else { 1553 } else {
1554 Callable callable = CodeFactory::RestArgumentsAccess(isolate); 1554 Callable callable = CodeFactory::FastNewRestParameter(isolate());
1555 CallDescriptor* desc = Linkage::GetStubCallDescriptor( 1555 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
1556 isolate, graph()->zone(), callable.descriptor(), 0, 1556 isolate(), graph()->zone(), callable.descriptor(), 0,
1557 CallDescriptor::kNeedsFrameState); 1557 CallDescriptor::kNeedsFrameState);
1558 const Operator* new_op = common()->Call(desc); 1558 const Operator* new_op = common()->Call(desc);
1559 Node* stub_code = jsgraph()->HeapConstant(callable.code()); 1559 Node* stub_code = jsgraph()->HeapConstant(callable.code());
1560 node->InsertInput(graph()->zone(), 0, stub_code); 1560 node->InsertInput(graph()->zone(), 0, stub_code);
1561 node->ReplaceInput(1, jsgraph()->Constant(parameter_count));
1562 node->InsertInput(graph()->zone(), 2, parameter_pointer);
1563 node->InsertInput(graph()->zone(), 3,
1564 jsgraph()->Constant(p.start_index()));
1565 NodeProperties::ChangeOp(node, new_op); 1561 NodeProperties::ChangeOp(node, new_op);
1566 return Changed(node); 1562 return Changed(node);
1567 } 1563 }
1568 } else if (outer_state->opcode() == IrOpcode::kFrameState) { 1564 } else if (outer_state->opcode() == IrOpcode::kFrameState) {
1569 // Use inline allocation for all mapped arguments objects within inlined 1565 // Use inline allocation for all mapped arguments objects within inlined
1570 // (i.e. non-outermost) frames, independent of the object size. 1566 // (i.e. non-outermost) frames, independent of the object size.
1571 if (p.type() == CreateArgumentsParameters::kMappedArguments) { 1567 if (type == CreateArgumentsType::kMappedArguments) {
1572 Handle<SharedFunctionInfo> shared; 1568 Handle<SharedFunctionInfo> shared;
1573 if (!state_info.shared_info().ToHandle(&shared)) return NoChange(); 1569 if (!state_info.shared_info().ToHandle(&shared)) return NoChange();
1574 Node* const callee = NodeProperties::GetValueInput(node, 0); 1570 Node* const callee = NodeProperties::GetValueInput(node, 0);
1575 Node* const control = NodeProperties::GetControlInput(node); 1571 Node* const control = NodeProperties::GetControlInput(node);
1576 Node* const context = NodeProperties::GetContextInput(node); 1572 Node* const context = NodeProperties::GetContextInput(node);
1577 Node* effect = NodeProperties::GetEffectInput(node); 1573 Node* effect = NodeProperties::GetEffectInput(node);
1578 // TODO(mstarzinger): Duplicate parameters are not handled yet. 1574 // TODO(mstarzinger): Duplicate parameters are not handled yet.
1579 if (shared->has_duplicate_parameters()) return NoChange(); 1575 if (shared->has_duplicate_parameters()) return NoChange();
1580 // Choose the correct frame state and frame state info depending on 1576 // Choose the correct frame state and frame state info depending on
1581 // whether there conceptually is an arguments adaptor frame in the call 1577 // whether there conceptually is an arguments adaptor frame in the call
(...skipping 21 matching lines...) Expand all
1603 STATIC_ASSERT(Heap::kSloppyArgumentsObjectSize == 5 * kPointerSize); 1599 STATIC_ASSERT(Heap::kSloppyArgumentsObjectSize == 5 * kPointerSize);
1604 a.Allocate(Heap::kSloppyArgumentsObjectSize); 1600 a.Allocate(Heap::kSloppyArgumentsObjectSize);
1605 a.Store(AccessBuilder::ForMap(), load_arguments_map); 1601 a.Store(AccessBuilder::ForMap(), load_arguments_map);
1606 a.Store(AccessBuilder::ForJSObjectProperties(), properties); 1602 a.Store(AccessBuilder::ForJSObjectProperties(), properties);
1607 a.Store(AccessBuilder::ForJSObjectElements(), elements); 1603 a.Store(AccessBuilder::ForJSObjectElements(), elements);
1608 a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length)); 1604 a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length));
1609 a.Store(AccessBuilder::ForArgumentsCallee(), callee); 1605 a.Store(AccessBuilder::ForArgumentsCallee(), callee);
1610 RelaxControls(node); 1606 RelaxControls(node);
1611 a.FinishAndChange(node); 1607 a.FinishAndChange(node);
1612 return Changed(node); 1608 return Changed(node);
1613 } else if (p.type() == CreateArgumentsParameters::kUnmappedArguments) { 1609 } else if (type == CreateArgumentsType::kUnmappedArguments) {
1614 // Use inline allocation for all unmapped arguments objects within inlined 1610 // Use inline allocation for all unmapped arguments objects within inlined
1615 // (i.e. non-outermost) frames, independent of the object size. 1611 // (i.e. non-outermost) frames, independent of the object size.
1616 Node* const control = NodeProperties::GetControlInput(node); 1612 Node* const control = NodeProperties::GetControlInput(node);
1617 Node* const context = NodeProperties::GetContextInput(node); 1613 Node* const context = NodeProperties::GetContextInput(node);
1618 Node* effect = NodeProperties::GetEffectInput(node); 1614 Node* effect = NodeProperties::GetEffectInput(node);
1619 // Choose the correct frame state and frame state info depending on 1615 // Choose the correct frame state and frame state info depending on
1620 // whether there conceptually is an arguments adaptor frame in the call 1616 // whether there conceptually is an arguments adaptor frame in the call
1621 // chain. 1617 // chain.
1622 Node* const args_state = GetArgumentsFrameState(frame_state); 1618 Node* const args_state = GetArgumentsFrameState(frame_state);
1623 FrameStateInfo args_state_info = OpParameter<FrameStateInfo>(args_state); 1619 FrameStateInfo args_state_info = OpParameter<FrameStateInfo>(args_state);
(...skipping 14 matching lines...) Expand all
1638 int length = args_state_info.parameter_count() - 1; // Minus receiver. 1634 int length = args_state_info.parameter_count() - 1; // Minus receiver.
1639 STATIC_ASSERT(Heap::kStrictArgumentsObjectSize == 4 * kPointerSize); 1635 STATIC_ASSERT(Heap::kStrictArgumentsObjectSize == 4 * kPointerSize);
1640 a.Allocate(Heap::kStrictArgumentsObjectSize); 1636 a.Allocate(Heap::kStrictArgumentsObjectSize);
1641 a.Store(AccessBuilder::ForMap(), load_arguments_map); 1637 a.Store(AccessBuilder::ForMap(), load_arguments_map);
1642 a.Store(AccessBuilder::ForJSObjectProperties(), properties); 1638 a.Store(AccessBuilder::ForJSObjectProperties(), properties);
1643 a.Store(AccessBuilder::ForJSObjectElements(), elements); 1639 a.Store(AccessBuilder::ForJSObjectElements(), elements);
1644 a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length)); 1640 a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length));
1645 RelaxControls(node); 1641 RelaxControls(node);
1646 a.FinishAndChange(node); 1642 a.FinishAndChange(node);
1647 return Changed(node); 1643 return Changed(node);
1648 } else if (p.type() == CreateArgumentsParameters::kRestArray) { 1644 } else if (type == CreateArgumentsType::kRestParameter) {
1645 Handle<SharedFunctionInfo> shared;
1646 if (!state_info.shared_info().ToHandle(&shared)) return NoChange();
1647 int start_index = shared->internal_formal_parameter_count();
1649 // Use inline allocation for all unmapped arguments objects within inlined 1648 // Use inline allocation for all unmapped arguments objects within inlined
1650 // (i.e. non-outermost) frames, independent of the object size. 1649 // (i.e. non-outermost) frames, independent of the object size.
1651 Node* const control = NodeProperties::GetControlInput(node); 1650 Node* const control = NodeProperties::GetControlInput(node);
1652 Node* const context = NodeProperties::GetContextInput(node); 1651 Node* const context = NodeProperties::GetContextInput(node);
1653 Node* effect = NodeProperties::GetEffectInput(node); 1652 Node* effect = NodeProperties::GetEffectInput(node);
1654 // Choose the correct frame state and frame state info depending on 1653 // Choose the correct frame state and frame state info depending on
1655 // whether there conceptually is an arguments adaptor frame in the call 1654 // whether there conceptually is an arguments adaptor frame in the call
1656 // chain. 1655 // chain.
1657 Node* const args_state = GetArgumentsFrameState(frame_state); 1656 Node* const args_state = GetArgumentsFrameState(frame_state);
1658 FrameStateInfo args_state_info = OpParameter<FrameStateInfo>(args_state); 1657 FrameStateInfo args_state_info = OpParameter<FrameStateInfo>(args_state);
1659 // Prepare element backing store to be used by the rest array. 1658 // Prepare element backing store to be used by the rest array.
1660 Node* const elements = 1659 Node* const elements =
1661 AllocateRestArguments(effect, control, args_state, p.start_index()); 1660 AllocateRestArguments(effect, control, args_state, start_index);
1662 effect = elements->op()->EffectOutputCount() > 0 ? elements : effect; 1661 effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
1663 // Load the JSArray object map from the current native context. 1662 // Load the JSArray object map from the current native context.
1664 Node* const load_native_context = effect = graph()->NewNode( 1663 Node* const load_native_context = effect = graph()->NewNode(
1665 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true), 1664 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
1666 context, context, effect); 1665 context, context, effect);
1667 Node* const load_jsarray_map = effect = graph()->NewNode( 1666 Node* const load_jsarray_map = effect = graph()->NewNode(
1668 simplified()->LoadField(AccessBuilder::ForContextSlot( 1667 simplified()->LoadField(AccessBuilder::ForContextSlot(
1669 Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX)), 1668 Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX)),
1670 load_native_context, effect, control); 1669 load_native_context, effect, control);
1671 // Actually allocate and initialize the jsarray. 1670 // Actually allocate and initialize the jsarray.
1672 AllocationBuilder a(jsgraph(), effect, control); 1671 AllocationBuilder a(jsgraph(), effect, control);
1673 Node* properties = jsgraph()->EmptyFixedArrayConstant(); 1672 Node* properties = jsgraph()->EmptyFixedArrayConstant();
1674 1673
1675 // -1 to minus receiver 1674 // -1 to minus receiver
1676 int argument_count = args_state_info.parameter_count() - 1; 1675 int argument_count = args_state_info.parameter_count() - 1;
1677 int length = std::max(0, argument_count - p.start_index()); 1676 int length = std::max(0, argument_count - start_index);
1678 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); 1677 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize);
1679 a.Allocate(JSArray::kSize); 1678 a.Allocate(JSArray::kSize);
1680 a.Store(AccessBuilder::ForMap(), load_jsarray_map); 1679 a.Store(AccessBuilder::ForMap(), load_jsarray_map);
1681 a.Store(AccessBuilder::ForJSObjectProperties(), properties); 1680 a.Store(AccessBuilder::ForJSObjectProperties(), properties);
1682 a.Store(AccessBuilder::ForJSObjectElements(), elements); 1681 a.Store(AccessBuilder::ForJSObjectElements(), elements);
1683 a.Store(AccessBuilder::ForJSArrayLength(FAST_ELEMENTS), 1682 a.Store(AccessBuilder::ForJSArrayLength(FAST_ELEMENTS),
1684 jsgraph()->Constant(length)); 1683 jsgraph()->Constant(length));
1685 RelaxControls(node); 1684 RelaxControls(node);
1686 a.FinishAndChange(node); 1685 a.FinishAndChange(node);
1687 return Changed(node); 1686 return Changed(node);
(...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after
2518 } 2517 }
2519 2518
2520 2519
2521 CompilationDependencies* JSTypedLowering::dependencies() const { 2520 CompilationDependencies* JSTypedLowering::dependencies() const {
2522 return dependencies_; 2521 return dependencies_;
2523 } 2522 }
2524 2523
2525 } // namespace compiler 2524 } // namespace compiler
2526 } // namespace internal 2525 } // namespace internal
2527 } // namespace v8 2526 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698