OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_PPC | 5 #if V8_TARGET_ARCH_PPC |
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 1056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1067 Operand(ExternalReference::interpreter_dispatch_table_address( | 1067 Operand(ExternalReference::interpreter_dispatch_table_address( |
1068 masm->isolate()))); | 1068 masm->isolate()))); |
1069 | 1069 |
1070 // Dispatch to the first bytecode handler for the function. | 1070 // Dispatch to the first bytecode handler for the function. |
1071 __ lbzx(r4, MemOperand(kInterpreterBytecodeArrayRegister, | 1071 __ lbzx(r4, MemOperand(kInterpreterBytecodeArrayRegister, |
1072 kInterpreterBytecodeOffsetRegister)); | 1072 kInterpreterBytecodeOffsetRegister)); |
1073 __ ShiftLeftImm(ip, r4, Operand(kPointerSizeLog2)); | 1073 __ ShiftLeftImm(ip, r4, Operand(kPointerSizeLog2)); |
1074 __ LoadPX(ip, MemOperand(kInterpreterDispatchTableRegister, ip)); | 1074 __ LoadPX(ip, MemOperand(kInterpreterDispatchTableRegister, ip)); |
1075 __ Call(ip); | 1075 __ Call(ip); |
1076 | 1076 |
1077 // Even though the first bytecode handler was called, we will never return. | 1077 masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset()); |
1078 __ Abort(kUnexpectedReturnFromBytecodeHandler); | 1078 |
| 1079 // The return value is in r3. |
| 1080 |
| 1081 // Get the arguments + reciever count. |
| 1082 __ LoadP(r5, MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp)); |
| 1083 __ lwz(r5, FieldMemOperand(r5, BytecodeArray::kParameterSizeOffset)); |
| 1084 |
| 1085 // Leave the frame (also dropping the register file). |
| 1086 __ LeaveFrame(StackFrame::JAVA_SCRIPT); |
| 1087 |
| 1088 __ add(sp, sp, r5); |
| 1089 __ blr(); |
1079 | 1090 |
1080 // If the bytecode array is no longer present, then the underlying function | 1091 // If the bytecode array is no longer present, then the underlying function |
1081 // has been switched to a different kind of code and we heal the closure by | 1092 // has been switched to a different kind of code and we heal the closure by |
1082 // switching the code entry field over to the new code object as well. | 1093 // switching the code entry field over to the new code object as well. |
1083 __ bind(&bytecode_array_not_present); | 1094 __ bind(&bytecode_array_not_present); |
1084 __ LeaveFrame(StackFrame::JAVA_SCRIPT); | 1095 __ LeaveFrame(StackFrame::JAVA_SCRIPT); |
1085 __ LoadP(r7, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); | 1096 __ LoadP(r7, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); |
1086 __ LoadP(r7, FieldMemOperand(r7, SharedFunctionInfo::kCodeOffset)); | 1097 __ LoadP(r7, FieldMemOperand(r7, SharedFunctionInfo::kCodeOffset)); |
1087 __ addi(r7, r7, Operand(Code::kHeaderSize - kHeapObjectTag)); | 1098 __ addi(r7, r7, Operand(Code::kHeaderSize - kHeapObjectTag)); |
1088 __ StoreP(r7, FieldMemOperand(r4, JSFunction::kCodeEntryOffset), r0); | 1099 __ StoreP(r7, FieldMemOperand(r4, JSFunction::kCodeEntryOffset), r0); |
1089 __ RecordWriteCodeEntryField(r4, r7, r8); | 1100 __ RecordWriteCodeEntryField(r4, r7, r8); |
1090 __ JumpToJSEntry(r7); | 1101 __ JumpToJSEntry(r7); |
1091 } | 1102 } |
1092 | 1103 |
1093 | 1104 |
1094 void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { | |
1095 // The return value is in accumulator, which is already in r3. | |
1096 | |
1097 // Leave the frame (also dropping the register file). | |
1098 __ LeaveFrame(StackFrame::JAVA_SCRIPT); | |
1099 | |
1100 // Drop receiver + arguments and return. | |
1101 __ lwz(r0, FieldMemOperand(kInterpreterBytecodeArrayRegister, | |
1102 BytecodeArray::kParameterSizeOffset)); | |
1103 __ add(sp, sp, r0); | |
1104 __ blr(); | |
1105 } | |
1106 | |
1107 | |
1108 static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register index, | 1105 static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register index, |
1109 Register count, Register scratch) { | 1106 Register count, Register scratch) { |
1110 Label loop; | 1107 Label loop; |
1111 __ addi(index, index, Operand(kPointerSize)); // Bias up for LoadPU | 1108 __ addi(index, index, Operand(kPointerSize)); // Bias up for LoadPU |
1112 __ mtctr(count); | 1109 __ mtctr(count); |
1113 __ bind(&loop); | 1110 __ bind(&loop); |
1114 __ LoadPU(scratch, MemOperand(index, -kPointerSize)); | 1111 __ LoadPU(scratch, MemOperand(index, -kPointerSize)); |
1115 __ push(scratch); | 1112 __ push(scratch); |
1116 __ bdnz(&loop); | 1113 __ bdnz(&loop); |
1117 } | 1114 } |
1118 | 1115 |
1119 | |
1120 // static | 1116 // static |
1121 void Builtins::Generate_InterpreterPushArgsAndCallImpl( | 1117 void Builtins::Generate_InterpreterPushArgsAndCallImpl( |
1122 MacroAssembler* masm, TailCallMode tail_call_mode) { | 1118 MacroAssembler* masm, TailCallMode tail_call_mode) { |
1123 // ----------- S t a t e ------------- | 1119 // ----------- S t a t e ------------- |
1124 // -- r3 : the number of arguments (not including the receiver) | 1120 // -- r3 : the number of arguments (not including the receiver) |
1125 // -- r5 : the address of the first argument to be pushed. Subsequent | 1121 // -- r5 : the address of the first argument to be pushed. Subsequent |
1126 // arguments should be consecutive above this, in the same order as | 1122 // arguments should be consecutive above this, in the same order as |
1127 // they are to be pushed onto the stack. | 1123 // they are to be pushed onto the stack. |
1128 // -- r4 : the target to call (can be any Object). | 1124 // -- r4 : the target to call (can be any Object). |
1129 // ----------------------------------- | 1125 // ----------------------------------- |
1130 | 1126 |
1131 // Calculate number of arguments (add one for receiver). | 1127 // Calculate number of arguments (add one for receiver). |
1132 __ addi(r6, r3, Operand(1)); | 1128 __ addi(r6, r3, Operand(1)); |
1133 | 1129 |
1134 // Push the arguments. | 1130 // Push the arguments. |
1135 Generate_InterpreterPushArgs(masm, r5, r6, r7); | 1131 Generate_InterpreterPushArgs(masm, r5, r6, r7); |
1136 | 1132 |
1137 // Call the target. | 1133 // Call the target. |
1138 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 1134 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
1139 tail_call_mode), | 1135 tail_call_mode), |
1140 RelocInfo::CODE_TARGET); | 1136 RelocInfo::CODE_TARGET); |
1141 } | 1137 } |
1142 | 1138 |
1143 | |
1144 // static | 1139 // static |
1145 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { | 1140 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { |
1146 // ----------- S t a t e ------------- | 1141 // ----------- S t a t e ------------- |
1147 // -- r3 : argument count (not including receiver) | 1142 // -- r3 : argument count (not including receiver) |
1148 // -- r6 : new target | 1143 // -- r6 : new target |
1149 // -- r4 : constructor to call | 1144 // -- r4 : constructor to call |
1150 // -- r5 : address of the first argument | 1145 // -- r5 : address of the first argument |
1151 // ----------------------------------- | 1146 // ----------------------------------- |
1152 | 1147 |
1153 // Push a slot for the receiver to be constructed. | 1148 // Push a slot for the receiver to be constructed. |
1154 __ li(r0, Operand::Zero()); | 1149 __ li(r0, Operand::Zero()); |
1155 __ push(r0); | 1150 __ push(r0); |
1156 | 1151 |
1157 // Push the arguments (skip if none). | 1152 // Push the arguments (skip if none). |
1158 Label skip; | 1153 Label skip; |
1159 __ cmpi(r3, Operand::Zero()); | 1154 __ cmpi(r3, Operand::Zero()); |
1160 __ beq(&skip); | 1155 __ beq(&skip); |
1161 Generate_InterpreterPushArgs(masm, r5, r3, r7); | 1156 Generate_InterpreterPushArgs(masm, r5, r3, r7); |
1162 __ bind(&skip); | 1157 __ bind(&skip); |
1163 | 1158 |
1164 // Call the constructor with r3, r4, and r6 unmodified. | 1159 // Call the constructor with r3, r4, and r6 unmodified. |
1165 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 1160 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
1166 } | 1161 } |
1167 | 1162 |
| 1163 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) { |
| 1164 // Set the return address to the correct point in the interpreter entry |
| 1165 // trampoline. |
| 1166 Smi* interpreter_entry_return_pc_offset( |
| 1167 masm->isolate()->heap()->interpreter_entry_return_pc_offset()); |
| 1168 DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0)); |
| 1169 __ Move(r5, masm->isolate()->builtins()->InterpreterEntryTrampoline()); |
| 1170 __ addi(r0, r5, Operand(interpreter_entry_return_pc_offset->value() + |
| 1171 Code::kHeaderSize - kHeapObjectTag)); |
| 1172 __ mtlr(r0); |
1168 | 1173 |
1169 static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) { | |
1170 // Initialize the dispatch table register. | 1174 // Initialize the dispatch table register. |
1171 __ mov(kInterpreterDispatchTableRegister, | 1175 __ mov(kInterpreterDispatchTableRegister, |
1172 Operand(ExternalReference::interpreter_dispatch_table_address( | 1176 Operand(ExternalReference::interpreter_dispatch_table_address( |
1173 masm->isolate()))); | 1177 masm->isolate()))); |
1174 | 1178 |
1175 // Get the bytecode array pointer from the frame. | 1179 // Get the bytecode array pointer from the frame. |
1176 __ LoadP(kInterpreterBytecodeArrayRegister, | 1180 __ LoadP(kInterpreterBytecodeArrayRegister, |
1177 MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp)); | 1181 MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp)); |
1178 | 1182 |
1179 if (FLAG_debug_code) { | 1183 if (FLAG_debug_code) { |
(...skipping 12 matching lines...) Expand all Loading... |
1192 | 1196 |
1193 // Dispatch to the target bytecode. | 1197 // Dispatch to the target bytecode. |
1194 __ lbzx(r4, MemOperand(kInterpreterBytecodeArrayRegister, | 1198 __ lbzx(r4, MemOperand(kInterpreterBytecodeArrayRegister, |
1195 kInterpreterBytecodeOffsetRegister)); | 1199 kInterpreterBytecodeOffsetRegister)); |
1196 __ ShiftLeftImm(ip, r4, Operand(kPointerSizeLog2)); | 1200 __ ShiftLeftImm(ip, r4, Operand(kPointerSizeLog2)); |
1197 __ LoadPX(ip, MemOperand(kInterpreterDispatchTableRegister, ip)); | 1201 __ LoadPX(ip, MemOperand(kInterpreterDispatchTableRegister, ip)); |
1198 __ Jump(ip); | 1202 __ Jump(ip); |
1199 } | 1203 } |
1200 | 1204 |
1201 | 1205 |
1202 static void Generate_InterpreterNotifyDeoptimizedHelper( | |
1203 MacroAssembler* masm, Deoptimizer::BailoutType type) { | |
1204 // Enter an internal frame. | |
1205 { | |
1206 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | |
1207 | |
1208 // Pass the deoptimization type to the runtime system. | |
1209 __ LoadSmiLiteral(r4, Smi::FromInt(static_cast<int>(type))); | |
1210 __ Push(r4); | |
1211 __ CallRuntime(Runtime::kNotifyDeoptimized); | |
1212 // Tear down internal frame. | |
1213 } | |
1214 | |
1215 // Drop state (we don't use these for interpreter deopts) and and pop the | |
1216 // accumulator value into the accumulator register. | |
1217 __ Drop(1); | |
1218 __ Pop(kInterpreterAccumulatorRegister); | |
1219 | |
1220 // Enter the bytecode dispatch. | |
1221 Generate_EnterBytecodeDispatch(masm); | |
1222 } | |
1223 | |
1224 | |
1225 void Builtins::Generate_InterpreterNotifyDeoptimized(MacroAssembler* masm) { | |
1226 Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); | |
1227 } | |
1228 | |
1229 | |
1230 void Builtins::Generate_InterpreterNotifySoftDeoptimized(MacroAssembler* masm) { | |
1231 Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); | |
1232 } | |
1233 | |
1234 | |
1235 void Builtins::Generate_InterpreterNotifyLazyDeoptimized(MacroAssembler* masm) { | |
1236 Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); | |
1237 } | |
1238 | |
1239 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) { | |
1240 // Set the address of the interpreter entry trampoline as a return address. | |
1241 // This simulates the initial call to bytecode handlers in interpreter entry | |
1242 // trampoline. The return will never actually be taken, but our stack walker | |
1243 // uses this address to determine whether a frame is interpreted. | |
1244 __ mov(r0, | |
1245 Operand(masm->isolate()->builtins()->InterpreterEntryTrampoline())); | |
1246 __ mtlr(r0); | |
1247 | |
1248 Generate_EnterBytecodeDispatch(masm); | |
1249 } | |
1250 | |
1251 | |
1252 void Builtins::Generate_CompileLazy(MacroAssembler* masm) { | 1206 void Builtins::Generate_CompileLazy(MacroAssembler* masm) { |
1253 // ----------- S t a t e ------------- | 1207 // ----------- S t a t e ------------- |
1254 // -- r3 : argument count (preserved for callee) | 1208 // -- r3 : argument count (preserved for callee) |
1255 // -- r6 : new target (preserved for callee) | 1209 // -- r6 : new target (preserved for callee) |
1256 // -- r4 : target function (preserved for callee) | 1210 // -- r4 : target function (preserved for callee) |
1257 // ----------------------------------- | 1211 // ----------------------------------- |
1258 // First lookup code, maybe we don't need to compile! | 1212 // First lookup code, maybe we don't need to compile! |
1259 Label gotta_call_runtime; | 1213 Label gotta_call_runtime; |
1260 Label maybe_call_runtime; | 1214 Label maybe_call_runtime; |
1261 Label try_shared; | 1215 Label try_shared; |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1534 __ LoadSmiLiteral(r3, Smi::FromInt(static_cast<int>(type))); | 1488 __ LoadSmiLiteral(r3, Smi::FromInt(static_cast<int>(type))); |
1535 __ push(r3); | 1489 __ push(r3); |
1536 __ CallRuntime(Runtime::kNotifyDeoptimized); | 1490 __ CallRuntime(Runtime::kNotifyDeoptimized); |
1537 } | 1491 } |
1538 | 1492 |
1539 // Get the full codegen state from the stack and untag it -> r9. | 1493 // Get the full codegen state from the stack and untag it -> r9. |
1540 __ LoadP(r9, MemOperand(sp, 0 * kPointerSize)); | 1494 __ LoadP(r9, MemOperand(sp, 0 * kPointerSize)); |
1541 __ SmiUntag(r9); | 1495 __ SmiUntag(r9); |
1542 // Switch on the state. | 1496 // Switch on the state. |
1543 Label with_tos_register, unknown_state; | 1497 Label with_tos_register, unknown_state; |
1544 __ cmpi(r9, Operand(FullCodeGenerator::NO_REGISTERS)); | 1498 __ cmpi(r9, |
| 1499 Operand(static_cast<int>(Deoptimizer::BailoutState::NO_REGISTERS))); |
1545 __ bne(&with_tos_register); | 1500 __ bne(&with_tos_register); |
1546 __ addi(sp, sp, Operand(1 * kPointerSize)); // Remove state. | 1501 __ addi(sp, sp, Operand(1 * kPointerSize)); // Remove state. |
1547 __ Ret(); | 1502 __ Ret(); |
1548 | 1503 |
1549 __ bind(&with_tos_register); | 1504 __ bind(&with_tos_register); |
| 1505 DCHECK_EQ(kInterpreterAccumulatorRegister.code(), r3.code()); |
1550 __ LoadP(r3, MemOperand(sp, 1 * kPointerSize)); | 1506 __ LoadP(r3, MemOperand(sp, 1 * kPointerSize)); |
1551 __ cmpi(r9, Operand(FullCodeGenerator::TOS_REG)); | 1507 __ cmpi(r9, |
| 1508 Operand(static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER))); |
1552 __ bne(&unknown_state); | 1509 __ bne(&unknown_state); |
1553 __ addi(sp, sp, Operand(2 * kPointerSize)); // Remove state. | 1510 __ addi(sp, sp, Operand(2 * kPointerSize)); // Remove state. |
1554 __ Ret(); | 1511 __ Ret(); |
1555 | 1512 |
1556 __ bind(&unknown_state); | 1513 __ bind(&unknown_state); |
1557 __ stop("no cases left"); | 1514 __ stop("no cases left"); |
1558 } | 1515 } |
1559 | 1516 |
1560 | 1517 |
1561 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { | 1518 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { |
(...skipping 1307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2869 __ bkpt(0); | 2826 __ bkpt(0); |
2870 } | 2827 } |
2871 } | 2828 } |
2872 | 2829 |
2873 | 2830 |
2874 #undef __ | 2831 #undef __ |
2875 } // namespace internal | 2832 } // namespace internal |
2876 } // namespace v8 | 2833 } // namespace v8 |
2877 | 2834 |
2878 #endif // V8_TARGET_ARCH_PPC | 2835 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |