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

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

Issue 1287463003: Refactor skipped code functions interface. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: rm garbage file. Created 5 years, 3 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
« no previous file with comments | « no previous file | runtime/vm/object.h » ('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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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/gc_marker.h" 5 #include "vm/gc_marker.h"
6 6
7 #include <map> 7 #include <map>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 it->second->VisitPointers(visitor); 67 it->second->VisitPointers(visitor);
68 } 68 }
69 } 69 }
70 70
71 private: 71 private:
72 Map delay_set_; 72 Map delay_set_;
73 Mutex* mutex_; 73 Mutex* mutex_;
74 }; 74 };
75 75
76 76
77 class SkippedCodeFunctions : public ZoneAllocated {
78 public:
79 SkippedCodeFunctions() {}
80
81 void Add(RawFunction* func) {
82 skipped_code_functions_.Add(func);
83 }
84
85 void DetachCode() {
86 intptr_t unoptimized_code_count = 0;
87 intptr_t current_code_count = 0;
88 for (int i = 0; i < skipped_code_functions_.length(); i++) {
89 RawFunction* func = skipped_code_functions_[i];
90 RawCode* code = func->ptr()->instructions_->ptr()->code_;
91 if (!code->IsMarked()) {
92 // If the code wasn't strongly visited through other references
93 // after skipping the function's code pointer, then we disconnect the
94 // code from the function.
95 func->StorePointer(
96 &(func->ptr()->instructions_),
97 StubCode::LazyCompile_entry()->code()->ptr()->instructions_);
98 uword entry_point = StubCode::LazyCompile_entry()->EntryPoint();
99 func->ptr()->entry_point_ = entry_point;
100 if (FLAG_log_code_drop) {
101 // NOTE: This code runs while GC is in progress and runs within
102 // a NoHandleScope block. Hence it is not okay to use a regular Zone
103 // or Scope handle. We use a direct stack handle so the raw pointer in
104 // this handle is not traversed. The use of a handle is mainly to
105 // be able to reuse the handle based code and avoid having to add
106 // helper functions to the raw object interface.
107 String name;
108 name = func->ptr()->name_;
109 ISL_Print("Detaching code: %s\n", name.ToCString());
110 current_code_count++;
111 }
112 }
113
114 code = func->ptr()->unoptimized_code_;
115 if (!code->IsMarked()) {
116 // If the code wasn't strongly visited through other references
117 // after skipping the function's code pointer, then we disconnect the
118 // code from the function.
119 func->StorePointer(&(func->ptr()->unoptimized_code_), Code::null());
120 if (FLAG_log_code_drop) {
121 unoptimized_code_count++;
122 }
123 }
124 }
125 if (FLAG_log_code_drop) {
126 ISL_Print(" total detached current: %" Pd "\n", current_code_count);
127 ISL_Print(" total detached unoptimized: %" Pd "\n",
128 unoptimized_code_count);
129 }
130 // Clean up.
131 skipped_code_functions_.Clear();
132 }
133
134 private:
135 GrowableArray<RawFunction*> skipped_code_functions_;
136
137 DISALLOW_COPY_AND_ASSIGN(SkippedCodeFunctions);
138 };
139
140
77 class MarkingVisitor : public ObjectPointerVisitor { 141 class MarkingVisitor : public ObjectPointerVisitor {
78 public: 142 public:
79 MarkingVisitor(Isolate* isolate, 143 MarkingVisitor(Isolate* isolate,
80 Heap* heap, 144 Heap* heap,
81 PageSpace* page_space, 145 PageSpace* page_space,
82 MarkingStack* marking_stack, 146 MarkingStack* marking_stack,
83 DelaySet* delay_set, 147 DelaySet* delay_set,
84 bool visit_function_code) 148 SkippedCodeFunctions* skipped_code_functions)
85 : ObjectPointerVisitor(isolate), 149 : ObjectPointerVisitor(isolate),
86 thread_(Thread::Current()), 150 thread_(Thread::Current()),
87 heap_(heap), 151 heap_(heap),
88 vm_heap_(Dart::vm_isolate()->heap()), 152 vm_heap_(Dart::vm_isolate()->heap()),
89 class_table_(isolate->class_table()), 153 class_table_(isolate->class_table()),
90 page_space_(page_space), 154 page_space_(page_space),
91 work_list_(marking_stack), 155 work_list_(marking_stack),
92 delay_set_(delay_set), 156 delay_set_(delay_set),
93 visiting_old_object_(NULL), 157 visiting_old_object_(NULL),
94 visit_function_code_(visit_function_code), 158 skipped_code_functions_(skipped_code_functions),
95 marked_bytes_(0) { 159 marked_bytes_(0) {
96 ASSERT(heap_ != vm_heap_); 160 ASSERT(heap_ != vm_heap_);
97 ASSERT(thread_->isolate() == isolate); 161 ASSERT(thread_->isolate() == isolate);
98 } 162 }
99 163
100 uintptr_t marked_bytes() const { return marked_bytes_; } 164 uintptr_t marked_bytes() const { return marked_bytes_; }
101 165
102 // Returns true if some non-zero amount of work was performed. 166 // Returns true if some non-zero amount of work was performed.
103 bool DrainMarkingStack() { 167 bool DrainMarkingStack() {
104 RawObject* raw_obj = work_list_.Pop(); 168 RawObject* raw_obj = work_list_.Pop();
(...skipping 19 matching lines...) Expand all
124 VisitingOldObject(NULL); 188 VisitingOldObject(NULL);
125 return true; 189 return true;
126 } 190 }
127 191
128 void VisitPointers(RawObject** first, RawObject** last) { 192 void VisitPointers(RawObject** first, RawObject** last) {
129 for (RawObject** current = first; current <= last; current++) { 193 for (RawObject** current = first; current <= last; current++) {
130 MarkObject(*current, current); 194 MarkObject(*current, current);
131 } 195 }
132 } 196 }
133 197
134 bool visit_function_code() const { return visit_function_code_; } 198 bool visit_function_code() const {
199 return skipped_code_functions_ == NULL;
200 }
135 201
136 virtual MallocGrowableArray<RawFunction*>* skipped_code_functions() { 202 virtual void add_skipped_code_function(RawFunction* func) {
137 return &skipped_code_functions_; 203 ASSERT(!visit_function_code());
204 skipped_code_functions_->Add(func);
138 } 205 }
139 206
140 // Returns the mark bit. Sets the watch bit if unmarked. (The prior value of 207 // Returns the mark bit. Sets the watch bit if unmarked. (The prior value of
141 // the watched bit is returned in 'watched_before' for validation purposes.) 208 // the watched bit is returned in 'watched_before' for validation purposes.)
142 // TODO(koda): When synchronizing header bits, this goes in a single CAS loop. 209 // TODO(koda): When synchronizing header bits, this goes in a single CAS loop.
143 static bool EnsureWatchedIfWhite(RawObject* obj, bool* watched_before) { 210 static bool EnsureWatchedIfWhite(RawObject* obj, bool* watched_before) {
144 if (obj->IsMarked()) { 211 if (obj->IsMarked()) {
145 return false; 212 return false;
146 } 213 }
147 if (!obj->IsWatched()) { 214 if (!obj->IsWatched()) {
(...skipping 16 matching lines...) Expand all
164 bool new_key = delay_set_->Insert(raw_weak); 231 bool new_key = delay_set_->Insert(raw_weak);
165 ASSERT(new_key == !watched_before); 232 ASSERT(new_key == !watched_before);
166 } else { 233 } else {
167 // Key is gray or black. Make the weak property black. 234 // Key is gray or black. Make the weak property black.
168 raw_weak->VisitPointers(this); 235 raw_weak->VisitPointers(this);
169 } 236 }
170 } 237 }
171 238
172 // Called when all marking is complete. 239 // Called when all marking is complete.
173 void Finalize() { 240 void Finalize() {
174 if (!visit_function_code_) { 241 work_list_.Finalize();
175 DetachCode(); 242 if (skipped_code_functions_ != NULL) {
243 skipped_code_functions_->DetachCode();
176 } 244 }
177 work_list_.Finalize();
178 } 245 }
179 246
180 void VisitingOldObject(RawObject* obj) { 247 void VisitingOldObject(RawObject* obj) {
181 ASSERT((obj == NULL) || obj->IsOldObject()); 248 ASSERT((obj == NULL) || obj->IsOldObject());
182 visiting_old_object_ = obj; 249 visiting_old_object_ = obj;
183 } 250 }
184 251
185 private: 252 private:
186 class WorkList : public ValueObject { 253 class WorkList : public ValueObject {
187 public: 254 public:
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 } 343 }
277 if (RawObject::IsVariableSizeClassId(raw_obj->GetClassId())) { 344 if (RawObject::IsVariableSizeClassId(raw_obj->GetClassId())) {
278 class_table_->UpdateLiveOld(raw_obj->GetClassId(), raw_obj->Size()); 345 class_table_->UpdateLiveOld(raw_obj->GetClassId(), raw_obj->Size());
279 } else { 346 } else {
280 class_table_->UpdateLiveOld(raw_obj->GetClassId(), 0); 347 class_table_->UpdateLiveOld(raw_obj->GetClassId(), 0);
281 } 348 }
282 349
283 MarkAndPush(raw_obj); 350 MarkAndPush(raw_obj);
284 } 351 }
285 352
286 void DetachCode() {
287 intptr_t unoptimized_code_count = 0;
288 intptr_t current_code_count = 0;
289 for (int i = 0; i < skipped_code_functions_.length(); i++) {
290 RawFunction* func = skipped_code_functions_[i];
291 RawCode* code = func->ptr()->instructions_->ptr()->code_;
292 if (!code->IsMarked()) {
293 // If the code wasn't strongly visited through other references
294 // after skipping the function's code pointer, then we disconnect the
295 // code from the function.
296 func->StorePointer(
297 &(func->ptr()->instructions_),
298 StubCode::LazyCompile_entry()->code()->ptr()->instructions_);
299 uword entry_point = StubCode::LazyCompile_entry()->EntryPoint();
300 func->ptr()->entry_point_ = entry_point;
301
302 if (FLAG_log_code_drop) {
303 // NOTE: This code runs while GC is in progress and runs within
304 // a NoHandleScope block. Hence it is not okay to use a regular Zone
305 // or Scope handle. We use a direct stack handle so the raw pointer in
306 // this handle is not traversed. The use of a handle is mainly to
307 // be able to reuse the handle based code and avoid having to add
308 // helper functions to the raw object interface.
309 String name;
310 name = func->ptr()->name_;
311 ISL_Print("Detaching code: %s\n", name.ToCString());
312 current_code_count++;
313 }
314 }
315
316 code = func->ptr()->unoptimized_code_;
317 if (!code->IsMarked()) {
318 // If the code wasn't strongly visited through other references
319 // after skipping the function's code pointer, then we disconnect the
320 // code from the function.
321 func->StorePointer(&(func->ptr()->unoptimized_code_), Code::null());
322 if (FLAG_log_code_drop) {
323 unoptimized_code_count++;
324 }
325 }
326 }
327 if (FLAG_log_code_drop) {
328 ISL_Print(" total detached current: %" Pd "\n", current_code_count);
329 ISL_Print(" total detached unoptimized: %" Pd "\n",
330 unoptimized_code_count);
331 }
332 // Clean up.
333 skipped_code_functions_.Clear();
334 }
335
336 Thread* thread_; 353 Thread* thread_;
337 Heap* heap_; 354 Heap* heap_;
338 Heap* vm_heap_; 355 Heap* vm_heap_;
339 ClassTable* class_table_; 356 ClassTable* class_table_;
340 PageSpace* page_space_; 357 PageSpace* page_space_;
341 WorkList work_list_; 358 WorkList work_list_;
342 DelaySet* delay_set_; 359 DelaySet* delay_set_;
343 RawObject* visiting_old_object_; 360 RawObject* visiting_old_object_;
344 const bool visit_function_code_; 361 SkippedCodeFunctions* skipped_code_functions_;
345 MallocGrowableArray<RawFunction*> skipped_code_functions_;
346 uintptr_t marked_bytes_; 362 uintptr_t marked_bytes_;
347 363
348 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor); 364 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor);
349 }; 365 };
350 366
351 367
352 static bool IsUnreachable(const RawObject* raw_obj) { 368 static bool IsUnreachable(const RawObject* raw_obj) {
353 if (!raw_obj->IsHeapObject()) { 369 if (!raw_obj->IsHeapObject()) {
354 return false; 370 return false;
355 } 371 }
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 ObjectIdRing* ring = isolate->object_id_ring(); 538 ObjectIdRing* ring = isolate->object_id_ring();
523 ASSERT(ring != NULL); 539 ASSERT(ring != NULL);
524 ring->VisitPointers(&visitor); 540 ring->VisitPointers(&visitor);
525 } 541 }
526 542
527 543
528 void GCMarker::MarkObjects(Isolate* isolate, 544 void GCMarker::MarkObjects(Isolate* isolate,
529 PageSpace* page_space, 545 PageSpace* page_space,
530 bool invoke_api_callbacks, 546 bool invoke_api_callbacks,
531 bool collect_code) { 547 bool collect_code) {
532 const bool visit_function_code = !collect_code;
533 Prologue(isolate, invoke_api_callbacks); 548 Prologue(isolate, invoke_api_callbacks);
534 // The API prologue/epilogue may create/destroy zones, so we must not 549 // The API prologue/epilogue may create/destroy zones, so we must not
535 // depend on zone allocations surviving beyond the epilogue callback. 550 // depend on zone allocations surviving beyond the epilogue callback.
536 { 551 {
537 StackZone zone(Thread::Current()); 552 StackZone stack_zone(Thread::Current());
553 Zone* zone = stack_zone.GetZone();
538 MarkingStack marking_stack; 554 MarkingStack marking_stack;
539 DelaySet delay_set; 555 DelaySet delay_set;
556 SkippedCodeFunctions* skipped_code_functions =
557 collect_code ? new(zone) SkippedCodeFunctions() : NULL;
540 MarkingVisitor mark(isolate, heap_, page_space, &marking_stack, 558 MarkingVisitor mark(isolate, heap_, page_space, &marking_stack,
541 &delay_set, visit_function_code); 559 &delay_set, skipped_code_functions);
542 IterateRoots(isolate, &mark, !invoke_api_callbacks); 560 IterateRoots(isolate, &mark, !invoke_api_callbacks);
543 mark.DrainMarkingStack(); 561 mark.DrainMarkingStack();
544 IterateWeakReferences(isolate, &mark); 562 IterateWeakReferences(isolate, &mark);
545 MarkingWeakVisitor mark_weak; 563 MarkingWeakVisitor mark_weak;
546 IterateWeakRoots(isolate, &mark_weak, invoke_api_callbacks); 564 IterateWeakRoots(isolate, &mark_weak, invoke_api_callbacks);
547 // TODO(koda): Add hand-over callback and centralize skipped code functions. 565 // TODO(koda): Add hand-over callback.
548 marked_bytes_ = mark.marked_bytes(); 566 marked_bytes_ = mark.marked_bytes();
549 mark.Finalize(); 567 mark.Finalize();
550 delay_set.ClearReferences(); 568 delay_set.ClearReferences();
551 ProcessWeakTables(page_space); 569 ProcessWeakTables(page_space);
552 ProcessObjectIdTable(isolate); 570 ProcessObjectIdTable(isolate);
553 } 571 }
554 Epilogue(isolate, invoke_api_callbacks); 572 Epilogue(isolate, invoke_api_callbacks);
555 } 573 }
556 574
557 } // namespace dart 575 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698