@@ -337,7 +337,7 @@ void Precompiler::DoCompileAll() {
337337 DropLibraries ();
338338
339339 BindStaticCalls ();
340- SwitchICCalls ();
340+ DedupUnlinkedCalls ();
341341 Obfuscate ();
342342
343343 ProgramVisitor::Dedup ();
@@ -612,16 +612,15 @@ void Precompiler::AddCalleesOf(const Function& function, intptr_t gop_offset) {
612612void Precompiler::AddCalleesOfHelper (const Object& entry,
613613 String* temp_selector,
614614 Class* temp_cls) {
615- if (entry.IsICData ()) {
616- const auto & call_site = ICData ::Cast (entry);
615+ if (entry.IsUnlinkedCall ()) {
616+ const auto & call_site = UnlinkedCall ::Cast (entry);
617617 // A dynamic call.
618- ASSERT (!call_site.is_static_call ());
619618 *temp_selector = call_site.target_name ();
620619 AddSelector (*temp_selector);
621620 if (temp_selector->raw () == Symbols::Call ().raw ()) {
622621 // Potential closure call.
623622 const Array& arguments_descriptor =
624- Array::Handle (Z, call_site.arguments_descriptor ());
623+ Array::Handle (Z, call_site.args_descriptor ());
625624 AddClosureCall (arguments_descriptor);
626625 }
627626 } else if (entry.IsMegamorphicCache ()) {
@@ -1986,49 +1985,27 @@ void Precompiler::BindStaticCalls() {
19861985 }
19871986}
19881987
1989- void Precompiler::SwitchICCalls () {
1988+ void Precompiler::DedupUnlinkedCalls () {
19901989 ASSERT (!I->compilation_allowed ());
19911990#if !defined(TARGET_ARCH_DBC)
1992- // Now that all functions have been compiled, we can switch to an instance
1993- // call sequence that loads the Code object and entry point directly from
1994- // the ic data array instead indirectly through a Function in the ic data
1995- // array. Iterate all the object pools and rewrite the ic data from
1996- // (cid, target function, count) to (cid, target code, entry point), and
1997- // replace the ICCallThroughFunction stub with ICCallThroughCode.
1998- class ICCallSwitcher {
1991+ class UnlinkedCallDeduper {
19991992 public:
2000- explicit ICCallSwitcher (Zone* zone)
1993+ explicit UnlinkedCallDeduper (Zone* zone)
20011994 : zone_(zone),
20021995 entry_(Object::Handle(zone)),
2003- ic_(ICData::Handle(zone)),
2004- target_name_(String::Handle(zone)),
2005- args_descriptor_(Array::Handle(zone)),
20061996 unlinked_(UnlinkedCall::Handle(zone)),
2007- target_code_(Code::Handle(zone)),
20081997 canonical_unlinked_calls_() {}
20091998
2010- void SwitchPool (const ObjectPool& pool) {
1999+ void DedupPool (const ObjectPool& pool) {
20112000 for (intptr_t i = 0 ; i < pool.Length (); i++) {
20122001 if (pool.TypeAt (i) != ObjectPool::EntryType::kTaggedObject ) {
20132002 continue ;
20142003 }
20152004 entry_ = pool.ObjectAt (i);
2016- if (entry_.IsICData ()) {
2017- // The only IC calls generated by precompilation are for switchable
2018- // calls.
2019- ic_ ^= entry_.raw ();
2020- ic_.ResetSwitchable (zone_);
2021-
2022- unlinked_ = UnlinkedCall::New ();
2023- target_name_ = ic_.target_name ();
2024- unlinked_.set_target_name (target_name_);
2025- args_descriptor_ = ic_.arguments_descriptor ();
2026- unlinked_.set_args_descriptor (args_descriptor_);
2005+ if (entry_.IsUnlinkedCall ()) {
2006+ unlinked_ ^= entry_.raw ();
20272007 unlinked_ = DedupUnlinkedCall (unlinked_);
20282008 pool.SetObjectAt (i, unlinked_);
2029- } else if (entry_.raw () == StubCode::ICCallThroughFunction ().raw ()) {
2030- target_code_ = StubCode::UnlinkedCall ().raw ();
2031- pool.SetObjectAt (i, target_code_);
20322009 }
20332010 }
20342011 }
@@ -2048,18 +2025,14 @@ void Precompiler::SwitchICCalls() {
20482025 private:
20492026 Zone* zone_;
20502027 Object& entry_;
2051- ICData& ic_;
2052- String& target_name_;
2053- Array& args_descriptor_;
20542028 UnlinkedCall& unlinked_;
2055- Code& target_code_;
20562029 UnlinkedCallSet canonical_unlinked_calls_;
20572030 };
20582031
2059- class SwitchICCallsVisitor : public FunctionVisitor {
2032+ class DedupUnlinkedCallsVisitor : public FunctionVisitor {
20602033 public:
2061- SwitchICCallsVisitor (ICCallSwitcher* ic_call_switcher , Zone* zone)
2062- : ic_call_switcher_(*ic_call_switcher ),
2034+ DedupUnlinkedCallsVisitor (UnlinkedCallDeduper* deduper , Zone* zone)
2035+ : deduper_(*deduper ),
20632036 code_ (Code::Handle(zone)),
20642037 pool_(ObjectPool::Handle(zone)) {}
20652038
@@ -2069,22 +2042,22 @@ void Precompiler::SwitchICCalls() {
20692042 }
20702043 code_ = function.CurrentCode ();
20712044 pool_ = code_.object_pool ();
2072- ic_call_switcher_. SwitchPool (pool_);
2045+ deduper_. DedupPool (pool_);
20732046 }
20742047
20752048 private:
2076- ICCallSwitcher& ic_call_switcher_ ;
2049+ UnlinkedCallDeduper& deduper_ ;
20772050 Code& code_;
20782051 ObjectPool& pool_;
20792052 };
20802053
2081- ICCallSwitcher switcher (Z);
2054+ UnlinkedCallDeduper deduper (Z);
20822055 auto & gop = ObjectPool::Handle(I->object_store ()->global_object_pool());
20832056 ASSERT (gop.IsNull() != FLAG_use_bare_instructions);
20842057 if (FLAG_use_bare_instructions) {
2085- switcher. SwitchPool (gop);
2058+ deduper. DedupPool (gop);
20862059 } else {
2087- SwitchICCallsVisitor visitor (&switcher , Z);
2060+ DedupUnlinkedCallsVisitor visitor (&deduper , Z);
20882061
20892062 // We need both iterations to ensure we visit all the functions that might
20902063 // end up in the snapshot. The ProgramVisitor will miss closures from
0 commit comments