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 |