[Vm-dev] [commit][3674] CogVM source as per VMMaker.oscog-eem.1824

commits at squeakvm.org commits at squeakvm.org
Wed Apr 20 00:32:49 UTC 2016


Revision: 3674
Author:   eliot
Date:     2016-04-19 17:32:46 -0700 (Tue, 19 Apr 2016)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.1824

Cogit:
Add a primitive that answers pc map data for methods which can be
used to better decorate methods in the VM Profiler.  Refactor the pc
map enumeration facilities so that the Sista pic data primitive can
share the same enumerator.  Do this by collapsing the
isBackwardBranch and annotation parameters into a single parameter.

Modified Paths:
--------------
    branches/Cog/nsspur64src/vm/cogit.h
    branches/Cog/nsspur64src/vm/cogitX64.c
    branches/Cog/nsspur64src/vm/cointerp.c
    branches/Cog/nsspur64src/vm/cointerp.h
    branches/Cog/nsspur64src/vm/gcc3x-cointerp.c
    branches/Cog/nsspursrc/vm/cogit.h
    branches/Cog/nsspursrc/vm/cogitARMv5.c
    branches/Cog/nsspursrc/vm/cogitIA32.c
    branches/Cog/nsspursrc/vm/cogitMIPSEL.c
    branches/Cog/nsspursrc/vm/cointerp.c
    branches/Cog/nsspursrc/vm/cointerp.h
    branches/Cog/nsspursrc/vm/gcc3x-cointerp.c
    branches/Cog/spur64src/vm/cogit.h
    branches/Cog/spur64src/vm/cogitX64.c
    branches/Cog/spur64src/vm/cointerp.c
    branches/Cog/spur64src/vm/cointerp.h
    branches/Cog/spur64src/vm/gcc3x-cointerp.c
    branches/Cog/spursistasrc/vm/cogit.h
    branches/Cog/spursistasrc/vm/cogitARMv5.c
    branches/Cog/spursistasrc/vm/cogitIA32.c
    branches/Cog/spursistasrc/vm/cogitMIPSEL.c
    branches/Cog/spursistasrc/vm/cointerp.c
    branches/Cog/spursistasrc/vm/cointerp.h
    branches/Cog/spursistasrc/vm/gcc3x-cointerp.c
    branches/Cog/spursrc/vm/cogit.h
    branches/Cog/spursrc/vm/cogitARMv5.c
    branches/Cog/spursrc/vm/cogitIA32.c
    branches/Cog/spursrc/vm/cogitMIPSEL.c
    branches/Cog/spursrc/vm/cointerp.c
    branches/Cog/spursrc/vm/cointerp.h
    branches/Cog/spursrc/vm/gcc3x-cointerp.c
    branches/Cog/src/vm/cogit.h
    branches/Cog/src/vm/cogitARMv5.c
    branches/Cog/src/vm/cogitIA32.c
    branches/Cog/src/vm/cogitMIPSEL.c
    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

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

Modified: branches/Cog/nsspur64src/vm/cogit.h
===================================================================
--- branches/Cog/nsspur64src/vm/cogit.h	2016-04-20 00:06:30 UTC (rev 3673)
+++ branches/Cog/nsspur64src/vm/cogit.h	2016-04-20 00:32:46 UTC (rev 3674)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619
+	CCodeGenerator VMMaker.oscog-eem.1824 uuid: 3e604324-d371-4ad6-ac2d-8acf325accfe
  */
 
 
@@ -86,6 +86,7 @@
 extern sqInt genQuickReturnConst(void);
 extern sqInt genQuickReturnInstVar(void);
 extern sqInt genQuickReturnSelf(void);
+extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj);
 extern void recordCallOffsetIn(CogMethod *cogMethod);
 extern void rewritePrimInvocationInto(CogMethod *cogMethod, void (*primFunctionPointer)(void));
 extern void voidCogCompiledCode(void);

Modified: branches/Cog/nsspur64src/vm/cogitX64.c
===================================================================
--- branches/Cog/nsspur64src/vm/cogitX64.c	2016-04-20 00:06:30 UTC (rev 3673)
+++ branches/Cog/nsspur64src/vm/cogitX64.c	2016-04-20 00:32:46 UTC (rev 3674)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619
+	CCodeGenerator VMMaker.oscog-eem.1824 uuid: 3e604324-d371-4ad6-ac2d-8acf325accfe
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619
+	StackToRegisterMappingCogit VMMaker.oscog-eem.1824 uuid: 3e604324-d371-4ad6-ac2d-8acf325accfe
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619 " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1824 uuid: 3e604324-d371-4ad6-ac2d-8acf325accfe " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -243,6 +243,7 @@
 #define PrimCallMayCallBack 4
 #define PrimCallNeedsNewMethod 1
 #define PrimCallNeedsPrimitiveFunction 2
+#define PrimErrNoMemory 9
 #define PrimErrWritePastObject 17
 #define PushCq 74
 #define PushCw 75
@@ -526,10 +527,11 @@
 static sqInt extBBytecode(void);
 static sqInt NoDbgRegParms fillInBlockHeadersAt(sqInt startAddress);
 static CogMethod * NoDbgRegParms fillInMethodHeadersizeselector(CogMethod *method, sqInt size, sqInt selector);
+static sqInt NoDbgRegParms findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetBcpc);
 static usqInt NoDbgRegParms findBlockMethodWithEntrystartBcpc(sqInt blockEntryMcpc, sqInt startBcpc);
 static sqInt NoDbgRegParms findMapLocationForMcpcinMethod(sqInt targetMcpc, CogMethod *cogMethod);
 extern CogBlockMethod * findMethodForStartBcpcinHomeMethod(sqInt startbcpc, CogMethod *cogMethod);
-static sqInt NoDbgRegParms findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranch, char *mcpc, sqInt bcpc, void *targetMcpc);
+static sqInt NoDbgRegParms findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetMcpc);
 static sqInt NoDbgRegParms firstMappedPCFor(CogMethod *cogMethod);
 extern void followForwardedLiteralsIn(CogMethod *cogMethod);
 extern void followForwardedMethods(void);
@@ -1045,8 +1047,11 @@
 static sqInt genStoreAndPopRemoteTempLongBytecode(void);
 static sqInt genStoreAndPopTemporaryVariableBytecode(void);
 static sqInt genStoreRemoteTempLongBytecode(void);
+extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj);
 static void maybeCompileAllocFillerCheck(void);
 static sqInt numSpecialSelectors(void);
+static usqInt NoDbgRegParms pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod);
+static sqInt NoDbgRegParms pcDataForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg);
 static PrimitiveDescriptor * primitiveGeneratorOrNil(void);
 extern void recordCallOffsetIn(CogMethod *cogMethod);
 static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask);
@@ -1806,6 +1811,8 @@
 static sqInt inBlock;
 static sqInt indexOfIRC;
 static sqInt initialPC;
+static sqInt introspectionData;
+static sqInt introspectionDataIndex;
 static int labelCounter;
 static sqInt lastSend;
 static usqInt limitAddress;
@@ -2822,7 +2829,7 @@
 	/* The stack check maps to the start of the first bytecode,
 	   the first bytecode being effectively after frame build. */
 	mcpc1 = (((usqInt)cogMethod)) + ((cogMethod->stackCheckOffset));
