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/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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |