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

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

Issue 70183010: Fixes a couple problems with GC of unoptimized code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month 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
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 9
10 #include "vm/allocation.h" 10 #include "vm/allocation.h"
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 116
117 DISALLOW_COPY_AND_ASSIGN(MarkingStack); 117 DISALLOW_COPY_AND_ASSIGN(MarkingStack);
118 }; 118 };
119 119
120 120
121 class MarkingVisitor : public ObjectPointerVisitor { 121 class MarkingVisitor : public ObjectPointerVisitor {
122 public: 122 public:
123 MarkingVisitor(Isolate* isolate, 123 MarkingVisitor(Isolate* isolate,
124 Heap* heap, 124 Heap* heap,
125 PageSpace* page_space, 125 PageSpace* page_space,
126 MarkingStack* marking_stack) 126 MarkingStack* marking_stack,
127 bool visit_function_code)
127 : ObjectPointerVisitor(isolate), 128 : ObjectPointerVisitor(isolate),
128 heap_(heap), 129 heap_(heap),
129 vm_heap_(Dart::vm_isolate()->heap()), 130 vm_heap_(Dart::vm_isolate()->heap()),
130 page_space_(page_space), 131 page_space_(page_space),
131 marking_stack_(marking_stack), 132 marking_stack_(marking_stack),
132 visiting_old_object_(NULL) { 133 visiting_old_object_(NULL),
134 visit_function_code_(visit_function_code) {
133 ASSERT(heap_ != vm_heap_); 135 ASSERT(heap_ != vm_heap_);
134 } 136 }
135 137
136 MarkingStack* marking_stack() const { return marking_stack_; } 138 MarkingStack* marking_stack() const { return marking_stack_; }
137 139
138 void VisitPointers(RawObject** first, RawObject** last) { 140 void VisitPointers(RawObject** first, RawObject** last) {
139 for (RawObject** current = first; current <= last; current++) { 141 for (RawObject** current = first; current <= last; current++) {
140 MarkObject(*current, current); 142 MarkObject(*current, current);
141 } 143 }
142 } 144 }
143 145
146 bool visit_function_code() { return visit_function_code_; }
147
148 GrowableArray<RawFunction*>* skipped_code_functions() {
149 return &skipped_code_functions_;
150 }
151
144 void DelayWeakProperty(RawWeakProperty* raw_weak) { 152 void DelayWeakProperty(RawWeakProperty* raw_weak) {
145 RawObject* raw_key = raw_weak->ptr()->key_; 153 RawObject* raw_key = raw_weak->ptr()->key_;
146 DelaySet::iterator it = delay_set_.find(raw_key); 154 DelaySet::iterator it = delay_set_.find(raw_key);
147 if (it != delay_set_.end()) { 155 if (it != delay_set_.end()) {
148 ASSERT(raw_key->IsWatched()); 156 ASSERT(raw_key->IsWatched());
149 } else { 157 } else {
150 ASSERT(!raw_key->IsWatched()); 158 ASSERT(!raw_key->IsWatched());
151 raw_key->SetWatchedBit(); 159 raw_key->SetWatchedBit();
152 } 160 }
153 delay_set_.insert(std::make_pair(raw_key, raw_weak)); 161 delay_set_.insert(std::make_pair(raw_key, raw_weak));
154 } 162 }
155 163
156 void Finalize() { 164 void Finalize() {
157 DelaySet::iterator it = delay_set_.begin(); 165 DelaySet::iterator it = delay_set_.begin();
158 for (; it != delay_set_.end(); ++it) { 166 for (; it != delay_set_.end(); ++it) {
159 WeakProperty::Clear(it->second); 167 WeakProperty::Clear(it->second);
160 } 168 }
169 if (!visit_function_code_) {
170 TryDetachingCode();
171 }
161 } 172 }
162 173
163 void VisitingOldObject(RawObject* obj) { 174 void VisitingOldObject(RawObject* obj) {
164 ASSERT((obj == NULL) || obj->IsOldObject()); 175 ASSERT((obj == NULL) || obj->IsOldObject());
165 visiting_old_object_ = obj; 176 visiting_old_object_ = obj;
166 } 177 }
167 178
168 private: 179 private:
169 void MarkAndPush(RawObject* raw_obj) { 180 void MarkAndPush(RawObject* raw_obj) {
170 ASSERT(raw_obj->IsHeapObject()); 181 ASSERT(raw_obj->IsHeapObject());
(...skipping 17 matching lines...) Expand all
188 raw_obj->ClearWatchedBit(); 199 raw_obj->ClearWatchedBit();
189 } 200 }
190 marking_stack_->Push(raw_obj); 201 marking_stack_->Push(raw_obj);
191 202
192 // TODO(iposva): Should we mark the classes early? 203 // TODO(iposva): Should we mark the classes early?
193 MarkObject(raw_class, NULL); 204 MarkObject(raw_class, NULL);
194 } 205 }
195 206
196 void MarkObject(RawObject* raw_obj, RawObject** p) { 207 void MarkObject(RawObject* raw_obj, RawObject** p) {
197 // Fast exit if the raw object is a Smi. 208 // Fast exit if the raw object is a Smi.
198 if (!raw_obj->IsHeapObject()) return; 209 if (!raw_obj->IsHeapObject()) {
210 return;
211 }
199 212
200 // Fast exit if the raw object is marked. 213 // Fast exit if the raw object is marked.
201 if (raw_obj->IsMarked()) return; 214 if (raw_obj->IsMarked()) {
215 return;
216 }
202 217
203 // Skip over new objects, but verify consistency of heap while at it. 218 // Skip over new objects, but verify consistency of heap while at it.
204 if (raw_obj->IsNewObject()) { 219 if (raw_obj->IsNewObject()) {
205 // TODO(iposva): Add consistency check. 220 // TODO(iposva): Add consistency check.
206 if ((visiting_old_object_ != NULL) && 221 if ((visiting_old_object_ != NULL) &&
207 !visiting_old_object_->IsRemembered()) { 222 !visiting_old_object_->IsRemembered()) {
208 ASSERT(p != NULL); 223 ASSERT(p != NULL);
209 visiting_old_object_->SetRememberedBit(); 224 visiting_old_object_->SetRememberedBit();
210 isolate()->store_buffer()->AddObjectGC(visiting_old_object_); 225 isolate()->store_buffer()->AddObjectGC(visiting_old_object_);
211 } 226 }
212 return; 227 return;
213 } 228 }
214 229
215 MarkAndPush(raw_obj); 230 MarkAndPush(raw_obj);
216 } 231 }
217 232
233 void TryDetachingCode() {
234 for (int i = 0; i < skipped_code_functions_.length(); i++) {
235 RawFunction* func = skipped_code_functions_[i];
236 RawCode* code = func->ptr()->code_;
237 if (!code->IsMarked()) {
238 // If the code wasn't marked even after skipping the function's code
239 // pointer, then we disconnect the code from the function. It will
240 // be swept.
241 func->ptr()->code_ = Code::null();
242 func->ptr()->unoptimized_code_ = Code::null();
243 if (FLAG_log_code_drop) {
244 String name;
Ivan Posva 2013/11/16 00:06:21 This needs about 10 lines of comments why this is
zra 2013/11/18 18:54:33 Done.
245 name = func->ptr()->name_;
246 OS::Print("Detaching code: %s\n", name.ToCString());
247 }
248 }
249 }
250 }
251
218 Heap* heap_; 252 Heap* heap_;
219 Heap* vm_heap_; 253 Heap* vm_heap_;
220 PageSpace* page_space_; 254 PageSpace* page_space_;
221 MarkingStack* marking_stack_; 255 MarkingStack* marking_stack_;
222 RawObject* visiting_old_object_; 256 RawObject* visiting_old_object_;
223 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; 257 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet;
224 DelaySet delay_set_; 258 DelaySet delay_set_;
259 bool visit_function_code_;
260 GrowableArray<RawFunction*> skipped_code_functions_;
225 261
226 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor); 262 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor);
227 }; 263 };
228 264
229 265
230 bool IsUnreachable(const RawObject* raw_obj) { 266 bool IsUnreachable(const RawObject* raw_obj) {
231 if (!raw_obj->IsHeapObject()) { 267 if (!raw_obj->IsHeapObject()) {
232 return false; 268 return false;
233 } 269 }
234 if (raw_obj == Object::null()) { 270 if (raw_obj == Object::null()) {
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 void GCMarker::ProcessObjectIdTable(Isolate* isolate) { 458 void GCMarker::ProcessObjectIdTable(Isolate* isolate) {
423 ObjectIdRingClearPointerVisitor visitor(isolate); 459 ObjectIdRingClearPointerVisitor visitor(isolate);
424 ObjectIdRing* ring = isolate->object_id_ring(); 460 ObjectIdRing* ring = isolate->object_id_ring();
425 ASSERT(ring != NULL); 461 ASSERT(ring != NULL);
426 ring->VisitPointers(&visitor); 462 ring->VisitPointers(&visitor);
427 } 463 }
428 464
429 465
430 void GCMarker::MarkObjects(Isolate* isolate, 466 void GCMarker::MarkObjects(Isolate* isolate,
431 PageSpace* page_space, 467 PageSpace* page_space,
432 bool invoke_api_callbacks) { 468 bool invoke_api_callbacks,
469 bool try_collecting_code) {
470 bool visit_function_code = !try_collecting_code;
433 MarkingStack marking_stack; 471 MarkingStack marking_stack;
434 Prologue(isolate, invoke_api_callbacks); 472 Prologue(isolate, invoke_api_callbacks);
435 MarkingVisitor mark(isolate, heap_, page_space, &marking_stack); 473 MarkingVisitor mark(
474 isolate, heap_, page_space, &marking_stack, visit_function_code);
436 IterateRoots(isolate, &mark, !invoke_api_callbacks); 475 IterateRoots(isolate, &mark, !invoke_api_callbacks);
437 DrainMarkingStack(isolate, &mark); 476 DrainMarkingStack(isolate, &mark);
438 IterateWeakReferences(isolate, &mark); 477 IterateWeakReferences(isolate, &mark);
439 MarkingWeakVisitor mark_weak; 478 MarkingWeakVisitor mark_weak;
440 IterateWeakRoots(isolate, &mark_weak, invoke_api_callbacks); 479 IterateWeakRoots(isolate, &mark_weak, invoke_api_callbacks);
441 mark.Finalize(); 480 mark.Finalize();
442 ProcessWeakTables(page_space); 481 ProcessWeakTables(page_space);
443 ProcessObjectIdTable(isolate); 482 ProcessObjectIdTable(isolate);
444 483
445
446 Epilogue(isolate, invoke_api_callbacks); 484 Epilogue(isolate, invoke_api_callbacks);
447 } 485 }
448 486
449 } // namespace dart 487 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698