Browse Source

Performance improvement for write barriers

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@7387 8c9fc860-2736-0410-a75d-ab315db34111
felixf 7 years ago
parent
commit
b01add9119
3 changed files with 36 additions and 7 deletions
  1. 16 2
      source/FoxIntermediateBackend.Mod
  2. 7 3
      source/Heaps.Mod
  3. 13 2
      source/WMPerfMonTabSystem.Mod

+ 16 - 2
source/FoxIntermediateBackend.Mod

@@ -7466,6 +7466,20 @@ TYPE
 			Emit(Push(position,op.op))
 		END PushString;
 
+		(* conservative check if x is potentially on the heap, excluding the module heap 
+			required for generational garbage collector
+		*)
+		PROCEDURE OnHeap(x: SyntaxTree.Expression): BOOLEAN;
+		VAR pos: LONGINT;
+		BEGIN
+			pos := x.position.start;
+			WHILE (x # NIL) & ~(x IS SyntaxTree.DereferenceDesignator) & ~(x IS SyntaxTree.SelfDesignator) DO
+				x := x(SyntaxTree.Designator).left;
+			END;
+			(*TRACE(pos, x # NIL);*)
+			RETURN x # NIL;
+		END OnHeap;
+
 		PROCEDURE VisitBuiltinCallDesignator(x: SyntaxTree.BuiltinCallDesignator);
 		VAR
 			p0,p1,p2,parameter: SyntaxTree.Expression; len,val: LONGINT; l,r: Operand; res,adr,reg: IntermediateCode.Operand; type, componentType: SyntaxTree.Type;
@@ -8074,7 +8088,7 @@ TYPE
 
 						IF (temporaryVariable # NIL) & (x.type = NIL) THEN
 							Designate(p0,l);
-							IF backend.writeBarriers THEN
+							IF backend.writeBarriers & OnHeap(p0) THEN
 								SaveRegisters();ReleaseUsedRegisters(saved);
 								Emit(Push(position,l.op));
 								Emit(Push(position,pointer));
@@ -10004,7 +10018,7 @@ TYPE
 				END;
 				ModifyAssignments(false);
 				RETURN;
-			ELSIF backend.writeBarriers & left.NeedsTrace() & ~((leftType IS SyntaxTree.MathArrayType) & ~IsStaticMathArray(leftType)) THEN
+			ELSIF backend.writeBarriers &  left.NeedsTrace() & OnHeap(left) & ~((leftType IS SyntaxTree.MathArrayType) & ~IsStaticMathArray(leftType)) THEN
 				SaveRegisters();ReleaseUsedRegisters(saved);
 				IF SemanticChecker.IsPointerType(leftType) THEN
 					Evaluate(right,rightO);

+ 7 - 3
source/Heaps.Mod

@@ -255,7 +255,7 @@ VAR
 	(** Statistics considering the last GC cyle *)
 	Nmark-, Nmarked-, NfinalizeAlive-, NfinalizeDead-: LONGINT;
 	NgcCyclesMark-, NgcCyclesLastRun-, NgcCyclesMax-, NgcCyclesAllRuns- : HUGEINT;
-	NgcSweepTime-, NgcSweepMax-: HUGEINT;
+	NgcSweeps-, NgcSweepTime-, NgcSweepMax-: HUGEINT;
 
 	gcStatus*: GCStatus;
 
@@ -285,7 +285,9 @@ BEGIN
 			tdAdr := block.typeBlock;
 			IF (tdAdr = systemBlockTag) OR (tdAdr = recordBlockTag) OR (tdAdr = protRecBlockTag) OR (tdAdr = arrayBlockTag) THEN
 				RETURN TRUE;
-			ELSE HALT(103);
+			ELSE 
+				Trace.Memory(p-64, 128);
+				HALT(103);
 			END
 		ELSE HALT(102);
 		END
@@ -686,6 +688,7 @@ VAR
 CONST FreeBlockHeaderSize = SIZEOF(FreeBlockDesc) + BlockHeaderSize;
 CONST StrongChecks = FALSE;
 BEGIN{UNCHECKED}
+	INC(NgcSweeps);
 	time1 := Machine.GetTimer();
 	ASSERT(~EnableFreeLists OR (size = MAX(LONGINT)));
 	lastFreeBlockAdr := NilVal;
@@ -1225,7 +1228,7 @@ BEGIN
 	CheckPostGC;
 	try := 1;
 	p := NIL;
-	IF  (GC = NilGC) OR (throughput < 64*1024*1024) THEN
+	IF  (GC = NilGC) OR (throughput < 32*1024*1024) THEN
 		GetFreeBlock(size, p);
 		IF  (p=NIL) THEN (* try restart sweep for once *)
 			GetFreeBlock(size, p);
@@ -1874,3 +1877,4 @@ Heaps.SetOld
 
 Kernel.GC
 
+SystemTools.ModuleState Heaps ~

+ 13 - 2
source/WMPerfMonTabSystem.Mod

@@ -13,7 +13,7 @@ TYPE
 
 		(* GC Statistics *)
 		gcCurrentRun : Perf.Indicator;
-		line1, line2 : Perf.Indicator;
+		line1, line2, line3 : Perf.Indicator;
 
 		(* CPU clock rate detection *)
 		cpuClockrate : Perf.Indicator;
@@ -99,6 +99,16 @@ TYPE
 			w.String(" ("); w.Int(Heaps.Nmark, 0); w.String(" calls to Heaps.Mark)");
 			w.Get(string);
 			line2.SetCaption(string);
+
+			(* Sweep phase *)
+			w.Reset;
+			w.String("Sweep phase: "); w.Int(Heaps.NgcSweeps, 0); w.String(" calls to sweep in ");
+			Plugins.MsToString(Plugins.CyclesToMs(Heaps.NgcSweepTime, clockrate), nbr); w.String(nbr);
+			w.String(" (max "); 
+			Plugins.MsToString(Plugins.CyclesToMs(Heaps.NgcSweepMax, clockrate), nbr); w.String(nbr);
+			w.String(")");
+			w.Get(string);
+			line3.SetCaption(string);
 		END HandleGcButton;
 
 		PROCEDURE HandleDetectButton(sender, data : ANY);
@@ -198,7 +208,7 @@ TYPE
 		PROCEDURE CreateGcStatisticsPanel() : WMStandardComponents.Panel;
 		VAR panel : WMStandardComponents.Panel; line : WMStandardComponents.Panel;
 		BEGIN
-			panel := Perf.NewGroupPanel("Garbage Collector", WMComponents.AlignTop, 80);
+			panel := Perf.NewGroupPanel("Garbage Collector", WMComponents.AlignTop, 120);
 
 			line := Perf.NewPanel(WMComponents.AlignTop, 0, 20); panel.AddContent(line);
 			line.AddContent(Perf.NewButton("Run GC", HandleGcButton));
@@ -208,6 +218,7 @@ TYPE
 
 			line1 := Perf.NewIndicator("", WMComponents.AlignTop, 0, 20); panel.AddContent(line1);
 			line2 := Perf.NewIndicator("", WMComponents.AlignTop, 0, 20); panel.AddContent(line2);
+			line3 := Perf.NewIndicator("", WMComponents.AlignTop, 0, 20); panel.AddContent(line3);
 
 			RETURN panel;
 		END CreateGcStatisticsPanel;