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 970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
981 } | 981 } |
982 | 982 |
983 | 983 |
984 void MacroAssembler::AssertNotSmi(Register object) { | 984 void MacroAssembler::AssertNotSmi(Register object) { |
985 if (emit_debug_code()) { | 985 if (emit_debug_code()) { |
986 test(object, Immediate(kSmiTagMask)); | 986 test(object, Immediate(kSmiTagMask)); |
987 Check(not_equal, kOperandIsASmi); | 987 Check(not_equal, kOperandIsASmi); |
988 } | 988 } |
989 } | 989 } |
990 | 990 |
991 | 991 void MacroAssembler::StubPrologue(StackFrame::Type type) { |
992 void MacroAssembler::StubPrologue() { | |
993 push(ebp); // Caller's frame pointer. | 992 push(ebp); // Caller's frame pointer. |
994 mov(ebp, esp); | 993 mov(ebp, esp); |
995 push(esi); // Callee's context. | 994 push(Immediate(Smi::FromInt(type))); |
996 push(Immediate(Smi::FromInt(StackFrame::STUB))); | |
997 } | 995 } |
998 | 996 |
999 | |
1000 void MacroAssembler::Prologue(bool code_pre_aging) { | 997 void MacroAssembler::Prologue(bool code_pre_aging) { |
1001 PredictableCodeSizeScope predictible_code_size_scope(this, | 998 PredictableCodeSizeScope predictible_code_size_scope(this, |
1002 kNoCodeAgeSequenceLength); | 999 kNoCodeAgeSequenceLength); |
1003 if (code_pre_aging) { | 1000 if (code_pre_aging) { |
1004 // Pre-age the code. | 1001 // Pre-age the code. |
1005 call(isolate()->builtins()->MarkCodeAsExecutedOnce(), | 1002 call(isolate()->builtins()->MarkCodeAsExecutedOnce(), |
1006 RelocInfo::CODE_AGE_SEQUENCE); | 1003 RelocInfo::CODE_AGE_SEQUENCE); |
1007 Nop(kNoCodeAgeSequenceLength - Assembler::kCallInstructionLength); | 1004 Nop(kNoCodeAgeSequenceLength - Assembler::kCallInstructionLength); |
1008 } else { | 1005 } else { |
1009 push(ebp); // Caller's frame pointer. | 1006 push(ebp); // Caller's frame pointer. |
(...skipping 14 matching lines...) Expand all Loading... |
1024 void MacroAssembler::EnterFrame(StackFrame::Type type, | 1021 void MacroAssembler::EnterFrame(StackFrame::Type type, |
1025 bool load_constant_pool_pointer_reg) { | 1022 bool load_constant_pool_pointer_reg) { |
1026 // Out-of-line constant pool not implemented on ia32. | 1023 // Out-of-line constant pool not implemented on ia32. |
1027 UNREACHABLE(); | 1024 UNREACHABLE(); |
1028 } | 1025 } |
1029 | 1026 |
1030 | 1027 |
1031 void MacroAssembler::EnterFrame(StackFrame::Type type) { | 1028 void MacroAssembler::EnterFrame(StackFrame::Type type) { |
1032 push(ebp); | 1029 push(ebp); |
1033 mov(ebp, esp); | 1030 mov(ebp, esp); |
1034 push(esi); | |
1035 push(Immediate(Smi::FromInt(type))); | 1031 push(Immediate(Smi::FromInt(type))); |
1036 push(Immediate(CodeObject())); | 1032 if (type == StackFrame::INTERNAL) { |
| 1033 push(Immediate(CodeObject())); |
| 1034 } |
1037 if (emit_debug_code()) { | 1035 if (emit_debug_code()) { |
1038 cmp(Operand(esp, 0), Immediate(isolate()->factory()->undefined_value())); | 1036 cmp(Operand(esp, 0), Immediate(isolate()->factory()->undefined_value())); |
1039 Check(not_equal, kCodeObjectNotProperlyPatched); | 1037 Check(not_equal, kCodeObjectNotProperlyPatched); |
1040 } | 1038 } |
1041 } | 1039 } |
1042 | 1040 |
1043 | 1041 |
1044 void MacroAssembler::LeaveFrame(StackFrame::Type type) { | 1042 void MacroAssembler::LeaveFrame(StackFrame::Type type) { |
1045 if (emit_debug_code()) { | 1043 if (emit_debug_code()) { |
1046 cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset), | 1044 cmp(Operand(ebp, CommonFrameConstants::kContextOrFrameTypeOffset), |
1047 Immediate(Smi::FromInt(type))); | 1045 Immediate(Smi::FromInt(type))); |
1048 Check(equal, kStackFrameTypesMustMatch); | 1046 Check(equal, kStackFrameTypesMustMatch); |
1049 } | 1047 } |
1050 leave(); | 1048 leave(); |
1051 } | 1049 } |
1052 | 1050 |
1053 | 1051 |
1054 void MacroAssembler::EnterExitFramePrologue() { | 1052 void MacroAssembler::EnterExitFramePrologue() { |
1055 // Set up the frame structure on the stack. | 1053 // Set up the frame structure on the stack. |
1056 DCHECK(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize); | 1054 DCHECK_EQ(+2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); |
1057 DCHECK(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize); | 1055 DCHECK_EQ(+1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); |
1058 DCHECK(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); | 1056 DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); |
1059 push(ebp); | 1057 push(ebp); |
1060 mov(ebp, esp); | 1058 mov(ebp, esp); |
1061 | 1059 |
1062 // Reserve room for entry stack pointer and push the code object. | 1060 // Reserve room for entry stack pointer and push the code object. |
1063 DCHECK(ExitFrameConstants::kSPOffset == -1 * kPointerSize); | 1061 push(Immediate(Smi::FromInt(StackFrame::EXIT))); |
| 1062 DCHECK_EQ(-2 * kPointerSize, ExitFrameConstants::kSPOffset); |
1064 push(Immediate(0)); // Saved entry sp, patched before call. | 1063 push(Immediate(0)); // Saved entry sp, patched before call. |
| 1064 DCHECK_EQ(-3 * kPointerSize, ExitFrameConstants::kCodeOffset); |
1065 push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. | 1065 push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. |
1066 | 1066 |
1067 // Save the frame pointer and the context in top. | 1067 // Save the frame pointer and the context in top. |
1068 ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate()); | 1068 ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate()); |
1069 ExternalReference context_address(Isolate::kContextAddress, isolate()); | 1069 ExternalReference context_address(Isolate::kContextAddress, isolate()); |
1070 ExternalReference c_function_address(Isolate::kCFunctionAddress, isolate()); | 1070 ExternalReference c_function_address(Isolate::kCFunctionAddress, isolate()); |
1071 mov(Operand::StaticVariable(c_entry_fp_address), ebp); | 1071 mov(Operand::StaticVariable(c_entry_fp_address), ebp); |
1072 mov(Operand::StaticVariable(context_address), esi); | 1072 mov(Operand::StaticVariable(context_address), esi); |
1073 mov(Operand::StaticVariable(c_function_address), ebx); | 1073 mov(Operand::StaticVariable(c_function_address), ebx); |
1074 } | 1074 } |
1075 | 1075 |
1076 | 1076 |
1077 void MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) { | 1077 void MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) { |
1078 // Optionally save all XMM registers. | 1078 // Optionally save all XMM registers. |
1079 if (save_doubles) { | 1079 if (save_doubles) { |
1080 int space = XMMRegister::kMaxNumRegisters * kDoubleSize + | 1080 int space = XMMRegister::kMaxNumRegisters * kDoubleSize + |
1081 argc * kPointerSize; | 1081 argc * kPointerSize; |
1082 sub(esp, Immediate(space)); | 1082 sub(esp, Immediate(space)); |
1083 const int offset = -2 * kPointerSize; | 1083 const int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; |
1084 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { | 1084 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { |
1085 XMMRegister reg = XMMRegister::from_code(i); | 1085 XMMRegister reg = XMMRegister::from_code(i); |
1086 movsd(Operand(ebp, offset - ((i + 1) * kDoubleSize)), reg); | 1086 movsd(Operand(ebp, offset - ((i + 1) * kDoubleSize)), reg); |
1087 } | 1087 } |
1088 } else { | 1088 } else { |
1089 sub(esp, Immediate(argc * kPointerSize)); | 1089 sub(esp, Immediate(argc * kPointerSize)); |
1090 } | 1090 } |
1091 | 1091 |
1092 // Get the required frame alignment for the OS. | 1092 // Get the required frame alignment for the OS. |
1093 const int kFrameAlignment = base::OS::ActivationFrameAlignment(); | 1093 const int kFrameAlignment = base::OS::ActivationFrameAlignment(); |
(...skipping 22 matching lines...) Expand all Loading... |
1116 | 1116 |
1117 void MacroAssembler::EnterApiExitFrame(int argc) { | 1117 void MacroAssembler::EnterApiExitFrame(int argc) { |
1118 EnterExitFramePrologue(); | 1118 EnterExitFramePrologue(); |
1119 EnterExitFrameEpilogue(argc, false); | 1119 EnterExitFrameEpilogue(argc, false); |
1120 } | 1120 } |
1121 | 1121 |
1122 | 1122 |
1123 void MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { | 1123 void MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { |
1124 // Optionally restore all XMM registers. | 1124 // Optionally restore all XMM registers. |
1125 if (save_doubles) { | 1125 if (save_doubles) { |
1126 const int offset = -2 * kPointerSize; | 1126 const int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; |
1127 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { | 1127 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { |
1128 XMMRegister reg = XMMRegister::from_code(i); | 1128 XMMRegister reg = XMMRegister::from_code(i); |
1129 movsd(reg, Operand(ebp, offset - ((i + 1) * kDoubleSize))); | 1129 movsd(reg, Operand(ebp, offset - ((i + 1) * kDoubleSize))); |
1130 } | 1130 } |
1131 } | 1131 } |
1132 | 1132 |
1133 if (pop_arguments) { | 1133 if (pop_arguments) { |
1134 // Get the return address from the stack and restore the frame pointer. | 1134 // Get the return address from the stack and restore the frame pointer. |
1135 mov(ecx, Operand(ebp, 1 * kPointerSize)); | 1135 mov(ecx, Operand(ebp, 1 * kPointerSize)); |
1136 mov(ebp, Operand(ebp, 0 * kPointerSize)); | 1136 mov(ebp, Operand(ebp, 0 * kPointerSize)); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1199 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, | 1199 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |
1200 Register scratch1, | 1200 Register scratch1, |
1201 Register scratch2, | 1201 Register scratch2, |
1202 Label* miss) { | 1202 Label* miss) { |
1203 Label same_contexts; | 1203 Label same_contexts; |
1204 | 1204 |
1205 DCHECK(!holder_reg.is(scratch1)); | 1205 DCHECK(!holder_reg.is(scratch1)); |
1206 DCHECK(!holder_reg.is(scratch2)); | 1206 DCHECK(!holder_reg.is(scratch2)); |
1207 DCHECK(!scratch1.is(scratch2)); | 1207 DCHECK(!scratch1.is(scratch2)); |
1208 | 1208 |
1209 // Load current lexical context from the stack frame. | 1209 // Load current lexical context from the active StandardFrame, which |
1210 mov(scratch1, Operand(ebp, StandardFrameConstants::kContextOffset)); | 1210 // my require crawling past STUB frames. |
| 1211 Label load_context; |
| 1212 Label has_context; |
| 1213 mov(scratch2, ebp); |
| 1214 bind(&load_context); |
| 1215 mov(scratch1, |
| 1216 MemOperand(scratch2, CommonFrameConstants::kContextOrFrameTypeOffset)); |
| 1217 JumpIfNotSmi(scratch1, &has_context); |
| 1218 mov(scratch2, MemOperand(scratch2, CommonFrameConstants::kCallerFPOffset)); |
| 1219 jmp(&load_context); |
| 1220 bind(&has_context); |
1211 | 1221 |
1212 // When generating debug code, make sure the lexical context is set. | 1222 // When generating debug code, make sure the lexical context is set. |
1213 if (emit_debug_code()) { | 1223 if (emit_debug_code()) { |
1214 cmp(scratch1, Immediate(0)); | 1224 cmp(scratch1, Immediate(0)); |
1215 Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext); | 1225 Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext); |
1216 } | 1226 } |
1217 // Load the native context of the current context. | 1227 // Load the native context of the current context. |
1218 mov(scratch1, ContextOperand(scratch1, Context::NATIVE_CONTEXT_INDEX)); | 1228 mov(scratch1, ContextOperand(scratch1, Context::NATIVE_CONTEXT_INDEX)); |
1219 | 1229 |
1220 // Check the context is a native context. | 1230 // Check the context is a native context. |
(...skipping 2009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3230 mov(eax, dividend); | 3240 mov(eax, dividend); |
3231 shr(eax, 31); | 3241 shr(eax, 31); |
3232 add(edx, eax); | 3242 add(edx, eax); |
3233 } | 3243 } |
3234 | 3244 |
3235 | 3245 |
3236 } // namespace internal | 3246 } // namespace internal |
3237 } // namespace v8 | 3247 } // namespace v8 |
3238 | 3248 |
3239 #endif // V8_TARGET_ARCH_IA32 | 3249 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |