From 74e6376b5c602250083b168723374dac7027cdce Mon Sep 17 00:00:00 2001 From: Ryan Macnak Date: Fri, 14 Oct 2016 10:01:42 -0700 Subject: [PATCH] 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 . --- runtime/vm/code_generator.cc | 8 ++------ runtime/vm/simulator_dbc.cc | 7 ++++--- runtime/vm/stub_code_arm.cc | 8 ++++---- runtime/vm/stub_code_arm64.cc | 7 ++++--- runtime/vm/stub_code_ia32.cc | 5 +++-- runtime/vm/stub_code_mips.cc | 7 ++++--- runtime/vm/stub_code_x64.cc | 7 ++++--- 7 files changed, 25 insertions(+), 24 deletions(-) diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc index a039e0770e9..1d101b9ba52 100644 --- a/runtime/vm/code_generator.cc +++ b/runtime/vm/code_generator.cc @@ -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 diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc index c25b5db9173..6c7112e26c5 100644 --- a/runtime/vm/simulator_dbc.cc +++ b/runtime/vm/simulator_dbc.cc @@ -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(FP[1]); + ASSERT(FP[1]->GetClassId() == kFunctionCid); + RawFunction* function = static_cast(FP[1]); + RawCode* code = function->ptr()->code_; SimulatorHelpers::SetFrameCode(FP, code); pp = code->ptr()->object_pool_->ptr(); - pc = reinterpret_cast(code->ptr()->entry_point_); + pc = reinterpret_cast(function->ptr()->entry_point_); pc_ = reinterpret_cast(pc); // For the profiler. } } diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc index d9ff9560014..b7c23465296 100644 --- a/runtime/vm/stub_code_arm.cc +++ b/runtime/vm/stub_code_arm.cc @@ -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); } diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc index f125fe6b831..1e3c78c7e08 100644 --- a/runtime/vm/stub_code_arm64.cc +++ b/runtime/vm/stub_code_arm64.cc @@ -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); } diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc index 0473a0d5db7..83f6ba06f02 100644 --- a/runtime/vm/stub_code_ia32.cc +++ b/runtime/vm/stub_code_ia32.cc @@ -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(); } diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc index 94e163cda6d..6df06424f3a 100644 --- a/runtime/vm/stub_code_mips.cc +++ b/runtime/vm/stub_code_mips.cc @@ -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); } diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc index 49cb3f3ac9f..7ff72e28047 100644 --- a/runtime/vm/stub_code_x64.cc +++ b/runtime/vm/stub_code_x64.cc @@ -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(); }