Index: runtime/vm/precompiler.cc |
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc |
index da3473927aa2e45734306dee8c3741f9c906651c..5a0f88eadc96990026eda32056d4ae4cb8d58c0b 100644 |
--- a/runtime/vm/precompiler.cc |
+++ b/runtime/vm/precompiler.cc |
@@ -502,15 +502,7 @@ void Precompiler::DoCompileAll( |
BindStaticCalls(); |
SwitchICCalls(); |
- ShareMegamorphicBuckets(); |
- DedupStackMaps(); |
- DedupCodeSourceMaps(); |
- DedupLists(); |
- |
- if (FLAG_dedup_instructions) { |
- // Reduces binary size but obfuscates profiler results. |
- DedupInstructions(); |
- } |
+ ProgramVisitor::Dedup(); |
zone_ = NULL; |
} |
@@ -2270,240 +2262,6 @@ 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: |
- explicit DedupStackMapsVisitor(Zone* zone) |
- : zone_(zone), |
- canonical_stackmaps_(), |
- code_(Code::Handle(zone)), |
- stackmaps_(Array::Handle(zone)), |
- stackmap_(StackMap::Handle(zone)) {} |
- |
- void Visit(const Function& function) { |
- if (!function.HasCode()) { |
- return; |
- } |
- code_ = function.CurrentCode(); |
- stackmaps_ = code_.stackmaps(); |
- if (stackmaps_.IsNull()) return; |
- for (intptr_t i = 0; i < stackmaps_.Length(); i++) { |
- stackmap_ ^= stackmaps_.At(i); |
- stackmap_ = DedupStackMap(stackmap_); |
- stackmaps_.SetAt(i, stackmap_); |
- } |
- } |
- |
- RawStackMap* DedupStackMap(const StackMap& stackmap) { |
- const StackMap* canonical_stackmap = |
- canonical_stackmaps_.LookupValue(&stackmap); |
- if (canonical_stackmap == NULL) { |
- canonical_stackmaps_.Insert( |
- &StackMap::ZoneHandle(zone_, stackmap.raw())); |
- return stackmap.raw(); |
- } else { |
- return canonical_stackmap->raw(); |
- } |
- } |
- |
- private: |
- Zone* zone_; |
- StackMapSet canonical_stackmaps_; |
- Code& code_; |
- Array& stackmaps_; |
- StackMap& stackmap_; |
- }; |
- |
- DedupStackMapsVisitor visitor(Z); |
- ProgramVisitor::VisitFunctions(&visitor); |
-} |
- |
- |
-void Precompiler::DedupCodeSourceMaps() { |
- class DedupCodeSourceMapsVisitor : public FunctionVisitor { |
- public: |
- explicit DedupCodeSourceMapsVisitor(Zone* zone) |
- : zone_(zone), |
- canonical_code_source_maps_(), |
- code_(Code::Handle(zone)), |
- code_source_map_(CodeSourceMap::Handle(zone)) {} |
- |
- void Visit(const Function& function) { |
- if (!function.HasCode()) { |
- return; |
- } |
- code_ = function.CurrentCode(); |
- code_source_map_ = code_.code_source_map(); |
- ASSERT(!code_source_map_.IsNull()); |
- code_source_map_ = DedupCodeSourceMap(code_source_map_); |
- code_.set_code_source_map(code_source_map_); |
- } |
- |
- RawCodeSourceMap* DedupCodeSourceMap(const CodeSourceMap& code_source_map) { |
- const CodeSourceMap* canonical_code_source_map = |
- canonical_code_source_maps_.LookupValue(&code_source_map); |
- if (canonical_code_source_map == NULL) { |
- canonical_code_source_maps_.Insert( |
- &CodeSourceMap::ZoneHandle(zone_, code_source_map.raw())); |
- return code_source_map.raw(); |
- } else { |
- return canonical_code_source_map->raw(); |
- } |
- } |
- |
- private: |
- Zone* zone_; |
- CodeSourceMapSet canonical_code_source_maps_; |
- Code& code_; |
- CodeSourceMap& code_source_map_; |
- }; |
- |
- DedupCodeSourceMapsVisitor visitor(Z); |
- ProgramVisitor::VisitFunctions(&visitor); |
-} |
- |
- |
-void Precompiler::DedupLists() { |
- class DedupListsVisitor : public FunctionVisitor { |
- public: |
- explicit DedupListsVisitor(Zone* zone) |
- : zone_(zone), |
- canonical_lists_(), |
- code_(Code::Handle(zone)), |
- list_(Array::Handle(zone)) {} |
- |
- void Visit(const Function& function) { |
- code_ = function.CurrentCode(); |
- if (!code_.IsNull()) { |
- list_ = code_.stackmaps(); |
- if (!list_.IsNull()) { |
- list_ = DedupList(list_); |
- code_.set_stackmaps(list_); |
- } |
- list_ = code_.inlined_id_to_function(); |
- if (!list_.IsNull()) { |
- list_ = DedupList(list_); |
- code_.set_inlined_id_to_function(list_); |
- } |
- } |
- |
- 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* 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_list->raw(); |
- } |
- } |
- |
- private: |
- Zone* zone_; |
- ArraySet canonical_lists_; |
- Code& code_; |
- Array& list_; |
- }; |
- |
- DedupListsVisitor visitor(Z); |
- ProgramVisitor::VisitFunctions(&visitor); |
-} |
- |
- |
-void Precompiler::DedupInstructions() { |
- class DedupInstructionsVisitor : public FunctionVisitor { |
- public: |
- explicit DedupInstructionsVisitor(Zone* zone) |
- : zone_(zone), |
- canonical_instructions_set_(), |
- code_(Code::Handle(zone)), |
- instructions_(Instructions::Handle(zone)) {} |
- |
- void Visit(const Function& function) { |
- if (!function.HasCode()) { |
- ASSERT(function.HasImplicitClosureFunction()); |
- return; |
- } |
- code_ = function.CurrentCode(); |
- instructions_ = code_.instructions(); |
- instructions_ = DedupOneInstructions(instructions_); |
- code_.SetActiveInstructions(instructions_); |
- code_.set_instructions(instructions_); |
- function.SetInstructions(code_); // Update cached entry point. |
- } |
- |
- RawInstructions* DedupOneInstructions(const Instructions& instructions) { |
- const Instructions* canonical_instructions = |
- canonical_instructions_set_.LookupValue(&instructions); |
- if (canonical_instructions == NULL) { |
- canonical_instructions_set_.Insert( |
- &Instructions::ZoneHandle(zone_, instructions.raw())); |
- return instructions.raw(); |
- } else { |
- return canonical_instructions->raw(); |
- } |
- } |
- |
- private: |
- Zone* zone_; |
- InstructionsSet canonical_instructions_set_; |
- Code& code_; |
- Instructions& instructions_; |
- }; |
- |
- DedupInstructionsVisitor visitor(Z); |
- ProgramVisitor::VisitFunctions(&visitor); |
-} |
- |
- |
void Precompiler::FinalizeAllClasses() { |
Library& lib = Library::Handle(Z); |
Class& cls = Class::Handle(Z); |