Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
| 6 | 6 |
| 7 #include "vm/code_generator.h" | 7 #include "vm/code_generator.h" |
| 8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
| 9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| (...skipping 2328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2339 // Run additional checks after all types are finalized. | 2339 // Run additional checks after all types are finalized. |
| 2340 if (cls.is_const()) { | 2340 if (cls.is_const()) { |
| 2341 CheckForLegalConstClass(cls); | 2341 CheckForLegalConstClass(cls); |
| 2342 } | 2342 } |
| 2343 if (FLAG_use_cha) { | 2343 if (FLAG_use_cha) { |
| 2344 GrowableArray<intptr_t> cids; | 2344 GrowableArray<intptr_t> cids; |
| 2345 CollectFinalizedSuperClasses(cls, &cids); | 2345 CollectFinalizedSuperClasses(cls, &cids); |
| 2346 CollectImmediateSuperInterfaces(cls, &cids); | 2346 CollectImmediateSuperInterfaces(cls, &cids); |
| 2347 RemoveCHAOptimizedCode(cids); | 2347 RemoveCHAOptimizedCode(cids); |
| 2348 } | 2348 } |
| 2349 if (cls.is_enum_class()) { | |
| 2350 AllocateEnumValues(cls); | |
| 2351 } | |
| 2352 } | |
| 2353 | |
| 2354 | |
| 2355 // Allocate instances for each enumeration value, and populate the | |
| 2356 // static field 'values'. | |
| 2357 // By allocating the instances programmatically, we save an implicit final | |
| 2358 // getter function object for each enumeration value and for the | |
| 2359 // values field. We also don't have to generate the code for these getters | |
| 2360 // from thin air (no source code is available). | |
| 2361 void ClassFinalizer::AllocateEnumValues(const Class &enum_cls) { | |
| 2362 const Field& index_field = | |
| 2363 Field::Handle(enum_cls.LookupInstanceField(Symbols::Index())); | |
| 2364 ASSERT(!index_field.IsNull()); | |
| 2365 const Field& values_field = | |
| 2366 Field::Handle(enum_cls.LookupStaticField(Symbols::Values())); | |
| 2367 ASSERT(!values_field.IsNull()); | |
| 2368 ASSERT(Instance::Handle(values_field.value()).IsArray()); | |
| 2369 Array& values_list = Array::Handle(Array::RawCast(values_field.value())); | |
| 2370 | |
| 2371 const Array& fields = Array::Handle(enum_cls.fields()); | |
| 2372 Field& field = Field::Handle(); | |
| 2373 Instance& ordinal_value = Instance::Handle(); | |
| 2374 Instance& enum_value = Instance::Handle(); | |
| 2375 | |
| 2376 for (intptr_t i = 0; i < fields.Length(); i++) { | |
| 2377 field = Field::RawCast(fields.At(i)); | |
| 2378 if (!field.is_static()) continue; | |
| 2379 ordinal_value = field.value(); | |
| 2380 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.
| |
| 2381 enum_value = Instance::New(enum_cls, Heap::kOld); | |
| 2382 enum_value.SetField(index_field, ordinal_value); | |
| 2383 field.set_value(enum_value); | |
| 2384 field.RecordStore(enum_value); | |
| 2385 intptr_t ord = Smi::Cast(ordinal_value).Value(); | |
| 2386 ASSERT(ord < values_list.Length()); | |
| 2387 values_list.SetAt(ord, enum_value); | |
| 2388 } | |
| 2389 values_list.MakeImmutable(); | |
| 2349 } | 2390 } |
| 2350 | 2391 |
| 2351 | 2392 |
| 2352 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { | 2393 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { |
| 2353 Class& test1 = Class::Handle(cls.raw()); | 2394 Class& test1 = Class::Handle(cls.raw()); |
| 2354 Class& test2 = Class::Handle(cls.SuperClass()); | 2395 Class& test2 = Class::Handle(cls.SuperClass()); |
| 2355 // A finalized class has been checked for cycles. | 2396 // A finalized class has been checked for cycles. |
| 2356 // Using the hare and tortoise algorithm for locating cycles. | 2397 // Using the hare and tortoise algorithm for locating cycles. |
| 2357 while (!test1.is_type_finalized() && | 2398 while (!test1.is_type_finalized() && |
| 2358 !test2.IsNull() && !test2.is_type_finalized()) { | 2399 !test2.IsNull() && !test2.is_type_finalized()) { |
| (...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3083 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3124 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
| 3084 field ^= fields_array.At(0); | 3125 field ^= fields_array.At(0); |
| 3085 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3126 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
| 3086 name ^= field.name(); | 3127 name ^= field.name(); |
| 3087 expected_name ^= String::New("_data"); | 3128 expected_name ^= String::New("_data"); |
| 3088 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3129 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 3089 #endif | 3130 #endif |
| 3090 } | 3131 } |
| 3091 | 3132 |
| 3092 } // namespace dart | 3133 } // namespace dart |
| OLD | NEW |