Chromium Code Reviews| Index: runtime/vm/precompiler.cc |
| diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc |
| index 9a77d4a28faa21a9d28e1d9a35d5dcd90cd228a5..ee146d9b23e02da1729b441073e0d9af591e3000 100644 |
| --- a/runtime/vm/precompiler.cc |
| +++ b/runtime/vm/precompiler.cc |
| @@ -61,6 +61,7 @@ Precompiler::Precompiler(Thread* thread, bool reset_fields) : |
| GrowableObjectArray::New())), |
| collected_closures_(GrowableObjectArray::Handle(Z, I->collected_closures())), |
| sent_selectors_(Z), |
| + stackmaps_(Z), |
| error_(Error::Handle(Z)) { |
| } |
| @@ -331,6 +332,8 @@ void Precompiler::CleanUp() { |
| // TODO(rmacnak): DropEmptyClasses(); |
| BindStaticCalls(); |
| + |
| + DedupStackmaps(); |
| } |
| @@ -764,4 +767,62 @@ void Precompiler::BindStaticCalls(const Function& function) { |
| code.set_static_calls_target_table(Object::empty_array()); |
| } |
| + |
| +void Precompiler::DedupStackmaps() { |
| + Library& lib = Library::Handle(Z); |
|
Florian Schneider
2015/10/07 10:40:07
This code for iterating over all functions seems t
rmacnak
2015/10/07 22:19:06
Recast as visitor. Covers clear code, bind static
|
| + Class& cls = Class::Handle(Z); |
| + Array& functions = Array::Handle(Z); |
| + Function& function = Function::Handle(Z); |
| + GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); |
| + |
| + for (intptr_t i = 0; i < libraries_.Length(); i++) { |
| + lib ^= libraries_.At(i); |
| + ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); |
| + while (it.HasNext()) { |
| + cls = it.GetNextClass(); |
| + if (cls.IsDynamicClass()) { |
| + continue; // class 'dynamic' is in the read-only VM isolate. |
| + } |
| + |
| + functions = cls.functions(); |
| + for (intptr_t j = 0; j < functions.Length(); j++) { |
| + function ^= functions.At(j); |
| + DedupStackmaps(function); |
| + } |
| + |
| + closures = cls.closures(); |
| + if (!closures.IsNull()) { |
| + for (intptr_t j = 0; j < closures.Length(); j++) { |
| + function ^= closures.At(j); |
| + DedupStackmaps(function); |
| + } |
| + } |
| + } |
| + } |
| +} |
| + |
| + |
| +void Precompiler::DedupStackmaps(const Function& function) { |
| + Code& code = Code::Handle(Z, function.CurrentCode()); |
| + Array& stackmaps = Array::Handle(Z, code.stackmaps()); |
| + if (stackmaps.IsNull()) return; |
| + Stackmap& stackmap = Stackmap::Handle(Z); |
| + for (intptr_t i = 0; i < stackmaps.Length(); i++) { |
| + stackmap ^= stackmaps.At(i); |
| + stackmap = DedupStackmap(stackmap); |
| + stackmaps.SetAt(i, stackmap); |
| + } |
| +} |
| + |
| + |
| +RawStackmap* Precompiler::DedupStackmap(const Stackmap& stackmap) { |
| + const Stackmap* canonical_stackmap = stackmaps_.Lookup(stackmap); |
| + if (canonical_stackmap == NULL) { |
| + stackmaps_.Add(Stackmap::ZoneHandle(Z, stackmap.raw())); |
| + return stackmap.raw(); |
| + } else { |
| + return canonical_stackmap->raw(); |
| + } |
| +} |
| + |
| } // namespace dart |