-	result = findIsBackwardBranchMcpcBcpcMatchingMcpc(null, 0, (((char *) mcpc1)), startbcpc, (((void *)mcpc)));
+	result = findIsBackwardBranchMcpcBcpcMatchingMcpc(null, (0 + (((long)HasBytecodePC) << 1)), (((char *) mcpc1)), startbcpc, (((void *)mcpc)));
 	if (result != 0) {
 		return result;
 	}
@@ -2835,10 +2842,11 @@
 		homeMethod = ((CogMethod *) cogMethod);
 		assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader))));
 		map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1;
-		assert(((((usqInt) (byteAt(map))) >> AnnotationShift) == IsAbsPCReference)
-		 || (((((usqInt) (byteAt(map))) >> AnnotationShift) == IsObjectReference)
-		 || (((((usqInt) (byteAt(map))) >> AnnotationShift) == IsRelativeCall)
-		 || ((((usqInt) (byteAt(map))) >> AnnotationShift) == IsDisplacementX2N))));
+		annotation = ((usqInt) (byteAt(map))) >> AnnotationShift;
+		assert((annotation == IsAbsPCReference)
+		 || ((annotation == IsObjectReference)
+		 || ((annotation == IsRelativeCall)
+		 || (annotation == IsDisplacementX2N))));
 		latestContinuation = startbcpc;
 		aMethodObj = (homeMethod->methodObject);
 		endbcpc = (numBytesOf(aMethodObj)) - 1;
@@ -2855,9 +2863,10 @@
 		homeMethod = cmHomeMethod(cogMethod);
 		map = findMapLocationForMcpcinMethod((((usqInt)cogMethod)) + (sizeof(CogBlockMethod)), homeMethod);
 		assert(map != 0);
-		assert(((((usqInt) (byteAt(map))) >> AnnotationShift) == HasBytecodePC)
-		 || ((((usqInt) (byteAt(map))) >> AnnotationShift) == IsDisplacementX2N));
-		while ((((usqInt) (byteAt(map))) >> AnnotationShift) != HasBytecodePC) {
+		annotation = ((usqInt) (byteAt(map))) >> AnnotationShift;
+		assert(((((usqInt) annotation) >> AnnotationShift) == HasBytecodePC)
+		 || ((((usqInt) annotation) >> AnnotationShift) == IsDisplacementX2N));
+		while (((annotation = ((usqInt) (byteAt(map))) >> AnnotationShift)) != HasBytecodePC) {
 			map -= 1;
 		}
 
@@ -2877,9 +2886,9 @@
 	: 0));
 		bcpc = startbcpc;
 	}
+	nExts = 0;
+	enumeratingCogMethod = homeMethod;
 
-	/* Now skip up through the bytecode pc map entry for the stack check. */
-	nExts = 0;
 	while ((((usqInt) (byteAt(map))) >> AnnotationShift) != HasBytecodePC) {
 		map -= 1;
 	}
@@ -2927,7 +2936,9 @@
 				}
 				isBackwardBranch = (isBranch(descriptor))
 				 && (isBackwardBranchatextsin(descriptor, bcpc, nExts, aMethodObj));
-				result = findIsBackwardBranchMcpcBcpcMatchingMcpc(descriptor, isBackwardBranch, (((char *) mcpc1)), bcpc, (((void *)mcpc)));
+				result = findIsBackwardBranchMcpcBcpcMatchingMcpc(descriptor, ((isBackwardBranch
+	? (((long)annotation) << 1) + 1
+	: ((long)annotation) << 1)), (((char *) mcpc1)), bcpc, (((void *)mcpc)));
 				if (result != 0) {
 					return result;
 				}
@@ -3666,7 +3677,7 @@
 closedPICRefersToUnmarkedObject(CogMethod *cPIC)
 {
     sqInt i;
-    sqInt object;
+    usqInt object;
     sqInt pc;
 
 	if (!((isImmediate((cPIC->selector)))
@@ -5203,6 +5214,16 @@
 	return method;
 }
 
+	/* Cogit>>#findBackwardBranch:IsBackwardBranch:Mcpc:Bcpc:MatchingBcpc: */
+static sqInt NoDbgRegParms
+findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetBcpc)
+{
+	return ((isBackwardBranchAndAnnotation & 1)
+	 && ((((sqInt)targetBcpc)) == bcpc)
+		? ((sqInt)mcpc)
+		: 0);
+}
+
 	/* Cogit>>#findBlockMethodWithEntry:startBcpc: */
 static usqInt NoDbgRegParms
 findBlockMethodWithEntrystartBcpc(sqInt blockEntryMcpc, sqInt startBcpc)
@@ -5281,11 +5302,11 @@
 
 	/* Cogit>>#find:IsBackwardBranch:Mcpc:Bcpc:MatchingMcpc: */
 static sqInt NoDbgRegParms
-findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranch, char *mcpc, sqInt bcpc, void *targetMcpc)
+findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetMcpc)
 {
 	return (targetMcpc == mcpc
 		? ((descriptor == null)
-			 || (isBackwardBranch)
+			 || (isBackwardBranchAndAnnotation & 1)
 				? bcpc
 				: bcpc + ((descriptor->numBytes)))
 		: 0);
@@ -8190,7 +8211,10 @@
 	/* The stack check maps to the start of the first bytecode,
 	   the first bytecode being effectively after frame build. */
 	mcpc = (((usqInt)cogMethod)) + ((cogMethod->stackCheckOffset));
-	result = 0;
+	result = (((0 + (((long)HasBytecodePC) << 1)) & 1)
+	 && ((((sqInt)(((void *)bcpc)))) == startbcpc)
+		? ((sqInt)(((char *) mcpc)))
+		: 0);
 	if (result != 0) {
 		return result;
 	}
@@ -8203,10 +8227,11 @@
 		homeMethod = ((CogMethod *) cogMethod);
 		assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader))));
 		map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1;
-		assert(((((usqInt) (byteAt(map))) >> AnnotationShift) == IsAbsPCReference)
-		 || (((((usqInt) (byteAt(map))) >> AnnotationShift) == IsObjectReference)
-		 || (((((usqInt) (byteAt(map))) >> AnnotationShift) == IsRelativeCall)
-		 || ((((usqInt) (byteAt(map))) >> AnnotationShift) == IsDisplacementX2N))));
+		annotation = ((usqInt) (byteAt(map))) >> AnnotationShift;
+		assert((annotation == IsAbsPCReference)
+		 || ((annotation == IsObjectReference)
+		 || ((annotation == IsRelativeCall)
+		 || (annotation == IsDisplacementX2N))));
 		latestContinuation = startbcpc;
 		aMethodObj = (homeMethod->methodObject);
 		endbcpc = (numBytesOf(aMethodObj)) - 1;
@@ -8223,9 +8248,10 @@
 		homeMethod = cmHomeMethod(cogMethod);
 		map = findMapLocationForMcpcinMethod((((usqInt)cogMethod)) + (sizeof(CogBlockMethod)), homeMethod);
 		assert(map != 0);
-		assert(((((usqInt) (byteAt(map))) >> AnnotationShift) == HasBytecodePC)
-		 || ((((usqInt) (byteAt(map))) >> AnnotationShift) == IsDisplacementX2N));
-		while ((((usqInt) (byteAt(map))) >> AnnotationShift) != HasBytecodePC) {
+		annotation = ((usqInt) (byteAt(map))) >> AnnotationShift;
+		assert(((((usqInt) annotation) >> AnnotationShift) == HasBytecodePC)
+		 || ((((usqInt) annotation) >> AnnotationShift) == IsDisplacementX2N));
+		while (((annotation = ((usqInt) (byteAt(map))) >> AnnotationShift)) != HasBytecodePC) {
 			map -= 1;
 		}
 
@@ -8245,9 +8271,9 @@
 	: 0));
 		bcpc1 = startbcpc;
 	}
