gc.cpp 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  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. return freed;
  25. }
  26. void ManagedHeap::_auto_collect(){
  27. #if !PK_DEBUG_NO_AUTO_GC
  28. if(_gc_lock_counter > 0) return;
  29. if(gc_counter < gc_threshold) return;
  30. gc_counter = 0;
  31. collect();
  32. gc_threshold = gen.size() * 2;
  33. if(gc_threshold < kMinGCThreshold) gc_threshold = kMinGCThreshold;
  34. #endif
  35. }
  36. int ManagedHeap::collect(){
  37. if(_gc_lock_counter > 0) FATAL_ERROR();
  38. mark();
  39. int freed = sweep();
  40. return freed;
  41. }
  42. ManagedHeap::~ManagedHeap(){
  43. for(PyObject* obj: _no_gc) { obj->~PyObject(); pool64_dealloc(obj); }
  44. for(PyObject* obj: gen) { obj->~PyObject(); pool64_dealloc(obj); }
  45. #if PK_DEBUG_GC_STATS
  46. for(auto& [type, count]: deleted){
  47. std::cout << "GC: " << obj_type_name(vm, type) << "=" << count << std::endl;
  48. }
  49. #endif
  50. }
  51. void FuncDecl::_gc_mark() const{
  52. code->_gc_mark();
  53. for(int i=0; i<kwargs.size(); i++) PK_OBJ_MARK(kwargs[i].value);
  54. }
  55. } // namespace pkpy