[Vm-dev] [commit][3288] CogVM source as per VMMaker.oscog-eem.1118

commits at squeakvm.org commits at squeakvm.org
Wed Mar 25 19:52:49 UTC 2015


Revision: 3288
Author:   eliot
Date:     2015-03-25 12:52:47 -0700 (Wed, 25 Mar 2015)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.1118

Work around a compiler bug in 64-bit gcc 4.4.7-4 on RedHat that elided one of
the two assignments to a corpse's header in threading it onto a weak survivor
list.  Do so by, in 64-bits, performing a single assignment to the corpse's
header, instead of two.

Mark copyToOldSpace:bytes:format: as not to be inlined so as to avoid impacting
copyAndForward's icache density.

Simplify the macros in sqMemoryAccess.h to avoid the double cast on the
oop argument of fooAtPointer[Put].

Modified Paths:
--------------
    branches/Cog/nsspursrc/vm/cointerp.c
    branches/Cog/nsspursrc/vm/cointerp.h
    branches/Cog/nsspursrc/vm/gcc3x-cointerp.c
    branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c
    branches/Cog/nsspurstacksrc/vm/interp.c
    branches/Cog/platforms/Cross/vm/sqMemoryAccess.h
    branches/Cog/spursistasrc/vm/cointerp.c
    branches/Cog/spursistasrc/vm/cointerp.h
    branches/Cog/spursistasrc/vm/gcc3x-cointerp.c
    branches/Cog/spursrc/vm/cointerp.c
    branches/Cog/spursrc/vm/cointerp.h
    branches/Cog/spursrc/vm/gcc3x-cointerp.c
    branches/Cog/spurstack64src/vm/gcc3x-interp.c
    branches/Cog/spurstack64src/vm/interp.c
    branches/Cog/spurstacksrc/vm/gcc3x-interp.c
    branches/Cog/spurstacksrc/vm/interp.c

Property Changed:
----------------
    branches/Cog/platforms/Cross/vm/sqSCCSVersion.h

Modified: branches/Cog/nsspursrc/vm/cointerp.c
===================================================================
--- branches/Cog/nsspursrc/vm/cointerp.c	2015-03-25 00:18:37 UTC (rev 3287)
+++ branches/Cog/nsspursrc/vm/cointerp.c	2015-03-25 19:52:47 UTC (rev 3288)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1117 uuid: 71e6dd3b-c884-47ec-a004-bce9fe9517c5
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1118 uuid: b055db97-d17b-4dfd-b281-57e8df3faf12
    from
-	CoInterpreter VMMaker.oscog-eem.1117 uuid: 71e6dd3b-c884-47ec-a004-bce9fe9517c5
+	CoInterpreter VMMaker.oscog-eem.1118 uuid: b055db97-d17b-4dfd-b281-57e8df3faf12
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1117 uuid: 71e6dd3b-c884-47ec-a004-bce9fe9517c5 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1118 uuid: b055db97-d17b-4dfd-b281-57e8df3faf12 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -845,10 +845,11 @@
 usqInt smallObjectBytesForSlots(sqInt numSlots);
 sqInt tagMask(void);
 static sqInt wordIndexableFormat(void);
-static void addToEphemeronList(sqInt ephemeronCorpse) NoDbgRegParms;
-static void addToWeakList(sqInt weakCorpse) NoDbgRegParms;
+static void addToEphemeronList(sqInt ephemeronCorpse) NoDbgRegParms NeverInline;
+static void addToWeakList(sqInt weakCorpse) NoDbgRegParms NeverInline;
 static sqInt allWeakSurvivorsOnWeakList(void);
 static sqInt copyAndForward(sqInt survivor) NoDbgRegParms;
+static sqInt copyToOldSpacebytesformat(sqInt survivor, sqInt bytesInObject, sqInt formatOfSurvivor) NoDbgRegParms NeverInline;
 static sqInt firstCorpse(sqInt headOfCorpseList) NoDbgRegParms;
 static void growRememberedSet(void);
 static sqInt isInRememberedSet(sqInt objOop) NoDbgRegParms;
@@ -1001,6 +1002,7 @@
 static sqInt goodContextSize(sqInt oop) NoDbgRegParms;
 static usqInt growOldSpaceByAtLeast(sqInt minAmmount) NoDbgRegParms;
 usqLong headerForSlotsformatclassIndex(sqInt numSlots, sqInt formatField, sqInt classIndex);
+usqLong headerForSlotshashformatclassIndex(sqInt numSlots, sqInt hash, sqInt formatField, sqInt classIndex);
 static sqInt hiddenRootSlots(void);
 sqInt identityHashHalfWordMask(void);
 static sqInt imageSegmentVersion(void);
@@ -1133,6 +1135,7 @@
 void printFreeList(sqInt chunkOrIndex);
 void printFreeTree(void);
 static void printFreeTreeChunk(sqInt chunkOrZero) NoDbgRegParms;
+void printHeaderOf(sqInt objOop);
 static void printHeaderTypeOf(sqInt objOop) NoDbgRegParms;
 void printInstancesOf(sqInt aClassOop);
 void printInstancesWithClassIndex(sqInt classIndex);
@@ -2363,7 +2366,7 @@
 /*560*/	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0,-1,-1
 	};
 char expensiveAsserts = 0;
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1117";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1118";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -6895,7 +6898,7 @@
 				usqInt newObj;
 				usqInt numBytes;
 				sqInt popValues;
-				sqInt size;
+				usqInt size;
 
 				VM_LABEL(pushNewArrayBytecode);
 				size = byteAtPointer(++localIP);
@@ -12855,7 +12858,7 @@
 				usqInt newObj;
 				usqInt numBytes;
 				sqInt popValues;
-				sqInt size;
+				usqInt size;
 
 				VM_LABEL(pushNewArrayBytecode1);
 				size = byteAtPointer(++localIP);
@@ -14206,7 +14209,7 @@
     CogMethod *cogMethod;
     sqInt methodField;
     sqInt methodField1;
-    usqInt theIP;
+    sqInt theIP;
 
 	assertl(GIV(stackPage) == (mostRecentlyUsedPage()), ln);
 	assertl(addressIsInPage(GIV(stackPage), lifp), ln);
@@ -28392,8 +28395,8 @@
     sqInt totalLength1;
     sqInt value;
     sqInt value1;
-    sqInt valueToStore;
-    sqInt valueToStore1;
+    usqInt valueToStore;
+    usqInt valueToStore1;
 
 	/* begin commonAtPut: */
 	value = longAt(GIV(stackPointer));
@@ -38408,8 +38411,8 @@
     sqInt totalLength1;
     sqInt value;
     sqInt value1;
-    sqInt valueToStore;
-    sqInt valueToStore1;
+    usqInt valueToStore;
+    usqInt valueToStore1;
 
 	/* begin commonAtPut: */
 	value = longAt(GIV(stackPointer));
@@ -41318,6 +41321,7 @@
 	references. Thread the corpse onto the weakList. Later, the weakList can
 	be followed, and
 	the forwarding pointer followed to locate the survivor. */
+/*	Should be too infrequent to lower icache density of copyAndForward: */
 
 static void
 addToEphemeronList(sqInt ephemeronCorpse)
@@ -41333,6 +41337,9 @@
 	/* begin setCorpseOffsetOf:to: */
 	assert(isYoung(ephemeronCorpse));
 	assert(isForwarded(ephemeronCorpse));
+	
+	/* On 64-bit gcc 4.4.7-4 the following is miscompiled at -O2; the first assignment is lost */
+
 	/* begin setHashBitsOf:to: */
 	hash = ((usqInt) ephemeronListOffset) >> 5;
 	flag("endianness");
@@ -41343,6 +41350,7 @@
 	assert(((format >= 0) && (format <= (formatMask()))));
 	flag("endianness");
 	longAtput(ephemeronCorpse, ((longAt(ephemeronCorpse)) & ((unsigned int)~(0x1F << 24))) + (format << 24));
+
 	GIV(ephemeronList) = (((usqInt) (ephemeronCorpse - GIV(newSpaceStart))) >> 3) + 1;
 	assert((firstCorpse(GIV(ephemeronList))) == ephemeronCorpse);
 }
@@ -41352,6 +41360,7 @@
 	Later on its surviving copy must be scanned to nil weak references.
 	Thread the corpse onto the weakList. Later, the weakList can be followed,
 	and the forwarding pointer followed to locate the survivor. */
+/*	Should be too infrequent to lower icache density of copyAndForward: */
 
 static void
 addToWeakList(sqInt weakCorpse)
