@@ -337,7 +337,7 @@ void Precompiler::DoCompileAll() {
337
337
DropLibraries ();
338
338
339
339
BindStaticCalls ();
340
- SwitchICCalls ();
340
+ DedupUnlinkedCalls ();
341
341
Obfuscate ();
342
342
343
343
ProgramVisitor::Dedup ();
@@ -612,16 +612,15 @@ void Precompiler::AddCalleesOf(const Function& function, intptr_t gop_offset) {
612
612
void Precompiler::AddCalleesOfHelper (const Object& entry,
613
613
String* temp_selector,
614
614
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);
617
617
// A dynamic call.
618
- ASSERT (!call_site.is_static_call ());
619
618
*temp_selector = call_site.target_name ();
620
619
AddSelector (*temp_selector);
621
620
if (temp_selector->raw () == Symbols::Call ().raw ()) {
622
621
// Potential closure call.
623
622
const Array& arguments_descriptor =
624
- Array::Handle (Z, call_site.arguments_descriptor ());
623
+ Array::Handle (Z, call_site.args_descriptor ());
625
624
AddClosureCall (arguments_descriptor);
626
625
}
627
626
} else if (entry.IsMegamorphicCache ()) {
@@ -1986,49 +1985,27 @@ void Precompiler::BindStaticCalls() {
1986
1985
}
1987
1986
}
1988
1987
1989
- void Precompiler::SwitchICCalls () {
1988
+ void Precompiler::DedupUnlinkedCalls () {
1990
1989
ASSERT (!I->compilation_allowed ());
1991
1990
#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 {
1999
1992
public:
2000
- explicit ICCallSwitcher (Zone* zone)
1993
+ explicit UnlinkedCallDeduper (Zone* zone)
2001
1994
: zone_(zone),
2002
1995
entry_(Object::Handle(zone)),
2003
- ic_(ICData::Handle(zone)),
2004
- target_name_(String::Handle(zone)),
2005
- args_descriptor_(Array::Handle(zone)),
2006
1996
unlinked_(UnlinkedCall::Handle(zone)),
2007
- target_code_(Code::Handle(zone)),
2008
1997
canonical_unlinked_calls_() {}
2009
1998
2010
- void SwitchPool (const ObjectPool& pool) {
1999
+ void DedupPool (const ObjectPool& pool) {
2011
2000
for (intptr_t i = 0 ; i < pool.Length (); i++) {
2012
2001
if (pool.TypeAt (i) != ObjectPool::EntryType::kTaggedObject ) {
2013
2002
continue ;
2014
2003
}
2015
2004
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 ();
2027
2007
unlinked_ = DedupUnlinkedCall (unlinked_);
2028
2008
pool.SetObjectAt (i, unlinked_);
2029
- } else if (entry_.raw () == StubCode::ICCallThroughFunction ().raw ()) {
2030
- target_code_ = StubCode::UnlinkedCall ().raw ();
2031
- pool.SetObjectAt (i, target_code_);
2032
2009
}
2033
2010
}
2034
2011
}
@@ -2048,18 +2025,14 @@ void Precompiler::SwitchICCalls() {
2048
2025
private:
2049
2026
Zone* zone_;
2050
2027
Object& entry_;
2051
- ICData& ic_;
2052
- String& target_name_;
2053
- Array& args_descriptor_;
2054
2028
UnlinkedCall& unlinked_;
2055
- Code& target_code_;
2056
2029
UnlinkedCallSet canonical_unlinked_calls_;
2057
2030
};
2058
2031
2059
- class SwitchICCallsVisitor : public FunctionVisitor {
2032
+ class DedupUnlinkedCallsVisitor : public FunctionVisitor {
2060
2033
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 ),
2063
2036
code_ (Code::Handle(zone)),
2064
2037
pool_(ObjectPool::Handle(zone)) {}
2065
2038
@@ -2069,22 +2042,22 @@ void Precompiler::SwitchICCalls() {
2069
2042
}
2070
2043
code_ = function.CurrentCode ();
2071
2044
pool_ = code_.object_pool ();
2072
- ic_call_switcher_. SwitchPool (pool_);
2045
+ deduper_. DedupPool (pool_);
2073
2046
}
2074
2047
2075
2048
private:
2076
- ICCallSwitcher& ic_call_switcher_ ;
2049
+ UnlinkedCallDeduper& deduper_ ;
2077
2050
Code& code_;
2078
2051
ObjectPool& pool_;
2079
2052
};
2080
2053
2081
- ICCallSwitcher switcher (Z);
2054
+ UnlinkedCallDeduper deduper (Z);
2082
2055
auto & gop = ObjectPool::Handle(I->object_store ()->global_object_pool());
2083
2056
ASSERT (gop.IsNull() != FLAG_use_bare_instructions);
2084
2057
if (FLAG_use_bare_instructions) {
2085
- switcher. SwitchPool (gop);
2058
+ deduper. DedupPool (gop);
2086
2059
} else {
2087
- SwitchICCallsVisitor visitor (&switcher , Z);
2060
+ DedupUnlinkedCallsVisitor visitor (&deduper , Z);
2088
2061
2089
2062
// We need both iterations to ensure we visit all the functions that might
2090
2063
// end up in the snapshot. The ProgramVisitor will miss closures from
0 commit comments