Fix unoptimized code calling a disabled code when --verify-on-transition is enabled.

Unoptimized code has a static call to optimized code.
Optimized code prologue goes to the OptimizeInvokedFunction runtime.
Callee schedule for background compilation and current code set the return entries return value.
Verify-on-transition triggers a safepoint, wherein the background compiler disables the old optimized code.
The OptimizedInvokedFunction stub calls through the disabled code.
FixCallersTarget see an unoptimized caller. BOOM

Similar problem without --verify-on-transition, except the safepoint comes from BackgroundCompiler::CompileOptimized.

Fixes #26927.

R=fschneider@google.com

Review URL: https://codereview.chromium.org/2418673002 .
This commit is contained in:
Ryan Macnak 2016-10-14 10:01:42 -07:00
parent 3d00ecdc8f
commit 74e6376b5c
7 changed files with 25 additions and 24 deletions

View file

@ -1864,9 +1864,7 @@ DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) {
ASSERT(isolate->background_compiler() != NULL);
isolate->background_compiler()->CompileOptimized(function);
// Continue in the same code.
const Code& code = Code::Handle(zone, function.CurrentCode());
ASSERT(!code.IsDisabled());
arguments.SetReturn(code);
arguments.SetReturn(function);
return;
}
}
@ -1888,9 +1886,7 @@ DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) {
const Code& optimized_code = Code::Handle(zone, function.CurrentCode());
ASSERT(!optimized_code.IsNull());
}
const Code& code = Code::Handle(zone, function.CurrentCode());
ASSERT(!code.IsDisabled());
arguments.SetReturn(code);
arguments.SetReturn(function);
#else
UNREACHABLE();
#endif // !DART_PRECOMPILED_RUNTIME

View file

@ -1209,11 +1209,12 @@ RawObject* Simulator::Call(const Code& code,
INVOKE_RUNTIME(DRT_OptimizeInvokedFunction, args);
{
// DRT_OptimizeInvokedFunction returns the code object to execute.
ASSERT(FP[1]->GetClassId() == kCodeCid);
RawCode* code = static_cast<RawCode*>(FP[1]);
ASSERT(FP[1]->GetClassId() == kFunctionCid);
RawFunction* function = static_cast<RawFunction*>(FP[1]);
RawCode* code = function->ptr()->code_;
SimulatorHelpers::SetFrameCode(FP, code);
pp = code->ptr()->object_pool_->ptr();
pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_);
pc = reinterpret_cast<uint32_t*>(function->ptr()->entry_point_);
pc_ = reinterpret_cast<uword>(pc); // For the profiler.
}
}

View file

@ -1896,12 +1896,12 @@ void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
__ Push(R8);
__ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
__ Pop(R0); // Discard argument.
__ Pop(R0); // Get Code object
__ Pop(R0); // Get Function object
__ Pop(R4); // Restore argument descriptor.
__ LeaveStubFrame();
__ mov(CODE_REG, Operand(R0));
__ ldr(R0, FieldAddress(R0, Code::entry_point_offset()));
__ bx(R0);
__ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
__ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
__ bx(R1);
__ bkpt(0);
}

View file

@ -1949,11 +1949,12 @@ void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
__ Push(R6);
__ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
__ Pop(R0); // Discard argument.
__ Pop(CODE_REG); // Get Code object
__ Pop(R0); // Get Function object
__ Pop(R4); // Restore argument descriptor.
__ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset());
__ LoadFieldFromOffset(CODE_REG, R0, Function::code_offset());
__ LoadFieldFromOffset(R1, R0, Function::entry_point_offset());
__ LeaveStubFrame();
__ br(R0);
__ br(R1);
__ brk(0);
}

View file

@ -1840,10 +1840,11 @@ void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
__ pushl(EBX);
__ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
__ popl(EAX); // Discard argument.
__ popl(EAX); // Get Code object
__ popl(EAX); // Get Function object
__ popl(EDX); // Restore argument descriptor.
__ movl(EAX, FieldAddress(EAX, Code::entry_point_offset()));
__ LeaveFrame();
__ movl(CODE_REG, FieldAddress(EAX, Function::code_offset()));
__ movl(EAX, FieldAddress(EAX, Function::entry_point_offset()));
__ jmp(EAX);
__ int3();
}

View file

@ -2023,12 +2023,13 @@ void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
__ sw(T0, Address(SP, 0 * kWordSize));
__ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
__ Comment("OptimizeFunctionStub return");
__ lw(CODE_REG, Address(SP, 1 * kWordSize)); // Get Code object
__ lw(T0, Address(SP, 1 * kWordSize)); // Get Function object
__ lw(S4, Address(SP, 2 * kWordSize)); // Restore argument descriptor.
__ addiu(SP, SP, Immediate(3 * kWordSize)); // Discard argument.
__ lw(T0, FieldAddress(CODE_REG, Code::entry_point_offset()));
__ LeaveStubFrameAndReturn(T0);
__ lw(CODE_REG, FieldAddress(T0, Function::code_offset()));
__ lw(T1, FieldAddress(T0, Function::entry_point_offset()));
__ LeaveStubFrameAndReturn(T1);
__ break_(0);
}

View file

@ -1914,11 +1914,12 @@ void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
__ pushq(RDI); // Arg0: function to optimize
__ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
__ popq(RAX); // Disard argument.
__ popq(CODE_REG); // Get Code object.
__ popq(RAX); // Get Code object.
__ popq(R10); // Restore argument descriptor.
__ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset()));
__ LeaveStubFrame();
__ jmp(RAX);
__ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
__ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
__ jmp(RCX);
__ int3();
}