Fix deoptimization for out-of-line constant pool.

Ensure that the stack contains the correct constant pool pointer when a
function deopts.

This CL depends on https://codereview.chromium.org/183803022/ landing first.

R=ulan@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19940 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
rmcilroy@chromium.org 2014-03-14 15:11:58 +00:00
parent eb2003da3f
commit f1f6d3095a
11 changed files with 125 additions and 31 deletions

View File

@ -377,6 +377,12 @@ void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) {
}
void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) {
// No out-of-line constant pool support.
UNREACHABLE();
}
#undef __
} } // namespace v8::internal

View File

@ -40,10 +40,18 @@ namespace internal {
Register JavaScriptFrame::fp_register() { return v8::internal::fp; }
Register JavaScriptFrame::context_register() { return cp; }
Register JavaScriptFrame::constant_pool_pointer_register() {
UNREACHABLE();
return no_reg;
}
Register StubFailureTrampolineFrame::fp_register() { return v8::internal::fp; }
Register StubFailureTrampolineFrame::context_register() { return cp; }
Register StubFailureTrampolineFrame::constant_pool_pointer_register() {
UNREACHABLE();
return no_reg;
}
Object*& ExitFrame::constant_pool_slot() const {

View File

@ -1353,8 +1353,14 @@ static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
// then tear down the parameters.
__ ldr(r1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp +
kPointerSize)));
__ mov(sp, fp);
__ ldm(ia_w, sp, fp.bit() | lr.bit());
if (FLAG_enable_ool_constant_pool) {
__ add(sp, fp, Operand(StandardFrameConstants::kConstantPoolOffset));
__ ldm(ia_w, sp, pp.bit() | fp.bit() | lr.bit());
} else {
__ mov(sp, fp);;
__ ldm(ia_w, sp, fp.bit() | lr.bit());
}
__ add(sp, sp, Operand::PointerOffsetFromSmiKey(r1));
__ add(sp, sp, Operand(kPointerSize)); // adjust for receiver
}

View File

@ -373,6 +373,12 @@ void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) {
}
void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) {
ASSERT(FLAG_enable_ool_constant_pool);
SetFrameSlot(offset, value);
}
#undef __
} } // namespace v8::internal

View File

