[vm/reload] Ensure we only morph instantiated classes and enums.

Fixes https://github.com/dart-lang/sdk/issues/51835
TEST=IsolateReload_EnumInMainLibraryModified

Change-Id: I4a8993cb44619a552866430b92f3941d49afbae6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/291051
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
This commit is contained in:
Alexander Aprelev 2023-03-25 01:33:07 +00:00 committed by Commit Queue
parent fd1b48d82e
commit 9daa67967f
3 changed files with 35 additions and 0 deletions

View file

@ -319,6 +319,7 @@ void InstanceMorpher::CreateMorphedCopies(Become* become) {
// We also forward Enum.values. No filler is needed because arrays never
// change shape.
ASSERT(old_values.ptr() != new_values.ptr());
become->Add(old_values, new_values);
#if defined(DEBUG)

View file

@ -5196,6 +5196,35 @@ TEST_CASE(IsolateReload_ImplicitGetterWithLoadGuard) {
EXPECT_STREQ("y: 3, z: 8208", SimpleInvokeStr(lib1, "main"));
}
// Regression test for https://github.com/dart-lang/sdk/issues/51835
TEST_CASE(IsolateReload_EnumInMainLibraryModified) {
const char* kScript =
"enum Bar { bar }\n"
"class Foo { int? a; toString() => 'foo'; }"
"main() {\n"
" return Foo().toString();\n"
"}\n";
Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
EXPECT_VALID(lib);
EXPECT_VALID(Dart_FinalizeAllClasses());
EXPECT_STREQ("foo", SimpleInvokeStr(lib, "main"));
const char* kReloadScript =
"enum Bar { bar }\n"
"class Foo { int? a; String? b; toString() => 'foo'; }"
"main() {\n"
" return Foo().toString();\n"
"}\n";
lib = TestCase::ReloadTestScript(kReloadScript);
EXPECT_VALID(lib);
Dart_SetFileModifiedCallback(NULL);
// Modification of an imported library propagates to the importing library.
EXPECT_STREQ("foo", SimpleInvokeStr(lib, "main"));
}
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
} // namespace dart

View file

@ -610,6 +610,11 @@ void Class::MarkFieldBoxedDuringReload(ClassTable* class_table,
bool Class::RequiresInstanceMorphing(ClassTable* class_table,
const Class& replacement) const {
if (!is_allocate_finalized()) {
// No instances of this class exists on the heap - nothing to morph.
return false;
}
if (replacement.is_enum_class()) {
return true;
}