[vm,dyn_modules] Fix single-target cid range dispatch for dynamically loaded classes
In AOT mode, when call site is transitioned from monomorphic state (with receiver cid1) to polymorphic (with receiver cid2), there is an optimization which checks if all _allocated_ classes in the class id range cid1..cid2 have the same dispatch target. If so, a specialized SingleTargetCall stub is used. The problem is that 'allocated' bit is only set during precompilation, and dynamically loaded classes were not considered as valid receiver classes by this optimization. As a result, the following situation could happen: cid1 < cid3 < cid2, cid1 dispatches to target1 cid2 dispatches to target1 cid3 should dispatch to target2, but it is still in range cid1..cid2 and SingleTargetCall stub would incorrectly dispatch it to target1. The fix is to treat all dynamically loaded classes as allocated when checking for single target optimization. TEST=pkg/dynamic_modules/test/data/single_target_cid_range_dispatch Fixes b/493677699 Change-Id: I42e407385a5d9b0a4a1017f713b47587c3c6a818 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/488920 Commit-Queue: Alexander Markov <alexmarkov@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com> Reviewed-by: Slava Egorov <vegorov@google.com> Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
committed by
Commit Queue
parent
aa3665ed78
commit
efce7c1cb0
@@ -2559,7 +2559,7 @@ static bool IsSingleTarget(IsolateGroup* isolate_group,
|
||||
if (!table->HasValidClassAt(cid)) continue;
|
||||
cls = table->At(cid);
|
||||
if (cls.is_abstract()) continue;
|
||||
if (!cls.is_allocated()) continue;
|
||||
if (!cls.is_allocated() && !cls.is_declared_in_bytecode()) continue;
|
||||
other_target = Resolver::ResolveDynamicAnyArgs(zone, cls, name,
|
||||
/*allow_add=*/false);
|
||||
if (other_target.ptr() != target.ptr()) {
|
||||
|
||||
Reference in New Issue
Block a user