@@ -41366,6 +41375,9 @@
 	/* begin setCorpseOffsetOf:to: */
 	assert(isYoung(weakCorpse));
 	assert(isForwarded(weakCorpse));
+	
+	/* On 64-bit gcc 4.4.7-4 the following is miscompiled at -O2; the first assignment is lost */
+
 	/* begin setHashBitsOf:to: */
 	hash = ((usqInt) weakListOffset) >> 5;
 	flag("endianness");
@@ -41376,6 +41388,7 @@
 	assert(((format >= 0) && (format <= (formatMask()))));
 	flag("endianness");
 	longAtput(weakCorpse, ((longAt(weakCorpse)) & ((unsigned int)~(0x1F << 24))) + (format << 24));
+
 	GIV(weakList) = (((usqInt) (weakCorpse - GIV(newSpaceStart))) >> 3) + 1;
 	assert((firstCorpse(GIV(weakList))) == weakCorpse);
 }
@@ -41426,12 +41439,8 @@
     usqInt bytesInObj;
     sqInt format;
     sqInt newLocation;
-    sqInt newOop;
     sqInt newStart;
-    sqInt newStart1;
-    sqInt nTenures;
     sqInt startOfSurvivor;
-    sqInt startOfSurvivor1;
     sqInt tenure;
 
 	assert((isInEden(survivor))
@@ -41462,46 +41471,18 @@
 	}
 	if (tenure
 	 || ((GIV(futureSurvivorStart) + bytesInObj) > ((GIV(futureSpace).limit)))) {
-		/* begin copyToOldSpace:bytes:format: */
-		assert((format == (formatOf(survivor)))
-		 && (((!(isMarked(survivor)))
-		 || (GIV(tenureCriterion) == MarkOnTenure))
-		 && ((!(isPinned(survivor)))
-		 && (!(isRemembered(survivor))))));
-		nTenures = GIV(statTenures);
-		startOfSurvivor = ((byteAt(survivor + 7)) == 0xFF
-			? survivor - BaseHeaderSize
-			: survivor);
-		newStart = allocateOldSpaceChunkOfBytes(bytesInObj);
-		if (!(newStart)) {
-			growOldSpaceByAtLeast(0);
-			newStart = allocateOldSpaceChunkOfBytes(bytesInObj);
-			if (!(newStart)) {
-				error("out of memory");
-			}
-		}
-		memcpy(((void *)newStart), ((void *)startOfSurvivor), bytesInObj);
-		newOop = newStart + (survivor - startOfSurvivor);
-		if ((format <= 5)
-		 || (format >= 24)) {
-			remember(newOop);
-		}
-		if (GIV(tenureCriterion) == MarkOnTenure) {
-			setIsMarkedOfto(newOop, 1);
-		}
-		GIV(statTenures) = nTenures + 1;
-		newLocation = newOop;
+		newLocation = copyToOldSpacebytesformat(survivor, bytesInObj, format);
 	}
 	else {
 		/* begin copyToFutureSpace:bytes: */
 		assert((GIV(futureSurvivorStart) + bytesInObj) <= ((GIV(futureSpace).limit)));
-		startOfSurvivor1 = ((byteAt(survivor + 7)) == 0xFF
+		startOfSurvivor = ((byteAt(survivor + 7)) == 0xFF
 			? survivor - BaseHeaderSize
 			: survivor);
-		newStart1 = GIV(futureSurvivorStart);
+		newStart = GIV(futureSurvivorStart);
 		GIV(futureSurvivorStart) += bytesInObj;
-		memcpy(((void *)newStart1), ((void *)startOfSurvivor1), bytesInObj);
-		newLocation = newStart1 + (survivor - startOfSurvivor1);
+		memcpy(((void *)newStart), ((void *)startOfSurvivor), bytesInObj);
+		newLocation = newStart + (survivor - startOfSurvivor);
 	}
 	/* begin forwardSurvivor:to: */
 	assert(isInNewSpace(survivor));
@@ -41525,7 +41506,49 @@
 	return newLocation;
 }
 
+
+/*	Copy survivor to oldSpace. Answer the new oop of the object. */
+/*	Should be too infrequent to lower icache density of copyAndForward: */
+
 static sqInt
+copyToOldSpacebytesformat(sqInt survivor, sqInt bytesInObject, sqInt formatOfSurvivor)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt newOop;
+    sqInt newStart;
+    sqInt nTenures;
+    sqInt startOfSurvivor;
+
+	assert((formatOfSurvivor == (formatOf(survivor)))
+	 && (((!(isMarked(survivor)))
+	 || (GIV(tenureCriterion) == MarkOnTenure))
+	 && ((!(isPinned(survivor)))
+	 && (!(isRemembered(survivor))))));
+	nTenures = GIV(statTenures);
+	startOfSurvivor = ((byteAt(survivor + 7)) == 0xFF
+		? survivor - BaseHeaderSize
+		: survivor);
+	newStart = allocateOldSpaceChunkOfBytes(bytesInObject);
+	if (!(newStart)) {
+		growOldSpaceByAtLeast(0);
+		newStart = allocateOldSpaceChunkOfBytes(bytesInObject);
+		if (!(newStart)) {
+			error("out of memory");
+		}
+	}
+	memcpy(((void *)newStart), ((void *)startOfSurvivor), bytesInObject);
+	newOop = newStart + (survivor - startOfSurvivor);
+	if ((formatOfSurvivor <= 5)
+	 || (formatOfSurvivor >= 24)) {
+		remember(newOop);
+	}
+	if (GIV(tenureCriterion) == MarkOnTenure) {
+		setIsMarkedOfto(newOop, 1);
+	}
+	GIV(statTenures) = nTenures + 1;
+	return newOop;
+}
+
+static sqInt
 firstCorpse(sqInt headOfCorpseList)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
 	return ((headOfCorpseList - 1) << 3) + GIV(newSpaceStart);
@@ -42488,6 +42511,9 @@
 				/* begin setCorpseOffsetOf:to: */
 				assert(isYoung(previousCorpse));
 				assert(isForwarded(previousCorpse));
+				
+				/* On 64-bit gcc 4.4.7-4 the following is miscompiled at -O2; the first assignment is lost */
+
 				/* begin setHashBitsOf:to: */
 				hash = ((usqInt) nextCorpseOffset) >> 5;
 				flag("endianness");
@@ -42498,6 +42524,7 @@
 				assert(((format >= 0) && (format <= (formatMask()))));
 				flag("endianness");
 				longAtput(previousCorpse, ((longAt(previousCorpse)) & ((unsigned int)~(0x1F << 24))) + (format << 24));
+
 			}
 			unfiredEphemeronsScavenged = 1;
 			((void) (scavengeReferentsOf(ephemeron)));
@@ -42891,7 +42918,7 @@
     sqInt ptr2;
     sqInt slotBytes;
     usqInt smallObj;
-    usqInt start;
+    sqInt start;
 
 	classIndex = (long32At(aClass + 4)) & 0x3FFFFF;
 	if (classIndex == 0) {
@@ -45825,7 +45852,7 @@
     sqInt fmt;
     sqInt hasYoung;
     sqInt i;
-    usqInt newObj;
+    sqInt newObj;
     usqInt newObj1;
     usqInt numBytes;
     usqInt numSlots;
@@ -45868,7 +45895,7 @@
 				GIV(needGCFlag) = 1;
 				forceInterruptCheck();
 			}
-			newObj = allocateSlotsInOldSpacebytesformatclassIndex(numSlots, numBytes, fmt, classIndex);
+			newObj = ((usqInt) (allocateSlotsInOldSpacebytesformatclassIndex(numSlots, numBytes, fmt, classIndex)));
 			goto l1;
 		}
 		if (numSlots >= 0xFF) {
@@ -48460,6 +48487,36 @@
 }
 
 
+/*	The header format in LSB is
+	MSB:	| 8: numSlots		| (on a byte boundary)
+	| 2 bits				|	(msb,lsb = {isMarked,?})
+	| 22: identityHash	| (on a word boundary)
+	| 3 bits				|	(msb <-> lsb = {isGrey,isPinned,isRemembered}
+	| 5: format			| (on a byte boundary)
+	| 2 bits				|	(msb,lsb = {isImmutable,?})
+	| 22: classIndex		| (on a word boundary) : LSB
+	The remaining bits (7) are used for
+	isImmutable	(bit 23)
+	isRemembered	(bit 29)
+	isPinned		(bit 30)
+	isGrey			(bit 31)
+	isMarked		(bit 55)
+	leaving 2 unused bits, each next to a 22-bit field, allowing those fields
+	to be
+	expanded to 23 bits.. The three bit field { isGrey, isPinned, isRemembered
+	} is for bits that are never set in young objects. This allows the
+	remembered table to be pruned when full by using these bits as a reference
+	count of
+	newSpace objects from the remembered table. Objects with a high count
+	should be tenured to prune the remembered table. */
+
+usqLong
+headerForSlotshashformatclassIndex(sqInt numSlots, sqInt hash, sqInt formatField, sqInt classIndex)
+{
+	return ((((((usqLong) numSlots)) << 56) + ((((usqLong) hash)) << (identityHashFullWordShift()))) + (formatField << 24)) + classIndex;
+}
+
+
 /*	Answer the number of extra root slots in the root of the hidden root
 	object. 
  */
