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

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