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

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

Issue 17554003: Change static calls in unoptimized code to always call via a stub. Using ICData, the call count of … (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
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 1780 matching lines...) Expand 10 before | Expand all | Expand 10 after
1791 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) { 1791 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) {
1792 GenerateNArgsCheckInlineCacheStub(assembler, 1); 1792 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1793 } 1793 }
1794 1794
1795 1795
1796 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { 1796 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
1797 GenerateNArgsCheckInlineCacheStub(assembler, 1); 1797 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1798 } 1798 }
1799 1799
1800 1800
1801 // Intermediary stub between a static call and its target. ICData contains
1802 // the target function and the call count.
1803 // S5: ICData
1804 void StubCode::GenerateUnoptimizedStaticCallStub(Assembler* assembler) {
1805 GenerateUsageCounterIncrement(assembler, T0);
1806 __ TraceSimMsg("UnoptimizedStaticCallStub");
1807 #if defined(DEBUG)
1808 { Label ok;
1809 // Check that the IC data array has NumberOfArgumentsChecked() == 0.
1810 // 'num_args_tested' is stored as an untagged int.
1811 __ lw(T0, FieldAddress(S5, ICData::num_args_tested_offset()));
1812 __ BranchEqual(T0, 0, &ok);
zra 2013/06/21 19:03:35 __ beq(T0, ZR, &ok)
srdjan 2013/06/21 20:30:18 Done.
1813 __ Stop("Incorrect IC data for unoptimized static call");
1814 __ Bind(&ok);
1815 }
1816 #endif // DEBUG
1817
1818 // S5: IC data object (preserved).
1819 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset()));
1820 // T0: ic_data_array with entries: target functions and count.
1821 __ AddImmediate(T0, Array::data_offset() - kHeapObjectTag);
1822 // T0: points directly to the first ic data array element.
1823 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
1824 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
1825
1826 // Increment count for this call.
1827 Label increment_done;
1828 __ lw(T4, Address(T0, count_offset));
1829 __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6);
1830 __ bgez(T5, &increment_done); // No overflow.
1831 __ delay_slot()->sw(T4, Address(T0, count_offset));
1832
1833 __ LoadImmediate(T1, Smi::RawValue(Smi::kMaxValue));
1834 __ sw(T1, Address(T0, count_offset));
1835
1836 __ Bind(&increment_done);
1837
1838 Label target_is_compiled;
1839 // Get function and call it, if possible.
1840 __ lw(T3, Address(T0, target_offset));
1841 __ lw(T4, FieldAddress(T3, Function::code_offset()));
1842 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
1843 __ bne(T4, TMP, &target_is_compiled);
1844
1845 __ EnterStubFrame();
1846 // Preserve target function and IC data object.
1847 int num_slots = 3; // Two preserved registers, one argument (function).
zra 2013/06/21 19:03:35 When the number of slots is fixed, I've been foreg
srdjan 2013/06/21 20:30:18 Done.
1848 __ addiu(SP, SP, Immediate(-num_slots * kWordSize));
1849 __ sw(S5, Address(SP, (num_slots - 1) * kWordSize)); // Preserve IC data.
1850 __ sw(T3, Address(SP, (num_slots - 2) * kWordSize)); // Preserve function.
1851 __ sw(T3, Address(SP, (num_slots - 3) * kWordSize)); // Function argument.
1852 __ CallRuntime(kCompileFunctionRuntimeEntry);
1853 __ lw(T3, Address(SP, (num_slots - 2) * kWordSize)); // Restore function.
1854 __ lw(S5, Address(SP, (num_slots - 1) * kWordSize)); // Restore IC data.
1855 __ addiu(SP, SP, Immediate(num_slots * kWordSize));
1856 // T3: target function.
1857 __ lw(T4, FieldAddress(T3, Function::code_offset()));
1858 __ LeaveStubFrame();
1859
1860 __ Bind(&target_is_compiled);
1861 // T4: target code.
1862 __ lw(T3, FieldAddress(T4, Code::instructions_offset()));
1863 __ AddImmediate(T3, Instructions::HeaderSize() - kHeapObjectTag);
1864 __ jr(T3);
1865 // Load arguments descriptor into S4.
1866 __ delay_slot()->
1867 lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset()));
1868 }
1869
1870
1801 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { 1871 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
1802 __ Unimplemented("BreakpointRuntime stub"); 1872 __ Unimplemented("BreakpointRuntime stub");
1803 } 1873 }
1804 1874
1805 1875
1806 // RA: return address (Dart code). 1876 // RA: return address (Dart code).
1807 // S4: Arguments descriptor array. 1877 // S5: IC data (unoptimized static call).
1808 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { 1878 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
1809 __ TraceSimMsg("BreakpointStaticStub"); 1879 __ TraceSimMsg("BreakpointStaticStub");
1810 // Create a stub frame as we are pushing some objects on the stack before 1880 // Create a stub frame as we are pushing some objects on the stack before
1811 // calling into the runtime. 1881 // calling into the runtime.
1812 __ EnterStubFrame(); 1882 __ EnterStubFrame();
1813 // Preserve arguments descriptor and make room for result. 1883 // Preserve arguments descriptor and make room for result.
1814 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 1884 __ addiu(SP, SP, Immediate(-2 * kWordSize));
1815 __ sw(S4, Address(SP, 1 * kWordSize)); 1885 __ sw(S5, Address(SP, 1 * kWordSize));
1816 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); 1886 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
1817 __ sw(TMP, Address(SP, 0 * kWordSize)); 1887 __ sw(TMP, Address(SP, 0 * kWordSize));
1818 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); 1888 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry);
1819 // Pop code object result and restore arguments descriptor. 1889 // Pop code object result and restore arguments descriptor.
1820 __ lw(T0, Address(SP, 0 * kWordSize)); 1890 __ lw(T0, Address(SP, 0 * kWordSize));
1821 __ lw(S4, Address(SP, 1 * kWordSize)); 1891 __ lw(S5, Address(SP, 1 * kWordSize));
1822 __ addiu(SP, SP, Immediate(2 * kWordSize)); 1892 __ addiu(SP, SP, Immediate(2 * kWordSize));
1823 __ LeaveStubFrame(); 1893 __ LeaveStubFrame();
1824 1894
1825 // Now call the static function. The breakpoint handler function 1895 // Now call the static function. The breakpoint handler function
1826 // ensures that the call target is compiled. 1896 // ensures that the call target is compiled.
1827 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); 1897 __ lw(T0, FieldAddress(T0, Code::instructions_offset()));
1828 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); 1898 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag);
1899 // Load arguments descriptor into S4.
1900 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset()));
1829 __ jr(T0); 1901 __ jr(T0);
1830 } 1902 }
1831 1903
1832 1904
1833 // V0: return value. 1905 // V0: return value.
1834 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { 1906 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) {
1835 __ TraceSimMsg("BreakpoingReturnStub"); 1907 __ TraceSimMsg("BreakpoingReturnStub");
1836 // Create a stub frame as we are pushing some objects on the stack before 1908 // Create a stub frame as we are pushing some objects on the stack before
1837 // calling into the runtime. 1909 // calling into the runtime.
1838 __ EnterStubFrame(); 1910 __ EnterStubFrame();
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
2245 __ lw(left, Address(SP, 1 * kWordSize)); 2317 __ lw(left, Address(SP, 1 * kWordSize));
2246 __ lw(temp2, Address(SP, 2 * kWordSize)); 2318 __ lw(temp2, Address(SP, 2 * kWordSize));
2247 __ lw(temp1, Address(SP, 3 * kWordSize)); 2319 __ lw(temp1, Address(SP, 3 * kWordSize));
2248 __ Ret(); 2320 __ Ret();
2249 __ delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize)); 2321 __ delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize));
2250 } 2322 }
2251 2323
2252 } // namespace dart 2324 } // namespace dart
2253 2325
2254 #endif // defined TARGET_ARCH_MIPS 2326 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698