@@ -58515,6 +58572,97 @@
 	}
 }
 
+
+/*	N.B. No safety bounds checks!! We need to look e.g. at corpses. */
+
+void
+printHeaderOf(sqInt objOop)
+{
+    sqInt aByte;
+    sqInt aByte1;
+    sqInt aByte2;
+    sqInt aByte3;
+    sqInt aByte4;
+    sqInt n;
+    sqInt n1;
+    sqInt n2;
+    sqInt n3;
+    sqInt n4;
+    usqInt numSlots;
+    usqInt numSlots1;
+
+	/* begin printHexnp: */
+	printf("0x%lx", ((unsigned long) objOop));
+	if ((numSlotsOfAny(objOop)) >= 0xFF) {
+		print(" hdr16 slotf ");
+		/* begin printHexnp: */
+		/* begin numSlotsOfAny: */
+		numSlots = byteAt((objOop - 8) + 7);
+		n = ((usqInt) ((numSlots == 0xFF
+	? longAt((objOop - 8) - BaseHeaderSize)
+	: numSlots)));
+		printf("0x%lx", ((unsigned long) n));
+		print(" slotc ");
+		/* begin printHexnp: */
+		printf("0x%lx", ((unsigned long) (longAt(objOop - BaseHeaderSize))));
+		/* begin space */
+		/* begin printChar: */
+		putchar(' ');
+	}
+	else {
+		print(" hdr8 slots ");
+		/* begin printHexnp: */
+		/* begin numSlotsOfAny: */
+		numSlots1 = byteAt(objOop + 7);
+		n1 = ((usqInt) ((numSlots1 == 0xFF
+	? longAt(objOop - BaseHeaderSize)
+	: numSlots1)));
+		printf("0x%lx", ((unsigned long) n1));
+	}
+	/* begin space */
+	/* begin printChar: */
+	putchar(' ');
+	/* begin printChar: */
+	aByte = (((((usqInt) (longAt(objOop + 4))) >> 23) & 1) != 0
+		? 'M'
+		: 'm');
+	putchar(aByte);
+	/* begin printChar: */
+	aByte1 = (((((usqInt) (longAt(objOop))) >> 0x1F) & 1) != 0
+		? 'G'
+		: 'g');
+	putchar(aByte1);
+	/* begin printChar: */
+	aByte2 = (((((usqInt) (longAt(objOop))) >> 30) & 1) != 0
+		? 'P'
+		: 'p');
+	putchar(aByte2);
+	/* begin printChar: */
+	aByte3 = (((((usqInt) (longAt(objOop))) >> 29) & 1) != 0
+		? 'R'
+		: 'r');
+	putchar(aByte3);
+	/* begin printChar: */
+	aByte4 = (((((usqInt) (longAt(objOop))) >> 23) & 1) != 0
+		? 'I'
+		: 'i');
+	putchar(aByte4);
+	print(" hash ");
+	/* begin printHexnp: */
+	n2 = (long32At(objOop + 4)) & 0x3FFFFF;
+	printf("0x%lx", ((unsigned long) n2));
+	print(" fmt ");
+	/* begin printHexnp: */
+	n3 = (((usqInt) (longAt(objOop))) >> 24) & 0x1F;
+	printf("0x%lx", ((unsigned long) n3));
+	print(" cidx ");
+	/* begin printHexnp: */
+	n4 = (longAt(objOop)) & 0x3FFFFF;
+	printf("0x%lx", ((unsigned long) n4));
+	/* begin cr */
+	printf("\n");
+}
+
 static void
 printHeaderTypeOf(sqInt objOop)
 {
@@ -61196,7 +61344,7 @@
 bridgeFromto(SpurSegmentInfo *aSegment, SpurSegmentInfo *nextSegmentOrNil)
 {
     sqInt bridgeSpan;
-    usqInt clifton;
+    sqInt clifton;
     usqInt segEnd;
 
 	segEnd = ((aSegment->segSize)) + ((aSegment->segStart));
@@ -61738,7 +61886,7 @@
     usqLong firstSavedBridgeWord;
     sqInt nWritten;
     usqInt pier1;
-    usqInt pier2;
+    sqInt pier2;
     usqLong secondSavedBridgeWord;
 
 	pier1 = (((segment->segSize)) + ((segment->segStart))) - (2 * BaseHeaderSize);
@@ -62243,7 +62391,7 @@
 static sqInt
 checkForAndFollowForwardedPrimitiveState(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt accessorDepth;
+    signed char accessorDepth;
     sqInt firstBytecode;
     sqInt found;
     sqInt header;
@@ -73032,7 +73180,7 @@
     sqInt sp1;
     sqInt stSize;
     sqInt totalLength;
-    sqInt valueToStore;
+    usqInt valueToStore;
 
 	hdr = long64At(array);
 	fmt = (((unsigned sqLong)hdr) >> 24) & 0x1F;
@@ -74295,8 +74443,8 @@
     sqInt totalLength;
     sqInt totalLength1;
     sqInt value;
-    sqInt valueToStore;
-    sqInt valueToStore1;
+    usqInt valueToStore;
+    usqInt valueToStore1;
 
 	value = longAt(GIV(stackPointer));
 	index = longAt(GIV(stackPointer) + (1 * BytesPerWord));
@@ -76068,7 +76216,7 @@
     sqInt rcvr;
     char *sp;
     sqInt totalLength;
-    sqInt valueToStore;
+    usqInt valueToStore;
 
 	newValue = longAt(GIV(stackPointer));
 	/* begin stackIntegerValue: */
@@ -76303,7 +76451,7 @@
     sqInt header1;
     sqInt i;
     sqInt methodHeader;
-    usqInt numSlots;
+    sqInt numSlots;
     usqInt numSlots1;
     sqInt rcvr;
     char *sp;
@@ -76359,9 +76507,9 @@
 			flag("endianness");
 			assert((classIndexOf(rcvr)) > (isForwardedObjectClassIndexPun()));
 			numSlots1 = byteAt(rcvr + 7);
-			numSlots = (numSlots1 == 0xFF
-				? longAt(rcvr - BaseHeaderSize)
-				: numSlots1);
+			numSlots = ((usqInt) ((numSlots1 == 0xFF
+	? longAt(rcvr - BaseHeaderSize)
+	: numSlots1)));
 		}
 	}
 	else {

Modified: branches/Cog/nsspursrc/vm/cointerp.h
===================================================================
--- branches/Cog/nsspursrc/vm/cointerp.h	2015-03-25 00:18:37 UTC (rev 3287)
+++ branches/Cog/nsspursrc/vm/cointerp.h	2015-03-25 19:52:47 UTC (rev 3288)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1117 uuid: 71e6dd3b-c884-47ec-a004-bce9fe9517c5
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1118 uuid: b055db97-d17b-4dfd-b281-57e8df3faf12
  */
 
 
@@ -178,6 +178,7 @@
 sqInt formatShift(void);
 sqInt freeObject(sqInt objOop);
 usqLong headerForSlotsformatclassIndex(sqInt numSlots, sqInt formatField, sqInt classIndex);
+usqLong headerForSlotshashformatclassIndex(sqInt numSlots, sqInt hash, sqInt formatField, sqInt classIndex);
 sqInt identityHashHalfWordMask(void);
 sqInt indexablePointersFormat(void);
 void inOrderPrintFreeTreeprintList(sqInt freeChunk, sqInt printNextList);
@@ -233,6 +234,7 @@
 void printFreeListHeads(void);
 void printFreeList(sqInt chunkOrIndex);
 void printFreeTree(void);
+void printHeaderOf(sqInt objOop);
 void printInstancesOf(sqInt aClassOop);
 void printInstancesWithClassIndex(sqInt classIndex);
 void printInvalidClassTableEntries(void);

Modified: branches/Cog/nsspursrc/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nsspursrc/vm/gcc3x-cointerp.c	2015-03-25 00:18:37 UTC (rev 3287)
+++ branches/Cog/nsspursrc/vm/gcc3x-cointerp.c	2015-03-25 19:52:47 UTC (rev 3288)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1117 uuid: 71e6dd3b-c884-47ec-a004-bce9fe9517c5
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1118 uuid: b055db97-d17b-4dfd-b281-57e8df3faf12
    from
-	CoInterpreter VMMaker.oscog-eem.1117 uuid: 71e6dd3b-c884-47ec-a004-bce9fe9517c5
+	CoInterpreter VMMaker.oscog-eem.1118 uuid: b055db97-d17b-4dfd-b281-57e8df3faf12
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1117 uuid: 71e6dd3b-c884-47ec-a004-bce9fe9517c5 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1118 uuid: b055db97-d17b-4dfd-b281-57e8df3faf12 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -848,10 +848,11 @@
 usqInt smallObjectBytesForSlots(sqInt numSlots);
 sqInt tagMask(void);
 static sqInt wordIndexableFormat(void);
-static void addToEphemeronList(sqInt ephemeronCorpse) NoDbgRegParms;
-static void addToWeakList(sqInt weakCorpse) NoDbgRegParms;
+static void addToEphemeronList(sqInt ephemeronCorpse) NoDbgRegParms NeverInline;
+static void addToWeakList(sqInt weakCorpse) NoDbgRegParms NeverInline;
 static sqInt allWeakSurvivorsOnWeakList(void);
 static sqInt copyAndForward(sqInt survivor) NoDbgRegParms;
+static sqInt copyToOldSpacebytesformat(sqInt survivor, sqInt bytesInObject, sqInt formatOfSurvivor) NoDbgRegParms NeverInline;
 static sqInt firstCorpse(sqInt headOfCorpseList) NoDbgRegParms;
 static void growRememberedSet(void);
 static sqInt isInRememberedSet(sqInt objOop) NoDbgRegParms;
@@ -1004,6 +1005,7 @@
 static sqInt goodContextSize(sqInt oop) NoDbgRegParms;
 static usqInt growOldSpaceByAtLeast(sqInt minAmmount) NoDbgRegParms;
 usqLong headerForSlotsformatclassIndex(sqInt numSlots, sqInt formatField, sqInt classIndex);
+usqLong headerForSlotshashformatclassIndex(sqInt numSlots, sqInt hash, sqInt formatField, sqInt classIndex);
 static sqInt hiddenRootSlots(void);
 sqInt identityHashHalfWordMask(void);
 static sqInt imageSegmentVersion(void);
@@ -1136,6 +1138,7 @@
 void printFreeList(sqInt chunkOrIndex);
 void printFreeTree(void);
 static void printFreeTreeChunk(sqInt chunkOrZero) NoDbgRegParms;
+void printHeaderOf(sqInt objOop);
 static void printHeaderTypeOf(sqInt objOop) NoDbgRegParms;
 void printInstancesOf(sqInt aClassOop);
 void printInstancesWithClassIndex(sqInt classIndex);
@@ -2366,7 +2369,7 @@
 /*560*/	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0,-1,-1
 	};
 char expensiveAsserts = 0;
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1117";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1118";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -6904,7 +6907,7 @@
 				usqInt newObj;
 				usqInt numBytes;
 				sqInt popValues;
-				sqInt size;
+				usqInt size;
 
 				VM_LABEL(pushNewArrayBytecode);
 				size = byteAtPointer(++localIP);
@@ -12864,7 +12867,7 @@
 				usqInt newObj;
 				usqInt numBytes;
 				sqInt popValues;
-				sqInt size;
+				usqInt size;
 
 				VM_LABEL(pushNewArrayBytecode1);
 				size = byteAtPointer(++localIP);
@@ -14215,7 +14218,7 @@
     CogMethod *cogMethod;
     sqInt methodField;
     sqInt methodField1;
-    usqInt theIP;
+    sqInt theIP;
 
 	assertl(GIV(stackPage) == (mostRecentlyUsedPage()), ln);
 	assertl(addressIsInPage(GIV(stackPage), lifp), ln);
@@ -28401,8 +28404,8 @@
     sqInt totalLength1;
     sqInt value;
     sqInt value1;
-    sqInt valueToStore;
-    sqInt valueToStore1;
+    usqInt valueToStore;
+    usqInt valueToStore1;
 
 	/* begin commonAtPut: */
 	value = longAt(GIV(stackPointer));
@@ -38417,8 +38420,8 @@
     sqInt totalLength1;
     sqInt value;
     sqInt value1;
-    sqInt valueToStore;
-    sqInt valueToStore1;
+    usqInt valueToStore;
+    usqInt valueToStore1;
 
 	/* begin commonAtPut: */
 	value = longAt(GIV(stackPointer));
@@ -41327,6 +41330,7 @@
 	references. Thread the corpse onto the weakList. Later, the weakList can
 	be followed, and
 	the forwarding pointer followed to locate the survivor. */
+/*	Should be too infrequent to lower icache density of copyAndForward: */
 
 static void
 addToEphemeronList(sqInt ephemeronCorpse)
@@ -41342,6 +41346,9 @@
 	/* begin setCorpseOffsetOf:to: */
 	assert(isYoung(ephemeronCorpse));
 	assert(isForwarded(ephemeronCorpse));
+	
+	/* On 64-bit gcc 4.4.7-4 the following is miscompiled at -O2; the first assignment is lost */
+
 	/* begin setHashBitsOf:to: */
 	hash = ((usqInt) ephemeronListOffset) >> 5;
 	flag("endianness");
@@ -41352,6 +41359,7 @@
 	assert(((format >= 0) && (format <= (formatMask()))));
 	flag("endianness");
 	longAtput(ephemeronCorpse, ((longAt(ephemeronCorpse)) & ((unsigned int)~(0x1F << 24))) + (format << 24));
+
 	GIV(ephemeronList) = (((usqInt) (ephemeronCorpse - GIV(newSpaceStart))) >> 3) + 1;
 	assert((firstCorpse(GIV(ephemeronList))) == ephemeronCorpse);
 }
