OLD | NEW |
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_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 1112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1123 | 1123 |
1124 void MacroAssembler::LeaveFrame(StackFrame::Type type) { | 1124 void MacroAssembler::LeaveFrame(StackFrame::Type type) { |
1125 if (emit_debug_code()) { | 1125 if (emit_debug_code()) { |
1126 cmp(Operand(ebp, CommonFrameConstants::kContextOrFrameTypeOffset), | 1126 cmp(Operand(ebp, CommonFrameConstants::kContextOrFrameTypeOffset), |
1127 Immediate(Smi::FromInt(type))); | 1127 Immediate(Smi::FromInt(type))); |
1128 Check(equal, kStackFrameTypesMustMatch); | 1128 Check(equal, kStackFrameTypesMustMatch); |
1129 } | 1129 } |
1130 leave(); | 1130 leave(); |
1131 } | 1131 } |
1132 | 1132 |
| 1133 void MacroAssembler::EnterExitFramePrologue(StackFrame::Type frame_type) { |
| 1134 DCHECK(frame_type == StackFrame::EXIT || |
| 1135 frame_type == StackFrame::BUILTIN_EXIT); |
1133 | 1136 |
1134 void MacroAssembler::EnterExitFramePrologue() { | |
1135 // Set up the frame structure on the stack. | 1137 // Set up the frame structure on the stack. |
1136 DCHECK_EQ(+2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); | 1138 DCHECK_EQ(+2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); |
1137 DCHECK_EQ(+1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); | 1139 DCHECK_EQ(+1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); |
1138 DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); | 1140 DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); |
1139 push(ebp); | 1141 push(ebp); |
1140 mov(ebp, esp); | 1142 mov(ebp, esp); |
1141 | 1143 |
1142 // Reserve room for entry stack pointer and push the code object. | 1144 // Reserve room for entry stack pointer and push the code object. |
1143 push(Immediate(Smi::FromInt(StackFrame::EXIT))); | 1145 push(Immediate(Smi::FromInt(frame_type))); |
1144 DCHECK_EQ(-2 * kPointerSize, ExitFrameConstants::kSPOffset); | 1146 DCHECK_EQ(-2 * kPointerSize, ExitFrameConstants::kSPOffset); |
1145 push(Immediate(0)); // Saved entry sp, patched before call. | 1147 push(Immediate(0)); // Saved entry sp, patched before call. |
1146 DCHECK_EQ(-3 * kPointerSize, ExitFrameConstants::kCodeOffset); | 1148 DCHECK_EQ(-3 * kPointerSize, ExitFrameConstants::kCodeOffset); |
1147 push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. | 1149 push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. |
1148 | 1150 |
1149 // Save the frame pointer and the context in top. | 1151 // Save the frame pointer and the context in top. |
1150 ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate()); | 1152 ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate()); |
1151 ExternalReference context_address(Isolate::kContextAddress, isolate()); | 1153 ExternalReference context_address(Isolate::kContextAddress, isolate()); |
1152 ExternalReference c_function_address(Isolate::kCFunctionAddress, isolate()); | 1154 ExternalReference c_function_address(Isolate::kCFunctionAddress, isolate()); |
1153 mov(Operand::StaticVariable(c_entry_fp_address), ebp); | 1155 mov(Operand::StaticVariable(c_entry_fp_address), ebp); |
(...skipping 21 matching lines...) Expand all Loading... |
1175 const int kFrameAlignment = base::OS::ActivationFrameAlignment(); | 1177 const int kFrameAlignment = base::OS::ActivationFrameAlignment(); |
1176 if (kFrameAlignment > 0) { | 1178 if (kFrameAlignment > 0) { |
1177 DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment)); | 1179 DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment)); |
1178 and_(esp, -kFrameAlignment); | 1180 and_(esp, -kFrameAlignment); |
1179 } | 1181 } |
1180 | 1182 |
1181 // Patch the saved entry sp. | 1183 // Patch the saved entry sp. |
1182 mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp); | 1184 mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp); |
1183 } | 1185 } |
1184 | 1186 |
1185 | 1187 void MacroAssembler::EnterExitFrame(int argc, bool save_doubles, |
1186 void MacroAssembler::EnterExitFrame(int argc, bool save_doubles) { | 1188 StackFrame::Type frame_type) { |
1187 EnterExitFramePrologue(); | 1189 EnterExitFramePrologue(frame_type); |
1188 | 1190 |
1189 // Set up argc and argv in callee-saved registers. | 1191 // Set up argc and argv in callee-saved registers. |
1190 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; | 1192 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; |
1191 mov(edi, eax); | 1193 mov(edi, eax); |
1192 lea(esi, Operand(ebp, eax, times_4, offset)); | 1194 lea(esi, Operand(ebp, eax, times_4, offset)); |
1193 | 1195 |
1194 // Reserve space for argc, argv and isolate. | 1196 // Reserve space for argc, argv and isolate. |
1195 EnterExitFrameEpilogue(argc, save_doubles); | 1197 EnterExitFrameEpilogue(argc, save_doubles); |
1196 } | 1198 } |
1197 | 1199 |
1198 | 1200 |
1199 void MacroAssembler::EnterApiExitFrame(int argc) { | 1201 void MacroAssembler::EnterApiExitFrame(int argc) { |
1200 EnterExitFramePrologue(); | 1202 EnterExitFramePrologue(StackFrame::EXIT); |
1201 EnterExitFrameEpilogue(argc, false); | 1203 EnterExitFrameEpilogue(argc, false); |
1202 } | 1204 } |
1203 | 1205 |
1204 | 1206 |
1205 void MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { | 1207 void MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { |
1206 // Optionally restore all XMM registers. | 1208 // Optionally restore all XMM registers. |
1207 if (save_doubles) { | 1209 if (save_doubles) { |
1208 const int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; | 1210 const int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; |
1209 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { | 1211 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { |
1210 XMMRegister reg = XMMRegister::from_code(i); | 1212 XMMRegister reg = XMMRegister::from_code(i); |
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2194 if (function->nargs >= 0) { | 2196 if (function->nargs >= 0) { |
2195 // TODO(1236192): Most runtime routines don't need the number of | 2197 // TODO(1236192): Most runtime routines don't need the number of |
2196 // arguments passed in because it is constant. At some point we | 2198 // arguments passed in because it is constant. At some point we |
2197 // should remove this need and make the runtime routine entry code | 2199 // should remove this need and make the runtime routine entry code |
2198 // smarter. | 2200 // smarter. |
2199 mov(eax, Immediate(function->nargs)); | 2201 mov(eax, Immediate(function->nargs)); |
2200 } | 2202 } |
2201 JumpToExternalReference(ExternalReference(fid, isolate())); | 2203 JumpToExternalReference(ExternalReference(fid, isolate())); |
2202 } | 2204 } |
2203 | 2205 |
2204 | 2206 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext, |
2205 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext) { | 2207 bool builtin_exit_frame) { |
2206 // Set the entry point and jump to the C entry runtime stub. | 2208 // Set the entry point and jump to the C entry runtime stub. |
2207 mov(ebx, Immediate(ext)); | 2209 mov(ebx, Immediate(ext)); |
2208 CEntryStub ces(isolate(), 1); | 2210 CEntryStub ces(isolate(), 1, kDontSaveFPRegs, kArgvOnStack, |
| 2211 builtin_exit_frame); |
2209 jmp(ces.GetCode(), RelocInfo::CODE_TARGET); | 2212 jmp(ces.GetCode(), RelocInfo::CODE_TARGET); |
2210 } | 2213 } |
2211 | 2214 |
2212 void MacroAssembler::PrepareForTailCall( | 2215 void MacroAssembler::PrepareForTailCall( |
2213 const ParameterCount& callee_args_count, Register caller_args_count_reg, | 2216 const ParameterCount& callee_args_count, Register caller_args_count_reg, |
2214 Register scratch0, Register scratch1, ReturnAddressState ra_state, | 2217 Register scratch0, Register scratch1, ReturnAddressState ra_state, |
2215 int number_of_temp_values_after_return_address) { | 2218 int number_of_temp_values_after_return_address) { |
2216 #if DEBUG | 2219 #if DEBUG |
2217 if (callee_args_count.is_reg()) { | 2220 if (callee_args_count.is_reg()) { |
2218 DCHECK(!AreAliased(callee_args_count.reg(), caller_args_count_reg, scratch0, | 2221 DCHECK(!AreAliased(callee_args_count.reg(), caller_args_count_reg, scratch0, |
(...skipping 1215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3434 mov(eax, dividend); | 3437 mov(eax, dividend); |
3435 shr(eax, 31); | 3438 shr(eax, 31); |
3436 add(edx, eax); | 3439 add(edx, eax); |
3437 } | 3440 } |
3438 | 3441 |
3439 | 3442 |
3440 } // namespace internal | 3443 } // namespace internal |
3441 } // namespace v8 | 3444 } // namespace v8 |
3442 | 3445 |
3443 #endif // V8_TARGET_ARCH_IA32 | 3446 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |