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

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: rebase, ports, deoptimize builtins 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
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 689 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 700
701 void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag, 701 void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag,
702 const CallWrapper& call_wrapper) { 702 const CallWrapper& call_wrapper) {
703 // You can't call a builtin without a valid frame. 703 // You can't call a builtin without a valid frame.
704 DCHECK(flag == JUMP_FUNCTION || has_frame()); 704 DCHECK(flag == JUMP_FUNCTION || has_frame());
705 705
706 // Rely on the assertion to check that the number of provided 706 // Rely on the assertion to check that the number of provided
707 // arguments match the expected number of arguments. Fake a 707 // arguments match the expected number of arguments. Fake a
708 // parameter count to avoid emitting code to do the check. 708 // parameter count to avoid emitting code to do the check.
709 ParameterCount expected(0); 709 ParameterCount expected(0);
710 GetBuiltinEntry(r8, native_context_index); 710 GetBuiltinFunction(rdi, native_context_index);
711 InvokeCode(r8, no_reg, expected, expected, flag, call_wrapper); 711 InvokeFunctionCode(rdi, no_reg, expected, expected, flag, call_wrapper);
712 } 712 }
713 713
714 714
715 void MacroAssembler::GetBuiltinFunction(Register target, 715 void MacroAssembler::GetBuiltinFunction(Register target,
716 int native_context_index) { 716 int native_context_index) {
717 // Load the builtins object into target register. 717 // Load the builtins object into target register.
718 movp(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 718 movp(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
719 movp(target, FieldOperand(target, JSGlobalObject::kNativeContextOffset)); 719 movp(target, FieldOperand(target, JSGlobalObject::kNativeContextOffset));
720 movp(target, ContextOperand(target, native_context_index)); 720 movp(target, ContextOperand(target, native_context_index));
721 } 721 }
722 722
723 723
724 void MacroAssembler::GetBuiltinEntry(Register target,
725 int native_context_index) {
726 DCHECK(!target.is(rdi));
727 // Load the JavaScript builtin function from the builtins object.
728 GetBuiltinFunction(rdi, native_context_index);
729 movp(target, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
730 }
731
732
733 #define REG(Name) \ 724 #define REG(Name) \
734 { Register::kCode_##Name } 725 { Register::kCode_##Name }
735 726
736 static const Register saved_regs[] = { 727 static const Register saved_regs[] = {
737 REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8), 728 REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8),
738 REG(r9), REG(r10), REG(r11) 729 REG(r9), REG(r10), REG(r11)
739 }; 730 };
740 731
741 #undef REG 732 #undef REG
742 733
(...skipping 3257 matching lines...) Expand 10 before | Expand all | Expand 10 after
4000 3991
4001 3992
4002 void MacroAssembler::InvokeFunction(Register function, 3993 void MacroAssembler::InvokeFunction(Register function,
4003 Register new_target, 3994 Register new_target,
4004 const ParameterCount& expected, 3995 const ParameterCount& expected,
4005 const ParameterCount& actual, 3996 const ParameterCount& actual,
4006 InvokeFlag flag, 3997 InvokeFlag flag,
4007 const CallWrapper& call_wrapper) { 3998 const CallWrapper& call_wrapper) {
4008 DCHECK(function.is(rdi)); 3999 DCHECK(function.is(rdi));
4009 movp(rsi, FieldOperand(function, JSFunction::kContextOffset)); 4000 movp(rsi, FieldOperand(function, JSFunction::kContextOffset));
4010 // Advances r8 to the end of the Code object header, to the start of 4001 InvokeFunctionCode(rdi, new_target, expected, actual, flag, call_wrapper);
4011 // the executable code.
4012 movp(r8, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
4013 InvokeCode(r8, new_target, expected, actual, flag, call_wrapper);
4014 } 4002 }
4015 4003
4016 4004
4017 void MacroAssembler::InvokeCode(Register code, 4005 void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
4018 Register new_target, 4006 const ParameterCount& expected,
4019 const ParameterCount& expected, 4007 const ParameterCount& actual,
4020 const ParameterCount& actual, 4008 InvokeFlag flag,
4021 InvokeFlag flag, 4009 const CallWrapper& call_wrapper) {
4022 const CallWrapper& call_wrapper) {
4023 // You can't call a function without a valid frame. 4010 // You can't call a function without a valid frame.
4024 DCHECK(flag == JUMP_FUNCTION || has_frame()); 4011 DCHECK(flag == JUMP_FUNCTION || has_frame());
4012 DCHECK(function.is(rdi));
4013 DCHECK_IMPLIES(new_target.is_valid(), new_target.is(rdx));
4025 4014
4026 // Ensure new target is passed in the correct register. Otherwise clear the 4015 if (call_wrapper.NeedsDebugStepCheck()) {
4027 // appropriate register in case new target is not given. 4016 FloodFunctionIfStepping(function, new_target, expected, actual);
4028 DCHECK_IMPLIES(new_target.is_valid(), new_target.is(rdx)); 4017 }
4018
4019 // Clear the new.target register if not given.
4029 if (!new_target.is_valid()) { 4020 if (!new_target.is_valid()) {
4030 LoadRoot(rdx, Heap::kUndefinedValueRootIndex); 4021 LoadRoot(rdx, Heap::kUndefinedValueRootIndex);
4031 } 4022 }
4032 4023
4033 Label done; 4024 Label done;
4034 bool definitely_mismatches = false; 4025 bool definitely_mismatches = false;
4035 InvokePrologue(expected, 4026 InvokePrologue(expected,
4036 actual, 4027 actual,
4037 &done, 4028 &done,
4038 &definitely_mismatches, 4029 &definitely_mismatches,
4039 flag, 4030 flag,
4040 Label::kNear, 4031 Label::kNear,
4041 call_wrapper); 4032 call_wrapper);
4042 if (!definitely_mismatches) { 4033 if (!definitely_mismatches) {
4034 // We call indirectly through the code field in the function to
4035 // allow recompilation to take effect without changing any of the
4036 // call sites.
4037 Operand code = FieldOperand(function, JSFunction::kCodeEntryOffset);
4043 if (flag == CALL_FUNCTION) { 4038 if (flag == CALL_FUNCTION) {
4044 call_wrapper.BeforeCall(CallSize(code)); 4039 call_wrapper.BeforeCall(CallSize(code));
4045 call(code); 4040 call(code);
4046 call_wrapper.AfterCall(); 4041 call_wrapper.AfterCall();
4047 } else { 4042 } else {
4048 DCHECK(flag == JUMP_FUNCTION); 4043 DCHECK(flag == JUMP_FUNCTION);
4049 jmp(code); 4044 jmp(code);
4050 } 4045 }
4051 bind(&done); 4046 bind(&done);
4052 } 4047 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
4112 jmp(done, near_jump); 4107 jmp(done, near_jump);
4113 } 4108 }
4114 } else { 4109 } else {
4115 Jump(adaptor, RelocInfo::CODE_TARGET); 4110 Jump(adaptor, RelocInfo::CODE_TARGET);
4116 } 4111 }
4117 bind(&invoke); 4112 bind(&invoke);
4118 } 4113 }
4119 } 4114 }
4120 4115
4121 4116
4117 void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target,
4118 const ParameterCount& expected,
4119 const ParameterCount& actual) {
4120 Label skip_flooding;
4121 ExternalReference debug_step_action =
4122 ExternalReference::debug_last_step_action_address(isolate());
4123 Operand debug_step_action_operand = ExternalOperand(debug_step_action);
4124 cmpb(debug_step_action_operand, Immediate(StepIn));
4125 j(not_equal, &skip_flooding);
4126 {
4127 FrameScope frame(this,
4128 has_frame() ? StackFrame::NONE : StackFrame::INTERNAL);
4129 if (expected.is_reg()) {
4130 Integer32ToSmi(expected.reg(), expected.reg());
4131 Push(expected.reg());
4132 }
4133 if (actual.is_reg()) {
4134 Integer32ToSmi(actual.reg(), actual.reg());
4135 Push(actual.reg());
4136 }
4137 if (new_target.is_valid()) {
4138 Push(new_target);
4139 }
4140 Push(fun);
4141 Push(fun);
4142 CallRuntime(Runtime::kDebugPrepareStepInIfStepping, 1);
4143 Pop(fun);
4144 if (new_target.is_valid()) {
4145 Pop(new_target);
4146 }
4147 if (actual.is_reg()) {
4148 Pop(actual.reg());
4149 SmiToInteger64(actual.reg(), actual.reg());
4150 }
4151 if (expected.is_reg()) {
4152 Pop(expected.reg());
4153 SmiToInteger64(expected.reg(), expected.reg());
4154 }
4155 }
4156 bind(&skip_flooding);
4157 }
4158
4159
4122 void MacroAssembler::StubPrologue() { 4160 void MacroAssembler::StubPrologue() {
4123 pushq(rbp); // Caller's frame pointer. 4161 pushq(rbp); // Caller's frame pointer.
4124 movp(rbp, rsp); 4162 movp(rbp, rsp);
4125 Push(rsi); // Callee's context. 4163 Push(rsi); // Callee's context.
4126 Push(Smi::FromInt(StackFrame::STUB)); 4164 Push(Smi::FromInt(StackFrame::STUB));
4127 } 4165 }
4128 4166
4129 4167
4130 void MacroAssembler::Prologue(bool code_pre_aging) { 4168 void MacroAssembler::Prologue(bool code_pre_aging) {
4131 PredictableCodeSizeScope predictible_code_size_scope(this, 4169 PredictableCodeSizeScope predictible_code_size_scope(this,
(...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after
5512 movl(rax, dividend); 5550 movl(rax, dividend);
5513 shrl(rax, Immediate(31)); 5551 shrl(rax, Immediate(31));
5514 addl(rdx, rax); 5552 addl(rdx, rax);
5515 } 5553 }
5516 5554
5517 5555
5518 } // namespace internal 5556 } // namespace internal
5519 } // namespace v8 5557 } // namespace v8
5520 5558
5521 #endif // V8_TARGET_ARCH_X64 5559 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/js/macros.py ('K') | « 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