@ -992,24 +992,19 @@ void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
if (FLAG_enable_ool_constant_pool) {
// For the bottommost output frame the constant pool pointer can be gotten
// from the input frame. For subsequent output frames, it can be gotten from
// the function's code.
Register constant_pool_reg =
JavaScriptFrame::constant_pool_pointer_register();
// from the input frame. For subsequent output frames, it can be read from
// the previous frame.
output_offset -= kPointerSize;
input_offset -= kPointerSize;
if (is_bottommost) {
value = input_->GetFrameSlot(input_offset);
} else {
value = reinterpret_cast<intptr_t>(
function->shared()->code()->constant_pool());
value = output_[frame_index - 1]->GetConstantPool();
}
output_frame->SetFrameSlot(output_offset, value);
output_frame->SetConstantPool(value);
if (is_topmost) output_frame->SetRegister(constant_pool_reg.code(), value);
output_frame->SetCallerConstantPool(output_offset, value);
if (trace_scope_) {
PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
V8PRIxPTR "; constant_pool\n",
V8PRIxPTR "; caller's constant_pool\n",
top_address + output_offset, output_offset, value);
}
}
@ -1067,6 +1062,18 @@ void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset);
output_frame->SetPc(pc_value);
// Update constant pool.
if (FLAG_enable_ool_constant_pool) {
intptr_t constant_pool_value =
reinterpret_cast<intptr_t>(non_optimized_code->constant_pool());
output_frame->SetConstantPool(constant_pool_value);
if (is_topmost) {
Register constant_pool_reg =
JavaScriptFrame::constant_pool_pointer_register();
output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
}
}
FullCodeGenerator::State state =
FullCodeGenerator::StateField::decode(pc_and_state);
output_frame->SetState(Smi::FromInt(state));
@ -1150,15 +1157,14 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
}
if (FLAG_enable_ool_constant_pool) {
// A marker value is used in place of the constant pool.
// Read the caller's constant pool from the previous frame.
output_offset -= kPointerSize;
intptr_t constant_pool = reinterpret_cast<intptr_t>(
Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
output_frame->SetFrameSlot(output_offset, constant_pool);
value = output_[frame_index - 1]->GetConstantPool();
output_frame->SetCallerConstantPool(output_offset, value);
if (trace_scope_) {
PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
V8PRIxPTR " ; constant_pool (adaptor sentinel)\n",
top_address + output_offset, output_offset, constant_pool);
V8PRIxPTR "; caller's constant_pool\n",
top_address + output_offset, output_offset, value);
}
}
@ -1205,6 +1211,11 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
adaptor_trampoline->instruction_start() +
isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
output_frame->SetPc(pc_value);
if (FLAG_enable_ool_constant_pool) {
intptr_t constant_pool_value =
reinterpret_cast<intptr_t>(adaptor_trampoline->constant_pool());
output_frame->SetConstantPool(constant_pool_value);
}
}
@ -1280,13 +1291,13 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
}
if (FLAG_enable_ool_constant_pool) {
// The constant pool pointer can be gotten from the previous frame.
// Read the caller's constant pool from the previous frame.
output_offset -= kPointerSize;
value = output_[frame_index - 1]->GetConstantPool();
output_frame->SetFrameSlot(output_offset, value);
output_frame->SetCallerConstantPool(output_offset, value);
if (trace_scope_) {
PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
V8PRIxPTR " ; constant pool\n",
V8PRIxPTR " ; caller's constant pool\n",
top_address + output_offset, output_offset, value);
}
}
@ -1367,6 +1378,11 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
construct_stub->instruction_start() +
isolate_->heap()->construct_stub_deopt_pc_offset()->value());
output_frame->SetPc(pc);
if (FLAG_enable_ool_constant_pool) {
intptr_t constant_pool_value =
reinterpret_cast<intptr_t>(construct_stub->constant_pool());
output_frame->SetConstantPool(constant_pool_value);
}
}
@ -1438,13 +1454,13 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
}
if (FLAG_enable_ool_constant_pool) {
// The constant pool pointer can be gotten from the previous frame.
// Read the caller's constant pool from the previous frame.
output_offset -= kPointerSize;
value = output_[frame_index - 1]->GetConstantPool();
output_frame->SetFrameSlot(output_offset, value);
output_frame->SetCallerConstantPool(output_offset, value);
if (trace_scope_) {
PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
V8PRIxPTR " ; constant pool\n",
V8PRIxPTR " ; caller's constant pool\n",
top_address + output_offset, output_offset, value);
}
}
@ -1506,6 +1522,11 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
intptr_t pc = reinterpret_cast<intptr_t>(
accessor_stub->instruction_start() + offset->value());
output_frame->SetPc(pc);
if (FLAG_enable_ool_constant_pool) {
intptr_t constant_pool_value =
reinterpret_cast<intptr_t>(accessor_stub->constant_pool());
output_frame->SetConstantPool(constant_pool_value);
}
}
@ -1609,17 +1630,14 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
}
if (FLAG_enable_ool_constant_pool) {
// The constant pool pointer can be gotten from the input frame.
Register constant_pool_pointer_register =
StubFailureTrampolineFrame::constant_pool_pointer_register();
// Read the caller's constant pool from the input frame.
input_frame_offset -= kPointerSize;
value = input_->GetFrameSlot(input_frame_offset);
output_frame->SetRegister(constant_pool_pointer_register.code(), value);
output_frame_offset -= kPointerSize;
output_frame->SetFrameSlot(output_frame_offset, value);
output_frame->SetCallerConstantPool(output_frame_offset, value);
if (trace_scope_) {
PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
V8PRIxPTR " ; constant_pool_pointer\n",
V8PRIxPTR " ; caller's constant_pool\n",
top_address + output_frame_offset, output_frame_offset, value);
}
}
@ -1753,6 +1771,14 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
ASSERT(trampoline != NULL);
output_frame->SetPc(reinterpret_cast<intptr_t>(
trampoline->instruction_start()));
if (FLAG_enable_ool_constant_pool) {
Register constant_pool_reg =
StubFailureTrampolineFrame::constant_pool_pointer_register();
intptr_t constant_pool_value =
reinterpret_cast<intptr_t>(trampoline->constant_pool());
output_frame->SetConstantPool(constant_pool_value);
output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
}
output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
Code* notify_failure = NotifyStubFailureBuiltin();
output_frame->SetContinuation(

View File

@ -508,6 +508,8 @@ class FrameDescription {
void SetCallerFp(unsigned offset, intptr_t value);
void SetCallerConstantPool(unsigned offset, intptr_t value);
intptr_t GetRegister(unsigned n) const {
#if DEBUG
// This convoluted ASSERT is needed to work around a gcc problem that

View File

@ -201,6 +201,11 @@ inline Address StandardFrame::ComputePCAddress(Address fp) {
}
inline Address StandardFrame::ComputeConstantPoolAddress(Address fp) {
return fp + StandardFrameConstants::kConstantPoolOffset;
}
inline bool StandardFrame::IsArgumentsAdaptorFrame(Address fp) {
Object* marker =
Memory::Object_at(fp + StandardFrameConstants::kContextOffset);

View File

@ -531,6 +531,10 @@ void ExitFrame::ComputeCallerState(State* state) const {
state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset);
state->pc_address = ResolveReturnAddressLocation(
reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset));
if (FLAG_enable_ool_constant_pool) {
state->constant_pool_address = reinterpret_cast<Address*>(
fp() + ExitFrameConstants::kConstantPoolOffset);
}
}
@ -574,6 +578,8 @@ void ExitFrame::FillState(Address fp, Address sp, State* state) {
state->fp = fp;
state->pc_address = ResolveReturnAddressLocation(
reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize));
state->constant_pool_address =
reinterpret_cast<Address*>(fp + ExitFrameConstants::kConstantPoolOffset);
}
@ -610,6 +616,8 @@ void StandardFrame::ComputeCallerState(State* state) const {
state->fp = caller_fp();
state->pc_address = ResolveReturnAddressLocation(
reinterpret_cast<Address*>(ComputePCAddress(fp())));
state->constant_pool_address =
reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp()));
}

