gc.cpp 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. #include "pocketpy/gc.h"
  2. namespace pkpy{
  3. int ManagedHeap::sweep(){
  4. std::vector<PyObject*> alive;
  5. for(PyObject* obj: gen){
  6. if(obj->gc_marked){
  7. obj->gc_marked = false;
  8. alive.push_back(obj);
  9. }else{
  10. #if PK_DEBUG_GC_STATS
  11. deleted[obj->type] += 1;
  12. #endif
  13. if(_gc_on_delete) _gc_on_delete(vm, obj);
  14. _delete(obj);
  15. }
  16. }
  17. // clear _no_gc marked flag
  18. for(PyObject* obj: _no_gc) obj->gc_marked = false;
  19. int freed = gen.size() - alive.size();
  20. #if PK_DEBUG_GC_STATS
  21. for(auto& [type, count]: deleted){
  22. std::cout << "GC: " << _type_name(vm, type).sv() << "=" << count << std::endl;
  23. }
  24. std::cout << "GC: " << alive.size() << "/" << gen.size() << " (" << freed << " freed)" << std::endl;
  25. deleted.clear();
  26. #endif
  27. gen.clear();
  28. gen.swap(alive);
  29. // clean up pools
  30. pools_shrink_to_fit();
  31. return freed;
  32. }
  33. void ManagedHeap::_auto_collect(){
  34. #if !PK_DEBUG_NO_AUTO_GC
  35. if(_gc_lock_counter > 0) return;
  36. gc_counter = 0;
  37. collect();
  38. gc_threshold = gen.size() * 2;
  39. if(gc_threshold < PK_GC_MIN_THRESHOLD) gc_threshold = PK_GC_MIN_THRESHOLD;
  40. #endif
  41. }
  42. int ManagedHeap::collect(){
  43. PK_ASSERT(_gc_lock_counter == 0)
  44. mark();
  45. int freed = sweep();
  46. return freed;
  47. }
  48. } // namespace pkpy