Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/x64/macro-assembler-x64.cc

Issue 1463803002: [debugger] flood function for stepping before calling it. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | test/cctest/test-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 701
702 void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag, 702 void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag,
703 const CallWrapper& call_wrapper) { 703 const CallWrapper& call_wrapper) {
704 // You can't call a builtin without a valid frame. 704 // You can't call a builtin without a valid frame.
705 DCHECK(flag == JUMP_FUNCTION || has_frame()); 705 DCHECK(flag == JUMP_FUNCTION || has_frame());
706 706
707 // Rely on the assertion to check that the number of provided 707 // Rely on the assertion to check that the number of provided
708 // arguments match the expected number of arguments. Fake a 708 // arguments match the expected number of arguments. Fake a
709 // parameter count to avoid emitting code to do the check. 709 // parameter count to avoid emitting code to do the check.
710 ParameterCount expected(0); 710 ParameterCount expected(0);
711 GetBuiltinEntry(r8, native_context_index); 711 GetBuiltinFunction(rdi, native_context_index);
712 InvokeCode(r8, no_reg, expected, expected, flag, call_wrapper); 712 InvokeFunctionCode(rdi, no_reg, expected, expected, flag, call_wrapper);
713 } 713 }
714 714
715 715
716 void MacroAssembler::GetBuiltinFunction(Register target, 716 void MacroAssembler::GetBuiltinFunction(Register target,
717 int native_context_index) { 717 int native_context_index) {
718 // Load the builtins object into target register. 718 // Load the builtins object into target register.
719 movp(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 719 movp(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
720 movp(target, FieldOperand(target, JSGlobalObject::kNativeContextOffset)); 720 movp(target, FieldOperand(target, JSGlobalObject::kNativeContextOffset));
721 movp(target, ContextOperand(target, native_context_index)); 721 movp(target, ContextOperand(target, native_context_index));
722 } 722 }
723 723
724 724
725 void MacroAssembler::GetBuiltinEntry(Register target,
726 int native_context_index) {
727 DCHECK(!target.is(rdi));
728 // Load the JavaScript builtin function from the builtins object.
729 GetBuiltinFunction(rdi, native_context_index);
730 movp(target, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
731 }
732
733
734 #define REG(Name) \ 725 #define REG(Name) \
735 { Register::kCode_##Name } 726 { Register::kCode_##Name }
736 727
737 static const Register saved_regs[] = { 728 static const Register saved_regs[] = {
738 REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8), 729 REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8),
739 REG(r9), REG(r10), REG(r11) 730 REG(r9), REG(r10), REG(r11)
740 }; 731 };
741 732
742 #undef REG 733 #undef REG
743 734
(...skipping 3268 matching lines...) Expand 10 before | Expand all | Expand 10 after
4012 4003
4013 4004
4014 void MacroAssembler::InvokeFunction(Register function, 4005 void MacroAssembler::InvokeFunction(Register function,
4015 Register new_target, 4006 Register new_target,
4016 const ParameterCount& expected, 4007 const ParameterCount& expected,
4017 const ParameterCount& actual, 4008 const ParameterCount& actual,
4018 InvokeFlag flag, 4009 InvokeFlag flag,
4019 const CallWrapper& call_wrapper) { 4010 const CallWrapper& call_wrapper) {
4020 DCHECK(function.is(rdi)); 4011 DCHECK(function.is(rdi));
4021 movp(rsi, FieldOperand(function, JSFunction::kContextOffset)); 4012 movp(rsi, FieldOperand(function, JSFunction::kContextOffset));
4022 // Advances r8 to the end of the Code object header, to the start of 4013 InvokeFunctionCode(rdi, new_target, expected, actual, flag, call_wrapper);
4023 // the executable code.
4024 movp(r8, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
4025 InvokeCode(r8, new_target, expected, actual, flag, call_wrapper);
4026 } 4014 }
4027 4015
4028 4016
4029 void MacroAssembler::InvokeCode(Register code, 4017 void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
4030 Register new_target, 4018 const ParameterCount& expected,
4031 const ParameterCount& expected, 4019 const ParameterCount& actual,
4032 const ParameterCount& actual, 4020 InvokeFlag flag,
4033 InvokeFlag flag, 4021 const CallWrapper& call_wrapper) {
4034 const CallWrapper& call_wrapper) {
4035 // You can't call a function without a valid frame. 4022 // You can't call a function without a valid frame.
4036 DCHECK(flag == JUMP_FUNCTION || has_frame()); 4023 DCHECK(flag == JUMP_FUNCTION || has_frame());
4024 DCHECK(function.is(rdi));
4025 DCHECK_IMPLIES(new_target.is_valid(), new_target.is(rdx));
4037 4026
4038 // Ensure new target is passed in the correct register. Otherwise clear the 4027 if (call_wrapper.NeedsDebugStepCheck()) {
4039 // appropriate register in case new target is not given. 4028 FloodFunctionIfStepping(function, new_target, expected, actual);
4040 DCHECK_IMPLIES(new_target.is_valid(), new_target.is(rdx)); 4029 }
4030
4031 // Clear the new.target register if not given.
4041 if (!new_target.is_valid()) { 4032 if (!new_target.is_valid()) {
4042 LoadRoot(rdx, Heap::kUndefinedValueRootIndex); 4033 LoadRoot(rdx, Heap::kUndefinedValueRootIndex);
4043 } 4034 }
4044 4035
4045 Label done; 4036 Label done;
4046 bool definitely_mismatches = false; 4037 bool definitely_mismatches = false;
4047 InvokePrologue(expected, 4038 InvokePrologue(expected,
4048 actual, 4039 actual,
4049 &done, 4040 &done,
4050 &definitely_mismatches, 4041 &definitely_mismatches,
4051 flag, 4042 flag,
4052 Label::kNear, 4043 Label::kNear,
4053 call_wrapper); 4044 call_wrapper);
4054 if (!definitely_mismatches) { 4045 if (!definitely_mismatches) {
4046 // We call indirectly through the code field in the function to
4047 // allow recompilation to take effect without changing any of the
4048 // call sites.
4049 Operand code = FieldOperand(function, JSFunction::kCodeEntryOffset);
4055 if (flag == CALL_FUNCTION) { 4050 if (flag == CALL_FUNCTION) {
4056 call_wrapper.BeforeCall(CallSize(code)); 4051 call_wrapper.BeforeCall(CallSize(code));
4057 call(code); 4052 call(code);
4058 call_wrapper.AfterCall(); 4053 call_wrapper.AfterCall();
4059 } else { 4054 } else {
4060 DCHECK(flag == JUMP_FUNCTION); 4055 DCHECK(flag == JUMP_FUNCTION);
4061 jmp(code); 4056 jmp(code);
4062 } 4057 }
4063 bind(&done); 4058 bind(&done);
4064 } 4059 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
4124 jmp(done, near_jump); 4119 jmp(done, near_jump);
4125 } 4120 }
4126 } else { 4121 } else {
4127 Jump(adaptor, RelocInfo::CODE_TARGET); 4122 Jump(adaptor, RelocInfo::CODE_TARGET);
4128 } 4123 }
4129 bind(&invoke); 4124 bind(&invoke);
4130 } 4125 }
4131 } 4126 }
4132 4127
4133 4128
4129 void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target,
4130 const ParameterCount& expected,
4131 const ParameterCount& actual) {
4132 Label skip_flooding;
4133 ExternalReference debug_step_action =
4134 ExternalReference::debug_last_step_action_address(isolate());
4135 Operand debug_step_action_operand = ExternalOperand(debug_step_action);
4136 cmpb(debug_step_action_operand, Immediate(StepIn));
4137 j(not_equal, &skip_flooding);
4138 {
4139 FrameScope frame(this,
4140 has_frame() ? StackFrame::NONE : StackFrame::INTERNAL);
4141 if (expected.is_reg()) {
4142 Integer32ToSmi(expected.reg(), expected.reg());
4143 Push(expected.reg());
4144 }
4145 if (actual.is_reg()) {
4146 Integer32ToSmi(actual.reg(), actual.reg());
4147 Push(actual.reg());
4148 }
4149 if (new_target.is_valid()) {
4150 Push(new_target);
4151 }
4152 Push(fun);
4153 Push(fun);
4154 CallRuntime(Runtime::kDebugPrepareStepInIfStepping, 1);
4155 Pop(fun);
4156 if (new_target.is_valid()) {
4157 Pop(new_target);
4158 }
4159 if (actual.is_reg()) {
4160 Pop(actual.reg());
4161 SmiToInteger64(actual.reg(), actual.reg());
4162 }
4163 if (expected.is_reg()) {
4164 Pop(expected.reg());
4165 SmiToInteger64(expected.reg(), expected.reg());
4166 }
4167 }
4168 bind(&skip_flooding);
4169 }
4170
4171
4134 void MacroAssembler::StubPrologue() { 4172 void MacroAssembler::StubPrologue() {
4135 pushq(rbp); // Caller's frame pointer. 4173 pushq(rbp); // Caller's frame pointer.
4136 movp(rbp, rsp); 4174 movp(rbp, rsp);
4137 Push(rsi); // Callee's context. 4175 Push(rsi); // Callee's context.
4138 Push(Smi::FromInt(StackFrame::STUB)); 4176 Push(Smi::FromInt(StackFrame::STUB));
4139 } 4177 }
4140 4178
4141 4179
4142 void MacroAssembler::Prologue(bool code_pre_aging) { 4180 void MacroAssembler::Prologue(bool code_pre_aging) {
4143 PredictableCodeSizeScope predictible_code_size_scope(this, 4181 PredictableCodeSizeScope predictible_code_size_scope(this,
(...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after
5524 movl(rax, dividend); 5562 movl(rax, dividend);
5525 shrl(rax, Immediate(31)); 5563 shrl(rax, Immediate(31));
5526 addl(rdx, rax); 5564 addl(rdx, rax);
5527 } 5565 }
5528 5566
5529 5567
5530 } // namespace internal 5568 } // namespace internal
5531 } // namespace v8 5569 } // namespace v8
5532 5570
5533 #endif // V8_TARGET_ARCH_X64 5571 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | test/cctest/test-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698