| 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" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 1275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1286 } | 1286 } |
| 1287 | 1287 |
| 1288 | 1288 |
| 1289 // Note: R5 must be preserved. | 1289 // Note: R5 must be preserved. |
| 1290 // Attempt a quick Smi operation for known operations ('kind'). The ICData | 1290 // Attempt a quick Smi operation for known operations ('kind'). The ICData |
| 1291 // must have been primed with a Smi/Smi check that will be used for counting | 1291 // must have been primed with a Smi/Smi check that will be used for counting |
| 1292 // the invocations. | 1292 // the invocations. |
| 1293 static void EmitFastSmiOp(Assembler* assembler, | 1293 static void EmitFastSmiOp(Assembler* assembler, |
| 1294 Token::Kind kind, | 1294 Token::Kind kind, |
| 1295 intptr_t num_args, | 1295 intptr_t num_args, |
| 1296 Label* not_smi_or_overflow, | 1296 Label* not_smi_or_overflow) { |
| 1297 bool should_update_result_range) { | |
| 1298 __ Comment("Fast Smi op"); | 1297 __ Comment("Fast Smi op"); |
| 1299 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Right. | 1298 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Right. |
| 1300 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Left. | 1299 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Left. |
| 1301 __ orr(TMP, R0, Operand(R1)); | 1300 __ orr(TMP, R0, Operand(R1)); |
| 1302 __ tsti(TMP, Immediate(kSmiTagMask)); | 1301 __ tsti(TMP, Immediate(kSmiTagMask)); |
| 1303 __ b(not_smi_or_overflow, NE); | 1302 __ b(not_smi_or_overflow, NE); |
| 1304 switch (kind) { | 1303 switch (kind) { |
| 1305 case Token::kADD: { | 1304 case Token::kADD: { |
| 1306 __ adds(R0, R1, Operand(R0)); // Adds. | 1305 __ adds(R0, R1, Operand(R0)); // Adds. |
| 1307 __ b(not_smi_or_overflow, VS); // Branch if overflow. | 1306 __ b(not_smi_or_overflow, VS); // Branch if overflow. |
| 1308 break; | 1307 break; |
| 1309 } | 1308 } |
| 1310 case Token::kSUB: { | 1309 case Token::kSUB: { |
| 1311 __ subs(R0, R1, Operand(R0)); // Subtract. | 1310 __ subs(R0, R1, Operand(R0)); // Subtract. |
| 1312 __ b(not_smi_or_overflow, VS); // Branch if overflow. | 1311 __ b(not_smi_or_overflow, VS); // Branch if overflow. |
| 1313 break; | 1312 break; |
| 1314 } | 1313 } |
| 1315 case Token::kEQ: { | 1314 case Token::kEQ: { |
| 1316 __ CompareRegisters(R0, R1); | 1315 __ CompareRegisters(R0, R1); |
| 1317 __ LoadObject(R0, Bool::True()); | 1316 __ LoadObject(R0, Bool::True()); |
| 1318 __ LoadObject(R1, Bool::False()); | 1317 __ LoadObject(R1, Bool::False()); |
| 1319 __ csel(R0, R1, R0, NE); | 1318 __ csel(R0, R1, R0, NE); |
| 1320 break; | 1319 break; |
| 1321 } | 1320 } |
| 1322 default: UNIMPLEMENTED(); | 1321 default: UNIMPLEMENTED(); |
| 1323 } | 1322 } |
| 1324 | 1323 |
| 1325 if (should_update_result_range) { | |
| 1326 Label done; | |
| 1327 __ UpdateRangeFeedback(R0, 2, R5, R1, R6, &done); | |
| 1328 __ Bind(&done); | |
| 1329 } | |
| 1330 | |
| 1331 // R5: IC data object (preserved). | 1324 // R5: IC data object (preserved). |
| 1332 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset()); | 1325 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset()); |
| 1333 // R6: ic_data_array with check entries: classes and target functions. | 1326 // R6: ic_data_array with check entries: classes and target functions. |
| 1334 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); | 1327 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); |
| 1335 // R6: points directly to the first ic data array element. | 1328 // R6: points directly to the first ic data array element. |
| 1336 #if defined(DEBUG) | 1329 #if defined(DEBUG) |
| 1337 // Check that first entry is for Smi/Smi. | 1330 // Check that first entry is for Smi/Smi. |
| 1338 Label error, ok; | 1331 Label error, ok; |
| 1339 const intptr_t imm_smi_cid = reinterpret_cast<intptr_t>(Smi::New(kSmiCid)); | 1332 const intptr_t imm_smi_cid = reinterpret_cast<intptr_t>(Smi::New(kSmiCid)); |
| 1340 __ ldr(R1, Address(R6, 0)); | 1333 __ ldr(R1, Address(R6, 0)); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1369 // - If receiver is Smi -> load Smi class. | 1362 // - If receiver is Smi -> load Smi class. |
| 1370 // - If receiver is not-Smi -> load receiver's class. | 1363 // - If receiver is not-Smi -> load receiver's class. |
| 1371 // - Check if 'num_args' (including receiver) match any IC data group. | 1364 // - Check if 'num_args' (including receiver) match any IC data group. |
| 1372 // - Match found -> jump to target. | 1365 // - Match found -> jump to target. |
| 1373 // - Match not found -> jump to IC miss. | 1366 // - Match not found -> jump to IC miss. |
| 1374 void StubCode::GenerateNArgsCheckInlineCacheStub( | 1367 void StubCode::GenerateNArgsCheckInlineCacheStub( |
| 1375 Assembler* assembler, | 1368 Assembler* assembler, |
| 1376 intptr_t num_args, | 1369 intptr_t num_args, |
| 1377 const RuntimeEntry& handle_ic_miss, | 1370 const RuntimeEntry& handle_ic_miss, |
| 1378 Token::Kind kind, | 1371 Token::Kind kind, |
| 1379 RangeCollectionMode range_collection_mode, | |
| 1380 bool optimized) { | 1372 bool optimized) { |
| 1381 ASSERT(num_args > 0); | 1373 ASSERT(num_args > 0); |
| 1382 #if defined(DEBUG) | 1374 #if defined(DEBUG) |
| 1383 { Label ok; | 1375 { Label ok; |
| 1384 // Check that the IC data array has NumArgsTested() == num_args. | 1376 // Check that the IC data array has NumArgsTested() == num_args. |
| 1385 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. | 1377 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. |
| 1386 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag, | 1378 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag, |
| 1387 kUnsignedWord); | 1379 kUnsignedWord); |
| 1388 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. | 1380 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
| 1389 __ andi(R6, R6, Immediate(ICData::NumArgsTestedMask())); | 1381 __ andi(R6, R6, Immediate(ICData::NumArgsTestedMask())); |
| 1390 __ CompareImmediate(R6, num_args); | 1382 __ CompareImmediate(R6, num_args); |
| 1391 __ b(&ok, EQ); | 1383 __ b(&ok, EQ); |
| 1392 __ Stop("Incorrect stub for IC data"); | 1384 __ Stop("Incorrect stub for IC data"); |
| 1393 __ Bind(&ok); | 1385 __ Bind(&ok); |
| 1394 } | 1386 } |
| 1395 #endif // DEBUG | 1387 #endif // DEBUG |
| 1396 | 1388 |
| 1397 Label stepping, done_stepping; | 1389 Label stepping, done_stepping; |
| 1398 if (FLAG_support_debugger && !optimized) { | 1390 if (FLAG_support_debugger && !optimized) { |
| 1399 __ Comment("Check single stepping"); | 1391 __ Comment("Check single stepping"); |
| 1400 __ LoadIsolate(R6); | 1392 __ LoadIsolate(R6); |
| 1401 __ LoadFromOffset( | 1393 __ LoadFromOffset( |
| 1402 R6, R6, Isolate::single_step_offset(), kUnsignedByte); | 1394 R6, R6, Isolate::single_step_offset(), kUnsignedByte); |
| 1403 __ CompareRegisters(R6, ZR); | 1395 __ CompareRegisters(R6, ZR); |
| 1404 __ b(&stepping, NE); | 1396 __ b(&stepping, NE); |
| 1405 __ Bind(&done_stepping); | 1397 __ Bind(&done_stepping); |
| 1406 } | 1398 } |
| 1407 | 1399 |
| 1408 __ Comment("Range feedback collection"); | |
| 1409 Label not_smi_or_overflow; | 1400 Label not_smi_or_overflow; |
| 1410 if (range_collection_mode == kCollectRanges) { | |
| 1411 ASSERT((num_args == 1) || (num_args == 2)); | |
| 1412 if (num_args == 2) { | |
| 1413 __ ldr(R0, Address(SP, 1 * kWordSize)); | |
| 1414 __ UpdateRangeFeedback(R0, 0, R5, R1, R4, ¬_smi_or_overflow); | |
| 1415 } | |
| 1416 | |
| 1417 __ ldr(R0, Address(SP, 0 * kWordSize)); | |
| 1418 __ UpdateRangeFeedback(R0, num_args - 1, R5, R1, R4, ¬_smi_or_overflow); | |
| 1419 } | |
| 1420 if (kind != Token::kILLEGAL) { | 1401 if (kind != Token::kILLEGAL) { |
| 1421 EmitFastSmiOp(assembler, | 1402 EmitFastSmiOp(assembler, |
| 1422 kind, | 1403 kind, |
| 1423 num_args, | 1404 num_args, |
| 1424 ¬_smi_or_overflow, | 1405 ¬_smi_or_overflow); |
| 1425 (range_collection_mode == kCollectRanges)); | |
| 1426 } | 1406 } |
| 1427 __ Bind(¬_smi_or_overflow); | 1407 __ Bind(¬_smi_or_overflow); |
| 1428 | 1408 |
| 1429 __ Comment("Extract ICData initial values and receiver cid"); | 1409 __ Comment("Extract ICData initial values and receiver cid"); |
| 1430 // Load arguments descriptor into R4. | 1410 // Load arguments descriptor into R4. |
| 1431 __ LoadFieldFromOffset(R4, R5, ICData::arguments_descriptor_offset()); | 1411 __ LoadFieldFromOffset(R4, R5, ICData::arguments_descriptor_offset()); |
| 1432 // Loop that checks if there is an IC data match. | 1412 // Loop that checks if there is an IC data match. |
| 1433 Label loop, update, test, found; | 1413 Label loop, update, test, found; |
| 1434 // R5: IC data object (preserved). | 1414 // R5: IC data object (preserved). |
| 1435 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset()); | 1415 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset()); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1539 __ LoadFromOffset(R1, R6, count_offset); | 1519 __ LoadFromOffset(R1, R6, count_offset); |
| 1540 __ adds(R1, R1, Operand(Smi::RawValue(1))); | 1520 __ adds(R1, R1, Operand(Smi::RawValue(1))); |
| 1541 __ LoadImmediate(R2, Smi::RawValue(Smi::kMaxValue)); | 1521 __ LoadImmediate(R2, Smi::RawValue(Smi::kMaxValue)); |
| 1542 __ csel(R1, R2, R1, VS); // Overflow. | 1522 __ csel(R1, R2, R1, VS); // Overflow. |
| 1543 __ StoreToOffset(R1, R6, count_offset); | 1523 __ StoreToOffset(R1, R6, count_offset); |
| 1544 } | 1524 } |
| 1545 | 1525 |
| 1546 __ Comment("Call target"); | 1526 __ Comment("Call target"); |
| 1547 __ Bind(&call_target_function); | 1527 __ Bind(&call_target_function); |
| 1548 // R0: target function. | 1528 // R0: target function. |
| 1549 if (range_collection_mode == kCollectRanges) { | 1529 __ LoadFieldFromOffset(CODE_REG, R0, Function::code_offset()); |
| 1550 __ LoadFieldFromOffset(R2, R0, Function::entry_point_offset()); | 1530 __ LoadFieldFromOffset(R2, R0, Function::entry_point_offset()); |
| 1551 __ ldr(R1, Address(SP, 0 * kWordSize)); | 1531 __ br(R2); |
| 1552 if (num_args == 2) { | |
| 1553 __ ldr(R3, Address(SP, 1 * kWordSize)); | |
| 1554 } | |
| 1555 __ EnterStubFrame(); | |
| 1556 __ Push(R5); | |
| 1557 if (num_args == 2) { | |
| 1558 __ Push(R3); | |
| 1559 } | |
| 1560 __ Push(R1); | |
| 1561 __ LoadFieldFromOffset(CODE_REG, R0, Function::code_offset()); | |
| 1562 __ blr(R2); | |
| 1563 | |
| 1564 Label done; | |
| 1565 __ ldr(R5, Address(FP, kFirstLocalSlotFromFp * kWordSize)); | |
| 1566 __ UpdateRangeFeedback(R0, 2, R5, R1, R4, &done); | |
| 1567 __ Bind(&done); | |
| 1568 __ LeaveStubFrame(); | |
| 1569 __ ret(); | |
| 1570 } else { | |
| 1571 __ LoadFieldFromOffset(CODE_REG, R0, Function::code_offset()); | |
| 1572 __ LoadFieldFromOffset(R2, R0, Function::entry_point_offset()); | |
| 1573 __ br(R2); | |
| 1574 } | |
| 1575 | 1532 |
| 1576 if (FLAG_support_debugger && !optimized) { | 1533 if (FLAG_support_debugger && !optimized) { |
| 1577 __ Bind(&stepping); | 1534 __ Bind(&stepping); |
| 1578 __ EnterStubFrame(); | 1535 __ EnterStubFrame(); |
| 1579 __ Push(R5); // Preserve IC data. | 1536 __ Push(R5); // Preserve IC data. |
| 1580 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1537 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 1581 __ Pop(R5); | 1538 __ Pop(R5); |
| 1582 __ RestoreCodePointer(); | 1539 __ RestoreCodePointer(); |
| 1583 __ LeaveStubFrame(); | 1540 __ LeaveStubFrame(); |
| 1584 __ b(&done_stepping); | 1541 __ b(&done_stepping); |
| 1585 } | 1542 } |
| 1586 } | 1543 } |
| 1587 | 1544 |
| 1588 | 1545 |
| 1589 // Use inline cache data array to invoke the target or continue in inline | 1546 // Use inline cache data array to invoke the target or continue in inline |
| 1590 // cache miss handler. Stub for 1-argument check (receiver class). | 1547 // cache miss handler. Stub for 1-argument check (receiver class). |
| 1591 // LR: return address. | 1548 // LR: return address. |
| 1592 // R5: inline cache data object. | 1549 // R5: inline cache data object. |
| 1593 // Inline cache data object structure: | 1550 // Inline cache data object structure: |
| 1594 // 0: function-name | 1551 // 0: function-name |
| 1595 // 1: N, number of arguments checked. | 1552 // 1: N, number of arguments checked. |
| 1596 // 2 .. (length - 1): group of checks, each check containing: | 1553 // 2 .. (length - 1): group of checks, each check containing: |
| 1597 // - N classes. | 1554 // - N classes. |
| 1598 // - 1 target function. | 1555 // - 1 target function. |
| 1599 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { | 1556 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { |
| 1600 GenerateUsageCounterIncrement(assembler, R6); | 1557 GenerateUsageCounterIncrement(assembler, R6); |
| 1601 GenerateNArgsCheckInlineCacheStub(assembler, 1, | 1558 GenerateNArgsCheckInlineCacheStub(assembler, 1, |
| 1602 kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL, | 1559 kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL); |
| 1603 kIgnoreRanges); | |
| 1604 } | 1560 } |
| 1605 | 1561 |
| 1606 | 1562 |
| 1607 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { | 1563 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { |
| 1608 GenerateUsageCounterIncrement(assembler, R6); | 1564 GenerateUsageCounterIncrement(assembler, R6); |
| 1609 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1565 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1610 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL, | 1566 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL); |
| 1611 kIgnoreRanges); | |
| 1612 } | 1567 } |
| 1613 | 1568 |
| 1614 | 1569 |
| 1615 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) { | 1570 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) { |
| 1616 GenerateUsageCounterIncrement(assembler, R6); | 1571 GenerateUsageCounterIncrement(assembler, R6); |
| 1617 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1572 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1618 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD, | 1573 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD); |
| 1619 kCollectRanges); | |
| 1620 } | 1574 } |
| 1621 | 1575 |
| 1622 | 1576 |
| 1623 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) { | 1577 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) { |
| 1624 GenerateUsageCounterIncrement(assembler, R6); | 1578 GenerateUsageCounterIncrement(assembler, R6); |
| 1625 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1579 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1626 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB, | 1580 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB); |
| 1627 kCollectRanges); | |
| 1628 } | 1581 } |
| 1629 | 1582 |
| 1630 | 1583 |
| 1631 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) { | 1584 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) { |
| 1632 GenerateUsageCounterIncrement(assembler, R6); | 1585 GenerateUsageCounterIncrement(assembler, R6); |
| 1633 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1586 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1634 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ, | 1587 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ); |
| 1635 kIgnoreRanges); | |
| 1636 } | 1588 } |
| 1637 | 1589 |
| 1638 | 1590 |
| 1639 void StubCode::GenerateUnaryRangeCollectingInlineCacheStub( | 1591 void StubCode::GenerateUnaryRangeCollectingInlineCacheStub( |
| 1640 Assembler* assembler) { | 1592 Assembler* assembler) { |
| 1641 GenerateUsageCounterIncrement(assembler, R6); | 1593 GenerateUsageCounterIncrement(assembler, R6); |
| 1642 GenerateNArgsCheckInlineCacheStub(assembler, 1, | 1594 GenerateNArgsCheckInlineCacheStub(assembler, 1, |
| 1643 kInlineCacheMissHandlerOneArgRuntimeEntry, | 1595 kInlineCacheMissHandlerOneArgRuntimeEntry, |
| 1644 Token::kILLEGAL, | 1596 Token::kILLEGAL); |
| 1645 kCollectRanges); | |
| 1646 } | 1597 } |
| 1647 | 1598 |
| 1648 | 1599 |
| 1649 void StubCode::GenerateBinaryRangeCollectingInlineCacheStub( | 1600 void StubCode::GenerateBinaryRangeCollectingInlineCacheStub( |
| 1650 Assembler* assembler) { | 1601 Assembler* assembler) { |
| 1651 GenerateUsageCounterIncrement(assembler, R6); | 1602 GenerateUsageCounterIncrement(assembler, R6); |
| 1652 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1603 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1653 kInlineCacheMissHandlerTwoArgsRuntimeEntry, | 1604 kInlineCacheMissHandlerTwoArgsRuntimeEntry, |
| 1654 Token::kILLEGAL, | 1605 Token::kILLEGAL); |
| 1655 kCollectRanges); | |
| 1656 } | 1606 } |
| 1657 | 1607 |
| 1658 | 1608 |
| 1659 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub( | 1609 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub( |
| 1660 Assembler* assembler) { | 1610 Assembler* assembler) { |
| 1661 GenerateOptimizedUsageCounterIncrement(assembler); | 1611 GenerateOptimizedUsageCounterIncrement(assembler); |
| 1662 GenerateNArgsCheckInlineCacheStub(assembler, 1, | 1612 GenerateNArgsCheckInlineCacheStub(assembler, 1, |
| 1663 kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL, | 1613 kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL, |
| 1664 kIgnoreRanges, true /* optimized */); | 1614 true /* optimized */); |
| 1665 } | 1615 } |
| 1666 | 1616 |
| 1667 | 1617 |
| 1668 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub( | 1618 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub( |
| 1669 Assembler* assembler) { | 1619 Assembler* assembler) { |
| 1670 GenerateOptimizedUsageCounterIncrement(assembler); | 1620 GenerateOptimizedUsageCounterIncrement(assembler); |
| 1671 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1621 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1672 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL, | 1622 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL, |
| 1673 kIgnoreRanges, true /* optimized */); | 1623 true /* optimized */); |
| 1674 } | 1624 } |
| 1675 | 1625 |
| 1676 | 1626 |
| 1677 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { | 1627 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { |
| 1678 GenerateUsageCounterIncrement(assembler, R6); | 1628 GenerateUsageCounterIncrement(assembler, R6); |
| 1679 #if defined(DEBUG) | 1629 #if defined(DEBUG) |
| 1680 { Label ok; | 1630 { Label ok; |
| 1681 // Check that the IC data array has NumArgsTested() == 0. | 1631 // Check that the IC data array has NumArgsTested() == 0. |
| 1682 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. | 1632 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. |
| 1683 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag, | 1633 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1737 __ RestoreCodePointer(); | 1687 __ RestoreCodePointer(); |
| 1738 __ LeaveStubFrame(); | 1688 __ LeaveStubFrame(); |
| 1739 __ b(&done_stepping); | 1689 __ b(&done_stepping); |
| 1740 } | 1690 } |
| 1741 } | 1691 } |
| 1742 | 1692 |
| 1743 | 1693 |
| 1744 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) { | 1694 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) { |
| 1745 GenerateUsageCounterIncrement(assembler, R6); | 1695 GenerateUsageCounterIncrement(assembler, R6); |
| 1746 GenerateNArgsCheckInlineCacheStub( | 1696 GenerateNArgsCheckInlineCacheStub( |
| 1747 assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL, | 1697 assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL); |
| 1748 kIgnoreRanges); | |
| 1749 } | 1698 } |
| 1750 | 1699 |
| 1751 | 1700 |
| 1752 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { | 1701 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { |
| 1753 GenerateUsageCounterIncrement(assembler, R6); | 1702 GenerateUsageCounterIncrement(assembler, R6); |
| 1754 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1703 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1755 kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL, | 1704 kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL); |
| 1756 kIgnoreRanges); | |
| 1757 } | 1705 } |
| 1758 | 1706 |
| 1759 | 1707 |
| 1760 // Stub for compiling a function and jumping to the compiled code. | 1708 // Stub for compiling a function and jumping to the compiled code. |
| 1761 // R5: IC-Data (for methods). | 1709 // R5: IC-Data (for methods). |
| 1762 // R4: Arguments descriptor. | 1710 // R4: Arguments descriptor. |
| 1763 // R0: Function. | 1711 // R0: Function. |
| 1764 void StubCode::GenerateLazyCompileStub(Assembler* assembler) { | 1712 void StubCode::GenerateLazyCompileStub(Assembler* assembler) { |
| 1765 // Preserve arg desc. and IC data object. | 1713 // Preserve arg desc. and IC data object. |
| 1766 __ EnterStubFrame(); | 1714 __ EnterStubFrame(); |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2249 } | 2197 } |
| 2250 | 2198 |
| 2251 | 2199 |
| 2252 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { | 2200 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { |
| 2253 __ brk(0); | 2201 __ brk(0); |
| 2254 } | 2202 } |
| 2255 | 2203 |
| 2256 } // namespace dart | 2204 } // namespace dart |
| 2257 | 2205 |
| 2258 #endif // defined TARGET_ARCH_ARM64 | 2206 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |