Chromium Code Reviews| Index: runtime/vm/precompiler.cc |
| diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc |
| index dc0edb5efd6cb0c112a7d077541404e1bd27e4af..b9a48ad363bd6a51a2f95c55b4df4cb459f47caa 100644 |
| --- a/runtime/vm/precompiler.cc |
| +++ b/runtime/vm/precompiler.cc |
| @@ -516,6 +516,69 @@ void Precompiler::Iterate() { |
| if (!changed_) { |
| TraceConstFunctions(); |
| } |
| + CollectCallbackFields(); |
| + } |
| +} |
| + |
| + |
| +void Precompiler::CollectCallbackFields() { |
| + Library& lib = Library::Handle(Z); |
| + Class& cls = Class::Handle(Z); |
| + Class& subcls = Class::Handle(Z); |
| + Array& fields = Array::Handle(Z); |
| + Field& field = Field::Handle(Z); |
| + Function& function = Function::Handle(Z); |
| + Function& dispatcher = Function::Handle(Z); |
| + Array& args_desc = Array::Handle(Z); |
| + AbstractType& field_type = AbstractType::Handle(Z); |
| + String& field_name = String::Handle(Z); |
| + GrowableArray<intptr_t> cids; |
| + |
| + 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.is_allocated()) continue; |
| + |
| + fields = cls.fields(); |
| + for (intptr_t k = 0; k < fields.Length(); k++) { |
| + field ^= fields.At(k); |
| + if (field.is_static()) continue; |
| + field_type = field.type(); |
| + if (!field_type.IsFunctionType()) continue; |
| + field_name = field.name(); |
| + if (!IsSent(field_name)) continue; |
| + // Create arguments descriptor with fixed parameters from |
| + // signature of field_type. |
| + function = Type::Cast(field_type).signature(); |
| + if (function.HasOptionalParameters()) continue; |
| + if (FLAG_trace_precompiler) { |
| + OS::Print("Found callback field %s\n", field_name.ToCString()); |
|
rmacnak
2016/08/01 23:41:08
THR_Print
Florian Schneider
2016/08/01 23:57:00
Done.
|
| + } |
| + args_desc = |
| + ArgumentsDescriptor::New(function.num_fixed_parameters()); |
| + cids.Clear(); |
| + if (!T->cha()->ConcreteSubclasses(cls, &cids)) return; |
|
rmacnak
2016/08/01 23:41:08
continue in the class loop
Without labeled break/
Florian Schneider
2016/08/01 23:57:00
Yes, done.
|
| + for (intptr_t j = 0; j < cids.length(); ++j) { |
| + subcls ^= I->class_table()->At(cids[j]); |
| + if (subcls.is_allocated()) { |
| + // Add dispatcher to cls. |
| + dispatcher = subcls.GetInvocationDispatcher( |
| + field_name, |
| + args_desc, |
| + RawFunction::kInvokeFieldDispatcher, |
| + /* create_if_absent = */ true); |
| + if (FLAG_trace_precompiler) { |
| + OS::Print("Added invoke-field-dispatcher for %s to %s\n", |
|
rmacnak
2016/08/01 23:41:08
THR_Print
Florian Schneider
2016/08/01 23:57:00
Done.
|
| + field_name.ToCString(), subcls.ToCString()); |
| + } |
| + AddFunction(dispatcher); |
| + } |
| + } |
| + } |
| + } |
| } |
| } |