summaryrefslogtreecommitdiff
path: root/ghc/interpreter
diff options
context:
space:
mode:
Diffstat (limited to 'ghc/interpreter')
-rw-r--r--ghc/interpreter/compiler.c26
-rw-r--r--ghc/interpreter/storage.c21
-rw-r--r--ghc/interpreter/storage.h6
3 files changed, 44 insertions, 9 deletions
diff --git a/ghc/interpreter/compiler.c b/ghc/interpreter/compiler.c
index ac85831778..c6b1cce8f0 100644
--- a/ghc/interpreter/compiler.c
+++ b/ghc/interpreter/compiler.c
@@ -11,8 +11,8 @@
* included in the distribution.
*
* $RCSfile: compiler.c,v $
- * $Revision: 1.26 $
- * $Date: 2000/04/06 14:23:55 $
+ * $Revision: 1.27 $
+ * $Date: 2000/04/11 16:36:53 $
* ------------------------------------------------------------------------*/
#include "hugsbasictypes.h"
@@ -1490,6 +1490,27 @@ Void evalExp ( void ) { /* compile and run input expression */
unless doRevertCAFs below is permanently TRUE.
*/
/* initScheduler(); */
+
+ /* Further comments, JRS 000411.
+ When control returns to Hugs, you have to be pretty careful about
+ the state of the heap. In particular, hugs.c may subsequently call
+ nukeModule() in storage.c, which removes modules from the system.
+ If a module defines a particular data constructor, the relevant
+ info table is also free()d. That gives a problem if there are
+ still closures hanging round in the heap with references to that
+ info table.
+
+ The solution is to firstly to revert CAFs, and then force a major
+ collection in between transitions from the mutation, ie actually
+ running Haskell, and nukeModule. Since major GCs are potentially
+ expensive, we don't want to do one at every call to nukeModule,
+ so the flag nukeModule_needs_major_gc is used to signal when one
+ is needed.
+
+ This all also seems to imply that doRevertCAFs should always
+ be TRUE.
+ */
+
# ifdef CRUDE_PROFILING
cp_init();
# endif
@@ -1499,6 +1520,7 @@ Void evalExp ( void ) { /* compile and run input expression */
SchedulerStatus status;
Bool doRevertCAFs = TRUE; /* do not change -- comment above */
HugsBreakAction brkOld = setBreakAction ( HugsRtsInterrupt );
+ nukeModule_needs_major_gc = TRUE;
status = rts_eval_(closureOfVar(v),10000,&result);
setBreakAction ( brkOld );
fflush (stderr);
diff --git a/ghc/interpreter/storage.c b/ghc/interpreter/storage.c
index 401168f0c7..95627f4912 100644
--- a/ghc/interpreter/storage.c
+++ b/ghc/interpreter/storage.c
@@ -9,8 +9,8 @@
* included in the distribution.
*
* $RCSfile: storage.c,v $
- * $Revision: 1.68 $
- * $Date: 2000/04/07 16:25:19 $
+ * $Revision: 1.69 $
+ * $Date: 2000/04/11 16:36:53 $
* ------------------------------------------------------------------------*/
#include "hugsbasictypes.h"
@@ -19,6 +19,7 @@
#include "errors.h"
#include "object.h"
#include <setjmp.h>
+#include "Stg.h"
/*#define DEBUG_SHOWUSE*/
@@ -1628,13 +1629,25 @@ Module newModule ( Text t ) /* add new module to module table */
return mod;
}
+
+Bool nukeModule_needs_major_gc = TRUE;
+
void nukeModule ( Module m )
{
ObjectCode* oc;
ObjectCode* oc2;
Int i;
-assert(isModule(m));
-/*fprintf(stderr, "NUKEMODULE `%s'\n", textToStr(module(m).text)); */
+
+ if (!isModule(m)) internal("nukeModule");
+
+ /* see comment in compiler.c about this,
+ and interaction with info tables */
+ if (nukeModule_needs_major_gc) {
+ /* fprintf ( stderr, "doing major GC in nukeModule\n"); */
+ performMajorGC();
+ nukeModule_needs_major_gc = FALSE;
+ }
+
oc = module(m).object;
while (oc) {
oc2 = oc->next;
diff --git a/ghc/interpreter/storage.h b/ghc/interpreter/storage.h
index 4949a40d0d..881d2730ce 100644
--- a/ghc/interpreter/storage.h
+++ b/ghc/interpreter/storage.h
@@ -10,8 +10,8 @@
* included in the distribution.
*
* $RCSfile: storage.h,v $
- * $Revision: 1.42 $
- * $Date: 2000/04/07 16:25:20 $
+ * $Revision: 1.43 $
+ * $Date: 2000/04/11 16:36:53 $
* ------------------------------------------------------------------------*/
#define DEBUG_STORAGE /* a moderate level of sanity checking */
@@ -619,7 +619,7 @@ extern Module currentModule; /* Module currently being processed */
extern List moduleGraph; /* :: [GRP_REC | GRP_NONREC] */
extern List prelModules; /* :: [CONID] */
extern List targetModules; /* :: [CONID] */
-
+extern Bool nukeModule_needs_major_gc; /* see comment in compiler.c */
extern Bool isValidModule ( Module );
extern Module newModule ( Text );