| 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 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 compiler->RecordSafepoint(locs()); | 227 compiler->RecordSafepoint(locs()); |
| 228 compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, | 228 compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, |
| 229 deopt_id(), | 229 deopt_id(), |
| 230 token_pos()); | 230 token_pos()); |
| 231 if (compiler->is_optimizing()) { | 231 if (compiler->is_optimizing()) { |
| 232 __ Drop1(); | 232 __ Drop1(); |
| 233 } | 233 } |
| 234 } | 234 } |
| 235 | 235 |
| 236 | 236 |
| 237 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( | 237 EMIT_NATIVE_CODE(PolymorphicInstanceCall, |
| 238 Zone* zone, bool optimizing) const { | 238 0, Location::RegisterLocation(0), |
| 239 return MakeCallSummary(zone); | 239 LocationSummary::kCall) { |
| 240 ASSERT(ic_data().NumArgsTested() == 1); |
| 241 const Array& arguments_descriptor = |
| 242 Array::Handle(ArgumentsDescriptor::New( |
| 243 instance_call()->ArgumentCount(), |
| 244 instance_call()->argument_names())); |
| 245 const intptr_t argdesc_kidx = __ AddConstant(arguments_descriptor); |
| 246 |
| 247 // Push the target onto the stack. |
| 248 if (with_checks()) { |
| 249 const intptr_t may_be_smi = |
| 250 (ic_data().GetReceiverClassIdAt(0) == kSmiCid) ? 1 : 0; |
| 251 GrowableArray<CidTarget> sorted_ic_data; |
| 252 FlowGraphCompiler::SortICDataByCount(ic_data(), |
| 253 &sorted_ic_data, |
| 254 /* drop_smi = */ true); |
| 255 const intptr_t sorted_length = sorted_ic_data.length(); |
| 256 if (!Utils::IsUint(8, sorted_length)) { |
| 257 Unsupported(compiler); |
| 258 UNREACHABLE(); |
| 259 } |
| 260 __ PushPolymorphicInstanceCall( |
| 261 instance_call()->ArgumentCount(), sorted_length + may_be_smi); |
| 262 if (may_be_smi == 1) { |
| 263 const Function& target = Function::ZoneHandle( |
| 264 compiler->zone(), ic_data().GetTargetAt(0)); |
| 265 __ Nop(compiler->ToEmbeddableCid(kSmiCid, this)); |
| 266 __ Nop(__ AddConstant(target)); |
| 267 } |
| 268 for (intptr_t i = 0; i < sorted_length; i++) { |
| 269 const Function& target = *sorted_ic_data[i].target; |
| 270 __ Nop(compiler->ToEmbeddableCid(sorted_ic_data[i].cid, this)); |
| 271 __ Nop(__ AddConstant(target)); |
| 272 } |
| 273 compiler->EmitDeopt( |
| 274 deopt_id(), ICData::kDeoptPolymorphicInstanceCallTestFail, 0); |
| 275 } else { |
| 276 ASSERT(ic_data().HasOneTarget()); |
| 277 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); |
| 278 __ PushConstant(target); |
| 279 } |
| 280 |
| 281 // Call the function. |
| 282 __ StaticCall(instance_call()->ArgumentCount(), argdesc_kidx); |
| 283 compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, |
| 284 deopt_id(), instance_call()->token_pos()); |
| 285 compiler->RecordAfterCall(this); |
| 286 __ PopLocal(locs()->out(0).reg()); |
| 240 } | 287 } |
| 241 | 288 |
| 242 | 289 |
| 243 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 244 ASSERT(ic_data().NumArgsTested() == 1); | |
| 245 if (!with_checks()) { | |
| 246 ASSERT(ic_data().HasOneTarget()); | |
| 247 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); | |
| 248 const Array& arguments_descriptor = | |
| 249 Array::Handle(ArgumentsDescriptor::New( | |
| 250 instance_call()->ArgumentCount(), | |
| 251 instance_call()->argument_names())); | |
| 252 const intptr_t argdesc_kidx = __ AddConstant(arguments_descriptor); | |
| 253 | |
| 254 __ PushConstant(target); | |
| 255 __ StaticCall(instance_call()->ArgumentCount(), argdesc_kidx); | |
| 256 compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, | |
| 257 deopt_id(), instance_call()->token_pos()); | |
| 258 compiler->RecordAfterCall(this); | |
| 259 __ PopLocal(locs()->out(0).reg()); | |
| 260 return; | |
| 261 } | |
| 262 Unsupported(compiler); | |
| 263 UNREACHABLE(); | |
| 264 } | |
| 265 | |
| 266 | |
| 267 EMIT_NATIVE_CODE(Stop, 0) { | 290 EMIT_NATIVE_CODE(Stop, 0) { |
| 268 __ Stop(message()); | 291 __ Stop(message()); |
| 269 } | 292 } |
| 270 | 293 |
| 271 | 294 |
| 272 EMIT_NATIVE_CODE(CheckStackOverflow, | 295 EMIT_NATIVE_CODE(CheckStackOverflow, |
| 273 0, Location::NoLocation(), | 296 0, Location::NoLocation(), |
| 274 LocationSummary::kCall) { | 297 LocationSummary::kCall) { |
| 275 __ CheckStack(); | 298 __ CheckStack(); |
| 276 compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, | 299 compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, |
| (...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1139 return kTagged; | 1162 return kTagged; |
| 1140 } | 1163 } |
| 1141 } | 1164 } |
| 1142 | 1165 |
| 1143 | 1166 |
| 1144 void Environment::DropArguments(intptr_t argc) { | 1167 void Environment::DropArguments(intptr_t argc) { |
| 1145 #if defined(DEBUG) | 1168 #if defined(DEBUG) |
| 1146 // Check that we are in the backend - register allocation has been run. | 1169 // Check that we are in the backend - register allocation has been run. |
| 1147 ASSERT(locations_ != NULL); | 1170 ASSERT(locations_ != NULL); |
| 1148 | 1171 |
| 1149 // Check that we are only dropping PushArgument instructions from the | 1172 // Check that we are only dropping a valid number of instructions from the |
| 1150 // environment. | 1173 // environment. |
| 1151 ASSERT(argc <= values_.length()); | 1174 ASSERT(argc <= values_.length()); |
| 1152 for (intptr_t i = 0; i < argc; i++) { | |
| 1153 ASSERT(values_[values_.length() - i - 1]->definition()->IsPushArgument()); | |
| 1154 } | |
| 1155 #endif | 1175 #endif |
| 1156 values_.TruncateTo(values_.length() - argc); | 1176 values_.TruncateTo(values_.length() - argc); |
| 1157 } | 1177 } |
| 1158 | 1178 |
| 1159 | 1179 |
| 1160 EMIT_NATIVE_CODE(CheckSmi, 1) { | 1180 EMIT_NATIVE_CODE(CheckSmi, 1) { |
| 1161 __ CheckSmi(locs()->in(0).reg()); | 1181 __ CheckSmi(locs()->in(0).reg()); |
| 1162 compiler->EmitDeopt(deopt_id(), | 1182 compiler->EmitDeopt(deopt_id(), |
| 1163 ICData::kDeoptCheckSmi, | 1183 ICData::kDeoptCheckSmi, |
| 1164 licm_hoisted_ ? ICData::kHoisted : 0); | 1184 licm_hoisted_ ? ICData::kHoisted : 0); |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1598 __ IfULe(length, index); | 1618 __ IfULe(length, index); |
| 1599 compiler->EmitDeopt(deopt_id(), | 1619 compiler->EmitDeopt(deopt_id(), |
| 1600 ICData::kDeoptCheckArrayBound, | 1620 ICData::kDeoptCheckArrayBound, |
| 1601 (generalized_ ? ICData::kGeneralized : 0) | | 1621 (generalized_ ? ICData::kGeneralized : 0) | |
| 1602 (licm_hoisted_ ? ICData::kHoisted : 0)); | 1622 (licm_hoisted_ ? ICData::kHoisted : 0)); |
| 1603 } | 1623 } |
| 1604 | 1624 |
| 1605 } // namespace dart | 1625 } // namespace dart |
| 1606 | 1626 |
| 1607 #endif // defined TARGET_ARCH_DBC | 1627 #endif // defined TARGET_ARCH_DBC |
| OLD | NEW |