| 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 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1270 } | 1270 } |
| 1271 | 1271 |
| 1272 | 1272 |
| 1273 // Note: R5 must be preserved. | 1273 // Note: R5 must be preserved. |
| 1274 // Attempt a quick Smi operation for known operations ('kind'). The ICData | 1274 // Attempt a quick Smi operation for known operations ('kind'). The ICData |
| 1275 // must have been primed with a Smi/Smi check that will be used for counting | 1275 // must have been primed with a Smi/Smi check that will be used for counting |
| 1276 // the invocations. | 1276 // the invocations. |
| 1277 static void EmitFastSmiOp(Assembler* assembler, | 1277 static void EmitFastSmiOp(Assembler* assembler, |
| 1278 Token::Kind kind, | 1278 Token::Kind kind, |
| 1279 intptr_t num_args, | 1279 intptr_t num_args, |
| 1280 Label* not_smi_or_overflow) { | 1280 Label* not_smi_or_overflow, |
| 1281 bool should_update_result_range) { |
| 1281 if (FLAG_throw_on_javascript_int_overflow) { | 1282 if (FLAG_throw_on_javascript_int_overflow) { |
| 1282 // The overflow check is more complex than implemented below. | 1283 // The overflow check is more complex than implemented below. |
| 1283 return; | 1284 return; |
| 1284 } | 1285 } |
| 1285 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Right. | 1286 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Right. |
| 1286 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Left. | 1287 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Left. |
| 1287 __ orr(TMP, R0, Operand(R1)); | 1288 __ orr(TMP, R0, Operand(R1)); |
| 1288 __ tsti(TMP, Immediate(kSmiTagMask)); | 1289 __ tsti(TMP, Immediate(kSmiTagMask)); |
| 1289 __ b(not_smi_or_overflow, NE); | 1290 __ b(not_smi_or_overflow, NE); |
| 1290 switch (kind) { | 1291 switch (kind) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1301 case Token::kEQ: { | 1302 case Token::kEQ: { |
| 1302 __ CompareRegisters(R0, R1); | 1303 __ CompareRegisters(R0, R1); |
| 1303 __ LoadObject(R0, Bool::True(), PP); | 1304 __ LoadObject(R0, Bool::True(), PP); |
| 1304 __ LoadObject(R1, Bool::False(), PP); | 1305 __ LoadObject(R1, Bool::False(), PP); |
| 1305 __ csel(R0, R1, R0, NE); | 1306 __ csel(R0, R1, R0, NE); |
| 1306 break; | 1307 break; |
| 1307 } | 1308 } |
| 1308 default: UNIMPLEMENTED(); | 1309 default: UNIMPLEMENTED(); |
| 1309 } | 1310 } |
| 1310 | 1311 |
| 1312 if (should_update_result_range) { |
| 1313 Label done; |
| 1314 __ UpdateRangeFeedback(R0, 2, R5, R1, R6, &done); |
| 1315 __ Bind(&done); |
| 1316 } |
| 1317 |
| 1311 // R5: IC data object (preserved). | 1318 // R5: IC data object (preserved). |
| 1312 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset(), kNoPP); | 1319 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset(), kNoPP); |
| 1313 // R6: ic_data_array with check entries: classes and target functions. | 1320 // R6: ic_data_array with check entries: classes and target functions. |
| 1314 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag, kNoPP); | 1321 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag, kNoPP); |
| 1315 // R6: points directly to the first ic data array element. | 1322 // R6: points directly to the first ic data array element. |
| 1316 #if defined(DEBUG) | 1323 #if defined(DEBUG) |
| 1317 // Check that first entry is for Smi/Smi. | 1324 // Check that first entry is for Smi/Smi. |
| 1318 Label error, ok; | 1325 Label error, ok; |
| 1319 const intptr_t imm_smi_cid = reinterpret_cast<intptr_t>(Smi::New(kSmiCid)); | 1326 const intptr_t imm_smi_cid = reinterpret_cast<intptr_t>(Smi::New(kSmiCid)); |
| 1320 __ ldr(R1, Address(R6, 0)); | 1327 __ ldr(R1, Address(R6, 0)); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1346 // - If receiver is null -> jump to IC miss. | 1353 // - If receiver is null -> jump to IC miss. |
| 1347 // - If receiver is Smi -> load Smi class. | 1354 // - If receiver is Smi -> load Smi class. |
| 1348 // - If receiver is not-Smi -> load receiver's class. | 1355 // - If receiver is not-Smi -> load receiver's class. |
| 1349 // - Check if 'num_args' (including receiver) match any IC data group. | 1356 // - Check if 'num_args' (including receiver) match any IC data group. |
| 1350 // - Match found -> jump to target. | 1357 // - Match found -> jump to target. |
| 1351 // - Match not found -> jump to IC miss. | 1358 // - Match not found -> jump to IC miss. |
| 1352 void StubCode::GenerateNArgsCheckInlineCacheStub( | 1359 void StubCode::GenerateNArgsCheckInlineCacheStub( |
| 1353 Assembler* assembler, | 1360 Assembler* assembler, |
| 1354 intptr_t num_args, | 1361 intptr_t num_args, |
| 1355 const RuntimeEntry& handle_ic_miss, | 1362 const RuntimeEntry& handle_ic_miss, |
| 1356 Token::Kind kind) { | 1363 Token::Kind kind, |
| 1364 RangeCollectionMode range_collection_mode) { |
| 1357 ASSERT(num_args > 0); | 1365 ASSERT(num_args > 0); |
| 1358 #if defined(DEBUG) | 1366 #if defined(DEBUG) |
| 1359 { Label ok; | 1367 { Label ok; |
| 1360 // Check that the IC data array has NumArgsTested() == num_args. | 1368 // Check that the IC data array has NumArgsTested() == num_args. |
| 1361 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. | 1369 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. |
| 1362 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag, | 1370 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag, |
| 1363 kNoPP, kUnsignedWord); | 1371 kNoPP, kUnsignedWord); |
| 1364 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. | 1372 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
| 1365 __ andi(R6, R6, Immediate(ICData::NumArgsTestedMask())); | 1373 __ andi(R6, R6, Immediate(ICData::NumArgsTestedMask())); |
| 1366 __ CompareImmediate(R6, num_args, kNoPP); | 1374 __ CompareImmediate(R6, num_args, kNoPP); |
| 1367 __ b(&ok, EQ); | 1375 __ b(&ok, EQ); |
| 1368 __ Stop("Incorrect stub for IC data"); | 1376 __ Stop("Incorrect stub for IC data"); |
| 1369 __ Bind(&ok); | 1377 __ Bind(&ok); |
| 1370 } | 1378 } |
| 1371 #endif // DEBUG | 1379 #endif // DEBUG |
| 1372 | 1380 |
| 1373 // Check single stepping. | 1381 // Check single stepping. |
| 1374 Label stepping, done_stepping; | 1382 Label stepping, done_stepping; |
| 1375 __ LoadIsolate(R6, kNoPP); | 1383 __ LoadIsolate(R6, kNoPP); |
| 1376 __ LoadFromOffset( | 1384 __ LoadFromOffset( |
| 1377 R6, R6, Isolate::single_step_offset(), kNoPP, kUnsignedByte); | 1385 R6, R6, Isolate::single_step_offset(), kNoPP, kUnsignedByte); |
| 1378 __ CompareRegisters(R6, ZR); | 1386 __ CompareRegisters(R6, ZR); |
| 1379 __ b(&stepping, NE); | 1387 __ b(&stepping, NE); |
| 1380 __ Bind(&done_stepping); | 1388 __ Bind(&done_stepping); |
| 1381 | 1389 |
| 1390 Label not_smi_or_overflow; |
| 1391 if (range_collection_mode == kCollectRanges) { |
| 1392 ASSERT((num_args == 1) || (num_args == 2)); |
| 1393 if (num_args == 2) { |
| 1394 __ ldr(R0, Address(SP, 1 * kWordSize)); |
| 1395 __ UpdateRangeFeedback(R0, 0, R5, R1, R4, ¬_smi_or_overflow); |
| 1396 } |
| 1397 |
| 1398 __ ldr(R0, Address(SP, 0 * kWordSize)); |
| 1399 __ UpdateRangeFeedback(R0, num_args - 1, R5, R1, R4, ¬_smi_or_overflow); |
| 1400 } |
| 1382 if (kind != Token::kILLEGAL) { | 1401 if (kind != Token::kILLEGAL) { |
| 1383 Label not_smi_or_overflow; | 1402 EmitFastSmiOp(assembler, |
| 1384 EmitFastSmiOp(assembler, kind, num_args, ¬_smi_or_overflow); | 1403 kind, |
| 1385 __ Bind(¬_smi_or_overflow); | 1404 num_args, |
| 1405 ¬_smi_or_overflow, |
| 1406 (range_collection_mode == kCollectRanges)); |
| 1386 } | 1407 } |
| 1408 __ Bind(¬_smi_or_overflow); |
| 1387 | 1409 |
| 1388 // Load arguments descriptor into R4. | 1410 // Load arguments descriptor into R4. |
| 1389 __ LoadFieldFromOffset(R4, R5, ICData::arguments_descriptor_offset(), kNoPP); | 1411 __ LoadFieldFromOffset(R4, R5, ICData::arguments_descriptor_offset(), kNoPP); |
| 1390 // Loop that checks if there is an IC data match. | 1412 // Loop that checks if there is an IC data match. |
| 1391 Label loop, update, test, found; | 1413 Label loop, update, test, found; |
| 1392 // R5: IC data object (preserved). | 1414 // R5: IC data object (preserved). |
| 1393 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset(), kNoPP); | 1415 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset(), kNoPP); |
| 1394 // R6: ic_data_array with check entries: classes and target functions. | 1416 // R6: ic_data_array with check entries: classes and target functions. |
| 1395 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag, kNoPP); | 1417 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag, kNoPP); |
| 1396 // R6: points directly to the first ic data array element. | 1418 // R6: points directly to the first ic data array element. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1490 __ adds(R1, R1, Operand(Smi::RawValue(1))); | 1512 __ adds(R1, R1, Operand(Smi::RawValue(1))); |
| 1491 __ LoadImmediate(R2, Smi::RawValue(Smi::kMaxValue), kNoPP); | 1513 __ LoadImmediate(R2, Smi::RawValue(Smi::kMaxValue), kNoPP); |
| 1492 __ csel(R1, R2, R1, VS); // Overflow. | 1514 __ csel(R1, R2, R1, VS); // Overflow. |
| 1493 __ StoreToOffset(R1, R6, count_offset, kNoPP); | 1515 __ StoreToOffset(R1, R6, count_offset, kNoPP); |
| 1494 | 1516 |
| 1495 __ Bind(&call_target_function); | 1517 __ Bind(&call_target_function); |
| 1496 // R0: target function. | 1518 // R0: target function. |
| 1497 __ LoadFieldFromOffset(R2, R0, Function::instructions_offset(), kNoPP); | 1519 __ LoadFieldFromOffset(R2, R0, Function::instructions_offset(), kNoPP); |
| 1498 __ AddImmediate( | 1520 __ AddImmediate( |
| 1499 R2, R2, Instructions::HeaderSize() - kHeapObjectTag, kNoPP); | 1521 R2, R2, Instructions::HeaderSize() - kHeapObjectTag, kNoPP); |
| 1500 __ br(R2); | 1522 if (range_collection_mode == kCollectRanges) { |
| 1523 __ ldr(R1, Address(SP, 0 * kWordSize)); |
| 1524 if (num_args == 2) { |
| 1525 __ ldr(R3, Address(SP, 1 * kWordSize)); |
| 1526 } |
| 1527 __ EnterStubFrame(); |
| 1528 __ Push(R5); |
| 1529 if (num_args == 2) { |
| 1530 __ Push(R3); |
| 1531 } |
| 1532 __ Push(R1); |
| 1533 __ blr(R2); |
| 1534 |
| 1535 Label done; |
| 1536 __ ldr(R5, Address(FP, kFirstLocalSlotFromFp * kWordSize)); |
| 1537 __ UpdateRangeFeedback(R0, 2, R5, R1, R4, &done); |
| 1538 __ Bind(&done); |
| 1539 __ LeaveStubFrame(); |
| 1540 __ ret(); |
| 1541 } else { |
| 1542 __ br(R2); |
| 1543 } |
| 1501 | 1544 |
| 1502 __ Bind(&stepping); | 1545 __ Bind(&stepping); |
| 1503 __ EnterStubFrame(); | 1546 __ EnterStubFrame(); |
| 1504 __ Push(R5); // Preserve IC data. | 1547 __ Push(R5); // Preserve IC data. |
| 1505 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1548 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 1506 __ Pop(R5); | 1549 __ Pop(R5); |
| 1507 __ LeaveStubFrame(); | 1550 __ LeaveStubFrame(); |
| 1508 __ b(&done_stepping); | 1551 __ b(&done_stepping); |
| 1509 } | 1552 } |
| 1510 | 1553 |
| 1511 | 1554 |
| 1512 // Use inline cache data array to invoke the target or continue in inline | 1555 // Use inline cache data array to invoke the target or continue in inline |
| 1513 // cache miss handler. Stub for 1-argument check (receiver class). | 1556 // cache miss handler. Stub for 1-argument check (receiver class). |
| 1514 // LR: return address. | 1557 // LR: return address. |
| 1515 // R5: inline cache data object. | 1558 // R5: inline cache data object. |
| 1516 // Inline cache data object structure: | 1559 // Inline cache data object structure: |
| 1517 // 0: function-name | 1560 // 0: function-name |
| 1518 // 1: N, number of arguments checked. | 1561 // 1: N, number of arguments checked. |
| 1519 // 2 .. (length - 1): group of checks, each check containing: | 1562 // 2 .. (length - 1): group of checks, each check containing: |
| 1520 // - N classes. | 1563 // - N classes. |
| 1521 // - 1 target function. | 1564 // - 1 target function. |
| 1522 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { | 1565 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { |
| 1523 GenerateUsageCounterIncrement(assembler, R6); | 1566 GenerateUsageCounterIncrement(assembler, R6); |
| 1524 GenerateNArgsCheckInlineCacheStub(assembler, 1, | 1567 GenerateNArgsCheckInlineCacheStub(assembler, 1, |
| 1525 kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL); | 1568 kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL, |
| 1569 kIgnoreRanges); |
| 1526 } | 1570 } |
| 1527 | 1571 |
| 1528 | 1572 |
| 1529 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { | 1573 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { |
| 1530 GenerateUsageCounterIncrement(assembler, R6); | 1574 GenerateUsageCounterIncrement(assembler, R6); |
| 1531 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1575 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1532 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL); | 1576 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL, |
| 1577 kIgnoreRanges); |
| 1533 } | 1578 } |
| 1534 | 1579 |
| 1535 | 1580 |
| 1536 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) { | 1581 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) { |
| 1537 GenerateUsageCounterIncrement(assembler, R6); | 1582 GenerateUsageCounterIncrement(assembler, R6); |
| 1538 GenerateNArgsCheckInlineCacheStub(assembler, 3, | 1583 GenerateNArgsCheckInlineCacheStub(assembler, 3, |
| 1539 kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL); | 1584 kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL, |
| 1585 kIgnoreRanges); |
| 1540 } | 1586 } |
| 1541 | 1587 |
| 1542 | 1588 |
| 1543 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) { | 1589 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) { |
| 1544 GenerateUsageCounterIncrement(assembler, R6); | 1590 GenerateUsageCounterIncrement(assembler, R6); |
| 1545 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1591 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1546 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD); | 1592 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD, |
| 1593 kCollectRanges); |
| 1547 } | 1594 } |
| 1548 | 1595 |
| 1549 | 1596 |
| 1550 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) { | 1597 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) { |
| 1551 GenerateUsageCounterIncrement(assembler, R6); | 1598 GenerateUsageCounterIncrement(assembler, R6); |
| 1552 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1599 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1553 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB); | 1600 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB, |
| 1601 kCollectRanges); |
| 1554 } | 1602 } |
| 1555 | 1603 |
| 1556 | 1604 |
| 1557 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) { | 1605 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) { |
| 1558 GenerateUsageCounterIncrement(assembler, R6); | 1606 GenerateUsageCounterIncrement(assembler, R6); |
| 1559 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1607 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1560 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ); | 1608 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ, |
| 1609 kIgnoreRanges); |
| 1561 } | 1610 } |
| 1562 | 1611 |
| 1563 | 1612 |
| 1613 void StubCode::GenerateUnaryRangeCollectingInlineCacheStub( |
| 1614 Assembler* assembler) { |
| 1615 GenerateUsageCounterIncrement(assembler, R6); |
| 1616 GenerateNArgsCheckInlineCacheStub(assembler, 1, |
| 1617 kInlineCacheMissHandlerOneArgRuntimeEntry, |
| 1618 Token::kILLEGAL, |
| 1619 kCollectRanges); |
| 1620 } |
| 1621 |
| 1622 |
| 1623 void StubCode::GenerateBinaryRangeCollectingInlineCacheStub( |
| 1624 Assembler* assembler) { |
| 1625 GenerateUsageCounterIncrement(assembler, R6); |
| 1626 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1627 kInlineCacheMissHandlerTwoArgsRuntimeEntry, |
| 1628 Token::kILLEGAL, |
| 1629 kCollectRanges); |
| 1630 } |
| 1631 |
| 1632 |
| 1564 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub( | 1633 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub( |
| 1565 Assembler* assembler) { | 1634 Assembler* assembler) { |
| 1566 GenerateOptimizedUsageCounterIncrement(assembler); | 1635 GenerateOptimizedUsageCounterIncrement(assembler); |
| 1567 GenerateNArgsCheckInlineCacheStub(assembler, 1, | 1636 GenerateNArgsCheckInlineCacheStub(assembler, 1, |
| 1568 kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL); | 1637 kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL, |
| 1638 kIgnoreRanges); |
| 1569 } | 1639 } |
| 1570 | 1640 |
| 1571 | 1641 |
| 1572 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub( | 1642 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub( |
| 1573 Assembler* assembler) { | 1643 Assembler* assembler) { |
| 1574 GenerateOptimizedUsageCounterIncrement(assembler); | 1644 GenerateOptimizedUsageCounterIncrement(assembler); |
| 1575 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1645 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1576 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL); | 1646 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL, |
| 1647 kIgnoreRanges); |
| 1577 } | 1648 } |
| 1578 | 1649 |
| 1579 | 1650 |
| 1580 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub( | 1651 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub( |
| 1581 Assembler* assembler) { | 1652 Assembler* assembler) { |
| 1582 GenerateOptimizedUsageCounterIncrement(assembler); | 1653 GenerateOptimizedUsageCounterIncrement(assembler); |
| 1583 GenerateNArgsCheckInlineCacheStub(assembler, 3, | 1654 GenerateNArgsCheckInlineCacheStub(assembler, 3, |
| 1584 kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL); | 1655 kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL, |
| 1656 kIgnoreRanges); |
| 1585 } | 1657 } |
| 1586 | 1658 |
| 1587 | 1659 |
| 1588 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { | 1660 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { |
| 1589 GenerateUsageCounterIncrement(assembler, R6); | 1661 GenerateUsageCounterIncrement(assembler, R6); |
| 1590 #if defined(DEBUG) | 1662 #if defined(DEBUG) |
| 1591 { Label ok; | 1663 { Label ok; |
| 1592 // Check that the IC data array has NumArgsTested() == 0. | 1664 // Check that the IC data array has NumArgsTested() == 0. |
| 1593 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. | 1665 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. |
| 1594 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag, | 1666 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1645 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1717 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 1646 __ Pop(R5); | 1718 __ Pop(R5); |
| 1647 __ LeaveStubFrame(); | 1719 __ LeaveStubFrame(); |
| 1648 __ b(&done_stepping); | 1720 __ b(&done_stepping); |
| 1649 } | 1721 } |
| 1650 | 1722 |
| 1651 | 1723 |
| 1652 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) { | 1724 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) { |
| 1653 GenerateUsageCounterIncrement(assembler, R6); | 1725 GenerateUsageCounterIncrement(assembler, R6); |
| 1654 GenerateNArgsCheckInlineCacheStub( | 1726 GenerateNArgsCheckInlineCacheStub( |
| 1655 assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL); | 1727 assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL, |
| 1728 kIgnoreRanges); |
| 1656 } | 1729 } |
| 1657 | 1730 |
| 1658 | 1731 |
| 1659 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { | 1732 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { |
| 1660 GenerateUsageCounterIncrement(assembler, R6); | 1733 GenerateUsageCounterIncrement(assembler, R6); |
| 1661 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1734 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1662 kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL); | 1735 kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL, |
| 1736 kIgnoreRanges); |
| 1663 } | 1737 } |
| 1664 | 1738 |
| 1665 | 1739 |
| 1666 // Stub for compiling a function and jumping to the compiled code. | 1740 // Stub for compiling a function and jumping to the compiled code. |
| 1667 // R5: IC-Data (for methods). | 1741 // R5: IC-Data (for methods). |
| 1668 // R4: Arguments descriptor. | 1742 // R4: Arguments descriptor. |
| 1669 // R0: Function. | 1743 // R0: Function. |
| 1670 void StubCode::GenerateLazyCompileStub(Assembler* assembler) { | 1744 void StubCode::GenerateLazyCompileStub(Assembler* assembler) { |
| 1671 // Preserve arg desc. and IC data object. | 1745 // Preserve arg desc. and IC data object. |
| 1672 __ EnterStubFrame(); | 1746 __ EnterStubFrame(); |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2016 const Register right = R0; | 2090 const Register right = R0; |
| 2017 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP); | 2091 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP); |
| 2018 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP); | 2092 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP); |
| 2019 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2093 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 2020 __ ret(); | 2094 __ ret(); |
| 2021 } | 2095 } |
| 2022 | 2096 |
| 2023 } // namespace dart | 2097 } // namespace dart |
| 2024 | 2098 |
| 2025 #endif // defined TARGET_ARCH_ARM64 | 2099 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |