diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 52cd6b4667..c7d4f7c3ee 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,7 @@ March 12, 2008 +- Fixed: DACSThinker::ActiveThinker was missing a read barrier. +- Loading a save game now initiates a collection. +- Added a finalization cost to the sweep stage. - Fixed: D_dehacked.cpp/PatchThing() allocated an actor on the stack. - Changed the sentinels in the thinker lists into a proper thinker. The old way wasn't playing well with the write barriers. diff --git a/src/d_net.cpp b/src/d_net.cpp index f17f7b460e..f58c6a2e90 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -1842,7 +1842,6 @@ void TryRunTics (void) M_Ticker (); I_GetTime (true); G_Ticker (); - GC::CheckGC (); gametic++; NetUpdate (); // check for new console commands diff --git a/src/dobject.h b/src/dobject.h index e2ad22aa00..b44e763a51 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -309,6 +309,12 @@ namespace GC Step(); } + // Forces a collection to start now. + static inline void StartCollection() + { + Threshold = AllocBytes; + } + // Marks a white object gray. If the object wants to die, the pointer // is NULLed instead. void Mark(DObject **obj); diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index ec0ede4b28..2a009618b0 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -185,11 +185,11 @@ static size_t PropagateAll() // //========================================================================== -static DObject **SweepList(DObject **p, size_t count) +static DObject **SweepList(DObject **p, size_t count, size_t *finalize_count) { - static int scount; DObject *curr; int deadmask = OtherWhite(); + size_t finalized = 0; while ((curr = *p) != NULL && count-- > 0) { @@ -210,8 +210,13 @@ static DObject **SweepList(DObject **p, size_t count) } curr->ObjectFlags |= OF_Cleanup; delete curr; + finalized++; } } + if (finalize_count != NULL) + { + *finalize_count = finalized; + } return p; } @@ -350,14 +355,15 @@ static size_t SingleStep() case GCS_Sweep: { size_t old = AllocBytes; - SweepPos = SweepList(SweepPos, GCSWEEPMAX); + size_t finalize_count; + SweepPos = SweepList(SweepPos, GCSWEEPMAX, &finalize_count); if (*SweepPos == NULL) { // Nothing more to sweep? State = GCS_Finalize; } assert(old >= AllocBytes); Estimate -= old - AllocBytes; - return GCSWEEPMAX * GCSWEEPCOST; + return (GCSWEEPMAX - finalize_count) * GCSWEEPCOST + finalize_count * GCFINALIZECOST; } case GCS_Finalize: diff --git a/src/g_game.cpp b/src/g_game.cpp index 53aa2906a8..085990ac92 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1823,6 +1823,11 @@ void G_DoLoadGame () delete png; fclose (stdfile); + + // At this point, the GC threshold is likely a lot higher than the + // amount of memory in use, so bring it down now by starting a + // collection. + GC::StartCollection(); } diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 37b56d57ff..0fb109397a 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -1562,7 +1562,7 @@ IMPLEMENT_POINTY_CLASS (DACSThinker) DECLARE_POINTER(Scripts) END_POINTERS -DACSThinker *DACSThinker::ActiveThinker = NULL; +TObjPtr DACSThinker::ActiveThinker; DACSThinker::DACSThinker () { diff --git a/src/p_acs.h b/src/p_acs.h index 9da001459c..a6168abc44 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -710,7 +710,7 @@ public: void Tick (); DLevelScript *RunningScripts[1000]; // Array of all synchronous scripts - static DACSThinker *ActiveThinker; + static TObjPtr ActiveThinker; void DumpScriptStatus(); void StopScriptsFor (AActor *actor);