[Vm-dev] [commit][2672] CogVM source as per VMMaker.oscog-eem.255.

commits at squeakvm.org commits at squeakvm.org
Sun Jan 13 03:48:28 UTC 2013


Revision: 2672
Author:   eliot
Date:     2013-01-12 19:48:28 -0800 (Sat, 12 Jan 2013)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.255.

[New[Co]]ObjectMemory:
Fix becomeForward: so that objects whose references are deleted are
freed and can no longer be resurrected via allObjects or allInstances.
Remove freed young roots from the rootsTable.  Filter freed objects
pointed to from the extraRootsTable (because these locations can change
it is wrong to remove entries from the extraRootsTable).

Make primitiveIdentityHash pop all arguments, for Newspeak VMMirrors.

StackToRegisterMappingCogit:
Fix marshalling of absent receiver sends.  The items beneath the
arguments (and to-be-pushed receiver) must be spilled before
the receiver is pushed.

Improve code quality for numArgs > numRegArgs sends when
receiver is not a spill and there are no uses of ReceiverResultReg
amongst args.  e.g. now avoids loading ReceiverResultReg from stack
in code such as 1 with: 2 with: 3 .

Modified Paths:
--------------
    branches/Cog/nscogsrc/vm/cogit.c
    branches/Cog/nscogsrc/vm/cogit.h
    branches/Cog/nscogsrc/vm/cogmethod.h
    branches/Cog/nscogsrc/vm/cointerp.c
    branches/Cog/nscogsrc/vm/cointerp.h
    branches/Cog/nscogsrc/vm/gcc3x-cointerp.c
    branches/Cog/nscogsrc/vm/interp.h
    branches/Cog/nscogsrc/vm/vmCallback.h
    branches/Cog/platforms/unix/vm/sqUnixMemory.c
    branches/Cog/src/vm/cogit.c
    branches/Cog/src/vm/cogit.h
    branches/Cog/src/vm/cogmethod.h
    branches/Cog/src/vm/cointerp.c
    branches/Cog/src/vm/cointerp.h
    branches/Cog/src/vm/cointerpmt.c
    branches/Cog/src/vm/cointerpmt.h
    branches/Cog/src/vm/gcc3x-cointerp.c
    branches/Cog/src/vm/gcc3x-cointerpmt.c
    branches/Cog/src/vm/interp.h
    branches/Cog/src/vm/vmCallback.h

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

Modified: branches/Cog/nscogsrc/vm/cogit.c
===================================================================
--- branches/Cog/nscogsrc/vm/cogit.c	2013-01-13 00:56:31 UTC (rev 2671)
+++ branches/Cog/nscogsrc/vm/cogit.c	2013-01-13 03:48:28 UTC (rev 2672)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.253 uuid: 4a3ac3fb-d367-478b-ad95-ad3bb8b6216f
+	CCodeGenerator VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.253 uuid: 4a3ac3fb-d367-478b-ad95-ad3bb8b6216f
+	StackToRegisterMappingCogit VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.253 uuid: 4a3ac3fb-d367-478b-ad95-ad3bb8b6216f " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8 " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -372,6 +372,7 @@
 static AbstractInstruction * annotateBytecode(AbstractInstruction *abstractInstruction);
 static AbstractInstruction * annotateobjRef(AbstractInstruction *abstractInstruction, sqInt anOop);
 static AbstractInstruction * annotatewith(AbstractInstruction *abstractInstruction, sqInt annotationFlag);
+static sqInt anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n);
 static void assertSaneJumpTarget(void *jumpTarget);
 static sqInt availableRegisterOrNil(void);
 static sqInt blockCreationBytecodeSizeForHeader(sqInt methodHeader);
@@ -2327,6 +2328,21 @@
 	return abstractInstruction;
 }
 
