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

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

Issue 19774007: Collect both arguments for math's min/max static functions. Later that information will be used to … (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 months 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/compiler.h" 10 #include "vm/compiler.h"
(...skipping 1344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 // Generate inline cache check for 'num_args'. 1355 // Generate inline cache check for 'num_args'.
1356 // LR: return address. 1356 // LR: return address.
1357 // R5: inline cache data object. 1357 // R5: inline cache data object.
1358 // Control flow: 1358 // Control flow:
1359 // - If receiver is null -> jump to IC miss. 1359 // - If receiver is null -> jump to IC miss.
1360 // - If receiver is Smi -> load Smi class. 1360 // - If receiver is Smi -> load Smi class.
1361 // - If receiver is not-Smi -> load receiver's class. 1361 // - If receiver is not-Smi -> load receiver's class.
1362 // - Check if 'num_args' (including receiver) match any IC data group. 1362 // - Check if 'num_args' (including receiver) match any IC data group.
1363 // - Match found -> jump to target. 1363 // - Match found -> jump to target.
1364 // - Match not found -> jump to IC miss. 1364 // - Match not found -> jump to IC miss.
1365 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, 1365 void StubCode::GenerateNArgsCheckInlineCacheStub(
1366 intptr_t num_args) { 1366 Assembler* assembler,
1367 intptr_t num_args,
1368 const RuntimeEntry& handle_ic_miss) {
1367 ASSERT(num_args > 0); 1369 ASSERT(num_args > 0);
1368 #if defined(DEBUG) 1370 #if defined(DEBUG)
1369 { Label ok; 1371 { Label ok;
1370 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. 1372 // Check that the IC data array has NumberOfArgumentsChecked() == num_args.
1371 // 'num_args_tested' is stored as an untagged int. 1373 // 'num_args_tested' is stored as an untagged int.
1372 __ ldr(R6, FieldAddress(R5, ICData::num_args_tested_offset())); 1374 __ ldr(R6, FieldAddress(R5, ICData::num_args_tested_offset()));
1373 __ CompareImmediate(R6, num_args); 1375 __ CompareImmediate(R6, num_args);
1374 __ b(&ok, EQ); 1376 __ b(&ok, EQ);
1375 __ Stop("Incorrect stub for IC data"); 1377 __ Stop("Incorrect stub for IC data");
1376 __ Bind(&ok); 1378 __ Bind(&ok);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1463 // Preserve IC data object and arguments descriptor array and 1465 // Preserve IC data object and arguments descriptor array and
1464 // setup space on stack for result (target code object). 1466 // setup space on stack for result (target code object).
1465 __ PushList((1 << R0) | (1 << R4) | (1 << R5)); 1467 __ PushList((1 << R0) | (1 << R4) | (1 << R5));
1466 // Push call arguments. 1468 // Push call arguments.
1467 for (intptr_t i = 0; i < num_args; i++) { 1469 for (intptr_t i = 0; i < num_args; i++) {
1468 __ LoadFromOffset(kWord, IP, R7, -i * kWordSize); 1470 __ LoadFromOffset(kWord, IP, R7, -i * kWordSize);
1469 __ Push(IP); 1471 __ Push(IP);
1470 } 1472 }
1471 // Pass IC data object. 1473 // Pass IC data object.
1472 __ Push(R5); 1474 __ Push(R5);
1473 1475 __ CallRuntime(handle_ic_miss);
1474 if (num_args == 1) {
1475 __ CallRuntime(kInlineCacheMissHandlerOneArgRuntimeEntry);
1476 } else if (num_args == 2) {
1477 __ CallRuntime(kInlineCacheMissHandlerTwoArgsRuntimeEntry);
1478 } else if (num_args == 3) {
1479 __ CallRuntime(kInlineCacheMissHandlerThreeArgsRuntimeEntry);
1480 } else {
1481 UNIMPLEMENTED();
1482 }
1483 // Remove the call arguments pushed earlier, including the IC data object. 1476 // Remove the call arguments pushed earlier, including the IC data object.
1484 __ Drop(num_args + 1); 1477 __ Drop(num_args + 1);
1485 // Pop returned code object into R0 (null if not found). 1478 // Pop returned code object into R0 (null if not found).
1486 // Restore arguments descriptor array and IC data array. 1479 // Restore arguments descriptor array and IC data array.
1487 __ PopList((1 << R0) | (1 << R4) | (1 << R5)); 1480 __ PopList((1 << R0) | (1 << R4) | (1 << R5));
1488 __ LeaveStubFrame(); 1481 __ LeaveStubFrame();
1489 Label call_target_function; 1482 Label call_target_function;
1490 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); 1483 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
1491 __ b(&call_target_function, NE); 1484 __ b(&call_target_function, NE);
1492 // NoSuchMethod or closure. 1485 // NoSuchMethod or closure.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1533 // LR: return address. 1526 // LR: return address.
1534 // R5: inline cache data object. 1527 // R5: inline cache data object.
1535 // Inline cache data object structure: 1528 // Inline cache data object structure:
1536 // 0: function-name 1529 // 0: function-name
1537 // 1: N, number of arguments checked. 1530 // 1: N, number of arguments checked.
1538 // 2 .. (length - 1): group of checks, each check containing: 1531 // 2 .. (length - 1): group of checks, each check containing:
1539 // - N classes. 1532 // - N classes.
1540 // - 1 target function. 1533 // - 1 target function.
1541 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { 1534 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
1542 GenerateUsageCounterIncrement(assembler, R6); 1535 GenerateUsageCounterIncrement(assembler, R6);
1543 GenerateNArgsCheckInlineCacheStub(assembler, 1); 1536 GenerateNArgsCheckInlineCacheStub(
1537 assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
1544 } 1538 }
1545 1539
1546 1540
1547 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { 1541 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
1548 GenerateUsageCounterIncrement(assembler, R6); 1542 GenerateUsageCounterIncrement(assembler, R6);
1549 GenerateNArgsCheckInlineCacheStub(assembler, 2); 1543 GenerateNArgsCheckInlineCacheStub(
1544 assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
1550 } 1545 }
1551 1546
1552 1547
1553 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) { 1548 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
1554 GenerateUsageCounterIncrement(assembler, R6); 1549 GenerateUsageCounterIncrement(assembler, R6);
1555 GenerateNArgsCheckInlineCacheStub(assembler, 3); 1550 GenerateNArgsCheckInlineCacheStub(
1551 assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
1556 } 1552 }
1557 1553
1558 1554
1559 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub( 1555 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
1560 Assembler* assembler) { 1556 Assembler* assembler) {
1561 GenerateOptimizedUsageCounterIncrement(assembler); 1557 GenerateOptimizedUsageCounterIncrement(assembler);
1562 GenerateNArgsCheckInlineCacheStub(assembler, 1); 1558 GenerateNArgsCheckInlineCacheStub(
1559 assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
1563 } 1560 }
1564 1561
1565 1562
1566 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub( 1563 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
1567 Assembler* assembler) { 1564 Assembler* assembler) {
1568 GenerateOptimizedUsageCounterIncrement(assembler); 1565 GenerateOptimizedUsageCounterIncrement(assembler);
1569 GenerateNArgsCheckInlineCacheStub(assembler, 2); 1566 GenerateNArgsCheckInlineCacheStub(
1567 assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
1570 } 1568 }
1571 1569
1572 1570
1573 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub( 1571 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
1574 Assembler* assembler) { 1572 Assembler* assembler) {
1575 GenerateOptimizedUsageCounterIncrement(assembler); 1573 GenerateOptimizedUsageCounterIncrement(assembler);
1576 GenerateNArgsCheckInlineCacheStub(assembler, 3); 1574 GenerateNArgsCheckInlineCacheStub(
1575 assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
1577 } 1576 }
1578 1577
1579 1578
1580 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) { 1579 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) {
1581 GenerateNArgsCheckInlineCacheStub(assembler, 1); 1580 GenerateNArgsCheckInlineCacheStub(
1581 assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
1582 } 1582 }
1583 1583
1584 1584
1585 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { 1585 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
1586 GenerateNArgsCheckInlineCacheStub(assembler, 1); 1586 GenerateNArgsCheckInlineCacheStub(
1587 assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
1587 } 1588 }
1588 1589
1589 1590
1590 // Intermediary stub between a static call and its target. ICData contains 1591 // Intermediary stub between a static call and its target. ICData contains
1591 // the target function and the call count. 1592 // the target function and the call count.
1592 // R5: ICData 1593 // R5: ICData
1593 void StubCode::GenerateUnoptimizedStaticCallStub(Assembler* assembler) { 1594 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
1594 GenerateUsageCounterIncrement(assembler, R6); 1595 GenerateUsageCounterIncrement(assembler, R6);
1595 #if defined(DEBUG) 1596 #if defined(DEBUG)
1596 { Label ok; 1597 { Label ok;
1597 // Check that the IC data array has NumberOfArgumentsChecked() == 0. 1598 // Check that the IC data array has NumberOfArgumentsChecked() == 0.
1598 // 'num_args_tested' is stored as an untagged int. 1599 // 'num_args_tested' is stored as an untagged int.
1599 __ ldr(R6, FieldAddress(R5, ICData::num_args_tested_offset())); 1600 __ ldr(R6, FieldAddress(R5, ICData::num_args_tested_offset()));
1600 __ CompareImmediate(R6, 0); 1601 __ CompareImmediate(R6, 0);
1601 __ b(&ok, EQ); 1602 __ b(&ok, EQ);
1602 __ Stop("Incorrect IC data for unoptimized static call"); 1603 __ Stop("Incorrect IC data for unoptimized static call");
1603 __ Bind(&ok); 1604 __ Bind(&ok);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1657 __ Bind(&target_is_compiled); 1658 __ Bind(&target_is_compiled);
1658 // R0: target code. 1659 // R0: target code.
1659 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); 1660 __ ldr(R0, FieldAddress(R0, Code::instructions_offset()));
1660 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag); 1661 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag);
1661 // Load arguments descriptor into R4. 1662 // Load arguments descriptor into R4.
1662 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); 1663 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
1663 __ bx(R0); 1664 __ bx(R0);
1664 } 1665 }
1665 1666
1666 1667
1668 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
1669 GenerateUsageCounterIncrement(assembler, R6);
1670 GenerateNArgsCheckInlineCacheStub(
1671 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry);
1672 }
1673
1674
1667 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { 1675 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
1668 __ Unimplemented("BreakpointRuntime stub"); 1676 __ Unimplemented("BreakpointRuntime stub");
1669 } 1677 }
1670 1678
1671 1679
1672 // LR: return address (Dart code). 1680 // LR: return address (Dart code).
1673 // R5: IC data (unoptimized static call). 1681 // R5: IC data (unoptimized static call).
1674 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { 1682 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
1675 // Create a stub frame as we are pushing some objects on the stack before 1683 // Create a stub frame as we are pushing some objects on the stack before
1676 // calling into the runtime. 1684 // calling into the runtime.
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
2090 __ ldr(left, Address(SP, 4 * kWordSize)); 2098 __ ldr(left, Address(SP, 4 * kWordSize));
2091 __ ldr(right, Address(SP, 3 * kWordSize)); 2099 __ ldr(right, Address(SP, 3 * kWordSize));
2092 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 2100 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2093 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); 2101 __ PopList((1 << R0) | (1 << R1) | (1 << R2));
2094 __ Ret(); 2102 __ Ret();
2095 } 2103 }
2096 2104
2097 } // namespace dart 2105 } // namespace dart
2098 2106
2099 #endif // defined TARGET_ARCH_ARM 2107 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698