@@ -93,6 +93,45 @@ class GCAllocatedRuntime {
9393
9494    virtual  void  gc_visit (GCVisitor* visitor) = 0;
9595};
96+ 
97+ //  Situation: Sometimes, we allocate an object on the stack (e.g. ASTInterpreter) who fields may be pointers
98+ //  to objects in the Pyston heap. These pointers need to be scanned by the GC. Since the GC scans the entire
99+ //  stack conservatively, these fields will be scanned. However, it is also possible that the stack-allocated
100+ //  object points to a non-Pyston heap object which contains pointers to Pyston heap objects. In that case, the
101+ //  conservative scanner won't get to those pointers.
102+ // 
103+ //  As such, objects who contain pointers to pointers to Pyston heap objects need a GC handler function. To do
104+ //  that, we allocate a small object in the Pyston heap that refers back to the stack object and scans it.
105+ class  StackObjectWithGCHandler  {
106+     class  StackObjectHandler  : public  GCAllocatedRuntime  {
107+     public: 
108+         StackObjectWithGCHandler* stack_object;
109+ 
110+         StackObjectHandler (StackObjectWithGCHandler* obj) : stack_object(obj) {}
111+         ~StackObjectHandler () = default ;
112+ 
113+         virtual  void  gc_visit (GCVisitor* visitor) {
114+             assert (stack_object);
115+             stack_object->gc_visit (visitor);
116+         }
117+     };
118+ 
119+     //  This is allocated in the Pyston heap and is conservatively scanned.
120+     StackObjectHandler* handler;
121+ 
122+ public: 
123+     //  GC visit function that will be called from the handler.
124+     virtual  void  gc_visit (GCVisitor* visitor) = 0;
125+ 
126+     StackObjectWithGCHandler () { handler = new  StackObjectHandler (this ); }
127+ 
128+     //  We delete the handler manually instead of letting the GC take care of it. In theory,
129+     //  the StackObjectHandler will become unreachable as long as the stack object is popped
130+     //  off the stack. The danger is that if the StackObjectHandler happens to be pointed to
131+     //  conservatively, it will be "reached" and its gc_visit function will be called.
132+     virtual  ~StackObjectWithGCHandler () { delete  handler; }
133+ };
134+ 
96135} //  namespace gc
97136}
98137
0 commit comments