@@ -41361,6 +41369,7 @@
 	Later on its surviving copy must be scanned to nil weak references.
 	Thread the corpse onto the weakList. Later, the weakList can be followed,
 	and the forwarding pointer followed to locate the survivor. */
+/*	Should be too infrequent to lower icache density of copyAndForward: */
 
 static void
 addToWeakList(sqInt weakCorpse)
@@ -41375,6 +41384,9 @@
 	/* begin setCorpseOffsetOf:to: */
 	assert(isYoung(weakCorpse));
 	assert(isForwarded(weakCorpse));
+	
+	/* On 64-bit gcc 4.4.7-4 the following is miscompiled at -O2; the first assignment is lost */
+
 	/* begin setHashBitsOf:to: */
 	hash = ((usqInt) weakListOffset) >> 5;
 	flag("endianness");
@@ -41385,6 +41397,7 @@
 	assert(((format >= 0) && (format <= (formatMask()))));
 	flag("endianness");
 	longAtput(weakCorpse, ((longAt(weakCorpse)) & ((unsigned int)~(0x1F << 24))) + (format << 24));
+
 	GIV(weakList) = (((usqInt) (weakCorpse - GIV(newSpaceStart))) >> 3) + 1;
 	assert((firstCorpse(GIV(weakList))) == weakCorpse);
 }
@@ -41435,12 +41448,8 @@
     usqInt bytesInObj;
     sqInt format;
     sqInt newLocation;
-    sqInt newOop;
     sqInt newStart;
-    sqInt newStart1;
-    sqInt nTenures;
     sqInt startOfSurvivor;