+	nExts = 0;
+	enumeratingCogMethod = homeMethod;
 
-	/* Now skip up through the bytecode pc map entry for the stack check. */
-	nExts = 0;
 	while ((((usqInt) (byteAt(map))) >> AnnotationShift) != HasBytecodePC) {
 		map -= 1;
 	}
@@ -8295,10 +8321,9 @@
 				}
 				isBackwardBranch = (isBranch(descriptor))
 				 && (isBackwardBranchatextsin(descriptor, bcpc1, nExts, aMethodObj));
-				result = (isBackwardBranch
-				 && ((((sqInt)(((void *)bcpc)))) == bcpc1)
-					? ((sqInt)(((char *) mcpc)))
-					: 0);
+				result = findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(descriptor, ((isBackwardBranch
+	? (((long)annotation) << 1) + 1
+	: ((long)annotation) << 1)), (((char *) mcpc)), bcpc1, (((void *)bcpc)));
 				if (result != 0) {
 					return result;
 				}
@@ -23047,6 +23072,213 @@
 }
 
 
+/*	Collect the branch and send data for cogMethod, storing it into arrayObj. */
+
+	/* SimpleStackBasedCogit>>#mapPCDataFor:into: */
+sqInt
+mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj)
+{
+    sqInt aMethodHeader;
+    sqInt aMethodHeader1;
+    sqInt aMethodObj;
+    sqInt annotation;
+    sqInt bcpc;
+    sqInt bsOffset;
+    sqInt byte;
+    CogBlockMethod *cogMethod1;
+    BytecodeDescriptor *descriptor;
+    sqInt distance;
+    sqInt endbcpc;
+    sqInt errCode;
+    CogMethod *homeMethod;
+    sqInt isBackwardBranch;
+    sqInt isInBlock;
+    sqInt latestContinuation;
+    sqInt map;
+    sqInt mapByte;
+    usqInt mcpc;
+    sqInt nExts;
+    sqInt nextBcpc;
+    sqInt result;
+    sqInt startbcpc;
+    sqInt targetPC;
+
+	latestContinuation = 0;
+	introspectionDataIndex = 0;
+	introspectionData = arrayObj;
+	if (((cogMethod->stackCheckOffset)) == 0) {
+		assert(introspectionDataIndex == 0);
+		if (0) {
+			storePointerUncheckedofObjectwithValue(0, introspectionData, nilObject());
+			storePointerUncheckedofObjectwithValue(1, introspectionData, ((cbNoSwitchEntryOffset << 3) | 1));
+			storePointerUncheckedofObjectwithValue(2, introspectionData, nilObject());
+			storePointerUncheckedofObjectwithValue(3, introspectionData, ((cbEntryOffset << 3) | 1));
+		}
+		else {
+			storePointerUncheckedofObjectwithValue(0, introspectionData, nilObject());
+			storePointerUncheckedofObjectwithValue(1, introspectionData, ((cmEntryOffset << 3) | 1));
+			storePointerUncheckedofObjectwithValue(2, introspectionData, nilObject());
+			storePointerUncheckedofObjectwithValue(3, introspectionData, ((cmNoCheckEntryOffset << 3) | 1));
+		}
+		return 4;
+	}
+	/* begin mapFor:bcpc:performUntil:arg: */
+	cogMethod1 = ((CogBlockMethod *) cogMethod);
+	startbcpc = startPCOfMethod((cogMethod->methodObject));
+	assert(((cogMethod1->stackCheckOffset)) > 0);
+
+	/* The stack check maps to the start of the first bytecode,
+	   the first bytecode being effectively after frame build. */
+	mcpc = (((usqInt)cogMethod1)) + ((cogMethod1->stackCheckOffset));
+	result = pcDataForAnnotationMcpcBcpcMethod(null, (0 + (((long)HasBytecodePC) << 1)), (((char *) mcpc)), startbcpc, (((void *)cogMethod)));
+	if (result != 0) {
+		errCode = result;
+		goto l4;
+	}
+
+	/* In both CMMethod and CMBlock cases find the start of the map and
+	   skip forward to the bytecode pc map entry for the stack check. */
+	bcpc = startbcpc;
+	if (((cogMethod1->cmType)) == CMMethod) {
+		isInBlock = 0;
+		homeMethod = ((CogMethod *) cogMethod1);
+		assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader))));
+		map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1;
+		annotation = ((usqInt) (byteAt(map))) >> AnnotationShift;
+		assert((annotation == IsAbsPCReference)
+		 || ((annotation == IsObjectReference)
+		 || ((annotation == IsRelativeCall)
+		 || (annotation == IsDisplacementX2N))));
+		latestContinuation = startbcpc;
+		aMethodObj = (homeMethod->methodObject);
+		endbcpc = (numBytesOf(aMethodObj)) - 1;
+		/* begin bytecodeSetOffsetForHeader: */
+		aMethodHeader = (homeMethod->methodHeader);
+		bsOffset = (headerIndicatesAlternateBytecodeSet(aMethodHeader)
+						? 256
+						: 0);
+		bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader));
+	}
+	else {
+		isInBlock = 1;
+		assert(bcpc == ((cogMethod1->startpc)));
+		homeMethod = cmHomeMethod(cogMethod1);
+		map = findMapLocationForMcpcinMethod((((usqInt)cogMethod1)) + (sizeof(CogBlockMethod)), homeMethod);
+		assert(map != 0);
+		annotation = ((usqInt) (byteAt(map))) >> AnnotationShift;
+		assert(((((usqInt) annotation) >> AnnotationShift) == HasBytecodePC)
+		 || ((((usqInt) annotation) >> AnnotationShift) == IsDisplacementX2N));
+		while (((annotation = ((usqInt) (byteAt(map))) >> AnnotationShift)) != HasBytecodePC) {
+			map -= 1;
+		}
+
+		/* skip fiducial; i.e. the map entry for the pc immediately following the method header. */
+		map -= 1;
+		aMethodObj = (homeMethod->methodObject);
+		bcpc = startbcpc - (blockCreationBytecodeSizeForHeader((homeMethod->methodHeader)));
+		/* begin bytecodeSetOffsetForHeader: */
+		aMethodHeader1 = (homeMethod->methodHeader);
+		bsOffset = (headerIndicatesAlternateBytecodeSet(aMethodHeader1)
+						? 256
+						: 0);
+		byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset;
+		descriptor = generatorAt(byte);
+		endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation)
+	? ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)
+	: 0));
+		bcpc = startbcpc;
+	}
+	nExts = 0;
+	enumeratingCogMethod = homeMethod;
+
+	while ((((usqInt) (byteAt(map))) >> AnnotationShift) != HasBytecodePC) {
+		map -= 1;
+	}
+	map -= 1;
+	while (((mapByte = byteAt(map))) != MapEnd) {
+
+		/* defensive; we exit on bcpc */
+		if (mapByte >= FirstAnnotation) {
+			annotation = ((usqInt) mapByte) >> AnnotationShift;
+			mcpc += (mapByte & DisplacementMask);
+			if ((annotation >= IsSendCall)
+			 || ((annotation == HasBytecodePC)
+			 || (annotation == IsNSSendCall))) {
+				while (1) {
+					byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset;
+					descriptor = generatorAt(byte);
+					if (isInBlock) {
+						if (bcpc >= endbcpc) {
+							errCode = 0;
+							goto l4;
+						}
+					}
+					else {
+						if (((descriptor->isReturn))
+						 && (bcpc >= latestContinuation)) {
+							errCode = 0;
+							goto l4;
+						}
+						if ((isBranch(descriptor))
+						 || ((descriptor->isBlockCreation))) {
+							/* begin latestContinuationPCFor:at:exts:in: */
+							distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj);
+							targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance));
+							latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation);
+						}
+					}
+					nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation)
+	? ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)
+	: 0));
+					if (((descriptor->isMapped))
+					 || (isInBlock
+					 && ((descriptor->isMappedInBlock)))) break;
+					bcpc = nextBcpc;
+					nExts = ((descriptor->isExtension)
+						? nExts + 1
+						: 0);
+				}
+				isBackwardBranch = (isBranch(descriptor))
+				 && (isBackwardBranchatextsin(descriptor, bcpc, nExts, aMethodObj));
+				result = pcDataForAnnotationMcpcBcpcMethod(descriptor, ((isBackwardBranch
+	? (((long)annotation) << 1) + 1
+	: ((long)annotation) << 1)), (((char *) mcpc)), bcpc, (((void *)cogMethod)));
+				if (result != 0) {
+					errCode = result;
+					goto l4;
+				}
+				bcpc = nextBcpc;
+				nExts = ((descriptor->isExtension)
+					? nExts + 1
+					: 0);
+			}
+		}
+		else {
+			assert(((((usqInt) mapByte) >> AnnotationShift) == IsDisplacementX2N)
+			 || ((((usqInt) mapByte) >> AnnotationShift) == IsAnnotationExtension));
+			if (mapByte < (((long)IsAnnotationExtension) << AnnotationShift)) {
+				mcpc += (((long)(mapByte - DisplacementX2N)) << AnnotationShift);
+			}
+		}
+		map -= 1;
+	}
+	errCode = 0;
+l4:	/* end mapFor:bcpc:performUntil:arg: */;
+	if (errCode != 0) {
+		assert(errCode == PrimErrNoMemory);
+		return -1;
+	}
+	if (((cogMethod->blockEntryOffset)) != 0) {
+		errCode = blockDispatchTargetsForperformarg(cogMethod, pcDataForBlockEntryMethod, ((sqInt)cogMethod));
+		if (errCode != 0) {
+			assert(errCode == PrimErrNoMemory);
+			return -1;
+		}
+	}
+	return introspectionDataIndex;
+}
+
+
 /*	If allocCheckFiller is true, words in newSpace from freeStart to
 	scavengeThreshold are filled with their address, and after each call of a
 	plugin primitive, the VM checks
@@ -23097,6 +23329,65 @@
 }
 
 
+/*	Collect the branch and send data for the block method starting at
+	blockEntryMcpc, storing it into picData.
+ */
+
+	/* SimpleStackBasedCogit>>#pcDataForBlockEntry:Method: */
+static usqInt NoDbgRegParms
+pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod)
+{
+	storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, nilObject());
+	storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((blockEntryMcpc - blockNoContextSwitchOffset) << 3) | 1));
+	storePointerUncheckedofObjectwithValue(introspectionDataIndex + 2, introspectionData, nilObject());
+	storePointerUncheckedofObjectwithValue(introspectionDataIndex + 3, introspectionData, ((blockEntryMcpc << 3) | 1));
+	introspectionDataIndex += 4;
+	return 0;
+}
+
+	/* SimpleStackBasedCogit>>#pcDataFor:Annotation:Mcpc:Bcpc:Method: */
+static sqInt NoDbgRegParms
+pcDataForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg)
+{
+    sqInt actualBcpc;
+    usqInt actualMcpc;
+
+	if (!(descriptor)) {
+
+		/* this is the stackCheck offset */
+		assert(introspectionDataIndex == 0);
+		if (0) {
+			storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, nilObject());
+			storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, ((cbNoSwitchEntryOffset << 3) | 1));
+			storePointerUncheckedofObjectwithValue(introspectionDataIndex + 2, introspectionData, nilObject());
+			storePointerUncheckedofObjectwithValue(introspectionDataIndex + 3, introspectionData, ((cbEntryOffset << 3) | 1));
+		}
+		else {
+			storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, nilObject());
+			storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, ((cmEntryOffset << 3) | 1));
+			storePointerUncheckedofObjectwithValue(introspectionDataIndex + 2, introspectionData, nilObject());
+			storePointerUncheckedofObjectwithValue(introspectionDataIndex + 3, introspectionData, ((cmNoCheckEntryOffset << 3) | 1));
+		}
+		storePointerUncheckedofObjectwithValue(introspectionDataIndex + 4, introspectionData, (((bcpc + 1) << 3) | 1));
+		storePointerUncheckedofObjectwithValue(introspectionDataIndex + 5, introspectionData, (((((((CogMethod *) cogMethodArg))->stackCheckOffset)) << 3) | 1));
+		introspectionDataIndex += 6;
+		return 0;
+	}
+	if (((((usqInt) isBackwardBranchAndAnnotation) >> 1) >= IsSendCall)
+	 || (((((usqInt) isBackwardBranchAndAnnotation) >> 1) == HasBytecodePC)
+	 || ((((usqInt) isBackwardBranchAndAnnotation) >> 1) == IsNSSendCall))) {
+		actualBcpc = (isBackwardBranchAndAnnotation & 1
+			? bcpc + 1
+			: (bcpc + ((descriptor->numBytes))) + 1);
+		actualMcpc = (((usqInt)mcpc)) - (((usqInt)cogMethodArg));
+		storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, ((actualBcpc << 3) | 1));
+		storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, ((actualMcpc << 3) | 1));
+		introspectionDataIndex += 2;
+	}
+	return 0;
+}
+
+
 /*	If there is a generator for the current primitive then answer it;
 	otherwise answer nil. */
 

