gc.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  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. obj->~PyObject();
  15. pool64_dealloc(obj);
  16. }
  17. }
  18. // clear _no_gc marked flag
  19. for(PyObject* obj: _no_gc) obj->gc.marked = false;
  20. int freed = gen.size() - alive.size();
  21. // std::cout << "GC: " << alive.size() << "/" << gen.size() << " (" << freed << " freed)" << std::endl;
  22. gen.clear();
  23. gen.swap(alive);
  24. // clean up pools
  25. pools_shrink_to_fit();
  26. return freed;
  27. }
  28. void ManagedHeap::_auto_collect(){
  29. #if !PK_DEBUG_NO_AUTO_GC
  30. if(_gc_lock_counter > 0) return;
  31. gc_counter = 0;
  32. collect();
  33. gc_threshold = gen.size() * 2;
  34. if(gc_threshold < PK_GC_MIN_THRESHOLD) gc_threshold = PK_GC_MIN_THRESHOLD;
  35. #endif
  36. }
  37. int ManagedHeap::collect(){
  38. PK_ASSERT(_gc_lock_counter == 0)
  39. mark();
  40. int freed = sweep();
  41. return freed;
  42. }
  43. ManagedHeap::~ManagedHeap(){
  44. for(PyObject* obj: _no_gc) { obj->~PyObject(); pool64_dealloc(obj); }
  45. for(PyObject* obj: gen) { obj->~PyObject(); pool64_dealloc(obj); }
  46. #if PK_DEBUG_GC_STATS
  47. for(auto& [type, count]: deleted){
  48. std::cout << "GC: " << obj_type_name(vm, type).sv() << "=" << count << std::endl;
  49. }
  50. #endif
  51. }
  52. void FuncDecl::_gc_mark() const{
  53. code->_gc_mark();
  54. for(int i=0; i<kwargs.size(); i++) PK_OBJ_MARK(kwargs[i].value);
  55. }
  56. } // namespace pkpy