Browse Source

(Heuritisc) GC working -- using correct SP / BP

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@6929 8c9fc860-2736-0410-a75d-ab315db34111
felixf 9 years ago
parent
commit
1ee859c02b

+ 3 - 3
source/Generic.Linux.I386.Glue.Mod

@@ -6,8 +6,8 @@ MODULE Glue;
 IMPORT SYSTEM, Trace;
 IMPORT SYSTEM, Trace;
 
 
 CONST 
 CONST 
-	base = 08048000H;
-	debug* = {0};
+	base* = 08048000H;
+	debug* = {0,1};
 VAR
 VAR
 	last-: RECORD END; (* empty variable linked to end of kernel *)
 	last-: RECORD END; (* empty variable linked to end of kernel *)
 	
 	
@@ -217,7 +217,7 @@ SystemTools.DoCommands
 		Runtime Trace Glue Unix Machine Heaps Modules Objects Kernel KernelLog 
 		Runtime Trace Glue Unix Machine Heaps Modules Objects Kernel KernelLog 
 Streams Commands StdIO TrapWriters Traps 
 Streams Commands StdIO TrapWriters Traps 
 Files UnixFiles Clock Dates Reals Strings Diagnostics 
 Files UnixFiles Clock Dates Reals Strings Diagnostics 
-BitSets StringPool ObjectFile GenericLinker Reflection  GenericLoader  Test BootConsole  
+BitSets StringPool ObjectFile GenericLinker Reflection  GenericLoader  BootConsole  
  ~
  ~
 
 
 	FSTools.CloseFiles simple_elf ~
 	FSTools.CloseFiles simple_elf ~

+ 4 - 2
source/Generic.Unix.I386.Machine.Mod

@@ -292,18 +292,20 @@ VAR
 		endBlockAdr := memBlockHead.endBlockAdr;
 		endBlockAdr := memBlockHead.endBlockAdr;
 		freeBlockAdr := beginBlockAdr;
 		freeBlockAdr := beginBlockAdr;
 	END GetStaticHeap;
 	END GetStaticHeap;
+	
+	VAR Last: RECORD END; (* linked to the end *)
 
 
 	(* returns if an address is a currently allocated heap address *)
 	(* returns if an address is a currently allocated heap address *)
 	PROCEDURE ValidHeapAddress*( p: ADDRESS ): BOOLEAN;
 	PROCEDURE ValidHeapAddress*( p: ADDRESS ): BOOLEAN;
 	VAR mb: MemoryBlock; 
 	VAR mb: MemoryBlock; 
 	BEGIN
 	BEGIN
+		IF (p>=Glue.base) & (p<=ADDRESSOF(Last)) THEN RETURN TRUE END;
 		mb := memBlockHead;  
 		mb := memBlockHead;  
 		WHILE mb # NIL DO
 		WHILE mb # NIL DO
 			IF (p >= mb.beginBlockAdr) & (p <= mb.endBlockAdr) THEN  RETURN TRUE  END;  
 			IF (p >= mb.beginBlockAdr) & (p <= mb.endBlockAdr) THEN  RETURN TRUE  END;  
 			mb := mb.next;  
 			mb := mb.next;  
 		END;  
 		END;  
-		RETURN TRUE;
-		RETURN FALSE  
+		RETURN FALSE;
 	END ValidHeapAddress;
 	END ValidHeapAddress;
 	
 	
 
 

+ 124 - 6
source/Generic.Unix.Objects.Mod

@@ -139,10 +139,10 @@ TYPE
 	VAR 
 	VAR 
 		n: Heaps.FinalizerNode;  start: BOOLEAN;
 		n: Heaps.FinalizerNode;  start: BOOLEAN;
 	
 	
-		PROCEDURE Start;
+		PROCEDURE Activate;
 		BEGIN {EXCLUSIVE}
 		BEGIN {EXCLUSIVE}
 			start := TRUE
 			start := TRUE
