| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cpu.h" | 8 #include "vm/cpu.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flow_graph_allocator.h" | 10 #include "vm/flow_graph_allocator.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 DEFINE_FLAG(bool, two_args_smi_icd, true, | 31 DEFINE_FLAG(bool, two_args_smi_icd, true, |
| 32 "Generate special IC stubs for two args Smi operations"); | 32 "Generate special IC stubs for two args Smi operations"); |
| 33 DEFINE_FLAG(bool, unbox_numeric_fields, true, | 33 DEFINE_FLAG(bool, unbox_numeric_fields, true, |
| 34 "Support unboxed double and float32x4 fields."); | 34 "Support unboxed double and float32x4 fields."); |
| 35 DECLARE_FLAG(bool, enable_type_checks); | 35 DECLARE_FLAG(bool, enable_type_checks); |
| 36 DECLARE_FLAG(bool, eliminate_type_checks); | 36 DECLARE_FLAG(bool, eliminate_type_checks); |
| 37 DECLARE_FLAG(bool, trace_optimization); | 37 DECLARE_FLAG(bool, trace_optimization); |
| 38 DECLARE_FLAG(bool, trace_constant_propagation); | 38 DECLARE_FLAG(bool, trace_constant_propagation); |
| 39 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 39 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
| 40 | 40 |
| 41 Definition::Definition() | 41 Definition::Definition(intptr_t deopt_id) |
| 42 : range_(NULL), | 42 : Instruction(deopt_id), |
| 43 range_(NULL), |
| 43 type_(NULL), | 44 type_(NULL), |
| 44 temp_index_(-1), | 45 temp_index_(-1), |
| 45 ssa_temp_index_(-1), | 46 ssa_temp_index_(-1), |
| 46 input_use_list_(NULL), | 47 input_use_list_(NULL), |
| 47 env_use_list_(NULL), | 48 env_use_list_(NULL), |
| 48 constant_value_(Object::ZoneHandle(ConstantPropagator::Unknown())) { | 49 constant_value_(Object::ZoneHandle(ConstantPropagator::Unknown())) { |
| 49 } | 50 } |
| 50 | 51 |
| 51 | 52 |
| 52 Definition* Definition::OriginalDefinition() { | 53 Definition* Definition::OriginalDefinition() { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 | 102 |
| 102 static int LowestFirst(const intptr_t* a, const intptr_t* b) { | 103 static int LowestFirst(const intptr_t* a, const intptr_t* b) { |
| 103 return *a - *b; | 104 return *a - *b; |
| 104 } | 105 } |
| 105 | 106 |
| 106 | 107 |
| 107 CheckClassInstr::CheckClassInstr(Value* value, | 108 CheckClassInstr::CheckClassInstr(Value* value, |
| 108 intptr_t deopt_id, | 109 intptr_t deopt_id, |
| 109 const ICData& unary_checks, | 110 const ICData& unary_checks, |
| 110 intptr_t token_pos) | 111 intptr_t token_pos) |
| 111 : unary_checks_(unary_checks), | 112 : TemplateInstruction<1>(deopt_id), |
| 113 unary_checks_(unary_checks), |
| 112 cids_(unary_checks.NumberOfChecks()), | 114 cids_(unary_checks.NumberOfChecks()), |
| 113 licm_hoisted_(false), | 115 licm_hoisted_(false), |
| 114 token_pos_(token_pos) { | 116 token_pos_(token_pos) { |
| 115 ASSERT(unary_checks.IsZoneHandle()); | 117 ASSERT(unary_checks.IsZoneHandle()); |
| 116 // Expected useful check data. | 118 // Expected useful check data. |
| 117 ASSERT(!unary_checks_.IsNull()); | 119 ASSERT(!unary_checks_.IsNull()); |
| 118 ASSERT(unary_checks_.NumberOfChecks() > 0); | 120 ASSERT(unary_checks_.NumberOfChecks() > 0); |
| 119 ASSERT(unary_checks_.NumArgsTested() == 1); | 121 ASSERT(unary_checks_.NumArgsTested() == 1); |
| 120 SetInputAt(0, value); | 122 SetInputAt(0, value); |
| 121 deopt_id_ = deopt_id; | |
| 122 // Otherwise use CheckSmiInstr. | 123 // Otherwise use CheckSmiInstr. |
| 123 ASSERT((unary_checks_.NumberOfChecks() != 1) || | 124 ASSERT((unary_checks_.NumberOfChecks() != 1) || |
| 124 (unary_checks_.GetReceiverClassIdAt(0) != kSmiCid)); | 125 (unary_checks_.GetReceiverClassIdAt(0) != kSmiCid)); |
| 125 for (intptr_t i = 0; i < unary_checks.NumberOfChecks(); ++i) { | 126 for (intptr_t i = 0; i < unary_checks.NumberOfChecks(); ++i) { |
| 126 cids_.Add(unary_checks.GetReceiverClassIdAt(i)); | 127 cids_.Add(unary_checks.GetReceiverClassIdAt(i)); |
| 127 } | 128 } |
| 128 cids_.Sort(LowestFirst); | 129 cids_.Sort(LowestFirst); |
| 129 } | 130 } |
| 130 | 131 |
| 131 | 132 |
| (...skipping 1482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1614 } else if (rhs == 0) { | 1615 } else if (rhs == 0) { |
| 1615 return right()->definition(); | 1616 return right()->definition(); |
| 1616 } else if (rhs == 2) { | 1617 } else if (rhs == 2) { |
| 1617 ConstantInstr* constant_1 = | 1618 ConstantInstr* constant_1 = |
| 1618 flow_graph->GetConstant(Smi::Handle(Smi::New(1))); | 1619 flow_graph->GetConstant(Smi::Handle(Smi::New(1))); |
| 1619 BinaryIntegerOpInstr* shift = | 1620 BinaryIntegerOpInstr* shift = |
| 1620 BinaryIntegerOpInstr::Make(representation(), | 1621 BinaryIntegerOpInstr::Make(representation(), |
| 1621 Token::kSHL, | 1622 Token::kSHL, |
| 1622 left()->CopyWithType(), | 1623 left()->CopyWithType(), |
| 1623 new Value(constant_1), | 1624 new Value(constant_1), |
| 1624 deopt_id_, | 1625 GetDeoptId(), |
| 1625 can_overflow(), | 1626 can_overflow(), |
| 1626 is_truncating(), | 1627 is_truncating(), |
| 1627 range()); | 1628 range()); |
| 1628 if (shift != NULL) { | 1629 if (shift != NULL) { |
| 1629 flow_graph->InsertBefore(this, shift, env(), FlowGraph::kValue); | 1630 flow_graph->InsertBefore(this, shift, env(), FlowGraph::kValue); |
| 1630 return shift; | 1631 return shift; |
| 1631 } | 1632 } |
| 1632 } | 1633 } |
| 1633 | 1634 |
| 1634 break; | 1635 break; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1652 } | 1653 } |
| 1653 break; | 1654 break; |
| 1654 case Token::kBIT_XOR: | 1655 case Token::kBIT_XOR: |
| 1655 if (rhs == 0) { | 1656 if (rhs == 0) { |
| 1656 return left()->definition(); | 1657 return left()->definition(); |
| 1657 } else if (rhs == range_mask) { | 1658 } else if (rhs == range_mask) { |
| 1658 UnaryIntegerOpInstr* bit_not = | 1659 UnaryIntegerOpInstr* bit_not = |
| 1659 UnaryIntegerOpInstr::Make(representation(), | 1660 UnaryIntegerOpInstr::Make(representation(), |
| 1660 Token::kBIT_NOT, | 1661 Token::kBIT_NOT, |
| 1661 left()->CopyWithType(), | 1662 left()->CopyWithType(), |
| 1662 deopt_id_, | 1663 GetDeoptId(), |
| 1663 range()); | 1664 range()); |
| 1664 if (bit_not != NULL) { | 1665 if (bit_not != NULL) { |
| 1665 flow_graph->InsertBefore(this, bit_not, env(), FlowGraph::kValue); | 1666 flow_graph->InsertBefore(this, bit_not, env(), FlowGraph::kValue); |
| 1666 return bit_not; | 1667 return bit_not; |
| 1667 } | 1668 } |
| 1668 } | 1669 } |
| 1669 break; | 1670 break; |
| 1670 | 1671 |
| 1671 case Token::kSUB: | 1672 case Token::kSUB: |
| 1672 if (rhs == 0) { | 1673 if (rhs == 0) { |
| 1673 return left()->definition(); | 1674 return left()->definition(); |
| 1674 } | 1675 } |
| 1675 break; | 1676 break; |
| 1676 | 1677 |
| 1677 case Token::kTRUNCDIV: | 1678 case Token::kTRUNCDIV: |
| 1678 if (rhs == 1) { | 1679 if (rhs == 1) { |
| 1679 return left()->definition(); | 1680 return left()->definition(); |
| 1680 } else if (rhs == -1) { | 1681 } else if (rhs == -1) { |
| 1681 UnaryIntegerOpInstr* negation = | 1682 UnaryIntegerOpInstr* negation = |
| 1682 UnaryIntegerOpInstr::Make(representation(), | 1683 UnaryIntegerOpInstr::Make(representation(), |
| 1683 Token::kNEGATE, | 1684 Token::kNEGATE, |
| 1684 left()->CopyWithType(), | 1685 left()->CopyWithType(), |
| 1685 deopt_id_, | 1686 GetDeoptId(), |
| 1686 range()); | 1687 range()); |
| 1687 if (negation != NULL) { | 1688 if (negation != NULL) { |
| 1688 flow_graph->InsertBefore(this, negation, env(), FlowGraph::kValue); | 1689 flow_graph->InsertBefore(this, negation, env(), FlowGraph::kValue); |
| 1689 return negation; | 1690 return negation; |
| 1690 } | 1691 } |
| 1691 } | 1692 } |
| 1692 break; | 1693 break; |
| 1693 | 1694 |
| 1694 case Token::kSHR: | 1695 case Token::kSHR: |
| 1695 if (rhs == 0) { | 1696 if (rhs == 0) { |
| 1696 return left()->definition(); | 1697 return left()->definition(); |
| 1697 } else if (rhs < 0) { | 1698 } else if (rhs < 0) { |
| 1698 DeoptimizeInstr* deopt = | 1699 DeoptimizeInstr* deopt = |
| 1699 new DeoptimizeInstr(ICData::kDeoptBinarySmiOp, deopt_id_); | 1700 new DeoptimizeInstr(ICData::kDeoptBinarySmiOp, GetDeoptId()); |
| 1700 flow_graph->InsertBefore(this, deopt, env(), FlowGraph::kEffect); | 1701 flow_graph->InsertBefore(this, deopt, env(), FlowGraph::kEffect); |
| 1701 return flow_graph->GetConstant(Smi::Handle(Smi::New(0))); | 1702 return flow_graph->GetConstant(Smi::Handle(Smi::New(0))); |
| 1702 } | 1703 } |
| 1703 break; | 1704 break; |
| 1704 | 1705 |
| 1705 case Token::kSHL: { | 1706 case Token::kSHL: { |
| 1706 const intptr_t kMaxShift = RepresentationBits(representation()) - 1; | 1707 const intptr_t kMaxShift = RepresentationBits(representation()) - 1; |
| 1707 if (rhs == 0) { | 1708 if (rhs == 0) { |
| 1708 return left()->definition(); | 1709 return left()->definition(); |
| 1709 } else if ((rhs < 0) || (rhs >= kMaxShift)) { | 1710 } else if ((rhs < 0) || (rhs >= kMaxShift)) { |
| 1710 if ((rhs < 0) || !is_truncating()) { | 1711 if ((rhs < 0) || !is_truncating()) { |
| 1711 DeoptimizeInstr* deopt = | 1712 DeoptimizeInstr* deopt = |
| 1712 new DeoptimizeInstr(ICData::kDeoptBinarySmiOp, deopt_id_); | 1713 new DeoptimizeInstr(ICData::kDeoptBinarySmiOp, GetDeoptId()); |
| 1713 flow_graph->InsertBefore(this, deopt, env(), FlowGraph::kEffect); | 1714 flow_graph->InsertBefore(this, deopt, env(), FlowGraph::kEffect); |
| 1714 } | 1715 } |
| 1715 return flow_graph->GetConstant(Smi::Handle(Smi::New(0))); | 1716 return flow_graph->GetConstant(Smi::Handle(Smi::New(0))); |
| 1716 } | 1717 } |
| 1717 break; | 1718 break; |
| 1718 } | 1719 } |
| 1719 | 1720 |
| 1720 default: | 1721 default: |
| 1721 break; | 1722 break; |
| 1722 } | 1723 } |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1953 BoxIntNInstr* box_defn = value()->definition()->AsBoxIntN(); | 1954 BoxIntNInstr* box_defn = value()->definition()->AsBoxIntN(); |
| 1954 if (box_defn != NULL) { | 1955 if (box_defn != NULL) { |
| 1955 if (box_defn->value()->definition()->representation() == representation()) { | 1956 if (box_defn->value()->definition()->representation() == representation()) { |
| 1956 return box_defn->value()->definition(); | 1957 return box_defn->value()->definition(); |
| 1957 } else { | 1958 } else { |
| 1958 UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr( | 1959 UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr( |
| 1959 box_defn->value()->definition()->representation(), | 1960 box_defn->value()->definition()->representation(), |
| 1960 representation(), | 1961 representation(), |
| 1961 box_defn->value()->CopyWithType(), | 1962 box_defn->value()->CopyWithType(), |
| 1962 (representation() == kUnboxedInt32) ? | 1963 (representation() == kUnboxedInt32) ? |
| 1963 deopt_id_ : Isolate::kNoDeoptId); | 1964 GetDeoptId() : Isolate::kNoDeoptId); |
| 1964 if ((representation() == kUnboxedInt32) && is_truncating()) { | 1965 if ((representation() == kUnboxedInt32) && is_truncating()) { |
| 1965 converter->mark_truncating(); | 1966 converter->mark_truncating(); |
| 1966 } | 1967 } |
| 1967 flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue); | 1968 flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue); |
| 1968 return converter; | 1969 return converter; |
| 1969 } | 1970 } |
| 1970 } | 1971 } |
| 1971 | 1972 |
| 1972 return this; | 1973 return this; |
| 1973 } | 1974 } |
| 1974 | 1975 |
| 1975 | 1976 |
| 1976 Definition* UnboxedIntConverterInstr::Canonicalize(FlowGraph* flow_graph) { | 1977 Definition* UnboxedIntConverterInstr::Canonicalize(FlowGraph* flow_graph) { |
| 1977 if (!HasUses()) return NULL; | 1978 if (!HasUses()) return NULL; |
| 1978 | 1979 |
| 1979 UnboxedIntConverterInstr* box_defn = | 1980 UnboxedIntConverterInstr* box_defn = |
| 1980 value()->definition()->AsUnboxedIntConverter(); | 1981 value()->definition()->AsUnboxedIntConverter(); |
| 1981 if ((box_defn != NULL) && (box_defn->representation() == from())) { | 1982 if ((box_defn != NULL) && (box_defn->representation() == from())) { |
| 1982 if (box_defn->from() == to()) { | 1983 if (box_defn->from() == to()) { |
| 1983 return box_defn->value()->definition(); | 1984 return box_defn->value()->definition(); |
| 1984 } | 1985 } |
| 1985 | 1986 |
| 1986 UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr( | 1987 UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr( |
| 1987 box_defn->from(), | 1988 box_defn->from(), |
| 1988 representation(), | 1989 representation(), |
| 1989 box_defn->value()->CopyWithType(), | 1990 box_defn->value()->CopyWithType(), |
| 1990 (to() == kUnboxedInt32) ? deopt_id_ : Isolate::kNoDeoptId); | 1991 (to() == kUnboxedInt32) ? GetDeoptId() : Isolate::kNoDeoptId); |
| 1991 if ((representation() == kUnboxedInt32) && is_truncating()) { | 1992 if ((representation() == kUnboxedInt32) && is_truncating()) { |
| 1992 converter->mark_truncating(); | 1993 converter->mark_truncating(); |
| 1993 } | 1994 } |
| 1994 flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue); | 1995 flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue); |
| 1995 return converter; | 1996 return converter; |
| 1996 } | 1997 } |
| 1997 | 1998 |
| 1998 UnboxIntegerInstr* unbox_defn = value()->definition()->AsUnboxInteger(); | 1999 UnboxIntegerInstr* unbox_defn = value()->definition()->AsUnboxInteger(); |
| 1999 if (unbox_defn != NULL && | 2000 if (unbox_defn != NULL && |
| 2000 (from() == kUnboxedMint) && | 2001 (from() == kUnboxedMint) && |
| 2001 (to() == kUnboxedInt32) && | 2002 (to() == kUnboxedInt32) && |
| 2002 unbox_defn->HasOnlyInputUse(value())) { | 2003 unbox_defn->HasOnlyInputUse(value())) { |
| 2003 // TODO(vegorov): there is a duplication of code between UnboxedIntCoverter | 2004 // TODO(vegorov): there is a duplication of code between UnboxedIntCoverter |
| 2004 // and code path that unboxes Mint into Int32. We should just schedule | 2005 // and code path that unboxes Mint into Int32. We should just schedule |
| 2005 // these instructions close to each other instead of fusing them. | 2006 // these instructions close to each other instead of fusing them. |
| 2006 Definition* replacement = | 2007 Definition* replacement = |
| 2007 new UnboxInt32Instr(unbox_defn->value()->CopyWithType(), deopt_id_); | 2008 new UnboxInt32Instr(unbox_defn->value()->CopyWithType(), GetDeoptId()); |
| 2008 if (is_truncating()) { | 2009 if (is_truncating()) { |
| 2009 replacement->AsUnboxInt32()->mark_truncating(); | 2010 replacement->AsUnboxInt32()->mark_truncating(); |
| 2010 } | 2011 } |
| 2011 flow_graph->InsertBefore(this, | 2012 flow_graph->InsertBefore(this, |
| 2012 replacement, | 2013 replacement, |
| 2013 env(), | 2014 env(), |
| 2014 FlowGraph::kValue); | 2015 FlowGraph::kValue); |
| 2015 return replacement; | 2016 return replacement; |
| 2016 } | 2017 } |
| 2017 | 2018 |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2488 bool optimizing) const { | 2489 bool optimizing) const { |
| 2489 UNREACHABLE(); | 2490 UNREACHABLE(); |
| 2490 return NULL; | 2491 return NULL; |
| 2491 } | 2492 } |
| 2492 | 2493 |
| 2493 | 2494 |
| 2494 void JoinEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2495 void JoinEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2495 __ Bind(compiler->GetJumpLabel(this)); | 2496 __ Bind(compiler->GetJumpLabel(this)); |
| 2496 if (!compiler->is_optimizing()) { | 2497 if (!compiler->is_optimizing()) { |
| 2497 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, | 2498 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, |
| 2498 deopt_id_, | 2499 GetDeoptId(), |
| 2499 Scanner::kNoSourcePos); | 2500 Scanner::kNoSourcePos); |
| 2500 } | 2501 } |
| 2501 if (HasParallelMove()) { | 2502 if (HasParallelMove()) { |
| 2502 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | 2503 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
| 2503 } | 2504 } |
| 2504 } | 2505 } |
| 2505 | 2506 |
| 2506 | 2507 |
| 2507 LocationSummary* TargetEntryInstr::MakeLocationSummary(Isolate* isolate, | 2508 LocationSummary* TargetEntryInstr::MakeLocationSummary(Isolate* isolate, |
| 2508 bool optimizing) const { | 2509 bool optimizing) const { |
| 2509 UNREACHABLE(); | 2510 UNREACHABLE(); |
| 2510 return NULL; | 2511 return NULL; |
| 2511 } | 2512 } |
| 2512 | 2513 |
| 2513 | 2514 |
| 2514 void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2515 void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2515 __ Bind(compiler->GetJumpLabel(this)); | 2516 __ Bind(compiler->GetJumpLabel(this)); |
| 2516 if (!compiler->is_optimizing()) { | 2517 if (!compiler->is_optimizing()) { |
| 2517 if (compiler->NeedsEdgeCounter(this)) { | 2518 if (compiler->NeedsEdgeCounter(this)) { |
| 2518 compiler->EmitEdgeCounter(); | 2519 compiler->EmitEdgeCounter(); |
| 2519 } | 2520 } |
| 2520 // The deoptimization descriptor points after the edge counter code for | 2521 // The deoptimization descriptor points after the edge counter code for |
| 2521 // uniformity with ARM and MIPS, where we can reuse pattern matching | 2522 // uniformity with ARM and MIPS, where we can reuse pattern matching |
| 2522 // code that matches backwards from the end of the pattern. | 2523 // code that matches backwards from the end of the pattern. |
| 2523 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, | 2524 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, |
| 2524 deopt_id_, | 2525 GetDeoptId(), |
| 2525 Scanner::kNoSourcePos); | 2526 Scanner::kNoSourcePos); |
| 2526 } | 2527 } |
| 2527 if (HasParallelMove()) { | 2528 if (HasParallelMove()) { |
| 2528 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | 2529 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
| 2529 } | 2530 } |
| 2530 } | 2531 } |
| 2531 | 2532 |
| 2532 | 2533 |
| 2533 LocationSummary* PhiInstr::MakeLocationSummary(Isolate* isolate, | 2534 LocationSummary* PhiInstr::MakeLocationSummary(Isolate* isolate, |
| 2534 bool optimizing) const { | 2535 bool optimizing) const { |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2720 ASSERT((InputCount() == 0) || (locs()->out(0).reg() == locs()->in(0).reg())); | 2721 ASSERT((InputCount() == 0) || (locs()->out(0).reg() == locs()->in(0).reg())); |
| 2721 __ Drop(num_temps()); | 2722 __ Drop(num_temps()); |
| 2722 } | 2723 } |
| 2723 | 2724 |
| 2724 | 2725 |
| 2725 StrictCompareInstr::StrictCompareInstr(intptr_t token_pos, | 2726 StrictCompareInstr::StrictCompareInstr(intptr_t token_pos, |
| 2726 Token::Kind kind, | 2727 Token::Kind kind, |
| 2727 Value* left, | 2728 Value* left, |
| 2728 Value* right, | 2729 Value* right, |
| 2729 bool needs_number_check) | 2730 bool needs_number_check) |
| 2730 : ComparisonInstr(token_pos, kind, left, right), | 2731 : ComparisonInstr(token_pos, |
| 2732 kind, |
| 2733 left, |
| 2734 right, |
| 2735 Isolate::Current()->GetNextDeoptId()), |
| 2731 needs_number_check_(needs_number_check) { | 2736 needs_number_check_(needs_number_check) { |
| 2732 deopt_id_ = Isolate::Current()->GetNextDeoptId(); | |
| 2733 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT)); | 2737 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT)); |
| 2734 } | 2738 } |
| 2735 | 2739 |
| 2736 | 2740 |
| 2737 LocationSummary* InstanceCallInstr::MakeLocationSummary(Isolate* isolate, | 2741 LocationSummary* InstanceCallInstr::MakeLocationSummary(Isolate* isolate, |
| 2738 bool optimizing) const { | 2742 bool optimizing) const { |
| 2739 return MakeCallSummary(); | 2743 return MakeCallSummary(); |
| 2740 } | 2744 } |
| 2741 | 2745 |
| 2742 | 2746 |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3209 } | 3213 } |
| 3210 ASSERT(result.IsString()); | 3214 ASSERT(result.IsString()); |
| 3211 const String& concatenated = | 3215 const String& concatenated = |
| 3212 String::ZoneHandle(Symbols::New(String::Cast(result))); | 3216 String::ZoneHandle(Symbols::New(String::Cast(result))); |
| 3213 return flow_graph->GetConstant(concatenated); | 3217 return flow_graph->GetConstant(concatenated); |
| 3214 } | 3218 } |
| 3215 | 3219 |
| 3216 | 3220 |
| 3217 InvokeMathCFunctionInstr::InvokeMathCFunctionInstr( | 3221 InvokeMathCFunctionInstr::InvokeMathCFunctionInstr( |
| 3218 ZoneGrowableArray<Value*>* inputs, | 3222 ZoneGrowableArray<Value*>* inputs, |
| 3219 intptr_t original_deopt_id, | 3223 intptr_t deopt_id, |
| 3220 MethodRecognizer::Kind recognized_kind, | 3224 MethodRecognizer::Kind recognized_kind, |
| 3221 intptr_t token_pos) | 3225 intptr_t token_pos) |
| 3222 : inputs_(inputs), | 3226 : Definition(deopt_id), |
| 3227 inputs_(inputs), |
| 3223 recognized_kind_(recognized_kind), | 3228 recognized_kind_(recognized_kind), |
| 3224 token_pos_(token_pos) { | 3229 token_pos_(token_pos) { |
| 3225 ASSERT(inputs_->length() == ArgumentCountFor(recognized_kind_)); | 3230 ASSERT(inputs_->length() == ArgumentCountFor(recognized_kind_)); |
| 3226 for (intptr_t i = 0; i < inputs_->length(); ++i) { | 3231 for (intptr_t i = 0; i < inputs_->length(); ++i) { |
| 3227 ASSERT((*inputs)[i] != NULL); | 3232 ASSERT((*inputs)[i] != NULL); |
| 3228 (*inputs)[i]->set_instruction(this); | 3233 (*inputs)[i]->set_instruction(this); |
| 3229 (*inputs)[i]->set_use_index(i); | 3234 (*inputs)[i]->set_use_index(i); |
| 3230 } | 3235 } |
| 3231 deopt_id_ = original_deopt_id; | |
| 3232 } | 3236 } |
| 3233 | 3237 |
| 3234 | 3238 |
| 3235 intptr_t InvokeMathCFunctionInstr::ArgumentCountFor( | 3239 intptr_t InvokeMathCFunctionInstr::ArgumentCountFor( |
| 3236 MethodRecognizer::Kind kind) { | 3240 MethodRecognizer::Kind kind) { |
| 3237 switch (kind) { | 3241 switch (kind) { |
| 3238 case MethodRecognizer::kDoubleTruncate: | 3242 case MethodRecognizer::kDoubleTruncate: |
| 3239 case MethodRecognizer::kDoubleFloor: | 3243 case MethodRecognizer::kDoubleFloor: |
| 3240 case MethodRecognizer::kDoubleCeil: { | 3244 case MethodRecognizer::kDoubleCeil: { |
| 3241 ASSERT(!TargetCPUFeatures::double_truncate_round_supported()); | 3245 ASSERT(!TargetCPUFeatures::double_truncate_round_supported()); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3331 case kCos: return "cos"; | 3335 case kCos: return "cos"; |
| 3332 case kSqrt: return "sqrt"; | 3336 case kSqrt: return "sqrt"; |
| 3333 case kDoubleSquare: return "double-square"; | 3337 case kDoubleSquare: return "double-square"; |
| 3334 } | 3338 } |
| 3335 UNREACHABLE(); | 3339 UNREACHABLE(); |
| 3336 return ""; | 3340 return ""; |
| 3337 } | 3341 } |
| 3338 | 3342 |
| 3339 | 3343 |
| 3340 MergedMathInstr::MergedMathInstr(ZoneGrowableArray<Value*>* inputs, | 3344 MergedMathInstr::MergedMathInstr(ZoneGrowableArray<Value*>* inputs, |
| 3341 intptr_t original_deopt_id, | 3345 intptr_t deopt_id, |
| 3342 MergedMathInstr::Kind kind) | 3346 MergedMathInstr::Kind kind) |
| 3343 : inputs_(inputs), | 3347 : Definition(deopt_id), |
| 3348 inputs_(inputs), |
| 3344 kind_(kind) { | 3349 kind_(kind) { |
| 3345 ASSERT(inputs_->length() == InputCountFor(kind_)); | 3350 ASSERT(inputs_->length() == InputCountFor(kind_)); |
| 3346 for (intptr_t i = 0; i < inputs_->length(); ++i) { | 3351 for (intptr_t i = 0; i < inputs_->length(); ++i) { |
| 3347 ASSERT((*inputs)[i] != NULL); | 3352 ASSERT((*inputs)[i] != NULL); |
| 3348 (*inputs)[i]->set_instruction(this); | 3353 (*inputs)[i]->set_instruction(this); |
| 3349 (*inputs)[i]->set_use_index(i); | 3354 (*inputs)[i]->set_use_index(i); |
| 3350 } | 3355 } |
| 3351 deopt_id_ = original_deopt_id; | |
| 3352 } | 3356 } |
| 3353 | 3357 |
| 3354 | 3358 |
| 3355 intptr_t MergedMathInstr::OutputIndexOf(intptr_t kind) { | 3359 intptr_t MergedMathInstr::OutputIndexOf(intptr_t kind) { |
| 3356 switch (kind) { | 3360 switch (kind) { |
| 3357 case MethodRecognizer::kMathSin: return 1; | 3361 case MethodRecognizer::kMathSin: return 1; |
| 3358 case MethodRecognizer::kMathCos: return 0; | 3362 case MethodRecognizer::kMathCos: return 0; |
| 3359 default: UNIMPLEMENTED(); return -1; | 3363 default: UNIMPLEMENTED(); return -1; |
| 3360 } | 3364 } |
| 3361 } | 3365 } |
| 3362 | 3366 |
| 3363 | 3367 |
| 3364 intptr_t MergedMathInstr::OutputIndexOf(Token::Kind token) { | 3368 intptr_t MergedMathInstr::OutputIndexOf(Token::Kind token) { |
| 3365 switch (token) { | 3369 switch (token) { |
| 3366 case Token::kTRUNCDIV: return 0; | 3370 case Token::kTRUNCDIV: return 0; |
| 3367 case Token::kMOD: return 1; | 3371 case Token::kMOD: return 1; |
| 3368 default: UNIMPLEMENTED(); return -1; | 3372 default: UNIMPLEMENTED(); return -1; |
| 3369 } | 3373 } |
| 3370 } | 3374 } |
| 3371 | 3375 |
| 3372 | 3376 |
| 3373 #undef __ | 3377 #undef __ |
| 3374 | 3378 |
| 3375 } // namespace dart | 3379 } // namespace dart |
| OLD | NEW |