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

Side by Side Diff: runtime/vm/pages.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/pages.h" 5 #include "vm/pages.h"
6 6
7 #include "platform/assert.h" 7 #include "platform/assert.h"
8 #include "vm/compiler_stats.h" 8 #include "vm/compiler_stats.h"
9 #include "vm/gc_marker.h" 9 #include "vm/gc_marker.h"
10 #include "vm/gc_sweeper.h" 10 #include "vm/gc_sweeper.h"
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 page = page->next(); 377 page = page->next();
378 } 378 }
379 page = large_pages_; 379 page = large_pages_;
380 while (page != NULL) { 380 while (page != NULL) {
381 page->WriteProtect(read_only); 381 page->WriteProtect(read_only);
382 page = page->next(); 382 page = page->next();
383 } 383 }
384 } 384 }
385 385
386 386
387 class CodeDetacherVisitor : public ObjectVisitor { 387 bool PageSpace::ShouldTryCollectingCode() {
388 public:
389 explicit CodeDetacherVisitor(Isolate* isolate) : ObjectVisitor(isolate) { }
390
391 virtual void VisitObject(RawObject* obj);
392
393 private:
394 static bool MayDetachCode(const Function& fn);
395 DISALLOW_COPY_AND_ASSIGN(CodeDetacherVisitor);
396 };
397
398
399 bool CodeDetacherVisitor::MayDetachCode(const Function& fn) {
400 return fn.HasCode() && // Not already detached.
401 !fn.HasOptimizedCode() &&
402 !fn.HasBreakpoint() &&
403 (fn.usage_counter() > 0);
404 }
405
406
407 void CodeDetacherVisitor::VisitObject(RawObject* raw_obj) {
408 Isolate* isolate = Isolate::Current();
409 HANDLESCOPE(isolate);
410 const Object& obj = Object::Handle(raw_obj);
411 if (obj.GetClassId() == kFunctionCid) {
412 const Function& fn = Function::Cast(obj);
413 if (CodeDetacherVisitor::MayDetachCode(fn)) {
414 fn.set_usage_counter(fn.usage_counter() / 2);
415 if (fn.usage_counter() == 0) {
416 if (FLAG_log_code_drop) {
417 const String& name = String::Handle(fn.name());
418 OS::Print("Detaching code for function %s\n", name.ToCString());
419 }
420 fn.DetachCode();
421 }
422 }
423 }
424 }
425
426
427 void PageSpace::TryDetachingCode() {
428 // Try to collect code if enough time has passed since the last attempt. 388 // Try to collect code if enough time has passed since the last attempt.
429 const int64_t start = OS::GetCurrentTimeMicros(); 389 const int64_t start = OS::GetCurrentTimeMicros();
430 const int64_t last_code_collection_in_us = 390 const int64_t last_code_collection_in_us =
431 page_space_controller_.last_code_collection_in_us(); 391 page_space_controller_.last_code_collection_in_us();
392
432 if ((start - last_code_collection_in_us) > 393 if ((start - last_code_collection_in_us) >
433 FLAG_code_collection_interval_in_us) { 394 FLAG_code_collection_interval_in_us) {
434 if (FLAG_log_code_drop) { 395 if (FLAG_log_code_drop) {
435 OS::Print("Trying to detach code.\n"); 396 OS::Print("Trying to detach code.\n");
436 } 397 }
437 Isolate* isolate = Isolate::Current();
438 CodeDetacherVisitor code_detacher(isolate);
439 heap_->IterateObjects(&code_detacher);
440 page_space_controller_.set_last_code_collection_in_us(start); 398 page_space_controller_.set_last_code_collection_in_us(start);
399 return true;
441 } 400 }
401 return false;
442 } 402 }
443 403
444 404
445 void PageSpace::MarkSweep(bool invoke_api_callbacks) { 405 void PageSpace::MarkSweep(bool invoke_api_callbacks) {
446 // MarkSweep is not reentrant. Make sure that is the case. 406 // MarkSweep is not reentrant. Make sure that is the case.
447 ASSERT(!sweeping_); 407 ASSERT(!sweeping_);
448 sweeping_ = true; 408 sweeping_ = true;
449 Isolate* isolate = Isolate::Current(); 409 Isolate* isolate = Isolate::Current();
450 if (FLAG_collect_code) {
451 TryDetachingCode();
452 }
453 410
454 NoHandleScope no_handles(isolate); 411 NoHandleScope no_handles(isolate);
455 412
456 if (FLAG_print_free_list_before_gc) { 413 if (FLAG_print_free_list_before_gc) {
457 OS::Print("Data Freelist (before GC):\n"); 414 OS::Print("Data Freelist (before GC):\n");
458 freelist_[HeapPage::kData].Print(); 415 freelist_[HeapPage::kData].Print();
459 OS::Print("Executable Freelist (before GC):\n"); 416 OS::Print("Executable Freelist (before GC):\n");
460 freelist_[HeapPage::kExecutable].Print(); 417 freelist_[HeapPage::kExecutable].Print();
461 } 418 }
462 419
463 if (FLAG_verify_before_gc) { 420 if (FLAG_verify_before_gc) {
464 OS::PrintErr("Verifying before MarkSweep..."); 421 OS::PrintErr("Verifying before MarkSweep...");
465 heap_->Verify(); 422 heap_->Verify();
466 OS::PrintErr(" done.\n"); 423 OS::PrintErr(" done.\n");
467 } 424 }
468 425
469 const int64_t start = OS::GetCurrentTimeMicros(); 426 const int64_t start = OS::GetCurrentTimeMicros();
470 427
471 // Mark all reachable old-gen objects. 428 // Mark all reachable old-gen objects.
429 bool try_collecting_code = FLAG_collect_code && ShouldTryCollectingCode();
472 GCMarker marker(heap_); 430 GCMarker marker(heap_);
473 marker.MarkObjects(isolate, this, invoke_api_callbacks); 431 marker.MarkObjects(isolate, this, invoke_api_callbacks, try_collecting_code);
474 432
475 int64_t mid1 = OS::GetCurrentTimeMicros(); 433 int64_t mid1 = OS::GetCurrentTimeMicros();
476 434
477 // Reset the bump allocation page to unused. 435 // Reset the bump allocation page to unused.
478 // Reset the freelists and setup sweeping. 436 // Reset the freelists and setup sweeping.
479 freelist_[HeapPage::kData].Reset(); 437 freelist_[HeapPage::kData].Reset();
480 freelist_[HeapPage::kExecutable].Reset(); 438 freelist_[HeapPage::kExecutable].Reset();
481 439
482 int64_t mid2 = OS::GetCurrentTimeMicros(); 440 int64_t mid2 = OS::GetCurrentTimeMicros();
483 441
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 return 0; 613 return 0;
656 } else { 614 } else {
657 ASSERT(total_time >= gc_time); 615 ASSERT(total_time >= gc_time);
658 int result= static_cast<int>((static_cast<double>(gc_time) / 616 int result= static_cast<int>((static_cast<double>(gc_time) /
659 static_cast<double>(total_time)) * 100); 617 static_cast<double>(total_time)) * 100);
660 return result; 618 return result;
661 } 619 }
662 } 620 }
663 621
664 } // namespace dart 622 } // namespace dart
OLDNEW
« runtime/vm/gc_marker.cc ('K') | « runtime/vm/pages.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698