Modified: branches/Cog/nsspur64src/vm/cointerp.c
===================================================================
--- branches/Cog/nsspur64src/vm/cointerp.c	2016-04-20 00:06:30 UTC (rev 3673)
+++ branches/Cog/nsspur64src/vm/cointerp.c	2016-04-20 00:32:46 UTC (rev 3674)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1824 uuid: 3e604324-d371-4ad6-ac2d-8acf325accfe
    from
-	CoInterpreter VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619
+	CoInterpreter VMMaker.oscog-eem.1824 uuid: 3e604324-d371-4ad6-ac2d-8acf325accfe
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1824 uuid: 3e604324-d371-4ad6-ac2d-8acf325accfe " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -615,6 +615,7 @@
 static void primitiveFlushCacheBySelector(void);
 extern usqInt primitiveFunctionPointerAddress(void);
 EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void);
+EXPORT(sqInt) primitiveMethodPCData(void);
 static void primitiveMethodXray(void);
 EXPORT(void) primitiveMinimumUnusedHeadroom(void);
 static void primitiveObjectAt(void);
@@ -1603,8 +1604,8 @@
 _iss StackPage * stackPage;
 _iss sqInt nilObj;
 _iss sqInt argumentCount;
+_iss sqInt specialObjectsOop;
 _iss sqInt bytecodeSetSelector;
-_iss sqInt specialObjectsOop;
 _iss sqInt messageSelector;
 _iss usqInt instructionPointer;
 _iss usqInt newMethod;
@@ -2429,7 +2430,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.1822";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1824";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -27079,7 +27080,62 @@
 	return 0;
 }
 
