OLD | NEW |
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 |
11 #include "vm/allocation.h" | 11 #include "vm/allocation.h" |
12 #include "vm/dart_api_state.h" | 12 #include "vm/dart_api_state.h" |
13 #include "vm/isolate.h" | 13 #include "vm/isolate.h" |
| 14 #include "vm/log.h" |
14 #include "vm/pages.h" | 15 #include "vm/pages.h" |
15 #include "vm/raw_object.h" | 16 #include "vm/raw_object.h" |
16 #include "vm/stack_frame.h" | 17 #include "vm/stack_frame.h" |
17 #include "vm/visitor.h" | 18 #include "vm/visitor.h" |
18 #include "vm/object_id_ring.h" | 19 #include "vm/object_id_ring.h" |
19 | 20 |
20 namespace dart { | 21 namespace dart { |
21 | 22 |
22 // A simple chunked marking stack. | 23 // A simple chunked marking stack. |
23 class MarkingStack : public ValueObject { | 24 class MarkingStack : public ValueObject { |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 MarkingStack* marking_stack() const { return marking_stack_; } | 141 MarkingStack* marking_stack() const { return marking_stack_; } |
141 | 142 |
142 void VisitPointers(RawObject** first, RawObject** last) { | 143 void VisitPointers(RawObject** first, RawObject** last) { |
143 for (RawObject** current = first; current <= last; current++) { | 144 for (RawObject** current = first; current <= last; current++) { |
144 MarkObject(*current, current); | 145 MarkObject(*current, current); |
145 } | 146 } |
146 } | 147 } |
147 | 148 |
148 bool visit_function_code() const { return visit_function_code_; } | 149 bool visit_function_code() const { return visit_function_code_; } |
149 | 150 |
150 GrowableArray<RawFunction*>* skipped_code_functions() { | 151 virtual GrowableArray<RawFunction*>* skipped_code_functions() { |
151 return &skipped_code_functions_; | 152 return &skipped_code_functions_; |
152 } | 153 } |
153 | 154 |
154 void DelayWeakProperty(RawWeakProperty* raw_weak) { | 155 void DelayWeakProperty(RawWeakProperty* raw_weak) { |
155 RawObject* raw_key = raw_weak->ptr()->key_; | 156 RawObject* raw_key = raw_weak->ptr()->key_; |
156 DelaySet::iterator it = delay_set_.find(raw_key); | 157 DelaySet::iterator it = delay_set_.find(raw_key); |
157 if (it != delay_set_.end()) { | 158 if (it != delay_set_.end()) { |
158 ASSERT(raw_key->IsWatched()); | 159 ASSERT(raw_key->IsWatched()); |
159 } else { | 160 } else { |
160 ASSERT(!raw_key->IsWatched()); | 161 ASSERT(!raw_key->IsWatched()); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 if (RawObject::IsVariableSizeClassId(raw_obj->GetClassId())) { | 233 if (RawObject::IsVariableSizeClassId(raw_obj->GetClassId())) { |
233 class_table_->UpdateLiveOld(raw_obj->GetClassId(), raw_obj->Size()); | 234 class_table_->UpdateLiveOld(raw_obj->GetClassId(), raw_obj->Size()); |
234 } else { | 235 } else { |
235 class_table_->UpdateLiveOld(raw_obj->GetClassId(), 0); | 236 class_table_->UpdateLiveOld(raw_obj->GetClassId(), 0); |
236 } | 237 } |
237 | 238 |
238 MarkAndPush(raw_obj); | 239 MarkAndPush(raw_obj); |
239 } | 240 } |
240 | 241 |
241 void DetachCode() { | 242 void DetachCode() { |
| 243 intptr_t unoptimized_code_count = 0; |
| 244 intptr_t current_code_count = 0; |
242 for (int i = 0; i < skipped_code_functions_.length(); i++) { | 245 for (int i = 0; i < skipped_code_functions_.length(); i++) { |
243 RawFunction* func = skipped_code_functions_[i]; | 246 RawFunction* func = skipped_code_functions_[i]; |
244 RawCode* code = func->ptr()->instructions_->ptr()->code_; | 247 RawCode* code = func->ptr()->instructions_->ptr()->code_; |
245 if (!code->IsMarked()) { | 248 if (!code->IsMarked()) { |
246 // If the code wasn't strongly visited through other references | 249 // If the code wasn't strongly visited through other references |
247 // after skipping the function's code pointer, then we disconnect the | 250 // after skipping the function's code pointer, then we disconnect the |
248 // code from the function. | 251 // code from the function. |
249 StubCode* stub_code = isolate()->stub_code(); | 252 StubCode* stub_code = isolate()->stub_code(); |
250 func->StorePointer( | 253 func->StorePointer( |
251 &(func->ptr()->instructions_), | 254 &(func->ptr()->instructions_), |
252 stub_code->LazyCompile_entry()->code()->ptr()->instructions_); | 255 stub_code->LazyCompile_entry()->code()->ptr()->instructions_); |
253 func->StorePointer(&(func->ptr()->unoptimized_code_), Code::null()); | |
254 if (FLAG_log_code_drop) { | 256 if (FLAG_log_code_drop) { |
255 // NOTE: This code runs while GC is in progress and runs within | 257 // NOTE: This code runs while GC is in progress and runs within |
256 // a NoHandleScope block. Hence it is not okay to use a regular Zone | 258 // a NoHandleScope block. Hence it is not okay to use a regular Zone |
257 // or Scope handle. We use a direct stack handle so the raw pointer in | 259 // or Scope handle. We use a direct stack handle so the raw pointer in |
258 // this handle is not traversed. The use of a handle is mainly to | 260 // this handle is not traversed. The use of a handle is mainly to |
259 // be able to reuse the handle based code and avoid having to add | 261 // be able to reuse the handle based code and avoid having to add |
260 // helper functions to the raw object interface. | 262 // helper functions to the raw object interface. |
261 String name; | 263 String name; |
262 name = func->ptr()->name_; | 264 name = func->ptr()->name_; |
263 OS::Print("Detaching code: %s\n", name.ToCString()); | 265 ISL_Print("Detaching code: %s\n", name.ToCString()); |
| 266 current_code_count++; |
264 } | 267 } |
265 } | 268 } |
| 269 |
| 270 code = func->ptr()->unoptimized_code_; |
| 271 if (!code->IsMarked()) { |
| 272 // If the code wasn't strongly visited through other references |
| 273 // after skipping the function's code pointer, then we disconnect the |
| 274 // code from the function. |
| 275 func->StorePointer(&(func->ptr()->unoptimized_code_), Code::null()); |
| 276 if (FLAG_log_code_drop) { |
| 277 unoptimized_code_count++; |
| 278 } |
| 279 } |
| 280 } |
| 281 if (FLAG_log_code_drop) { |
| 282 ISL_Print(" total detached current: %" Pd "\n", current_code_count); |
| 283 ISL_Print(" total detached unoptimized: %" Pd "\n", |
| 284 unoptimized_code_count); |
266 } | 285 } |
267 } | 286 } |
268 | 287 |
269 Heap* heap_; | 288 Heap* heap_; |
270 Heap* vm_heap_; | 289 Heap* vm_heap_; |
271 ClassTable* class_table_; | 290 ClassTable* class_table_; |
272 PageSpace* page_space_; | 291 PageSpace* page_space_; |
273 MarkingStack* marking_stack_; | 292 MarkingStack* marking_stack_; |
274 RawObject* visiting_old_object_; | 293 RawObject* visiting_old_object_; |
275 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; | 294 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 MarkingWeakVisitor mark_weak; | 534 MarkingWeakVisitor mark_weak; |
516 IterateWeakRoots(isolate, &mark_weak, invoke_api_callbacks); | 535 IterateWeakRoots(isolate, &mark_weak, invoke_api_callbacks); |
517 mark.Finalize(); | 536 mark.Finalize(); |
518 ProcessWeakTables(page_space); | 537 ProcessWeakTables(page_space); |
519 ProcessObjectIdTable(isolate); | 538 ProcessObjectIdTable(isolate); |
520 } | 539 } |
521 Epilogue(isolate, invoke_api_callbacks); | 540 Epilogue(isolate, invoke_api_callbacks); |
522 } | 541 } |
523 | 542 |
524 } // namespace dart | 543 } // namespace dart |
OLD | NEW |