OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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/globals.h" // Needed here to get TARGET_ARCH_DBC. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_DBC. |
6 #if defined(TARGET_ARCH_DBC) | 6 #if defined(TARGET_ARCH_DBC) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
95 M(ExtractNthOutput) \ | 95 M(ExtractNthOutput) \ |
96 M(BinaryUint32Op) \ | 96 M(BinaryUint32Op) \ |
97 M(ShiftUint32Op) \ | 97 M(ShiftUint32Op) \ |
98 M(UnaryUint32Op) \ | 98 M(UnaryUint32Op) \ |
99 M(UnboxedIntConverter) \ | 99 M(UnboxedIntConverter) \ |
100 M(GrowRegExpStack) \ | 100 M(GrowRegExpStack) \ |
101 M(BoxInteger32) \ | 101 M(BoxInteger32) \ |
102 M(UnboxInteger32) \ | 102 M(UnboxInteger32) \ |
103 M(CheckedSmiOp) \ | 103 M(CheckedSmiOp) \ |
104 M(CheckArrayBound) \ | 104 M(CheckArrayBound) \ |
105 M(CheckClass) \ | |
106 M(TestSmi) \ | 105 M(TestSmi) \ |
107 M(RelationalOp) \ | 106 M(RelationalOp) \ |
108 M(EqualityCompare) \ | 107 M(EqualityCompare) \ |
109 M(LoadIndexed) | 108 M(LoadIndexed) |
110 | 109 |
111 // Location summaries actually are not used by the unoptimizing DBC compiler | 110 // Location summaries actually are not used by the unoptimizing DBC compiler |
112 // because we don't allocate any registers. | 111 // because we don't allocate any registers. |
113 static LocationSummary* CreateLocationSummary( | 112 static LocationSummary* CreateLocationSummary( |
114 Zone* zone, | 113 Zone* zone, |
115 intptr_t num_inputs, | 114 intptr_t num_inputs, |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
497 return comparison()->locs(); | 496 return comparison()->locs(); |
498 } | 497 } |
499 | 498 |
500 | 499 |
501 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 500 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
502 comparison()->EmitBranchCode(compiler, this); | 501 comparison()->EmitBranchCode(compiler, this); |
503 } | 502 } |
504 | 503 |
505 | 504 |
506 EMIT_NATIVE_CODE(Goto, 0) { | 505 EMIT_NATIVE_CODE(Goto, 0) { |
506 if (!compiler->is_optimizing()) { | |
507 // Add a deoptimization descriptor for deoptimizing instructions that | |
508 // may be inserted before this instruction. | |
509 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, | |
510 GetDeoptId(), | |
511 TokenPosition::kNoSource); | |
512 } | |
507 if (HasParallelMove()) { | 513 if (HasParallelMove()) { |
508 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | 514 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
509 } | 515 } |
510 // We can fall through if the successor is the next block in the list. | 516 // We can fall through if the successor is the next block in the list. |
511 // Otherwise, we need a jump. | 517 // Otherwise, we need a jump. |
512 if (!compiler->CanFallThroughTo(successor())) { | 518 if (!compiler->CanFallThroughTo(successor())) { |
513 __ Jump(compiler->GetJumpLabel(successor())); | 519 __ Jump(compiler->GetJumpLabel(successor())); |
514 } | 520 } |
515 } | 521 } |
516 | 522 |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
976 compiler->EmitDeopt(deopt_id(), ICData::kDeoptBinaryDoubleOp, | 982 compiler->EmitDeopt(deopt_id(), ICData::kDeoptBinaryDoubleOp, |
977 licm_hoisted_ ? ICData::kHoisted : 0); | 983 licm_hoisted_ ? ICData::kHoisted : 0); |
978 __ CheckSmi(right); | 984 __ CheckSmi(right); |
979 } | 985 } |
980 compiler->EmitDeopt(deopt_id(), ICData::kDeoptBinaryDoubleOp, | 986 compiler->EmitDeopt(deopt_id(), ICData::kDeoptBinaryDoubleOp, |
981 licm_hoisted_ ? ICData::kHoisted : 0); | 987 licm_hoisted_ ? ICData::kHoisted : 0); |
982 } | 988 } |
983 | 989 |
984 | 990 |
985 EMIT_NATIVE_CODE(CheckClassId, 1) { | 991 EMIT_NATIVE_CODE(CheckClassId, 1) { |
986 intptr_t cid = __ AddConstant(Smi::Handle(Smi::New(cid_))); | 992 if (!Utils::IsUint(16, cid_)) { |
987 __ CheckClassId(locs()->in(0).reg(), cid); | 993 #if defined(PRODUCT) |
994 compiler->Bailout("CheckClassInstr::EmitNativeCode"); | |
995 #else // defined(PRODUCT) | |
996 compiler->Bailout(ToCString()); | |
997 #endif // defined(PRODUCT) | |
998 } | |
999 __ CheckClassId(locs()->in(0).reg(), cid_); | |
988 compiler->EmitDeopt(deopt_id(), ICData::kDeoptCheckClass); | 1000 compiler->EmitDeopt(deopt_id(), ICData::kDeoptCheckClass); |
989 } | 1001 } |
990 | 1002 |
991 | 1003 |
1004 EMIT_NATIVE_CODE(CheckClass, 1) { | |
1005 #if defined(PRODUCT) | |
1006 const char* bailout_msg = "CheckClassInstr::EmitNativeCode"; | |
1007 #else // defined(PRODUCT) | |
1008 const char* bailout_msg = ToCString(); | |
1009 #endif // defined(PRODUCT) | |
1010 const Register value = locs()->in(0).reg(); | |
1011 if (IsNullCheck()) { | |
1012 ASSERT(DeoptIfNull() || DeoptIfNotNull()); | |
1013 if (DeoptIfNull()) { | |
1014 __ IfEqNull(value); | |
1015 } else { | |
1016 __ IfNeNull(value); | |
1017 } | |
1018 } else { | |
1019 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || | |
1020 (unary_checks().NumberOfChecks() > 1)); | |
1021 const intptr_t may_be_smi = | |
1022 (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) ? 1 : 0; | |
1023 if (IsDenseSwitch()) { | |
1024 ASSERT(cids_[0] < cids_[cids_.length() - 1]); | |
1025 const intptr_t low_cid = cids_[0]; | |
1026 if (!Utils::IsUint(16, low_cid)) { | |
1027 compiler->Bailout(bailout_msg); | |
1028 } | |
1029 const intptr_t cid_mask = ComputeCidMask(); | |
1030 __ CheckDenseSwitch(value, may_be_smi); | |
1031 __ Nop(low_cid); | |
1032 __ Nop(__ AddConstant(Smi::Handle(Smi::New(cid_mask)))); | |
1033 } else { | |
1034 GrowableArray<CidTarget> sorted_ic_data; | |
1035 FlowGraphCompiler::SortICDataByCount(unary_checks(), | |
1036 &sorted_ic_data, | |
1037 /* drop_smi = */ true); | |
1038 const intptr_t sorted_length = sorted_ic_data.length(); | |
1039 ASSERT(sorted_length >= 1); | |
1040 if (sorted_length == 1) { | |
1041 const intptr_t cid = sorted_ic_data[0].cid; | |
1042 if (!Utils::IsUint(16, cid)) { | |
1043 compiler->Bailout(bailout_msg); | |
1044 } | |
1045 __ CheckClassId(value, cid); | |
Vyacheslav Egorov (Google)
2016/06/30 08:04:13
I don't think this is correct if may_be_smi is tru
zra
2016/06/30 15:30:53
Okay. I'm just going to put this back to how it wa
Vyacheslav Egorov (Google)
2016/06/30 15:32:09
You can just emit CheckCids instead.
| |
1046 } else { | |
1047 if (!Utils::IsUint(8, sorted_length)) { | |
1048 compiler->Bailout(bailout_msg); | |
1049 } | |
1050 __ CheckCids(value, may_be_smi, sorted_length); | |
1051 for (intptr_t i = 0; i < sorted_length; i++) { | |
1052 const intptr_t cid = sorted_ic_data[i].cid; | |
1053 if (!Utils::IsUint(16, cid)) { | |
Vyacheslav Egorov (Google)
2016/06/30 08:04:13
This should really be a helper, e.g. on compiler
| |
1054 compiler->Bailout(bailout_msg); | |
1055 } | |
1056 __ Nop(cid); | |
1057 } | |
1058 } | |
1059 } | |
1060 } | |
1061 compiler->EmitDeopt(deopt_id(), | |
1062 ICData::kDeoptCheckClass, | |
1063 licm_hoisted_ ? ICData::kHoisted : 0); | |
1064 } | |
1065 | |
1066 | |
992 EMIT_NATIVE_CODE(BinarySmiOp, 2, Location::RequiresRegister()) { | 1067 EMIT_NATIVE_CODE(BinarySmiOp, 2, Location::RequiresRegister()) { |
993 const Register left = locs()->in(0).reg(); | 1068 const Register left = locs()->in(0).reg(); |
994 const Register right = locs()->in(1).reg(); | 1069 const Register right = locs()->in(1).reg(); |
995 const Register out = locs()->out(0).reg(); | 1070 const Register out = locs()->out(0).reg(); |
996 const bool can_deopt = CanDeoptimize(); | 1071 const bool can_deopt = CanDeoptimize(); |
997 bool needs_nop = false; | 1072 bool needs_nop = false; |
998 switch (op_kind()) { | 1073 switch (op_kind()) { |
999 case Token::kADD: | 1074 case Token::kADD: |
1000 __ Add(out, left, right); | 1075 __ Add(out, left, right); |
1001 needs_nop = true; | 1076 needs_nop = true; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1035 case Token::kSHL: | 1110 case Token::kSHL: |
1036 __ Shl(out, left, right); | 1111 __ Shl(out, left, right); |
1037 needs_nop = true; | 1112 needs_nop = true; |
1038 break; | 1113 break; |
1039 default: | 1114 default: |
1040 UNREACHABLE(); | 1115 UNREACHABLE(); |
1041 } | 1116 } |
1042 if (can_deopt) { | 1117 if (can_deopt) { |
1043 compiler->EmitDeopt(deopt_id(), ICData::kDeoptBinarySmiOp); | 1118 compiler->EmitDeopt(deopt_id(), ICData::kDeoptBinarySmiOp); |
1044 } else if (needs_nop) { | 1119 } else if (needs_nop) { |
1045 __ Nop(); | 1120 __ Nop(0); |
1046 } | 1121 } |
1047 } | 1122 } |
1048 | 1123 |
1049 | 1124 |
1050 EMIT_NATIVE_CODE(UnarySmiOp, 1, Location::RequiresRegister()) { | 1125 EMIT_NATIVE_CODE(UnarySmiOp, 1, Location::RequiresRegister()) { |
1051 switch (op_kind()) { | 1126 switch (op_kind()) { |
1052 case Token::kNEGATE: { | 1127 case Token::kNEGATE: { |
1053 __ Neg(locs()->out(0).reg(), locs()->in(0).reg()); | 1128 __ Neg(locs()->out(0).reg(), locs()->in(0).reg()); |
1054 compiler->EmitDeopt(deopt_id(), ICData::kDeoptUnaryOp); | 1129 compiler->EmitDeopt(deopt_id(), ICData::kDeoptUnaryOp); |
1055 break; | 1130 break; |
1056 } | 1131 } |
1057 case Token::kBIT_NOT: | 1132 case Token::kBIT_NOT: |
1058 __ BitNot(locs()->out(0).reg(), locs()->in(0).reg()); | 1133 __ BitNot(locs()->out(0).reg(), locs()->in(0).reg()); |
1059 break; | 1134 break; |
1060 default: | 1135 default: |
1061 UNREACHABLE(); | 1136 UNREACHABLE(); |
1062 } | 1137 } |
1063 } | 1138 } |
1064 | 1139 |
1065 } // namespace dart | 1140 } // namespace dart |
1066 | 1141 |
1067 #endif // defined TARGET_ARCH_DBC | 1142 #endif // defined TARGET_ARCH_DBC |
OLD | NEW |