فهرست منبع

Enable garbage collection again, taking into account the local variables in generators

Yentl Van Tendeloo 7 سال پیش
والد
کامیت
e7778bdf18
4فایلهای تغییر یافته به همراه52 افزوده شده و 8 حذف شده
  1. 2 2
      hybrid_server/classes/mvkcontroller.xml
  2. 45 0
      kernel/modelverse_kernel/main.py
  3. 4 5
      state/modelverse_state/main.py
  4. 1 1
      wrappers/modelverse_SCCD.py

+ 2 - 2
hybrid_server/classes/mvkcontroller.xml

@@ -298,7 +298,6 @@
                     </state>
                 </state>
 
-                <!--
                 <state id="mvs_GC" initial="suspend_tasks">
                     <state id="suspend_tasks">
                         <onentry>
@@ -311,14 +310,15 @@
                     <state id="mvs_GC">
                         <onentry>
                             <script>
+                                self.execute_modelverse("", "protect_temporary_variables", [])
                                 self.mvs.purge()
+                                self.execute_modelverse("", "unprotect_temporary_variables", [])
                             </script>
                             <raise scope="broad" event="resume_task"/>
                         </onentry>
                         <transition after="self.sccd_yield() + 10" target="."/>
                     </state>
                 </state>
-                -->
             </parallel>
 
             <state id="remove_sockets">

+ 45 - 0
kernel/modelverse_kernel/main.py

@@ -37,6 +37,51 @@ class ModelverseKernel(object):
 
         self.debug_info = defaultdict(list)
 
+    def try_to_protect(self, var):
+        if isinstance(var, dict) and "id" in var and var['id'] is not None:
+            return set([var['id']])
+        elif type(var) == int:
+            return set([var])
+        elif isinstance(var, dict):
+            protect = set()
+            for v in var.values():
+                protect |= self.try_to_protect(v)
+            return protect
+        elif isinstance(var, list):
+            protect = set()
+            for v in var:
+                protect |= self.try_to_protect(v)
+            return protect
+        elif isinstance(var, set):
+            protect = set()
+            for v in var:
+                protect |= self.try_to_protect(v)
+            return protect
+        return set()
+
+    def protect_temporary_variables(self, taskname):
+        generators = []
+        for h in self.request_handlers.values():
+            for handler in h.values():
+                for generator in handler.generator_stack:
+                    generators.append(generator)
+
+        to_protect = set()
+        for gen in generators:
+            variables = gen.gi_frame.f_locals
+            for var in variables.values():
+                to_protect |= self.try_to_protect(var)
+
+        # Create the node to which everything is attached
+        self.fixed_node, = yield [("CN", [])]
+        yield [("CE", [self.root, self.fixed_node])]
+        yield [("CE", [self.fixed_node, node]) for node in to_protect]
+        yield [("RETURN", [None])]
+
+    def unprotect_temporary_variables(self, taskname):
+        yield [("DN", [self.fixed_node])]
+        yield [("RETURN", [None])]
+
     def execute_yields(self, taskname, operation, params, reply):
         self.taskname = taskname
         if taskname not in self.request_handlers:

+ 4 - 5
state/modelverse_state/main.py

@@ -373,16 +373,15 @@ class ModelverseState(object):
             # If they haven't, they will be removed because the source was removed.
             self.to_delete.add(t)
 
-    def garbage_collect(self):  
-        return
+    def purge(self):
+        print("PURGE")
+        #return
+
         while self.to_delete:
             t = self.to_delete.pop()
             if t in self.incoming and not self.incoming[t]:
                 self.delete_node(t)
 
-    def purge(self):
-        return
-        self.garbage_collect()
         values = set(self.edges)
         values.update(self.nodes)
         visit_list = [self.root]

+ 1 - 1
wrappers/modelverse_SCCD.py

@@ -1,7 +1,7 @@
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
-Date:   Fri May 18 15:41:18 2018
+Date:   Tue May 22 11:16:00 2018
 
 Model author: Yentl Van Tendeloo
 Model name:   MvK Server