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

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

Issue 17421003: Store arguments descriptor in ICData. Remove loading of arguments descriptor at unoptimized call si… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 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
« no previous file with comments | « runtime/vm/stub_code_mips.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_X64) 6 #if defined(TARGET_ARCH_X64)
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 1381 matching lines...) Expand 10 before | Expand all | Expand 10 after
1392 __ popq(RAX); 1392 __ popq(RAX);
1393 __ popq(RAX); 1393 __ popq(RAX);
1394 __ popq(RAX); // Get result into RAX. 1394 __ popq(RAX); // Get result into RAX.
1395 1395
1396 // Remove the stub frame as we are about to return. 1396 // Remove the stub frame as we are about to return.
1397 __ LeaveFrame(); 1397 __ LeaveFrame();
1398 __ ret(); 1398 __ ret();
1399 } 1399 }
1400 1400
1401 1401
1402 // Cannot use function object from ICData as it may be the inlined
1403 // function and not the top-scope function.
1402 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { 1404 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
1403 Register argdesc_reg = R10;
1404 Register ic_reg = RBX; 1405 Register ic_reg = RBX;
1405 Register func_reg = RDI; 1406 Register func_reg = RDI;
1406 if (FLAG_trace_optimized_ic_calls) { 1407 if (FLAG_trace_optimized_ic_calls) {
1407 __ EnterStubFrame(); 1408 __ EnterStubFrame();
1408 __ pushq(func_reg); // Preserve 1409 __ pushq(func_reg); // Preserve
1409 __ pushq(argdesc_reg); // Preserve.
1410 __ pushq(ic_reg); // Preserve. 1410 __ pushq(ic_reg); // Preserve.
1411 __ pushq(ic_reg); // Argument. 1411 __ pushq(ic_reg); // Argument.
1412 __ pushq(func_reg); // Argument. 1412 __ pushq(func_reg); // Argument.
1413 __ CallRuntime(kTraceICCallRuntimeEntry); 1413 __ CallRuntime(kTraceICCallRuntimeEntry);
1414 __ popq(RAX); // Discard argument; 1414 __ popq(RAX); // Discard argument;
1415 __ popq(RAX); // Discard argument; 1415 __ popq(RAX); // Discard argument;
1416 __ popq(ic_reg); // Restore. 1416 __ popq(ic_reg); // Restore.
1417 __ popq(argdesc_reg); // Restore.
1418 __ popq(func_reg); // Restore. 1417 __ popq(func_reg); // Restore.
1419 __ LeaveFrame(); 1418 __ LeaveFrame();
1420 } 1419 }
1421 __ incq(FieldAddress(func_reg, Function::usage_counter_offset())); 1420 __ incq(FieldAddress(func_reg, Function::usage_counter_offset()));
1422 } 1421 }
1423 1422
1424 1423
1425 // Loads function into 'temp_reg', preserves 'ic_reg'. 1424 // Loads function into 'temp_reg', preserves 'ic_reg'.
1426 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, 1425 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
1427 Register temp_reg) { 1426 Register temp_reg) {
1428 Register ic_reg = RBX; 1427 Register ic_reg = RBX;
1429 Register func_reg = temp_reg; 1428 Register func_reg = temp_reg;
1430 ASSERT(ic_reg != func_reg); 1429 ASSERT(ic_reg != func_reg);
1431 __ movq(func_reg, FieldAddress(ic_reg, ICData::function_offset())); 1430 __ movq(func_reg, FieldAddress(ic_reg, ICData::function_offset()));
1432 __ incq(FieldAddress(func_reg, Function::usage_counter_offset())); 1431 __ incq(FieldAddress(func_reg, Function::usage_counter_offset()));
1433 } 1432 }
1434 1433
1435 1434
1436 // Generate inline cache check for 'num_args'. 1435 // Generate inline cache check for 'num_args'.
1437 // RBX: Inline cache data object. 1436 // RBX: Inline cache data object.
1438 // R10: Arguments descriptor array.
1439 // TOS(0): return address 1437 // TOS(0): return address
1440 // Control flow: 1438 // Control flow:
1441 // - If receiver is null -> jump to IC miss. 1439 // - If receiver is null -> jump to IC miss.
1442 // - If receiver is Smi -> load Smi class. 1440 // - If receiver is Smi -> load Smi class.
1443 // - If receiver is not-Smi -> load receiver's class. 1441 // - If receiver is not-Smi -> load receiver's class.
1444 // - Check if 'num_args' (including receiver) match any IC data group. 1442 // - Check if 'num_args' (including receiver) match any IC data group.
1445 // - Match found -> jump to target. 1443 // - Match found -> jump to target.
1446 // - Match not found -> jump to IC miss. 1444 // - Match not found -> jump to IC miss.
1447 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, 1445 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
1448 intptr_t num_args) { 1446 intptr_t num_args) {
1449 ASSERT(num_args > 0); 1447 ASSERT(num_args > 0);
1450 #if defined(DEBUG) 1448 #if defined(DEBUG)
1451 { Label ok; 1449 { Label ok;
1452 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. 1450 // Check that the IC data array has NumberOfArgumentsChecked() == num_args.
1453 // 'num_args_tested' is stored as an untagged int. 1451 // 'num_args_tested' is stored as an untagged int.
1454 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset())); 1452 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset()));
1455 __ cmpq(RCX, Immediate(num_args)); 1453 __ cmpq(RCX, Immediate(num_args));
1456 __ j(EQUAL, &ok, Assembler::kNearJump); 1454 __ j(EQUAL, &ok, Assembler::kNearJump);
1457 __ Stop("Incorrect stub for IC data"); 1455 __ Stop("Incorrect stub for IC data");
1458 __ Bind(&ok); 1456 __ Bind(&ok);
1459 } 1457 }
1460 #endif // DEBUG 1458 #endif // DEBUG
1461 1459
1460 // Load arguments descriptor into R10.
1461 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
1462 // Loop that checks if there is an IC data match. 1462 // Loop that checks if there is an IC data match.
1463 Label loop, update, test, found, get_class_id_as_smi; 1463 Label loop, update, test, found, get_class_id_as_smi;
1464 // RBX: IC data object (preserved). 1464 // RBX: IC data object (preserved).
1465 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset())); 1465 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset()));
1466 // R12: ic_data_array with check entries: classes and target functions. 1466 // R12: ic_data_array with check entries: classes and target functions.
1467 __ leaq(R12, FieldAddress(R12, Array::data_offset())); 1467 __ leaq(R12, FieldAddress(R12, Array::data_offset()));
1468 // R12: points directly to the first ic data array element. 1468 // R12: points directly to the first ic data array element.
1469 1469
1470 // Get the receiver's class ID (first read number of arguments from 1470 // Get the receiver's class ID (first read number of arguments from
1471 // arguments descriptor array and then access the receiver from the stack). 1471 // arguments descriptor array and then access the receiver from the stack).
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1584 __ Bind(&not_smi); 1584 __ Bind(&not_smi);
1585 __ LoadClassId(RAX, RAX); 1585 __ LoadClassId(RAX, RAX);
1586 __ SmiTag(RAX); 1586 __ SmiTag(RAX);
1587 __ ret(); 1587 __ ret();
1588 } 1588 }
1589 1589
1590 1590
1591 // Use inline cache data array to invoke the target or continue in inline 1591 // Use inline cache data array to invoke the target or continue in inline
1592 // cache miss handler. Stub for 1-argument check (receiver class). 1592 // cache miss handler. Stub for 1-argument check (receiver class).
1593 // RBX: Inline cache data object. 1593 // RBX: Inline cache data object.
1594 // R10: Arguments descriptor array.
1595 // TOS(0): Return address. 1594 // TOS(0): Return address.
1596 // Inline cache data object structure: 1595 // Inline cache data object structure:
1597 // 0: function-name 1596 // 0: function-name
1598 // 1: N, number of arguments checked. 1597 // 1: N, number of arguments checked.
1599 // 2 .. (length - 1): group of checks, each check containing: 1598 // 2 .. (length - 1): group of checks, each check containing:
1600 // - N classes. 1599 // - N classes.
1601 // - 1 target function. 1600 // - 1 target function.
1602 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { 1601 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
1603 GenerateUsageCounterIncrement(assembler, RCX); 1602 GenerateUsageCounterIncrement(assembler, RCX);
1604 GenerateNArgsCheckInlineCacheStub(assembler, 1); 1603 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1605 } 1604 }
1606 1605
1607 1606
1608 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { 1607 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
1609 GenerateUsageCounterIncrement(assembler, RCX); 1608 GenerateUsageCounterIncrement(assembler, RCX);
1610 GenerateNArgsCheckInlineCacheStub(assembler, 2); 1609 GenerateNArgsCheckInlineCacheStub(assembler, 2);
1611 } 1610 }
1612 1611
1613 1612
1614 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) { 1613 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
1615 GenerateUsageCounterIncrement(assembler, RCX); 1614 GenerateUsageCounterIncrement(assembler, RCX);
1616 GenerateNArgsCheckInlineCacheStub(assembler, 3); 1615 GenerateNArgsCheckInlineCacheStub(assembler, 3);
1617 } 1616 }
1618 1617
1619 // Use inline cache data array to invoke the target or continue in inline 1618 // Use inline cache data array to invoke the target or continue in inline
1620 // cache miss handler. Stub for 1-argument check (receiver class). 1619 // cache miss handler. Stub for 1-argument check (receiver class).
1621 // RDI: function which counter needs to be incremented. 1620 // RDI: function which counter needs to be incremented.
1622 // RBX: Inline cache data object. 1621 // RBX: Inline cache data object.
1623 // R10: Arguments descriptor array.
1624 // TOS(0): Return address. 1622 // TOS(0): Return address.
1625 // Inline cache data object structure: 1623 // Inline cache data object structure:
1626 // 0: function-name 1624 // 0: function-name
1627 // 1: N, number of arguments checked. 1625 // 1: N, number of arguments checked.
1628 // 2 .. (length - 1): group of checks, each check containing: 1626 // 2 .. (length - 1): group of checks, each check containing:
1629 // - N classes. 1627 // - N classes.
1630 // - 1 target function. 1628 // - 1 target function.
1631 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub( 1629 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
1632 Assembler* assembler) { 1630 Assembler* assembler) {
1633 GenerateOptimizedUsageCounterIncrement(assembler); 1631 GenerateOptimizedUsageCounterIncrement(assembler);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1676 __ pushq(raw_null); // Room for result. 1674 __ pushq(raw_null); // Room for result.
1677 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry); 1675 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry);
1678 __ popq(RAX); // Address of original. 1676 __ popq(RAX); // Address of original.
1679 __ popq(R10); // Restore arguments. 1677 __ popq(R10); // Restore arguments.
1680 __ popq(RBX); 1678 __ popq(RBX);
1681 __ LeaveFrame(); 1679 __ LeaveFrame();
1682 __ jmp(RAX); // Jump to original stub. 1680 __ jmp(RAX); // Jump to original stub.
1683 } 1681 }
1684 1682
1685 1683
1686 // R10: Arguments descriptor array.
1687 // TOS(0): return address (Dart code). 1684 // TOS(0): return address (Dart code).
1688 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { 1685 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
1689 const Immediate& raw_null = 1686 const Immediate& raw_null =
1690 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1687 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1691 __ EnterStubFrame(); 1688 __ EnterStubFrame();
1692 __ pushq(R10); // Preserve arguments descriptor. 1689 __ pushq(R10); // Preserve arguments descriptor.
1693 __ pushq(raw_null); // Room for result. 1690 __ pushq(raw_null); // Room for result.
1694 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); 1691 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry);
1695 __ popq(RAX); // Code object. 1692 __ popq(RAX); // Code object.
1696 __ popq(R10); // Restore arguments descriptor. 1693 __ popq(R10); // Restore arguments descriptor.
(...skipping 15 matching lines...) Expand all
1712 __ popq(RAX); 1709 __ popq(RAX);
1713 __ LeaveFrame(); 1710 __ LeaveFrame();
1714 1711
1715 __ popq(R11); // discard return address of call to this stub. 1712 __ popq(R11); // discard return address of call to this stub.
1716 __ LeaveFrame(); 1713 __ LeaveFrame();
1717 __ ret(); 1714 __ ret();
1718 } 1715 }
1719 1716
1720 1717
1721 // RBX: Inline cache data array. 1718 // RBX: Inline cache data array.
1722 // R10: Arguments descriptor array.
1723 // TOS(0): return address (Dart code). 1719 // TOS(0): return address (Dart code).
1724 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { 1720 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
1725 __ EnterStubFrame(); 1721 __ EnterStubFrame();
1726 __ pushq(RBX); 1722 __ pushq(RBX);
1727 __ pushq(R10);
1728 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); 1723 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry);
1729 __ popq(R10);
1730 __ popq(RBX); 1724 __ popq(RBX);
1731 __ LeaveFrame(); 1725 __ LeaveFrame();
1732 1726
1733 // Find out which dispatch stub to call. 1727 // Find out which dispatch stub to call.
1734 Label test_two, test_three, test_four; 1728 Label test_two, test_three, test_four;
1735 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset())); 1729 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset()));
1736 __ cmpq(RCX, Immediate(1)); 1730 __ cmpq(RCX, Immediate(1));
1737 __ j(NOT_EQUAL, &test_two, Assembler::kNearJump); 1731 __ j(NOT_EQUAL, &test_two, Assembler::kNearJump);
1738 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); 1732 __ jmp(&StubCode::OneArgCheckInlineCacheLabel());
1739 __ Bind(&test_two); 1733 __ Bind(&test_two);
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
2078 __ cmpq(left, right); 2072 __ cmpq(left, right);
2079 __ Bind(&done); 2073 __ Bind(&done);
2080 __ popq(right); 2074 __ popq(right);
2081 __ popq(left); 2075 __ popq(left);
2082 __ ret(); 2076 __ ret();
2083 } 2077 }
2084 2078
2085 } // namespace dart 2079 } // namespace dart
2086 2080
2087 #endif // defined TARGET_ARCH_X64 2081 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698