-    sqInt startOfSurvivor1;
     sqInt tenure;
 
 	assert((isInEden(survivor))
@@ -41471,46 +41480,18 @@
 	}
 	if (tenure
 	 || ((GIV(futureSurvivorStart) + bytesInObj) > ((GIV(futureSpace).limit)))) {
-		/* begin copyToOldSpace:bytes:format: */
-		assert((format == (formatOf(survivor)))
-		 && (((!(isMarked(survivor)))
-		 || (GIV(tenureCriterion) == MarkOnTenure))
-		 && ((!(isPinned(survivor)))
-		 && (!(isRemembered(survivor))))));
-		nTenures = GIV(statTenures);
-		startOfSurvivor = ((byteAt(survivor + 7)) == 0xFF
-			? survivor - BaseHeaderSize
-			: survivor);
-		newStart = allocateOldSpaceChunkOfBytes(bytesInObj);
-		if (!(newStart)) {
-			growOldSpaceByAtLeast(0);
-			newStart = allocateOldSpaceChunkOfBytes(bytesInObj);
-			if (!(newStart)) {
-				error("out of memory");
-			}
-		}
-		memcpy(((void *)newStart), ((void *)startOfSurvivor), bytesInObj);
-		newOop = newStart + (survivor - startOfSurvivor);
-		if ((format <= 5)
-		 || (format >= 24)) {
-			remember(newOop);
-		}
-		if (GIV(tenureCriterion) == MarkOnTenure) {
-			setIsMarkedOfto(newOop, 1);
-		}
-		GIV(statTenures) = nTenures + 1;
-		newLocation = newOop;
+		newLocation = copyToOldSpacebytesformat(survivor, bytesInObj, format);
 	}
 	else {
 		/* begin copyToFutureSpace:bytes: */
 		assert((GIV(futureSurvivorStart) + bytesInObj) <= ((GIV(futureSpace).limit)));
-		startOfSurvivor1 = ((byteAt(survivor + 7)) == 0xFF
+		startOfSurvivor = ((byteAt(survivor + 7)) == 0xFF
 			? survivor - BaseHeaderSize
 			: survivor);
-		newStart1 = GIV(futureSurvivorStart);
+		newStart = GIV(futureSurvivorStart);
 		GIV(futureSurvivorStart) += bytesInObj;
-		memcpy(((void *)newStart1), ((void *)startOfSurvivor1), bytesInObj);
-		newLocation = newStart1 + (survivor - startOfSurvivor1);
+		memcpy(((void *)newStart), ((void *)startOfSurvivor), bytesInObj);
+		newLocation = newStart + (survivor - startOfSurvivor);
 	}
 	/* begin forwardSurvivor:to: */
 	assert(isInNewSpace(survivor));
@@ -41534,7 +41515,49 @@
 	return newLocation;
 }
 
+
+/*	Copy survivor to oldSpace. Answer the new oop of the object. */
+/*	Should be too infrequent to lower icache density of copyAndForward: */
+
 static sqInt
+copyToOldSpacebytesformat(sqInt survivor, sqInt bytesInObject, sqInt formatOfSurvivor)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt newOop;
+    sqInt newStart;
+    sqInt nTenures;
+    sqInt startOfSurvivor;
+
+	assert((formatOfSurvivor == (formatOf(survivor)))
+	 && (((!(isMarked(survivor)))
+	 || (GIV(tenureCriterion) == MarkOnTenure))
+	 && ((!(isPinned(survivor)))
+	 && (!(isRemembered(survivor))))));
+	nTenures = GIV(statTenures);
+	startOfSurvivor = ((byteAt(survivor + 7)) == 0xFF
+		? survivor - BaseHeaderSize
+		: survivor);
+	newStart = allocateOldSpaceChunkOfBytes(bytesInObject);
+	if (!(newStart)) {
+		growOldSpaceByAtLeast(0);
+		newStart = allocateOldSpaceChunkOfBytes(bytesInObject);
+		if (!(newStart)) {
+			error("out of memory");
+		}
+	}
+	memcpy(((void *)newStart), ((void *)startOfSurvivor), bytesInObject);
+	newOop = newStart + (survivor - startOfSurvivor);
+	if ((formatOfSurvivor <= 5)
+	 || (formatOfSurvivor >= 24)) {
+		remember(newOop);
+	}
+	if (GIV(tenureCriterion) == MarkOnTenure) {
+		setIsMarkedOfto(newOop, 1);
+	}
+	GIV(statTenures) = nTenures + 1;
+	return newOop;
+}
+
+static sqInt
 firstCorpse(sqInt headOfCorpseList)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
 	return ((headOfCorpseList - 1) << 3) + GIV(newSpaceStart);
@@ -42497,6 +42520,9 @@
 				/* begin setCorpseOffsetOf:to: */
 				assert(isYoung(previousCorpse));
 				assert(isForwarded(previousCorpse));
+				
+				/* On 64-bit gcc 4.4.7-4 the following is miscompiled at -O2; the first assignment is lost */
+
 				/* begin setHashBitsOf:to: */
 				hash = ((usqInt) nextCorpseOffset) >> 5;
 				flag("endianness");
@@ -42507,6 +42533,7 @@
 				assert(((format >= 0) && (format <= (formatMask()))));
 				flag("endianness");
 				longAtput(previousCorpse, ((longAt(previousCorpse)) & ((unsigned int)~(0x1F << 24))) + (format << 24));
+
 			}
 			unfiredEphemeronsScavenged = 1;
 			((void) (scavengeReferentsOf(ephemeron)));
@@ -42900,7 +42927,7 @@
     sqInt ptr2;
     sqInt slotBytes;
     usqInt smallObj;
-    usqInt start;
+    sqInt start;
 
 	classIndex = (long32At(aClass + 4)) & 0x3FFFFF;
 	if (classIndex == 0) {
@@ -45834,7 +45861,7 @@
     sqInt fmt;
     sqInt hasYoung;
     sqInt i;
-    usqInt newObj;
+    sqInt newObj;
     usqInt newObj1;
     usqInt numBytes;
     usqInt numSlots;
@@ -45877,7 +45904,7 @@
 				GIV(needGCFlag) = 1;
 				forceInterruptCheck();
 			}
-			newObj = allocateSlotsInOldSpacebytesformatclassIndex(numSlots, numBytes, fmt, classIndex);
+			newObj = ((usqInt) (allocateSlotsInOldSpacebytesformatclassIndex(numSlots, numBytes, fmt, classIndex)));
 			goto l1;
 		}
 		if (numSlots >= 0xFF) {
@@ -48469,6 +48496,36 @@
 }
 
 
+/*	The header format in LSB is
+	MSB:	| 8: numSlots		| (on a byte boundary)
+	| 2 bits				|	(msb,lsb = {isMarked,?})
+	| 22: identityHash	| (on a word boundary)
+	| 3 bits				|	(msb <-> lsb = {isGrey,isPinned,isRemembered}
+	| 5: format			| (on a byte boundary)
+	| 2 bits				|	(msb,lsb = {isImmutable,?})
+	| 22: classIndex		| (on a word boundary) : LSB
+	The remaining bits (7) are used for
+	isImmutable	(bit 23)
+	isRemembered	(bit 29)
+	isPinned		(bit 30)
+	isGrey			(bit 31)
+	isMarked		(bit 55)
+	leaving 2 unused bits, each next to a 22-bit field, allowing those fields
+	to be
+	expanded to 23 bits.. The three bit field { isGrey, isPinned, isRemembered
+	} is for bits that are never set in young objects. This allows the
+	remembered table to be pruned when full by using these bits as a reference
+	count of
+	newSpace objects from the remembered table. Objects with a high count
+	should be tenured to prune the remembered table. */
+
+usqLong
+headerForSlotshashformatclassIndex(sqInt numSlots, sqInt hash, sqInt formatField, sqInt classIndex)
+{
+	return ((((((usqLong) numSlots)) << 56) + ((((usqLong) hash)) << (identityHashFullWordShift()))) + (formatField << 24)) + classIndex;
+}
+
+
 /*	Answer the number of extra root slots in the root of the hidden root
 	object. 
  */
@@ -58524,6 +58581,97 @@
 	}
 }
 