+	/* CoInterpreterPrimitives>>#primitiveMethodPCData */
+EXPORT(sqInt)
+primitiveMethodPCData(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt cm;
+    CogMethod *cogMethod;
+    sqInt data;
+    sqInt data1;
+    sqInt methodHeader;
+    sqInt methodReceiver;
+    sqInt nEntries;
+    sqInt nSlots;
+    char *sp;
 
+	if (GIV(argumentCount) != 0) {
+		return (GIV(primFailCode) = PrimErrBadNumArgs);
+	}
+	methodReceiver = longAt(GIV(stackPointer));
+	data = 0;
+	if (methodHasCogMethod(methodReceiver)) {
+		/* begin pcDataFor: */
+		methodHeader = longAt((methodReceiver + BaseHeaderSize) + (((long)HeaderIndex) << (shiftForWord())));
+		assert((isNonImmediate(methodHeader))
+		 && ((((usqInt)methodHeader)) < (startOfMemory())));
+		cogMethod = ((CogMethod *) methodHeader);
+		cm = (cogMethod->methodObject);
+		nSlots = (((byteSizeOf(cm)) - (((literalCountOfMethodHeader(methodHeaderOf(cm))) + LiteralStart) * BytesPerOop)) * 2) + ((8 * 2) / BytesPerOop);
+		data1 = instantiateClassindexableSize(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((long)ClassArray) << (shiftForWord()))), nSlots);
+		if (!(data1)) {
+			data = -1;
+			goto l1;
+		}
+		nEntries = mapPCDataForinto(cogMethod, data1);
+		if (nEntries == 0) {
+			data = 0;
+			goto l1;
+		}
+		if (nEntries < nSlots) {
+			shortentoIndexableSize(data1, nEntries);
+		}
+		data = data1;
+	l1:	/* end pcDataFor: */;
+		if (data == -1) {
+			return (GIV(primFailCode) = PrimErrNoMemory);
+		}
+	}
+	if (data == 0) {
+		data = instantiateClassindexableSize(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((long)ClassArray) << (shiftForWord()))), 0);
+	}
+	/* begin pop:thenPush: */
+	longAtput((sp = GIV(stackPointer) + ((1 - 1) * BytesPerWord)), data);
+	GIV(stackPointer) = sp;
+	return 0;
+}
+
+
 /*	Lift the veil from a method and answer an integer describing the interior
 	state of its machine code.
 	Used for e.g. VM tests so they can verify they're testing what they think
@@ -61618,7 +61674,7 @@
     usqInt prevFree;
     usqInt prevFreeChunk;
     usqInt prevPrevFree;
-    usqInt prevPrevFreeChunk;
+    sqInt prevPrevFreeChunk;
     sqInt slotBytes;
     sqInt slotBytes1;
     usqInt there;
@@ -67276,7 +67332,7 @@
     sqInt limit;
     sqInt newEndOfMemory;
     sqInt next;
-    sqInt node;
+    usqInt node;
     usqInt numSlots;
     usqInt numSlots1;
     SpurSegmentInfo *seg;
@@ -85060,6 +85116,7 @@
 	{(void*)_m, "primitiveLessThanLargeIntegers\000\377", (void*)primitiveLessThanLargeIntegers},
 	{(void*)_m, "primitiveLongRunningPrimitive\000\377", (void*)primitiveLongRunningPrimitive},
 	{(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\377", (void*)primitiveLongRunningPrimitiveSemaphore},
+	{(void*)_m, "primitiveMethodPCData\000\377", (void*)primitiveMethodPCData},
 	{(void*)_m, "primitiveMillisecondClockMask\000\377", (void*)primitiveMillisecondClockMask},
 	{(void*)_m, "primitiveMinimumUnusedHeadroom\000\377", (void*)primitiveMinimumUnusedHeadroom},
 	{(void*)_m, "primitiveModLargeIntegers\000\377", (void*)primitiveModLargeIntegers},

Modified: branches/Cog/nsspur64src/vm/cointerp.h
===================================================================
--- branches/Cog/nsspur64src/vm/cointerp.h	2016-04-20 00:06:30 UTC (rev 3673)
+++ branches/Cog/nsspur64src/vm/cointerp.h	2016-04-20 00:32:46 UTC (rev 3674)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1824 uuid: 3e604324-d371-4ad6-ac2d-8acf325accfe
  */
 
 

Modified: branches/Cog/nsspur64src/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nsspur64src/vm/gcc3x-cointerp.c	2016-04-20 00:06:30 UTC (rev 3673)
+++ branches/Cog/nsspur64src/vm/gcc3x-cointerp.c	2016-04-20 00:32:46 UTC (rev 3674)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1824 uuid: 3e604324-d371-4ad6-ac2d-8acf325accfe
    from
-	CoInterpreter VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619
+	CoInterpreter VMMaker.oscog-eem.1824 uuid: 3e604324-d371-4ad6-ac2d-8acf325accfe
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1824 uuid: 3e604324-d371-4ad6-ac2d-8acf325accfe " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -618,6 +618,7 @@
 static void primitiveFlushCacheBySelector(void);
 extern usqInt primitiveFunctionPointerAddress(void);
 EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void);
+EXPORT(sqInt) primitiveMethodPCData(void);
 static void primitiveMethodXray(void);
 EXPORT(void) primitiveMinimumUnusedHeadroom(void);
 static void primitiveObjectAt(void);
@@ -1606,8 +1607,8 @@
 _iss StackPage * stackPage;
 _iss sqInt nilObj;
 _iss sqInt argumentCount;
+_iss sqInt specialObjectsOop;
 _iss sqInt bytecodeSetSelector;
-_iss sqInt specialObjectsOop;
 _iss sqInt messageSelector;
 _iss usqInt instructionPointer;
 _iss usqInt newMethod;
@@ -2432,7 +2433,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.1822";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1824";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -27088,7 +27089,62 @@
 	return 0;
 }
 
