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

Side by Side Diff: runtime/vm/stub_code_ia32.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_arm.cc ('k') | runtime/vm/stub_code_mips.cc » ('j') | 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_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 1398 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 __ popl(EAX); 1409 __ popl(EAX);
1410 __ popl(EAX); 1410 __ popl(EAX);
1411 __ popl(EAX); // Get result into EAX. 1411 __ popl(EAX); // Get result into EAX.
1412 1412
1413 // Remove the stub frame as we are about to return. 1413 // Remove the stub frame as we are about to return.
1414 __ LeaveFrame(); 1414 __ LeaveFrame();
1415 __ ret(); 1415 __ ret();
1416 } 1416 }
1417 1417
1418 1418
1419 // Cannot use function object from ICData as it may be the inlined
1420 // function and not the top-scope function.
1419 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { 1421 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
1420 Register argdesc_reg = EDX;
1421 Register ic_reg = ECX; 1422 Register ic_reg = ECX;
1422 Register func_reg = EDI; 1423 Register func_reg = EDI;
1423 if (FLAG_trace_optimized_ic_calls) { 1424 if (FLAG_trace_optimized_ic_calls) {
1424 __ EnterStubFrame(); 1425 __ EnterStubFrame();
1425 __ pushl(func_reg); // Preserve 1426 __ pushl(func_reg); // Preserve
1426 __ pushl(argdesc_reg); // Preserve.
1427 __ pushl(ic_reg); // Preserve. 1427 __ pushl(ic_reg); // Preserve.
1428 __ pushl(ic_reg); // Argument. 1428 __ pushl(ic_reg); // Argument.
1429 __ pushl(func_reg); // Argument. 1429 __ pushl(func_reg); // Argument.
1430 __ CallRuntime(kTraceICCallRuntimeEntry); 1430 __ CallRuntime(kTraceICCallRuntimeEntry);
1431 __ popl(EAX); // Discard argument; 1431 __ popl(EAX); // Discard argument;
1432 __ popl(EAX); // Discard argument; 1432 __ popl(EAX); // Discard argument;
1433 __ popl(ic_reg); // Restore. 1433 __ popl(ic_reg); // Restore.
1434 __ popl(argdesc_reg); // Restore.
1435 __ popl(func_reg); // Restore. 1434 __ popl(func_reg); // Restore.
1436 __ LeaveFrame(); 1435 __ LeaveFrame();
1437 } 1436 }
1438 __ incl(FieldAddress(func_reg, Function::usage_counter_offset())); 1437 __ incl(FieldAddress(func_reg, Function::usage_counter_offset()));
1439 } 1438 }
1440 1439
1441 1440
1442 // Loads function into 'temp_reg'. 1441 // Loads function into 'temp_reg'.
1443 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, 1442 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
1444 Register temp_reg) { 1443 Register temp_reg) {
1445 Register ic_reg = ECX; 1444 Register ic_reg = ECX;
1446 Register func_reg = temp_reg; 1445 Register func_reg = temp_reg;
1447 ASSERT(ic_reg != func_reg); 1446 ASSERT(ic_reg != func_reg);
1448 __ movl(func_reg, FieldAddress(ic_reg, ICData::function_offset())); 1447 __ movl(func_reg, FieldAddress(ic_reg, ICData::function_offset()));
1449 __ incl(FieldAddress(func_reg, Function::usage_counter_offset())); 1448 __ incl(FieldAddress(func_reg, Function::usage_counter_offset()));
1450 } 1449 }
1451 1450
1452 1451
1453 // Generate inline cache check for 'num_args'. 1452 // Generate inline cache check for 'num_args'.
1454 // ECX: Inline cache data object. 1453 // ECX: Inline cache data object.
1455 // EDX: Arguments descriptor array.
1456 // TOS(0): return address 1454 // TOS(0): return address
1457 // Control flow: 1455 // Control flow:
1458 // - If receiver is null -> jump to IC miss. 1456 // - If receiver is null -> jump to IC miss.
1459 // - If receiver is Smi -> load Smi class. 1457 // - If receiver is Smi -> load Smi class.
1460 // - If receiver is not-Smi -> load receiver's class. 1458 // - If receiver is not-Smi -> load receiver's class.
1461 // - Check if 'num_args' (including receiver) match any IC data group. 1459 // - Check if 'num_args' (including receiver) match any IC data group.
1462 // - Match found -> jump to target. 1460 // - Match found -> jump to target.
1463 // - Match not found -> jump to IC miss. 1461 // - Match not found -> jump to IC miss.
1464 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, 1462 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
1465 intptr_t num_args) { 1463 intptr_t num_args) {
1466 ASSERT(num_args > 0); 1464 ASSERT(num_args > 0);
1467 #if defined(DEBUG) 1465 #if defined(DEBUG)
1468 { Label ok; 1466 { Label ok;
1469 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. 1467 // Check that the IC data array has NumberOfArgumentsChecked() == num_args.
1470 // 'num_args_tested' is stored as an untagged int. 1468 // 'num_args_tested' is stored as an untagged int.
1471 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset())); 1469 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset()));
1472 __ cmpl(EBX, Immediate(num_args)); 1470 __ cmpl(EBX, Immediate(num_args));
1473 __ j(EQUAL, &ok, Assembler::kNearJump); 1471 __ j(EQUAL, &ok, Assembler::kNearJump);
1474 __ Stop("Incorrect stub for IC data"); 1472 __ Stop("Incorrect stub for IC data");
1475 __ Bind(&ok); 1473 __ Bind(&ok);
1476 } 1474 }
1477 #endif // DEBUG 1475 #endif // DEBUG
1478 1476
1477 // Load arguments descriptor into EDX.
1478 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset()));
1479 // Loop that checks if there is an IC data match. 1479 // Loop that checks if there is an IC data match.
1480 Label loop, update, test, found, get_class_id_as_smi; 1480 Label loop, update, test, found, get_class_id_as_smi;
1481 // ECX: IC data object (preserved). 1481 // ECX: IC data object (preserved).
1482 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); 1482 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset()));
1483 // EBX: ic_data_array with check entries: classes and target functions. 1483 // EBX: ic_data_array with check entries: classes and target functions.
1484 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); 1484 __ leal(EBX, FieldAddress(EBX, Array::data_offset()));
1485 // EBX: points directly to the first ic data array element. 1485 // EBX: points directly to the first ic data array element.
1486 1486
1487 // Get the receiver's class ID (first read number of arguments from 1487 // Get the receiver's class ID (first read number of arguments from
1488 // arguments descriptor array and then access the receiver from the stack). 1488 // arguments descriptor array and then access the receiver from the stack).
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1604 __ Bind(&not_smi); 1604 __ Bind(&not_smi);
1605 __ LoadClassId(EAX, EAX); 1605 __ LoadClassId(EAX, EAX);
1606 __ SmiTag(EAX); 1606 __ SmiTag(EAX);
1607 __ ret(); 1607 __ ret();
1608 } 1608 }
1609 1609
1610 1610
1611 // Use inline cache data array to invoke the target or continue in inline 1611 // Use inline cache data array to invoke the target or continue in inline
1612 // cache miss handler. Stub for 1-argument check (receiver class). 1612 // cache miss handler. Stub for 1-argument check (receiver class).
1613 // ECX: Inline cache data object. 1613 // ECX: Inline cache data object.
1614 // EDX: Arguments descriptor array.
1615 // TOS(0): Return address. 1614 // TOS(0): Return address.
1616 // Inline cache data object structure: 1615 // Inline cache data object structure:
1617 // 0: function-name 1616 // 0: function-name
1618 // 1: N, number of arguments checked. 1617 // 1: N, number of arguments checked.
1619 // 2 .. (length - 1): group of checks, each check containing: 1618 // 2 .. (length - 1): group of checks, each check containing:
1620 // - N classes. 1619 // - N classes.
1621 // - 1 target function. 1620 // - 1 target function.
1622 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { 1621 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
1623 GenerateUsageCounterIncrement(assembler, EBX); 1622 GenerateUsageCounterIncrement(assembler, EBX);
1624 GenerateNArgsCheckInlineCacheStub(assembler, 1); 1623 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1625 } 1624 }
1626 1625
1627 1626
1628 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { 1627 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
1629 GenerateUsageCounterIncrement(assembler, EBX); 1628 GenerateUsageCounterIncrement(assembler, EBX);
1630 GenerateNArgsCheckInlineCacheStub(assembler, 2); 1629 GenerateNArgsCheckInlineCacheStub(assembler, 2);
1631 } 1630 }
1632 1631
1633 1632
1634 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) { 1633 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
1635 GenerateUsageCounterIncrement(assembler, EBX); 1634 GenerateUsageCounterIncrement(assembler, EBX);
1636 GenerateNArgsCheckInlineCacheStub(assembler, 3); 1635 GenerateNArgsCheckInlineCacheStub(assembler, 3);
1637 } 1636 }
1638 1637
1639 1638
1640 // Use inline cache data array to invoke the target or continue in inline 1639 // Use inline cache data array to invoke the target or continue in inline
1641 // cache miss handler. Stub for 1-argument check (receiver class). 1640 // cache miss handler. Stub for 1-argument check (receiver class).
1642 // EDI: function which counter needs to be incremented. 1641 // EDI: function which counter needs to be incremented.
1643 // ECX: Inline cache data object. 1642 // ECX: Inline cache data object.
1644 // EDX: Arguments descriptor array.
1645 // TOS(0): Return address. 1643 // TOS(0): Return address.
1646 // Inline cache data object structure: 1644 // Inline cache data object structure:
1647 // 0: function-name 1645 // 0: function-name
1648 // 1: N, number of arguments checked. 1646 // 1: N, number of arguments checked.
1649 // 2 .. (length - 1): group of checks, each check containing: 1647 // 2 .. (length - 1): group of checks, each check containing:
1650 // - N classes. 1648 // - N classes.
1651 // - 1 target function. 1649 // - 1 target function.
1652 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub( 1650 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
1653 Assembler* assembler) { 1651 Assembler* assembler) {
1654 GenerateOptimizedUsageCounterIncrement(assembler); 1652 GenerateOptimizedUsageCounterIncrement(assembler);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1742 // Instead of returning to the patched Dart function, emulate the 1740 // Instead of returning to the patched Dart function, emulate the
1743 // smashed return code pattern and return to the function's caller. 1741 // smashed return code pattern and return to the function's caller.
1744 __ popl(ECX); // Discard return address to patched dart code. 1742 __ popl(ECX); // Discard return address to patched dart code.
1745 // Execute function epilog code that was smashed in the Dart code. 1743 // Execute function epilog code that was smashed in the Dart code.
1746 __ LeaveFrame(); 1744 __ LeaveFrame();
1747 __ ret(); 1745 __ ret();
1748 } 1746 }
1749 1747
1750 1748
1751 // ECX: Inline cache data array. 1749 // ECX: Inline cache data array.
1752 // EDX: Arguments descriptor array.
1753 // TOS(0): return address (Dart code). 1750 // TOS(0): return address (Dart code).
1754 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { 1751 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
1755 // Create a stub frame as we are pushing some objects on the stack before 1752 // Create a stub frame as we are pushing some objects on the stack before
1756 // calling into the runtime. 1753 // calling into the runtime.
1757 __ EnterStubFrame(); 1754 __ EnterStubFrame();
1758 __ pushl(ECX); 1755 __ pushl(ECX);
1759 __ pushl(EDX);
1760 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); 1756 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry);
1761 __ popl(EDX);
1762 __ popl(ECX); 1757 __ popl(ECX);
1763 __ LeaveFrame(); 1758 __ LeaveFrame();
1764 1759
1765 // Find out which dispatch stub to call. 1760 // Find out which dispatch stub to call.
1766 Label test_two, test_three, test_four; 1761 Label test_two, test_three, test_four;
1767 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset())); 1762 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset()));
1768 __ cmpl(EBX, Immediate(1)); 1763 __ cmpl(EBX, Immediate(1));
1769 __ j(NOT_EQUAL, &test_two, Assembler::kNearJump); 1764 __ j(NOT_EQUAL, &test_two, Assembler::kNearJump);
1770 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); 1765 __ jmp(&StubCode::OneArgCheckInlineCacheLabel());
1771 __ Bind(&test_two); 1766 __ Bind(&test_two);
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
2122 __ Bind(&done); 2117 __ Bind(&done);
2123 __ popl(temp); 2118 __ popl(temp);
2124 __ popl(right); 2119 __ popl(right);
2125 __ popl(left); 2120 __ popl(left);
2126 __ ret(); 2121 __ ret();
2127 } 2122 }
2128 2123
2129 } // namespace dart 2124 } // namespace dart
2130 2125
2131 #endif // defined TARGET_ARCH_IA32 2126 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_arm.cc ('k') | runtime/vm/stub_code_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698