Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(393)

Side by Side Diff: runtime/vm/class_finalizer.cc

Issue 1873143003: - Use a hash table to canonicalize instances/arrays to avoid having to iterate over a linear list a… (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: address-code-review Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « runtime/lib/integers.cc ('k') | runtime/vm/dart_entry.cc » ('j') | runtime/vm/object.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698