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

Side by Side Diff: runtime/vm/stub_code_mips.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_ia32.cc ('k') | runtime/vm/stub_code_x64.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_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
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 1471 matching lines...) Expand 10 before | Expand all | Expand 10 after
1482 1482
1483 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry); 1483 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry);
1484 1484
1485 __ lw(V0, Address(SP, 4 * kWordSize)); // Get result into V0. 1485 __ lw(V0, Address(SP, 4 * kWordSize)); // Get result into V0.
1486 __ LeaveStubFrameAndReturn(); 1486 __ LeaveStubFrameAndReturn();
1487 } 1487 }
1488 1488
1489 1489
1490 // T0: function object. 1490 // T0: function object.
1491 // S5: inline cache data object. 1491 // S5: inline cache data object.
1492 // S4: arguments descriptor array. 1492 // Cannot use function object from ICData as it may be the inlined
1493 // function and not the top-scope function.
1493 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { 1494 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
1494 __ TraceSimMsg("OptimizedUsageCounterIncrement"); 1495 __ TraceSimMsg("OptimizedUsageCounterIncrement");
1495 Register ic_reg = S5; 1496 Register ic_reg = S5;
1496 Register func_reg = T0; 1497 Register func_reg = T0;
1497 if (FLAG_trace_optimized_ic_calls) { 1498 if (FLAG_trace_optimized_ic_calls) {
1498 __ EnterStubFrame(); 1499 __ EnterStubFrame();
1499 __ addiu(SP, SP, Immediate(-5 * kWordSize)); 1500 __ addiu(SP, SP, Immediate(-4 * kWordSize));
1500 __ sw(T0, Address(SP, 4 * kWordSize)); 1501 __ sw(T0, Address(SP, 3 * kWordSize));
1501 __ sw(S5, Address(SP, 3 * kWordSize)); 1502 __ sw(S5, Address(SP, 2 * kWordSize));
1502 __ sw(S4, Address(SP, 2 * kWordSize)); // Preserve.
1503 __ sw(ic_reg, Address(SP, 1 * kWordSize)); // Argument. 1503 __ sw(ic_reg, Address(SP, 1 * kWordSize)); // Argument.
1504 __ sw(func_reg, Address(SP, 0 * kWordSize)); // Argument. 1504 __ sw(func_reg, Address(SP, 0 * kWordSize)); // Argument.
1505 __ CallRuntime(kTraceICCallRuntimeEntry); 1505 __ CallRuntime(kTraceICCallRuntimeEntry);
1506 __ lw(S4, Address(SP, 2 * kWordSize)); // Restore. 1506 __ lw(S5, Address(SP, 2 * kWordSize));
1507 __ lw(S5, Address(SP, 3 * kWordSize)); 1507 __ lw(T0, Address(SP, 3 * kWordSize));
1508 __ lw(T0, Address(SP, 4 * kWordSize)); 1508 __ addiu(SP, SP, Immediate(4 * kWordSize)); // Discard argument;
1509 __ addiu(SP, SP, Immediate(5 * kWordSize)); // Discard argument;
1510 __ LeaveStubFrame(); 1509 __ LeaveStubFrame();
1511 } 1510 }
1512 __ lw(T7, FieldAddress(func_reg, Function::usage_counter_offset())); 1511 __ lw(T7, FieldAddress(func_reg, Function::usage_counter_offset()));
1513 Label is_hot; 1512 Label is_hot;
1514 if (FlowGraphCompiler::CanOptimize()) { 1513 if (FlowGraphCompiler::CanOptimize()) {
1515 ASSERT(FLAG_optimization_counter_threshold > 1); 1514 ASSERT(FLAG_optimization_counter_threshold > 1);
1516 __ BranchSignedGreaterEqual(T7, FLAG_optimization_counter_threshold, 1515 __ BranchSignedGreaterEqual(T7, FLAG_optimization_counter_threshold,
1517 &is_hot); 1516 &is_hot);
1518 // As long as VM has no OSR do not optimize in the middle of the function 1517 // As long as VM has no OSR do not optimize in the middle of the function
1519 // but only at exit so that we have collected all type feedback before 1518 // but only at exit so that we have collected all type feedback before
(...skipping 26 matching lines...) Expand all
1546 } 1545 }
1547 __ addiu(T1, T1, Immediate(1)); 1546 __ addiu(T1, T1, Immediate(1));
1548 __ sw(T1, FieldAddress(func_reg, Function::usage_counter_offset())); 1547 __ sw(T1, FieldAddress(func_reg, Function::usage_counter_offset()));
1549 __ Bind(&is_hot); 1548 __ Bind(&is_hot);
1550 } 1549 }
1551 1550
1552 1551
1553 // Generate inline cache check for 'num_args'. 1552 // Generate inline cache check for 'num_args'.
1554 // RA: return address 1553 // RA: return address
1555 // S5: Inline cache data object. 1554 // S5: Inline cache data object.
1556 // S4: Arguments descriptor array.
1557 // Control flow: 1555 // Control flow:
1558 // - If receiver is null -> jump to IC miss. 1556 // - If receiver is null -> jump to IC miss.
1559 // - If receiver is Smi -> load Smi class. 1557 // - If receiver is Smi -> load Smi class.
1560 // - If receiver is not-Smi -> load receiver's class. 1558 // - If receiver is not-Smi -> load receiver's class.
1561 // - Check if 'num_args' (including receiver) match any IC data group. 1559 // - Check if 'num_args' (including receiver) match any IC data group.
1562 // - Match found -> jump to target. 1560 // - Match found -> jump to target.
1563 // - Match not found -> jump to IC miss. 1561 // - Match not found -> jump to IC miss.
1564 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, 1562 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
1565 intptr_t num_args) { 1563 intptr_t num_args) {
1566 __ TraceSimMsg("NArgsCheckInlineCacheStub"); 1564 __ TraceSimMsg("NArgsCheckInlineCacheStub");
1567 ASSERT(num_args > 0); 1565 ASSERT(num_args > 0);
1568 #if defined(DEBUG) 1566 #if defined(DEBUG)
1569 { Label ok; 1567 { Label ok;
1570 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. 1568 // Check that the IC data array has NumberOfArgumentsChecked() == num_args.
1571 // 'num_args_tested' is stored as an untagged int. 1569 // 'num_args_tested' is stored as an untagged int.
1572 __ lw(T0, FieldAddress(S5, ICData::num_args_tested_offset())); 1570 __ lw(T0, FieldAddress(S5, ICData::num_args_tested_offset()));
1573 __ BranchEqual(T0, num_args, &ok); 1571 __ BranchEqual(T0, num_args, &ok);
1574 __ Stop("Incorrect stub for IC data"); 1572 __ Stop("Incorrect stub for IC data");
1575 __ Bind(&ok); 1573 __ Bind(&ok);
1576 } 1574 }
1577 #endif // DEBUG 1575 #endif // DEBUG
1578 1576
1577 // Load argument descriptor into S4.
1578 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset()));
1579 // Preserve return address, since RA is needed for subroutine call. 1579 // Preserve return address, since RA is needed for subroutine call.
1580 __ mov(T2, RA); 1580 __ mov(T2, RA);
1581 // Loop that checks if there is an IC data match. 1581 // Loop that checks if there is an IC data match.
1582 Label loop, update, test, found, get_class_id_as_smi; 1582 Label loop, update, test, found, get_class_id_as_smi;
1583 // S5: IC data object (preserved). 1583 // S5: IC data object (preserved).
1584 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset())); 1584 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset()));
1585 // T0: ic_data_array with check entries: classes and target functions. 1585 // T0: ic_data_array with check entries: classes and target functions.
1586 __ AddImmediate(T0, Array::data_offset() - kHeapObjectTag); 1586 __ AddImmediate(T0, Array::data_offset() - kHeapObjectTag);
1587 // T0: points directly to the first ic data array element. 1587 // T0: points directly to the first ic data array element.
1588 1588
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1736 __ LoadClassId(T3, T3); 1736 __ LoadClassId(T3, T3);
1737 __ jr(RA); 1737 __ jr(RA);
1738 __ delay_slot()->SmiTag(T3); 1738 __ delay_slot()->SmiTag(T3);
1739 } 1739 }
1740 1740
1741 1741
1742 // Use inline cache data array to invoke the target or continue in inline 1742 // Use inline cache data array to invoke the target or continue in inline
1743 // cache miss handler. Stub for 1-argument check (receiver class). 1743 // cache miss handler. Stub for 1-argument check (receiver class).
1744 // RA: Return address. 1744 // RA: Return address.
1745 // S5: Inline cache data object. 1745 // S5: Inline cache data object.
1746 // S4: Arguments descriptor array.
1747 // Inline cache data object structure: 1746 // Inline cache data object structure:
1748 // 0: function-name 1747 // 0: function-name
1749 // 1: N, number of arguments checked. 1748 // 1: N, number of arguments checked.
1750 // 2 .. (length - 1): group of checks, each check containing: 1749 // 2 .. (length - 1): group of checks, each check containing:
1751 // - N classes. 1750 // - N classes.
1752 // - 1 target function. 1751 // - 1 target function.
1753 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { 1752 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
1754 GenerateUsageCounterIncrement(assembler, T0); 1753 GenerateUsageCounterIncrement(assembler, T0);
1755 GenerateNArgsCheckInlineCacheStub(assembler, 1); 1754 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1756 } 1755 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1843 __ LeaveStubFrame(); 1842 __ LeaveStubFrame();
1844 1843
1845 // Instead of returning to the patched Dart function, emulate the 1844 // Instead of returning to the patched Dart function, emulate the
1846 // smashed return code pattern and return to the function's caller. 1845 // smashed return code pattern and return to the function's caller.
1847 __ LeaveDartFrameAndReturn(); 1846 __ LeaveDartFrameAndReturn();
1848 } 1847 }
1849 1848
1850 1849
1851 // RA: return address (Dart code). 1850 // RA: return address (Dart code).
1852 // S5: Inline cache data array. 1851 // S5: Inline cache data array.
1853 // S4: Arguments descriptor array.
1854 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { 1852 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
1855 // Create a stub frame as we are pushing some objects on the stack before 1853 // Create a stub frame as we are pushing some objects on the stack before
1856 // calling into the runtime. 1854 // calling into the runtime.
1857 __ TraceSimMsg("BreakpointDynamicStub"); 1855 __ TraceSimMsg("BreakpointDynamicStub");
1858 __ EnterStubFrame(); 1856 __ EnterStubFrame();
1859 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 1857 __ Push(S5);
1860 __ sw(S5, Address(SP, 1 * kWordSize));
1861 __ sw(S4, Address(SP, 0 * kWordSize));
1862 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); 1858 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry);
1863 __ lw(S4, Address(SP, 0 * kWordSize)); 1859 __ Pop(S5);
1864 __ lw(S5, Address(SP, 1 * kWordSize));
1865 __ addiu(SP, SP, Immediate(2 * kWordSize));
1866 __ LeaveStubFrame(); 1860 __ LeaveStubFrame();
1867 1861
1868 // Find out which dispatch stub to call. 1862 // Find out which dispatch stub to call.
1869 __ lw(TMP1, FieldAddress(S5, ICData::num_args_tested_offset())); 1863 __ lw(TMP1, FieldAddress(S5, ICData::num_args_tested_offset()));
1870 1864
1871 Label one_arg, two_args, three_args; 1865 Label one_arg, two_args, three_args;
1872 __ BranchEqual(TMP1, 1, &one_arg); 1866 __ BranchEqual(TMP1, 1, &one_arg);
1873 __ BranchEqual(TMP1, 2, &two_args); 1867 __ BranchEqual(TMP1, 2, &two_args);
1874 __ BranchEqual(TMP1, 3, &three_args); 1868 __ BranchEqual(TMP1, 3, &three_args);
1875 __ Stop("Unsupported number of arguments tested."); 1869 __ Stop("Unsupported number of arguments tested.");
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
2251 __ lw(left, Address(SP, 1 * kWordSize)); 2245 __ lw(left, Address(SP, 1 * kWordSize));
2252 __ lw(temp2, Address(SP, 2 * kWordSize)); 2246 __ lw(temp2, Address(SP, 2 * kWordSize));
2253 __ lw(temp1, Address(SP, 3 * kWordSize)); 2247 __ lw(temp1, Address(SP, 3 * kWordSize));
2254 __ Ret(); 2248 __ Ret();
2255 __ delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize)); 2249 __ delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize));
2256 } 2250 }
2257 2251
2258 } // namespace dart 2252 } // namespace dart
2259 2253
2260 #endif // defined TARGET_ARCH_MIPS 2254 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_ia32.cc ('k') | runtime/vm/stub_code_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698