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

Side by Side Diff: src/mips64/builtins-mips64.cc

Issue 1969423002: [Interpreter] Remove InterpreterExitTrampoline and replace with returning to the entry trampoline. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Review comments Created 4 years, 7 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
« no previous file with comments | « src/mips/builtins-mips.cc ('k') | src/objects.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_MIPS64 5 #if V8_TARGET_ARCH_MIPS64
6 6
7 #include "src/codegen.h" 7 #include "src/codegen.h"
8 #include "src/debug/debug.h" 8 #include "src/debug/debug.h"
9 #include "src/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/full-codegen/full-codegen.h" 10 #include "src/full-codegen/full-codegen.h"
(...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 933
934 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { 934 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
935 Generate_JSEntryTrampolineHelper(masm, false); 935 Generate_JSEntryTrampolineHelper(masm, false);
936 } 936 }
937 937
938 938
939 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { 939 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
940 Generate_JSEntryTrampolineHelper(masm, true); 940 Generate_JSEntryTrampolineHelper(masm, true);
941 } 941 }
942 942
943
944 // Generate code for entering a JS function with the interpreter. 943 // Generate code for entering a JS function with the interpreter.
945 // On entry to the function the receiver and arguments have been pushed on the 944 // On entry to the function the receiver and arguments have been pushed on the
946 // stack left to right. The actual argument count matches the formal parameter 945 // stack left to right. The actual argument count matches the formal parameter
947 // count expected by the function. 946 // count expected by the function.
948 // 947 //
949 // The live registers are: 948 // The live registers are:
950 // o a1: the JS function object being called. 949 // o a1: the JS function object being called.
951 // o a3: the new target 950 // o a3: the new target
952 // o cp: our context 951 // o cp: our context
953 // o fp: the caller's frame pointer 952 // o fp: the caller's frame pointer
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 Operand(ExternalReference::interpreter_dispatch_table_address( 1032 Operand(ExternalReference::interpreter_dispatch_table_address(
1034 masm->isolate()))); 1033 masm->isolate())));
1035 1034
1036 // Dispatch to the first bytecode handler for the function. 1035 // Dispatch to the first bytecode handler for the function.
1037 __ Daddu(a0, kInterpreterBytecodeArrayRegister, 1036 __ Daddu(a0, kInterpreterBytecodeArrayRegister,
1038 kInterpreterBytecodeOffsetRegister); 1037 kInterpreterBytecodeOffsetRegister);
1039 __ lbu(a0, MemOperand(a0)); 1038 __ lbu(a0, MemOperand(a0));
1040 __ Dlsa(at, kInterpreterDispatchTableRegister, a0, kPointerSizeLog2); 1039 __ Dlsa(at, kInterpreterDispatchTableRegister, a0, kPointerSizeLog2);
1041 __ ld(at, MemOperand(at)); 1040 __ ld(at, MemOperand(at));
1042 __ Call(at); 1041 __ Call(at);
1042 masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
1043 1043
1044 // Even though the first bytecode handler was called, we will never return. 1044 // The return value is in v0.
1045 __ Abort(kUnexpectedReturnFromBytecodeHandler); 1045
1046 // Get the arguments + reciever count.
1047 __ ld(t0, MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
1048 __ lw(t0, FieldMemOperand(t0, BytecodeArray::kParameterSizeOffset));
1049
1050 // Leave the frame (also dropping the register file).
1051 __ LeaveFrame(StackFrame::JAVA_SCRIPT);
1052
1053 // Drop receiver + arguments and return.
1054 __ Daddu(sp, sp, t0);
1055 __ Jump(ra);
1046 1056
1047 // Load debug copy of the bytecode array. 1057 // Load debug copy of the bytecode array.
1048 __ bind(&load_debug_bytecode_array); 1058 __ bind(&load_debug_bytecode_array);
1049 __ ld(kInterpreterBytecodeArrayRegister, 1059 __ ld(kInterpreterBytecodeArrayRegister,
1050 FieldMemOperand(debug_info, DebugInfo::kAbstractCodeIndex)); 1060 FieldMemOperand(debug_info, DebugInfo::kAbstractCodeIndex));
1051 __ Branch(&bytecode_array_loaded); 1061 __ Branch(&bytecode_array_loaded);
1052 1062
1053 // If the bytecode array is no longer present, then the underlying function 1063 // If the bytecode array is no longer present, then the underlying function
1054 // has been switched to a different kind of code and we heal the closure by 1064 // has been switched to a different kind of code and we heal the closure by
1055 // switching the code entry field over to the new code object as well. 1065 // switching the code entry field over to the new code object as well.
1056 __ bind(&bytecode_array_not_present); 1066 __ bind(&bytecode_array_not_present);
1057 __ LeaveFrame(StackFrame::JAVA_SCRIPT); 1067 __ LeaveFrame(StackFrame::JAVA_SCRIPT);
1058 __ ld(a4, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); 1068 __ ld(a4, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1059 __ ld(a4, FieldMemOperand(a4, SharedFunctionInfo::kCodeOffset)); 1069 __ ld(a4, FieldMemOperand(a4, SharedFunctionInfo::kCodeOffset));
1060 __ Daddu(a4, a4, Operand(Code::kHeaderSize - kHeapObjectTag)); 1070 __ Daddu(a4, a4, Operand(Code::kHeaderSize - kHeapObjectTag));
1061 __ sd(a4, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); 1071 __ sd(a4, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
1062 __ RecordWriteCodeEntryField(a1, a4, a5); 1072 __ RecordWriteCodeEntryField(a1, a4, a5);
1063 __ Jump(a4); 1073 __ Jump(a4);
1064 } 1074 }
1065 1075
1066
1067 void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
1068 // The return value is in accumulator, which is already in v0.
1069
1070 // Leave the frame (also dropping the register file).
1071 __ LeaveFrame(StackFrame::JAVA_SCRIPT);
1072
1073 // Drop receiver + arguments and return.
1074 __ lw(at, FieldMemOperand(kInterpreterBytecodeArrayRegister,
1075 BytecodeArray::kParameterSizeOffset));
1076 __ Daddu(sp, sp, at);
1077 __ Jump(ra);
1078 }
1079
1080
1081 // static 1076 // static
1082 void Builtins::Generate_InterpreterPushArgsAndCallImpl( 1077 void Builtins::Generate_InterpreterPushArgsAndCallImpl(
1083 MacroAssembler* masm, TailCallMode tail_call_mode) { 1078 MacroAssembler* masm, TailCallMode tail_call_mode) {
1084 // ----------- S t a t e ------------- 1079 // ----------- S t a t e -------------
1085 // -- a0 : the number of arguments (not including the receiver) 1080 // -- a0 : the number of arguments (not including the receiver)
1086 // -- a2 : the address of the first argument to be pushed. Subsequent 1081 // -- a2 : the address of the first argument to be pushed. Subsequent
1087 // arguments should be consecutive above this, in the same order as 1082 // arguments should be consecutive above this, in the same order as
1088 // they are to be pushed onto the stack. 1083 // they are to be pushed onto the stack.
1089 // -- a1 : the target to call (can be any Object). 1084 // -- a1 : the target to call (can be any Object).
1090 // ----------------------------------- 1085 // -----------------------------------
(...skipping 12 matching lines...) Expand all
1103 __ push(t0); 1098 __ push(t0);
1104 __ bind(&loop_check); 1099 __ bind(&loop_check);
1105 __ Branch(&loop_header, gt, a2, Operand(a3)); 1100 __ Branch(&loop_header, gt, a2, Operand(a3));
1106 1101
1107 // Call the target. 1102 // Call the target.
1108 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, 1103 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
1109 tail_call_mode), 1104 tail_call_mode),
1110 RelocInfo::CODE_TARGET); 1105 RelocInfo::CODE_TARGET);
1111 } 1106 }
1112 1107
1113
1114 // static 1108 // static
1115 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { 1109 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
1116 // ----------- S t a t e ------------- 1110 // ----------- S t a t e -------------
1117 // -- a0 : argument count (not including receiver) 1111 // -- a0 : argument count (not including receiver)
1118 // -- a3 : new target 1112 // -- a3 : new target
1119 // -- a1 : constructor to call 1113 // -- a1 : constructor to call
1120 // -- a2 : address of the first argument 1114 // -- a2 : address of the first argument
1121 // ----------------------------------- 1115 // -----------------------------------
1122 1116
1123 // Find the address of the last argument. 1117 // Find the address of the last argument.
(...skipping 10 matching lines...) Expand all
1134 __ ld(t1, MemOperand(a2)); 1128 __ ld(t1, MemOperand(a2));
1135 __ Daddu(a2, a2, Operand(-kPointerSize)); 1129 __ Daddu(a2, a2, Operand(-kPointerSize));
1136 __ push(t1); 1130 __ push(t1);
1137 __ bind(&loop_check); 1131 __ bind(&loop_check);
1138 __ Branch(&loop_header, gt, a2, Operand(t0)); 1132 __ Branch(&loop_header, gt, a2, Operand(t0));
1139 1133
1140 // Call the constructor with a0, a1, and a3 unmodified. 1134 // Call the constructor with a0, a1, and a3 unmodified.
1141 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 1135 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
1142 } 1136 }
1143 1137
1138 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
1139 // Set the return address to the correct point in the interpreter entry
1140 // trampoline.
1141 Smi* interpreter_entry_return_pc_offset(
1142 masm->isolate()->heap()->interpreter_entry_return_pc_offset());
1143 DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0));
1144 __ li(t0, Operand(masm->isolate()->builtins()->InterpreterEntryTrampoline()));
1145 __ Daddu(ra, t0, Operand(interpreter_entry_return_pc_offset->value() +
1146 Code::kHeaderSize - kHeapObjectTag));
1144 1147
1145 static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
1146 // Initialize the dispatch table register. 1148 // Initialize the dispatch table register.
1147 __ li(kInterpreterDispatchTableRegister, 1149 __ li(kInterpreterDispatchTableRegister,
1148 Operand(ExternalReference::interpreter_dispatch_table_address( 1150 Operand(ExternalReference::interpreter_dispatch_table_address(
1149 masm->isolate()))); 1151 masm->isolate())));
1150 1152
1151 // Get the bytecode array pointer from the frame. 1153 // Get the bytecode array pointer from the frame.
1152 __ ld(kInterpreterBytecodeArrayRegister, 1154 __ ld(kInterpreterBytecodeArrayRegister,
1153 MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp)); 1155 MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
1154 1156
1155 if (FLAG_debug_code) { 1157 if (FLAG_debug_code) {
(...skipping 13 matching lines...) Expand all
1169 1171
1170 // Dispatch to the target bytecode. 1172 // Dispatch to the target bytecode.
1171 __ Daddu(a1, kInterpreterBytecodeArrayRegister, 1173 __ Daddu(a1, kInterpreterBytecodeArrayRegister,
1172 kInterpreterBytecodeOffsetRegister); 1174 kInterpreterBytecodeOffsetRegister);
1173 __ lbu(a1, MemOperand(a1)); 1175 __ lbu(a1, MemOperand(a1));
1174 __ Dlsa(a1, kInterpreterDispatchTableRegister, a1, kPointerSizeLog2); 1176 __ Dlsa(a1, kInterpreterDispatchTableRegister, a1, kPointerSizeLog2);
1175 __ ld(a1, MemOperand(a1)); 1177 __ ld(a1, MemOperand(a1));
1176 __ Jump(a1); 1178 __ Jump(a1);
1177 } 1179 }
1178 1180
1179
1180 static void Generate_InterpreterNotifyDeoptimizedHelper(
1181 MacroAssembler* masm, Deoptimizer::BailoutType type) {
1182 // Enter an internal frame.
1183 {
1184 FrameScope scope(masm, StackFrame::INTERNAL);
1185
1186 // Pass the deoptimization type to the runtime system.
1187 __ li(a1, Operand(Smi::FromInt(static_cast<int>(type))));
1188 __ push(a1);
1189 __ CallRuntime(Runtime::kNotifyDeoptimized);
1190 // Tear down internal frame.
1191 }
1192
1193 // Drop state (we don't use these for interpreter deopts) and and pop the
1194 // accumulator value into the accumulator register.
1195 __ Drop(1);
1196 __ Pop(kInterpreterAccumulatorRegister);
1197
1198 // Enter the bytecode dispatch.
1199 Generate_EnterBytecodeDispatch(masm);
1200 }
1201
1202
1203 void Builtins::Generate_InterpreterNotifyDeoptimized(MacroAssembler* masm) {
1204 Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
1205 }
1206
1207
1208 void Builtins::Generate_InterpreterNotifySoftDeoptimized(MacroAssembler* masm) {
1209 Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
1210 }
1211
1212
1213 void Builtins::Generate_InterpreterNotifyLazyDeoptimized(MacroAssembler* masm) {
1214 Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
1215 }
1216
1217 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
1218 // Set the address of the interpreter entry trampoline as a return address.
1219 // This simulates the initial call to bytecode handlers in interpreter entry
1220 // trampoline. The return will never actually be taken, but our stack walker
1221 // uses this address to determine whether a frame is interpreted.
1222 __ li(ra, Operand(masm->isolate()->builtins()->InterpreterEntryTrampoline()));
1223
1224 Generate_EnterBytecodeDispatch(masm);
1225 }
1226
1227
1228 void Builtins::Generate_CompileLazy(MacroAssembler* masm) { 1181 void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
1229 // ----------- S t a t e ------------- 1182 // ----------- S t a t e -------------
1230 // -- a0 : argument count (preserved for callee) 1183 // -- a0 : argument count (preserved for callee)
1231 // -- a3 : new target (preserved for callee) 1184 // -- a3 : new target (preserved for callee)
1232 // -- a1 : target function (preserved for callee) 1185 // -- a1 : target function (preserved for callee)
1233 // ----------------------------------- 1186 // -----------------------------------
1234 // First lookup code, maybe we don't need to compile! 1187 // First lookup code, maybe we don't need to compile!
1235 Label gotta_call_runtime, gotta_call_runtime_no_stack; 1188 Label gotta_call_runtime, gotta_call_runtime_no_stack;
1236 Label maybe_call_runtime; 1189 Label maybe_call_runtime;
1237 Label try_shared; 1190 Label try_shared;
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
1514 __ li(a0, Operand(Smi::FromInt(static_cast<int>(type)))); 1467 __ li(a0, Operand(Smi::FromInt(static_cast<int>(type))));
1515 __ push(a0); 1468 __ push(a0);
1516 __ CallRuntime(Runtime::kNotifyDeoptimized); 1469 __ CallRuntime(Runtime::kNotifyDeoptimized);
1517 } 1470 }
1518 1471
1519 // Get the full codegen state from the stack and untag it -> a6. 1472 // Get the full codegen state from the stack and untag it -> a6.
1520 __ ld(a6, MemOperand(sp, 0 * kPointerSize)); 1473 __ ld(a6, MemOperand(sp, 0 * kPointerSize));
1521 __ SmiUntag(a6); 1474 __ SmiUntag(a6);
1522 // Switch on the state. 1475 // Switch on the state.
1523 Label with_tos_register, unknown_state; 1476 Label with_tos_register, unknown_state;
1524 __ Branch(&with_tos_register, 1477 __ Branch(&with_tos_register, ne, a6,
1525 ne, a6, Operand(FullCodeGenerator::NO_REGISTERS)); 1478 Operand(static_cast<int>(Deoptimizer::BailoutState::NO_REGISTERS)));
1526 __ Ret(USE_DELAY_SLOT); 1479 __ Ret(USE_DELAY_SLOT);
1527 // Safe to fill delay slot Addu will emit one instruction. 1480 // Safe to fill delay slot Addu will emit one instruction.
1528 __ Daddu(sp, sp, Operand(1 * kPointerSize)); // Remove state. 1481 __ Daddu(sp, sp, Operand(1 * kPointerSize)); // Remove state.
1529 1482
1530 __ bind(&with_tos_register); 1483 __ bind(&with_tos_register);
1484 DCHECK_EQ(kInterpreterAccumulatorRegister.code(), v0.code());
1531 __ ld(v0, MemOperand(sp, 1 * kPointerSize)); 1485 __ ld(v0, MemOperand(sp, 1 * kPointerSize));
1532 __ Branch(&unknown_state, ne, a6, Operand(FullCodeGenerator::TOS_REG)); 1486 __ Branch(&unknown_state, ne, t2,
1487 Operand(static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER)));
1533 1488
1534 __ Ret(USE_DELAY_SLOT); 1489 __ Ret(USE_DELAY_SLOT);
1535 // Safe to fill delay slot Addu will emit one instruction. 1490 // Safe to fill delay slot Addu will emit one instruction.
1536 __ Daddu(sp, sp, Operand(2 * kPointerSize)); // Remove state. 1491 __ Daddu(sp, sp, Operand(2 * kPointerSize)); // Remove state.
1537 1492
1538 __ bind(&unknown_state); 1493 __ bind(&unknown_state);
1539 __ stop("no cases left"); 1494 __ stop("no cases left");
1540 } 1495 }
1541 1496
1542 1497
(...skipping 1341 matching lines...) Expand 10 before | Expand all | Expand 10 after
2884 } 2839 }
2885 } 2840 }
2886 2841
2887 2842
2888 #undef __ 2843 #undef __
2889 2844
2890 } // namespace internal 2845 } // namespace internal
2891 } // namespace v8 2846 } // namespace v8
2892 2847
2893 #endif // V8_TARGET_ARCH_MIPS64 2848 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/mips/builtins-mips.cc ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698