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_X64 | 5 #if V8_TARGET_ARCH_X64 |
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 4009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4020 void MacroAssembler::DebugBreak() { | 4020 void MacroAssembler::DebugBreak() { |
4021 Set(rax, 0); // No arguments. | 4021 Set(rax, 0); // No arguments. |
4022 LoadAddress(rbx, | 4022 LoadAddress(rbx, |
4023 ExternalReference(Runtime::kHandleDebuggerStatement, isolate())); | 4023 ExternalReference(Runtime::kHandleDebuggerStatement, isolate())); |
4024 CEntryStub ces(isolate(), 1); | 4024 CEntryStub ces(isolate(), 1); |
4025 DCHECK(AllowThisStubCall(&ces)); | 4025 DCHECK(AllowThisStubCall(&ces)); |
4026 Call(ces.GetCode(), RelocInfo::DEBUGGER_STATEMENT); | 4026 Call(ces.GetCode(), RelocInfo::DEBUGGER_STATEMENT); |
4027 } | 4027 } |
4028 | 4028 |
4029 | 4029 |
| 4030 // |
| 4031 // Stack structure for the function g() tail calling f(): |
| 4032 // |
| 4033 // ------- Caller frame: ------- |
| 4034 // | ... |
| 4035 // | g()'s arg M |
| 4036 // | ... |
| 4037 // | g()'s arg 1 |
| 4038 // | g()'s receiver arg |
| 4039 // | g()'s caller pc |
| 4040 // ------- g()'s frame: ------- |
| 4041 // | g()'s caller fp <- fp |
| 4042 // | g()'s context |
| 4043 // | function pointer: g |
| 4044 // | ------------------------- |
| 4045 // | ... |
| 4046 // | ... |
| 4047 // | f()'s arg N |
| 4048 // | ... |
| 4049 // | f()'s arg 1 |
| 4050 // | f()'s receiver arg |
| 4051 // | f()'s caller pc <- sp |
| 4052 // ---------------------- |
| 4053 // |
| 4054 void MacroAssembler::DropCurrentJSFrame(Register args_reg, Register scratch1, |
| 4055 Register scratch2, Register scratch3) { |
| 4056 DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3)); |
| 4057 |
| 4058 Label no_arguments_adaptor, formal_parameter_count_loaded; |
| 4059 // TODO(ishell): check for arguments adaptor frame presence |
| 4060 movp(scratch2, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
| 4061 Cmp(Operand(scratch2, StandardFrameConstants::kContextOffset), |
| 4062 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
| 4063 j(not_equal, &no_arguments_adaptor, Label::kNear); |
| 4064 |
| 4065 // Drop arguments adaptor frame and load arguments count. |
| 4066 movp(rbp, scratch2); |
| 4067 SmiToInteger32(scratch1, |
| 4068 Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 4069 jmp(&formal_parameter_count_loaded, Label::kNear); |
| 4070 |
| 4071 bind(&no_arguments_adaptor); |
| 4072 // Load caller's formal parameter count |
| 4073 movp(scratch1, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
| 4074 movp(scratch1, FieldOperand(scratch1, JSFunction::kSharedFunctionInfoOffset)); |
| 4075 LoadSharedFunctionInfoSpecialField( |
| 4076 scratch1, scratch1, SharedFunctionInfo::kFormalParameterCountOffset); |
| 4077 |
| 4078 bind(&formal_parameter_count_loaded); |
| 4079 |
| 4080 // Calculate the destination address where we will put the return address |
| 4081 // after we drop current frame. |
| 4082 Register new_sp_reg = scratch2; |
| 4083 subp(scratch1, args_reg); |
| 4084 leap(new_sp_reg, Operand(rbp, scratch1, times_pointer_size, |
| 4085 StandardFrameConstants::kCallerPCOffset)); |
| 4086 |
| 4087 if (emit_debug_code()) { |
| 4088 cmpp(rsp, new_sp_reg); |
| 4089 Check(below, kStackAccessBelowStackPointer); |
| 4090 } |
| 4091 |
| 4092 // Copy receiver and return address as well. |
| 4093 Register count_reg = scratch1; |
| 4094 leap(count_reg, Operand(args_reg, 2)); |
| 4095 |
| 4096 // Copy return address from caller's frame to current frame's return address |
| 4097 // to avoid its trashing and let the following loop copy it to the right |
| 4098 // place. |
| 4099 Register tmp_reg = scratch3; |
| 4100 movp(tmp_reg, Operand(rbp, StandardFrameConstants::kCallerPCOffset)); |
| 4101 movp(Operand(rsp, 0), tmp_reg); |
| 4102 |
| 4103 // Restore caller's frame pointer now as it could be overwritten by |
| 4104 // the copying loop. |
| 4105 movp(rbp, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
| 4106 |
| 4107 Operand src(rsp, count_reg, times_pointer_size, 0); |
| 4108 Operand dst(new_sp_reg, count_reg, times_pointer_size, 0); |
| 4109 |
| 4110 // Now copy callee arguments to the caller frame going backwards to avoid |
| 4111 // callee arguments corruption (source and destination areas could overlap). |
| 4112 Label loop, entry; |
| 4113 jmp(&entry, Label::kNear); |
| 4114 bind(&loop); |
| 4115 decp(count_reg); |
| 4116 movp(tmp_reg, src); |
| 4117 movp(dst, tmp_reg); |
| 4118 bind(&entry); |
| 4119 cmpp(count_reg, Immediate(0)); |
| 4120 j(not_equal, &loop, Label::kNear); |
| 4121 |
| 4122 // Leave current frame. |
| 4123 movp(rsp, new_sp_reg); |
| 4124 } |
| 4125 |
| 4126 |
4030 void MacroAssembler::InvokeFunction(Register function, | 4127 void MacroAssembler::InvokeFunction(Register function, |
4031 Register new_target, | 4128 Register new_target, |
4032 const ParameterCount& actual, | 4129 const ParameterCount& actual, |
4033 InvokeFlag flag, | 4130 InvokeFlag flag, |
4034 const CallWrapper& call_wrapper) { | 4131 const CallWrapper& call_wrapper) { |
4035 movp(rbx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); | 4132 movp(rbx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); |
4036 LoadSharedFunctionInfoSpecialField( | 4133 LoadSharedFunctionInfoSpecialField( |
4037 rbx, rbx, SharedFunctionInfo::kFormalParameterCountOffset); | 4134 rbx, rbx, SharedFunctionInfo::kFormalParameterCountOffset); |
4038 | 4135 |
4039 ParameterCount expected(rbx); | 4136 ParameterCount expected(rbx); |
(...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5076 } | 5173 } |
5077 | 5174 |
5078 bind(&done); | 5175 bind(&done); |
5079 } | 5176 } |
5080 | 5177 |
5081 | 5178 |
5082 void MacroAssembler::InitializeFieldsWithFiller(Register current_address, | 5179 void MacroAssembler::InitializeFieldsWithFiller(Register current_address, |
5083 Register end_address, | 5180 Register end_address, |
5084 Register filler) { | 5181 Register filler) { |
5085 Label loop, entry; | 5182 Label loop, entry; |
5086 jmp(&entry); | 5183 jmp(&entry, Label::kNear); |
5087 bind(&loop); | 5184 bind(&loop); |
5088 movp(Operand(current_address, 0), filler); | 5185 movp(Operand(current_address, 0), filler); |
5089 addp(current_address, Immediate(kPointerSize)); | 5186 addp(current_address, Immediate(kPointerSize)); |
5090 bind(&entry); | 5187 bind(&entry); |
5091 cmpp(current_address, end_address); | 5188 cmpp(current_address, end_address); |
5092 j(below, &loop); | 5189 j(below, &loop, Label::kNear); |
5093 } | 5190 } |
5094 | 5191 |
5095 | 5192 |
5096 void MacroAssembler::LoadContext(Register dst, int context_chain_length) { | 5193 void MacroAssembler::LoadContext(Register dst, int context_chain_length) { |
5097 if (context_chain_length > 0) { | 5194 if (context_chain_length > 0) { |
5098 // Move up the chain of contexts to the context containing the slot. | 5195 // Move up the chain of contexts to the context containing the slot. |
5099 movp(dst, Operand(rsi, Context::SlotOffset(Context::PREVIOUS_INDEX))); | 5196 movp(dst, Operand(rsi, Context::SlotOffset(Context::PREVIOUS_INDEX))); |
5100 for (int i = 1; i < context_chain_length; i++) { | 5197 for (int i = 1; i < context_chain_length; i++) { |
5101 movp(dst, Operand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX))); | 5198 movp(dst, Operand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX))); |
5102 } | 5199 } |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5510 movl(rax, dividend); | 5607 movl(rax, dividend); |
5511 shrl(rax, Immediate(31)); | 5608 shrl(rax, Immediate(31)); |
5512 addl(rdx, rax); | 5609 addl(rdx, rax); |
5513 } | 5610 } |
5514 | 5611 |
5515 | 5612 |
5516 } // namespace internal | 5613 } // namespace internal |
5517 } // namespace v8 | 5614 } // namespace v8 |
5518 | 5615 |
5519 #endif // V8_TARGET_ARCH_X64 | 5616 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |