Commit 0b9b48b5 authored by Yang Guo's avatar Yang Guo Committed by Commit Bot

[debug] fix break for builtin constructors with regular construct stub.

Regular construct stubs eventually call InvokeFunction, which does
performs debug hook checking. For builtins such as Object, Array, etc.
this approach does not work since they have specialized construct stubs
that do not check for the debug hook.

R=bmeurer@chromium.org

Bug: v8:178
Change-Id: I3e1f5d2dae1c7a6220b7236bd6ea71d83a65171f
Reviewed-on: https://chromium-review.googlesource.com/931702Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Commit-Queue: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51503}
parent 3856d8d5
......@@ -3468,6 +3468,9 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
if (m.Value()->IsJSFunction()) {
Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value());
// Do not reduce constructors with break points.
if (function->shared()->HasBreakInfo()) return NoChange();
// Don't inline cross native context.
if (function->native_context() != *native_context()) return NoChange();
......
......@@ -1197,15 +1197,16 @@ TEST(BreakPointReturn) {
TEST(BreakPointBuiltin) {
i::FLAG_allow_natives_syntax = true;
i::FLAG_block_concurrent_recompilation = true;
break_point_hit_count = 0;
i::FLAG_experimental_inline_promise_constructor = true;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
SetDebugEventListener(env->GetIsolate(), DebugEventBreakPointHitCount);
v8::Local<v8::Function> builtin =
CompileRun("String.prototype.repeat").As<v8::Function>();
// === Test simple builtin ===
break_point_hit_count = 0;
v8::Local<v8::Function> builtin =
CompileRun("String.prototype.repeat").As<v8::Function>();
CompileRun("'a'.repeat(10)");
CHECK_EQ(0, break_point_hit_count);
......@@ -1219,6 +1220,41 @@ TEST(BreakPointBuiltin) {
CompileRun("'b'.repeat(10)");
CHECK_EQ(1, break_point_hit_count);
// === Test bound function from a builtin ===
break_point_hit_count = 0;
builtin = CompileRun(
"var boundrepeat = String.prototype.repeat.bind('a');"
"String.prototype.repeat")
.As<v8::Function>();
CompileRun("boundrepeat(10)");
CHECK_EQ(0, break_point_hit_count);
// Run with breakpoint.
bp = SetBreakPoint(builtin, 0);
CompileRun("boundrepeat(10)");
CHECK_EQ(1, break_point_hit_count);
// Run without breakpoints.
ClearBreakPoint(bp);
CompileRun("boundrepeat(10)");
CHECK_EQ(1, break_point_hit_count);
// === Test constructor builtin (for ones with normal construct stubs) ===
break_point_hit_count = 0;
builtin = CompileRun("Promise").As<v8::Function>();
CompileRun("new Promise(()=>{})");
CHECK_EQ(0, break_point_hit_count);
// Run with breakpoint.
bp = SetBreakPoint(builtin, 0);
CompileRun("new Promise(()=>{})");
CHECK_EQ(1, break_point_hit_count);
// Run without breakpoints.
ClearBreakPoint(bp);
CompileRun("new Promise(()=>{})");
CHECK_EQ(1, break_point_hit_count);
// === Test inlined builtin ===
break_point_hit_count = 0;
builtin = CompileRun("Math.sin").As<v8::Function>();
......@@ -1245,6 +1281,58 @@ TEST(BreakPointBuiltin) {
CompileRun("test(0.3);");
CHECK_EQ(3, break_point_hit_count);
// === Test inlined bound builtin ===
break_point_hit_count = 0;
builtin = CompileRun("String.prototype.repeat").As<v8::Function>();
CompileRun("function test(x) { return 'a' + boundrepeat(x) }");
CompileRun(
"test(4); test(5);"
"%OptimizeFunctionOnNextCall(test); test(6);");
CHECK_EQ(0, break_point_hit_count);
// Run with breakpoint.
bp = SetBreakPoint(builtin, 0);
CompileRun("'a'.repeat(2);");
CHECK_EQ(1, break_point_hit_count);
CompileRun("test(7);");
CHECK_EQ(2, break_point_hit_count);
// Re-optimize.
CompileRun("%OptimizeFunctionOnNextCall(test);");
CompileRun("test(8);");
CHECK_EQ(3, break_point_hit_count);
// Run without breakpoints.
ClearBreakPoint(bp);
CompileRun("test(9);");
CHECK_EQ(3, break_point_hit_count);
// === Test inlined constructor builtin (regular construct builtin) ===
break_point_hit_count = 0;
builtin = CompileRun("Promise").As<v8::Function>();
CompileRun("function test(x) { return new Promise(()=>x); }");
CompileRun(
"test(4); test(5);"
"%OptimizeFunctionOnNextCall(test); test(6);");
CHECK_EQ(0, break_point_hit_count);
// Run with breakpoint.
bp = SetBreakPoint(builtin, 0);
CompileRun("new Promise();");
CHECK_EQ(1, break_point_hit_count);
CompileRun("test(7);");
CHECK_EQ(2, break_point_hit_count);
// Re-optimize.
CompileRun("%OptimizeFunctionOnNextCall(test);");
CompileRun("test(8);");
CHECK_EQ(3, break_point_hit_count);
// Run without breakpoints.
ClearBreakPoint(bp);
CompileRun("test(9);");
CHECK_EQ(3, break_point_hit_count);
// === Test concurrent optimization ===
break_point_hit_count = 0;
builtin = CompileRun("Math.sin").As<v8::Function>();
......
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