[deoptimizer] Do not modify stack_fp which is used as a key for lookup of previously materialized objects.

BUG=chromium:604680, v8:4698
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#35693}
This commit is contained in:
ishell 2016-04-21 02:53:06 -07:00 committed by Commit bot
parent 2cfac65eac
commit b4dbb2f710
2 changed files with 66 additions and 25 deletions

View File

@ -895,11 +895,8 @@ void Deoptimizer::DoComputeJSFrame(TranslatedFrame* translated_frame,
CHECK_NULL(output_[frame_index]);
output_[frame_index] = output_frame;
// The top address for the bottommost output frame can be computed from
// the input frame pointer and the output frame's height. For all
// subsequent output frames, it can be computed from the previous one's
// top address and the current frame's size.
Register fp_reg = JavaScriptFrame::fp_register();
// The top address of the frame is computed from the previous frame's top and
// this frame's size.
intptr_t top_address;
if (is_bottommost) {
top_address = caller_frame_top_ - output_frame_size;
@ -947,7 +944,10 @@ void Deoptimizer::DoComputeJSFrame(TranslatedFrame* translated_frame,
output_frame->SetCallerFp(output_offset, value);
intptr_t fp_value = top_address + output_offset;
output_frame->SetFp(fp_value);
if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value);
if (is_topmost) {
Register fp_reg = JavaScriptFrame::fp_register();
output_frame->SetRegister(fp_reg.code(), fp_value);
}
DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
if (FLAG_enable_embedded_constant_pool) {
@ -1117,11 +1117,8 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
CHECK_NULL(output_[frame_index]);
output_[frame_index] = output_frame;
// The top address for the bottommost output frame can be computed from
// the input frame pointer and the output frame's height. For all
// subsequent output frames, it can be computed from the previous one's
// top address and the current frame's size.
Register fp_reg = InterpretedFrame::fp_register();
// The top address of the frame is computed from the previous frame's top and
// this frame's size.
intptr_t top_address;
if (is_bottommost) {
top_address = caller_frame_top_ - output_frame_size;
@ -1170,7 +1167,10 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
output_frame->SetCallerFp(output_offset, value);
intptr_t fp_value = top_address + output_offset;
output_frame->SetFp(fp_value);
if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value);
if (is_topmost) {
Register fp_reg = InterpretedFrame::fp_register();
output_frame->SetRegister(fp_reg.code(), fp_value);
}
DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
if (FLAG_enable_embedded_constant_pool) {
@ -1334,8 +1334,8 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(
CHECK(output_[frame_index] == NULL);
output_[frame_index] = output_frame;
// The top address of the frame is computed from the previous
// frame's top and this frame's size.
// The top address of the frame is computed from the previous frame's top and
// this frame's size.
intptr_t top_address;
if (is_bottommost) {
top_address = caller_frame_top_ - output_frame_size;
@ -1485,7 +1485,6 @@ void Deoptimizer::DoComputeTailCallerFrame(TranslatedFrame* translated_frame,
offset, stack_fp_, new_stack_fp, caller_frame_top_,
new_caller_frame_top);
}
stack_fp_ = new_stack_fp;
caller_frame_top_ = new_caller_frame_top;
caller_fp_ = adaptor_caller_fp;
caller_pc_ = adaptor_caller_pc;
@ -1521,8 +1520,8 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame,
DCHECK(output_[frame_index] == NULL);
output_[frame_index] = output_frame;
// The top address of the frame is computed from the previous
// frame's top and this frame's size.
// The top address of the frame is computed from the previous frame's top and
// this frame's size.
intptr_t top_address;
top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
output_frame->SetTop(top_address);
@ -1807,13 +1806,9 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslatedFrame* translated_frame,
CHECK_EQ(frame_index, 0);
output_[frame_index] = output_frame;
// The top address for the output frame can be computed from the input
// frame pointer and the output frame's height. Subtract space for the
// context and function slots.
Register fp_reg = StubFailureTrampolineFrame::fp_register();
intptr_t top_address =
stack_fp_ - StubFailureTrampolineFrameConstants::kFixedFrameSizeFromFp -
height_in_bytes;
// The top address of the frame is computed from the previous frame's top and
// this frame's size.
intptr_t top_address = caller_frame_top_ - output_frame_size;
output_frame->SetTop(top_address);
// Set caller's PC (JSFunction continuation).
@ -1827,7 +1822,8 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslatedFrame* translated_frame,
value = caller_fp_;
output_frame_offset -= kFPOnStackSize;
output_frame->SetCallerFp(output_frame_offset, value);
intptr_t frame_ptr = stack_fp_;
intptr_t frame_ptr = top_address + output_frame_offset;
Register fp_reg = StubFailureTrampolineFrame::fp_register();
output_frame->SetRegister(fp_reg.code(), frame_ptr);
output_frame->SetFp(frame_ptr);
DebugPrintOutputSlot(value, frame_index, output_frame_offset,

View File

@ -0,0 +1,45 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --harmony-tailcalls
function h() {
var res = g.arguments;
return res;
}
function g(o) {
var res = h();
return res;
}
function f1() {
var o = { x : 42 };
var res = g(o);
return 1;
}
function f0(a, b) {
"use strict";
return f1(5);
}
function boom(b) {
if (b) throw new Error("boom!");
}
%NeverOptimizeFunction(h);
f0();
f0();
%OptimizeFunctionOnNextCall(f0);
boom(false);
boom(false);
%OptimizeFunctionOnNextCall(boom);
try {
f0(1, 2, 3);
boom(true, 1, 2, 3);
} catch (e) {
}