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

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

Issue 203523011: Introduce a lazy-compile stub for functions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: rebased Created 6 years, 8 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 890 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 901
902 // Verify that the class of the object is a closure class by checking that 902 // Verify that the class of the object is a closure class by checking that
903 // class.signature_function() is not null. 903 // class.signature_function() is not null.
904 __ LoadClass(T0, T1); 904 __ LoadClass(T0, T1);
905 __ lw(T0, FieldAddress(T0, Class::signature_function_offset())); 905 __ lw(T0, FieldAddress(T0, Class::signature_function_offset()));
906 906
907 // See if actual class is not a closure class. 907 // See if actual class is not a closure class.
908 __ beq(T0, T7, &not_closure); 908 __ beq(T0, T7, &not_closure);
909 909
910 // T0 is just the signature function. Load the actual closure function. 910 // T0 is just the signature function. Load the actual closure function.
911 __ lw(T2, FieldAddress(T1, Closure::function_offset())); 911 __ lw(T0, FieldAddress(T1, Closure::function_offset()));
912 912
913 // Load closure context in CTX; note that CTX has already been preserved. 913 // Load closure context in CTX; note that CTX has already been preserved.
914 __ lw(CTX, FieldAddress(T1, Closure::context_offset())); 914 __ lw(CTX, FieldAddress(T1, Closure::context_offset()));
915 915
916 Label function_compiled; 916 // Load closure function code in T2.
917 // Load closure function code in T0. 917 __ lw(T2, FieldAddress(T0, Function::code_offset()));
918 __ lw(T0, FieldAddress(T2, Function::code_offset())); 918 __ lw(T2, FieldAddress(T2, Code::instructions_offset()));
919 __ bne(T0, T7, &function_compiled); 919 __ AddImmediate(T2, Instructions::HeaderSize() - kHeapObjectTag);
920 920 __ jr(T2);
921 // Create a stub frame as we are pushing some objects on the stack before
922 // calling into the runtime.
923 __ EnterStubFrame();
924
925 // Preserve arguments descriptor array and read-only function object argument.
926 __ addiu(SP, SP, Immediate(-2 * kWordSize));
927 __ sw(S4, Address(SP, 1 * kWordSize));
928 __ sw(T2, Address(SP, 0 * kWordSize));
929 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
930 __ TraceSimMsg("GenerateCallClosureFunctionStub return");
931 // Restore arguments descriptor array and read-only function object argument.
932 __ lw(T2, Address(SP, 0 * kWordSize));
933 __ lw(S4, Address(SP, 1 * kWordSize));
934 __ addiu(SP, SP, Immediate(2 * kWordSize));
935 // Restore T0.
936 __ lw(T0, FieldAddress(T2, Function::code_offset()));
937
938 // Remove the stub frame as we are about to jump to the closure function.
939 __ LeaveStubFrame();
940
941 __ Bind(&function_compiled);
942 // T0: Code.
943 // S4: Arguments descriptor array.
944 __ lw(T0, FieldAddress(T0, Code::instructions_offset()));
945 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag);
946 __ jr(T0);
947 921
948 __ Bind(&not_closure); 922 __ Bind(&not_closure);
949 // Call runtime to attempt to resolve and invoke a call method on a 923 // Call runtime to attempt to resolve and invoke a call method on a
950 // non-closure object, passing the non-closure object and its arguments array, 924 // non-closure object, passing the non-closure object and its arguments array,
951 // returning here. 925 // returning here.
952 // If no call method exists, throw a NoSuchMethodError. 926 // If no call method exists, throw a NoSuchMethodError.
953 // T1: non-closure object. 927 // T1: non-closure object.
954 // S4: arguments descriptor array. 928 // S4: arguments descriptor array.
955 929
956 // Create a stub frame as we are pushing some objects on the stack before 930 // Create a stub frame as we are pushing some objects on the stack before
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after
1731 1705
1732 __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6); 1706 __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6);
1733 1707
1734 __ bgez(T5, &call_target_function); // No overflow. 1708 __ bgez(T5, &call_target_function); // No overflow.
1735 __ delay_slot()->sw(T4, Address(T0, count_offset)); 1709 __ delay_slot()->sw(T4, Address(T0, count_offset));
1736 1710
1737 __ LoadImmediate(T1, Smi::RawValue(Smi::kMaxValue)); 1711 __ LoadImmediate(T1, Smi::RawValue(Smi::kMaxValue));
1738 __ sw(T1, Address(T0, count_offset)); 1712 __ sw(T1, Address(T0, count_offset));
1739 1713
1740 __ Bind(&call_target_function); 1714 __ Bind(&call_target_function);
1741 // T3: Target function. 1715 // T0 <- T3: Target function.
1716 __ mov(T0, T3);
1742 Label is_compiled; 1717 Label is_compiled;
1743 __ lw(T4, FieldAddress(T3, Function::code_offset())); 1718 __ lw(T4, FieldAddress(T0, Function::code_offset()));
1744 if (FLAG_collect_code) { 1719 __ lw(T4, FieldAddress(T4, Code::instructions_offset()));
1745 __ BranchNotEqual(T4, reinterpret_cast<int32_t>(Object::null()), 1720 __ AddImmediate(T4, Instructions::HeaderSize() - kHeapObjectTag);
1746 &is_compiled); 1721 __ jr(T4);
1747 __ EnterStubFrame();
1748 __ addiu(SP, SP, Immediate(-3 * kWordSize));
1749 __ sw(S5, Address(SP, 2 * kWordSize)); // Preserve IC data.
1750 __ sw(S4, Address(SP, 1 * kWordSize)); // Preserve arg desc.
1751 __ sw(T3, Address(SP, 0 * kWordSize)); // Function argument.
1752 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1753 __ lw(T3, Address(SP, 0 * kWordSize)); // Restore Function.
1754 __ lw(S4, Address(SP, 1 * kWordSize)); // Restore arg desc.
1755 __ lw(S5, Address(SP, 2 * kWordSize)); // Restore IC data.
1756 __ addiu(SP, SP, Immediate(3 * kWordSize));
1757 __ LeaveStubFrame();
1758 __ lw(T4, FieldAddress(T3, Function::code_offset()));
1759 __ Bind(&is_compiled);
1760 }
1761 __ lw(T3, FieldAddress(T4, Code::instructions_offset()));
1762 __ AddImmediate(T3, Instructions::HeaderSize() - kHeapObjectTag);
1763 __ jr(T3);
1764 1722
1765 // Instance in T3, return its class-id in T3 as Smi. 1723 // Instance in T3, return its class-id in T3 as Smi.
1766 __ Bind(&get_class_id_as_smi); 1724 __ Bind(&get_class_id_as_smi);
1767 Label not_smi; 1725 Label not_smi;
1768 // Test if Smi -> load Smi class for comparison. 1726 // Test if Smi -> load Smi class for comparison.
1769 __ andi(CMPRES1, T3, Immediate(kSmiTagMask)); 1727 __ andi(CMPRES1, T3, Immediate(kSmiTagMask));
1770 __ bne(CMPRES1, ZR, &not_smi); 1728 __ bne(CMPRES1, ZR, &not_smi);
1771 __ jr(RA); 1729 __ jr(RA);
1772 __ delay_slot()->addiu(T3, ZR, Immediate(Smi::RawValue(kSmiCid))); 1730 __ delay_slot()->addiu(T3, ZR, Immediate(Smi::RawValue(kSmiCid)));
1773 1731
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1893 __ lw(T4, Address(T0, count_offset)); 1851 __ lw(T4, Address(T0, count_offset));
1894 __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6); 1852 __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6);
1895 __ bgez(T5, &increment_done); // No overflow. 1853 __ bgez(T5, &increment_done); // No overflow.
1896 __ delay_slot()->sw(T4, Address(T0, count_offset)); 1854 __ delay_slot()->sw(T4, Address(T0, count_offset));
1897 1855
1898 __ LoadImmediate(T1, Smi::RawValue(Smi::kMaxValue)); 1856 __ LoadImmediate(T1, Smi::RawValue(Smi::kMaxValue));
1899 __ sw(T1, Address(T0, count_offset)); 1857 __ sw(T1, Address(T0, count_offset));
1900 1858
1901 __ Bind(&increment_done); 1859 __ Bind(&increment_done);
1902 1860
1903 Label target_is_compiled; 1861 // Load arguments descriptor into S4.
1862 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset()));
1863
1904 // Get function and call it, if possible. 1864 // Get function and call it, if possible.
1905 __ lw(T3, Address(T0, target_offset)); 1865 __ lw(T0, Address(T0, target_offset));
1906 __ lw(T4, FieldAddress(T3, Function::code_offset())); 1866 __ lw(T4, FieldAddress(T0, Function::code_offset()));
1907 __ LoadImmediate(CMPRES1, reinterpret_cast<intptr_t>(Object::null()));
1908 __ bne(T4, CMPRES1, &target_is_compiled);
1909 1867
1910 __ EnterStubFrame();
1911 // Preserve target function and IC data object.
1912 // Two preserved registers, one argument (function) => 3 slots.
1913 __ addiu(SP, SP, Immediate(-3 * kWordSize));
1914 __ sw(S5, Address(SP, 2 * kWordSize)); // Preserve IC data.
1915 __ sw(T3, Address(SP, 1 * kWordSize)); // Preserve function.
1916 __ sw(T3, Address(SP, 0 * kWordSize)); // Function argument.
1917 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1918 __ lw(T3, Address(SP, 1 * kWordSize)); // Restore function.
1919 __ lw(S5, Address(SP, 2 * kWordSize)); // Restore IC data.
1920 __ addiu(SP, SP, Immediate(3 * kWordSize));
1921 // T3: target function.
1922 __ lw(T4, FieldAddress(T3, Function::code_offset()));
1923 __ LeaveStubFrame();
1924
1925 __ Bind(&target_is_compiled);
1926 // T4: target code. 1868 // T4: target code.
1927 __ lw(T3, FieldAddress(T4, Code::instructions_offset())); 1869 __ lw(T4, FieldAddress(T4, Code::instructions_offset()));
1928 __ AddImmediate(T3, Instructions::HeaderSize() - kHeapObjectTag); 1870 __ AddImmediate(T4, Instructions::HeaderSize() - kHeapObjectTag);
1929 __ jr(T3); 1871 __ jr(T4);
1930 // Load arguments descriptor into S4.
1931 __ delay_slot()->
1932 lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset()));
1933 } 1872 }
1934 1873
1935 1874
1936 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { 1875 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
1937 GenerateUsageCounterIncrement(assembler, T0); 1876 GenerateUsageCounterIncrement(assembler, T0);
1938 GenerateNArgsCheckInlineCacheStub( 1877 GenerateNArgsCheckInlineCacheStub(
1939 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry); 1878 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry);
1940 } 1879 }
1941 1880
1942 1881
1943 // Stub for calling the CompileFunction runtime call. 1882 // Stub for compiling a function and jumping to the compiled code.
1944 // S5: IC-Data. 1883 // S5: IC-Data (for methods).
1945 // S4: Arguments descriptor. 1884 // S4: Arguments descriptor.
1946 // T0: Function. 1885 // T0: Function.
1947 void StubCode::GenerateCompileFunctionRuntimeCallStub(Assembler* assembler) { 1886 void StubCode::GenerateLazyCompileStub(Assembler* assembler) {
1948 __ EnterStubFrame(); 1887 __ EnterStubFrame();
1949 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 1888 __ addiu(SP, SP, Immediate(-3 * kWordSize));
1950 __ sw(S5, Address(SP, 2 * kWordSize)); // Preserve IC data object. 1889 __ sw(S5, Address(SP, 2 * kWordSize)); // Preserve IC data object.
1951 __ sw(S4, Address(SP, 1 * kWordSize)); // Preserve args descriptor array. 1890 __ sw(S4, Address(SP, 1 * kWordSize)); // Preserve args descriptor array.
1952 __ sw(T0, Address(SP, 0 * kWordSize)); // Pass function. 1891 __ sw(T0, Address(SP, 0 * kWordSize)); // Pass function.
1953 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); 1892 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1954 __ lw(T0, Address(SP, 0 * kWordSize)); // Restore function. 1893 __ lw(T0, Address(SP, 0 * kWordSize)); // Restore function.
1955 __ lw(S4, Address(SP, 1 * kWordSize)); // Restore args descriptor array. 1894 __ lw(S4, Address(SP, 1 * kWordSize)); // Restore args descriptor array.
1956 __ lw(S5, Address(SP, 2 * kWordSize)); // Restore IC data array. 1895 __ lw(S5, Address(SP, 2 * kWordSize)); // Restore IC data array.
1957 __ LeaveStubFrameAndReturn(); 1896 __ addiu(SP, SP, Immediate(3 * kWordSize));
1897 __ LeaveStubFrame();
1898
1899 __ lw(T2, FieldAddress(T0, Function::code_offset()));
1900 __ lw(T2, FieldAddress(T2, Code::instructions_offset()));
1901 __ AddImmediate(T2, Instructions::HeaderSize() - kHeapObjectTag);
1902 __ jr(T2);
1958 } 1903 }
1959 1904
1960 1905
1961 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { 1906 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
1962 __ Comment("BreakpointRuntime stub"); 1907 __ Comment("BreakpointRuntime stub");
1963 __ EnterStubFrame(); 1908 __ EnterStubFrame();
1964 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 1909 __ addiu(SP, SP, Immediate(-3 * kWordSize));
1965 __ sw(S5, Address(SP, 2 * kWordSize)); 1910 __ sw(S5, Address(SP, 2 * kWordSize));
1966 __ sw(S4, Address(SP, 1 * kWordSize)); 1911 __ sw(S4, Address(SP, 1 * kWordSize));
1967 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); 1912 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
2295 const Register right = T0; 2240 const Register right = T0;
2296 __ lw(left, Address(SP, 1 * kWordSize)); 2241 __ lw(left, Address(SP, 1 * kWordSize));
2297 __ lw(right, Address(SP, 0 * kWordSize)); 2242 __ lw(right, Address(SP, 0 * kWordSize));
2298 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); 2243 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2);
2299 __ Ret(); 2244 __ Ret();
2300 } 2245 }
2301 2246
2302 } // namespace dart 2247 } // namespace dart
2303 2248
2304 #endif // defined TARGET_ARCH_MIPS 2249 #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