+
+/*	N.B. No safety bounds checks!! We need to look e.g. at corpses. */
+
+void
+printHeaderOf(sqInt objOop)
+{
+    sqInt aByte;
+    sqInt aByte1;
+    sqInt aByte2;
+    sqInt aByte3;
+    sqInt aByte4;
+    sqInt n;
+    sqInt n1;
+    sqInt n2;
+    sqInt n3;
+    sqInt n4;
+    usqInt numSlots;
+    usqInt numSlots1;
+
+	/* begin printHexnp: */
+	printf("0x%lx", ((unsigned long) objOop));
+	if ((numSlotsOfAny(objOop)) >= 0xFF) {
+		print(" hdr16 slotf ");
+		/* begin printHexnp: */
+		/* begin numSlotsOfAny: */
+		numSlots = byteAt((objOop - 8) + 7);
+		n = ((usqInt) ((numSlots == 0xFF
+	? longAt((objOop - 8) - BaseHeaderSize)
+	: numSlots)));
+		printf("0x%lx", ((unsigned long) n));
+		print(" slotc ");
+		/* begin printHexnp: */
+		printf("0x%lx", ((unsigned long) (longAt(objOop - BaseHeaderSize))));
+		/* begin space */
+		/* begin printChar: */
+		putchar(' ');
+	}
+	else {
+		print(" hdr8 slots ");
+		/* begin printHexnp: */
+		/* begin numSlotsOfAny: */
+		numSlots1 = byteAt(objOop + 7);
+		n1 = ((usqInt) ((numSlots1 == 0xFF
+	? longAt(objOop - BaseHeaderSize)
+	: numSlots1)));
+		printf("0x%lx", ((unsigned long) n1));
+	}
+	/* begin space */
+	/* begin printChar: */
+	putchar(' ');
+	/* begin printChar: */
+	aByte = (((((usqInt) (longAt(objOop + 4))) >> 23) & 1) != 0
+		? 'M'
+		: 'm');
+	putchar(aByte);
+	/* begin printChar: */
+	aByte1 = (((((usqInt) (longAt(objOop))) >> 0x1F) & 1) != 0
+		? 'G'
+		: 'g');
+	putchar(aByte1);
+	/* begin printChar: */
+	aByte2 = (((((usqInt) (longAt(objOop))) >> 30) & 1) != 0
+		? 'P'
+		: 'p');
+	putchar(aByte2);
+	/* begin printChar: */
+	aByte3 = (((((usqInt) (longAt(objOop))) >> 29) & 1) != 0
+		? 'R'
+		: 'r');
+	putchar(aByte3);
+	/* begin printChar: */
+	aByte4 = (((((usqInt) (longAt(objOop))) >> 23) & 1) != 0
+		? 'I'
+		: 'i');
+	putchar(aByte4);
+	print(" hash ");
+	/* begin printHexnp: */
+	n2 = (long32At(objOop + 4)) & 0x3FFFFF;
+	printf("0x%lx", ((unsigned long) n2));
+	print(" fmt ");
+	/* begin printHexnp: */
+	n3 = (((usqInt) (longAt(objOop))) >> 24) & 0x1F;
+	printf("0x%lx", ((unsigned long) n3));
+	print(" cidx ");
+	/* begin printHexnp: */
+	n4 = (longAt(objOop)) & 0x3FFFFF;
+	printf("0x%lx", ((unsigned long) n4));
+	/* begin cr */
+	printf("\n");
+}
+
 static void
 printHeaderTypeOf(sqInt objOop)
 {
@@ -61205,7 +61353,7 @@
 bridgeFromto(SpurSegmentInfo *aSegment, SpurSegmentInfo *nextSegmentOrNil)
 {
     sqInt bridgeSpan;
-    usqInt clifton;
+    sqInt clifton;
     usqInt segEnd;
 
 	segEnd = ((aSegment->segSize)) + ((aSegment->segStart));
@@ -61747,7 +61895,7 @@
     usqLong firstSavedBridgeWord;
     sqInt nWritten;
     usqInt pier1;
-    usqInt pier2;
+    sqInt pier2;
     usqLong secondSavedBridgeWord;
 
 	pier1 = (((segment->segSize)) + ((segment->segStart))) - (2 * BaseHeaderSize);
@@ -62252,7 +62400,7 @@
 static sqInt
 checkForAndFollowForwardedPrimitiveState(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt accessorDepth;
+    signed char accessorDepth;
     sqInt firstBytecode;
     sqInt found;
     sqInt header;
@@ -73041,7 +73189,7 @@
     sqInt sp1;
     sqInt stSize;
     sqInt totalLength;
-    sqInt valueToStore;
+    usqInt valueToStore;
 
 	hdr = long64At(array);
 	fmt = (((unsigned sqLong)hdr) >> 24) & 0x1F;
@@ -74304,8 +74452,8 @@
     sqInt totalLength;
     sqInt totalLength1;
     sqInt value;
-    sqInt valueToStore;
-    sqInt valueToStore1;
+    usqInt valueToStore;
+    usqInt valueToStore1;
 
 	value = longAt(GIV(stackPointer));
 	index = longAt(GIV(stackPointer) + (1 * BytesPerWord));
@@ -76077,7 +76225,7 @@
     sqInt rcvr;
     char *sp;
     sqInt totalLength;
-    sqInt valueToStore;
+    usqInt valueToStore;
 
 	newValue = longAt(GIV(stackPointer));
 	/* begin stackIntegerValue: */
@@ -76312,7 +76460,7 @@
     sqInt header1;
     sqInt i;
     sqInt methodHeader;
-    usqInt numSlots;
+    sqInt numSlots;
     usqInt numSlots1;
     sqInt rcvr;
     char *sp;
@@ -76368,9 +76516,9 @@
 			flag("endianness");
 			assert((classIndexOf(rcvr)) > (isForwardedObjectClassIndexPun()));
 			numSlots1 = byteAt(rcvr + 7);
-			numSlots = (numSlots1 == 0xFF
-				? longAt(rcvr - BaseHeaderSize)
-				: numSlots1);
+			numSlots = ((usqInt) ((numSlots1 == 0xFF
+	? longAt(rcvr - BaseHeaderSize)
+	: numSlots1)));
 		}
 	}
 	else {

Modified: branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c
===================================================================
--- branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c	2015-03-25 00:18:37 UTC (rev 3287)
+++ branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c	2015-03-25 19:52:47 UTC (rev 3288)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1117 uuid: 71e6dd3b-c884-47ec-a004-bce9fe9517c5
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1118 uuid: b055db97-d17b-4dfd-b281-57e8df3faf12
    from
-	StackInterpreter VMMaker.oscog-eem.1117 uuid: 71e6dd3b-c884-47ec-a004-bce9fe9517c5
+	StackInterpreter VMMaker.oscog-eem.1118 uuid: b055db97-d17b-4dfd-b281-57e8df3faf12
  */
-static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.1117 uuid: 71e6dd3b-c884-47ec-a004-bce9fe9517c5 " __DATE__ ;
+static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.1118 uuid: b055db97-d17b-4dfd-b281-57e8df3faf12 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -596,10 +596,11 @@
 usqInt smallObjectBytesForSlots(sqInt numSlots);
 sqInt tagMask(void);
 static sqInt wordIndexableFormat(void);
-static void addToEphemeronList(sqInt ephemeronCorpse) NoDbgRegParms;
-static void addToWeakList(sqInt weakCorpse) NoDbgRegParms;
+static void addToEphemeronList(sqInt ephemeronCorpse) NoDbgRegParms NeverInline;
+static void addToWeakList(sqInt weakCorpse) NoDbgRegParms NeverInline;
 static sqInt allWeakSurvivorsOnWeakList(void);
 static sqInt copyAndForward(sqInt survivor) NoDbgRegParms;
+static sqInt copyToOldSpacebytesformat(sqInt survivor, sqInt bytesInObject, sqInt formatOfSurvivor) NoDbgRegParms NeverInline;
 static sqInt firstCorpse(sqInt headOfCorpseList) NoDbgRegParms;
 static void growRememberedSet(void);
 static sqInt isInRememberedSet(sqInt objOop) NoDbgRegParms;
@@ -752,6 +753,7 @@
 static sqInt goodContextSize(sqInt oop) NoDbgRegParms;
 static usqInt growOldSpaceByAtLeast(sqInt minAmmount) NoDbgRegParms;
 usqLong headerForSlotsformatclassIndex(sqInt numSlots, sqInt formatField, sqInt classIndex);
+usqLong headerForSlotshashformatclassIndex(sqInt numSlots, sqInt hash, sqInt formatField, sqInt classIndex);
 static sqInt hiddenRootSlots(void);
 sqInt identityHashHalfWordMask(void);
 static sqInt imageSegmentVersion(void);
@@ -884,6 +886,7 @@
 void printFreeList(sqInt chunkOrIndex);
 void printFreeTree(void);
 static void printFreeTreeChunk(sqInt chunkOrZero) NoDbgRegParms;
+void printHeaderOf(sqInt objOop);
 static void printHeaderTypeOf(sqInt objOop) NoDbgRegParms;
 void printInstancesOf(sqInt aClassOop);
 void printInstancesWithClassIndex(sqInt classIndex);
@@ -2112,7 +2115,7 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 char expensiveAsserts = 0;
-const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreterPrimitives_VMMaker.oscog-eem.1117";
+const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreterPrimitives_VMMaker.oscog-eem.1118";
 volatile int sendTrace;
 sqInt suppressHeartbeatFlag;
 
@@ -27644,6 +27647,7 @@
 	references. Thread the corpse onto the weakList. Later, the weakList can
 	be followed, and
 	the forwarding pointer followed to locate the survivor. */
+/*	Should be too infrequent to lower icache density of copyAndForward: */
 
 static void
 addToEphemeronList(sqInt ephemeronCorpse)
@@ -27659,6 +27663,9 @@
 	/* begin setCorpseOffsetOf:to: */
 	assert(isYoung(ephemeronCorpse));
 	assert(isForwarded(ephemeronCorpse));
+	
+	/* On 64-bit gcc 4.4.7-4 the following is miscompiled at -O2; the first assignment is lost */
+
 	/* begin setHashBitsOf:to: */
 	hash = ((usqInt) ephemeronListOffset) >> 5;
 	flag("endianness");
@@ -27669,6 +27676,7 @@
 	assert(((format >= 0) && (format <= (formatMask()))));
 	flag("endianness");
 	longAtput(ephemeronCorpse, ((longAt(ephemeronCorpse)) & ((unsigned int)~(0x1F << 24))) + (format << 24));
+
 	GIV(ephemeronList) = (((usqInt) (ephemeronCorpse - GIV(newSpaceStart))) >> 3) + 1;
 	assert((firstCorpse(GIV(ephemeronList))) == ephemeronCorpse);
 }
@@ -27678,6 +27686,7 @@
 	Later on its surviving copy must be scanned to nil weak references.
 	Thread the corpse onto the weakList. Later, the weakList can be followed,
 	and the forwarding pointer followed to locate the survivor. */
+/*	Should be too infrequent to lower icache density of copyAndForward: */
 
 static void
 addToWeakList(sqInt weakCorpse)
@@ -27692,6 +27701,9 @@
 	/* begin setCorpseOffsetOf:to: */
 	assert(isYoung(weakCorpse));
 	assert(isForwarded(weakCorpse));
+	
+	/* On 64-bit gcc 4.4.7-4 the following is miscompiled at -O2; the first assignment is lost */
+
 	/* begin setHashBitsOf:to: */
 	hash = ((usqInt) weakListOffset) >> 5;
 	flag("endianness");
@@ -27702,6 +27714,7 @@
 	assert(((format >= 0) && (format <= (formatMask()))));
 	flag("endianness");
 	longAtput(weakCorpse, ((longAt(weakCorpse)) & ((unsigned int)~(0x1F << 24))) + (format << 24));
+
 	GIV(weakList) = (((usqInt) (weakCorpse - GIV(newSpaceStart))) >> 3) + 1;
 	assert((firstCorpse(GIV(weakList))) == weakCorpse);
 }
