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 990 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1001 } | 1001 } |
1002 | 1002 |
1003 | 1003 |
1004 void MacroAssembler::AssertNotSmi(Register object) { | 1004 void MacroAssembler::AssertNotSmi(Register object) { |
1005 if (emit_debug_code()) { | 1005 if (emit_debug_code()) { |
1006 test(object, Immediate(kSmiTagMask)); | 1006 test(object, Immediate(kSmiTagMask)); |
1007 Check(not_equal, kOperandIsASmi); | 1007 Check(not_equal, kOperandIsASmi); |
1008 } | 1008 } |
1009 } | 1009 } |
1010 | 1010 |
1011 | 1011 void MacroAssembler::StubPrologue(StackFrame::Type type) { |
1012 void MacroAssembler::StubPrologue() { | |
1013 push(ebp); // Caller's frame pointer. | 1012 push(ebp); // Caller's frame pointer. |
1014 mov(ebp, esp); | 1013 mov(ebp, esp); |
1015 push(esi); // Callee's context. | 1014 push(Immediate(Smi::FromInt(type))); |
1016 push(Immediate(Smi::FromInt(StackFrame::STUB))); | |
1017 } | 1015 } |
1018 | 1016 |
1019 | |
1020 void MacroAssembler::Prologue(bool code_pre_aging) { | 1017 void MacroAssembler::Prologue(bool code_pre_aging) { |
1021 PredictableCodeSizeScope predictible_code_size_scope(this, | 1018 PredictableCodeSizeScope predictible_code_size_scope(this, |
1022 kNoCodeAgeSequenceLength); | 1019 kNoCodeAgeSequenceLength); |
1023 if (code_pre_aging) { | 1020 if (code_pre_aging) { |
1024 // Pre-age the code. | 1021 // Pre-age the code. |
1025 call(isolate()->builtins()->MarkCodeAsExecutedOnce(), | 1022 call(isolate()->builtins()->MarkCodeAsExecutedOnce(), |
1026 RelocInfo::CODE_AGE_SEQUENCE); | 1023 RelocInfo::CODE_AGE_SEQUENCE); |
1027 Nop(kNoCodeAgeSequenceLength - Assembler::kCallInstructionLength); | 1024 Nop(kNoCodeAgeSequenceLength - Assembler::kCallInstructionLength); |
1028 } else { | 1025 } else { |
1029 push(ebp); // Caller's frame pointer. | 1026 push(ebp); // Caller's frame pointer. |
(...skipping 14 matching lines...) Expand all Loading... |
1044 void MacroAssembler::EnterFrame(StackFrame::Type type, | 1041 void MacroAssembler::EnterFrame(StackFrame::Type type, |
1045 bool load_constant_pool_pointer_reg) { | 1042 bool load_constant_pool_pointer_reg) { |
1046 // Out-of-line constant pool not implemented on ia32. | 1043 // Out-of-line constant pool not implemented on ia32. |
1047 UNREACHABLE(); | 1044 UNREACHABLE(); |
1048 } | 1045 } |
1049 | 1046 |
1050 | 1047 |
1051 void MacroAssembler::EnterFrame(StackFrame::Type type) { | 1048 void MacroAssembler::EnterFrame(StackFrame::Type type) { |
1052 push(ebp); | 1049 push(ebp); |
1053 mov(ebp, esp); | 1050 mov(ebp, esp); |
1054 push(esi); | |
1055 push(Immediate(Smi::FromInt(type))); | 1051 push(Immediate(Smi::FromInt(type))); |
1056 push(Immediate(CodeObject())); | 1052 if (type == StackFrame::INTERNAL) { |
| 1053 push(Immediate(CodeObject())); |
| 1054 } |
1057 if (emit_debug_code()) { | 1055 if (emit_debug_code()) { |
1058 cmp(Operand(esp, 0), Immediate(isolate()->factory()->undefined_value())); | 1056 cmp(Operand(esp, 0), Immediate(isolate()->factory()->undefined_value())); |
1059 Check(not_equal, kCodeObjectNotProperlyPatched); | 1057 Check(not_equal, kCodeObjectNotProperlyPatched); |
1060 } | 1058 } |
1061 } | 1059 } |
1062 | 1060 |
1063 | 1061 |
1064 void MacroAssembler::LeaveFrame(StackFrame::Type type) { | 1062 void MacroAssembler::LeaveFrame(StackFrame::Type type) { |
1065 if (emit_debug_code()) { | 1063 if (emit_debug_code()) { |
1066 cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset), | 1064 cmp(Operand(ebp, CommonFrameConstants::kContextOrFrameTypeOffset), |
1067 Immediate(Smi::FromInt(type))); | 1065 Immediate(Smi::FromInt(type))); |
1068 Check(equal, kStackFrameTypesMustMatch); | 1066 Check(equal, kStackFrameTypesMustMatch); |
1069 } | 1067 } |
1070 leave(); | 1068 leave(); |
1071 } | 1069 } |
1072 | 1070 |
1073 | 1071 |
1074 void MacroAssembler::EnterExitFramePrologue() { | 1072 void MacroAssembler::EnterExitFramePrologue() { |
1075 // Set up the frame structure on the stack. | 1073 // Set up the frame structure on the stack. |
1076 DCHECK(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize); | 1074 DCHECK_EQ(+2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); |
1077 DCHECK(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize); | 1075 DCHECK_EQ(+1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); |
1078 DCHECK(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); | 1076 DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); |
1079 push(ebp); | 1077 push(ebp); |
1080 mov(ebp, esp); | 1078 mov(ebp, esp); |
1081 | 1079 |
1082 // Reserve room for entry stack pointer and push the code object. | 1080 // Reserve room for entry stack pointer and push the code object. |
1083 DCHECK(ExitFrameConstants::kSPOffset == -1 * kPointerSize); | 1081 push(Immediate(Smi::FromInt(StackFrame::EXIT))); |
| 1082 DCHECK_EQ(-2 * kPointerSize, ExitFrameConstants::kSPOffset); |
1084 push(Immediate(0)); // Saved entry sp, patched before call. | 1083 push(Immediate(0)); // Saved entry sp, patched before call. |
| 1084 DCHECK_EQ(-3 * kPointerSize, ExitFrameConstants::kCodeOffset); |
1085 push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. | 1085 push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. |
1086 | 1086 |
1087 // Save the frame pointer and the context in top. | 1087 // Save the frame pointer and the context in top. |
1088 ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate()); | 1088 ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate()); |
1089 ExternalReference context_address(Isolate::kContextAddress, isolate()); | 1089 ExternalReference context_address(Isolate::kContextAddress, isolate()); |
1090 ExternalReference c_function_address(Isolate::kCFunctionAddress, isolate()); | 1090 ExternalReference c_function_address(Isolate::kCFunctionAddress, isolate()); |
1091 mov(Operand::StaticVariable(c_entry_fp_address), ebp); | 1091 mov(Operand::StaticVariable(c_entry_fp_address), ebp); |
1092 mov(Operand::StaticVariable(context_address), esi); | 1092 mov(Operand::StaticVariable(context_address), esi); |
1093 mov(Operand::StaticVariable(c_function_address), ebx); | 1093 mov(Operand::StaticVariable(c_function_address), ebx); |
1094 } | 1094 } |
1095 | 1095 |
1096 | 1096 |
1097 void MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) { | 1097 void MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) { |
1098 // Optionally save all XMM registers. | 1098 // Optionally save all XMM registers. |
1099 if (save_doubles) { | 1099 if (save_doubles) { |
1100 int space = XMMRegister::kMaxNumRegisters * kDoubleSize + | 1100 int space = XMMRegister::kMaxNumRegisters * kDoubleSize + |
1101 argc * kPointerSize; | 1101 argc * kPointerSize; |
1102 sub(esp, Immediate(space)); | 1102 sub(esp, Immediate(space)); |
1103 const int offset = -2 * kPointerSize; | 1103 const int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; |
1104 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { | 1104 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { |
1105 XMMRegister reg = XMMRegister::from_code(i); | 1105 XMMRegister reg = XMMRegister::from_code(i); |
1106 movsd(Operand(ebp, offset - ((i + 1) * kDoubleSize)), reg); | 1106 movsd(Operand(ebp, offset - ((i + 1) * kDoubleSize)), reg); |
1107 } | 1107 } |
1108 } else { | 1108 } else { |
1109 sub(esp, Immediate(argc * kPointerSize)); | 1109 sub(esp, Immediate(argc * kPointerSize)); |
1110 } | 1110 } |
1111 | 1111 |
1112 // Get the required frame alignment for the OS. | 1112 // Get the required frame alignment for the OS. |
1113 const int kFrameAlignment = base::OS::ActivationFrameAlignment(); | 1113 const int kFrameAlignment = base::OS::ActivationFrameAlignment(); |
(...skipping 22 matching lines...) Expand all Loading... |
1136 | 1136 |
1137 void MacroAssembler::EnterApiExitFrame(int argc) { | 1137 void MacroAssembler::EnterApiExitFrame(int argc) { |
1138 EnterExitFramePrologue(); | 1138 EnterExitFramePrologue(); |
1139 EnterExitFrameEpilogue(argc, false); | 1139 EnterExitFrameEpilogue(argc, false); |
1140 } | 1140 } |
1141 | 1141 |
1142 | 1142 |
1143 void MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { | 1143 void MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { |
1144 // Optionally restore all XMM registers. | 1144 // Optionally restore all XMM registers. |
1145 if (save_doubles) { | 1145 if (save_doubles) { |
1146 const int offset = -2 * kPointerSize; | 1146 const int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; |
1147 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { | 1147 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { |
1148 XMMRegister reg = XMMRegister::from_code(i); | 1148 XMMRegister reg = XMMRegister::from_code(i); |
1149 movsd(reg, Operand(ebp, offset - ((i + 1) * kDoubleSize))); | 1149 movsd(reg, Operand(ebp, offset - ((i + 1) * kDoubleSize))); |
1150 } | 1150 } |
1151 } | 1151 } |
1152 | 1152 |
1153 if (pop_arguments) { | 1153 if (pop_arguments) { |
1154 // Get the return address from the stack and restore the frame pointer. | 1154 // Get the return address from the stack and restore the frame pointer. |
1155 mov(ecx, Operand(ebp, 1 * kPointerSize)); | 1155 mov(ecx, Operand(ebp, 1 * kPointerSize)); |
1156 mov(ebp, Operand(ebp, 0 * kPointerSize)); | 1156 mov(ebp, Operand(ebp, 0 * kPointerSize)); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1219 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, | 1219 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |
1220 Register scratch1, | 1220 Register scratch1, |
1221 Register scratch2, | 1221 Register scratch2, |
1222 Label* miss) { | 1222 Label* miss) { |
1223 Label same_contexts; | 1223 Label same_contexts; |
1224 | 1224 |
1225 DCHECK(!holder_reg.is(scratch1)); | 1225 DCHECK(!holder_reg.is(scratch1)); |
1226 DCHECK(!holder_reg.is(scratch2)); | 1226 DCHECK(!holder_reg.is(scratch2)); |
1227 DCHECK(!scratch1.is(scratch2)); | 1227 DCHECK(!scratch1.is(scratch2)); |
1228 | 1228 |
1229 // Load current lexical context from the stack frame. | 1229 // Load current lexical context from the active StandardFrame, which |
1230 mov(scratch1, Operand(ebp, StandardFrameConstants::kContextOffset)); | 1230 // may require crawling past STUB frames. |
| 1231 Label load_context; |
| 1232 Label has_context; |
| 1233 mov(scratch2, ebp); |
| 1234 bind(&load_context); |
| 1235 mov(scratch1, |
| 1236 MemOperand(scratch2, CommonFrameConstants::kContextOrFrameTypeOffset)); |
| 1237 JumpIfNotSmi(scratch1, &has_context); |
| 1238 mov(scratch2, MemOperand(scratch2, CommonFrameConstants::kCallerFPOffset)); |
| 1239 jmp(&load_context); |
| 1240 bind(&has_context); |
1231 | 1241 |
1232 // When generating debug code, make sure the lexical context is set. | 1242 // When generating debug code, make sure the lexical context is set. |
1233 if (emit_debug_code()) { | 1243 if (emit_debug_code()) { |
1234 cmp(scratch1, Immediate(0)); | 1244 cmp(scratch1, Immediate(0)); |
1235 Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext); | 1245 Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext); |
1236 } | 1246 } |
1237 // Load the native context of the current context. | 1247 // Load the native context of the current context. |
1238 mov(scratch1, ContextOperand(scratch1, Context::NATIVE_CONTEXT_INDEX)); | 1248 mov(scratch1, ContextOperand(scratch1, Context::NATIVE_CONTEXT_INDEX)); |
1239 | 1249 |
1240 // Check the context is a native context. | 1250 // Check the context is a native context. |
(...skipping 2080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3321 mov(eax, dividend); | 3331 mov(eax, dividend); |
3322 shr(eax, 31); | 3332 shr(eax, 31); |
3323 add(edx, eax); | 3333 add(edx, eax); |
3324 } | 3334 } |
3325 | 3335 |
3326 | 3336 |
3327 } // namespace internal | 3337 } // namespace internal |
3328 } // namespace v8 | 3338 } // namespace v8 |
3329 | 3339 |
3330 #endif // V8_TARGET_ARCH_IA32 | 3340 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |