gc.h 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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. static const int kMinGCThreshold = 3072;
  16. int gc_threshold = kMinGCThreshold;
  17. int gc_counter = 0;
  18. /********************/
  19. int _gc_lock_counter = 0;
  20. struct 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/blueloveTH/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/blueloveTH/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