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 2498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2509 } | 2509 } |
2510 | 2510 |
2511 | 2511 |
2512 // Allocate instances for each enumeration value, and populate the | 2512 // Allocate instances for each enumeration value, and populate the |
2513 // static field 'values'. | 2513 // static field 'values'. |
2514 // By allocating the instances programmatically, we save an implicit final | 2514 // By allocating the instances programmatically, we save an implicit final |
2515 // getter function object for each enumeration value and for the | 2515 // getter function object for each enumeration value and for the |
2516 // values field. We also don't have to generate the code for these getters | 2516 // values field. We also don't have to generate the code for these getters |
2517 // from thin air (no source code is available). | 2517 // from thin air (no source code is available). |
2518 void ClassFinalizer::AllocateEnumValues(const Class &enum_cls) { | 2518 void ClassFinalizer::AllocateEnumValues(const Class &enum_cls) { |
| 2519 Thread* thread = Thread::Current(); |
| 2520 Zone* zone = thread->zone(); |
2519 const Field& index_field = | 2521 const Field& index_field = |
2520 Field::Handle(enum_cls.LookupInstanceField(Symbols::Index())); | 2522 Field::Handle(zone, enum_cls.LookupInstanceField(Symbols::Index())); |
2521 ASSERT(!index_field.IsNull()); | 2523 ASSERT(!index_field.IsNull()); |
2522 const Field& values_field = | 2524 const Field& values_field = |
2523 Field::Handle(enum_cls.LookupStaticField(Symbols::Values())); | 2525 Field::Handle(zone, enum_cls.LookupStaticField(Symbols::Values())); |
2524 ASSERT(!values_field.IsNull()); | 2526 ASSERT(!values_field.IsNull()); |
2525 ASSERT(Instance::Handle(values_field.StaticValue()).IsArray()); | 2527 ASSERT(Instance::Handle(zone, values_field.StaticValue()).IsArray()); |
2526 Array& values_list = Array::Handle( | 2528 Array& values_list = Array::Handle( |
2527 Array::RawCast(values_field.StaticValue())); | 2529 zone, Array::RawCast(values_field.StaticValue())); |
2528 | 2530 |
2529 const Array& fields = Array::Handle(enum_cls.fields()); | 2531 const Array& fields = Array::Handle(zone, enum_cls.fields()); |
2530 Field& field = Field::Handle(); | 2532 Field& field = Field::Handle(zone); |
2531 Instance& ordinal_value = Instance::Handle(); | 2533 Instance& ordinal_value = Instance::Handle(zone); |
2532 Instance& enum_value = Instance::Handle(); | 2534 Instance& enum_value = Instance::Handle(zone); |
2533 | 2535 |
2534 for (intptr_t i = 0; i < fields.Length(); i++) { | 2536 for (intptr_t i = 0; i < fields.Length(); i++) { |
2535 field = Field::RawCast(fields.At(i)); | 2537 field = Field::RawCast(fields.At(i)); |
2536 if (!field.is_static()) continue; | 2538 if (!field.is_static()) continue; |
2537 ordinal_value = field.StaticValue(); | 2539 ordinal_value = field.StaticValue(); |
2538 // The static fields that need to be initialized with enum instances | 2540 // The static fields that need to be initialized with enum instances |
2539 // contain the smi value of the ordinal number, which was stored in | 2541 // contain the smi value of the ordinal number, which was stored in |
2540 // the field by the parser. Other fields contain non-smi values. | 2542 // the field by the parser. Other fields contain non-smi values. |
2541 if (!ordinal_value.IsSmi()) continue; | 2543 if (!ordinal_value.IsSmi()) continue; |
2542 enum_value = Instance::New(enum_cls, Heap::kOld); | 2544 enum_value = Instance::New(enum_cls, Heap::kOld); |
2543 enum_value.SetField(index_field, ordinal_value); | 2545 enum_value.SetField(index_field, ordinal_value); |
2544 const char* error_msg = ""; | 2546 const char* error_msg = ""; |
2545 enum_value = enum_value.CheckAndCanonicalize(&error_msg); | 2547 enum_value = enum_value.CheckAndCanonicalize(thread, &error_msg); |
2546 ASSERT(!enum_value.IsNull()); | 2548 ASSERT(!enum_value.IsNull()); |
2547 ASSERT(enum_value.IsCanonical()); | 2549 ASSERT(enum_value.IsCanonical()); |
2548 field.SetStaticValue(enum_value, true); | 2550 field.SetStaticValue(enum_value, true); |
2549 field.RecordStore(enum_value); | 2551 field.RecordStore(enum_value); |
2550 intptr_t ord = Smi::Cast(ordinal_value).Value(); | 2552 intptr_t ord = Smi::Cast(ordinal_value).Value(); |
2551 ASSERT(ord < values_list.Length()); | 2553 ASSERT(ord < values_list.Length()); |
2552 values_list.SetAt(ord, enum_value); | 2554 values_list.SetAt(ord, enum_value); |
2553 } | 2555 } |
2554 values_list.MakeImmutable(); | 2556 values_list.MakeImmutable(); |
2555 const char* error_msg = NULL; | 2557 const char* error_msg = NULL; |
2556 values_list ^= values_list.CheckAndCanonicalize(&error_msg); | 2558 values_list ^= values_list.CheckAndCanonicalize(thread, &error_msg); |
2557 ASSERT(!values_list.IsNull()); | 2559 ASSERT(!values_list.IsNull()); |
2558 } | 2560 } |
2559 | 2561 |
2560 | 2562 |
2561 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { | 2563 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { |
2562 Class& test1 = Class::Handle(cls.raw()); | 2564 Class& test1 = Class::Handle(cls.raw()); |
2563 Class& test2 = Class::Handle(cls.SuperClass()); | 2565 Class& test2 = Class::Handle(cls.SuperClass()); |
2564 // A finalized class has been checked for cycles. | 2566 // A finalized class has been checked for cycles. |
2565 // Using the hare and tortoise algorithm for locating cycles. | 2567 // Using the hare and tortoise algorithm for locating cycles. |
2566 while (!test1.is_type_finalized() && | 2568 while (!test1.is_type_finalized() && |
(...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3315 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3317 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
3316 field ^= fields_array.At(0); | 3318 field ^= fields_array.At(0); |
3317 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3319 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
3318 name ^= field.name(); | 3320 name ^= field.name(); |
3319 expected_name ^= String::New("_data"); | 3321 expected_name ^= String::New("_data"); |
3320 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3322 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
3321 #endif | 3323 #endif |
3322 } | 3324 } |
3323 | 3325 |
3324 } // namespace dart | 3326 } // namespace dart |
OLD | NEW |