// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. #include "vm/class_table.h" #include "vm/flags.h" #include "vm/freelist.h" #include "vm/object.h" #include "vm/raw_object.h" #include "vm/visitor.h" namespace dart { DEFINE_FLAG(bool, print_class_table, false, "Print initial class table."); ClassTable::ClassTable() : top_(kNumPredefinedCids), capacity_(0), table_(NULL) { if (Dart::vm_isolate() == NULL) { capacity_ = initial_capacity_; table_ = reinterpret_cast( calloc(capacity_, sizeof(RawClass*))); // NOLINT } else { // Duplicate the class table from the VM isolate. ClassTable* vm_class_table = Dart::vm_isolate()->class_table(); capacity_ = vm_class_table->capacity_; table_ = reinterpret_cast( calloc(capacity_, sizeof(RawClass*))); // NOLINT for (intptr_t i = kObjectCid; i < kInstanceCid; i++) { table_[i] = vm_class_table->At(i); } table_[kFreeListElement] = vm_class_table->At(kFreeListElement); table_[kDynamicCid] = vm_class_table->At(kDynamicCid); table_[kVoidCid] = vm_class_table->At(kVoidCid); } } ClassTable::~ClassTable() { free(table_); } void ClassTable::Register(const Class& cls) { intptr_t index = cls.id(); if (index != kIllegalCid) { ASSERT(index > 0); ASSERT(index < kNumPredefinedCids); ASSERT(table_[index] == 0); ASSERT(index < capacity_); table_[index] = cls.raw(); // Add the vtable for this predefined class into the static vtable registry // if it has not been setup yet. cpp_vtable cls_vtable = cls.handle_vtable(); cpp_vtable table_entry = Object::builtin_vtables_[index]; ASSERT((table_entry == 0) || (table_entry == cls_vtable)); if (table_entry == 0) { Object::builtin_vtables_[index] = cls_vtable; } } else { if (top_ == capacity_) { // Grow the capacity of the class table. intptr_t new_capacity = capacity_ + capacity_increment_; RawClass** new_table = reinterpret_cast( realloc(table_, new_capacity * sizeof(RawClass*))); // NOLINT for (intptr_t i = capacity_; i < new_capacity; i++) { new_table[i] = NULL; } capacity_ = new_capacity; table_ = new_table; } ASSERT(top_ < capacity_); cls.set_id(top_); table_[top_] = cls.raw(); top_++; // Increment next index. } } void ClassTable::VisitObjectPointers(ObjectPointerVisitor* visitor) { ASSERT(visitor != NULL); visitor->VisitPointers(reinterpret_cast(&table_[0]), top_); } void ClassTable::Print() { Class& cls = Class::Handle(); String& name = String::Handle(); for (intptr_t i = 1; i < top_; i++) { cls = At(i); if (cls.raw() != reinterpret_cast(0)) { name = cls.Name(); OS::Print("%" Pd ": %s\n", i, name.ToCString()); } } } } // namespace dart