Commit cee3c754 authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: [debugger] flood function for stepping before calling it.

Port 81e131ce

R=yangguo@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=

Review URL: https://codereview.chromium.org/1482153005

Cr-Commit-Position: refs/heads/master@{#32432}
parent 493fba88
......@@ -40,7 +40,8 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
ParameterCount actual(0);
ParameterCount expected(expected_arguments);
__ LoadAccessor(r4, holder, accessor_index, ACCESSOR_GETTER);
__ InvokeFunction(r4, expected, actual, CALL_FUNCTION, NullCallWrapper());
__ InvokeFunction(r4, expected, actual, CALL_FUNCTION,
CheckDebugStepCallWrapper());
} else {
// If we generate a global code snippet for deoptimization only, remember
// the place to continue after deoptimization.
......@@ -81,7 +82,8 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
ParameterCount actual(1);
ParameterCount expected(expected_arguments);
__ LoadAccessor(r4, holder, accessor_index, ACCESSOR_SETTER);
__ InvokeFunction(r4, expected, actual, CALL_FUNCTION, NullCallWrapper());
__ InvokeFunction(r4, expected, actual, CALL_FUNCTION,
CheckDebugStepCallWrapper());
} else {
// If we generate a global code snippet for deoptimization only, remember
// the place to continue after deoptimization.
......
......@@ -572,7 +572,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
__ Call(code, RelocInfo::CODE_TARGET);
} else {
ParameterCount actual(r3);
__ InvokeFunction(r4, r6, actual, CALL_FUNCTION, NullCallWrapper());
__ InvokeFunction(r4, r6, actual, CALL_FUNCTION,
CheckDebugStepCallWrapper());
}
// Store offset of return address for deoptimizer.
......@@ -1707,10 +1708,10 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
#if !V8_TARGET_ARCH_PPC64
__ SmiUntag(r5);
#endif
__ LoadP(r7, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
ParameterCount actual(r3);
ParameterCount expected(r5);
__ InvokeCode(r7, no_reg, expected, actual, JUMP_FUNCTION, NullCallWrapper());
__ InvokeFunctionCode(r4, no_reg, expected, actual, JUMP_FUNCTION,
CheckDebugStepCallWrapper());
// The function is a "classConstructor", need to raise an exception.
__ bind(&class_constructor);
......
......@@ -1086,16 +1086,64 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
}
void MacroAssembler::InvokeCode(Register code, Register new_target,
const ParameterCount& expected,
const ParameterCount& actual, InvokeFlag flag,
const CallWrapper& call_wrapper) {
void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target,
const ParameterCount& expected,
const ParameterCount& actual) {
Label skip_flooding;
ExternalReference debug_step_action =
ExternalReference::debug_last_step_action_address(isolate());
mov(r7, Operand(debug_step_action));
lbz(r7, MemOperand(r7));
cmpi(r7, Operand(StepIn));
bne(&skip_flooding);
{
FrameScope frame(this,
has_frame() ? StackFrame::NONE : StackFrame::INTERNAL);
if (expected.is_reg()) {
SmiTag(expected.reg());
Push(expected.reg());
}
if (actual.is_reg()) {
SmiTag(actual.reg());
Push(actual.reg());
}
if (new_target.is_valid()) {
Push(new_target);
}
Push(fun, fun);
CallRuntime(Runtime::kDebugPrepareStepInIfStepping, 1);
Pop(fun);
if (new_target.is_valid()) {
Pop(new_target);
}
if (actual.is_reg()) {
Pop(actual.reg());
SmiUntag(actual.reg());
}
if (expected.is_reg()) {
Pop(expected.reg());
SmiUntag(expected.reg());
}
}
bind(&skip_flooding);
}
void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
const CallWrapper& call_wrapper) {
// You can't call a function without a valid frame.
DCHECK(flag == JUMP_FUNCTION || has_frame());
// Ensure new target is passed in the correct register. Otherwise clear the
// appropriate register in case new target is not given.
DCHECK(function.is(r4));
DCHECK_IMPLIES(new_target.is_valid(), new_target.is(r6));
if (call_wrapper.NeedsDebugStepCheck()) {
FloodFunctionIfStepping(function, new_target, expected, actual);
}
// Clear the new.target register if not given.
if (!new_target.is_valid()) {
LoadRoot(r6, Heap::kUndefinedValueRootIndex);
}
......@@ -1105,6 +1153,11 @@ void MacroAssembler::InvokeCode(Register code, Register new_target,
InvokePrologue(expected, actual, &done, &definitely_mismatches, flag,
call_wrapper);
if (!definitely_mismatches) {
// We call indirectly through the code field in the function to
// allow recompilation to take effect without changing any of the
// call sites.
Register code = ip;
LoadP(code, FieldMemOperand(function, JSFunction::kCodeEntryOffset));
if (flag == CALL_FUNCTION) {
call_wrapper.BeforeCall(CallSize(code));
CallJSEntry(code);
......@@ -1132,20 +1185,19 @@ void MacroAssembler::InvokeFunction(Register fun, Register new_target,
DCHECK(fun.is(r4));
Register expected_reg = r5;
Register code_reg = ip;
Register temp_reg = r7;
LoadP(code_reg, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
LoadP(temp_reg, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
LoadWordArith(expected_reg,
FieldMemOperand(
code_reg, SharedFunctionInfo::kFormalParameterCountOffset));
temp_reg, SharedFunctionInfo::kFormalParameterCountOffset));
#if !defined(V8_TARGET_ARCH_PPC64)
SmiUntag(expected_reg);
#endif
LoadP(code_reg, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
ParameterCount expected(expected_reg);
InvokeCode(code_reg, new_target, expected, actual, flag, call_wrapper);
InvokeFunctionCode(fun, new_target, expected, actual, flag, call_wrapper);
}
......@@ -1163,11 +1215,7 @@ void MacroAssembler::InvokeFunction(Register function,
// Get the function and setup the context.
LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
// We call indirectly through the code field in the function to
// allow recompilation to take effect without changing any of the
// call sites.
LoadP(ip, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
InvokeCode(ip, no_reg, expected, actual, flag, call_wrapper);
InvokeFunctionCode(r4, no_reg, expected, actual, flag, call_wrapper);
}
......
......@@ -551,9 +551,10 @@ class MacroAssembler : public Assembler {
// JavaScript invokes
// Invoke the JavaScript function code by either calling or jumping.
void InvokeCode(Register code, Register new_target,
const ParameterCount& expected, const ParameterCount& actual,
InvokeFlag flag, const CallWrapper& call_wrapper);
void InvokeFunctionCode(Register function, Register new_target,
const ParameterCount& expected,
const ParameterCount& actual, InvokeFlag flag,
const CallWrapper& call_wrapper);
// Invoke the JavaScript function in the given register. Changes the
// current context to the context in the function before invoking.
......@@ -1494,6 +1495,10 @@ class MacroAssembler : public Assembler {
bool* definitely_mismatches, InvokeFlag flag,
const CallWrapper& call_wrapper);
void FloodFunctionIfStepping(Register fun, Register new_target,
const ParameterCount& expected,
const ParameterCount& actual);
void InitializeNewString(Register string, Register length,
Heap::RootListIndex map_index, Register scratch1,
Register scratch2);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment