Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: runtime/vm/stub_code_arm.cc

Issue 735543003: Range feedback for binary integer operations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: ready for review Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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_ARM) 6 #if defined(TARGET_ARCH_ARM)
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/cpu.h" 10 #include "vm/cpu.h"
(...skipping 1298 matching lines...) Expand 10 before | Expand all | Expand 10 after
1309 // - If receiver is null -> jump to IC miss. 1309 // - If receiver is null -> jump to IC miss.
1310 // - If receiver is Smi -> load Smi class. 1310 // - If receiver is Smi -> load Smi class.
1311 // - If receiver is not-Smi -> load receiver's class. 1311 // - If receiver is not-Smi -> load receiver's class.
1312 // - Check if 'num_args' (including receiver) match any IC data group. 1312 // - Check if 'num_args' (including receiver) match any IC data group.
1313 // - Match found -> jump to target. 1313 // - Match found -> jump to target.
1314 // - Match not found -> jump to IC miss. 1314 // - Match not found -> jump to IC miss.
1315 void StubCode::GenerateNArgsCheckInlineCacheStub( 1315 void StubCode::GenerateNArgsCheckInlineCacheStub(
1316 Assembler* assembler, 1316 Assembler* assembler,
1317 intptr_t num_args, 1317 intptr_t num_args,
1318 const RuntimeEntry& handle_ic_miss, 1318 const RuntimeEntry& handle_ic_miss,
1319 Token::Kind kind) { 1319 Token::Kind kind,
1320 RangeCollectionMode range_collection_mode) {
1320 ASSERT(num_args > 0); 1321 ASSERT(num_args > 0);
1321 #if defined(DEBUG) 1322 #if defined(DEBUG)
1322 { Label ok; 1323 { Label ok;
1323 // Check that the IC data array has NumArgsTested() == num_args. 1324 // Check that the IC data array has NumArgsTested() == num_args.
1324 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. 1325 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
1325 __ ldr(R6, FieldAddress(R5, ICData::state_bits_offset())); 1326 __ ldr(R6, FieldAddress(R5, ICData::state_bits_offset()));
1326 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. 1327 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed.
1327 __ and_(R6, R6, Operand(ICData::NumArgsTestedMask())); 1328 __ and_(R6, R6, Operand(ICData::NumArgsTestedMask()));
1328 __ CompareImmediate(R6, num_args); 1329 __ CompareImmediate(R6, num_args);
1329 __ b(&ok, EQ); 1330 __ b(&ok, EQ);
1330 __ Stop("Incorrect stub for IC data"); 1331 __ Stop("Incorrect stub for IC data");
1331 __ Bind(&ok); 1332 __ Bind(&ok);
1332 } 1333 }
1333 #endif // DEBUG 1334 #endif // DEBUG
1334 1335
1335 1336
1336 // Check single stepping. 1337 // Check single stepping.
1337 Label stepping, done_stepping; 1338 Label stepping, done_stepping;
1338 __ LoadIsolate(R6); 1339 __ LoadIsolate(R6);
1339 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); 1340 __ ldrb(R6, Address(R6, Isolate::single_step_offset()));
1340 __ CompareImmediate(R6, 0); 1341 __ CompareImmediate(R6, 0);
1341 __ b(&stepping, NE); 1342 __ b(&stepping, NE);
1342 __ Bind(&done_stepping); 1343 __ Bind(&done_stepping);
1343 1344
1345 Label not_smi_or_overflow;
zra 2014/12/11 04:29:33 What is the effect of this change on unoptimized c
Vyacheslav Egorov (Google) 2014/12/11 13:06:25 There are no visible regression on the dart2js com
1346 if (range_collection_mode == kCollectRanges) {
1347 ASSERT((num_args == 1) || (num_args == 2));
1348 if (num_args == 2) {
1349 __ ldr(R0, Address(SP, 1 * kWordSize));
1350 __ UpdateRangeFeedback(R0, 0, R5, R1, R4, &not_smi_or_overflow);
1351 }
1352
1353 __ ldr(R0, Address(SP, 0 * kWordSize));
1354 __ UpdateRangeFeedback(R0, num_args - 1, R5, R1, R4, &not_smi_or_overflow);
1355 }
1344 if (kind != Token::kILLEGAL) { 1356 if (kind != Token::kILLEGAL) {
1345 Label not_smi_or_overflow;
1346 EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow); 1357 EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
1347 __ Bind(&not_smi_or_overflow);
1348 } 1358 }
1359 __ Bind(&not_smi_or_overflow);
1349 1360
1350 // Load arguments descriptor into R4. 1361 // Load arguments descriptor into R4.
1351 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); 1362 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
1352 // Loop that checks if there is an IC data match. 1363 // Loop that checks if there is an IC data match.
1353 Label loop, update, test, found; 1364 Label loop, update, test, found;
1354 // R5: IC data object (preserved). 1365 // R5: IC data object (preserved).
1355 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset())); 1366 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset()));
1356 // R6: ic_data_array with check entries: classes and target functions. 1367 // R6: ic_data_array with check entries: classes and target functions.
1357 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); 1368 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag);
1358 // R6: points directly to the first ic data array element. 1369 // R6: points directly to the first ic data array element.
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1440 // Update counter. 1451 // Update counter.
1441 __ LoadFromOffset(kWord, R1, R6, count_offset); 1452 __ LoadFromOffset(kWord, R1, R6, count_offset);
1442 __ adds(R1, R1, Operand(Smi::RawValue(1))); 1453 __ adds(R1, R1, Operand(Smi::RawValue(1)));
1443 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS); // Overflow. 1454 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS); // Overflow.
1444 __ StoreIntoSmiField(Address(R6, count_offset), R1); 1455 __ StoreIntoSmiField(Address(R6, count_offset), R1);
1445 1456
1446 __ Bind(&call_target_function); 1457 __ Bind(&call_target_function);
1447 // R0: target function. 1458 // R0: target function.
1448 __ ldr(R2, FieldAddress(R0, Function::instructions_offset())); 1459 __ ldr(R2, FieldAddress(R0, Function::instructions_offset()));
1449 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag); 1460 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
1450 __ bx(R2); 1461 if (range_collection_mode == kCollectRanges) {
1462 __ ldr(R1, Address(SP, 0 * kWordSize));
1463 if (num_args == 2) {
1464 __ ldr(R3, Address(SP, 1 * kWordSize));
1465 }
1466 __ EnterStubFrame();
1467 if (num_args == 2) {
1468 __ PushList((1 << R1) | (1 << R3) | (1 << R5));
1469 } else {
1470 __ PushList((1 << R1) | (1 << R5));
1471 }
1472 __ blx(R2);
1473
1474 Label done;
1475 __ ldr(R5, Address(FP, kFirstLocalSlotFromFp * kWordSize));
1476 __ UpdateRangeFeedback(R0, 2, R5, R1, R4, &done);
1477 __ Bind(&done);
1478 __ LeaveStubFrame();
1479 __ Ret();
1480 } else {
1481 __ bx(R2);
1482 }
1451 1483
1452 __ Bind(&stepping); 1484 __ Bind(&stepping);
1453 __ EnterStubFrame(); 1485 __ EnterStubFrame();
1454 __ Push(R5); // Preserve IC data. 1486 __ Push(R5); // Preserve IC data.
1455 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); 1487 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
1456 __ Pop(R5); 1488 __ Pop(R5);
1457 __ LeaveStubFrame(); 1489 __ LeaveStubFrame();
1458 __ b(&done_stepping); 1490 __ b(&done_stepping);
1459 } 1491 }
1460 1492
1461 1493
1462 // Use inline cache data array to invoke the target or continue in inline 1494 // Use inline cache data array to invoke the target or continue in inline
1463 // cache miss handler. Stub for 1-argument check (receiver class). 1495 // cache miss handler. Stub for 1-argument check (receiver class).
1464 // LR: return address. 1496 // LR: return address.
1465 // R5: inline cache data object. 1497 // R5: inline cache data object.
1466 // Inline cache data object structure: 1498 // Inline cache data object structure:
1467 // 0: function-name 1499 // 0: function-name
1468 // 1: N, number of arguments checked. 1500 // 1: N, number of arguments checked.
1469 // 2 .. (length - 1): group of checks, each check containing: 1501 // 2 .. (length - 1): group of checks, each check containing:
1470 // - N classes. 1502 // - N classes.
1471 // - 1 target function. 1503 // - 1 target function.
1472 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { 1504 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
1473 GenerateUsageCounterIncrement(assembler, R6); 1505 GenerateUsageCounterIncrement(assembler, R6);
1474 GenerateNArgsCheckInlineCacheStub(assembler, 1, 1506 GenerateNArgsCheckInlineCacheStub(assembler,
1475 kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL); 1507 1,
1508 kInlineCacheMissHandlerOneArgRuntimeEntry,
1509 Token::kILLEGAL,
1510 kIgnoreRanges);
1476 } 1511 }
1477 1512
1478 1513
1479 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { 1514 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
1480 GenerateUsageCounterIncrement(assembler, R6); 1515 GenerateUsageCounterIncrement(assembler, R6);
1481 GenerateNArgsCheckInlineCacheStub(assembler, 2, 1516 GenerateNArgsCheckInlineCacheStub(assembler,
1482 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL); 1517 2,
1518 kInlineCacheMissHandlerTwoArgsRuntimeEntry,
1519 Token::kILLEGAL,
1520 kIgnoreRanges);
1483 } 1521 }
1484 1522
1485 1523
1486 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) { 1524 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
1487 GenerateUsageCounterIncrement(assembler, R6); 1525 GenerateUsageCounterIncrement(assembler, R6);
1488 GenerateNArgsCheckInlineCacheStub(assembler, 3, 1526 GenerateNArgsCheckInlineCacheStub(assembler,
1489 kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL); 1527 3,
1528 kInlineCacheMissHandlerThreeArgsRuntimeEntry,
1529 Token::kILLEGAL,
1530 kIgnoreRanges);
1490 } 1531 }
1491 1532
1492 1533
1493 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) { 1534 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
1494 GenerateUsageCounterIncrement(assembler, R6); 1535 GenerateUsageCounterIncrement(assembler, R6);
1495 GenerateNArgsCheckInlineCacheStub(assembler, 2, 1536 GenerateNArgsCheckInlineCacheStub(assembler,
1496 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD); 1537 2,
1538 kInlineCacheMissHandlerTwoArgsRuntimeEntry,
1539 Token::kADD,
1540 kCollectRanges);
1497 } 1541 }
1498 1542
1499 1543
1500 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) { 1544 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
1501 GenerateUsageCounterIncrement(assembler, R6); 1545 GenerateUsageCounterIncrement(assembler, R6);
1502 GenerateNArgsCheckInlineCacheStub(assembler, 2, 1546 GenerateNArgsCheckInlineCacheStub(assembler, 2,
1503 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB); 1547 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB,
1548 kCollectRanges);
1504 } 1549 }
1505 1550
1506 1551
1507 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) { 1552 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
1508 GenerateUsageCounterIncrement(assembler, R6); 1553 GenerateUsageCounterIncrement(assembler, R6);
1509 GenerateNArgsCheckInlineCacheStub(assembler, 2, 1554 GenerateNArgsCheckInlineCacheStub(assembler, 2,
1510 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ); 1555 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ,
1556 kIgnoreRanges);
1511 } 1557 }
1512 1558
1513 1559
1560 void StubCode::GenerateUnaryRangeCollectingInlineCacheStub(
1561 Assembler* assembler) {
1562 GenerateUsageCounterIncrement(assembler, R6);
1563 GenerateNArgsCheckInlineCacheStub(assembler, 1,
1564 kInlineCacheMissHandlerOneArgRuntimeEntry,
1565 Token::kILLEGAL,
1566 kCollectRanges);
1567 }
1568
1569
1570 void StubCode::GenerateBinaryRangeCollectingInlineCacheStub(
1571 Assembler* assembler) {
1572 GenerateUsageCounterIncrement(assembler, R6);
1573 GenerateNArgsCheckInlineCacheStub(assembler, 2,
1574 kInlineCacheMissHandlerTwoArgsRuntimeEntry,
1575 Token::kILLEGAL,
1576 kCollectRanges);
1577 }
1578
1579
1514 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub( 1580 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
1515 Assembler* assembler) { 1581 Assembler* assembler) {
1516 GenerateOptimizedUsageCounterIncrement(assembler); 1582 GenerateOptimizedUsageCounterIncrement(assembler);
1517 GenerateNArgsCheckInlineCacheStub(assembler, 1, 1583 GenerateNArgsCheckInlineCacheStub(assembler, 1,
1518 kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL); 1584 kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
1585 kIgnoreRanges);
1519 } 1586 }
1520 1587
1521 1588
1522 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub( 1589 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
1523 Assembler* assembler) { 1590 Assembler* assembler) {
1524 GenerateOptimizedUsageCounterIncrement(assembler); 1591 GenerateOptimizedUsageCounterIncrement(assembler);
1525 GenerateNArgsCheckInlineCacheStub(assembler, 2, 1592 GenerateNArgsCheckInlineCacheStub(assembler, 2,
1526 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL); 1593 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
1594 kIgnoreRanges);
1527 } 1595 }
1528 1596
1529 1597
1530 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub( 1598 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
1531 Assembler* assembler) { 1599 Assembler* assembler) {
1532 GenerateOptimizedUsageCounterIncrement(assembler); 1600 GenerateOptimizedUsageCounterIncrement(assembler);
1533 GenerateNArgsCheckInlineCacheStub(assembler, 3, 1601 GenerateNArgsCheckInlineCacheStub(assembler, 3,
1534 kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL); 1602 kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL,
1603 kIgnoreRanges);
1535 } 1604 }
1536 1605
1537 1606
1538 // Intermediary stub between a static call and its target. ICData contains 1607 // Intermediary stub between a static call and its target. ICData contains
1539 // the target function and the call count. 1608 // the target function and the call count.
1540 // R5: ICData 1609 // R5: ICData
1541 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { 1610 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
1542 GenerateUsageCounterIncrement(assembler, R6); 1611 GenerateUsageCounterIncrement(assembler, R6);
1543 #if defined(DEBUG) 1612 #if defined(DEBUG)
1544 { Label ok; 1613 { Label ok;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1594 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); 1663 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
1595 __ Pop(R5); 1664 __ Pop(R5);
1596 __ LeaveStubFrame(); 1665 __ LeaveStubFrame();
1597 __ b(&done_stepping); 1666 __ b(&done_stepping);
1598 } 1667 }
1599 1668
1600 1669
1601 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) { 1670 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) {
1602 GenerateUsageCounterIncrement(assembler, R6); 1671 GenerateUsageCounterIncrement(assembler, R6);
1603 GenerateNArgsCheckInlineCacheStub( 1672 GenerateNArgsCheckInlineCacheStub(
1604 assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL); 1673 assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
1674 kIgnoreRanges);
1605 } 1675 }
1606 1676
1607 1677
1608 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { 1678 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
1609 GenerateUsageCounterIncrement(assembler, R6); 1679 GenerateUsageCounterIncrement(assembler, R6);
1610 GenerateNArgsCheckInlineCacheStub(assembler, 2, 1680 GenerateNArgsCheckInlineCacheStub(assembler, 2,
1611 kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL); 1681 kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
1682 kIgnoreRanges);
1612 } 1683 }
1613 1684
1614 1685
1615 // Stub for compiling a function and jumping to the compiled code. 1686 // Stub for compiling a function and jumping to the compiled code.
1616 // R5: IC-Data (for methods). 1687 // R5: IC-Data (for methods).
1617 // R4: Arguments descriptor. 1688 // R4: Arguments descriptor.
1618 // R0: Function. 1689 // R0: Function.
1619 void StubCode::GenerateLazyCompileStub(Assembler* assembler) { 1690 void StubCode::GenerateLazyCompileStub(Assembler* assembler) {
1620 // Preserve arg desc. and IC data object. 1691 // Preserve arg desc. and IC data object.
1621 __ EnterStubFrame(); 1692 __ EnterStubFrame();
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
1971 const Register right = R0; 2042 const Register right = R0;
1972 __ ldr(left, Address(SP, 1 * kWordSize)); 2043 __ ldr(left, Address(SP, 1 * kWordSize));
1973 __ ldr(right, Address(SP, 0 * kWordSize)); 2044 __ ldr(right, Address(SP, 0 * kWordSize));
1974 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 2045 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
1975 __ Ret(); 2046 __ Ret();
1976 } 2047 }
1977 2048
1978 } // namespace dart 2049 } // namespace dart
1979 2050
1980 #endif // defined TARGET_ARCH_ARM 2051 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698