Index: runtime/vm/precompiler.cc |
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc |
index 1d111ddc7486877dc08c0d04320fec32d86d4532..06045411f1660b21bbd9da1adb7684c25add0d5a 100644 |
--- a/runtime/vm/precompiler.cc |
+++ b/runtime/vm/precompiler.cc |
@@ -213,6 +213,7 @@ void Precompiler::DoCompileAll( |
DropLibraries(); |
BindStaticCalls(); |
+ SwitchICCalls(); |
DedupStackmaps(); |
DedupStackmapLists(); |
@@ -1655,6 +1656,71 @@ void Precompiler::BindStaticCalls() { |
} |
+void Precompiler::SwitchICCalls() { |
srdjan
2016/03/15 19:15:48
Add brief comment explaining what is being changed
rmacnak
2016/03/16 18:21:31
Done.
|
+ class SwitchICCallsVisitor : public FunctionVisitor { |
+ public: |
+ explicit SwitchICCallsVisitor(Zone* zone) : |
+ code_(Code::Handle(zone)), |
+ pool_(ObjectPool::Handle(zone)), |
+ entry_(Object::Handle(zone)), |
+ ic_(ICData::Handle(zone)), |
+ target_(Function::Handle(zone)), |
+ target_code_(Code::Handle(zone)), |
+ entry_point_(Smi::Handle(zone)) { |
+ } |
+ |
+ void VisitFunction(const Function& function) { |
+ if (!function.HasCode()) { |
+ ASSERT(function.HasImplicitClosureFunction()); |
+ return; |
+ } |
+ |
+ code_ = function.CurrentCode(); |
+ pool_ = code_.object_pool(); |
+ for (intptr_t i = 0; i < pool_.Length(); i++) { |
+ if (pool_.InfoAt(i) != ObjectPool::kTaggedObject) continue; |
+ entry_ = pool_.ObjectAt(i); |
+ if (entry_.IsICData()) { |
+ ic_ ^= entry_.raw(); |
+ if (ic_.NumArgsTested() != 1) continue; |
srdjan
2016/03/15 19:15:48
Please explain why only NumArgsTests == 1 is switc
rmacnak
2016/03/16 18:21:32
Done.
|
+ for (intptr_t j = 0; j < ic_.NumberOfChecks(); j++) { |
+ entry_ = ic_.GetTargetOrCodeAt(j); |
+ if (entry_.IsFunction()) { |
+ target_ ^= entry_.raw(); |
+ ASSERT(target_.HasCode()); |
+ target_code_ = target_.CurrentCode(); |
+ entry_point_ = |
+ reinterpret_cast<RawSmi*>(target_code_.EntryPoint()); |
srdjan
2016/03/15 19:15:48
Check that it is smi
rmacnak
2016/03/16 18:21:32
Smi::FromAlignedAddress
|
+ ic_.SetCodeAt(j, target_code_); |
+ ic_.SetEntryPointAt(j, entry_point_); |
+ } else { |
+ // We've already seen and switched this ICData. |
+ ASSERT(entry_.IsCode()); |
+ } |
+ } |
+ } else if (entry_.raw() == |
+ StubCode::ICLookupThroughFunction_entry()->code()) { |
+ target_code_ = StubCode::ICLookupThroughCode_entry()->code(); |
+ pool_.SetObjectAt(i, target_code_); |
+ } |
+ } |
+ } |
+ |
+ private: |
+ Code& code_; |
+ ObjectPool& pool_; |
+ Object& entry_; |
+ ICData& ic_; |
+ Function& target_; |
+ Code& target_code_; |
+ Smi& entry_point_; |
+ }; |
+ |
srdjan
2016/03/15 19:15:48
ASSERT that compilation is not allowed?
rmacnak
2016/03/16 18:21:32
Done.
|
+ SwitchICCallsVisitor visitor(Z); |
+ VisitFunctions(&visitor); |
+} |
+ |
+ |
void Precompiler::DedupStackmaps() { |
class DedupStackmapsVisitor : public FunctionVisitor { |
public: |