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

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

Issue 816773005: Copy-on-write class table for concurrent reading. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/class_table.h ('k') | runtime/vm/pages.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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_table.h" 5 #include "vm/class_table.h"
6 #include "vm/flags.h" 6 #include "vm/flags.h"
7 #include "vm/freelist.h" 7 #include "vm/freelist.h"
8 #include "vm/growable_array.h"
8 #include "vm/heap.h" 9 #include "vm/heap.h"
9 #include "vm/object.h" 10 #include "vm/object.h"
10 #include "vm/raw_object.h" 11 #include "vm/raw_object.h"
11 #include "vm/visitor.h" 12 #include "vm/visitor.h"
12 13
13 namespace dart { 14 namespace dart {
14 15
15 DEFINE_FLAG(bool, print_class_table, false, "Print initial class table."); 16 DEFINE_FLAG(bool, print_class_table, false, "Print initial class table.");
16 17
17 ClassTable::ClassTable() 18 ClassTable::ClassTable()
18 : top_(kNumPredefinedCids), capacity_(0), table_(NULL), 19 : top_(kNumPredefinedCids), capacity_(0), table_(NULL),
20 old_tables_(new MallocGrowableArray<RawClass**>()),
Ivan Posva 2015/01/20 22:46:45 Wondering why you decided on MallocGrowableArray v
koda 2015/01/21 14:36:09 1. To avoid yet another ad hoc linked list impleme
19 class_heap_stats_table_(NULL), 21 class_heap_stats_table_(NULL),
20 predefined_class_heap_stats_table_(NULL) { 22 predefined_class_heap_stats_table_(NULL) {
21 if (Dart::vm_isolate() == NULL) { 23 if (Dart::vm_isolate() == NULL) {
22 capacity_ = initial_capacity_; 24 capacity_ = initial_capacity_;
23 table_ = reinterpret_cast<RawClass**>( 25 table_ = reinterpret_cast<RawClass**>(
24 calloc(capacity_, sizeof(RawClass*))); // NOLINT 26 calloc(capacity_, sizeof(RawClass*))); // NOLINT
25 } else { 27 } else {
26 // Duplicate the class table from the VM isolate. 28 // Duplicate the class table from the VM isolate.
27 ClassTable* vm_class_table = Dart::vm_isolate()->class_table(); 29 ClassTable* vm_class_table = Dart::vm_isolate()->class_table();
28 capacity_ = vm_class_table->capacity_; 30 capacity_ = vm_class_table->capacity_;
(...skipping 15 matching lines...) Expand all
44 calloc(kNumPredefinedCids, sizeof(ClassHeapStats))); // NOLINT 46 calloc(kNumPredefinedCids, sizeof(ClassHeapStats))); // NOLINT
45 for (intptr_t i = 0; i < kNumPredefinedCids; i++) { 47 for (intptr_t i = 0; i < kNumPredefinedCids; i++) {
46 predefined_class_heap_stats_table_[i].Initialize(); 48 predefined_class_heap_stats_table_[i].Initialize();
47 } 49 }
48 } 50 }
49 51
50 52
51 ClassTable::ClassTable(ClassTable* original) 53 ClassTable::ClassTable(ClassTable* original)
52 : top_(original->top_), 54 : top_(original->top_),
53 capacity_(original->top_), 55 capacity_(original->top_),
54 table_(reinterpret_cast<RawClass**>( 56 table_(original->table_),
55 calloc(original->top_, sizeof(RawClass*)))), 57 old_tables_(NULL),
56 class_heap_stats_table_(NULL), 58 class_heap_stats_table_(NULL),
57 predefined_class_heap_stats_table_(NULL) { 59 predefined_class_heap_stats_table_(NULL) {
58 for (intptr_t i = 1; i < top_; i++) { 60 }
59 table_[i] = original->At(i); 61
62
63 ClassTable::~ClassTable() {
64 if (old_tables_ != NULL) {
65 FreeOldTables();
66 delete old_tables_;
67 free(table_);
68 free(predefined_class_heap_stats_table_);
69 free(class_heap_stats_table_);
70 } else {
71 // This instance was a shallow copy. It doesn't own any memory.
72 ASSERT(predefined_class_heap_stats_table_ == NULL);
73 ASSERT(class_heap_stats_table_ == NULL);
60 } 74 }
61 } 75 }
62 76
63 77
64 ClassTable::~ClassTable() { 78 void ClassTable::FreeOldTables() {
65 free(table_); 79 while (old_tables_->length() > 0) {
66 free(predefined_class_heap_stats_table_); 80 free(old_tables_->RemoveLast());
67 free(class_heap_stats_table_); 81 }
68 } 82 }
69 83
70 84
71 void ClassTable::Register(const Class& cls) { 85 void ClassTable::Register(const Class& cls) {
72 intptr_t index = cls.id(); 86 intptr_t index = cls.id();
73 if (index != kIllegalCid) { 87 if (index != kIllegalCid) {
74 ASSERT(index > 0); 88 ASSERT(index > 0);
75 ASSERT(index < kNumPredefinedCids); 89 ASSERT(index < kNumPredefinedCids);
76 ASSERT(table_[index] == 0); 90 ASSERT(table_[index] == 0);
77 ASSERT(index < capacity_); 91 ASSERT(index < capacity_);
78 table_[index] = cls.raw(); 92 table_[index] = cls.raw();
79 // Add the vtable for this predefined class into the static vtable registry 93 // Add the vtable for this predefined class into the static vtable registry
80 // if it has not been setup yet. 94 // if it has not been setup yet.
81 cpp_vtable cls_vtable = cls.handle_vtable(); 95 cpp_vtable cls_vtable = cls.handle_vtable();
82 cpp_vtable table_entry = Object::builtin_vtables_[index]; 96 cpp_vtable table_entry = Object::builtin_vtables_[index];
83 ASSERT((table_entry == 0) || (table_entry == cls_vtable)); 97 ASSERT((table_entry == 0) || (table_entry == cls_vtable));
84 if (table_entry == 0) { 98 if (table_entry == 0) {
85 Object::builtin_vtables_[index] = cls_vtable; 99 Object::builtin_vtables_[index] = cls_vtable;
86 } 100 }
87 } else { 101 } else {
88 if (top_ == capacity_) { 102 if (top_ == capacity_) {
89 // Grow the capacity of the class table. 103 // Grow the capacity of the class table.
104 // TODO(koda): Add ClassTable::Grow to share code.
90 intptr_t new_capacity = capacity_ + capacity_increment_; 105 intptr_t new_capacity = capacity_ + capacity_increment_;
91 RawClass** new_table = reinterpret_cast<RawClass**>( 106 RawClass** new_table = reinterpret_cast<RawClass**>(
92 realloc(table_, new_capacity * sizeof(RawClass*))); // NOLINT 107 malloc(new_capacity * sizeof(RawClass*))); // NOLINT
108 memmove(new_table, table_, capacity_ * sizeof(RawClass*));
93 ClassHeapStats* new_stats_table = reinterpret_cast<ClassHeapStats*>( 109 ClassHeapStats* new_stats_table = reinterpret_cast<ClassHeapStats*>(
94 realloc(class_heap_stats_table_, 110 realloc(class_heap_stats_table_,
95 new_capacity * sizeof(ClassHeapStats))); // NOLINT 111 new_capacity * sizeof(ClassHeapStats))); // NOLINT
96 for (intptr_t i = capacity_; i < new_capacity; i++) { 112 for (intptr_t i = capacity_; i < new_capacity; i++) {
97 new_table[i] = NULL; 113 new_table[i] = NULL;
98 new_stats_table[i].Initialize(); 114 new_stats_table[i].Initialize();
99 } 115 }
100 capacity_ = new_capacity; 116 capacity_ = new_capacity;
101 table_ = new_table; 117 old_tables_->Add(table_);
118 table_ = new_table; // TODO(koda): This should use atomics.
102 class_heap_stats_table_ = new_stats_table; 119 class_heap_stats_table_ = new_stats_table;
103 } 120 }
104 ASSERT(top_ < capacity_); 121 ASSERT(top_ < capacity_);
105 if (!Class::is_valid_id(top_)) { 122 if (!Class::is_valid_id(top_)) {
106 FATAL1("Fatal error in ClassTable::Register: invalid index %" Pd "\n", 123 FATAL1("Fatal error in ClassTable::Register: invalid index %" Pd "\n",
107 top_); 124 top_);
108 } 125 }
109 cls.set_id(top_); 126 cls.set_id(top_);
110 table_[top_] = cls.raw(); 127 table_[top_] = cls.raw();
111 top_++; // Increment next index. 128 top_++; // Increment next index.
112 } 129 }
113 } 130 }
114 131
115 132
116 void ClassTable::RegisterAt(intptr_t index, const Class& cls) { 133 void ClassTable::RegisterAt(intptr_t index, const Class& cls) {
117 ASSERT(index != kIllegalCid); 134 ASSERT(index != kIllegalCid);
118 ASSERT(index >= kNumPredefinedCids); 135 ASSERT(index >= kNumPredefinedCids);
119 if (index >= capacity_) { 136 if (index >= capacity_) {
120 // Grow the capacity of the class table. 137 // Grow the capacity of the class table.
138 // TODO(koda): Add ClassTable::Grow to share code.
121 intptr_t new_capacity = index + capacity_increment_; 139 intptr_t new_capacity = index + capacity_increment_;
122 if (!Class::is_valid_id(index) || new_capacity < capacity_) { 140 if (!Class::is_valid_id(index) || new_capacity < capacity_) {
123 FATAL1("Fatal error in ClassTable::Register: invalid index %" Pd "\n", 141 FATAL1("Fatal error in ClassTable::Register: invalid index %" Pd "\n",
124 index); 142 index);
125 } 143 }
126 RawClass** new_table = reinterpret_cast<RawClass**>( 144 RawClass** new_table = reinterpret_cast<RawClass**>(
127 realloc(table_, new_capacity * sizeof(RawClass*))); // NOLINT 145 malloc(new_capacity * sizeof(RawClass*))); // NOLINT
146 memmove(new_table, table_, capacity_ * sizeof(RawClass*));
128 ClassHeapStats* new_stats_table = reinterpret_cast<ClassHeapStats*>( 147 ClassHeapStats* new_stats_table = reinterpret_cast<ClassHeapStats*>(
129 realloc(class_heap_stats_table_, 148 realloc(class_heap_stats_table_,
130 new_capacity * sizeof(ClassHeapStats))); // NOLINT 149 new_capacity * sizeof(ClassHeapStats))); // NOLINT
131 for (intptr_t i = capacity_; i < new_capacity; i++) { 150 for (intptr_t i = capacity_; i < new_capacity; i++) {
132 new_table[i] = NULL; 151 new_table[i] = NULL;
133 new_stats_table[i].Initialize(); 152 new_stats_table[i].Initialize();
134 } 153 }
135 capacity_ = new_capacity; 154 capacity_ = new_capacity;
136 table_ = new_table; 155 old_tables_->Add(table_);
156 table_ = new_table; // TODO(koda): This should use atomics.
137 class_heap_stats_table_ = new_stats_table; 157 class_heap_stats_table_ = new_stats_table;
138 ASSERT(capacity_increment_ >= 1); 158 ASSERT(capacity_increment_ >= 1);
139 } 159 }
140 ASSERT(table_[index] == 0); 160 ASSERT(table_[index] == 0);
141 cls.set_id(index); 161 cls.set_id(index);
142 table_[index] = cls.raw(); 162 table_[index] = cls.raw();
143 if (index >= top_) { 163 if (index >= top_) {
144 top_ = index + 1; 164 top_ = index + 1;
145 } 165 }
146 } 166 }
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 472
453 void ClassTable::UpdateLiveNew(intptr_t cid, intptr_t size) { 473 void ClassTable::UpdateLiveNew(intptr_t cid, intptr_t size) {
454 ClassHeapStats* stats = PreliminaryStatsAt(cid); 474 ClassHeapStats* stats = PreliminaryStatsAt(cid);
455 ASSERT(stats != NULL); 475 ASSERT(stats != NULL);
456 ASSERT(size >= 0); 476 ASSERT(size >= 0);
457 stats->post_gc.AddNew(size); 477 stats->post_gc.AddNew(size);
458 } 478 }
459 479
460 480
461 } // namespace dart 481 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_table.h ('k') | runtime/vm/pages.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698