Browse Source

Intermediate step

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@7188 8c9fc860-2736-0410-a75d-ab315db34111
felixf 8 years ago
parent
commit
e3cd6e39d0
1 changed files with 11 additions and 7 deletions
  1. 11 7
      source/Heaps.Mod

+ 11 - 7
source/Heaps.Mod

@@ -561,6 +561,7 @@ END GetFreeBlock;
 PROCEDURE LazySweep(size: SIZE; VAR p: FreeBlock);
 PROCEDURE LazySweep(size: SIZE; VAR p: FreeBlock);
 VAR 
 VAR 
 	lastFreeBlockAdr: ADDRESS;
 	lastFreeBlockAdr: ADDRESS;
+	lastFreeBlockSize: SIZE;
 	block {UNTRACED}: HeapBlock ; freeBlock{UNTRACED}, lastFreeBlock{UNTRACED}: FreeBlock; 
 	block {UNTRACED}: HeapBlock ; freeBlock{UNTRACED}, lastFreeBlock{UNTRACED}: FreeBlock; 
 	blockMark: LONGINT; blockSize: SIZE;
 	blockMark: LONGINT; blockSize: SIZE;
 	time1, time2: HUGEINT;
 	time1, time2: HUGEINT;
@@ -584,7 +585,7 @@ BEGIN{UNCHECKED}
 			block := SYSTEM.VAL(HeapBlock, sweepBlockAdr + BlockHeaderSize); (* get heap block *)
 			block := SYSTEM.VAL(HeapBlock, sweepBlockAdr + BlockHeaderSize); (* get heap block *)
 			blockMark := block.mark; (* cache these values since they may be overwritten during concatenation *)
 			blockMark := block.mark; (* cache these values since they may be overwritten during concatenation *)
 			blockSize := block.size;
 			blockSize := block.size;
-			IF (blockMark < sweepMarkValue) THEN
+			IF (blockMark - sweepMarkValue < 0) THEN
 				IF (block IS SystemBlock) OR (block IS RecordBlock) OR (block IS ProtRecBlock) OR (block IS ArrayBlock) THEN
 				IF (block IS SystemBlock) OR (block IS RecordBlock) OR (block IS ProtRecBlock) OR (block IS ArrayBlock) THEN
 					freeBlock := SYSTEM.VAL(FreeBlock, block);
 					freeBlock := SYSTEM.VAL(FreeBlock, block);
 					InitFreeBlock(freeBlock, Unmarked, NilVal, blockSize); (* convert this block into a free heap block and clear its data *)
 					InitFreeBlock(freeBlock, Unmarked, NilVal, blockSize); (* convert this block into a free heap block and clear its data *)
@@ -596,8 +597,11 @@ BEGIN{UNCHECKED}
 				IF lastFreeBlockAdr = NilVal THEN
 				IF lastFreeBlockAdr = NilVal THEN
 					lastFreeBlockAdr := sweepBlockAdr;
 					lastFreeBlockAdr := sweepBlockAdr;
 					lastFreeBlock := freeBlock;
 					lastFreeBlock := freeBlock;
-				ELSIF lastFreeBlockAdr + lastFreeBlock.size = sweepBlockAdr THEN
+					lastFreeBlockSize := blockSize;
+				ELSE
+					ASSERT(lastFreeBlockAdr + lastFreeBlockSize = sweepBlockAdr);
 					(* there are two contiguous free blocks - merge them *)
 					(* there are two contiguous free blocks - merge them *)
+					INC(lastFreeBlockSize, blockSize);
 					INC(lastFreeBlock.size,blockSize);
 					INC(lastFreeBlock.size,blockSize);
 					(* overwrite free block -- for GC tracing in case something's wrong 
 					(* overwrite free block -- for GC tracing in case something's wrong 
 						should be moved down to merging phase
 						should be moved down to merging phase
@@ -608,17 +612,17 @@ BEGIN{UNCHECKED}
 				ASSERT(~(block IS FreeBlock));
 				ASSERT(~(block IS FreeBlock));
 			END;
 			END;
 			IF (lastFreeBlockAdr # NilVal) & ((blockMark >= sweepMarkValue) OR (sweepBlockAdr + blockSize = sweepMemBlock.endBlockAdr) 
 			IF (lastFreeBlockAdr # NilVal) & ((blockMark >= sweepMarkValue) OR (sweepBlockAdr + blockSize = sweepMemBlock.endBlockAdr) 
-				OR (ADDRESS(lastFreeBlock.size) >= ADDRESS (size))
+				OR (ADDRESS(lastFreeBlockSize) >= ADDRESS (size))
 			)
 			)
 			THEN (* no further merging is possible *)
 			THEN (* no further merging is possible *)
 				ASSERT(sweepBlockAdr + blockSize <= sweepMemBlock.endBlockAdr);
 				ASSERT(sweepBlockAdr + blockSize <= sweepMemBlock.endBlockAdr);
 				(*IF lastFreeBlockAdr # NilVal THEN*)
 				(*IF lastFreeBlockAdr # NilVal THEN*)
-					IF ADDRESS(lastFreeBlock.size) >= ADDRESS (size) THEN (* block found - may be too big *)
+					IF ADDRESS(lastFreeBlockSize (*lastFreeBlock.size*) ) >= ADDRESS (size) THEN (* block found - may be too big *)
 						p := lastFreeBlock;
 						p := lastFreeBlock;
-						IF ADDRESS(p.size) > ADDRESS (size) THEN (* block too big - divide block into two parts: block with required size and remaining free block *)
-							ASSERT(ADDRESS(p.size - size) >= FreeBlockHeaderSize);
+						IF ADDRESS(lastFreeBlockSize) > ADDRESS (size) THEN (* block too big - divide block into two parts: block with required size and remaining free block *)
+							ASSERT(ADDRESS(lastFreeBlockSize - size) >= FreeBlockHeaderSize);
 							freeBlock := SYSTEM.VAL(FreeBlock, SYSTEM.VAL(ADDRESS, p) + size);
 							freeBlock := SYSTEM.VAL(FreeBlock, SYSTEM.VAL(ADDRESS, p) + size);
-							InitFreeBlock(freeBlock, Unmarked, NilVal, p.size - size);
+							InitFreeBlock(freeBlock, Unmarked, NilVal, lastFreeBlockSize - size);
 							p.size := size;
 							p.size := size;
 						END;
 						END;
 						sweepBlockAdr := lastFreeBlockAdr + size; (* make sure next lazy sweep continues after block p *)
 						sweepBlockAdr := lastFreeBlockAdr + size; (* make sure next lazy sweep continues after block p *)