+static sqInt
+anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n)
+{
+    sqInt i;
+    sqInt regMask;
+
+	regMask = registerMaskFor(reg);
+	for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) {
+		if ((registerMask(simStackAt(i))) & regMask) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
 static void
 assertSaneJumpTarget(void *jumpTarget)
 {
@@ -15497,6 +15513,7 @@
     sqInt index;
     sqInt numSpilled;
 
+	ssFlushTo(simStackPtr - numArgs);
 	if (numArgs > (numRegArgs())) {
 
 		/* The arguments must be pushed to the stack, and hence the receiver
@@ -15525,7 +15542,6 @@
 		ssFlushTo(simStackPtr);
 	}
 	else {
-		ssFlushTo((simStackPtr - numArgs) - 1);
 		if (numArgs > 0) {
 			if (((numRegArgs()) > 1)
 			 && (numArgs > 1)) {
@@ -15558,12 +15574,38 @@
 static void
 marshallSendArguments(sqInt numArgs)
 {
+    sqInt anyRefs;
+    CogSimStackEntry * cascade0;
+    sqInt numSpilled;
+
+	ssFlushTo((simStackPtr - numArgs) - 1);
 	if (numArgs > (numRegArgs())) {
-		ssFlushTo(simStackPtr);
-		storeToReg(simStackAt(simStackPtr - numArgs), ReceiverResultReg);
+
+		/* If there are no spills and no references to ReceiverResultReg
+		   the fetch of ReceiverResultReg from the stack can be avoided
+		   by assigning directly to ReceiverResultReg and pushing it. */
+
+		numSpilled = numberOfSpillsInTopNItems(numArgs + 1);
+		anyRefs = anyReferencesToRegisterinTopNItems(ReceiverResultReg, numArgs + 1);
+		if ((numSpilled > 0)
+		 || (anyRefs)) {
+			ssFlushTo(simStackPtr);
+			storeToReg(simStackAt(simStackPtr - numArgs), ReceiverResultReg);
+		}
+		else {
+			cascade0 = simStackAt(simStackPtr - numArgs);
+			storeToReg(cascade0, ReceiverResultReg);
+			(cascade0->type = SSRegister);
+			(cascade0->registerr = ReceiverResultReg);
+			ssFlushTo(simStackPtr);
+		}
 	}
 	else {
-		ssFlushTo((simStackPtr - numArgs) - 1);
+
+		/* Move the args to the register arguments, being careful to do
+		   so last to first so e.g. previous contents don't get overwritten.
+		   Also check for any arg registers in use by other args. */
+
 		if (numArgs > 0) {
 			if (((numRegArgs()) > 1)
 			 && (numArgs > 1)) {

Modified: branches/Cog/nscogsrc/vm/cogit.h
===================================================================
--- branches/Cog/nscogsrc/vm/cogit.h	2013-01-13 00:56:31 UTC (rev 2671)
+++ branches/Cog/nscogsrc/vm/cogit.h	2013-01-13 03:48:28 UTC (rev 2672)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.253 uuid: 4a3ac3fb-d367-478b-ad95-ad3bb8b6216f
+	CCodeGenerator VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
  */
 
 

Modified: branches/Cog/nscogsrc/vm/cogmethod.h
===================================================================
--- branches/Cog/nscogsrc/vm/cogmethod.h	2013-01-13 00:56:31 UTC (rev 2671)
+++ branches/Cog/nscogsrc/vm/cogmethod.h	2013-01-13 03:48:28 UTC (rev 2672)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.253 uuid: 4a3ac3fb-d367-478b-ad95-ad3bb8b6216f
+	CCodeGenerator VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
  */
 
 typedef struct {

Modified: branches/Cog/nscogsrc/vm/cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.c	2013-01-13 00:56:31 UTC (rev 2671)
+++ branches/Cog/nscogsrc/vm/cointerp.c	2013-01-13 03:48:28 UTC (rev 2672)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.252 uuid: 50d6c392-d32d-49a5-9251-32ad9c299572
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
    from
-	CoInterpreter VMMaker.oscog-eem.252 uuid: 50d6c392-d32d-49a5-9251-32ad9c299572
+	CoInterpreter VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.252 uuid: 50d6c392-d32d-49a5-9251-32ad9c299572 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -358,7 +358,6 @@
 void assertValidMachineCodeFrame(sqInt instrPtr);
 static void assertValidStackLimits(void);
 static void attemptToSwitchToMachineCode(sqInt bcpc);
-static sqInt baseHeader(sqInt oop);
 sqInt becomewith(sqInt array1, sqInt array2);
 static sqInt becomewithtwoWaycopyHash(sqInt array1, sqInt array2, sqInt twoWayFlag, sqInt copyHashFlag);
 void beRootIfOld(sqInt oop);
@@ -640,6 +639,7 @@
 sqInt isWordsOrBytes(sqInt oop);
 sqInt isWords(sqInt oop);
 sqInt isYoungObject(sqInt obj);
+static sqInt isYoungRoot(sqInt oop);
 sqInt isYoung(sqInt oop);
 static sqInt isinstanceOfcompactClassIndex(sqInt oop, sqInt classOop, sqInt compactClassIndex);
 sqInt isKindOfClass(sqInt oop, sqInt aClass);
@@ -1059,6 +1059,7 @@
 sqInt remap(sqInt oop);
 static sqInt removeFirstLinkOfList(sqInt aList);
 EXPORT(sqInt) removeGCRoot(sqInt *varLoc);
+static sqInt removeYoungRoot(sqInt obj);
 static void restoreHeadersFromtofromandtofrom(sqInt firstIn, sqInt lastIn, sqInt hdrBaseIn, sqInt firstOut, sqInt lastOut, sqInt hdrBaseOut);
 static sqInt resumepreemptedYieldingIffrom(sqInt aProcess, sqInt yieldImplicitly, sqInt sourceCode);
 EXPORT(sqInt) returnAsThroughCallbackContext(sqInt returnTypeOop, VMCallbackContext *vmCallbackContext, sqInt callbackMethodContext);
@@ -1190,8 +1191,8 @@
 _iss usqInt youngStart;
 _iss StackPage * pages;
 _iss char * stackBasePlus1;
+_iss sqInt rootTableCount;
 _iss usqInt endOfMemory;
-_iss sqInt rootTableCount;
 _iss sqInt trueObj;
 _iss sqInt falseObj;
 _iss sqInt remapBufferCount;
@@ -1928,7 +1929,7 @@
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
 static usqInt heapBase;
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.252";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.255";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -13179,7 +13180,8 @@
 		if ((((usqInt) (longAt(array1 + fieldOffset)))) < (((usqInt) GIV(youngStart)))) {
 			return 0;
 		}
-		if ((((usqInt) (longAt(array2 + fieldOffset)))) < (((usqInt) GIV(youngStart)))) {
+		if (((((usqInt) (longAt(array2 + fieldOffset)))) < (((usqInt) GIV(youngStart))))
+		 && (((longAt(array2 + fieldOffset)) & 1) == 0)) {
 			return 0;
 		}
 		fieldOffset -= BytesPerWord;
@@ -13474,12 +13476,6 @@
 	}
 }
 
-static sqInt
-baseHeader(sqInt oop)
-{
-	return longAt(oop);
-}
-
 sqInt
 becomewith(sqInt array1, sqInt array2)
 {
@@ -13518,6 +13514,10 @@
     sqInt headerPointer;
     sqInt methodHeader;
     sqInt numLiterals;
+    sqInt objHeader;
+    sqInt objHeaderBytes;
+    sqInt objHeaderType;
+    sqInt objSize;
     sqInt oop1;
     sqInt oop11;
     sqInt oop2;
@@ -13537,7 +13537,8 @@
 		 && ((lastPointerOf(array1)) == (lastPointerOf(array2))))) {
 		return PrimErrBadArgument;
 	}
-	if (twoWayFlag) {
+	if (twoWayFlag
+	 || (copyHashFlag)) {
 		if (!(containOnlyOopsand(array1, array2))) {
 			return PrimErrInappropriate;
 		}
@@ -13596,20 +13597,20 @@
 				sp = longAt((array1 + BaseHeaderSize) + (StackPointerIndex << ShiftForWord));
 				if (!((sp & 1))) {
 					contextSize = 0;
-					goto l1;
+					goto l2;
 				}
 				assert((ReceiverIndex + ((sp >> 1))) < (lengthOf(array1)));
 				contextSize = (sp >> 1);
-			l1:	/* end fetchStackPointerOf: */;
+			l2:	/* end fetchStackPointerOf: */;
 				fieldOffset = (CtxtTempFrameStart + contextSize) * BytesPerWord;
-				goto l2;
+				goto l3;
 			}
 			fieldOffset = (sizeBitsOfSafe(array1)) - BaseHeaderSize;
-			goto l2;
+			goto l3;
 		}
 		if (fmt < 12) {
 			fieldOffset = 0;
-			goto l2;
+			goto l3;
 		}
 		/* begin literalCountOfHeader: */
 		/* begin headerOf: */
@@ -13622,7 +13623,7 @@
 						? (((usqInt) headerPointer) >> 1) & 65535
 						: (((usqInt) headerPointer) >> 10) & 255);
 		fieldOffset = (numLiterals * BytesPerWord) + BaseHeaderSize;
-	l2:	/* end lastPointerOf: */;
+	l3:	/* end lastPointerOf: */;
 		while (fieldOffset >= BaseHeaderSize) {
 			oop1 = longAt(array1 + fieldOffset);
 			oop2 = longAt(array2 + fieldOffset);
@@ -13671,13 +13672,38 @@
 			if (copyHashFlag) {
 
 				/* Change the hash of the new oop (oop2) to be that of the old (oop1)
-				   so mutated objects in hash structures will be
-				   happy after the change. */
+				   so mutated objects in hash structures will be  happy after the change. */
 
 				hdr11 = longAt(oop11);
 				hdr21 = longAt(oop21);
 				longAtput(oop21, (hdr21 & AllButHashBits) | (hdr11 & HashBits));
 			}
+			/* begin freeObject: */
+			VM_LABEL(0freeObject);
+			assert((!(isCompiledMethod(oop11)))
+			 || (!(methodHasCogMethod(oop11))));
+			objHeader = longAt(oop11);
+			if ((objHeader & RootBit) != 0) {
+				removeYoungRoot(oop11);
+			}
+			objHeaderType = objHeader & TypeMask;
+			objHeaderBytes = headerTypeBytes[objHeaderType];
+			if ((objHeaderType & 1) == 1) {
+
+				/* HeaderTypeClass or HeaderTypeShort */
+
+				objSize = objHeader & SizeMask;
+			}
+			else {
+				if (objHeaderType == HeaderTypeFree) {
+					null;
+					goto l1;
+				}
+				objSize = (longAt(oop11 - (BytesPerWord * 2))) & LongSizeMask;
+			}
+			assert(((objSize + objHeaderBytes) & AllButTypeMask) == (objSize + objHeaderBytes));
+			longAtput(oop11 - objHeaderBytes, (objSize + objHeaderBytes) | HeaderTypeFree);
+		l1:	/* end freeObject: */;
 			fwdBlock2 += BytesPerWord * 4;
 		}
 	}
@@ -13709,13 +13735,13 @@
 
 		/* begin noteAsRoot:headerLoc: */
 		header = longAt(oop);
-		if ((header & RootBit) == 0) {
+		if (!((header & RootBit) != 0)) {
 
 			/* record oop as root only if not already recorded */
 
 			if (GIV(rootTableCount) < RootTableSize) {
 
-				/* record root if there is enough room in the roots  table */
+				/* record root if there is enough room in the roots table */
 
 				GIV(rootTableCount) += 1;
 				GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -15354,16 +15380,16 @@
 
 	assert(isNonIntegerObject(anOop));
 	assert(oopisLessThan(anOop, youngStart()));
-	assert(((baseHeader(anOop)) & RootBit) == 0);
+	assert(!(isYoungRoot(anOop)));
 	/* begin noteAsRoot:headerLoc: */
 	header = longAt(anOop);
-	if ((header & RootBit) == 0) {
+	if (!((header & RootBit) != 0)) {
 
 		/* record oop as root only if not already recorded */
 
 		if (GIV(rootTableCount) < RootTableSize) {
 
-			/* record root if there is enough room in the roots  table */
+			/* record root if there is enough room in the roots table */
 
 			GIV(rootTableCount) += 1;
 			GIV(rootTable)[GIV(rootTableCount)] = anOop;
@@ -15961,7 +15987,7 @@
 			}
 			else {
 				hdr = longAt(obj);
-				if ((hdr & RootBit) == 0) {
+				if (!((hdr & RootBit) != 0)) {
 					print("non-root in rootTable @ ");
 					printNum(ri);
 					print(" = ");
@@ -16259,7 +16285,7 @@
 		printf("\n");
 		return 0;
 	}
-	if ((((longAt(oop)) & RootBit) == 1)
+	if ((((longAt(oop)) & RootBit) != 0)
 	 && (oop >= GIV(youngStart))) {
 		print("root bit is set in a young object");
 		/* begin cr */
@@ -24281,6 +24307,15 @@
 	return (((usqInt) obj)) >= (((usqInt) GIV(youngStart)));
 }
 
+
+/*	Answer if oop is a root for objects in youngSpace */
+
+static sqInt
+isYoungRoot(sqInt oop)
+{
+	return ((longAt(oop)) & RootBit) != 0;
+}
+
 sqInt
 isYoung(sqInt oop)
 {
@@ -26063,7 +26098,8 @@
 	}
 	for (i = 1; i <= GIV(extraRootCount); i += 1) {
 		oop = (GIV(extraRoots)[i])[0];
-		if (!((oop & 1))) {
+		if (!(((oop & 1))
+			 || (((longAt(oop)) & TypeMask) == HeaderTypeFree))) {
 			(GIV(extraRoots)[i])[0] = (remap(oop));
 		}
 	}
@@ -27052,7 +27088,8 @@
 	}
 	for (i = 1; i <= GIV(extraRootCount); i += 1) {
 		oop = (GIV(extraRoots)[i])[0];
-		if (!((oop & 1))) {
+		if (!(((oop & 1))
+			 || (((longAt(oop)) & TypeMask) == HeaderTypeFree))) {
 			markAndTrace(oop);
 		}
 	}
@@ -28469,7 +28506,7 @@
 		error("unused header bit 30 is set; should be zero");
 		return 0;
 	}
-	if ((((longAt(oop)) & RootBit) == 1)
+	if ((((longAt(oop)) & RootBit) != 0)
 	 && (oop >= GIV(youngStart))) {
 		error("root bit is set in a young object");
 		return 0;
@@ -28995,13 +29032,13 @@
 
 		/* begin noteAsRoot:headerLoc: */
 		header = longAt(oop);
-		if ((header & RootBit) == 0) {
+		if (!((header & RootBit) != 0)) {
 
 			/* record oop as root only if not already recorded */
 
 			if (GIV(rootTableCount) < RootTableSize) {
 
-				/* record root if there is enough room in the roots  table */
+				/* record root if there is enough room in the roots table */
 
 				GIV(rootTableCount) += 1;
 				GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -36113,7 +36150,7 @@
 	}
 	else {
 		/* begin pop:thenPushInteger: */
-		longAtput((sp = GIV(stackPointer) + ((1 - 1) * BytesPerWord)), ((((((usqInt) (longAt(thisReceiver))) >> HashBitsOffset) & HashMaskUnshifted) << 1) | 1));
+		longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), ((((((usqInt) (longAt(thisReceiver))) >> HashBitsOffset) & HashMaskUnshifted) << 1) | 1));
 		GIV(stackPointer) = sp;
 	}
 }
@@ -43992,8 +44029,13 @@
 
 void
 printCallStack(void)
-{
-	printCallStackFP(GIV(framePointer));
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+	if (GIV(framePointer) == null) {
+		printCallStackOf(longAt(((longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord))) + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord)));
+	}
+	else {
+		printCallStackFP(GIV(framePointer));
+	}
 }
 
 static void
@@ -46786,11 +46828,9 @@
 removeGCRoot(sqInt *varLoc)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt i;
-    sqInt *root;
 
 	for (i = 1; i <= GIV(extraRootCount); i++) {
-		root = GIV(extraRoots)[i];
-		if (root == varLoc) {
+		if (varLoc == (GIV(extraRoots)[i])) {
 
 			/* swap varLoc with last entry */
 
@@ -46803,6 +46843,29 @@
 }
 
 
+/*	Remove the given young root form the root table (for freeObject: for
+	becomeForward:). 
+ */
+
+static sqInt
+removeYoungRoot(sqInt obj)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt i;
+
+	for (i = 1; i <= GIV(rootTableCount); i++) {
+		if (obj == (GIV(rootTable)[i])) {
+
+			/* swap obj with last entry */
+
+			GIV(rootTable)[i] = (GIV(rootTable)[GIV(rootTableCount)]);
+			GIV(rootTableCount) -= 1;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+
 /*	Restore headers smashed by forwarding links */
 
 static void
@@ -51026,13 +51089,13 @@
 							assert(fwdBlockValid(fwdBlock4));
 							/* begin noteAsRoot:headerLoc: */
 							header13 = longAt(fwdBlock4 + BytesPerWord);
-							if ((header13 & RootBit) == 0) {
+							if (!((header13 & RootBit) != 0)) {
 
 								/* record oop as root only if not already recorded */
 
 								if (GIV(rootTableCount) < RootTableSize) {
 
-									/* record root if there is enough room in the roots  table */
+									/* record root if there is enough room in the roots table */
 
 									GIV(rootTableCount) += 1;
 									GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -51054,13 +51117,13 @@
 
 							/* begin noteAsRoot:headerLoc: */
 							header2 = longAt(oop);
-							if ((header2 & RootBit) == 0) {
+							if (!((header2 & RootBit) != 0)) {
 
 								/* record oop as root only if not already recorded */
 
 								if (GIV(rootTableCount) < RootTableSize) {
 
-									/* record root if there is enough room in the roots  table */
+									/* record root if there is enough room in the roots table */
 
 									GIV(rootTableCount) += 1;
 									GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -51110,13 +51173,13 @@
 						assert(fwdBlockValid(fwdBlock2));
 						/* begin noteAsRoot:headerLoc: */
 						header11 = longAt(fwdBlock2 + BytesPerWord);
-						if ((header11 & RootBit) == 0) {
+						if (!((header11 & RootBit) != 0)) {
 
 							/* record oop as root only if not already recorded */
 
 							if (GIV(rootTableCount) < RootTableSize) {
 
-								/* record root if there is enough room in the roots  table */
+								/* record root if there is enough room in the roots table */
 
 								GIV(rootTableCount) += 1;
 								GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -51138,13 +51201,13 @@
 
 						/* begin noteAsRoot:headerLoc: */
 						header21 = longAt(oop);
-						if ((header21 & RootBit) == 0) {
+						if (!((header21 & RootBit) != 0)) {
 
 							/* record oop as root only if not already recorded */
 
 							if (GIV(rootTableCount) < RootTableSize) {
 
-								/* record root if there is enough room in the roots  table */
+								/* record root if there is enough room in the roots table */
 
 								GIV(rootTableCount) += 1;
 								GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -51333,13 +51396,13 @@
 							assert(fwdBlockValid(fwdBlock));
 							/* begin noteAsRoot:headerLoc: */
 							header1 = longAt(fwdBlock + BytesPerWord);
-							if ((header1 & RootBit) == 0) {
+							if (!((header1 & RootBit) != 0)) {
 
 								/* record oop as root only if not already recorded */
 
 								if (GIV(rootTableCount) < RootTableSize) {
 
-									/* record root if there is enough room in the roots  table */
+									/* record root if there is enough room in the roots table */
 
 									GIV(rootTableCount) += 1;
 									GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -51361,13 +51424,13 @@
 
 							/* begin noteAsRoot:headerLoc: */
 							header2 = longAt(oop);
-							if ((header2 & RootBit) == 0) {
+							if (!((header2 & RootBit) != 0)) {
 
 								/* record oop as root only if not already recorded */
 
 								if (GIV(rootTableCount) < RootTableSize) {
 
-									/* record root if there is enough room in the roots  table */
+									/* record root if there is enough room in the roots table */
 
 									GIV(rootTableCount) += 1;
 									GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -51417,13 +51480,13 @@
 						assert(fwdBlockValid(fwdBlock2));
 						/* begin noteAsRoot:headerLoc: */
 						header11 = longAt(fwdBlock2 + BytesPerWord);
-						if ((header11 & RootBit) == 0) {
+						if (!((header11 & RootBit) != 0)) {
 
 							/* record oop as root only if not already recorded */
 
 							if (GIV(rootTableCount) < RootTableSize) {
 
-								/* record root if there is enough room in the roots  table */
+								/* record root if there is enough room in the roots table */
 
 								GIV(rootTableCount) += 1;
 								GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -51445,13 +51508,13 @@
 
 						/* begin noteAsRoot:headerLoc: */
 						header21 = longAt(oop);
-						if ((header21 & RootBit) == 0) {
+						if (!((header21 & RootBit) != 0)) {
 
 							/* record oop as root only if not already recorded */
 
 							if (GIV(rootTableCount) < RootTableSize) {
 
-								/* record root if there is enough room in the roots  table */
+								/* record root if there is enough room in the roots table */
 
 								GIV(rootTableCount) += 1;
 								GIV(rootTable)[GIV(rootTableCount)] = oop;

Modified: branches/Cog/nscogsrc/vm/cointerp.h
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.h	2013-01-13 00:56:31 UTC (rev 2671)
+++ branches/Cog/nscogsrc/vm/cointerp.h	2013-01-13 03:48:28 UTC (rev 2672)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.252 uuid: 50d6c392-d32d-49a5-9251-32ad9c299572
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
  */
 
 

Modified: branches/Cog/nscogsrc/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2013-01-13 00:56:31 UTC (rev 2671)
+++ branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2013-01-13 03:48:28 UTC (rev 2672)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.252 uuid: 50d6c392-d32d-49a5-9251-32ad9c299572
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
    from
-	CoInterpreter VMMaker.oscog-eem.252 uuid: 50d6c392-d32d-49a5-9251-32ad9c299572
+	CoInterpreter VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.252 uuid: 50d6c392-d32d-49a5-9251-32ad9c299572 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -361,7 +361,6 @@
 void assertValidMachineCodeFrame(sqInt instrPtr);
 static void assertValidStackLimits(void);
 static void attemptToSwitchToMachineCode(sqInt bcpc);
-static sqInt baseHeader(sqInt oop);
 sqInt becomewith(sqInt array1, sqInt array2);
 static sqInt becomewithtwoWaycopyHash(sqInt array1, sqInt array2, sqInt twoWayFlag, sqInt copyHashFlag);
 void beRootIfOld(sqInt oop);
@@ -643,6 +642,7 @@
 sqInt isWordsOrBytes(sqInt oop);
 sqInt isWords(sqInt oop);
 sqInt isYoungObject(sqInt obj);
+static sqInt isYoungRoot(sqInt oop);
 sqInt isYoung(sqInt oop);
 static sqInt isinstanceOfcompactClassIndex(sqInt oop, sqInt classOop, sqInt compactClassIndex);
 sqInt isKindOfClass(sqInt oop, sqInt aClass);
@@ -1062,6 +1062,7 @@
 sqInt remap(sqInt oop);
 static sqInt removeFirstLinkOfList(sqInt aList);
 EXPORT(sqInt) removeGCRoot(sqInt *varLoc);
+static sqInt removeYoungRoot(sqInt obj);
 static void restoreHeadersFromtofromandtofrom(sqInt firstIn, sqInt lastIn, sqInt hdrBaseIn, sqInt firstOut, sqInt lastOut, sqInt hdrBaseOut);
 static sqInt resumepreemptedYieldingIffrom(sqInt aProcess, sqInt yieldImplicitly, sqInt sourceCode);
 EXPORT(sqInt) returnAsThroughCallbackContext(sqInt returnTypeOop, VMCallbackContext *vmCallbackContext, sqInt callbackMethodContext);
@@ -1193,8 +1194,8 @@
 _iss usqInt youngStart;
 _iss StackPage * pages;
 _iss char * stackBasePlus1;
+_iss sqInt rootTableCount;
 _iss usqInt endOfMemory;
-_iss sqInt rootTableCount;
 _iss sqInt trueObj;
 _iss sqInt falseObj;
 _iss sqInt remapBufferCount;
@@ -1931,7 +1932,7 @@
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
 static usqInt heapBase;
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.252";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.255";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -13188,7 +13189,8 @@
 		if ((((usqInt) (longAt(array1 + fieldOffset)))) < (((usqInt) GIV(youngStart)))) {
 			return 0;
 		}
-		if ((((usqInt) (longAt(array2 + fieldOffset)))) < (((usqInt) GIV(youngStart)))) {
+		if (((((usqInt) (longAt(array2 + fieldOffset)))) < (((usqInt) GIV(youngStart))))
+		 && (((longAt(array2 + fieldOffset)) & 1) == 0)) {
 			return 0;
 		}
 		fieldOffset -= BytesPerWord;
@@ -13483,12 +13485,6 @@
 	}
 }
 
-static sqInt
-baseHeader(sqInt oop)
-{
-	return longAt(oop);
-}
-
 sqInt
 becomewith(sqInt array1, sqInt array2)
 {
@@ -13527,6 +13523,10 @@
     sqInt headerPointer;
     sqInt methodHeader;
     sqInt numLiterals;
+    sqInt objHeader;
+    sqInt objHeaderBytes;
+    sqInt objHeaderType;
+    sqInt objSize;
     sqInt oop1;
     sqInt oop11;
     sqInt oop2;
@@ -13546,7 +13546,8 @@
 		 && ((lastPointerOf(array1)) == (lastPointerOf(array2))))) {
 		return PrimErrBadArgument;
 	}
-	if (twoWayFlag) {
+	if (twoWayFlag
+	 || (copyHashFlag)) {
 		if (!(containOnlyOopsand(array1, array2))) {
 			return PrimErrInappropriate;
 		}
@@ -13605,20 +13606,20 @@
 				sp = longAt((array1 + BaseHeaderSize) + (StackPointerIndex << ShiftForWord));
 				if (!((sp & 1))) {
 					contextSize = 0;
-					goto l1;
+					goto l2;
 				}
 				assert((ReceiverIndex + ((sp >> 1))) < (lengthOf(array1)));
 				contextSize = (sp >> 1);
-			l1:	/* end fetchStackPointerOf: */;
+			l2:	/* end fetchStackPointerOf: */;
 				fieldOffset = (CtxtTempFrameStart + contextSize) * BytesPerWord;
-				goto l2;
+				goto l3;
 			}
 			fieldOffset = (sizeBitsOfSafe(array1)) - BaseHeaderSize;
-			goto l2;
+			goto l3;
 		}
 		if (fmt < 12) {
 			fieldOffset = 0;
-			goto l2;
+			goto l3;
 		}
 		/* begin literalCountOfHeader: */
 		/* begin headerOf: */
@@ -13631,7 +13632,7 @@
 						? (((usqInt) headerPointer) >> 1) & 65535
 						: (((usqInt) headerPointer) >> 10) & 255);
 		fieldOffset = (numLiterals * BytesPerWord) + BaseHeaderSize;
-	l2:	/* end lastPointerOf: */;
+	l3:	/* end lastPointerOf: */;
 		while (fieldOffset >= BaseHeaderSize) {
 			oop1 = longAt(array1 + fieldOffset);
 			oop2 = longAt(array2 + fieldOffset);
@@ -13680,13 +13681,38 @@
 			if (copyHashFlag) {
 
 				/* Change the hash of the new oop (oop2) to be that of the old (oop1)
-				   so mutated objects in hash structures will be
-				   happy after the change. */
+				   so mutated objects in hash structures will be  happy after the change. */
 
 				hdr11 = longAt(oop11);
 				hdr21 = longAt(oop21);
 				longAtput(oop21, (hdr21 & AllButHashBits) | (hdr11 & HashBits));
 			}
+			/* begin freeObject: */
+			VM_LABEL(0freeObject);
+			assert((!(isCompiledMethod(oop11)))
+			 || (!(methodHasCogMethod(oop11))));
+			objHeader = longAt(oop11);
+			if ((objHeader & RootBit) != 0) {
+				removeYoungRoot(oop11);
+			}
+			objHeaderType = objHeader & TypeMask;
+			objHeaderBytes = headerTypeBytes[objHeaderType];
+			if ((objHeaderType & 1) == 1) {
+
+				/* HeaderTypeClass or HeaderTypeShort */
+
+				objSize = objHeader & SizeMask;
+			}
+			else {
+				if (objHeaderType == HeaderTypeFree) {
+					null;
+					goto l1;
+				}
+				objSize = (longAt(oop11 - (BytesPerWord * 2))) & LongSizeMask;
+			}
+			assert(((objSize + objHeaderBytes) & AllButTypeMask) == (objSize + objHeaderBytes));
+			longAtput(oop11 - objHeaderBytes, (objSize + objHeaderBytes) | HeaderTypeFree);
+		l1:	/* end freeObject: */;
 			fwdBlock2 += BytesPerWord * 4;
 		}
 	}
@@ -13718,13 +13744,13 @@
 
 		/* begin noteAsRoot:headerLoc: */
 		header = longAt(oop);
-		if ((header & RootBit) == 0) {
+		if (!((header & RootBit) != 0)) {
 
 			/* record oop as root only if not already recorded */
 
 			if (GIV(rootTableCount) < RootTableSize) {
 
-				/* record root if there is enough room in the roots  table */
+				/* record root if there is enough room in the roots table */
 
 				GIV(rootTableCount) += 1;
 				GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -15363,16 +15389,16 @@
 
 	assert(isNonIntegerObject(anOop));
 	assert(oopisLessThan(anOop, youngStart()));
-	assert(((baseHeader(anOop)) & RootBit) == 0);
+	assert(!(isYoungRoot(anOop)));
 	/* begin noteAsRoot:headerLoc: */
 	header = longAt(anOop);
-	if ((header & RootBit) == 0) {
+	if (!((header & RootBit) != 0)) {
 
 		/* record oop as root only if not already recorded */
 
 		if (GIV(rootTableCount) < RootTableSize) {
 
-			/* record root if there is enough room in the roots  table */
+			/* record root if there is enough room in the roots table */
 
 			GIV(rootTableCount) += 1;
 			GIV(rootTable)[GIV(rootTableCount)] = anOop;
@@ -15970,7 +15996,7 @@
 			}
 			else {
 				hdr = longAt(obj);
-				if ((hdr & RootBit) == 0) {
+				if (!((hdr & RootBit) != 0)) {
 					print("non-root in rootTable @ ");
 					printNum(ri);
 					print(" = ");
@@ -16268,7 +16294,7 @@
 		printf("\n");
 		return 0;
 	}
-	if ((((longAt(oop)) & RootBit) == 1)
+	if ((((longAt(oop)) & RootBit) != 0)
 	 && (oop >= GIV(youngStart))) {
 		print("root bit is set in a young object");
 		/* begin cr */
@@ -24290,6 +24316,15 @@
 	return (((usqInt) obj)) >= (((usqInt) GIV(youngStart)));
 }
 
+
+/*	Answer if oop is a root for objects in youngSpace */
+
+static sqInt
+isYoungRoot(sqInt oop)
+{
+	return ((longAt(oop)) & RootBit) != 0;
+}
+
 sqInt
 isYoung(sqInt oop)
 {
@@ -26072,7 +26107,8 @@
 	}
 	for (i = 1; i <= GIV(extraRootCount); i += 1) {
 		oop = (GIV(extraRoots)[i])[0];
-		if (!((oop & 1))) {
+		if (!(((oop & 1))
+			 || (((longAt(oop)) & TypeMask) == HeaderTypeFree))) {
 			(GIV(extraRoots)[i])[0] = (remap(oop));
 		}
 	}
@@ -27061,7 +27097,8 @@
 	}
 	for (i = 1; i <= GIV(extraRootCount); i += 1) {
 		oop = (GIV(extraRoots)[i])[0];
-		if (!((oop & 1))) {
+		if (!(((oop & 1))
+			 || (((longAt(oop)) & TypeMask) == HeaderTypeFree))) {
 			markAndTrace(oop);
 		}
 	}
@@ -28478,7 +28515,7 @@
 		error("unused header bit 30 is set; should be zero");
 		return 0;
 	}
-	if ((((longAt(oop)) & RootBit) == 1)
+	if ((((longAt(oop)) & RootBit) != 0)
 	 && (oop >= GIV(youngStart))) {
 		error("root bit is set in a young object");
 		return 0;
@@ -29004,13 +29041,13 @@
 
 		/* begin noteAsRoot:headerLoc: */
 		header = longAt(oop);
-		if ((header & RootBit) == 0) {
+		if (!((header & RootBit) != 0)) {
 
 			/* record oop as root only if not already recorded */
 
 			if (GIV(rootTableCount) < RootTableSize) {
 
-				/* record root if there is enough room in the roots  table */
+				/* record root if there is enough room in the roots table */
 
 				GIV(rootTableCount) += 1;
 				GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -36122,7 +36159,7 @@
 	}
 	else {
 		/* begin pop:thenPushInteger: */
-		longAtput((sp = GIV(stackPointer) + ((1 - 1) * BytesPerWord)), ((((((usqInt) (longAt(thisReceiver))) >> HashBitsOffset) & HashMaskUnshifted) << 1) | 1));
+		longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), ((((((usqInt) (longAt(thisReceiver))) >> HashBitsOffset) & HashMaskUnshifted) << 1) | 1));
 		GIV(stackPointer) = sp;
 	}
 }
@@ -44001,8 +44038,13 @@
 
 void
 printCallStack(void)
-{
-	printCallStackFP(GIV(framePointer));
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+	if (GIV(framePointer) == null) {
+		printCallStackOf(longAt(((longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord))) + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord)));
+	}
+	else {
+		printCallStackFP(GIV(framePointer));
+	}
 }
 
 static void
@@ -46795,11 +46837,9 @@
 removeGCRoot(sqInt *varLoc)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt i;
-    sqInt *root;
 
 	for (i = 1; i <= GIV(extraRootCount); i++) {
-		root = GIV(extraRoots)[i];
-		if (root == varLoc) {
+		if (varLoc == (GIV(extraRoots)[i])) {
 
 			/* swap varLoc with last entry */
 
@@ -46812,6 +46852,29 @@
 }
 
 
+/*	Remove the given young root form the root table (for freeObject: for
+	becomeForward:). 
+ */
+
+static sqInt
+removeYoungRoot(sqInt obj)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt i;
+
+	for (i = 1; i <= GIV(rootTableCount); i++) {
+		if (obj == (GIV(rootTable)[i])) {
+
+			/* swap obj with last entry */
+
+			GIV(rootTable)[i] = (GIV(rootTable)[GIV(rootTableCount)]);
+			GIV(rootTableCount) -= 1;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+
 /*	Restore headers smashed by forwarding links */
 
 static void
@@ -51035,13 +51098,13 @@
 							assert(fwdBlockValid(fwdBlock4));
 							/* begin noteAsRoot:headerLoc: */
 							header13 = longAt(fwdBlock4 + BytesPerWord);
-							if ((header13 & RootBit) == 0) {
+							if (!((header13 & RootBit) != 0)) {
 
 								/* record oop as root only if not already recorded */
 
 								if (GIV(rootTableCount) < RootTableSize) {
 
-									/* record root if there is enough room in the roots  table */
+									/* record root if there is enough room in the roots table */
 
 									GIV(rootTableCount) += 1;
 									GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -51063,13 +51126,13 @@
 
 							/* begin noteAsRoot:headerLoc: */
 							header2 = longAt(oop);
-							if ((header2 & RootBit) == 0) {
+							if (!((header2 & RootBit) != 0)) {
 
 								/* record oop as root only if not already recorded */
 
 								if (GIV(rootTableCount) < RootTableSize) {
 
-									/* record root if there is enough room in the roots  table */
+									/* record root if there is enough room in the roots table */
 
 									GIV(rootTableCount) += 1;
 									GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -51119,13 +51182,13 @@
 						assert(fwdBlockValid(fwdBlock2));
 						/* begin noteAsRoot:headerLoc: */
 						header11 = longAt(fwdBlock2 + BytesPerWord);
-						if ((header11 & RootBit) == 0) {
+						if (!((header11 & RootBit) != 0)) {
 
 							/* record oop as root only if not already recorded */
 
 							if (GIV(rootTableCount) < RootTableSize) {
 
-								/* record root if there is enough room in the roots  table */
+								/* record root if there is enough room in the roots table */
 
 								GIV(rootTableCount) += 1;
 								GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -51147,13 +51210,13 @@
 
 						/* begin noteAsRoot:headerLoc: */
 						header21 = longAt(oop);
-						if ((header21 & RootBit) == 0) {
+						if (!((header21 & RootBit) != 0)) {
 
 							/* record oop as root only if not already recorded */
 
 							if (GIV(rootTableCount) < RootTableSize) {
 
-								/* record root if there is enough room in the roots  table */
+								/* record root if there is enough room in the roots table */
 
 								GIV(rootTableCount) += 1;
 								GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -51342,13 +51405,13 @@
 							assert(fwdBlockValid(fwdBlock));
 							/* begin noteAsRoot:headerLoc: */
 							header1 = longAt(fwdBlock + BytesPerWord);
-							if ((header1 & RootBit) == 0) {
+							if (!((header1 & RootBit) != 0)) {
 
 								/* record oop as root only if not already recorded */
 
 								if (GIV(rootTableCount) < RootTableSize) {
 
-									/* record root if there is enough room in the roots  table */
+									/* record root if there is enough room in the roots table */
 
 									GIV(rootTableCount) += 1;
 									GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -51370,13 +51433,13 @@
 
 							/* begin noteAsRoot:headerLoc: */
 							header2 = longAt(oop);
-							if ((header2 & RootBit) == 0) {
+							if (!((header2 & RootBit) != 0)) {
 
 								/* record oop as root only if not already recorded */
 
 								if (GIV(rootTableCount) < RootTableSize) {
 
-									/* record root if there is enough room in the roots  table */
+									/* record root if there is enough room in the roots table */
 
 									GIV(rootTableCount) += 1;
 									GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -51426,13 +51489,13 @@
 						assert(fwdBlockValid(fwdBlock2));
 						/* begin noteAsRoot:headerLoc: */
 						header11 = longAt(fwdBlock2 + BytesPerWord);
-						if ((header11 & RootBit) == 0) {
+						if (!((header11 & RootBit) != 0)) {
 
 							/* record oop as root only if not already recorded */
 
 							if (GIV(rootTableCount) < RootTableSize) {
 
-								/* record root if there is enough room in the roots  table */
+								/* record root if there is enough room in the roots table */
 
 								GIV(rootTableCount) += 1;
 								GIV(rootTable)[GIV(rootTableCount)] = oop;
@@ -51454,13 +51517,13 @@
 
 						/* begin noteAsRoot:headerLoc: */
 						header21 = longAt(oop);
-						if ((header21 & RootBit) == 0) {
+						if (!((header21 & RootBit) != 0)) {
 
 							/* record oop as root only if not already recorded */
 
 							if (GIV(rootTableCount) < RootTableSize) {
 
-								/* record root if there is enough room in the roots  table */
+								/* record root if there is enough room in the roots table */
 
 								GIV(rootTableCount) += 1;
 								GIV(rootTable)[GIV(rootTableCount)] = oop;

Modified: branches/Cog/nscogsrc/vm/interp.h
===================================================================
--- branches/Cog/nscogsrc/vm/interp.h	2013-01-13 00:56:31 UTC (rev 2671)
+++ branches/Cog/nscogsrc/vm/interp.h	2013-01-13 03:48:28 UTC (rev 2672)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.252 uuid: 50d6c392-d32d-49a5-9251-32ad9c299572
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
  */
 
 #define VM_PROXY_MAJOR 1

Modified: branches/Cog/nscogsrc/vm/vmCallback.h
===================================================================
--- branches/Cog/nscogsrc/vm/vmCallback.h	2013-01-13 00:56:31 UTC (rev 2671)
+++ branches/Cog/nscogsrc/vm/vmCallback.h	2013-01-13 03:48:28 UTC (rev 2672)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.252 uuid: 50d6c392-d32d-49a5-9251-32ad9c299572
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
  */
 
 #define VM_CALLBACK_INC 1


Property changes on: branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
___________________________________________________________________
Modified: checkindate
   - Thu Jan 10 15:32:24 PST 2013
   + Sat Jan 12 19:44:53 PST 2013

Modified: branches/Cog/platforms/unix/vm/sqUnixMemory.c
===================================================================
--- branches/Cog/platforms/unix/vm/sqUnixMemory.c	2013-01-13 00:56:31 UTC (rev 2671)
+++ branches/Cog/platforms/unix/vm/sqUnixMemory.c	2013-01-13 03:48:28 UTC (rev 2672)
@@ -51,6 +51,14 @@
 #include "config.h"
 #include "debug.h"
 
+void *uxAllocateMemory(sqInt minHeapSize, sqInt desiredHeapSize);
+char *uxGrowMemoryBy(char *oldLimit, sqInt delta);
+char *uxShrinkMemoryBy(char *oldLimit, sqInt delta);
+sqInt uxMemoryExtraBytesLeft(sqInt includingSwap);
+
+static int	    pageSize = 0;
+static unsigned int pageMask = 0;
+
 #if defined(HAVE_MMAP)
 
 #include <stdio.h>
@@ -79,11 +87,6 @@
 # define ALWAYS_USE_MMAP 1
 #endif
 
-void *uxAllocateMemory(sqInt minHeapSize, sqInt desiredHeapSize);
-char *uxGrowMemoryBy(char *oldLimit, sqInt delta);
-char *uxShrinkMemoryBy(char *oldLimit, sqInt delta);
-sqInt uxMemoryExtraBytesLeft(sqInt includingSwap);
-
 #if defined(SQ_IMAGE32) && defined(SQ_HOST64)
 char *sqMemoryBase= (char *)-1;
 #endif
@@ -96,9 +99,6 @@
 static int   heapSize	=  0;
 static int   heapLimit	=  0;
 
-static int	    pageSize = 0;
-static unsigned int pageMask = 0;
-
 #define valign(x)	((x) & pageMask)
 
 static int min(int x, int y) { return (x < y) ? x : y; }
@@ -244,14 +244,28 @@
 }
 
 
-#else  /* !HAVE_MMAP */
+#else  /* HAVE_MMAP */
 
+# if COG
+void *
+uxAllocateMemory(sqInt minHeapSize, sqInt desiredHeapSize)
+{
+	if (pageMask) {
+		fprintf(stderr, "uxAllocateMemory: already called\n");
+		exit(1);
+	}
+	pageSize = getpagesize();
+	pageMask = ~(pageSize - 1);
+	return malloc(desiredHeapSize);
+}
+# else /* COG */
 void *uxAllocateMemory(sqInt minHeapSize, sqInt desiredHeapSize)	{ return malloc(desiredHeapSize); }
+# endif /* COG */
 char *uxGrowMemoryBy(char * oldLimit, sqInt delta)			{ return oldLimit; }
 char *uxShrinkMemoryBy(char *oldLimit, sqInt delta)			{ return oldLimit; }
 sqInt uxMemoryExtraBytesLeft(sqInt includingSwap)			{ return 0; }
 
-#endif
+#endif /* HAVE_MMAP */
 
 
 

Modified: branches/Cog/src/vm/cogit.c
===================================================================
--- branches/Cog/src/vm/cogit.c	2013-01-13 00:56:31 UTC (rev 2671)
+++ branches/Cog/src/vm/cogit.c	2013-01-13 03:48:28 UTC (rev 2672)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.250 uuid: e0de5572-7682-4c5e-b5a0-ca2f32cf0c81
+	CCodeGenerator VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.250 uuid: e0de5572-7682-4c5e-b5a0-ca2f32cf0c81
+	StackToRegisterMappingCogit VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.250 uuid: e0de5572-7682-4c5e-b5a0-ca2f32cf0c81 " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8 " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -372,6 +372,7 @@
 static AbstractInstruction * annotateBytecode(AbstractInstruction *abstractInstruction);
 static AbstractInstruction * annotateobjRef(AbstractInstruction *abstractInstruction, sqInt anOop);
 static AbstractInstruction * annotatewith(AbstractInstruction *abstractInstruction, sqInt annotationFlag);
+static sqInt anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n);
 static void assertSaneJumpTarget(void *jumpTarget);
 static sqInt availableRegisterOrNil(void);
 static sqInt blockCreationBytecodeSizeForHeader(sqInt methodHeader);
@@ -869,6 +870,7 @@
 static sqInt noCogMethodsMaximallyMarked(void);
 static void nopsFromto(AbstractInstruction * self_in_nopsFromto, sqInt startAddr, sqInt endAddr);
 static sqInt noTargetsFreeInClosedPIC(CogMethod *cPIC);
+static sqInt numberOfSpillsInTopNItems(sqInt n);
 static sqInt numCheckFeaturesOpcodes(AbstractInstruction * self_in_numCheckFeaturesOpcodes);
 static sqInt numICacheFlushOpcodes(AbstractInstruction * self_in_numICacheFlushOpcodes);
 static sqInt numLowLevelLockOpcodes(AbstractInstruction * self_in_numLowLevelLockOpcodes);
@@ -2013,6 +2015,21 @@
 	return abstractInstruction;
 }
 
+static sqInt
+anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n)
+{
+    sqInt i;
+    sqInt regMask;
+
+	regMask = registerMaskFor(reg);
+	for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) {
+		if ((registerMask(simStackAt(i))) & regMask) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
 static void
 assertSaneJumpTarget(void *jumpTarget)
 {
@@ -14217,12 +14234,38 @@
 static void
 marshallSendArguments(sqInt numArgs)
 {
+    sqInt anyRefs;
+    CogSimStackEntry * cascade0;
+    sqInt numSpilled;
+
+	ssFlushTo((simStackPtr - numArgs) - 1);
 	if (numArgs > (numRegArgs())) {
-		ssFlushTo(simStackPtr);
-		storeToReg(simStackAt(simStackPtr - numArgs), ReceiverResultReg);
+
+		/* If there are no spills and no references to ReceiverResultReg
+		   the fetch of ReceiverResultReg from the stack can be avoided
+		   by assigning directly to ReceiverResultReg and pushing it. */
+
+		numSpilled = numberOfSpillsInTopNItems(numArgs + 1);
+		anyRefs = anyReferencesToRegisterinTopNItems(ReceiverResultReg, numArgs + 1);
+		if ((numSpilled > 0)
+		 || (anyRefs)) {
+			ssFlushTo(simStackPtr);
+			storeToReg(simStackAt(simStackPtr - numArgs), ReceiverResultReg);
+		}
+		else {
+			cascade0 = simStackAt(simStackPtr - numArgs);
+			storeToReg(cascade0, ReceiverResultReg);
+			(cascade0->type = SSRegister);
+			(cascade0->registerr = ReceiverResultReg);
+			ssFlushTo(simStackPtr);
+		}
 	}
 	else {
-		ssFlushTo((simStackPtr - numArgs) - 1);
+
+		/* Move the args to the register arguments, being careful to do
+		   so last to first so e.g. previous contents don't get overwritten.
+		   Also check for any arg registers in use by other args. */
+
 		if (numArgs > 0) {
 			if (((numRegArgs()) > 1)
 			 && (numArgs > 1)) {
@@ -14517,7 +14560,20 @@
 	return 1;
 }
 
+static sqInt
+numberOfSpillsInTopNItems(sqInt n)
+{
+    sqInt i;
 
+	for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) {
+		if (((simStackAt(i)->type)) == SSSpill) {
+			return n - (simStackPtr - i);
+		}
+	}
+	return 0;
+}
+
+
 /*	Answer the number of opcodes required to compile the CPUID call to extract
 	the extended features information.
  */

Modified: branches/Cog/src/vm/cogit.h
===================================================================
--- branches/Cog/src/vm/cogit.h	2013-01-13 00:56:31 UTC (rev 2671)
+++ branches/Cog/src/vm/cogit.h	2013-01-13 03:48:28 UTC (rev 2672)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.250 uuid: e0de5572-7682-4c5e-b5a0-ca2f32cf0c81
+	CCodeGenerator VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
  */
 
 

Modified: branches/Cog/src/vm/cogmethod.h
===================================================================
--- branches/Cog/src/vm/cogmethod.h	2013-01-13 00:56:31 UTC (rev 2671)
+++ branches/Cog/src/vm/cogmethod.h	2013-01-13 03:48:28 UTC (rev 2672)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.250 uuid: e0de5572-7682-4c5e-b5a0-ca2f32cf0c81
+	CCodeGenerator VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
  */
 
 typedef struct {

Modified: branches/Cog/src/vm/cointerp.c
===================================================================
--- branches/Cog/src/vm/cointerp.c	2013-01-13 00:56:31 UTC (rev 2671)
+++ branches/Cog/src/vm/cointerp.c	2013-01-13 03:48:28 UTC (rev 2672)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.252 uuid: 50d6c392-d32d-49a5-9251-32ad9c299572
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
    from
-	CoInterpreter VMMaker.oscog-eem.252 uuid: 50d6c392-d32d-49a5-9251-32ad9c299572
+	CoInterpreter VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.252 uuid: 50d6c392-d32d-49a5-9251-32ad9c299572 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -355,7 +355,6 @@
 void assertValidMachineCodeFrame(sqInt instrPtr);
 static void assertValidStackLimits(void);
 static void attemptToSwitchToMachineCode(sqInt bcpc);
-static sqInt baseHeader(sqInt oop);
 sqInt becomewith(sqInt array1, sqInt array2);
 static sqInt becomewithtwoWaycopyHash(sqInt array1, sqInt array2, sqInt twoWayFlag, sqInt copyHashFlag);
 void beRootIfOld(sqInt oop);
@@ -632,6 +631,7 @@
 sqInt isWordsOrBytes(sqInt oop);
 sqInt isWords(sqInt oop);
 sqInt isYoungObject(sqInt obj);
+static sqInt isYoungRoot(sqInt oop);
 sqInt isYoung(sqInt oop);
 static sqInt isinstanceOfcompactClassIndex(sqInt oop, sqInt classOop, sqInt compactClassIndex);
 sqInt isKindOfClass(sqInt oop, sqInt aClass);
@@ -1050,6 +1050,7 @@
 sqInt remap(sqInt oop);
 static sqInt removeFirstLinkOfList(sqInt aList);
 EXPORT(sqInt) removeGCRoot(sqInt *varLoc);
+static sqInt removeYoungRoot(sqInt obj);
 static void restoreHeadersFromtofromandtofrom(sqInt firstIn, sqInt lastIn, sqInt hdrBaseIn, sqInt firstOut, sqInt lastOut, sqInt hdrBaseOut);
 static sqInt resumepreemptedYieldingIffrom(sqInt aProcess, sqInt yieldImplicitly, sqInt sourceCode);
 EXPORT(sqInt) returnAsThroughCallbackContext(sqInt returnTypeOop, VMCallbackContext *vmCallbackContext, sqInt callbackMethodContext);
@@ -1180,8 +1181,8 @@
 _iss StackPage * pages;
 _iss usqInt youngStart;
 _iss char * stackBasePlus1;
+_iss sqInt rootTableCount;
 _iss usqInt endOfMemory;
-_iss sqInt rootTableCount;
 _iss sqInt remapBufferCount;
 _iss sqInt trueObj;
 _iss sqInt falseObj;
@@ -1918,7 +1919,7 @@
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
 static usqInt heapBase;
-const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.252]";
+const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.255]";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -9287,7 +9288,8 @@
 		if ((((usqInt) (longAt(array1 + fieldOffset)))) < (((usqInt) GIV(youngStart)))) {
 			return 0;
 		}
-		if ((((usqInt) (longAt(array2 + fieldOffset)))) < (((usqInt) GIV(youngStart)))) {
+		if (((((usqInt) (longAt(array2 + fieldOffset)))) < (((usqInt) GIV(youngStart))))
+		 && (((longAt(array2 + fieldOffset)) & 1) == 0)) {
 			return 0;
 		}
 		fieldOffset -= BytesPerWord;
@@ -9579,12 +9581,6 @@
 	}
 }
 
-static sqInt
-baseHeader(sqInt oop)
-{
-	return longAt(oop);
-}
-
 sqInt
 becomewith(sqInt array1, sqInt array2)
 {
@@ -9623,6 +9619,10 @@
     sqInt headerPointer;
     sqInt methodHeader;
     sqInt numLiterals;
+    sqInt objHeader;
+    sqInt objHeaderBytes;
+    sqInt objHeaderType;
+    sqInt objSize;
     sqInt oop1;
     sqInt oop11;
     sqInt oop2;
@@ -9642,7 +9642,8 @@
 		 && ((lastPointerOf(array1)) == (lastPointerOf(array2))))) {
 		return PrimErrBadArgument;
 	}
-	if (twoWayFlag) {
+	if (twoWayFlag
+	 || (copyHashFlag)) {
 		if (!(containOnlyOopsand(array1, array2))) {
 			return PrimErrInappropriate;
 		}
@@ -9701,20 +9702,20 @@
 				sp = longAt((array1 + BaseHeaderSize) + (StackPointerIndex << ShiftForWord));
 				if (!((sp & 1))) {
 					contextSize = 0;
-					goto l1;
+					goto l2;
 				}
 				assert((ReceiverIndex + ((sp >> 1))) < (lengthOf(array1)));
 				contextSize = (sp >> 1);
-			l1:	/* end fetchStackPointerOf: */;
+			l2:	/* end fetchStackPointerOf: */;
 				fieldOffset = (CtxtTempFrameStart + contextSize) * BytesPerWord;
-				goto l2;
+				goto l3;
 			}
 			fieldOffset = (sizeBitsOfSafe(array1)) - BaseHeaderSize;
-			goto l2;
+			goto l3;
 		}
 		if (fmt < 12) {
 			fieldOffset = 0;
-			goto l2;
+			goto l3;
 		}
 		/* begin literalCountOfHeader: */
 		/* begin headerOf: */
@@ -9725,7 +9726,7 @@
 			: methodHeader);
 		numLiterals = (((usqInt) headerPointer) >> 10) & 255;
 		fieldOffset = (numLiterals * BytesPerWord) + BaseHeaderSize;
-	l2:	/* end lastPointerOf: */;
+	l3:	/* end lastPointerOf: */;
 		while (fieldOffset >= BaseHeaderSize) {
 			oop1 = longAt(array1 + fieldOffset);
 			oop2 = longAt(array2 + fieldOffset);
@@ -9774,13 +9775,38 @@
 			if (copyHashFlag) {
 
 				/* Change the hash of the new oop (oop2) to be that of the old (oop1)
-				   so mutated objects in hash structures will be
-				   happy after the change. */
+				   so mutated objects in hash structures will be  happy after the change. */
 
 				hdr11 = longAt(oop11);
 				hdr21 = longAt(oop21);
 				longAtput(oop21, (hdr21 & AllButHashBits) | (hdr11 & HashBits));
 			}
+			/* begin freeObject: */
+			VM_LABEL(0freeObject);
+			assert((!(isCompiledMethod(oop11)))
+			 || (!(methodHasCogMethod(oop11))));
+			objHeader = longAt(oop11);
+			if ((objHeader & RootBit) != 0) {
+				removeYoungRoot(oop11);
+			}
+			objHeaderType = objHeader & TypeMask;
+			objHeaderBytes = headerTypeBytes[objHeaderType];
+			if ((objHeaderType & 1) == 1) {
+
+				/* HeaderTypeClass or HeaderTypeShort */
+

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list