OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. |
6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 // Generic summary for call instructions that have all arguments pushed | 27 // Generic summary for call instructions that have all arguments pushed |
28 // on the stack and return the result in a fixed register R0. | 28 // on the stack and return the result in a fixed register R0. |
29 LocationSummary* Instruction::MakeCallSummary() { | 29 LocationSummary* Instruction::MakeCallSummary() { |
30 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); | 30 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); |
31 result->set_out(0, Location::RegisterLocation(R0)); | 31 result->set_out(0, Location::RegisterLocation(R0)); |
32 return result; | 32 return result; |
33 } | 33 } |
34 | 34 |
35 | 35 |
36 LocationSummary* PushArgumentInstr::MakeLocationSummary(bool opt) const { | 36 LocationSummary* PushArgumentInstr::MakeLocationSummary(bool opt) const { |
37 UNIMPLEMENTED(); | 37 const intptr_t kNumInputs = 1; |
38 return NULL; | 38 const intptr_t kNumTemps= 0; |
| 39 LocationSummary* locs = |
| 40 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 41 locs->set_in(0, Location::AnyOrConstant(value())); |
| 42 return locs; |
39 } | 43 } |
40 | 44 |
41 | 45 |
42 void PushArgumentInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 46 void PushArgumentInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
43 UNIMPLEMENTED(); | 47 // In SSA mode, we need an explicit push. Nothing to do in non-SSA mode |
| 48 // where PushArgument is handled by BindInstr::EmitNativeCode. |
| 49 if (compiler->is_optimizing()) { |
| 50 Location value = locs()->in(0); |
| 51 if (value.IsRegister()) { |
| 52 __ Push(value.reg()); |
| 53 } else if (value.IsConstant()) { |
| 54 __ PushObject(value.constant(), PP); |
| 55 } else { |
| 56 ASSERT(value.IsStackSlot()); |
| 57 const intptr_t value_offset = value.ToStackSlotOffset(); |
| 58 __ LoadFromOffset(TMP, FP, value_offset); |
| 59 __ Push(TMP); |
| 60 } |
| 61 } |
44 } | 62 } |
45 | 63 |
46 | 64 |
47 LocationSummary* ReturnInstr::MakeLocationSummary(bool opt) const { | 65 LocationSummary* ReturnInstr::MakeLocationSummary(bool opt) const { |
48 const intptr_t kNumInputs = 1; | 66 const intptr_t kNumInputs = 1; |
49 const intptr_t kNumTemps = 0; | 67 const intptr_t kNumTemps = 0; |
50 LocationSummary* locs = | 68 LocationSummary* locs = |
51 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 69 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
52 locs->set_in(0, Location::RegisterLocation(R0)); | 70 locs->set_in(0, Location::RegisterLocation(R0)); |
53 return locs; | 71 return locs; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 return NULL; | 113 return NULL; |
96 } | 114 } |
97 | 115 |
98 | 116 |
99 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 117 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
100 UNIMPLEMENTED(); | 118 UNIMPLEMENTED(); |
101 } | 119 } |
102 | 120 |
103 | 121 |
104 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const { | 122 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const { |
105 UNIMPLEMENTED(); | 123 return LocationSummary::Make(0, |
106 return NULL; | 124 Location::RequiresRegister(), |
| 125 LocationSummary::kNoCall); |
107 } | 126 } |
108 | 127 |
109 | 128 |
110 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 129 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
111 UNIMPLEMENTED(); | 130 Register result = locs()->out(0).reg(); |
| 131 __ LoadFromOffset(result, FP, local().index() * kWordSize); |
112 } | 132 } |
113 | 133 |
114 | 134 |
115 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const { | 135 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const { |
116 UNIMPLEMENTED(); | 136 return LocationSummary::Make(1, |
117 return NULL; | 137 Location::SameAsFirstInput(), |
| 138 LocationSummary::kNoCall); |
118 } | 139 } |
119 | 140 |
120 | 141 |
121 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 142 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
122 UNIMPLEMENTED(); | 143 Register value = locs()->in(0).reg(); |
| 144 Register result = locs()->out(0).reg(); |
| 145 ASSERT(result == value); // Assert that register assignment is correct. |
| 146 __ StoreToOffset(value, FP, local().index() * kWordSize); |
123 } | 147 } |
124 | 148 |
125 | 149 |
126 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const { | 150 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const { |
127 return LocationSummary::Make(0, | 151 return LocationSummary::Make(0, |
128 Location::RequiresRegister(), | 152 Location::RequiresRegister(), |
129 LocationSummary::kNoCall); | 153 LocationSummary::kNoCall); |
130 } | 154 } |
131 | 155 |
132 | 156 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 } | 245 } |
222 | 246 |
223 | 247 |
224 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 248 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
225 BranchInstr* branch) { | 249 BranchInstr* branch) { |
226 UNIMPLEMENTED(); | 250 UNIMPLEMENTED(); |
227 } | 251 } |
228 | 252 |
229 | 253 |
230 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const { | 254 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const { |
231 UNIMPLEMENTED(); | 255 const intptr_t kNumInputs = 0; |
232 return NULL; | 256 const intptr_t kNumTemps = 3; |
| 257 LocationSummary* locs = |
| 258 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 259 locs->set_temp(0, Location::RegisterLocation(R1)); |
| 260 locs->set_temp(1, Location::RegisterLocation(R2)); |
| 261 locs->set_temp(2, Location::RegisterLocation(R5)); |
| 262 locs->set_out(0, Location::RegisterLocation(R0)); |
| 263 return locs; |
233 } | 264 } |
234 | 265 |
235 | 266 |
236 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 267 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
237 UNIMPLEMENTED(); | 268 ASSERT(locs()->temp(0).reg() == R1); |
| 269 ASSERT(locs()->temp(1).reg() == R2); |
| 270 ASSERT(locs()->temp(2).reg() == R5); |
| 271 Register result = locs()->out(0).reg(); |
| 272 |
| 273 // Push the result place holder initialized to NULL. |
| 274 __ PushObject(Object::ZoneHandle(), PP); |
| 275 // Pass a pointer to the first argument in R2. |
| 276 if (!function().HasOptionalParameters()) { |
| 277 __ AddImmediate(R2, FP, (kParamEndSlotFromFp + |
| 278 function().NumParameters()) * kWordSize, PP); |
| 279 } else { |
| 280 __ AddImmediate(R2, FP, kFirstLocalSlotFromFp * kWordSize, PP); |
| 281 } |
| 282 // Compute the effective address. When running under the simulator, |
| 283 // this is a redirection address that forces the simulator to call |
| 284 // into the runtime system. |
| 285 uword entry = reinterpret_cast<uword>(native_c_function()); |
| 286 const ExternalLabel* stub_entry; |
| 287 if (is_bootstrap_native()) { |
| 288 stub_entry = &StubCode::CallBootstrapCFunctionLabel(); |
| 289 #if defined(USING_SIMULATOR) |
| 290 entry = Simulator::RedirectExternalReference( |
| 291 entry, Simulator::kBootstrapNativeCall, function().NumParameters()); |
| 292 #endif |
| 293 } else { |
| 294 // In the case of non bootstrap native methods the CallNativeCFunction |
| 295 // stub generates the redirection address when running under the simulator |
| 296 // and hence we do not change 'entry' here. |
| 297 stub_entry = &StubCode::CallNativeCFunctionLabel(); |
| 298 #if defined(USING_SIMULATOR) |
| 299 if (!function().IsNativeAutoSetupScope()) { |
| 300 entry = Simulator::RedirectExternalReference( |
| 301 entry, Simulator::kBootstrapNativeCall, function().NumParameters()); |
| 302 } |
| 303 #endif |
| 304 } |
| 305 __ LoadImmediate(R5, entry, PP); |
| 306 __ LoadImmediate(R1, NativeArguments::ComputeArgcTag(function()), PP); |
| 307 compiler->GenerateCall(token_pos(), |
| 308 stub_entry, |
| 309 PcDescriptors::kOther, |
| 310 locs()); |
| 311 __ Pop(result); |
238 } | 312 } |
239 | 313 |
240 | 314 |
241 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(bool opt) const { | 315 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(bool opt) const { |
242 UNIMPLEMENTED(); | 316 UNIMPLEMENTED(); |
243 return NULL; | 317 return NULL; |
244 } | 318 } |
245 | 319 |
246 | 320 |
247 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 321 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
(...skipping 915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1163 return NULL; | 1237 return NULL; |
1164 } | 1238 } |
1165 | 1239 |
1166 | 1240 |
1167 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1241 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1168 UNIMPLEMENTED(); | 1242 UNIMPLEMENTED(); |
1169 } | 1243 } |
1170 | 1244 |
1171 | 1245 |
1172 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const { | 1246 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const { |
1173 UNIMPLEMENTED(); | 1247 comparison()->InitializeLocationSummary(opt); |
1174 return NULL; | 1248 // Branches don't produce a result. |
| 1249 comparison()->locs()->set_out(0, Location::NoLocation()); |
| 1250 return comparison()->locs(); |
1175 } | 1251 } |
1176 | 1252 |
1177 | 1253 |
1178 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1254 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1179 UNIMPLEMENTED(); | 1255 comparison()->EmitBranchCode(compiler, this); |
1180 } | 1256 } |
1181 | 1257 |
1182 | 1258 |
1183 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const { | 1259 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const { |
1184 UNIMPLEMENTED(); | 1260 UNIMPLEMENTED(); |
1185 return NULL; | 1261 return NULL; |
1186 } | 1262 } |
1187 | 1263 |
1188 | 1264 |
1189 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1265 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1309 deopt_id_, | 1385 deopt_id_, |
1310 Scanner::kNoSourcePos); | 1386 Scanner::kNoSourcePos); |
1311 } | 1387 } |
1312 if (HasParallelMove()) { | 1388 if (HasParallelMove()) { |
1313 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | 1389 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
1314 } | 1390 } |
1315 } | 1391 } |
1316 | 1392 |
1317 | 1393 |
1318 LocationSummary* GotoInstr::MakeLocationSummary(bool opt) const { | 1394 LocationSummary* GotoInstr::MakeLocationSummary(bool opt) const { |
1319 UNIMPLEMENTED(); | 1395 return new LocationSummary(0, 0, LocationSummary::kNoCall); |
1320 return NULL; | |
1321 } | 1396 } |
1322 | 1397 |
1323 | 1398 |
1324 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1399 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1325 UNIMPLEMENTED(); | 1400 if (!compiler->is_optimizing()) { |
| 1401 compiler->EmitEdgeCounter(); |
| 1402 // Add a deoptimization descriptor for deoptimizing instructions that |
| 1403 // may be inserted before this instruction. On ARM64 this descriptor |
| 1404 // points after the edge counter code so that we can reuse the same |
| 1405 // pattern matching code as at call sites, which matches backwards from |
| 1406 // the end of the pattern. |
| 1407 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 1408 GetDeoptId(), |
| 1409 Scanner::kNoSourcePos); |
| 1410 } |
| 1411 if (HasParallelMove()) { |
| 1412 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
| 1413 } |
| 1414 |
| 1415 // We can fall through if the successor is the next block in the list. |
| 1416 // Otherwise, we need a jump. |
| 1417 if (!compiler->CanFallThroughTo(successor())) { |
| 1418 __ b(compiler->GetJumpLabel(successor())); |
| 1419 } |
1326 } | 1420 } |
1327 | 1421 |
1328 | 1422 |
1329 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const { | 1423 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const { |
1330 UNIMPLEMENTED(); | 1424 UNIMPLEMENTED(); |
1331 return NULL; | 1425 return NULL; |
1332 } | 1426 } |
1333 | 1427 |
1334 | 1428 |
1335 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1429 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1336 UNIMPLEMENTED(); | 1430 UNIMPLEMENTED(); |
1337 } | 1431 } |
1338 | 1432 |
1339 | 1433 |
| 1434 static Condition NegateCondition(Condition condition) { |
| 1435 switch (condition) { |
| 1436 case EQ: return NE; |
| 1437 case NE: return EQ; |
| 1438 case LT: return GE; |
| 1439 case LE: return GT; |
| 1440 case GT: return LE; |
| 1441 case GE: return LT; |
| 1442 case CC: return CS; |
| 1443 case LS: return HI; |
| 1444 case HI: return LS; |
| 1445 case CS: return CC; |
| 1446 default: |
| 1447 UNREACHABLE(); |
| 1448 return EQ; |
| 1449 } |
| 1450 } |
| 1451 |
| 1452 |
| 1453 static void EmitBranchOnCondition(FlowGraphCompiler* compiler, |
| 1454 Condition true_condition, |
| 1455 BranchLabels labels) { |
| 1456 if (labels.fall_through == labels.false_label) { |
| 1457 // If the next block is the false successor we will fall through to it. |
| 1458 __ b(labels.true_label, true_condition); |
| 1459 } else { |
| 1460 // If the next block is not the false successor we will branch to it. |
| 1461 Condition false_condition = NegateCondition(true_condition); |
| 1462 __ b(labels.false_label, false_condition); |
| 1463 |
| 1464 // Fall through or jump to the true successor. |
| 1465 if (labels.fall_through != labels.true_label) { |
| 1466 __ b(labels.true_label); |
| 1467 } |
| 1468 } |
| 1469 } |
| 1470 |
| 1471 |
1340 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const { | 1472 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const { |
1341 UNIMPLEMENTED(); | 1473 const intptr_t kNumInputs = 2; |
1342 return NULL; | 1474 const intptr_t kNumTemps = 0; |
| 1475 if (needs_number_check()) { |
| 1476 LocationSummary* locs = |
| 1477 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1478 locs->set_in(0, Location::RegisterLocation(R0)); |
| 1479 locs->set_in(1, Location::RegisterLocation(R1)); |
| 1480 locs->set_out(0, Location::RegisterLocation(R0)); |
| 1481 return locs; |
| 1482 } |
| 1483 LocationSummary* locs = |
| 1484 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1485 locs->set_in(0, Location::RegisterOrConstant(left())); |
| 1486 // Only one of the inputs can be a constant. Choose register if the first one |
| 1487 // is a constant. |
| 1488 locs->set_in(1, locs->in(0).IsConstant() |
| 1489 ? Location::RequiresRegister() |
| 1490 : Location::RegisterOrConstant(right())); |
| 1491 locs->set_out(0, Location::RequiresRegister()); |
| 1492 return locs; |
1343 } | 1493 } |
1344 | 1494 |
1345 | 1495 |
1346 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, | 1496 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
1347 BranchLabels labels) { | 1497 BranchLabels labels) { |
1348 UNIMPLEMENTED(); | 1498 Location left = locs()->in(0); |
1349 return VS; | 1499 Location right = locs()->in(1); |
| 1500 ASSERT(!left.IsConstant() || !right.IsConstant()); |
| 1501 if (left.IsConstant()) { |
| 1502 compiler->EmitEqualityRegConstCompare(right.reg(), |
| 1503 left.constant(), |
| 1504 needs_number_check(), |
| 1505 token_pos()); |
| 1506 } else if (right.IsConstant()) { |
| 1507 compiler->EmitEqualityRegConstCompare(left.reg(), |
| 1508 right.constant(), |
| 1509 needs_number_check(), |
| 1510 token_pos()); |
| 1511 } else { |
| 1512 compiler->EmitEqualityRegRegCompare(left.reg(), |
| 1513 right.reg(), |
| 1514 needs_number_check(), |
| 1515 token_pos()); |
| 1516 } |
| 1517 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE; |
| 1518 return true_condition; |
1350 } | 1519 } |
1351 | 1520 |
1352 | 1521 |
1353 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1522 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1354 UNIMPLEMENTED(); | 1523 __ Comment("StrictCompareInstr"); |
| 1524 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
| 1525 |
| 1526 Label is_true, is_false; |
| 1527 BranchLabels labels = { &is_true, &is_false, &is_false }; |
| 1528 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 1529 EmitBranchOnCondition(compiler, true_condition, labels); |
| 1530 |
| 1531 Register result = locs()->out(0).reg(); |
| 1532 Label done; |
| 1533 __ Bind(&is_false); |
| 1534 __ LoadObject(result, Bool::False(), PP); |
| 1535 __ b(&done); |
| 1536 __ Bind(&is_true); |
| 1537 __ LoadObject(result, Bool::True(), PP); |
| 1538 __ Bind(&done); |
1355 } | 1539 } |
1356 | 1540 |
1357 | 1541 |
1358 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 1542 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
1359 BranchInstr* branch) { | 1543 BranchInstr* branch) { |
1360 UNIMPLEMENTED(); | 1544 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
| 1545 |
| 1546 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 1547 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 1548 EmitBranchOnCondition(compiler, true_condition, labels); |
1361 } | 1549 } |
1362 | 1550 |
1363 | 1551 |
1364 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const { | 1552 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const { |
1365 UNIMPLEMENTED(); | 1553 UNIMPLEMENTED(); |
1366 return NULL; | 1554 return NULL; |
1367 } | 1555 } |
1368 | 1556 |
1369 | 1557 |
1370 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1558 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1371 UNIMPLEMENTED(); | 1559 UNIMPLEMENTED(); |
1372 } | 1560 } |
1373 | 1561 |
1374 | 1562 |
1375 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const { | 1563 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const { |
1376 UNIMPLEMENTED(); | 1564 UNIMPLEMENTED(); |
1377 return NULL; | 1565 return NULL; |
1378 } | 1566 } |
1379 | 1567 |
1380 | 1568 |
1381 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1569 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1382 UNIMPLEMENTED(); | 1570 UNIMPLEMENTED(); |
1383 } | 1571 } |
1384 | 1572 |
1385 } // namespace dart | 1573 } // namespace dart |
1386 | 1574 |
1387 #endif // defined TARGET_ARCH_ARM64 | 1575 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |