Chromium Code Reviews| Index: runtime/vm/class_finalizer.cc |
| =================================================================== |
| --- runtime/vm/class_finalizer.cc (revision 41810) |
| +++ runtime/vm/class_finalizer.cc (working copy) |
| @@ -2346,9 +2346,50 @@ |
| CollectImmediateSuperInterfaces(cls, &cids); |
| RemoveCHAOptimizedCode(cids); |
| } |
| + if (cls.is_enum_class()) { |
| + AllocateEnumValues(cls); |
| + } |
| } |
| +// Allocate instances for each enumeration value, and populate the |
| +// static field 'values'. |
| +// By allocating the instances programmatically, we save an implicit final |
| +// getter function object for each enumeration value and for the |
| +// values field. We also don't have to generate the code for these getters |
| +// from thin air (no source code is available). |
| +void ClassFinalizer::AllocateEnumValues(const Class &enum_cls) { |
| + const Field& index_field = |
| + Field::Handle(enum_cls.LookupInstanceField(Symbols::Index())); |
| + ASSERT(!index_field.IsNull()); |
| + const Field& values_field = |
| + Field::Handle(enum_cls.LookupStaticField(Symbols::Values())); |
| + ASSERT(!values_field.IsNull()); |
| + ASSERT(Instance::Handle(values_field.value()).IsArray()); |
| + Array& values_list = Array::Handle(Array::RawCast(values_field.value())); |
| + |
| + const Array& fields = Array::Handle(enum_cls.fields()); |
| + Field& field = Field::Handle(); |
| + Instance& ordinal_value = Instance::Handle(); |
| + Instance& enum_value = Instance::Handle(); |
| + |
| + for (intptr_t i = 0; i < fields.Length(); i++) { |
| + field = Field::RawCast(fields.At(i)); |
| + if (!field.is_static()) continue; |
| + ordinal_value = field.value(); |
| + if (!ordinal_value.IsSmi()) continue; |
|
srdjan
2014/11/18 21:19:18
Maybe add comment how it can be non-smi.
hausner
2014/11/18 23:14:07
Done.
|
| + enum_value = Instance::New(enum_cls, Heap::kOld); |
| + enum_value.SetField(index_field, ordinal_value); |
| + field.set_value(enum_value); |
| + field.RecordStore(enum_value); |
| + intptr_t ord = Smi::Cast(ordinal_value).Value(); |
| + ASSERT(ord < values_list.Length()); |
| + values_list.SetAt(ord, enum_value); |
| + } |
| + values_list.MakeImmutable(); |
| +} |
| + |
| + |
| bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { |
| Class& test1 = Class::Handle(cls.raw()); |
| Class& test2 = Class::Handle(cls.SuperClass()); |