@@ -27752,12 +27765,8 @@
     usqInt bytesInObj;
     sqInt format;
     sqInt newLocation;
-    sqInt newOop;
     sqInt newStart;
-    sqInt newStart1;
-    sqInt nTenures;
     sqInt startOfSurvivor;
-    sqInt startOfSurvivor1;
     sqInt tenure;
 
 	assert((isInEden(survivor))
@@ -27788,46 +27797,18 @@
 	}
 	if (tenure
 	 || ((GIV(futureSurvivorStart) + bytesInObj) > ((GIV(futureSpace).limit)))) {
-		/* begin copyToOldSpace:bytes:format: */
-		assert((format == (formatOf(survivor)))
-		 && (((!(isMarked(survivor)))
-		 || (GIV(tenureCriterion) == MarkOnTenure))
-		 && ((!(isPinned(survivor)))
-		 && (!(isRemembered(survivor))))));
-		nTenures = GIV(statTenures);
-		startOfSurvivor = ((byteAt(survivor + 7)) == 0xFF
-			? survivor - BaseHeaderSize
-			: survivor);
-		newStart = allocateOldSpaceChunkOfBytes(bytesInObj);
-		if (!(newStart)) {
-			growOldSpaceByAtLeast(0);
-			newStart = allocateOldSpaceChunkOfBytes(bytesInObj);
-			if (!(newStart)) {
-				error("out of memory");
-			}
-		}
-		memcpy(((void *)newStart), ((void *)startOfSurvivor), bytesInObj);
-		newOop = newStart + (survivor - startOfSurvivor);
-		if ((format <= 5)
-		 || (format >= 24)) {
-			remember(newOop);
-		}
-		if (GIV(tenureCriterion) == MarkOnTenure) {
-			setIsMarkedOfto(newOop, 1);
-		}
-		GIV(statTenures) = nTenures + 1;
-		newLocation = newOop;
+		newLocation = copyToOldSpacebytesformat(survivor, bytesInObj, format);
 	}
 	else {
 		/* begin copyToFutureSpace:bytes: */
 		assert((GIV(futureSurvivorStart) + bytesInObj) <= ((GIV(futureSpace).limit)));
-		startOfSurvivor1 = ((byteAt(survivor + 7)) == 0xFF
+		startOfSurvivor = ((byteAt(survivor + 7)) == 0xFF
 			? survivor - BaseHeaderSize
 			: survivor);
-		newStart1 = GIV(futureSurvivorStart);
+		newStart = GIV(futureSurvivorStart);
 		GIV(futureSurvivorStart) += bytesInObj;
-		memcpy(((void *)newStart1), ((void *)startOfSurvivor1), bytesInObj);
-		newLocation = newStart1 + (survivor - startOfSurvivor1);
+		memcpy(((void *)newStart), ((void *)startOfSurvivor), bytesInObj);
+		newLocation = newStart + (survivor - startOfSurvivor);
 	}
 	/* begin forwardSurvivor:to: */
 	assert(isInNewSpace(survivor));
@@ -27851,7 +27832,49 @@
 	return newLocation;
 }
 
+
+/*	Copy survivor to oldSpace. Answer the new oop of the object. */
+/*	Should be too infrequent to lower icache density of copyAndForward: */
+
 static sqInt
+copyToOldSpacebytesformat(sqInt survivor, sqInt bytesInObject, sqInt formatOfSurvivor)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt newOop;
+    sqInt newStart;
+    sqInt nTenures;
+    sqInt startOfSurvivor;
+
+	assert((formatOfSurvivor == (formatOf(survivor)))
+	 && (((!(isMarked(survivor)))
+	 || (GIV(tenureCriterion) == MarkOnTenure))
+	 && ((!(isPinned(survivor)))
+	 && (!(isRemembered(survivor))))));
+	nTenures = GIV(statTenures);
+	startOfSurvivor = ((byteAt(survivor + 7)) == 0xFF
+		? survivor - BaseHeaderSize
+		: survivor);
+	newStart = allocateOldSpaceChunkOfBytes(bytesInObject);
+	if (!(newStart)) {
+		growOldSpaceByAtLeast(0);
+		newStart = allocateOldSpaceChunkOfBytes(bytesInObject);
+		if (!(newStart)) {
+			error("out of memory");
+		}
+	}
+	memcpy(((void *)newStart), ((void *)startOfSurvivor), bytesInObject);
+	newOop = newStart + (survivor - startOfSurvivor);
+	if ((formatOfSurvivor <= 5)
+	 || (formatOfSurvivor >= 24)) {
+		remember(newOop);
+	}
+	if (GIV(tenureCriterion) == MarkOnTenure) {
+		setIsMarkedOfto(newOop, 1);
+	}
+	GIV(statTenures) = nTenures + 1;
+	return newOop;
+}
+
+static sqInt
 firstCorpse(sqInt headOfCorpseList)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
 	return ((headOfCorpseList - 1) << 3) + GIV(newSpaceStart);
@@ -28805,6 +28828,9 @@
 				/* begin setCorpseOffsetOf:to: */
 				assert(isYoung(previousCorpse));
 				assert(isForwarded(previousCorpse));
+				
+				/* On 64-bit gcc 4.4.7-4 the following is miscompiled at -O2; the first assignment is lost */
+
 				/* begin setHashBitsOf:to: */
 				hash = ((usqInt) nextCorpseOffset) >> 5;
 				flag("endianness");
@@ -28815,6 +28841,7 @@
 				assert(((format >= 0) && (format <= (formatMask()))));
 				flag("endianness");
 				longAtput(previousCorpse, ((longAt(previousCorpse)) & ((unsigned int)~(0x1F << 24))) + (format << 24));
+
 			}
 			unfiredEphemeronsScavenged = 1;
 			((void) (scavengeReferentsOf(ephemeron)));
@@ -34836,6 +34863,36 @@
 }
 
 
