Browse Source

Experimental fix, prevent write barrier from running during object destroy in reclaim free objects phase.

gdouglas 12 years ago
parent
commit
f2991ab431
2 changed files with 39 additions and 12 deletions
  1. 38 11
      gmsrc/src/gm/gmIncGC.cpp
  2. 1 1
      gmsrc/src/gm/gmIncGC.h

+ 38 - 11
gmsrc/src/gm/gmIncGC.cpp

@@ -642,6 +642,12 @@ bool gmGarbageCollector::Collect()
 
 
   m_doneTracing = true;
   m_doneTracing = true;
 
 
+#if GM_GC_TURN_OFF_ABLE
+  // Turn off gc until almost out of memory.
+  // Can only do when allocating black.
+  m_gcTurnedOff = true;
+#endif //GM_GC_TURN_OFF_ABLE  
+
   // Let the collect continue until garbage memory has been reclaimed
   // Let the collect continue until garbage memory has been reclaimed
   // This could be done as an external phase
   // This could be done as an external phase
   if(ReclaimSomeFreeObjects())
   if(ReclaimSomeFreeObjects())
@@ -649,13 +655,9 @@ bool gmGarbageCollector::Collect()
     return false;
     return false;
   }
   }
 
 
-#if GM_GC_TURN_OFF_ABLE  
-  // Turn off gc until almost out of memory.
-  // Can only do when allocating black.
-  m_gcTurnedOff = true;
-#else //GM_GC_TURN_OFF_ABLE  
+#if !GM_GC_TURN_OFF_ABLE
   Flip();
   Flip();
-#endif //GM_GC_TURN_OFF_ABLE  
+#endif //!GM_GC_TURN_OFF_ABLE
 
 
   return true;
   return true;
 }
 }
@@ -670,7 +672,7 @@ void gmGarbageCollector::Flip()
     m_flipCallback();
     m_flipCallback();
   }
   }
 
 
-#if GM_GC_TURN_OFF_ABLE  
+#if GM_GC_TURN_OFF_ABLE
   // The garbage collector can only be turned off if we are allocating black.
   // The garbage collector can only be turned off if we are allocating black.
   m_gcTurnedOff = false; // Turn the garbage collector back on.
   m_gcTurnedOff = false; // Turn the garbage collector back on.
 #endif //GM_GC_TURN_OFF_ABLE  
 #endif //GM_GC_TURN_OFF_ABLE  
@@ -681,6 +683,27 @@ void gmGarbageCollector::Flip()
 }
 }
 
 
 
 
+int gmGarbageCollector::ReclaimSomeFreeObjects()
+{
+  // NOTE: Reclaiming/Destructing free objects only occurs after a collect cycle
+  //       when the GC is logically off.  This code has a GM_GC_TURN_OFF_ABLE option
+  //       and partial and full collect functions, which complicates the code somewhat.
+  //       For this reason, I will ensure the 'collection is off' flag is set
+  //       so the WriteBarrier cannot run during destruct.
+  //       The intended collection flag will be restored, in case the calling code
+  //       wants to run continuously or is ready to start the next cycle.
+
+#if GM_GC_TURN_OFF_ABLE
+  //TODO enable this and test GM_ASSERT( m_gcTurnedOff == true );
+#endif //GM_GC_TURN_OFF_ABLE
+
+  bool desiredState = m_gcTurnedOff;
+  m_gcTurnedOff = true; // Paranoid flag off
+  int count = m_colorSet.DestructSomeFreeObjects(m_maxObjsToDestructPerIncrement);
+  m_gcTurnedOff = desiredState; // Restore flag for continuous operation
+  return count;
+}
+
 // This function is called when there are no free objects in the colorset.
 // This function is called when there are no free objects in the colorset.
 // If the gc is turned off, it calls flip to reclaim any garbage objects
 // If the gc is turned off, it calls flip to reclaim any garbage objects
 // that have been found by the garbage collector.
 // that have been found by the garbage collector.
@@ -738,17 +761,21 @@ void gmGarbageCollector::FullCollect()
   {
   {
     // Do the collect phase
     // Do the collect phase
   }
   }
-  ReclaimObjectsAndRestartCollection(); // Do flip and turn it back on
 
 
-  // NOTE: The GC is now restarted and in an 'On' state, meaning it will now collect again from the machine.
-  //       This behavior may not be desirable, so this function really needs more analysis to determine the
-  //       optimum sequence for a full collect with minimal redundancy.
+  // NOTE: (Below) Moved the restart after freeing objects so GC is logically off during object destruction
 
 
   // Free memory of garbage objects
   // Free memory of garbage objects
   while(ReclaimSomeFreeObjects())
   while(ReclaimSomeFreeObjects())
   {
   {
     // Reclaim all garbage
     // Reclaim all garbage
   }
   }
+
+  ReclaimObjectsAndRestartCollection(); // Do flip and turn it back on
+
+  // NOTE: The GC is now restarted and in an 'On' state, meaning it will now collect again from the machine.
+  //       This behavior may not be desirable, so this function really needs more analysis to determine the
+  //       optimum sequence for a full collect with minimal redundancy.
+
   m_fullThrottle = false;
   m_fullThrottle = false;
 }
 }
 
 

+ 1 - 1
gmsrc/src/gm/gmIncGC.h

@@ -327,7 +327,7 @@ public:
   void DestructAll();
   void DestructAll();
 
 
   /// \brief Reclaim some free objects.
   /// \brief Reclaim some free objects.
-  int ReclaimSomeFreeObjects()                    {return m_colorSet.DestructSomeFreeObjects(m_maxObjsToDestructPerIncrement);}
+  int ReclaimSomeFreeObjects();
 
 
   /// \brief Make an object persistant by moving it into the persistant list.
   /// \brief Make an object persistant by moving it into the persistant list.
   void MakeObjectPersistant(gmGCObjBase* a_obj)   {m_colorSet.MakePersistant(a_obj);}
   void MakeObjectPersistant(gmGCObjBase* a_obj)   {m_colorSet.MakePersistant(a_obj);}