mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 03:17:55 +00:00
[reload] Rehash constants before running new initializers.
Use of constants before rehashing can result in duplicate "canonical" constants. Change-Id: I48c008b269267461c30933002c5a5e57005dfef5 Reviewed-on: https://dart-review.googlesource.com/5282 Reviewed-by: Alexander Aprelev <aam@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
8f1ca007f2
commit
2d698cc4d0
|
@ -333,6 +333,7 @@ cc/IsolateReload_RunNewFieldInitializersMutateStaticField: Skip
|
|||
cc/IsolateReload_RunNewFieldInitializersReferenceStaticField: Skip
|
||||
cc/IsolateReload_RunNewFieldInitializersSyntaxError3: Fail
|
||||
cc/IsolateReload_RunNewFieldInitializersThrows: Skip
|
||||
cc/IsolateReload_RunNewFieldInitializersWithConsts: Skip
|
||||
cc/IsolateReload_ShapeChangeRetainsHash: Skip
|
||||
cc/IsolateReload_SmiFastPathStubs: Fail
|
||||
cc/IsolateReload_TearOff_AddArguments2: Fail
|
||||
|
|
|
@ -1288,8 +1288,19 @@ void IsolateReloadContext::Commit() {
|
|||
Become::ElementsForwardIdentity(before, after);
|
||||
}
|
||||
|
||||
// Run the initializers for new instance fields.
|
||||
RunNewFieldInitializers();
|
||||
// Rehash constants map for all classes. Constants are hashed by address, and
|
||||
// addresses may change during a become operation.
|
||||
RehashConstants();
|
||||
|
||||
#ifdef DEBUG
|
||||
// Verify that all canonical instances are correctly setup in the
|
||||
// corresponding canonical tables.
|
||||
Thread* thread = Thread::Current();
|
||||
I->heap()->CollectAllGarbage();
|
||||
HeapIterationScope iteration(thread);
|
||||
VerifyCanonicalVisitor check_canonical(thread);
|
||||
iteration.IterateObjects(&check_canonical);
|
||||
#endif // DEBUG
|
||||
|
||||
if (FLAG_identity_reload) {
|
||||
if (saved_num_cids_ != I->class_table()->NumCids()) {
|
||||
|
@ -1306,18 +1317,8 @@ void IsolateReloadContext::Commit() {
|
|||
}
|
||||
}
|
||||
|
||||
// Rehash constants map for all classes.
|
||||
RehashConstants();
|
||||
|
||||
#ifdef DEBUG
|
||||
// Verify that all canonical instances are correctly setup in the
|
||||
// corresponding canonical tables.
|
||||
Thread* thread = Thread::Current();
|
||||
I->heap()->CollectAllGarbage();
|
||||
HeapIterationScope iteration(thread);
|
||||
VerifyCanonicalVisitor check_canonical(thread);
|
||||
iteration.IterateObjects(&check_canonical);
|
||||
#endif // DEBUG
|
||||
// Run the initializers for new instance fields.
|
||||
RunNewFieldInitializers();
|
||||
}
|
||||
|
||||
void IsolateReloadContext::RehashConstants() {
|
||||
|
|
|
@ -3542,6 +3542,57 @@ TEST_CASE(IsolateReload_RunNewFieldInitialiazersSuperClass) {
|
|||
EXPECT_STREQ("right", SimpleInvokeStr(lib, "main"));
|
||||
}
|
||||
|
||||
TEST_CASE(IsolateReload_RunNewFieldInitializersWithConsts) {
|
||||
const char* kScript =
|
||||
"class C {\n"
|
||||
" final x;\n"
|
||||
" const C(this.x);\n"
|
||||
"}\n"
|
||||
"var a = const C(const C(1));\n"
|
||||
"var b = const C(const C(2));\n"
|
||||
"var c = const C(const C(3));\n"
|
||||
"var d = const C(const C(4));\n"
|
||||
"class Foo {\n"
|
||||
"}\n"
|
||||
"Foo value;\n"
|
||||
"main() {\n"
|
||||
" value = new Foo();\n"
|
||||
" a; b; c; d;\n"
|
||||
" return 'Okay';\n"
|
||||
"}\n";
|
||||
|
||||
Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
|
||||
EXPECT_VALID(lib);
|
||||
EXPECT_STREQ("Okay", SimpleInvokeStr(lib, "main"));
|
||||
|
||||
const char* kReloadScript =
|
||||
"class C {\n"
|
||||
" final x;\n"
|
||||
" const C(this.x);\n"
|
||||
"}\n"
|
||||
"var a = const C(const C(1));\n"
|
||||
"var b = const C(const C(2));\n"
|
||||
"var c = const C(const C(3));\n"
|
||||
"var d = const C(const C(4));\n"
|
||||
"class Foo {\n"
|
||||
" var d = const C(const C(4));\n"
|
||||
" var c = const C(const C(3));\n"
|
||||
" var b = const C(const C(2));\n"
|
||||
" var a = const C(const C(1));\n"
|
||||
"}\n"
|
||||
"Foo value;\n"
|
||||
"main() {\n"
|
||||
" return '${identical(a, value.a)} ${identical(b, value.b)}'"
|
||||
" ' ${identical(c, value.c)} ${identical(d, value.d)}';\n"
|
||||
"}\n";
|
||||
|
||||
lib = TestCase::ReloadTestScript(kReloadScript);
|
||||
EXPECT_VALID(lib);
|
||||
// Verify that we ran field initializers on existing instances and the const
|
||||
// expressions were properly canonicalized.
|
||||
EXPECT_STREQ("true true true true", SimpleInvokeStr(lib, "main"));
|
||||
}
|
||||
|
||||
TEST_CASE(IsolateReload_TypedefToNotTypedef) {
|
||||
const char* kScript =
|
||||
"typedef bool Predicate(dynamic x);\n"
|
||||
|
|
Loading…
Reference in a new issue