Index: runtime/vm/precompiler.cc |
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc |
index 985617c748d2e4d2b92f757873b2d1a40586703a..df91db83d9059be0e5dfc3b68dc3d1268119ee89 100644 |
--- a/runtime/vm/precompiler.cc |
+++ b/runtime/vm/precompiler.cc |
@@ -396,8 +396,9 @@ void Precompiler::DoCompileAll( |
BindStaticCalls(); |
SwitchICCalls(); |
+ ShareMegamorphicBuckets(); |
DedupStackmaps(); |
- DedupStackmapLists(); |
+ DedupLists(); |
if (FLAG_dedup_instructions) { |
// Reduces binary size but obfuscates profiler results. |
@@ -2152,6 +2153,29 @@ void Precompiler::SwitchICCalls() { |
} |
+void Precompiler::ShareMegamorphicBuckets() { |
+ const GrowableObjectArray& table = GrowableObjectArray::Handle(Z, |
+ I->object_store()->megamorphic_cache_table()); |
+ if (table.IsNull()) return; |
+ MegamorphicCache& cache = MegamorphicCache::Handle(Z); |
+ |
+ const intptr_t capacity = 1; |
+ const Array& buckets = Array::Handle(Z, |
+ Array::New(MegamorphicCache::kEntryLength * capacity, Heap::kOld)); |
+ const Function& handler = |
+ Function::Handle(Z, MegamorphicCacheTable::miss_handler(I)); |
+ MegamorphicCache::SetEntry(buckets, 0, |
+ MegamorphicCache::smi_illegal_cid(), handler); |
+ |
+ for (intptr_t i = 0; i < table.Length(); i++) { |
+ cache ^= table.At(i); |
+ cache.set_buckets(buckets); |
+ cache.set_mask(capacity - 1); |
+ cache.set_filled_entry_count(0); |
+ } |
+} |
+ |
+ |
void Precompiler::DedupStackmaps() { |
class DedupStackmapsVisitor : public FunctionVisitor { |
public: |
@@ -2202,50 +2226,73 @@ void Precompiler::DedupStackmaps() { |
} |
-void Precompiler::DedupStackmapLists() { |
- class DedupStackmapListsVisitor : public FunctionVisitor { |
+void Precompiler::DedupLists() { |
+ class DedupListsVisitor : public FunctionVisitor { |
public: |
- explicit DedupStackmapListsVisitor(Zone* zone) : |
+ explicit DedupListsVisitor(Zone* zone) : |
zone_(zone), |
- canonical_stackmap_lists_(), |
+ canonical_lists_(), |
code_(Code::Handle(zone)), |
- stackmaps_(Array::Handle(zone)), |
- stackmap_(Stackmap::Handle(zone)) { |
+ list_(Array::Handle(zone)) { |
} |
void Visit(const Function& function) { |
- if (!function.HasCode()) { |
- return; |
- } |
code_ = function.CurrentCode(); |
- stackmaps_ = code_.stackmaps(); |
- if (stackmaps_.IsNull()) return; |
+ if (!code_.IsNull()) { |
+ list_ = code_.stackmaps(); |
+ if (!list_.IsNull()) { |
+ list_ = DedupList(list_); |
+ code_.set_stackmaps(list_); |
+ } |
+ } |
- stackmaps_ = DedupStackmapList(stackmaps_); |
- code_.set_stackmaps(stackmaps_); |
+ list_ = function.parameter_types(); |
+ if (!list_.IsNull()) { |
+ if (!function.IsSignatureFunction() && |
+ !function.IsClosureFunction() && |
+ (function.name() != Symbols::Call().raw()) && |
+ !list_.InVMHeap()) { |
+ // Parameter types not needed for function type tests. |
+ for (intptr_t i = 0; i < list_.Length(); i++) { |
+ list_.SetAt(i, Object::dynamic_type()); |
+ } |
+ } |
+ list_ = DedupList(list_); |
+ function.set_parameter_types(list_); |
+ } |
+ |
+ list_ = function.parameter_names(); |
+ if (!list_.IsNull()) { |
+ if (!function.HasOptionalNamedParameters() && |
+ !list_.InVMHeap()) { |
+ // Parameter names not needed for resolution. |
+ for (intptr_t i = 0; i < list_.Length(); i++) { |
+ list_.SetAt(i, Symbols::OptimizedOut()); |
+ } |
+ } |
+ list_ = DedupList(list_); |
+ function.set_parameter_names(list_); |
+ } |
} |
- RawArray* DedupStackmapList(const Array& stackmaps) { |
- const Array* canonical_stackmap_list = |
- canonical_stackmap_lists_.LookupValue(&stackmaps); |
- if (canonical_stackmap_list == NULL) { |
- canonical_stackmap_lists_.Insert( |
- &Array::ZoneHandle(zone_, stackmaps.raw())); |
- return stackmaps.raw(); |
+ RawArray* DedupList(const Array& list) { |
+ const Array* canonical_list = canonical_lists_.LookupValue(&list); |
+ if (canonical_list == NULL) { |
+ canonical_lists_.Insert(&Array::ZoneHandle(zone_, list.raw())); |
+ return list.raw(); |
} else { |
- return canonical_stackmap_list->raw(); |
+ return canonical_list->raw(); |
} |
} |
private: |
Zone* zone_; |
- ArraySet canonical_stackmap_lists_; |
+ ArraySet canonical_lists_; |
Code& code_; |
- Array& stackmaps_; |
- Stackmap& stackmap_; |
+ Array& list_; |
}; |
- DedupStackmapListsVisitor visitor(Z); |
+ DedupListsVisitor visitor(Z); |
VisitFunctions(&visitor); |
} |