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

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 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/gc_marker.h ('k') | runtime/vm/intermediate_language.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 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() const { 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 DetachCode();
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 DetachCode() {
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 strongly visited through other references
239 // after skipping the function's code pointer, then we disconnect the
240 // code from the function.
241 func->ptr()->code_ = Code::null();
242 func->ptr()->unoptimized_code_ = Code::null();
243 if (FLAG_log_code_drop) {
244 // NOTE: This code runs while GC is in progress and runs within
245 // a NoHandleScope block. Hence it is not okay to use a regular Zone
246 // or Scope handle. We use a direct stack handle so the raw pointer in
247 // this handle is not traversed. The use of a handle is mainly to
248 // be able to reuse the handle based code and avoid having to add
249 // helper functions to the raw object interface.
250 String name;
251 name = func->ptr()->name_;
252 OS::Print("Detaching code: %s\n", name.ToCString());
253 }
254 }
255 }
256 }
257
218 Heap* heap_; 258 Heap* heap_;
219 Heap* vm_heap_; 259 Heap* vm_heap_;
220 PageSpace* page_space_; 260 PageSpace* page_space_;
221 MarkingStack* marking_stack_; 261 MarkingStack* marking_stack_;
222 RawObject* visiting_old_object_; 262 RawObject* visiting_old_object_;
223 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; 263 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet;
224 DelaySet delay_set_; 264 DelaySet delay_set_;
265 const bool visit_function_code_;
266 GrowableArray<RawFunction*> skipped_code_functions_;
225 267
226 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor); 268 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor);
227 }; 269 };
228 270
229 271
230 bool IsUnreachable(const RawObject* raw_obj) { 272 bool IsUnreachable(const RawObject* raw_obj) {
231 if (!raw_obj->IsHeapObject()) { 273 if (!raw_obj->IsHeapObject()) {
232 return false; 274 return false;
233 } 275 }
234 if (raw_obj == Object::null()) { 276 if (raw_obj == Object::null()) {
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 void GCMarker::ProcessObjectIdTable(Isolate* isolate) { 464 void GCMarker::ProcessObjectIdTable(Isolate* isolate) {
423 ObjectIdRingClearPointerVisitor visitor(isolate); 465 ObjectIdRingClearPointerVisitor visitor(isolate);
424 ObjectIdRing* ring = isolate->object_id_ring(); 466 ObjectIdRing* ring = isolate->object_id_ring();
425 ASSERT(ring != NULL); 467 ASSERT(ring != NULL);
426 ring->VisitPointers(&visitor); 468 ring->VisitPointers(&visitor);
427 } 469 }
428 470
429 471
430 void GCMarker::MarkObjects(Isolate* isolate, 472 void GCMarker::MarkObjects(Isolate* isolate,
431 PageSpace* page_space, 473 PageSpace* page_space,
432 bool invoke_api_callbacks) { 474 bool invoke_api_callbacks,
475 bool collect_code) {
476 const bool visit_function_code = !collect_code;
433 MarkingStack marking_stack; 477 MarkingStack marking_stack;
434 Prologue(isolate, invoke_api_callbacks); 478 Prologue(isolate, invoke_api_callbacks);
435 MarkingVisitor mark(isolate, heap_, page_space, &marking_stack); 479 MarkingVisitor mark(
480 isolate, heap_, page_space, &marking_stack, visit_function_code);
436 IterateRoots(isolate, &mark, !invoke_api_callbacks); 481 IterateRoots(isolate, &mark, !invoke_api_callbacks);
437 DrainMarkingStack(isolate, &mark); 482 DrainMarkingStack(isolate, &mark);
438 IterateWeakReferences(isolate, &mark); 483 IterateWeakReferences(isolate, &mark);
439 MarkingWeakVisitor mark_weak; 484 MarkingWeakVisitor mark_weak;
440 IterateWeakRoots(isolate, &mark_weak, invoke_api_callbacks); 485 IterateWeakRoots(isolate, &mark_weak, invoke_api_callbacks);
441 mark.Finalize(); 486 mark.Finalize();
442 ProcessWeakTables(page_space); 487 ProcessWeakTables(page_space);
443 ProcessObjectIdTable(isolate); 488 ProcessObjectIdTable(isolate);
444 489
445
446 Epilogue(isolate, invoke_api_callbacks); 490 Epilogue(isolate, invoke_api_callbacks);
447 } 491 }
448 492
449 } // namespace dart 493 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/gc_marker.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698