+/*	The header format in LSB is
+	MSB:	| 8: numSlots		| (on a byte boundary)
+	| 2 bits				|	(msb,lsb = {isMarked,?})
+	| 22: identityHash	| (on a word boundary)
+	| 3 bits				|	(msb <-> lsb = {isGrey,isPinned,isRemembered}
+	| 5: format			| (on a byte boundary)
+	| 2 bits				|	(msb,lsb = {isImmutable,?})
+	| 22: classIndex		| (on a word boundary) : LSB
+	The remaining bits (7) are used for
+	isImmutable	(bit 23)
+	isRemembered	(bit 29)
+	isPinned		(bit 30)
+	isGrey			(bit 31)
+	isMarked		(bit 55)
+	leaving 2 unused bits, each next to a 22-bit field, allowing those fields
+	to be
+	expanded to 23 bits.. The three bit field { isGrey, isPinned, isRemembered
+	} is for bits that are never set in young objects. This allows the
+	remembered table to be pruned when full by using these bits as a reference
+	count of
+	newSpace objects from the remembered table. Objects with a high count
+	should be tenured to prune the remembered table. */
+
+usqLong
+headerForSlotshashformatclassIndex(sqInt numSlots, sqInt hash, sqInt formatField, sqInt classIndex)
+{
+	return ((((((usqLong) numSlots)) << 56) + ((((usqLong) hash)) << (identityHashFullWordShift()))) + (formatField << 24)) + classIndex;
+}
+
+
 /*	Answer the number of extra root slots in the root of the hidden root
 	object. 
  */
@@ -44663,6 +44720,97 @@
 	}
 }
 
+
+/*	N.B. No safety bounds checks!! We need to look e.g. at corpses. */
+
+void
+printHeaderOf(sqInt objOop)
+{
+    sqInt aByte;
+    sqInt aByte1;
+    sqInt aByte2;
+    sqInt aByte3;
+    sqInt aByte4;
+    sqInt n;
+    sqInt n1;
+    sqInt n2;
+    sqInt n3;
+    sqInt n4;
+    usqInt numSlots;
+    usqInt numSlots1;
+
+	/* begin printHexnp: */
+	printf("0x%lx", ((unsigned long) objOop));
+	if ((numSlotsOfAny(objOop)) >= 0xFF) {
+		print(" hdr16 slotf ");
+		/* begin printHexnp: */
+		/* begin numSlotsOfAny: */
+		numSlots = byteAt((objOop - 8) + 7);
+		n = ((usqInt) ((numSlots == 0xFF
+	? longAt((objOop - 8) - BaseHeaderSize)
+	: numSlots)));
+		printf("0x%lx", ((unsigned long) n));
+		print(" slotc ");
+		/* begin printHexnp: */
+		printf("0x%lx", ((unsigned long) (longAt(objOop - BaseHeaderSize))));
+		/* begin space */
+		/* begin printChar: */
+		putchar(' ');
+	}
+	else {
+		print(" hdr8 slots ");
+		/* begin printHexnp: */
+		/* begin numSlotsOfAny: */
+		numSlots1 = byteAt(objOop + 7);
+		n1 = ((usqInt) ((numSlots1 == 0xFF
+	? longAt(objOop - BaseHeaderSize)
+	: numSlots1)));
+		printf("0x%lx", ((unsigned long) n1));
+	}
+	/* begin space */
+	/* begin printChar: */
+	putchar(' ');
+	/* begin printChar: */
+	aByte = (((((usqInt) (longAt(objOop + 4))) >> 23) & 1) != 0
+		? 'M'
+		: 'm');
+	putchar(aByte);
+	/* begin printChar: */
+	aByte1 = (((((usqInt) (longAt(objOop))) >> 0x1F) & 1) != 0
+		? 'G'
+		: 'g');
+	putchar(aByte1);
+	/* begin printChar: */
+	aByte2 = (((((usqInt) (longAt(objOop))) >> 30) & 1) != 0
+		? 'P'
+		: 'p');
+	putchar(aByte2);
+	/* begin printChar: */
+	aByte3 = (((((usqInt) (longAt(objOop))) >> 29) & 1) != 0
+		? 'R'
+		: 'r');
+	putchar(aByte3);
+	/* begin printChar: */
+	aByte4 = (((((usqInt) (longAt(objOop))) >> 23) & 1) != 0
+		? 'I'
+		: 'i');
+	putchar(aByte4);
+	print(" hash ");
+	/* begin printHexnp: */
+	n2 = (long32At(objOop + 4)) & 0x3FFFFF;
+	printf("0x%lx", ((unsigned long) n2));
+	print(" fmt ");
+	/* begin printHexnp: */
+	n3 = (((usqInt) (longAt(objOop))) >> 24) & 0x1F;
+	printf("0x%lx", ((unsigned long) n3));
+	print(" cidx ");
+	/* begin printHexnp: */
+	n4 = (longAt(objOop)) & 0x3FFFFF;
+	printf("0x%lx", ((unsigned long) n4));
+	/* begin cr */
+	printf("\n");
+}
+
 static void
 printHeaderTypeOf(sqInt objOop)
 {

Modified: branches/Cog/nsspurstacksrc/vm/interp.c
===================================================================
--- branches/Cog/nsspurstacksrc/vm/interp.c	2015-03-25 00:18:37 UTC (rev 3287)
+++ branches/Cog/nsspurstacksrc/vm/interp.c	2015-03-25 19:52:47 UTC (rev 3288)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1117 uuid: 71e6dd3b-c884-47ec-a004-bce9fe9517c5
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1118 uuid: b055db97-d17b-4dfd-b281-57e8df3faf12
    from
-	StackInterpreter VMMaker.oscog-eem.1117 uuid: 71e6dd3b-c884-47ec-a004-bce9fe9517c5
+	StackInterpreter VMMaker.oscog-eem.1118 uuid: b055db97-d17b-4dfd-b281-57e8df3faf12
  */
-static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.1117 uuid: 71e6dd3b-c884-47ec-a004-bce9fe9517c5 " __DATE__ ;
+static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.1118 uuid: b055db97-d17b-4dfd-b281-57e8df3faf12 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -593,10 +593,11 @@
 usqInt smallObjectBytesForSlots(sqInt numSlots);
 sqInt tagMask(void);
 static sqInt wordIndexableFormat(void);
-static void addToEphemeronList(sqInt ephemeronCorpse) NoDbgRegParms;
-static void addToWeakList(sqInt weakCorpse) NoDbgRegParms;
+static void addToEphemeronList(sqInt ephemeronCorpse) NoDbgRegParms NeverInline;
+static void addToWeakList(sqInt weakCorpse) NoDbgRegParms NeverInline;
 static sqInt allWeakSurvivorsOnWeakList(void);
 static sqInt copyAndForward(sqInt survivor) NoDbgRegParms;
+static sqInt copyToOldSpacebytesformat(sqInt survivor, sqInt bytesInObject, sqInt formatOfSurvivor) NoDbgRegParms NeverInline;
 static sqInt firstCorpse(sqInt headOfCorpseList) NoDbgRegParms;
 static void growRememberedSet(void);
 static sqInt isInRememberedSet(sqInt objOop) NoDbgRegParms;
@@ -749,6 +750,7 @@
 static sqInt goodContextSize(sqInt oop) NoDbgRegParms;
 static usqInt growOldSpaceByAtLeast(sqInt minAmmount) NoDbgRegParms;
 usqLong headerForSlotsformatclassIndex(sqInt numSlots, sqInt formatField, sqInt classIndex);
+usqLong headerForSlotshashformatclassIndex(sqInt numSlots, sqInt hash, sqInt formatField, sqInt classIndex);
 static sqInt hiddenRootSlots(void);
 sqInt identityHashHalfWordMask(void);
 static sqInt imageSegmentVersion(void);
@@ -881,6 +883,7 @@
 void printFreeList(sqInt chunkOrIndex);
 void printFreeTree(void);
 static void printFreeTreeChunk(sqInt chunkOrZero) NoDbgRegParms;
+void printHeaderOf(sqInt objOop);
 static void printHeaderTypeOf(sqInt objOop) NoDbgRegParms;
 void printInstancesOf(sqInt aClassOop);
 void printInstancesWithClassIndex(sqInt classIndex);
@@ -2109,7 +2112,7 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 char expensiveAsserts = 0;
-const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreterPrimitives_VMMaker.oscog-eem.1117";
+const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreterPrimitives_VMMaker.oscog-eem.1118";
 volatile int sendTrace;
 sqInt suppressHeartbeatFlag;
 
@@ -27635,6 +27638,7 @@
 	references. Thread the corpse onto the weakList. Later, the weakList can
 	be followed, and
 	the forwarding pointer followed to locate the survivor. */
+/*	Should be too infrequent to lower icache density of copyAndForward: */
 
 static void
 addToEphemeronList(sqInt ephemeronCorpse)
@@ -27650,6 +27654,9 @@
 	/* begin setCorpseOffsetOf:to: */

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list