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

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 & added MIPS code Created 6 years, 9 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 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 // Load closure function code in T2.
916 Label function_compiled; 917 Label function_compiled;
917 // Load closure function code in T0. 918 __ lw(T2, FieldAddress(T0, Function::code_offset()));
918 __ lw(T0, FieldAddress(T2, Function::code_offset())); 919 __ beq(T2, T7, &function_compiled);
919 __ bne(T0, T7, &function_compiled); 920 __ Branch(&StubCode::LazyCompileClosureLabel());
920
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 921
941 __ Bind(&function_compiled); 922 __ Bind(&function_compiled);
942 // T0: Code. 923 __ lw(T2, FieldAddress(T2, Code::instructions_offset()));
943 // S4: Arguments descriptor array. 924 __ AddImmediate(T2, Instructions::HeaderSize() - kHeapObjectTag);
944 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); 925 __ jr(T2);
945 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag);
946 __ jr(T0);
947 926
948 __ Bind(&not_closure); 927 __ Bind(&not_closure);
949 // Call runtime to attempt to resolve and invoke a call method on a 928 // 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, 929 // non-closure object, passing the non-closure object and its arguments array,
951 // returning here. 930 // returning here.
952 // If no call method exists, throw a NoSuchMethodError. 931 // If no call method exists, throw a NoSuchMethodError.
953 // T1: non-closure object. 932 // T1: non-closure object.
954 // S4: arguments descriptor array. 933 // S4: arguments descriptor array.
955 934
956 // Create a stub frame as we are pushing some objects on the stack before 935 // 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 1710
1732 __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6); 1711 __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6);
1733 1712
1734 __ bgez(T5, &call_target_function); // No overflow. 1713 __ bgez(T5, &call_target_function); // No overflow.
1735 __ delay_slot()->sw(T4, Address(T0, count_offset)); 1714 __ delay_slot()->sw(T4, Address(T0, count_offset));
1736 1715
1737 __ LoadImmediate(T1, Smi::RawValue(Smi::kMaxValue)); 1716 __ LoadImmediate(T1, Smi::RawValue(Smi::kMaxValue));
1738 __ sw(T1, Address(T0, count_offset)); 1717 __ sw(T1, Address(T0, count_offset));
1739 1718
1740 __ Bind(&call_target_function); 1719 __ Bind(&call_target_function);
1741 // T3: Target function. 1720 // T0 <- T3: Target function.
1721 __ mov(T0, T3);
1742 Label is_compiled; 1722 Label is_compiled;
1743 __ lw(T4, FieldAddress(T3, Function::code_offset())); 1723 __ lw(T4, FieldAddress(T3, Function::code_offset()));
1744 if (FLAG_collect_code) { 1724 if (FLAG_collect_code) {
1745 __ BranchNotEqual(T4, reinterpret_cast<int32_t>(Object::null()), 1725 __ BranchNotEqual(T4, reinterpret_cast<int32_t>(Object::null()),
1746 &is_compiled); 1726 &is_compiled);
1747 __ EnterStubFrame(); 1727 __ Branch(&StubCode::LazyCompileLabel());
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); 1728 __ Bind(&is_compiled);
1760 } 1729 }
1761 __ lw(T3, FieldAddress(T4, Code::instructions_offset())); 1730 __ lw(T3, FieldAddress(T4, Code::instructions_offset()));
1762 __ AddImmediate(T3, Instructions::HeaderSize() - kHeapObjectTag); 1731 __ AddImmediate(T3, Instructions::HeaderSize() - kHeapObjectTag);
1763 __ jr(T3); 1732 __ jr(T3);
1764 1733
1765 // Instance in T3, return its class-id in T3 as Smi. 1734 // Instance in T3, return its class-id in T3 as Smi.
1766 __ Bind(&get_class_id_as_smi); 1735 __ Bind(&get_class_id_as_smi);
1767 Label not_smi; 1736 Label not_smi;
1768 // Test if Smi -> load Smi class for comparison. 1737 // Test if Smi -> load Smi class for comparison.
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1893 __ lw(T4, Address(T0, count_offset)); 1862 __ lw(T4, Address(T0, count_offset));
1894 __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6); 1863 __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6);
1895 __ bgez(T5, &increment_done); // No overflow. 1864 __ bgez(T5, &increment_done); // No overflow.
1896 __ delay_slot()->sw(T4, Address(T0, count_offset)); 1865 __ delay_slot()->sw(T4, Address(T0, count_offset));
1897 1866
1898 __ LoadImmediate(T1, Smi::RawValue(Smi::kMaxValue)); 1867 __ LoadImmediate(T1, Smi::RawValue(Smi::kMaxValue));
1899 __ sw(T1, Address(T0, count_offset)); 1868 __ sw(T1, Address(T0, count_offset));
1900 1869
1901 __ Bind(&increment_done); 1870 __ Bind(&increment_done);
1902 1871
1872 // Load arguments descriptor into S4.
1873 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset()));
1874
1903 Label target_is_compiled; 1875 Label target_is_compiled;
1904 // Get function and call it, if possible. 1876 // Get function and call it, if possible.
1905 __ lw(T3, Address(T0, target_offset)); 1877 __ lw(T0, Address(T0, target_offset));
1906 __ lw(T4, FieldAddress(T3, Function::code_offset())); 1878 __ lw(T4, FieldAddress(T0, Function::code_offset()));
1907 __ LoadImmediate(CMPRES1, reinterpret_cast<intptr_t>(Object::null())); 1879 __ LoadImmediate(CMPRES1, reinterpret_cast<intptr_t>(Object::null()));
1908 __ bne(T4, CMPRES1, &target_is_compiled); 1880 __ bne(T4, CMPRES1, &target_is_compiled);
1909 1881 __ Branch(&StubCode::LazyCompileLabel());
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 1882
1925 __ Bind(&target_is_compiled); 1883 __ Bind(&target_is_compiled);
1926 // T4: target code. 1884 // T4: target code.
1927 __ lw(T3, FieldAddress(T4, Code::instructions_offset())); 1885 __ lw(T3, FieldAddress(T4, Code::instructions_offset()));
1928 __ AddImmediate(T3, Instructions::HeaderSize() - kHeapObjectTag); 1886 __ AddImmediate(T3, Instructions::HeaderSize() - kHeapObjectTag);
1929 __ jr(T3); 1887 __ jr(T3);
1930 // Load arguments descriptor into S4.
1931 __ delay_slot()->
1932 lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset()));
1933 } 1888 }
1934 1889
1935 1890
1936 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { 1891 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
1937 GenerateUsageCounterIncrement(assembler, T0); 1892 GenerateUsageCounterIncrement(assembler, T0);
1938 GenerateNArgsCheckInlineCacheStub( 1893 GenerateNArgsCheckInlineCacheStub(
1939 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry); 1894 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry);
1940 } 1895 }
1941 1896
1942 1897
1943 // Stub for calling the CompileFunction runtime call. 1898 // Stub for compiling a function and jumping to the compiled code.
1944 // S5: IC-Data. 1899 // S5: IC-Data.
1945 // S4: Arguments descriptor. 1900 // S4: Arguments descriptor.
1946 // T0: Function. 1901 // T0: Function.
1947 void StubCode::GenerateCompileFunctionRuntimeCallStub(Assembler* assembler) { 1902 void StubCode::GenerateLazyCompileStub(Assembler* assembler) {
1948 __ EnterStubFrame(); 1903 __ EnterStubFrame();
1949 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 1904 __ addiu(SP, SP, Immediate(-3 * kWordSize));
1950 __ sw(S5, Address(SP, 2 * kWordSize)); // Preserve IC data object. 1905 __ sw(S5, Address(SP, 2 * kWordSize)); // Preserve IC data object.
1951 __ sw(S4, Address(SP, 1 * kWordSize)); // Preserve args descriptor array. 1906 __ sw(S4, Address(SP, 1 * kWordSize)); // Preserve args descriptor array.
1952 __ sw(T0, Address(SP, 0 * kWordSize)); // Pass function. 1907 __ sw(T0, Address(SP, 0 * kWordSize)); // Pass function.
1953 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); 1908 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1954 __ lw(T0, Address(SP, 0 * kWordSize)); // Restore function. 1909 __ lw(T0, Address(SP, 0 * kWordSize)); // Restore function.
1955 __ lw(S4, Address(SP, 1 * kWordSize)); // Restore args descriptor array. 1910 __ lw(S4, Address(SP, 1 * kWordSize)); // Restore args descriptor array.
1956 __ lw(S5, Address(SP, 2 * kWordSize)); // Restore IC data array. 1911 __ lw(S5, Address(SP, 2 * kWordSize)); // Restore IC data array.
1912 __ LeaveStubFrame();
1913
1914 __ lw(T2, FieldAddress(T0, Function::code_offset()));
1915 __ lw(T2, FieldAddress(T2, Code::instructions_offset()));
1916 __ AddImmediate(T2, Instructions::HeaderSize() - kHeapObjectTag);
1917 __ jr(T2);
1918 }
1919
1920
1921 // Stub for compiling a closure and jumping to the compiled code.
1922 // S5: IC-Data.
1923 // S4: Arguments descriptor.
1924 // T0: Function.
1925 void StubCode::GenerateLazyCompileClosureStub(Assembler* assembler) {
1926 __ EnterStubFrame();
1927 __ addiu(SP, SP, Immediate(-3 * kWordSize));
1928 __ sw(S4, Address(SP, 1 * kWordSize)); // Preserve args descriptor array.
1929 __ sw(T0, Address(SP, 0 * kWordSize)); // Pass function.
1930 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1931 __ lw(T0, Address(SP, 0 * kWordSize)); // Restore function.
1932 __ lw(S4, Address(SP, 1 * kWordSize)); // Restore args descriptor array.
1933 __ LeaveStubFrame();
1934
1935 __ lw(T2, FieldAddress(T0, Function::code_offset()));
1936 __ lw(T2, FieldAddress(T2, Code::instructions_offset()));
1937 __ AddImmediate(T2, Instructions::HeaderSize() - kHeapObjectTag);
1938 __ jr(T2);
1939 }
1940
1941
1942 // Stub for calling the CompileFunction runtime call.
1943 // T0: Function.
1944 void StubCode::GenerateCompileFunctionRuntimeCallStub(Assembler* assembler) {
1945 __ EnterStubFrame();
1946 __ addiu(SP, SP, Immediate(-2 * kWordSize));
1947 __ sw(T0, Address(SP, 0 * kWordSize)); // Pass function.
1948 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1949 __ lw(T0, Address(SP, 0 * kWordSize)); // Restore function.
1957 __ LeaveStubFrameAndReturn(); 1950 __ LeaveStubFrameAndReturn();
1958 } 1951 }
1959 1952
1960 1953
1961 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { 1954 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
1962 __ Comment("BreakpointRuntime stub"); 1955 __ Comment("BreakpointRuntime stub");
1963 __ EnterStubFrame(); 1956 __ EnterStubFrame();
1964 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 1957 __ addiu(SP, SP, Immediate(-3 * kWordSize));
1965 __ sw(S5, Address(SP, 2 * kWordSize)); 1958 __ sw(S5, Address(SP, 2 * kWordSize));
1966 __ sw(S4, Address(SP, 1 * kWordSize)); 1959 __ sw(S4, Address(SP, 1 * kWordSize));
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
2295 const Register right = T0; 2288 const Register right = T0;
2296 __ lw(left, Address(SP, 1 * kWordSize)); 2289 __ lw(left, Address(SP, 1 * kWordSize));
2297 __ lw(right, Address(SP, 0 * kWordSize)); 2290 __ lw(right, Address(SP, 0 * kWordSize));
2298 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); 2291 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2);
2299 __ Ret(); 2292 __ Ret();
2300 } 2293 }
2301 2294
2302 } // namespace dart 2295 } // namespace dart
2303 2296
2304 #endif // defined TARGET_ARCH_MIPS 2297 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698