Chromium Code Reviews| Index: runtime/vm/gc_marker.cc |
| =================================================================== |
| --- runtime/vm/gc_marker.cc (revision 30197) |
| +++ runtime/vm/gc_marker.cc (working copy) |
| @@ -123,13 +123,15 @@ |
| MarkingVisitor(Isolate* isolate, |
| Heap* heap, |
| PageSpace* page_space, |
| - MarkingStack* marking_stack) |
| + MarkingStack* marking_stack, |
| + bool visit_function_code) |
| : ObjectPointerVisitor(isolate), |
| heap_(heap), |
| vm_heap_(Dart::vm_isolate()->heap()), |
| page_space_(page_space), |
| marking_stack_(marking_stack), |
| - visiting_old_object_(NULL) { |
| + visiting_old_object_(NULL), |
| + visit_function_code_(visit_function_code) { |
| ASSERT(heap_ != vm_heap_); |
| } |
| @@ -141,6 +143,12 @@ |
| } |
| } |
| + bool visit_function_code() { return visit_function_code_; } |
| + |
| + GrowableArray<RawFunction*>* skipped_code_functions() { |
| + return &skipped_code_functions_; |
| + } |
| + |
| void DelayWeakProperty(RawWeakProperty* raw_weak) { |
| RawObject* raw_key = raw_weak->ptr()->key_; |
| DelaySet::iterator it = delay_set_.find(raw_key); |
| @@ -158,6 +166,9 @@ |
| for (; it != delay_set_.end(); ++it) { |
| WeakProperty::Clear(it->second); |
| } |
| + if (!visit_function_code_) { |
| + TryDetachingCode(); |
| + } |
| } |
| void VisitingOldObject(RawObject* obj) { |
| @@ -195,10 +206,14 @@ |
| void MarkObject(RawObject* raw_obj, RawObject** p) { |
| // Fast exit if the raw object is a Smi. |
| - if (!raw_obj->IsHeapObject()) return; |
| + if (!raw_obj->IsHeapObject()) { |
| + return; |
| + } |
| // Fast exit if the raw object is marked. |
| - if (raw_obj->IsMarked()) return; |
| + if (raw_obj->IsMarked()) { |
| + return; |
| + } |
| // Skip over new objects, but verify consistency of heap while at it. |
| if (raw_obj->IsNewObject()) { |
| @@ -215,6 +230,25 @@ |
| MarkAndPush(raw_obj); |
| } |
| + void TryDetachingCode() { |
| + for (int i = 0; i < skipped_code_functions_.length(); i++) { |
| + RawFunction* func = skipped_code_functions_[i]; |
| + RawCode* code = func->ptr()->code_; |
| + if (!code->IsMarked()) { |
| + // If the code wasn't marked even after skipping the function's code |
| + // pointer, then we disconnect the code from the function. It will |
| + // be swept. |
| + func->ptr()->code_ = Code::null(); |
| + func->ptr()->unoptimized_code_ = Code::null(); |
| + if (FLAG_log_code_drop) { |
| + 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.
|
| + name = func->ptr()->name_; |
| + OS::Print("Detaching code: %s\n", name.ToCString()); |
| + } |
| + } |
| + } |
| + } |
| + |
| Heap* heap_; |
| Heap* vm_heap_; |
| PageSpace* page_space_; |
| @@ -222,6 +256,8 @@ |
| RawObject* visiting_old_object_; |
| typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; |
| DelaySet delay_set_; |
| + bool visit_function_code_; |
| + GrowableArray<RawFunction*> skipped_code_functions_; |
| DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor); |
| }; |
| @@ -429,10 +465,13 @@ |
| void GCMarker::MarkObjects(Isolate* isolate, |
| PageSpace* page_space, |
| - bool invoke_api_callbacks) { |
| + bool invoke_api_callbacks, |
| + bool try_collecting_code) { |
| + bool visit_function_code = !try_collecting_code; |
| MarkingStack marking_stack; |
| Prologue(isolate, invoke_api_callbacks); |
| - MarkingVisitor mark(isolate, heap_, page_space, &marking_stack); |
| + MarkingVisitor mark( |
| + isolate, heap_, page_space, &marking_stack, visit_function_code); |
| IterateRoots(isolate, &mark, !invoke_api_callbacks); |
| DrainMarkingStack(isolate, &mark); |
| IterateWeakReferences(isolate, &mark); |
| @@ -442,7 +481,6 @@ |
| ProcessWeakTables(page_space); |
| ProcessObjectIdTable(isolate); |
| - |
| Epilogue(isolate, invoke_api_callbacks); |
| } |