Insert proper padding between lazy deoptimization points and safepoints.

On x64 we need 13 bytes for patching the call for lazy deopt. We have to
make sure that patching does not overwrite the code at the safepoint.

BUG=v8:1847
Review URL: http://codereview.chromium.org/8775009

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10126 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 75a81659
...@@ -49,7 +49,9 @@ class SafepointGenerator : public CallWrapper { ...@@ -49,7 +49,9 @@ class SafepointGenerator : public CallWrapper {
deopt_mode_(mode) { } deopt_mode_(mode) { }
virtual ~SafepointGenerator() { } virtual ~SafepointGenerator() { }
virtual void BeforeCall(int call_size) const { } virtual void BeforeCall(int call_size) const {
codegen_->EnsureSpaceForLazyDeopt(Deoptimizer::patch_size() - call_size);
}
virtual void AfterCall() const { virtual void AfterCall() const {
codegen_->RecordSafepoint(pointers_, deopt_mode_); codegen_->RecordSafepoint(pointers_, deopt_mode_);
...@@ -241,7 +243,7 @@ bool LCodeGen::GenerateBody() { ...@@ -241,7 +243,7 @@ bool LCodeGen::GenerateBody() {
instr->CompileToNative(this); instr->CompileToNative(this);
} }
} }
EnsureSpaceForLazyDeopt(); EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
return !is_aborted(); return !is_aborted();
} }
...@@ -439,6 +441,7 @@ void LCodeGen::CallCodeGeneric(Handle<Code> code, ...@@ -439,6 +441,7 @@ void LCodeGen::CallCodeGeneric(Handle<Code> code,
LInstruction* instr, LInstruction* instr,
SafepointMode safepoint_mode, SafepointMode safepoint_mode,
int argc) { int argc) {
EnsureSpaceForLazyDeopt(Deoptimizer::patch_size() - masm()->CallSize(code));
ASSERT(instr != NULL); ASSERT(instr != NULL);
LPointerMap* pointers = instr->pointer_map(); LPointerMap* pointers = instr->pointer_map();
RecordPosition(pointers->position()); RecordPosition(pointers->position());
...@@ -4176,25 +4179,24 @@ void LCodeGen::EmitIsConstructCall(Register temp) { ...@@ -4176,25 +4179,24 @@ void LCodeGen::EmitIsConstructCall(Register temp) {
} }
void LCodeGen::EnsureSpaceForLazyDeopt() { void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
// Ensure that we have enough space after the previous lazy-bailout // Ensure that we have enough space after the previous lazy-bailout
// instruction for patching the code here. // instruction for patching the code here.
int current_pc = masm()->pc_offset(); int current_pc = masm()->pc_offset();
int patch_size = Deoptimizer::patch_size(); if (current_pc < last_lazy_deopt_pc_ + space_needed) {
if (current_pc < last_lazy_deopt_pc_ + patch_size) { int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
int padding_size = last_lazy_deopt_pc_ + patch_size - current_pc;
while (padding_size > 0) { while (padding_size > 0) {
int nop_size = padding_size > 9 ? 9 : padding_size; int nop_size = padding_size > 9 ? 9 : padding_size;
__ nop(nop_size); __ nop(nop_size);
padding_size -= nop_size; padding_size -= nop_size;
} }
} }
last_lazy_deopt_pc_ = masm()->pc_offset();
} }
void LCodeGen::DoLazyBailout(LLazyBailout* instr) { void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
EnsureSpaceForLazyDeopt(); EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
last_lazy_deopt_pc_ = masm()->pc_offset();
ASSERT(instr->HasEnvironment()); ASSERT(instr->HasEnvironment());
LEnvironment* env = instr->environment(); LEnvironment* env = instr->environment();
RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
...@@ -4265,7 +4267,7 @@ void LCodeGen::DoStackCheck(LStackCheck* instr) { ...@@ -4265,7 +4267,7 @@ void LCodeGen::DoStackCheck(LStackCheck* instr) {
new DeferredStackCheck(this, instr); new DeferredStackCheck(this, instr);
__ CompareRoot(rsp, Heap::kStackLimitRootIndex); __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
__ j(below, deferred_stack_check->entry()); __ j(below, deferred_stack_check->entry());
EnsureSpaceForLazyDeopt(); EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
__ bind(instr->done_label()); __ bind(instr->done_label());
deferred_stack_check->SetExit(instr->done_label()); deferred_stack_check->SetExit(instr->done_label());
// There is no LLazyBailout instruction for stack-checks. We have to // There is no LLazyBailout instruction for stack-checks. We have to
......
...@@ -305,7 +305,7 @@ class LCodeGen BASE_EMBEDDED { ...@@ -305,7 +305,7 @@ class LCodeGen BASE_EMBEDDED {
Address address; Address address;
}; };
void EnsureSpaceForLazyDeopt(); void EnsureSpaceForLazyDeopt(int space_needed);
LChunk* const chunk_; LChunk* const chunk_;
MacroAssembler* const masm_; MacroAssembler* const masm_;
......
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