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

Side by Side Diff: runtime/vm/stub_code_ia32.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_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 1399 matching lines...) Expand 10 before | Expand all | Expand 10 after
1410 // Generate inline cache check for 'num_args'. 1410 // Generate inline cache check for 'num_args'.
1411 // ECX: Inline cache data object. 1411 // ECX: Inline cache data object.
1412 // TOS(0): return address 1412 // TOS(0): return address
1413 // Control flow: 1413 // Control flow:
1414 // - If receiver is null -> jump to IC miss. 1414 // - If receiver is null -> jump to IC miss.
1415 // - If receiver is Smi -> load Smi class. 1415 // - If receiver is Smi -> load Smi class.
1416 // - If receiver is not-Smi -> load receiver's class. 1416 // - If receiver is not-Smi -> load receiver's class.
1417 // - Check if 'num_args' (including receiver) match any IC data group. 1417 // - Check if 'num_args' (including receiver) match any IC data group.
1418 // - Match found -> jump to target. 1418 // - Match found -> jump to target.
1419 // - Match not found -> jump to IC miss. 1419 // - Match not found -> jump to IC miss.
1420 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, 1420 void StubCode::GenerateNArgsCheckInlineCacheStub(
1421 intptr_t num_args) { 1421 Assembler* assembler,
1422 intptr_t num_args,
1423 const RuntimeEntry& handle_ic_miss) {
1422 ASSERT(num_args > 0); 1424 ASSERT(num_args > 0);
1423 #if defined(DEBUG) 1425 #if defined(DEBUG)
1424 { Label ok; 1426 { Label ok;
1425 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. 1427 // Check that the IC data array has NumberOfArgumentsChecked() == num_args.
1426 // 'num_args_tested' is stored as an untagged int. 1428 // 'num_args_tested' is stored as an untagged int.
1427 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset())); 1429 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset()));
1428 __ cmpl(EBX, Immediate(num_args)); 1430 __ cmpl(EBX, Immediate(num_args));
1429 __ j(EQUAL, &ok, Assembler::kNearJump); 1431 __ j(EQUAL, &ok, Assembler::kNearJump);
1430 __ Stop("Incorrect stub for IC data"); 1432 __ Stop("Incorrect stub for IC data");
1431 __ Bind(&ok); 1433 __ Bind(&ok);
1432 } 1434 }
1433 #endif // DEBUG 1435 #endif // DEBUG
1434 1436
1435 // Check single stepping. 1437 // Check single stepping.
1436 Label not_stepping; 1438 Label not_stepping;
1437 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); 1439 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset()));
1438 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); 1440 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset()));
1439 __ cmpl(EAX, Immediate(0)); 1441 __ cmpl(EAX, Immediate(0));
1440 __ j(EQUAL, &not_stepping, Assembler::kNearJump); 1442 __ j(EQUAL, &not_stepping, Assembler::kNearJump);
1441 1443
1442 __ EnterStubFrame(); 1444 __ EnterStubFrame();
1443 __ pushl(ECX); 1445 __ pushl(ECX);
1444 __ CallRuntime(kSingleStepHandlerRuntimeEntry); 1446 __ CallRuntime(kSingleStepHandlerRuntimeEntry);
1445 __ popl(ECX); 1447 __ popl(ECX);
1446 __ LeaveFrame(); 1448 __ LeaveFrame();
1447 __ Bind(&not_stepping); 1449 __ Bind(&not_stepping);
1448 1450
1451 // ECX: IC data object (preserved).
1449 // Load arguments descriptor into EDX. 1452 // Load arguments descriptor into EDX.
1450 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); 1453 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset()));
1451 // Loop that checks if there is an IC data match. 1454 // Loop that checks if there is an IC data match.
1452 Label loop, update, test, found, get_class_id_as_smi; 1455 Label loop, update, test, found, get_class_id_as_smi;
1453 // ECX: IC data object (preserved). 1456 // ECX: IC data object (preserved).
1454 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); 1457 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset()));
1455 // EBX: ic_data_array with check entries: classes and target functions. 1458 // EBX: ic_data_array with check entries: classes and target functions.
1456 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); 1459 __ leal(EBX, FieldAddress(EBX, Array::data_offset()));
1457 // EBX: points directly to the first ic data array element. 1460 // EBX: points directly to the first ic data array element.
1458 1461
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1512 __ EnterStubFrame(); 1515 __ EnterStubFrame();
1513 __ pushl(EDX); // Preserve arguments descriptor array. 1516 __ pushl(EDX); // Preserve arguments descriptor array.
1514 __ pushl(ECX); // Preserve IC data object. 1517 __ pushl(ECX); // Preserve IC data object.
1515 __ pushl(raw_null); // Setup space on stack for result (target code object). 1518 __ pushl(raw_null); // Setup space on stack for result (target code object).
1516 // Push call arguments. 1519 // Push call arguments.
1517 for (intptr_t i = 0; i < num_args; i++) { 1520 for (intptr_t i = 0; i < num_args; i++) {
1518 __ movl(EBX, Address(EAX, -kWordSize * i)); 1521 __ movl(EBX, Address(EAX, -kWordSize * i));
1519 __ pushl(EBX); 1522 __ pushl(EBX);
1520 } 1523 }
1521 __ pushl(ECX); // Pass IC data object. 1524 __ pushl(ECX); // Pass IC data object.
1522 if (num_args == 1) { 1525 __ CallRuntime(handle_ic_miss);
1523 __ CallRuntime(kInlineCacheMissHandlerOneArgRuntimeEntry);
1524 } else if (num_args == 2) {
1525 __ CallRuntime(kInlineCacheMissHandlerTwoArgsRuntimeEntry);
1526 } else if (num_args == 3) {
1527 __ CallRuntime(kInlineCacheMissHandlerThreeArgsRuntimeEntry);
1528 } else {
1529 UNIMPLEMENTED();
1530 }
1531 // Remove the call arguments pushed earlier, including the IC data object. 1526 // Remove the call arguments pushed earlier, including the IC data object.
1532 for (intptr_t i = 0; i < num_args + 1; i++) { 1527 for (intptr_t i = 0; i < num_args + 1; i++) {
1533 __ popl(EAX); 1528 __ popl(EAX);
1534 } 1529 }
1535 __ popl(EAX); // Pop returned code object into EAX (null if not found). 1530 __ popl(EAX); // Pop returned code object into EAX (null if not found).
1536 __ popl(ECX); // Restore IC data array. 1531 __ popl(ECX); // Restore IC data array.
1537 __ popl(EDX); // Restore arguments descriptor array. 1532 __ popl(EDX); // Restore arguments descriptor array.
1538 __ LeaveFrame(); 1533 __ LeaveFrame();
1539 Label call_target_function; 1534 Label call_target_function;
1540 __ cmpl(EAX, raw_null); 1535 __ cmpl(EAX, raw_null);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 // ECX: Inline cache data object. 1578 // ECX: Inline cache data object.
1584 // TOS(0): Return address. 1579 // TOS(0): Return address.
1585 // Inline cache data object structure: 1580 // Inline cache data object structure:
1586 // 0: function-name 1581 // 0: function-name
1587 // 1: N, number of arguments checked. 1582 // 1: N, number of arguments checked.
1588 // 2 .. (length - 1): group of checks, each check containing: 1583 // 2 .. (length - 1): group of checks, each check containing:
1589 // - N classes. 1584 // - N classes.
1590 // - 1 target function. 1585 // - 1 target function.
1591 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { 1586 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
1592 GenerateUsageCounterIncrement(assembler, EBX); 1587 GenerateUsageCounterIncrement(assembler, EBX);
1593 GenerateNArgsCheckInlineCacheStub(assembler, 1); 1588 GenerateNArgsCheckInlineCacheStub(
1589 assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
1594 } 1590 }
1595 1591
1596 1592
1597 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { 1593 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
1598 GenerateUsageCounterIncrement(assembler, EBX); 1594 GenerateUsageCounterIncrement(assembler, EBX);
1599 GenerateNArgsCheckInlineCacheStub(assembler, 2); 1595 GenerateNArgsCheckInlineCacheStub(
1596 assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
1600 } 1597 }
1601 1598
1602 1599
1603 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) { 1600 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
1604 GenerateUsageCounterIncrement(assembler, EBX); 1601 GenerateUsageCounterIncrement(assembler, EBX);
1605 GenerateNArgsCheckInlineCacheStub(assembler, 3); 1602 GenerateNArgsCheckInlineCacheStub(
1603 assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
1606 } 1604 }
1607 1605
1608 1606
1609 // Use inline cache data array to invoke the target or continue in inline 1607 // Use inline cache data array to invoke the target or continue in inline
1610 // cache miss handler. Stub for 1-argument check (receiver class). 1608 // cache miss handler. Stub for 1-argument check (receiver class).
1611 // EDI: function which counter needs to be incremented. 1609 // EDI: function which counter needs to be incremented.
1612 // ECX: Inline cache data object. 1610 // ECX: Inline cache data object.
1613 // TOS(0): Return address. 1611 // TOS(0): Return address.
1614 // Inline cache data object structure: 1612 // Inline cache data object structure:
1615 // 0: function-name 1613 // 0: function-name
1616 // 1: N, number of arguments checked. 1614 // 1: N, number of arguments checked.
1617 // 2 .. (length - 1): group of checks, each check containing: 1615 // 2 .. (length - 1): group of checks, each check containing:
1618 // - N classes. 1616 // - N classes.
1619 // - 1 target function. 1617 // - 1 target function.
1620 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub( 1618 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
1621 Assembler* assembler) { 1619 Assembler* assembler) {
1622 GenerateOptimizedUsageCounterIncrement(assembler); 1620 GenerateOptimizedUsageCounterIncrement(assembler);
1623 GenerateNArgsCheckInlineCacheStub(assembler, 1); 1621 GenerateNArgsCheckInlineCacheStub(
1622 assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
1624 } 1623 }
1625 1624
1626 1625
1627 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub( 1626 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
1628 Assembler* assembler) { 1627 Assembler* assembler) {
1629 GenerateOptimizedUsageCounterIncrement(assembler); 1628 GenerateOptimizedUsageCounterIncrement(assembler);
1630 GenerateNArgsCheckInlineCacheStub(assembler, 2); 1629 GenerateNArgsCheckInlineCacheStub(
1630 assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
1631 } 1631 }
1632 1632
1633 1633
1634 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub( 1634 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
1635 Assembler* assembler) { 1635 Assembler* assembler) {
1636 GenerateOptimizedUsageCounterIncrement(assembler); 1636 GenerateOptimizedUsageCounterIncrement(assembler);
1637 GenerateNArgsCheckInlineCacheStub(assembler, 3); 1637 GenerateNArgsCheckInlineCacheStub(
1638 assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
1638 } 1639 }
1639 1640
1640 1641
1641 // Do not count as no type feedback is collected. 1642 // Do not count as no type feedback is collected.
1642 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) { 1643 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) {
1643 GenerateNArgsCheckInlineCacheStub(assembler, 1); 1644 GenerateNArgsCheckInlineCacheStub(
1645 assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
1644 } 1646 }
1645 1647
1646 1648
1647 // Megamorphic call is currently implemented as IC call but through a stub 1649 // Megamorphic call is currently implemented as IC call but through a stub
1648 // that does not check/count function invocations. 1650 // that does not check/count function invocations.
1649 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { 1651 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
1650 GenerateNArgsCheckInlineCacheStub(assembler, 1); 1652 GenerateNArgsCheckInlineCacheStub(
1653 assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
1651 } 1654 }
1652 1655
1653 // Intermediary stub between a static call and its target. ICData contains 1656 // Intermediary stub between a static call and its target. ICData contains
1654 // the target function and the call count. 1657 // the target function and the call count.
1655 // ECX: ICData 1658 // ECX: ICData
1656 void StubCode::GenerateUnoptimizedStaticCallStub(Assembler* assembler) { 1659 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
1657 GenerateUsageCounterIncrement(assembler, EBX); 1660 GenerateUsageCounterIncrement(assembler, EBX);
1661
1658 #if defined(DEBUG) 1662 #if defined(DEBUG)
1659 { Label ok; 1663 { Label ok;
1660 // Check that the IC data array has NumberOfArgumentsChecked() == 0. 1664 // Check that the IC data array has NumberOfArgumentsChecked() == num_args.
1661 // 'num_args_tested' is stored as an untagged int. 1665 // 'num_args_tested' is stored as an untagged int.
1662 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset())); 1666 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset()));
1663 __ cmpl(EBX, Immediate(0)); 1667 __ cmpl(EBX, Immediate(0));
1664 __ j(EQUAL, &ok, Assembler::kNearJump); 1668 __ j(EQUAL, &ok, Assembler::kNearJump);
1665 __ Stop("Incorrect IC data for unoptimized static call"); 1669 __ Stop("Incorrect IC data for unoptimized static call");
1666 __ Bind(&ok); 1670 __ Bind(&ok);
1667 } 1671 }
1668 #endif // DEBUG 1672 #endif // DEBUG
1669
1670 // Check single stepping. 1673 // Check single stepping.
1671 Label not_stepping; 1674 Label not_stepping;
1672 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); 1675 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset()));
1673 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); 1676 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset()));
1674 __ cmpl(EAX, Immediate(0)); 1677 __ cmpl(EAX, Immediate(0));
1675 __ j(EQUAL, &not_stepping, Assembler::kNearJump); 1678 __ j(EQUAL, &not_stepping, Assembler::kNearJump);
1676 1679
1677 __ EnterStubFrame(); 1680 __ EnterStubFrame();
1678 __ pushl(ECX); 1681 __ pushl(ECX);
1679 __ CallRuntime(kSingleStepHandlerRuntimeEntry); 1682 __ CallRuntime(kSingleStepHandlerRuntimeEntry);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1718 __ Bind(&target_is_compiled); 1721 __ Bind(&target_is_compiled);
1719 // EAX: Target code. 1722 // EAX: Target code.
1720 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); 1723 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset()));
1721 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1724 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1722 // Load arguments descriptor into EDX. 1725 // Load arguments descriptor into EDX.
1723 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); 1726 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset()));
1724 __ jmp(EAX); 1727 __ jmp(EAX);
1725 } 1728 }
1726 1729
1727 1730
1731 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
1732 GenerateUsageCounterIncrement(assembler, EBX);
1733 GenerateNArgsCheckInlineCacheStub(
1734 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry);
1735 }
1736
1737
1728 // EDX, EXC: May contain arguments to runtime stub. 1738 // EDX, EXC: May contain arguments to runtime stub.
1729 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { 1739 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
1730 __ EnterStubFrame(); 1740 __ EnterStubFrame();
1731 // Save runtime args. 1741 // Save runtime args.
1732 __ pushl(ECX); 1742 __ pushl(ECX);
1733 __ pushl(EDX); 1743 __ pushl(EDX);
1734 // Room for result. Debugger stub returns address of the 1744 // Room for result. Debugger stub returns address of the
1735 // unpatched runtime stub. 1745 // unpatched runtime stub.
1736 const Immediate& raw_null = 1746 const Immediate& raw_null =
1737 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1747 Immediate(reinterpret_cast<intptr_t>(Object::null()));
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
2201 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 2211 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2202 __ popl(temp); 2212 __ popl(temp);
2203 __ popl(right); 2213 __ popl(right);
2204 __ popl(left); 2214 __ popl(left);
2205 __ ret(); 2215 __ ret();
2206 } 2216 }
2207 2217
2208 } // namespace dart 2218 } // namespace dart
2209 2219
2210 #endif // defined TARGET_ARCH_IA32 2220 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698