Chromium Code Reviews| 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 |