Skip to content

Commit cb80ea7

Browse files
alexmarkovcommit-bot@chromium.org
authored andcommitted
[vm/bytecode] Avoid using stale bytecode after expression evaluation
Hot reload finds all KernelProgramInfo objects and resets object table in the bytecode component (BytecodeReader::ResetObjectTable). This involves reading of object offsets from kernel binary. In case of expression evaluation, kernel binary is temporary and it is deallocated immediately after expression evaluation is finished. This change prevents patching of object table of bytecode components created for expression evaluation, after expression evaluation is finished. Fixes service/simple_reload_test with bytecode in dartk-asan-linux-release-x64 configuration. Change-Id: I240dfa2a79030ae2924721e67d2ce7476e8da6fe Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/117600 Reviewed-by: Ryan Macnak <[email protected]> Commit-Queue: Alexander Markov <[email protected]>
1 parent 765651b commit cb80ea7

File tree

1 file changed

+32
-15
lines changed

1 file changed

+32
-15
lines changed

runtime/vm/object.cc

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11430,8 +11430,10 @@ static RawObject* EvaluateCompiledExpressionHelper(
1143011430
const String& klass,
1143111431
const Array& arguments,
1143211432
const TypeArguments& type_arguments) {
11433+
Zone* zone = Thread::Current()->zone();
1143311434
#if defined(DART_PRECOMPILED_RUNTIME)
1143411435
const String& error_str = String::Handle(
11436+
zone,
1143511437
String::New("Expression evaluation not available in precompiled mode."));
1143611438
return ApiError::New(error_str);
1143711439
#else
@@ -11440,36 +11442,51 @@ static RawObject* EvaluateCompiledExpressionHelper(
1144011442

1144111443
if (kernel_pgm == NULL) {
1144211444
return ApiError::New(String::Handle(
11443-
String::New("Kernel isolate returned ill-formed kernel.")));
11445+
zone, String::New("Kernel isolate returned ill-formed kernel.")));
1144411446
}
1144511447

1144611448
kernel::KernelLoader loader(kernel_pgm.get(),
1144711449
/*uri_to_source_table=*/nullptr);
11448-
const Object& result = Object::Handle(
11449-
loader.LoadExpressionEvaluationFunction(library_url, klass));
11450+
auto& result = Object::Handle(
11451+
zone, loader.LoadExpressionEvaluationFunction(library_url, klass));
1145011452
kernel_pgm.reset();
1145111453

1145211454
if (result.IsError()) return result.raw();
1145311455

11454-
const Function& callee = Function::Cast(result);
11456+
const auto& callee = Function::CheckedHandle(zone, result.raw());
1145511457

1145611458
// type_arguments is null if all type arguments are dynamic.
1145711459
if (type_definitions.Length() == 0 || type_arguments.IsNull()) {
11458-
return DartEntry::InvokeFunction(callee, arguments);
11460+
result = DartEntry::InvokeFunction(callee, arguments);
11461+
} else {
11462+
intptr_t num_type_args = type_arguments.Length();
11463+
Array& real_arguments =
11464+
Array::Handle(zone, Array::New(arguments.Length() + 1));
11465+
real_arguments.SetAt(0, type_arguments);
11466+
Object& arg = Object::Handle(zone);
11467+
for (intptr_t i = 0; i < arguments.Length(); ++i) {
11468+
arg = arguments.At(i);
11469+
real_arguments.SetAt(i + 1, arg);
11470+
}
11471+
11472+
const Array& args_desc = Array::Handle(
11473+
zone, ArgumentsDescriptor::New(num_type_args, arguments.Length()));
11474+
result = DartEntry::InvokeFunction(callee, real_arguments, args_desc);
1145911475
}
1146011476

11461-
intptr_t num_type_args = type_arguments.Length();
11462-
Array& real_arguments = Array::Handle(Array::New(arguments.Length() + 1));
11463-
real_arguments.SetAt(0, type_arguments);
11464-
Object& arg = Object::Handle();
11465-
for (intptr_t i = 0; i < arguments.Length(); ++i) {
11466-
arg = arguments.At(i);
11467-
real_arguments.SetAt(i + 1, arg);
11477+
if (callee.is_declared_in_bytecode()) {
11478+
// Expression evaluation binary expires immediately after evaluation is
11479+
// finished. However, hot reload may still find corresponding
11480+
// KernelProgramInfo object in the heap and it would try to patch it.
11481+
// To prevent accessing stale kernel binary in ResetObjectTable, bytecode
11482+
// component of the callee's KernelProgramInfo is reset here.
11483+
const auto& script = Script::Handle(zone, callee.script());
11484+
const auto& info =
11485+
KernelProgramInfo::Handle(zone, script.kernel_program_info());
11486+
info.set_bytecode_component(Object::null_array());
1146811487
}
1146911488

11470-
const Array& args_desc = Array::Handle(
11471-
ArgumentsDescriptor::New(num_type_args, arguments.Length()));
11472-
return DartEntry::InvokeFunction(callee, real_arguments, args_desc);
11489+
return result.raw();
1147311490
#endif
1147411491
}
1147511492

0 commit comments

Comments
 (0)