[vm, bytecode] Fix memory leak in calls from compiled code to interpreted code.
Change-Id: If82d371fc49892508dd33cd837e6b06b40325a48
Reviewed-on: https://dart-review.googlesource.com/c/87264
Reviewed-by: RĂ©gis Crelier <regis@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 81a7ce9..8c5e663 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -2650,16 +2650,21 @@
ASSERT(Function::HasBytecode(function));
ASSERT(interpreter != NULL);
#endif
- const Object& result = Object::Handle(
- thread->zone(), interpreter->Call(function, argdesc, argc, argv, thread));
+ RawObject* result = interpreter->Call(function, argdesc, argc, argv, thread);
DEBUG_ASSERT(thread->top_exit_frame_info() == exit_fp);
- if (result.IsError()) {
+ if (RawObject::IsErrorClassId(result->GetClassIdMayBeSmi())) {
+ // Must not allocate handles in the caller's zone.
+ StackZone stack_zone(thread);
+ // Protect the result in a handle before transitioning, which may trigger
+ // GC.
+ const Error& error =
+ Error::Handle(stack_zone.GetZone(), static_cast<RawError*>(result));
// Propagating an error may cause allocation. Check if we need to block for
// a safepoint by switching to "in VM" execution state.
TransitionGeneratedToVM transition(thread);
- Exceptions::PropagateError(Error::Cast(result));
+ Exceptions::PropagateError(error);
}
- return result.raw();
+ return result;
#endif // defined(DART_PRECOMPILED_RUNTIME)
}