+	/* CoInterpreterPrimitives>>#primitiveMethodPCData */
+EXPORT(sqInt)
+primitiveMethodPCData(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt cm;
+    CogMethod *cogMethod;
+    sqInt data;
+    sqInt data1;
+    sqInt methodHeader;
+    sqInt methodReceiver;
+    sqInt nEntries;
+    sqInt nSlots;
+    char *sp;
 
+	if (GIV(argumentCount) != 0) {
+		return (GIV(primFailCode) = PrimErrBadNumArgs);
+	}
+	methodReceiver = longAt(GIV(stackPointer));
+	data = 0;
+	if (methodHasCogMethod(methodReceiver)) {
+		/* begin pcDataFor: */
+		methodHeader = longAt((methodReceiver + BaseHeaderSize) + (((long)HeaderIndex) << (shiftForWord())));
+		assert((isNonImmediate(methodHeader))
+		 && ((((usqInt)methodHeader)) < (startOfMemory())));
+		cogMethod = ((CogMethod *) methodHeader);
+		cm = (cogMethod->methodObject);
+		nSlots = (((byteSizeOf(cm)) - (((literalCountOfMethodHeader(methodHeaderOf(cm))) + LiteralStart) * BytesPerOop)) * 2) + ((8 * 2) / BytesPerOop);
+		data1 = instantiateClassindexableSize(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((long)ClassArray) << (shiftForWord()))), nSlots);
+		if (!(data1)) {
+			data = -1;
+			goto l1;
+		}
+		nEntries = mapPCDataForinto(cogMethod, data1);
+		if (nEntries == 0) {
+			data = 0;
+			goto l1;
+		}
+		if (nEntries < nSlots) {
+			shortentoIndexableSize(data1, nEntries);
+		}
+		data = data1;
+	l1:	/* end pcDataFor: */;
+		if (data == -1) {
+			return (GIV(primFailCode) = PrimErrNoMemory);
+		}
+	}
+	if (data == 0) {
+		data = instantiateClassindexableSize(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((long)ClassArray) << (shiftForWord()))), 0);
+	}
+	/* begin pop:thenPush: */
+	longAtput((sp = GIV(stackPointer) + ((1 - 1) * BytesPerWord)), data);
+	GIV(stackPointer) = sp;
+	return 0;
+}
+
+
 /*	Lift the veil from a method and answer an integer describing the interior
 	state of its machine code.
 	Used for e.g. VM tests so they can verify they're testing what they think
@@ -61627,7 +61683,7 @@
     usqInt prevFree;
     usqInt prevFreeChunk;
     usqInt prevPrevFree;
-    usqInt prevPrevFreeChunk;
+    sqInt prevPrevFreeChunk;
     sqInt slotBytes;
     sqInt slotBytes1;
     usqInt there;
@@ -67285,7 +67341,7 @@
     sqInt limit;
     sqInt newEndOfMemory;
     sqInt next;
-    sqInt node;
+    usqInt node;
     usqInt numSlots;
     usqInt numSlots1;
     SpurSegmentInfo *seg;
@@ -85069,6 +85125,7 @@
 	{(void*)_m, "primitiveLessThanLargeIntegers\000\377", (void*)primitiveLessThanLargeIntegers},
 	{(void*)_m, "primitiveLongRunningPrimitive\000\377", (void*)primitiveLongRunningPrimitive},
 	{(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\377", (void*)primitiveLongRunningPrimitiveSemaphore},
+	{(void*)_m, "primitiveMethodPCData\000\377", (void*)primitiveMethodPCData},
 	{(void*)_m, "primitiveMillisecondClockMask\000\377", (void*)primitiveMillisecondClockMask},
 	{(void*)_m, "primitiveMinimumUnusedHeadroom\000\377", (void*)primitiveMinimumUnusedHeadroom},
 	{(void*)_m, "primitiveModLargeIntegers\000\377", (void*)primitiveModLargeIntegers},

Modified: branches/Cog/nsspursrc/vm/cogit.h
===================================================================
--- branches/Cog/nsspursrc/vm/cogit.h	2016-04-20 00:06:30 UTC (rev 3673)
+++ branches/Cog/nsspursrc/vm/cogit.h	2016-04-20 00:32:46 UTC (rev 3674)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619
+	CCodeGenerator VMMaker.oscog-eem.1824 uuid: 3e604324-d371-4ad6-ac2d-8acf325accfe
  */
 
 
@@ -86,6 +86,7 @@
 extern sqInt genQuickReturnConst(void);
 extern sqInt genQuickReturnInstVar(void);
 extern sqInt genQuickReturnSelf(void);
+extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj);
 extern void recordCallOffsetIn(CogMethod *cogMethod);
 extern void rewritePrimInvocationInto(CogMethod *cogMethod, void (*primFunctionPointer)(void));
 extern void voidCogCompiledCode(void);

Modified: branches/Cog/nsspursrc/vm/cogitARMv5.c
===================================================================
--- branches/Cog/nsspursrc/vm/cogitARMv5.c	2016-04-20 00:06:30 UTC (rev 3673)
+++ branches/Cog/nsspursrc/vm/cogitARMv5.c	2016-04-20 00:32:46 UTC (rev 3674)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619
+	CCodeGenerator VMMaker.oscog-eem.1824 uuid: 3e604324-d371-4ad6-ac2d-8acf325accfe
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619
+	StackToRegisterMappingCogit VMMaker.oscog-eem.1824 uuid: 3e604324-d371-4ad6-ac2d-8acf325accfe
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619 " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1824 uuid: 3e604324-d371-4ad6-ac2d-8acf325accfe " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -256,6 +256,7 @@
 #define PrimCallMayCallBack 4
 #define PrimCallNeedsNewMethod 1
 #define PrimCallNeedsPrimitiveFunction 2
+#define PrimErrNoMemory 9
 #define PrimErrWritePastObject 17
 #define PushCq 74
 #define PushCw 75
@@ -628,10 +629,11 @@
 static sqInt extBBytecode(void);
 static sqInt NoDbgRegParms fillInBlockHeadersAt(sqInt startAddress);
 static CogMethod * NoDbgRegParms fillInMethodHeadersizeselector(CogMethod *method, sqInt size, sqInt selector);
+static sqInt NoDbgRegParms findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetBcpc);
 static usqInt NoDbgRegParms findBlockMethodWithEntrystartBcpc(sqInt blockEntryMcpc, sqInt startBcpc);
 static sqInt NoDbgRegParms findMapLocationForMcpcinMethod(sqInt targetMcpc, CogMethod *cogMethod);
 extern CogBlockMethod * findMethodForStartBcpcinHomeMethod(sqInt startbcpc, CogMethod *cogMethod);
-static sqInt NoDbgRegParms findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranch, char *mcpc, sqInt bcpc, void *targetMcpc);
+static sqInt NoDbgRegParms findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetMcpc);
 static sqInt NoDbgRegParms firstMappedPCFor(CogMethod *cogMethod);
 extern void followForwardedLiteralsIn(CogMethod *cogMethod);
 extern void followForwardedMethods(void);
@@ -1088,8 +1090,11 @@
 static sqInt genStoreAndPopRemoteTempLongBytecode(void);
 static sqInt genStoreAndPopTemporaryVariableBytecode(void);
 static sqInt genStoreRemoteTempLongBytecode(void);
+extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj);
 static void maybeCompileAllocFillerCheck(void);
 static sqInt numSpecialSelectors(void);
+static usqInt NoDbgRegParms pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod);
+static sqInt NoDbgRegParms pcDataForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg);
 static PrimitiveDescriptor * primitiveGeneratorOrNil(void);
 extern void recordCallOffsetIn(CogMethod *cogMethod);
 static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask);
@@ -1851,6 +1856,8 @@
 static sqInt inBlock;
 static sqInt indexOfIRC;
 static sqInt initialPC;
+static sqInt introspectionData;
+static sqInt introspectionDataIndex;
 static int labelCounter;
 static sqInt lastDumpedLiteralIndex;
 static sqInt lastSend;
@@ -7545,7 +7552,7 @@
 	/* The stack check maps to the start of the first bytecode,
 	   the first bytecode being effectively after frame build. */
 	mcpc1 = (((usqInt)cogMethod)) + ((cogMethod->stackCheckOffset));
-	result = findIsBackwardBranchMcpcBcpcMatchingMcpc(null, 0, (((char *) mcpc1)), startbcpc, (((void *)mcpc)));
+	result = findIsBackwardBranchMcpcBcpcMatchingMcpc(null, (0 + (HasBytecodePC << 1)), (((char *) mcpc1)), startbcpc, (((void *)mcpc)));
 	if (result != 0) {
 		return result;
 	}
@@ -7558,10 +7565,11 @@
 		homeMethod = ((CogMethod *) cogMethod);
 		assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader))));
 		map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1;