-		END Start;
+		END Activate;
 		
 		
 	BEGIN {ACTIVE, SAFE, PRIORITY(High)}
 	BEGIN {ACTIVE, SAFE, PRIORITY(High)}
 		finCaller := CurrentProcess( );  start := FALSE;
 		finCaller := CurrentProcess( );  start := FALSE;
@@ -191,15 +191,65 @@ TYPE
 					
 					
 				
 				
 		PROCEDURE FindRoots*;
 		PROCEDURE FindRoots*;
-		VAR sp, ptr: ADDRESS;
+		VAR sp, ptr, bp, n, a0, a1, adr: ADDRESS; desc: Modules.ProcedureDescPointer; i: LONGINT; p {UNTRACED}: ANY;
+			me: Process;
 		BEGIN
 		BEGIN
 			IF mode # Terminated THEN
 			IF mode # Terminated THEN
+			
+
+			IF SELF = CurrentProcess() THEN
+				context.r_sp := Machine.CurrentSP();
+				context.r_bp := Machine.CurrentBP();
+				context.r_pc := ADDRESS OF FindRoots;
+			END;
+
+			sp := context.r_sp; bp := context.r_bp; (*pc := context.r_pc;*)
+
+			IF Heaps.GCType= Heaps.HeuristicStackInspectionGC THEN
+				Heaps.Candidate( context.r_di);  Heaps.Candidate( context.r_si );
+				Heaps.Candidate( context.r_bx ); Heaps.Candidate( context.r_dx);
+				Heaps.Candidate( context.r_cx ); Heaps.Candidate( context.r_ax);
+				TRACE(sp, stackBottom);
+				IF (stackBottom # 0) & (sp # 0) & (sp <= stackBottom) THEN
+					TRACE(sp, stackBottom -sp);
+					Heaps.RegisterCandidates( sp, stackBottom - sp );
+				END;
+			ELSIF Heaps.GCType = Heaps.MetaDataForStackGC THEN
+				IF bp < stackBottom THEN
+					WHILE (bp # Heaps.NilVal) & (bp < stackBottom)  DO (* do not test for bp >= sp: could be wrong temporarily! *)
+						S.GET(bp, n);
+						IF ODD(n) THEN (* procedure descriptor at bp *)
+							desc := S.VAL(Modules.ProcedureDescPointer, n-1);
+							IF desc # NIL THEN
+								a0 := ADDRESSOF(desc.offsets);
+								a1 :=  S.VAL(ADDRESS, desc.offsets);
+								ASSERT(a0+SIZEOF(ADDRESS)=a1,54321);
+								FOR i := 0 TO LEN(desc.offsets)-1 DO
+									adr := bp + desc.offsets[i]; (* pointer at offset *)
+									S.GET(adr, p); (* load pointer *)
+									IF p # NIL THEN 
+										Heaps.Mark(p);
+									END;
+								END;
+							END;
+							S.GET(bp + SIZEOF(ADDRESS), bp);
+						ELSE (* classical stack frame *)
+							bp := n; 
+						END;
+					END;
+					
+					ASSERT((bp = stackBottom) OR (bp=0) ,12345);
+				END; 
+			END;
+
+			(*
 				sp := context.r_sp;
 				sp := context.r_sp;
 				WHILE sp < stackBottom DO  
 				WHILE sp < stackBottom DO  
 					S.GET( sp, ptr );  
 					S.GET( sp, ptr );  
 					IF (ptr # 0) & (ptr MOD 8 = 0) THEN  Heaps.Candidate( ptr )  END;  
 					IF (ptr # 0) & (ptr MOD 8 = 0) THEN  Heaps.Candidate( ptr )  END;  
 					INC( sp, AddrSize )  
 					INC( sp, AddrSize )  
 				END;
 				END;
+				*)
 			END;
 			END;
 			Heaps.Mark( nextProcess ) 
 			Heaps.Mark( nextProcess ) 
 		END FindRoots;
 		END FindRoots;
@@ -266,6 +316,39 @@ TYPE
 				
 				
 	END Process;
 	END Process;
 
 
+	GCStatusExt = OBJECT(Heaps.GCStatus)
+	
+	(* called from Heaps.InvokeGC, i.e. this is a hidden upcall. However, it is necessary to take the Machine.Objects lock here since writing
+		    the set of variables here must not be interrupted, i.e. atomic writing of the set of variables is absolutely necessary.  They system may hang
+		    if the lock is not taken. *)
+		PROCEDURE SetgcOngoing(value: BOOLEAN);
+		VAR p: Heaps.ProcessLink; cur, r: Process; res: LONGINT; num: LONGINT; time: LONGINT;
+		BEGIN (* serialize writers *)
+			cur:= CurrentProcess();
+			IF value THEN
+				(*collect := TRUE; 
+				
+				TRACE(collect); 
+				collect := FALSE;
+				*)
+				Machine.Acquire( Machine.Heaps );
+				cur.context.r_sp := Machine.CurrentSP();
+				cur.context.r_bp := Machine.CurrentBP();
+				cur.context.r_pc := ADDRESS OF GCLoop;
+				TRACE(cur.context.r_sp, cur.context.r_bp, cur.context.r_pc);
+				SuspendActivities;
+				
+				Heaps.CollectGarbage( Modules.root );
+				Machine.Release( Machine.Heaps );
+				ResumeActivities;
+				finalizerCaller.Activate;
+
+				
+			END;
+		END SetgcOngoing;
+
+	END GCStatusExt;
+
 
 
 	
 	
 	PROCEDURE BodyStarter;
 	PROCEDURE BodyStarter;
@@ -635,13 +718,27 @@ TYPE
 	END GetContext;
 	END GetContext;
 	
 	
 	PROCEDURE SuspendActivities;
 	PROCEDURE SuspendActivities;
-	VAR t: Process;  
+	VAR t,me: Process;  res: LONGINT;
 	BEGIN
 	BEGIN
+		me := CurrentProcess();
+		t := root;
+				
+		WHILE t # NIL DO
+			IF (t # me) THEN  
+				Unix.ThrSuspend(t.threadId ); 
+			END;
+			t := t.nextProcess
+		END;
+	(*
+	VAR t, me: Process;  
+	BEGIN
+		
 		t := root;
 		t := root;
 		WHILE t # NIL DO
 		WHILE t # NIL DO
 			IF (t # mainProcess) & (t # finCaller) THEN  Unix.ThrSuspend( t.threadId )  END;
 			IF (t # mainProcess) & (t # finCaller) THEN  Unix.ThrSuspend( t.threadId )  END;
 			t := t.nextProcess
 			t := t.nextProcess
 		END;
 		END;
+	*)
 	END SuspendActivities;
 	END SuspendActivities;
 
 
 	PROCEDURE ResumeActivities;
 	PROCEDURE ResumeActivities;
@@ -665,19 +762,27 @@ TYPE
 	(*!	GCLoop gets called as last procedure in BootConsole (main thread). 
 	(*!	GCLoop gets called as last procedure in BootConsole (main thread). 
 		The stack of the main thread is not limited by the  boot parameter 'StackSize' !!
 		The stack of the main thread is not limited by the  boot parameter 'StackSize' !!
 	*)
 	*)
+	
 	PROCEDURE GCLoop*;	(* Timer and GC activity *)
 	PROCEDURE GCLoop*;	(* Timer and GC activity *)
+	VAR cur: Process;
 	BEGIN
 	BEGIN
+		cur:= CurrentProcess();
 		SetPriority( GCPriority );
 		SetPriority( GCPriority );
 		LOOP
 		LOOP
 			IF collect THEN  
 			IF collect THEN  
-				TRACE(collect);
+				TRACE(collect); 
 				collect := FALSE;
 				collect := FALSE;
 				Machine.Acquire( Machine.Heaps );
 				Machine.Acquire( Machine.Heaps );
+				cur.context.r_sp := Machine.CurrentSP();
+				cur.context.r_bp := Machine.CurrentBP();
+				cur.context.r_sp := ADDRESS OF GCLoop;
+
 				SuspendActivities;
 				SuspendActivities;
+				
 				Heaps.CollectGarbage( Modules.root );
 				Heaps.CollectGarbage( Modules.root );
 				Machine.Release( Machine.Heaps );
 				Machine.Release( Machine.Heaps );
 				ResumeActivities;
 				ResumeActivities;
-				finalizerCaller.Start;
+				finalizerCaller.Activate;
 				Unix.ConSignal( gcFinished );
 				Unix.ConSignal( gcFinished );
 			ELSE
 			ELSE
 				Unix.ThrSleep( 10 ); 
 				Unix.ThrSleep( 10 ); 
@@ -688,6 +793,7 @@ TYPE
 	
 	
 	
 	
 	
 	
+	
 	PROCEDURE CurrentProcessTime*(): HUGEINT;
 	PROCEDURE CurrentProcessTime*(): HUGEINT;
 	BEGIN
 	BEGIN
 		RETURN  Machine.GetTimer()
 		RETURN  Machine.GetTimer()
@@ -770,6 +876,9 @@ TYPE
 		NEW( finalizerCaller );
 		NEW( finalizerCaller );
 		(*
 		(*
 		Heaps.saveSP := SaveSP;
 		Heaps.saveSP := SaveSP;
+		*)
+		Heaps.gcStatus := GCStatusFactory()
+		(*
 		Heaps.GC := InvokeGC;
 		Heaps.GC := InvokeGC;
 		Heaps.InvokeGC := InvokeGC;
 		Heaps.InvokeGC := InvokeGC;
 		*)
 		*)
@@ -781,6 +890,15 @@ TYPE
 		Machine.Shutdown(FALSE);
 		Machine.Shutdown(FALSE);
 	END Final;
 	END Final;
 
 
+
+	PROCEDURE GCStatusFactory(): Heaps.GCStatus;
+	VAR gcStatusExt : GCStatusExt;
+	BEGIN
+		ASSERT(Heaps.gcStatus = NIL);
+		NEW(gcStatusExt);
+		RETURN gcStatusExt
+	END GCStatusFactory;
+
 BEGIN
 BEGIN
 	TRACE("Objects.Body1");
 	TRACE("Objects.Body1");
 	Init;
 	Init;

+ 13 - 1
source/Generic.Unix.Traps.Mod

@@ -75,6 +75,16 @@ VAR
 		Machine.Release( Machine.Trap )
 		Machine.Release( Machine.Trap )
 	END FinishTrap;
 	END FinishTrap;
 	
 	
+	PROCEDURE Registers(CONST c:Unix.McontextDesc; w: Streams.Writer);
+	BEGIN
+		w.String("EAX= "); w.Address(c.r_ax);
+		w.String(" EBX= "); w.Address(c.r_bx);
+		w.String(" ECX= "); w.Address(c.r_cx);
+		w.String(" EDX= "); w.Address(c.r_dx);
+		w.String(" ESI= "); w.Address(c.r_si);
+		w.String(" EDI= "); w.Address(c.r_di);
+		w.Ln;
+	END Registers;
 	
 	
 
 
 	PROCEDURE Trap( sig: LONGINT;  ucp: Unix.Ucontext;  fatalerror: BOOLEAN );  
 	PROCEDURE Trap( sig: LONGINT;  ucp: Unix.Ucontext;  fatalerror: BOOLEAN );  
@@ -99,6 +109,7 @@ VAR
 			w := TrapWriters.GetWriter();
 			w := TrapWriters.GetWriter();
 			w.Char( 1X );   (* begin of trap text *) 
 			w.Char( 1X );   (* begin of trap text *) 
 		END;
 		END;
+		
 
 
 		w.Ln;  
 		w.Ln;  
 		w.String( Machine.version ); w.String( "   " );  TimeTag( w );  w.Ln; 
 		w.String( Machine.version ); w.String( "   " );  TimeTag( w );  w.Ln; 
@@ -108,13 +119,13 @@ VAR
 		ELSE  
 		ELSE  
 			w.String( "[recursive Trap] " )  
 			w.String( "[recursive Trap] " )  
 		END;  
 		END;  
+		sp := ucp.mc.r_sp;
 		CASE sig OF 
 		CASE sig OF 
 		| 1:		w.String( "1 (Hangup signal)" );   
 		| 1:		w.String( "1 (Hangup signal)" );   
 		| 2:  	w.String( "2 (User interrupt)" );   
 		| 2:  	w.String( "2 (User interrupt)" );   
 		| 3:		w.String( "3 (Quit signal)" );   
 		| 3:		w.String( "3 (Quit signal)" );   
 		| 4:  	w.String( "4 (Illegal instruction)" );   
 		| 4:  	w.String( "4 (Illegal instruction)" );   
 		| 5:   	w.String( "5." );  
 		| 5:   	w.String( "5." );  
-				sp := ucp.mc.r_sp;
 				S.GET( sp, trapno );  w.Int( trapno, 0 );  
 				S.GET( sp, trapno );  w.Int( trapno, 0 );  
 				CASE trapno OF 
 				CASE trapno OF 
 				| 1:		w.String( "  (WITH guard failed)" ) 
 				| 1:		w.String( "  (WITH guard failed)" ) 
@@ -151,6 +162,7 @@ VAR
 			w.String( "    sp = " );  w.Address( sp );  w.String( ", fp = " );  w.Address( bp ); 
 			w.String( "    sp = " );  w.Address( sp );  w.String( ", fp = " );  w.Address( bp ); 
 			w.String( ", pc = " );  w.Address( pc );  w.Ln;  
 			w.String( ", pc = " );  w.Address( pc );  w.Ln;  
 			w.Ln;  
 			w.Ln;  
+			Registers(ucp.mc,w);
 			Reflection.StackTraceBack( w, pc, bp, sp, Objects.GetStackBottom( process ), TRUE, FALSE );
 			Reflection.StackTraceBack( w, pc, bp, sp, Objects.GetStackBottom( process ), TRUE, FALSE );
 			SearchExceptionHandler( process, ucp, handler ); 
 			SearchExceptionHandler( process, ucp, handler ); 
 		END;
 		END;

+ 1 - 0
source/Heaps.Mod

@@ -342,6 +342,7 @@ BEGIN
 			Inspect(protected.awaitingLock.head);
 			Inspect(protected.awaitingLock.head);
 			Inspect(protected.awaitingCond.head);
 			Inspect(protected.awaitingCond.head);
 			Inspect(protected.lockedBy);
 			Inspect(protected.lockedBy);
+			Inspect(protected.lock);
 		END;
 		END;
 		orgHeapBlock := ExtractFromMarkList();
 		orgHeapBlock := ExtractFromMarkList();
 	END;
 	END;

+ 1 - 1
source/Unix.Kernel.Mod

@@ -199,7 +199,7 @@ END Left;
 BEGIN
 BEGIN
 	ASSERT(1000 MOD Second = 0);	(* for Elapsed *)
 	ASSERT(1000 MOD Second = 0);	(* for Elapsed *)
 	second := Second;
 	second := Second;
-	
+	Heaps.GC := Heaps.InvokeGC;
 	Machine.Acquire(Machine.TraceOutput);
 	Machine.Acquire(Machine.TraceOutput);
 	Trace.String( Machine.version ); Trace.String(": Kernel: Initialized and started."); Trace.Ln;
 	Trace.String( Machine.version ); Trace.String(": Kernel: Initialized and started."); Trace.Ln;
 	Machine.Release(Machine.TraceOutput);
 	Machine.Release(Machine.TraceOutput);