gc.h 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #pragma once
  2. #include "common.h"
  3. #include "memory.h"
  4. #include "obj.h"
  5. #include "codeobject.h"
  6. #include "namedict.h"
  7. namespace pkpy {
  8. struct ManagedHeap{
  9. std::vector<PyObject*> _no_gc;
  10. std::vector<PyObject*> gen;
  11. VM* vm;
  12. void (*_gc_on_delete)(VM*, PyObject*) = nullptr;
  13. void (*_gc_marker_ex)(VM*) = nullptr;
  14. ManagedHeap(VM* vm): vm(vm) {}
  15. int gc_threshold = PK_GC_MIN_THRESHOLD;
  16. int gc_counter = 0;
  17. /********************/
  18. int _gc_lock_counter = 0;
  19. struct ScopeLock{
  20. PK_ALWAYS_PASS_BY_POINTER(ScopeLock)
  21. ManagedHeap* heap;
  22. ScopeLock(ManagedHeap* heap): heap(heap){
  23. heap->_gc_lock_counter++;
  24. }
  25. ~ScopeLock(){
  26. heap->_gc_lock_counter--;
  27. }
  28. };
  29. ScopeLock gc_scope_lock(){
  30. return ScopeLock(this);
  31. }
  32. /********************/
  33. template<typename T, typename... Args>
  34. PyObject* gcnew(Type type, Args&&... args){
  35. using __T = Py_<std::decay_t<T>>;
  36. // https://github.com/pocketpy/pocketpy/issues/94#issuecomment-1594784476
  37. PyObject* obj = new(pool64_alloc<__T>()) Py_<std::decay_t<T>>(type, std::forward<Args>(args)...);
  38. gen.push_back(obj);
  39. gc_counter++;
  40. return obj;
  41. }
  42. template<typename T, typename... Args>
  43. PyObject* _new(Type type, Args&&... args){
  44. using __T = Py_<std::decay_t<T>>;
  45. // https://github.com/pocketpy/pocketpy/issues/94#issuecomment-1594784476
  46. PyObject* obj = new(pool64_alloc<__T>()) Py_<std::decay_t<T>>(type, std::forward<Args>(args)...);
  47. obj->gc_enabled = false;
  48. _no_gc.push_back(obj);
  49. return obj;
  50. }
  51. #if PK_DEBUG_GC_STATS
  52. inline static std::map<Type, int> deleted;
  53. #endif
  54. int sweep();
  55. void _auto_collect();
  56. bool _should_auto_collect() const { return gc_counter >= gc_threshold; }
  57. int collect();
  58. void mark();
  59. ~ManagedHeap();
  60. };
  61. } // namespace pkpy