-		assert(((((usqInt) (byteAt(map))) >> AnnotationShift) == IsAbsPCReference)
-		 || (((((usqInt) (byteAt(map))) >> AnnotationShift) == IsObjectReference)
-		 || (((((usqInt) (byteAt(map))) >> AnnotationShift) == IsRelativeCall)
-		 || ((((usqInt) (byteAt(map))) >> AnnotationShift) == IsDisplacementX2N))));
+		annotation = ((usqInt) (byteAt(map))) >> AnnotationShift;
+		assert((annotation == IsAbsPCReference)
+		 || ((annotation == IsObjectReference)
+		 || ((annotation == IsRelativeCall)
+		 || (annotation == IsDisplacementX2N))));
 		latestContinuation = startbcpc;
 		aMethodObj = (homeMethod->methodObject);
 		endbcpc = (numBytesOf(aMethodObj)) - 1;
@@ -7578,9 +7586,10 @@
 		homeMethod = cmHomeMethod(cogMethod);
 		map = findMapLocationForMcpcinMethod((((usqInt)cogMethod)) + (sizeof(CogBlockMethod)), homeMethod);
 		assert(map != 0);
-		assert(((((usqInt) (byteAt(map))) >> AnnotationShift) == HasBytecodePC)
-		 || ((((usqInt) (byteAt(map))) >> AnnotationShift) == IsDisplacementX2N));
-		while ((((usqInt) (byteAt(map))) >> AnnotationShift) != HasBytecodePC) {
+		annotation = ((usqInt) (byteAt(map))) >> AnnotationShift;
+		assert(((((usqInt) annotation) >> AnnotationShift) == HasBytecodePC)
+		 || ((((usqInt) annotation) >> AnnotationShift) == IsDisplacementX2N));
+		while (((annotation = ((usqInt) (byteAt(map))) >> AnnotationShift)) != HasBytecodePC) {
 			map -= 1;
 		}
 
@@ -7600,8 +7609,6 @@
 	: 0));
 		bcpc = startbcpc;
 	}
-
-	/* Now skip up through the bytecode pc map entry for the stack check. */
 	nExts = 0;
 	while ((((usqInt) (byteAt(map))) >> AnnotationShift) != HasBytecodePC) {
 		map -= 1;
@@ -7650,7 +7657,9 @@
 				}
 				isBackwardBranch = (isBranch(descriptor))
 				 && (isBackwardBranchatextsin(descriptor, bcpc, nExts, aMethodObj));
-				result = findIsBackwardBranchMcpcBcpcMatchingMcpc(descriptor, isBackwardBranch, (((char *) mcpc1)), bcpc, (((void *)mcpc)));
+				result = findIsBackwardBranchMcpcBcpcMatchingMcpc(descriptor, ((isBackwardBranch
+	? (annotation << 1) + 1
+	: annotation << 1)), (((char *) mcpc1)), bcpc, (((void *)mcpc)));
 				if (result != 0) {
 					return result;
 				}
@@ -9920,6 +9929,16 @@
 	return method;
 }
 
+	/* Cogit>>#findBackwardBranch:IsBackwardBranch:Mcpc:Bcpc:MatchingBcpc: */
+static sqInt NoDbgRegParms
+findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetBcpc)
+{
+	return ((isBackwardBranchAndAnnotation & 1)
+	 && ((((sqInt)targetBcpc)) == bcpc)
+		? ((sqInt)mcpc)
+		: 0);
+}
+
 	/* Cogit>>#findBlockMethodWithEntry:startBcpc: */
 static usqInt NoDbgRegParms
 findBlockMethodWithEntrystartBcpc(sqInt blockEntryMcpc, sqInt startBcpc)
@@ -9998,11 +10017,11 @@
 
 	/* Cogit>>#find:IsBackwardBranch:Mcpc:Bcpc:MatchingMcpc: */
 static sqInt NoDbgRegParms
-findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranch, char *mcpc, sqInt bcpc, void *targetMcpc)
+findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetMcpc)
 {
 	return (targetMcpc == mcpc
 		? ((descriptor == null)
-			 || (isBackwardBranch)
+			 || (isBackwardBranchAndAnnotation & 1)
 				? bcpc
 				: bcpc + ((descriptor->numBytes)))
 		: 0);
@@ -10629,12 +10648,12 @@
 generateMapAtstart(sqInt addressOrNull, sqInt startAddress)
 {
     unsigned char annotation;
-    sqInt delta;
+    usqInt delta;
     sqInt i;
     AbstractInstruction *instruction;
     sqInt length;
-    sqInt location;
-    sqInt mapEntry;
+    usqInt location;
+    usqInt mapEntry;
     sqInt maxDelta;
     usqInt mcpc;
 
@@ -12984,7 +13003,10 @@
 	/* The stack check maps to the start of the first bytecode,
 	   the first bytecode being effectively after frame build. */
 	mcpc = (((usqInt)cogMethod)) + ((cogMethod->stackCheckOffset));
-	result = 0;
+	result = (((0 + (HasBytecodePC << 1)) & 1)
+	 && ((((sqInt)(((void *)bcpc)))) == startbcpc)
+		? ((sqInt)(((char *) mcpc)))
+		: 0);
 	if (result != 0) {
 		return result;
 	}
@@ -12997,10 +13019,11 @@
 		homeMethod = ((CogMethod *) cogMethod);
 		assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader))));
 		map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1;
-		assert(((((usqInt) (byteAt(map))) >> AnnotationShift) == IsAbsPCReference)
-		 || (((((usqInt) (byteAt(map))) >> AnnotationShift) == IsObjectReference)
-		 || (((((usqInt) (byteAt(map))) >> AnnotationShift) == IsRelativeCall)
-		 || ((((usqInt) (byteAt(map))) >> AnnotationShift) == IsDisplacementX2N))));
+		annotation = ((usqInt) (byteAt(map))) >> AnnotationShift;
+		assert((annotation == IsAbsPCReference)
+		 || ((annotation == IsObjectReference)
+		 || ((annotation == IsRelativeCall)
+		 || (annotation == IsDisplacementX2N))));
 		latestContinuation = startbcpc;
 		aMethodObj = (homeMethod->methodObject);
 		endbcpc = (numBytesOf(aMethodObj)) - 1;
@@ -13017,9 +13040,10 @@
 		homeMethod = cmHomeMethod(cogMethod);
 		map = findMapLocationForMcpcinMethod((((usqInt)cogMethod)) + (sizeof(CogBlockMethod)), homeMethod);
 		assert(map != 0);
-		assert(((((usqInt) (byteAt(map))) >> AnnotationShift) == HasBytecodePC)
-		 || ((((usqInt) (byteAt(map))) >> AnnotationShift) == IsDisplacementX2N));
-		while ((((usqInt) (byteAt(map))) >> AnnotationShift) != HasBytecodePC) {
+		annotation = ((usqInt) (byteAt(map))) >> AnnotationShift;
+		assert(((((usqInt) annotation) >> AnnotationShift) == HasBytecodePC)
+		 || ((((usqInt) annotation) >> AnnotationShift) == IsDisplacementX2N));
+		while (((annotation = ((usqInt) (byteAt(map))) >> AnnotationShift)) != HasBytecodePC) {
 			map -= 1;
 		}
 
@@ -13039,8 +13063,6 @@
 	: 0));
 		bcpc1 = startbcpc;
 	}
-
-	/* Now skip up through the bytecode pc map entry for the stack check. */
 	nExts = 0;
 	while ((((usqInt) (byteAt(map))) >> AnnotationShift) != HasBytecodePC) {
 		map -= 1;
@@ -13089,10 +13111,9 @@
 				}
 				isBackwardBranch = (isBranch(descriptor))
 				 && (isBackwardBranchatextsin(descriptor, bcpc1, nExts, aMethodObj));