View File

@ -225,10 +225,12 @@ class StackFrame BASE_EMBEDDED {
};
struct State {
State() : sp(NULL), fp(NULL), pc_address(NULL) { }
State() : sp(NULL), fp(NULL), pc_address(NULL),
constant_pool_address(NULL) { }
Address sp;
Address fp;
Address* pc_address;
Address* constant_pool_address;
};
// Copy constructor; it breaks the connection to host iterator
@ -270,6 +272,11 @@ class StackFrame BASE_EMBEDDED {
Address pc() const { return *pc_address(); }
void set_pc(Address pc) { *pc_address() = pc; }
Address constant_pool() const { return *constant_pool_address(); }
void set_constant_pool(ConstantPoolArray* constant_pool) {
*constant_pool_address() = reinterpret_cast<Address>(constant_pool);
}
virtual void SetCallerFp(Address caller_fp) = 0;
// Manually changes value of fp in this object.
@ -277,6 +284,10 @@ class StackFrame BASE_EMBEDDED {
Address* pc_address() const { return state_.pc_address; }
Address* constant_pool_address() const {
return state_.constant_pool_address;
}
// Get the id of this stack frame.
Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
@ -496,6 +507,10 @@ class StandardFrame: public StackFrame {
// by the provided frame pointer.
static inline Address ComputePCAddress(Address fp);
// Computes the address of the constant pool field in the standard
// frame given by the provided frame pointer.
static inline Address ComputeConstantPoolAddress(Address fp);
// Iterate over expression stack including stack handlers, locals,
// and parts of the fixed part including context and code fields.
void IterateExpressions(ObjectVisitor* v) const;

View File

@ -463,6 +463,12 @@ void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) {
}
void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) {
// No out-of-line constant pool support.
UNREACHABLE();
}
#undef __

View File

@ -361,6 +361,12 @@ void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) {
}
void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) {
// No out-of-line constant pool support.
UNREACHABLE();
}
#undef __