-				result = (isBackwardBranch
-				 && ((((sqInt)(((void *)bcpc)))) == bcpc1)
-					? ((sqInt)(((char *) mcpc)))
-					: 0);
+				result = findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(descriptor, ((isBackwardBranch
+	? (annotation << 1) + 1
+	: annotation << 1)), (((char *) mcpc)), bcpc1, (((void *)bcpc)));
 				if (result != 0) {
 					return result;
 				}
@@ -24768,6 +24789,211 @@
 }
 
 
+/*	Collect the branch and send data for cogMethod, storing it into arrayObj. */
+
+	/* SimpleStackBasedCogit>>#mapPCDataFor:into: */
+sqInt
+mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj)
+{
+    sqInt aMethodHeader;
+    sqInt aMethodHeader1;
+    sqInt aMethodObj;
+    sqInt annotation;
+    sqInt bcpc;
+    sqInt bsOffset;
+    sqInt byte;
+    CogBlockMethod *cogMethod1;
+    BytecodeDescriptor *descriptor;
+    sqInt distance;
+    sqInt endbcpc;
+    sqInt errCode;
+    CogMethod *homeMethod;
+    sqInt isBackwardBranch;
+    sqInt isInBlock;
+    sqInt latestContinuation;
+    sqInt map;
+    sqInt mapByte;
+    usqInt mcpc;
+    sqInt nExts;
+    sqInt nextBcpc;
+    sqInt result;
+    sqInt startbcpc;
+    sqInt targetPC;
+
+	latestContinuation = 0;
+	introspectionDataIndex = 0;
+	introspectionData = arrayObj;
+	if (((cogMethod->stackCheckOffset)) == 0) {
+		assert(introspectionDataIndex == 0);
+		if (0) {
+			storePointerUncheckedofObjectwithValue(0, introspectionData, nilObject());
+			storePointerUncheckedofObjectwithValue(1, introspectionData, ((cbNoSwitchEntryOffset << 1) | 1));
+			storePointerUncheckedofObjectwithValue(2, introspectionData, nilObject());
+			storePointerUncheckedofObjectwithValue(3, introspectionData, ((cbEntryOffset << 1) | 1));
+		}
+		else {
+			storePointerUncheckedofObjectwithValue(0, introspectionData, nilObject());
+			storePointerUncheckedofObjectwithValue(1, introspectionData, ((cmEntryOffset << 1) | 1));
+			storePointerUncheckedofObjectwithValue(2, introspectionData, nilObject());
+			storePointerUncheckedofObjectwithValue(3, introspectionData, ((cmNoCheckEntryOffset << 1) | 1));
+		}
+		return 4;
+	}
+	/* begin mapFor:bcpc:performUntil:arg: */
+	cogMethod1 = ((CogBlockMethod *) cogMethod);
+	startbcpc = startPCOfMethod((cogMethod->methodObject));
+	assert(((cogMethod1->stackCheckOffset)) > 0);
+
+	/* The stack check maps to the start of the first bytecode,
+	   the first bytecode being effectively after frame build. */
+	mcpc = (((usqInt)cogMethod1)) + ((cogMethod1->stackCheckOffset));
+	result = pcDataForAnnotationMcpcBcpcMethod(null, (0 + (HasBytecodePC << 1)), (((char *) mcpc)), startbcpc, (((void *)cogMethod)));
+	if (result != 0) {
+		errCode = result;
+		goto l4;
+	}
+
+	/* In both CMMethod and CMBlock cases find the start of the map and
+	   skip forward to the bytecode pc map entry for the stack check. */
+	bcpc = startbcpc;
+	if (((cogMethod1->cmType)) == CMMethod) {
+		isInBlock = 0;
+		homeMethod = ((CogMethod *) cogMethod1);
+		assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader))));
+		map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1;
+		annotation = ((usqInt) (byteAt(map))) >> AnnotationShift;
+		assert((annotation == IsAbsPCReference)
+		 || ((annotation == IsObjectReference)
+		 || ((annotation == IsRelativeCall)
+		 || (annotation == IsDisplacementX2N))));
+		latestContinuation = startbcpc;
+		aMethodObj = (homeMethod->methodObject);
+		endbcpc = (numBytesOf(aMethodObj)) - 1;
+		/* begin bytecodeSetOffsetForHeader: */
+		aMethodHeader = (homeMethod->methodHeader);
+		bsOffset = (headerIndicatesAlternateBytecodeSet(aMethodHeader)
+						? 256
+						: 0);
+		bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader));
+	}
+	else {
+		isInBlock = 1;
+		assert(bcpc == ((cogMethod1->startpc)));
+		homeMethod = cmHomeMethod(cogMethod1);
+		map = findMapLocationForMcpcinMethod((((usqInt)cogMethod1)) + (sizeof(CogBlockMethod)), homeMethod);
+		assert(map != 0);
+		annotation = ((usqInt) (byteAt(map))) >> AnnotationShift;
+		assert(((((usqInt) annotation) >> AnnotationShift) == HasBytecodePC)
+		 || ((((usqInt) annotation) >> AnnotationShift) == IsDisplacementX2N));
+		while (((annotation = ((usqInt) (byteAt(map))) >> AnnotationShift)) != HasBytecodePC) {
+			map -= 1;
+		}
+
+		/* skip fiducial; i.e. the map entry for the pc immediately following the method header. */
+		map -= 1;
+		aMethodObj = (homeMethod->methodObject);
+		bcpc = startbcpc - (blockCreationBytecodeSizeForHeader((homeMethod->methodHeader)));
+		/* begin bytecodeSetOffsetForHeader: */
+		aMethodHeader1 = (homeMethod->methodHeader);
+		bsOffset = (headerIndicatesAlternateBytecodeSet(aMethodHeader1)
+						? 256
+						: 0);
+		byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset;
+		descriptor = generatorAt(byte);
+		endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation)
+	? ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)
+	: 0));
+		bcpc = startbcpc;
+	}
+	nExts = 0;
+	while ((((usqInt) (byteAt(map))) >> AnnotationShift) != HasBytecodePC) {
+		map -= 1;
+	}
+	map -= 1;
+	while (((mapByte = byteAt(map))) != MapEnd) {
+
+		/* defensive; we exit on bcpc */
+		if (mapByte >= FirstAnnotation) {
+			annotation = ((usqInt) mapByte) >> AnnotationShift;
+			mcpc += (mapByte & DisplacementMask) * 4;
+			if ((annotation >= IsSendCall)
+			 || ((annotation == HasBytecodePC)
+			 || (annotation == IsNSSendCall))) {
+				while (1) {
+					byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset;
+					descriptor = generatorAt(byte);
+					if (isInBlock) {
+						if (bcpc >= endbcpc) {
+							errCode = 0;
+							goto l4;
+						}
+					}
+					else {
+						if (((descriptor->isReturn))
+						 && (bcpc >= latestContinuation)) {
+							errCode = 0;
+							goto l4;
+						}
+						if ((isBranch(descriptor))
+						 || ((descriptor->isBlockCreation))) {
+							/* begin latestContinuationPCFor:at:exts:in: */
+							distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj);
+							targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance));
+							latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation);
+						}
+					}
+					nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation)
+	? ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)
+	: 0));
+					if (((descriptor->isMapped))
+					 || (isInBlock
+					 && ((descriptor->isMappedInBlock)))) break;
+					bcpc = nextBcpc;

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list