[Vm-dev] [commit][2673] CogVM source as per VMMaker.oscog-eem.258

commits at squeakvm.org commits at squeakvm.org
Fri Jan 18 19:25:44 UTC 2013


Revision: 2673
Author:   eliot
Date:     2013-01-18 11:25:43 -0800 (Fri, 18 Jan 2013)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.258

Fix becomeForward: when the rootTbale overflows.  There were two bugs here.
One is that initializeMemoryFirstFree: used to clear the needGCFlag so if the
rootTable overflowed noteAsRoot:headerLoc:'s setting of the needGCFlag would
be undone after the sweep.  The other is that rooitTable overflow was indicated
by rootTableCount >= RootTableSize which could be undone by becomeForward:
freeing roots which need to be removed from the rootTable.  At some point in
becomeForward the rootTable would fill but at a later point a root would be
freed, causing the table to become not full.

The fix is two fold.  1. Add an explicit rootTableOverflowed flag instead of
relying on rootTableCount >= RootTableSize.  2. move the clearing of the
needGCFlag to the GC routines.  Remove unnecessary senders of needGCFlag: false,
and remove the accessor.

As a side effect rewrite primitiveRootTable in terms of a new
ObjectMemory>>rootTableObject.  Remove the rootTable: accessor.

Implement checkAllAccessibleObjectsOkay &
checkOkayInterpreterObjects: (used to debug the above).

Fix NewObjectMemory initialization to set freeStart at the same
time as setting endOfMemory.  This allows load-time scans and
assert code to use freeStart instead of endOfMemory.

Simplify markAndTraceStackPage: ; since the two implementations
are distinct they don't need to contain the isCog if-then-else.

Implement NewObjectMemory>>shorten:toIndexableSize: so that the last object
is correctly shortened (cut back freeStart).  Refactor the allocation check
filling code into maybeFillWithAllocationCheckFillerFrom:to:.

Make longPrintOop: print the class oop.

Fix bug in printCallStackOf:currentFP: for widowed contexts.
Use fputs for print: instead of printf.

Rewrite the stackLimit computation after a moment of clarity.  Allow the system
to reduce the space for frames by up to an 1/8th.  Make sure there's at least
as much headroom as asked for.  This changes the stack page size from 4096 to
2048 and much reduces the interpreterAllocationReserveBytes.

Don't round up interpreterAllocationReserveBytes to a power of two.

Integrate the named serial primitives plus Luc Fabresse's latest fix.

Improve cygwin HoiwToBuilds with info on latest versions (thanks Ron).


Map SO_REUSEPOR to kIP_REUSEPORT instead of kIP_REUSEADDR in sqMacNetwork.c.
This doesn't fix the Mac Socket test failures because the Mac build uses the
unix code.  Sigh.

Modified Paths:
--------------
    branches/Cog/cygwinbuild/HowToBuild
    branches/Cog/cygwinbuild/Makefile
    branches/Cog/nscogbuild/cygwinbuild/HowToBuild
    branches/Cog/nscogbuild/cygwinbuild/Makefile
    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/Mac OS/plugins/SocketPlugin/sqMacNetwork.c
    branches/Cog/scripts/uploadvms
    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/nscogbuild/cygwinbuild/mvm
    branches/Cog/platforms/Cross/vm/sqSCCSVersion.h

Modified: branches/Cog/cygwinbuild/HowToBuild
===================================================================
--- branches/Cog/cygwinbuild/HowToBuild	2013-01-13 03:48:28 UTC (rev 2672)
+++ branches/Cog/cygwinbuild/HowToBuild	2013-01-18 19:25:43 UTC (rev 2673)
@@ -8,16 +8,22 @@
 1. Install the tools:
 - Install cygwin from www.cygwin.com.  As of writing the VM is built using
 CYGWIN_NT-5.1 mcstalkerxp 1.5.24(0.156/4/2) 2007-01-31 10:57 i686 Cygwin
+Make sure you install the MinGW support, which in th elist of packages is called
+"mingw-binutils: Binutils for MinGW.org Win32 toolchain".
+If, on compiling, you see the error
+	--export-dynamic is not supported for PE targets, did you mean --export-all-symbols?
+then replace --export-dynamic with --export-all-symbols in the makefiles.
+
 2. Check out the following sources from svn (if you haven't already - if you're
    reading this in cygwinbuild its likely you've already got the sources)
      svn co http://www.squeakvm.org/svn/squeak/branches/Cog/platforms
      svn co http://www.squeakvm.org/svn/squeak/branches/Cog/src
      svn co http://www.squeakvm.org/svn/squeak/branches/Cog/cygwinbuild
 2a. If you want the whole kit and caboodle including the VMMaker image try e.g.
-     svn co http://www.squeakvm.org/svn/squeak/branches/Cog cogvm
+     svn co http://www.squeakvm.org/svn/squeak/branches/Cog oscogvm
 
-3. Open a cygwin bash shell, cd into the cygbuild directory and execute
-     make
+3. Open a cygwin bash shell, cd into the cygwinbuild directory and execute
+     mvm
 
    Caution: if you previously used the mingw gnutools approach, you probably
    have a path to that 2.x gcc in your Windows PATH.  Make sure that 'which gcc'
@@ -35,9 +41,10 @@
 3a. The cygwin makefile supports building three VM configurations, product,
     assert and debug, building product by default.  To build a configuration
 	simply type make configuration, e.g.
+		make
 		make assert
 	The configurations are
-	product: stripped  & unstripped production VMs optimized at -O2 in
+	product (default): stripped  & unstripped production VMs optimized at -O2 in
 		build/vm/Croquet.exe
 		build/vm/CroquetUnstripped.exe
 	assert: an unstripped VM that includes assertion checks optimized at -O1 in
@@ -62,8 +69,7 @@
 
 3b. If you want to get the Cog VM simulator working you'll need to build the
 BochsIA32Plugin/BochsIA32Plugin.xcodeproj project and to build that you'll
-need to first build bochs.  WARNING: No one has tried to build the plugin on
-Win32.  You are on your own but your efforts will be warmly welcomed.
+need to first build bochs.
 First check-out the processor simulator source tree containing Bochs:
      svn co http://www.squeakvm.org/svn/squeak/branches/Cog/processors
 Then build the libraries winbochs/{cpu/libcpu.a,disasm/libdisasm.a,fpu/libfpu.a}

Modified: branches/Cog/cygwinbuild/Makefile
===================================================================
--- branches/Cog/cygwinbuild/Makefile	2013-01-13 03:48:28 UTC (rev 2672)
+++ branches/Cog/cygwinbuild/Makefile	2013-01-18 19:25:43 UTC (rev 2673)
@@ -6,6 +6,7 @@
 #############################################################################
 # Base definitions:
 # default configuration from product, assert & debug
+#
 CONFIGURATION=product
 # default VM threading from multi, single
 THREADING=single
@@ -161,21 +162,18 @@
 #
 # Note: I had to use 'gcc' instead of 'ld' to prevent unresolved symbols
 #       The switch '-mwindows' gives us a GUI app instead of a console app.
+#		Newer cygwins want --export-all-symbols in place of --export-dynamic.
 #
 LD:=	 gcc
 LDFLAGS:= -mno-cygwin -mwindows -mthreads -Wl,--export-dynamic -L/usr/lib/mingw
 CONSOLELDFLAGS:= -mno-cygwin -mconsole -mthreads -Wl,--export-dynamic -L/usr/lib/mingw
+#LDFLAGS:= -mno-cygwin -mwindows -mthreads -Wl,--export-all-symbols -L/usr/lib/mingw
+#CONSOLELDFLAGS:= -mno-cygwin -mconsole -mthreads -Wl,--export-all-symbols -L/usr/lib/mingw
 STDLIBS:= -lddraw -ldinput -lopengl32 -lwsock32 -lcomdlg32 -lole32 -lwinmm \
 	 -lversion -lwininet -luser32 -lgdi32 -lpsapi -lkernel32 -lcrtdll \
 	-ldsound -lsecur32
 
 #############################################################################
-# Gnuifier settings
-#
-AWK:=		gawk
-GNUIFY:= $(PLATDIR)/win32/misc/gnuify
-
-#############################################################################
 # Tools to use
 #
 AR:= ar rc
@@ -313,7 +311,6 @@
 #############################################################################
 # Building plugins
 #
-
 .PHONY: FORCE
 
 # Internal plugin.  Build as lib then link in lib
@@ -340,16 +337,13 @@
 
 #############################################################################
 # Basic rules
-
+#
 $(OBJDIR)/%.o: %.c $(wildcard $(CROSSDIR)/*.h) $(wildcard $(WIN32DIR)/*.h) $(wildcard $(MAKERDIR)/*.h)
 		$(CC) -o $@ $(CFLAGS) $(INCLUDES) $(DEFS) -c $<
 
 .c.s:
 		$(CC) -S -o $@ -fverbose-asm -Wa,ah $(CFLAGS) $(INCLUDES) $(DEFS) -c $<
 
-gnu-interp.c:	interp.c $(GNUIFY)
-		$(AWK) -f $(GNUIFY) $< > $(VMDIR)/$@
-
 .rc.res:
 		$(RC) $(RCFLAGS) -i $< -o $(OBJDIR)/$@
 
@@ -363,7 +357,6 @@
 #############################################################################
 # Extra specific dependencies
 #
-
 sqNamedPrims.h: plugins.int mkNamedPrims.exe
 	./mkNamedPrims.exe $(INTERNAL_PLUGINS) > sqNamedPrims.h
 

Modified: branches/Cog/nscogbuild/cygwinbuild/HowToBuild
===================================================================
--- branches/Cog/nscogbuild/cygwinbuild/HowToBuild	2013-01-13 03:48:28 UTC (rev 2672)
+++ branches/Cog/nscogbuild/cygwinbuild/HowToBuild	2013-01-18 19:25:43 UTC (rev 2673)
@@ -8,16 +8,23 @@
 1. Install the tools:
 - Install cygwin from www.cygwin.com.  As of writing the VM is built using
 CYGWIN_NT-5.1 mcstalkerxp 1.5.24(0.156/4/2) 2007-01-31 10:57 i686 Cygwin
+Make sure you install the MinGW support, which in th elist of packages is called
+"mingw-binutils: Binutils for MinGW.org Win32 toolchain".
+If, on compiling, you see the error
+	--export-dynamic is not supported for PE targets, did you mean --export-all-symbols?
+then replace --export-dynamic with --export-all-symbols in the makefiles.
+
 2. Check out the following sources from svn (if you haven't already - if you're
    reading this in cygwinbuild its likely you've already got the sources)
      svn co http://www.squeakvm.org/svn/squeak/branches/Cog/platforms
-     svn co http://www.squeakvm.org/svn/squeak/branches/Cog/src
-     svn co http://www.squeakvm.org/svn/squeak/branches/Cog/cygwinbuild
+     svn co http://www.squeakvm.org/svn/squeak/branches/Cog/nscogsrc
+     svn co http://www.squeakvm.org/svn/squeak/branches/Cog/nscogbuild
 2a. If you want the whole kit and caboodle including the VMMaker image try e.g.
-     svn co http://www.squeakvm.org/svn/squeak/branches/Cog cogvm
+     svn co http://www.squeakvm.org/svn/squeak/branches/Cog oscogvm
 
-3. Open a cygwin bash shell, cd into the cygbuild directory and execute
-     make
+3. Open a cygwin bash shell, cd into the nscogbuild/cygwinbuild directory and
+   execute
+     mvm
 
    Caution: if you previously used the mingw gnutools approach, you probably
    have a path to that 2.x gcc in your Windows PATH.  Make sure that 'which gcc'
@@ -36,9 +43,10 @@
 3a. The cygwin makefile supports building three VM configurations, product,
     assert and debug, building product by default.  To build a configuration
 	simply type make configuration, e.g.
+		make
 		make assert
 	The configurations are
-	product: stripped  & unstripped production VMs optimized at -O2 in
+	product (default): stripped  & unstripped production VMs optimized at -O2 in
 		build/vm/Croquet.exe
 		build/vm/CroquetUnstripped.exe
 	assert: an unstripped VM that includes assertion checks optimized at -O1 in
@@ -63,8 +71,7 @@
 
 3a. If you want to get the Cog VM simulator working you'll need to build the
 BochsIA32Plugin/BochsIA32Plugin.xcodeproj project and to build that you'll
-need to first build bochs.  WARNING: No one has tried to build the plugin on
-Win32.  You are on your own but your efforts will be warmly welcomed.
+need to first build bochs.
 First check-out the processor simulator source tree containing Bochs:
      svn co http://www.squeakvm.org/svn/squeak/branches/Cog/processors
 Then build the libraries winbochs/{cpu/libcpu.a,disasm/libdisasm.a,fpu/libfpu.a}

Modified: branches/Cog/nscogbuild/cygwinbuild/Makefile
===================================================================
--- branches/Cog/nscogbuild/cygwinbuild/Makefile	2013-01-13 03:48:28 UTC (rev 2672)
+++ branches/Cog/nscogbuild/cygwinbuild/Makefile	2013-01-18 19:25:43 UTC (rev 2673)
@@ -6,6 +6,7 @@
 #############################################################################
 # Base definitions:
 # default configuration from product, assert & debug
+#
 CONFIGURATION=product
 
 # The name of the VM to build
@@ -136,21 +137,18 @@
 #
 # Note: I had to use 'gcc' instead of 'ld' to prevent unresolved symbols
 #       The switch '-mwindows' gives us a GUI app instead of a console app.
+#		Newer cygwins want --export-all-symbols in place of --export-dynamic.
 #
 LD:=	 gcc
 LDFLAGS:= -mno-cygwin -mwindows -Wl,--export-dynamic -L/usr/lib/mingw
 CONSOLELDFLAGS:= -mno-cygwin -mconsole -Wl,--export-dynamic -L/usr/lib/mingw
+#LDFLAGS:= -mno-cygwin -mwindows -Wl,--export-all-symbols -L/usr/lib/mingw
+#CONSOLELDFLAGS:= -mno-cygwin -mconsole -Wl,--export-all-symbols -L/usr/lib/mingw
 STDLIBS:= -lddraw -ldinput -lopengl32 -lwsock32 -lcomdlg32 -lole32 -lwinmm \
 	 -lversion -lwininet -luser32 -lgdi32 -lpsapi -lkernel32 -lcrtdll \
 	-ldsound -lsecur32
 
 #############################################################################
-# Gnuifier settings
-#
-AWK:=		gawk
-GNUIFY:= $(PLATDIR)/win32/misc/gnuify
-
-#############################################################################
 # Tools to use
 #
 AR:= ar rc
@@ -272,7 +270,6 @@
 #############################################################################
 # Building plugins
 #
-
 .PHONY: FORCE
 
 # Internal plugin.  Build as lib then link in lib
@@ -299,16 +296,13 @@
 
 #############################################################################
 # Basic rules
-
+#
 $(OBJDIR)/%.o: %.c $(wildcard $(CROSSDIR)/*.h) $(wildcard $(WIN32DIR)/*.h) $(wildcard $(MAKERDIR)/*.h)
 		$(CC) -o $@ $(CFLAGS) $(INCLUDES) $(DEFS) -c $<
 
 .c.s:
 		$(CC) -S -o $@ -fverbose-asm -Wa,ah $(CFLAGS) $(INCLUDES) $(DEFS) -c $<
 
-gnu-interp.c:	interp.c $(GNUIFY)
-		$(AWK) -f $(GNUIFY) $< > $(VMDIR)/$@
-
 .rc.res:
 		$(RC) $(RCFLAGS) -i $< -o $(OBJDIR)/$@
 
@@ -322,7 +316,6 @@
 #############################################################################
 # Extra specific dependencies
 #
-
 sqNamedPrims.h: plugins.int mkNamedPrims.exe
 	./mkNamedPrims.exe $(INTERNAL_PLUGINS) > sqNamedPrims.h
 


Property changes on: branches/Cog/nscogbuild/cygwinbuild/mvm
___________________________________________________________________
Added: svn:executable
   + *

Modified: branches/Cog/nscogsrc/vm/cogit.c
===================================================================
--- branches/Cog/nscogsrc/vm/cogit.c	2013-01-13 03:48:28 UTC (rev 2672)
+++ branches/Cog/nscogsrc/vm/cogit.c	2013-01-18 19:25:43 UTC (rev 2673)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
+	CCodeGenerator VMMaker.oscog-eem.256 uuid: bfea3efd-4e81-4e85-922e-cf4f58ee5d64
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
+	StackToRegisterMappingCogit VMMaker.oscog-eem.256 uuid: bfea3efd-4e81-4e85-922e-cf4f58ee5d64
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8 " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.256 uuid: bfea3efd-4e81-4e85-922e-cf4f58ee5d64 " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -1319,22 +1319,22 @@
 	{ genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0 },
 	{ genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0 },
 	{ genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorArithmetic, 0, 0, 0, 76, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorArithmetic, 0, 0, 0, 77, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorComparison, 0, 0, 0, 24, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorComparison, 0, 0, 0, 26, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorComparison, 0, 0, 0, 27, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorComparison, 0, 0, 0, 25, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorComparison, 0, 0, 0, 16, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorComparison, 0, 0, 0, 17, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorArithmetic, 0, 0, 0, AddRR, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorArithmetic, 0, 0, 0, SubRR, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorComparison, 0, 0, 0, JumpLess, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorComparison, 0, 0, 0, JumpGreater, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorComparison, 0, 0, 0, JumpLessOrEqual, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorComparison, 0, 0, 0, JumpGreaterOrEqual, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorComparison, 0, 0, 0, JumpZero, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorComparison, 0, 0, 0, JumpNonZero, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorArithmetic, 0, 0, 0, 78, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorArithmetic, 0, 0, 0, 79, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorArithmetic, 0, 0, 0, AndRR, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorArithmetic, 0, 0, 0, OrRR, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
@@ -1479,22 +1479,22 @@
 	{ genExtPushPseudoVariableOrOuterBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushConstantZeroBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushConstantOneBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genSpecialSelectorArithmetic, 0, 0, 0, 76, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorArithmetic, 0, 0, 0, 77, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorComparison, 0, 0, 0, 24, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorComparison, 0, 0, 0, 26, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorComparison, 0, 0, 0, 27, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorComparison, 0, 0, 0, 25, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorComparison, 0, 0, 0, 16, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorComparison, 0, 0, 0, 17, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorArithmetic, 0, 0, 0, AddRR, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorArithmetic, 0, 0, 0, SubRR, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorComparison, 0, 0, 0, JumpLess, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorComparison, 0, 0, 0, JumpGreater, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorComparison, 0, 0, 0, JumpLessOrEqual, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorComparison, 0, 0, 0, JumpGreaterOrEqual, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorComparison, 0, 0, 0, JumpZero, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorComparison, 0, 0, 0, JumpNonZero, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorArithmetic, 0, 0, 0, 78, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorArithmetic, 0, 0, 0, 79, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorArithmetic, 0, 0, 0, AndRR, 1, 0, 0, 0, 0, 1, 0, 0 },
+	{ genSpecialSelectorArithmetic, 0, 0, 0, OrRR, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },

Modified: branches/Cog/nscogsrc/vm/cogit.h
===================================================================
--- branches/Cog/nscogsrc/vm/cogit.h	2013-01-13 03:48:28 UTC (rev 2672)
+++ branches/Cog/nscogsrc/vm/cogit.h	2013-01-18 19:25:43 UTC (rev 2673)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
+	CCodeGenerator VMMaker.oscog-eem.256 uuid: bfea3efd-4e81-4e85-922e-cf4f58ee5d64
  */
 
 

Modified: branches/Cog/nscogsrc/vm/cogmethod.h
===================================================================
--- branches/Cog/nscogsrc/vm/cogmethod.h	2013-01-13 03:48:28 UTC (rev 2672)
+++ branches/Cog/nscogsrc/vm/cogmethod.h	2013-01-18 19:25:43 UTC (rev 2673)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
+	CCodeGenerator VMMaker.oscog-eem.256 uuid: bfea3efd-4e81-4e85-922e-cf4f58ee5d64
  */
 
 typedef struct {

Modified: branches/Cog/nscogsrc/vm/cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.c	2013-01-13 03:48:28 UTC (rev 2672)
+++ branches/Cog/nscogsrc/vm/cointerp.c	2013-01-18 19:25:43 UTC (rev 2673)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.258 uuid: da1433f1-de50-475f-be33-f462b300a2ea
    from
-	CoInterpreter VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8
+	CoInterpreter VMMaker.oscog-eem.258 uuid: da1433f1-de50-475f-be33-f462b300a2ea
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.255 uuid: 51e53ec1-8caf-41f6-9293-1088ef4b82d8 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.258 uuid: da1433f1-de50-475f-be33-f462b300a2ea " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -361,6 +361,7 @@
 sqInt becomewith(sqInt array1, sqInt array2);
 static sqInt becomewithtwoWaycopyHash(sqInt array1, sqInt array2, sqInt twoWayFlag, sqInt copyHashFlag);
 void beRootIfOld(sqInt oop);
+static void beRootWhileForwarding(sqInt oop);
 sqInt booleanValueOf(sqInt obj);
 static sqInt byteLengthOf(sqInt oop);
 sqInt byteSizeOf(sqInt oop);
@@ -398,6 +399,7 @@
 static sqInt changeClassOfto(sqInt rcvr, sqInt argClass);
 sqInt characterForAscii(sqInt ascii);
 sqInt characterTable(void);
+sqInt checkAllAccessibleObjectsOkay(void);
 void checkAssertsEnabledInCoInterpreter(void);
 static sqInt checkCodeIntegrity(sqInt fullGCFlag);
 static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void);
@@ -408,8 +410,12 @@
 static sqInt checkInterpreterIntegrity(void);
 static sqInt checkIsStillMarriedContextcurrentFP(sqInt aContext, char *currentFP);
 static sqInt checkLogIntegrity(void);
+static sqInt checkOkayFields(sqInt oop);
+sqInt checkOkayInterpreterObjects(sqInt writeBack);
 sqInt checkOkayOop(usqInt oop);
-sqInt checkOopHasOkayClass(usqInt oop);
+static sqInt checkOkayStackPage(StackPage *thePage);
+static sqInt checkOkayStackZone(sqInt writeBack);
+sqInt checkOopHasOkayClass(sqInt obj);
 static sqInt checkOopIntegritynamed(sqInt obj, char *name);
 static sqInt checkOopIntegritynamedindex(sqInt obj, char *name, sqInt i);
 static void checkProfileTick(sqInt aPrimitiveMethod);
@@ -589,7 +595,7 @@
 static void initializeInterpreter(sqInt bytesToShift);
 static void initializeMemoryFirstFree(sqInt firstFree);
 static void initializeObjectMemory(sqInt bytesToShift);
-static void initializeStacknumSlotspageSizestackLimitOffsetstackPageHeadroom(char *theStackPages, sqInt stackSlots, sqInt slotsPerPage, sqInt stackLimitOffsetBytes, sqInt stackPageHeadroomBytes);
+static void initializeStacknumSlotspageSize(char *theStackPages, sqInt stackSlots, sqInt slotsPerPage);
 sqInt initialPCForHeadermethod(sqInt methodHeader, sqInt theMethod);
 static sqInt installinAtCacheatstring(sqInt rcvr, sqInt *cache, sqInt atIx, sqInt stringy);
 sqInt instanceSizeOf(sqInt classObj);
@@ -936,7 +942,6 @@
 static void primitiveRelinquishProcessor(void);
 EXPORT(void) primitiveRemLargeIntegers(void);
 static void primitiveResume(void);
-EXPORT(sqInt) primitiveRootTable(void);
 EXPORT(sqInt) primitiveRootTableAt(void);
 static void primitiveScanCharacters(void);
 EXPORT(sqInt) primitiveScreenDepth(void);
@@ -1114,11 +1119,13 @@
 double stackFloatValue(sqInt offset);
 sqInt stackIntegerValue(sqInt offset);
 usqInt stackLimitAddress(void);
+static sqInt stackLimitBytes(void);
 static sqInt stackLimitOffset(void);
 sqInt stackObjectValue(sqInt offset);
 static StackPage * stackPageAt(sqInt index);
 static sqInt stackPageByteSize(void);
 static StackPage * stackPageFor(void *pointer);
+static sqInt stackPageHeadroom(void);
 usqInt stackPointerAddress(void);
 static sqInt stackPointerIndexForFrame(char *theFP);
 sqInt stackPositiveMachineIntegerValue(sqInt offset);
@@ -1184,15 +1191,13 @@
 _iss sqInt bytecodeSetSelector;
 _iss usqInt instructionPointer;
 _iss sqInt argumentCount;
+_iss usqInt freeStart;
 _iss sqInt nilObj;
-_iss usqInt freeStart;
 _iss sqInt messageSelector;
 _iss usqInt newMethod;
 _iss usqInt youngStart;
 _iss StackPage * pages;
 _iss char * stackBasePlus1;
-_iss sqInt rootTableCount;
-_iss usqInt endOfMemory;
 _iss sqInt trueObj;
 _iss sqInt falseObj;
 _iss sqInt remapBufferCount;
@@ -1201,13 +1206,15 @@
 _iss sqInt bytesPerPage;
 _iss char * stackLimit;
 _iss usqInt reserveStart;
+_iss sqInt rootTableCount;
 _iss usqInt memoryLimit;
+_iss usqInt endOfMemory;
 _iss StackPage * mostRecentlyUsedPage;
-_iss sqInt needGCFlag;
 _iss usqInt scavengeThreshold;
 _iss sqInt numStackPages;
 _iss unsigned char primTraceLogIndex;
 _iss sqLong nextProfileTick;
+_iss sqInt needGCFlag;
 _iss sqInt jmpDepth;
 _iss usqInt fwdTableNext;
 _iss sqInt longRunningPrimitiveCheckSemaphore;
@@ -1223,6 +1230,7 @@
 _iss usqLong nextWakeupUsecs;
 _iss sqInt preemptionYields;
 _iss sqInt profileMethod;
+_iss sqInt rootTableOverflowed;
 _iss sqInt cogCompiledCodeCompactionCalledFor;
 _iss sqInt highestRunnableProcessPriority;
 _iss sqInt lastCoggableInterpretedBlockMethod;
@@ -1246,6 +1254,7 @@
 _iss sqInt statIOProcessEvents;
 _iss sqInt statShrinkMemory;
 _iss sqInt cogCodeSize;
+_iss sqInt cogMethodZone;
 _iss usqInt fwdTableLast;
 _iss usqLong gcStartUsecs;
 _iss sqInt lastBackwardJumpMethod;
@@ -1255,7 +1264,6 @@
 _iss sqInt statMkFwdCount;
 _iss sqInt tenuringThreshold;
 _iss sqInt thisClassIndex;
-_iss sqInt cogMethodZone;
 _iss sqInt edenBytes;
 _iss sqInt forceTenureFlag;
 _iss sqInt interruptPending;
@@ -1305,8 +1313,8 @@
 _iss sqInt traceLog[TraceBufferSize /* 768 */];
 _iss sqInt atCache[AtCacheTotalSize + 1 /* 65 */];
 _iss sqInt remapBuffer[RemapBufferSize + 1 /* 26 */];
+_iss sqInt primTraceLog[256];
 _iss sqInt rootTable[RootTableSize + 1 /* 2501 */];
-_iss sqInt primTraceLog[256];
 _iss sqInt* extraRoots[ExtraRootSize + 1 /* 2049 */];
 _iss usqInt suspendedCallbacks[MaxJumpBuf + 1 /* 33 */];
 _iss usqInt suspendedMethods[MaxJumpBuf + 1 /* 33 */];
@@ -1929,7 +1937,7 @@
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
 static usqInt heapBase;
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.255";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.258";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -2007,7 +2015,7 @@
 		theStackMemory = alloca(stackPagesBytes);
 		sqMakeMemoryNotExecutableFromTo(((usqInt)(startOfMemory())), ((usqInt)GIV(memoryLimit)));
 		sqMakeMemoryNotExecutableFromTo(((usqInt)theStackMemory), (((usqInt)theStackMemory)) + stackPagesBytes);
-		initializeStacknumSlotspageSizestackLimitOffsetstackPageHeadroom(theStackMemory, ((sqInt) stackPagesBytes >> 2), ((sqInt) stackPageBytes >> 2), (IFrameSlots + 64) * BytesPerWord, (stackPageHeadroomBytes()) + 1024);
+		initializeStacknumSlotspageSize(theStackMemory, ((sqInt) stackPagesBytes >> 2), ((sqInt) stackPageBytes >> 2));
 		loadInitialContext();
 		ioInitHeartbeat();
 		initialEnterSmalltalkExecutive();
@@ -13050,7 +13058,7 @@
 	/* begin oopFromChunk: */
 	chunk = startOfMemory();
 	oop = chunk + (headerTypeBytes[(longAt(chunk)) & TypeMask]);
-	while ((((usqInt) oop)) < (((usqInt) GIV(endOfMemory)))) {
+	while ((((usqInt) oop)) < (((usqInt) GIV(freeStart)))) {
 		if (!(((longAt(oop)) & TypeMask) == HeaderTypeFree)) {
 			totalObjects += 1;
 			/* begin adjustFieldsAndClassOf:by: */
@@ -13077,10 +13085,8 @@
 		l1:	/* end adjustFieldsAndClassOf:by: */;
 		}
 		/* begin objectAfter: */
-		if (DoAssertionChecks) {
-			if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-				error("no objects after the end of memory");
-			}
+		if (!(asserta((((usqInt) oop)) < (((usqInt) GIV(freeStart)))))) {
+			error("no objects after the end of memory");
 		}
 		if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
 			sz = (longAt(oop)) & AllButTypeMask;
@@ -13580,7 +13586,7 @@
 		assert(pageListIsWellFormed());
 	}
 	GIV(gcMode) = GCModeBecome;
-	mapPointersInObjectsFromto(start, GIV(endOfMemory));
+	mapPointersInObjectsFromto(start, GIV(freeStart));
 	if (twoWayFlag) {
 		/* begin restoreHeadersAfterBecoming:with: */
 		VM_LABEL(0restoreHeadersAfterBecomingwith);
@@ -13741,12 +13747,16 @@
 
 			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.
+				   IMPORTANT: since clearRootsTable is the only thing that clears root bits
+				   do *not* set the root bit unless an object is in the root table.  checking
+				   routines will complain about the root bit being unset instead of the table
+				   being full, but that's life */
 
 				GIV(rootTableCount) += 1;
 				GIV(rootTable)[GIV(rootTableCount)] = oop;
 				longAtput(oop, header | RootBit);
-				if (GIV(rootTableCount) > RootTableRedZone) {
+				if (GIV(rootTableCount) >= RootTableRedZone) {
 
 					/* if we're now in the red zone force an IGC ASAP */
 
@@ -13755,11 +13765,87 @@
 					forceInterruptCheck();
 				}
 			}
+			else {
+
+				/* note overflow; will need to do a fullGC instead of an incremental. */
+
+				GIV(rootTableOverflowed) = 1;
+			}
 		}
 	}
 }
 
 
+/*	Record that the given oop in the old object area points to an object in
+	the young area when oop may be forwarded.
+ */
+/*	Warning: No young objects should be recorded as roots. Callers are
+	responsible for ensuring this constraint is not violated.
+ */
+/*	for debugging... */
+/*	If labelled, gcc duplicates the label when inlining
+	updatePointersInRangeFrom:to: 
+ */
+
+static void
+beRootWhileForwarding(sqInt oop)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt fwdBlock;
+    sqInt header;
+    sqInt header1;
+    sqInt headerLoc;
+
+	header = longAt(oop);
+	if ((header & MarkBit) != 0) {
+
+		/* This oop is forwarded */
+
+		fwdBlock = (header & AllButMarkBitAndTypeMask) << 1;
+		assert(fwdBlockValid(fwdBlock));
+		headerLoc = fwdBlock + BytesPerWord;
+	}
+	else {
+
+		/* Normal -- no forwarding */
+
+		headerLoc = oop;
+	}
+	/* begin noteAsRoot:headerLoc: */
+	header1 = longAt(headerLoc);
+	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.
+			   IMPORTANT: since clearRootsTable is the only thing that clears root bits
+			   do *not* set the root bit unless an object is in the root table.  checking
+			   routines will complain about the root bit being unset instead of the table
+			   being full, but that's life */
+
+			GIV(rootTableCount) += 1;
+			GIV(rootTable)[GIV(rootTableCount)] = oop;
+			longAtput(headerLoc, header1 | RootBit);
+			if (GIV(rootTableCount) >= RootTableRedZone) {
+
+				/* if we're now in the red zone force an IGC ASAP */
+
+				/* begin scheduleIncrementalGC */
+				GIV(needGCFlag) = 1;
+				forceInterruptCheck();
+			}
+		}
+		else {
+
+			/* note overflow; will need to do a fullGC instead of an incremental. */
+
+			GIV(rootTableOverflowed) = 1;
+		}
+	}
+}
+
+
 /*	convert true and false (Smalltalk) to true or false(C) */
 
 sqInt
@@ -15389,12 +15475,16 @@
 
 		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.
+			   IMPORTANT: since clearRootsTable is the only thing that clears root bits
+			   do *not* set the root bit unless an object is in the root table.  checking
+			   routines will complain about the root bit being unset instead of the table
+			   being full, but that's life */
 
 			GIV(rootTableCount) += 1;
 			GIV(rootTable)[GIV(rootTableCount)] = anOop;
 			longAtput(anOop, header | RootBit);
-			if (GIV(rootTableCount) > RootTableRedZone) {
+			if (GIV(rootTableCount) >= RootTableRedZone) {
 
 				/* if we're now in the red zone force an IGC ASAP */
 
@@ -15403,6 +15493,12 @@
 				forceInterruptCheck();
 			}
 		}
+		else {
+
+			/* note overflow; will need to do a fullGC instead of an incremental. */
+
+			GIV(rootTableOverflowed) = 1;
+		}
 	}
 	return anOop;
 }
@@ -15590,6 +15686,98 @@
 	return longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CharacterTable << ShiftForWord));
 }
 
+
+/*	Ensure that all accessible objects in the heap are okay. */
+
+sqInt
+checkAllAccessibleObjectsOkay(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt chunk;
+    sqInt header;
+    sqInt header1;
+    sqInt header2;
+    sqInt obj;
+    sqInt obj1;
+    sqInt ok;
+    sqInt oop;
+    sqInt sz;
+    sqInt sz1;
+    sqInt sz2;
+
+	ok = 1;
+	/* begin firstAccessibleObject */
+	/* begin oopFromChunk: */
+	chunk = startOfMemory();
+	obj1 = chunk + (headerTypeBytes[(longAt(chunk)) & TypeMask]);
+	while ((((usqInt) obj1)) < (((usqInt) GIV(freeStart)))) {
+		if (!(((longAt(obj1)) & TypeMask) == HeaderTypeFree)) {
+			oop = obj1;
+			goto l2;
+		}
+		/* begin objectAfter: */
+		if (!(asserta((((usqInt) obj1)) < (((usqInt) GIV(freeStart)))))) {
+			error("no objects after the end of memory");
+		}
+		if (((longAt(obj1)) & TypeMask) == HeaderTypeFree) {
+			sz = (longAt(obj1)) & AllButTypeMask;
+		}
+		else {
+			/* begin sizeBitsOf: */
+			header = longAt(obj1);
+			sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+				? (longAt(obj1 - (BytesPerWord * 2))) & LongSizeMask
+				: header & SizeMask);
+		}
+		obj1 = (obj1 + sz) + (headerTypeBytes[(longAt(obj1 + sz)) & TypeMask]);
+	}
+	error("heap is empty");
+	oop = null;
+l2:	/* end firstAccessibleObject */;
+	while (!(oop == null)) {
+		ok = ok && (checkOkayFields(oop));
+		/* begin accessibleObjectAfter: */
+		/* begin objectAfter: */
+		if (!(asserta((((usqInt) oop)) < (((usqInt) GIV(freeStart)))))) {
+			error("no objects after the end of memory");
+		}
+		if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
+			sz2 = (longAt(oop)) & AllButTypeMask;
+		}
+		else {
+			/* begin sizeBitsOf: */
+			header2 = longAt(oop);
+			sz2 = ((header2 & TypeMask) == HeaderTypeSizeAndClass
+				? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
+				: header2 & SizeMask);
+		}
+		obj = (oop + sz2) + (headerTypeBytes[(longAt(oop + sz2)) & TypeMask]);
+		while ((((usqInt) obj)) < (((usqInt) GIV(freeStart)))) {
+			if (!(((longAt(obj)) & TypeMask) == HeaderTypeFree)) {
+				oop = obj;
+				goto l1;
+			}
+			/* begin objectAfter: */
+			if (!(asserta((((usqInt) obj)) < (((usqInt) GIV(freeStart)))))) {
+				error("no objects after the end of memory");
+			}
+			if (((longAt(obj)) & TypeMask) == HeaderTypeFree) {
+				sz1 = (longAt(obj)) & AllButTypeMask;
+			}
+			else {
+				/* begin sizeBitsOf: */
+				header1 = longAt(obj);
+				sz1 = ((header1 & TypeMask) == HeaderTypeSizeAndClass
+					? (longAt(obj - (BytesPerWord * 2))) & LongSizeMask
+					: header1 & SizeMask);
+			}
+			obj = (obj + sz1) + (headerTypeBytes[(longAt(obj + sz1)) & TypeMask]);
+		}
+		oop = null;
+	l1:	/* end accessibleObjectAfter: */;
+	}
+	return ok;
+}
+
 void
 checkAssertsEnabledInCoInterpreter(void)
 {
@@ -15719,7 +15907,10 @@
 		commenceCogCompiledCodeCompaction();
 	}
 	if (GIV(needGCFlag)) {
-		GIV(needGCFlag) = 0;
+
+		/* sufficientSpaceAfterGC: runs the incremental GC and
+		   then, if not enough space is available, the fullGC. */
+
 		if (!(sufficientSpaceAfterGC(0))) {
 			setSignalLowSpaceFlagAndSaveProcess();
 		}
@@ -15962,7 +16153,8 @@
 		printNum(GIV(rootTableCount));
 		/* begin cr */
 		printf("\n");
-		ok = 0;
+		ok = GIV(rootTableOverflowed)
+		 && (GIV(needGCFlag));
 	}
 	for (ri = 1; ri <= GIV(rootTableCount); ri += 1) {
 		obj = GIV(rootTable)[ri];
@@ -16192,6 +16384,142 @@
 }
 
 
+/*	Check if the argument is an ok object.
+	If this is a pointers object, check that its fields are all okay oops. */
+
+static sqInt
+checkOkayFields(sqInt oop)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt ccIndex;
+    sqInt fieldOop;
+    sqInt hasYoung;
+    sqInt i;
+    sqInt i1;
+    sqInt oop1;
+
+	if ((oop == null)
+	 || (oop == 0)) {
+		return 1;
+	}
+	if ((oop & 1)) {
+		return 1;
+	}
+	if (!(checkOkayOop(oop))) {
+		return 0;
+	}
+	if (!(checkOopHasOkayClass(oop))) {
+		return 0;
+	}
+	/* begin isYoung: */
+	oop1 = (((ccIndex = (((usqInt) (longAt(oop))) >> 12) & 31)) == 0
+		? (longAt(oop - BaseHeaderSize)) & AllButTypeMask
+		: longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << ShiftForWord))) + BaseHeaderSize) + ((ccIndex - 1) << ShiftForWord)));
+	hasYoung = ((oop1 & 1) == 0)
+	 && ((((usqInt) oop1)) >= (((usqInt) GIV(youngStart))));
+	if (!((((oop & 1) == 0)
+ && (((((usqInt) (longAt(oop))) >> 8) & 15) <= 4))
+		 || (((((usqInt) (longAt(oop))) >> 8) & 15) >= 12))) {
+		return 1;
+	}
+	if (((((usqInt) (longAt(oop))) >> 8) & 15) >= 12) {
+		i = (literalCountOfHeader(headerOf(oop))) - 1;
+	}
+	else {
+		if (((oop & 1) == 0)
+		 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
+			i = (CtxtTempFrameStart + (fetchStackPointerOf(oop))) - 1;
+		}
+		else {
+			i = (lengthOf(oop)) - 1;
+		}
+	}
+	while (i >= 0) {
+		fieldOop = longAt((oop + BaseHeaderSize) + (i << ShiftForWord));
+		if ((fieldOop & 1) == 0) {
+			if ((i == 0)
+			 && (((((usqInt) (longAt(oop))) >> 8) & 15) >= 12)) {
+				if ((methodFor(pointerForOop(fieldOop))) == 0) {
+					print("method ");
+					printHex(oop);
+					print(" has an invalid cog method reference");
+					return 0;
+				}
+			}
+			else {
+				hasYoung = hasYoung
+				 || (((fieldOop & 1) == 0)
+				 && ((((usqInt) fieldOop)) >= (((usqInt) GIV(youngStart)))));
+				if (!(checkOkayOop(fieldOop))) {
+					return 0;
+				}
+				if (!(checkOopHasOkayClass(fieldOop))) {
+					return 0;
+				}
+			}
+		}
+		i -= 1;
+	}
+	if (hasYoung) {
+		/* begin checkOkayYoungReferrer: */
+		if ((((usqInt) oop)) >= (((usqInt) GIV(youngStart)))) {
+			return 1;
+		}
+		if (!(((longAt(oop)) & RootBit) != 0)) {
+			print("root bit is not set in ");
+			printHex(oop);
+			/* begin cr */
+			printf("\n");
+			return 0;
+		}
+		for (i1 = 1; i1 <= GIV(rootTableCount); i1 += 1) {
+			if (oop == (GIV(rootTable)[i1])) {
+				return 1;
+			}
+		}
+		printHex(oop);
+		print(" has root bit set but is not in rootTable");
+		/* begin cr */
+		printf("\n");
+		return 0;
+	}
+	return 1;
+}
+
+sqInt
+checkOkayInterpreterObjects(sqInt writeBack)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt i;
+    sqInt ok;
+    sqInt oop;
+    sqInt oopOrZero;
+
+	ok = 1;
+	ok = ok && (checkOkayFields(GIV(nilObj)));
+	ok = ok && (checkOkayFields(GIV(falseObj)));
+	ok = ok && (checkOkayFields(GIV(trueObj)));
+	ok = ok && (checkOkayFields(GIV(specialObjectsOop)));
+	ok = ok && (checkOkayFields(GIV(messageSelector)));
+	ok = ok && (checkOkayFields(GIV(newMethod)));
+	ok = ok && (checkOkayFields(GIV(lkupClass)));
+	for (i = 0; i <= (MethodCacheEntries - 1); i += MethodCacheEntrySize) {
+		oopOrZero = GIV(methodCache)[i + MethodCacheSelector];
+		if (!(oopOrZero == 0)) {
+			ok = ok && (checkOkayFields(GIV(methodCache)[i + MethodCacheSelector]));
+			ok = ok && (checkOkayFields(GIV(methodCache)[i + MethodCacheClass]));
+			ok = ok && (checkOkayFields(GIV(methodCache)[i + MethodCacheMethod]));
+		}
+	}
+	for (i = 1; i <= (remapBufferCount()); i += 1) {
+		oop = GIV(remapBuffer)[i];
+		if (!((oop & 1))) {
+			ok = ok && (checkOkayFields(oop));
+		}
+	}
+	ok = ok && (checkOkayStackZone(writeBack));
+	return ok;
+}
+
+
 /*	Verify that the given oop is legitimate. Check address, header, and size
 	but not class.
 	Answer true if OK. Otherwise print reason and answer false. */
@@ -16209,15 +16537,19 @@
 	if ((oop & 1)) {
 		return 1;
 	}
-	if (!((oop >= (startOfMemory()))
-		 && (oop < GIV(freeStart)))) {
-		print("oop is not a valid address");
+	if (!((oopisGreaterThanOrEqualTo(oop, startOfMemory()))
+		 && ((((usqInt) oop)) < (((usqInt) GIV(freeStart)))))) {
+		print("oop ");
+		printHex(oop);
+		print(" is not a valid address");
 		/* begin cr */
 		printf("\n");
 		return 0;
 	}
 	if (!((oop % BytesPerWord) == 0)) {
-		print("oop is not a word-aligned address");
+		print("oop ");
+		printHex(oop);
+		print(" is not a word-aligned address");
 		/* begin cr */
 		printf("\n");
 		return 0;
@@ -16227,22 +16559,28 @@
 	sz = ((header & TypeMask) == HeaderTypeSizeAndClass
 		? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
 		: header & SizeMask);
-	if (!((oop + sz) < GIV(freeStart))) {
-		print("oop size would make it extend beyond the end of memory");
+	if (!((((usqInt) (oop + sz))) <= (((usqInt) GIV(freeStart))))) {
+		print("oop ");
+		printHex(oop);
+		print(" size would make it extend beyond the end of memory");
 		/* begin cr */
 		printf("\n");
 		return 0;
 	}
 	type = (longAt(oop)) & TypeMask;
 	if (type == HeaderTypeFree) {
-		print("oop is a free chunk, not an object");
+		print("oop ");
+		printHex(oop);
+		print(" is a free chunk, not an object");
 		/* begin cr */
 		printf("\n");
 		return 0;
 	}
 	if (type == HeaderTypeShort) {
 		if (((((usqInt) (longAt(oop))) >> 12) & 31) == 0) {
-			print("cannot have zero compact class field in a short header");
+			print("oop ");
+			printHex(oop);
+			print(" cannot have zero compact class field in a short header");
 			/* begin cr */
 			printf("\n");
 			return 0;
@@ -16251,7 +16589,9 @@
 	if (type == HeaderTypeClass) {
 		if (!((oop >= BytesPerWord)
 			 && (((longAt(oop - BytesPerWord)) & TypeMask) == type))) {
-			print("class header word has wrong type");
+			print("oop ");
+			printHex(oop);
+			print(" class header word has wrong type");
 			/* begin cr */
 			printf("\n");
 			return 0;
@@ -16261,7 +16601,9 @@
 		if (!((oop >= (BytesPerWord * 2))
 			 && ((((longAt(oop - (BytesPerWord * 2))) & TypeMask) == type)
 			 && (((longAt(oop - BytesPerWord)) & TypeMask) == type)))) {
-			print("class header word has wrong type");
+			print("oop ");
+			printHex(oop);
+			print(" class header word has wrong type");
 			/* begin cr */
 			printf("\n");
 			return 0;
@@ -16269,7 +16611,9 @@
 	}
 	fmt = (((usqInt) (longAt(oop))) >> 8) & 15;
 	if ((fmt == 5) || (fmt == 7)) {
-		print("oop has an unknown format type");
+		print("oop ");
+		printHex(oop);
+		print(" has an unknown format type");
 		/* begin cr */
 		printf("\n");
 		return 0;
@@ -16280,14 +16624,18 @@
 		unusedBit = unusedBit << 16;
 	}
 	if (!(((longAt(oop)) & unusedBit) == 0)) {
-		print("unused header bit 30 is set; should be zero");
+		print("oop ");
+		printHex(oop);
+		print(" unused header bit 30 is set; should be zero");
 		/* begin cr */
 		printf("\n");
 		return 0;
 	}
 	if ((((longAt(oop)) & RootBit) != 0)
 	 && (oop >= GIV(youngStart))) {
-		print("root bit is set in a young object");
+		print("oop ");
+		printHex(oop);
+		print(" root bit is set in a young object");
 		/* begin cr */
 		printf("\n");
 		return 0;
@@ -16295,59 +16643,161 @@
 	return 1;
 }
 
+static sqInt
+checkOkayStackPage(StackPage *thePage)
+{
+    char *callerFP;
+    char *frameRcvrOffset;
+    sqInt ok;
+    sqInt oop;
+    char *theFP;
+    char *theSP;
 
-/*	Attempt to verify that the given oop has a reasonable behavior. The class
-	must be a valid, non-integer oop and must not be nilObj. It must be a
-	pointers object with three or more fields. Finally, the instance
-	specification field of the behavior must match that of the instance. If OK
-	answer true. If not, print reason and answer false.
- */
+	theSP = (thePage->headSP);
+	theFP = (thePage->headFP);
 
+	/* Skip the instruction pointer on top of stack of inactive pages. */
+
+	ok = 1;
+	if (!(thePage == GIV(stackPage))) {
+		theSP += BytesPerWord;
+	}
+	while (1) {
+		frameRcvrOffset = ((((usqInt)(longAt(theFP + FoxMethod)))) < (startOfMemory())
+			? theFP + FoxMFReceiver
+			: theFP + FoxIFReceiver);
+		while (theSP <= frameRcvrOffset) {
+			oop = longAt(theSP);
+			if (!((oop & 1))) {
+				ok = ok && (checkOkayFields(oop));
+			}
+			theSP += BytesPerWord;
+		}
+		if (((((usqInt)(longAt(theFP + FoxMethod)))) < (startOfMemory())
+			? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+			: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
+			assert(isContext(frameContext(theFP)));
+			ok = ok && (checkOkayFields(longAt(theFP + FoxThisContext)));
+		}
+		ok = ok && (checkOkayFields(((((usqInt)(longAt(theFP + FoxMethod)))) < (startOfMemory())
+	? (mframeHomeMethod(theFP)->methodObject)
+	: (/* begin iframeMethod: */
+		longAt(theFP + FoxMethod)))));
+		if (!(((callerFP = frameCallerFP(theFP))) != 0)) break;
+		theSP = (theFP + FoxCallerSavedIP) + BytesPerWord;
+		theFP = callerFP;
+	}
+
+	/* caller ip is frameCallerContext in a base frame */
+
+	theSP = (1
+		? (theFP + FoxCallerSavedIP) + BytesPerWord
+		: theFP + FoxCallerSavedIP);
+	while (theSP <= ((thePage->baseAddress))) {
+		oop = longAt(theSP);
+		if (!((oop & 1))) {
+			ok = ok && (checkOkayFields(oop));
+		}
+		theSP += BytesPerWord;
+	}
+	return ok;
+}
+
+
+/*	Check that all objects in the stack zone are okay */
+
+static sqInt
+checkOkayStackZone(sqInt writeBack)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt i;
+    sqInt ok;
+    StackPage *thePage;
+
+	if (writeBack) {
+		/* begin externalWriteBackHeadFramePointers */
+		assert((GIV(framePointer) - GIV(stackPointer)) < LargeContextSize);
+		assert(GIV(stackPage) == (mostRecentlyUsedPage()));
+		/* begin setHeadFP:andSP:inPage: */
+		assert(GIV(stackPointer) < GIV(framePointer));
+		assert((GIV(stackPointer) < ((GIV(stackPage)->baseAddress)))
+		 && (GIV(stackPointer) > (((GIV(stackPage)->realStackLimit)) - LargeContextSize)));
+		assert((GIV(framePointer) < ((GIV(stackPage)->baseAddress)))
+		 && (GIV(framePointer) > (((GIV(stackPage)->realStackLimit)) - (((sqInt) LargeContextSize >> 1)))));
+		(GIV(stackPage)->headFP = GIV(framePointer));
+		(GIV(stackPage)->headSP = GIV(stackPointer));
+		assert(pageListIsWellFormed());
+	}
+	ok = 1;
+	for (i = 0; i <= (GIV(numStackPages) - 1); i += 1) {
+		/* begin stackPageAt: */
+		thePage = stackPageAtpages(i, GIV(pages));
+		if (!(isFree(thePage))) {
+			ok = ok && (checkOkayStackPage(thePage));
+		}
+	}
+	return ok;
+}
+
+
+/*	Attempt to verify that the given obj has a reasonable behavior. The class
+	must be a
+	valid, non-integer oop and must not be nilObj. It must be a pointers
+	object with three
+	or more fields. Finally, the instance specification field of the behavior
+	must match that
+	of the instance. If OK answer true. If not, print reason and answer false. */
+
 sqInt
-checkOopHasOkayClass(usqInt oop)
-{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+checkOopHasOkayClass(sqInt obj)
+{
     sqInt behaviorFormatBits;
     sqInt ccIndex;
     sqInt formatMask;
-    usqInt oopClass;
-    sqInt oopFormatBits;
+    sqInt objClass;
+    sqInt objFormatBits;
 
-	if (!(checkOkayOop(oop))) {
+	if (!(checkOkayOop(obj))) {
 		return 0;
 	}
-	oopClass = ((usqInt) (((oop & 1)
-	? longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassInteger << ShiftForWord))
-	: (((ccIndex = (((usqInt) (longAt(oop))) >> 12) & 31)) == 0
-			? (longAt(oop - BaseHeaderSize)) & AllButTypeMask
-			: longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << ShiftForWord))) + BaseHeaderSize) + ((ccIndex - 1) << ShiftForWord))))));
-	if ((oopClass & 1)) {
-		print("a SmallInteger is not a valid class or behavior");
+	objClass = ((usqInt) ((((ccIndex = (((usqInt) (longAt(obj))) >> 12) & 31)) == 0
+	? (longAt(obj - BaseHeaderSize)) & AllButTypeMask
+	: longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << ShiftForWord))) + BaseHeaderSize) + ((ccIndex - 1) << ShiftForWord)))));
+	if ((objClass & 1)) {
+		print("obj ");
+		printHex(obj);
+		print(" a SmallInteger is not a valid class or behavior");
 		/* begin cr */
 		printf("\n");
 		return 0;
 	}
-	if (!(okayOop(oopClass))) {
-		print("class oop is not ok");
+	if (!(okayOop(objClass))) {
+		print("obj ");
+		printHex(obj);
+		print(" class obj is not ok");
 		/* begin cr */
 		printf("\n");
 		return 0;
 	}
-	if (!((((oopClass & 1) == 0)
- && (((((usqInt) (longAt(oopClass))) >> 8) & 15) <= 4))
-		 && ((lengthOf(oopClass)) >= 3))) {
-		print("a class (behavior) must be a pointers object of size >= 3");
+	if (!((((objClass & 1) == 0)
+ && (((((usqInt) (longAt(objClass))) >> 8) & 15) <= 4))
+		 && ((lengthOf(objClass)) >= 3))) {
+		print("obj ");
+		printHex(obj);
+		print(" a class (behavior) must be a pointers object of size >= 3");
 		/* begin cr */
 		printf("\n");
 		return 0;
 	}
-	formatMask = (((oop & 1) == 0)
-	 && (((((usqInt) (longAt(oop))) >> 8) & 15) >= 8)
+	formatMask = (((obj & 1) == 0)
+	 && (((((usqInt) (longAt(obj))) >> 8) & 15) >= 8)
 		? 3072
 		: 3840);
-	behaviorFormatBits = ((longAt((oopClass + BaseHeaderSize) + (InstanceSpecificationIndex << ShiftForWord))) - 1) & formatMask;
-	oopFormatBits = (longAt(oop)) & formatMask;
-	if (!(behaviorFormatBits == oopFormatBits)) {
-		print("object and its class (behavior) formats differ");
+	behaviorFormatBits = ((longAt((objClass + BaseHeaderSize) + (InstanceSpecificationIndex << ShiftForWord))) - 1) & formatMask;
+	objFormatBits = (longAt(obj)) & formatMask;
+	if (!(behaviorFormatBits == objFormatBits)) {
+		print("obj ");
+		printHex(obj);
+		print(" and its class (behavior) formats differ");
 		/* begin cr */
 		printf("\n");
 		return 0;
@@ -19018,8 +19468,10 @@
     sqInt startAddr;
     sqInt startOop;
     sqInt startOop1;
+    sqInt stopAddr;
     sqInt stopAddr1;
     sqInt stopAddr2;
+    sqInt stopAddr3;
     sqInt swapFloatWords;
     sqInt sz;
     sqInt sz1;
@@ -19033,7 +19485,7 @@
 		startAddr = startOfMemory();
 		flag("Dan");
 		addr = startAddr;
-		while ((((usqInt) addr)) < (((usqInt) GIV(endOfMemory)))) {
+		while ((((usqInt) addr)) < (((usqInt) GIV(freeStart)))) {
 			longAtput(addr, byteSwapped(longAt(addr)));
 			addr += BytesPerWord;
 		}
@@ -19042,12 +19494,13 @@
 		/* begin oopFromChunk: */
 		chunk1 = startOfMemory();
 		startOop1 = chunk1 + (headerTypeBytes[(longAt(chunk1)) & TypeMask]);
+		stopAddr3 = GIV(freeStart);
 		swapFloatWords = ((VMBIGENDIAN
 	? 1
 	: 0)) != GIV(imageFloatsBigEndian);
 		assert(ClassFloatCompactIndex != 0);
 		oop1 = startOop1;
-		while ((((usqInt) oop1)) < (((usqInt) GIV(endOfMemory)))) {
+		while ((((usqInt) oop1)) < (((usqInt) stopAddr3))) {
 			if (!(((longAt(oop1)) & TypeMask) == HeaderTypeFree)) {
 				fmt = (((usqInt) (longAt(oop1))) >> 8) & 15;
 				if (fmt >= 8) {
@@ -19099,10 +19552,8 @@
 				}
 			}
 			/* begin objectAfter: */
-			if (DoAssertionChecks) {
-				if ((((usqInt) oop1)) >= (((usqInt) GIV(endOfMemory)))) {
-					error("no objects after the end of memory");
-				}
+			if (!(asserta((((usqInt) oop1)) < (((usqInt) GIV(freeStart)))))) {
+				error("no objects after the end of memory");
 			}
 			if (((longAt(oop1)) & TypeMask) == HeaderTypeFree) {
 				sz = (longAt(oop1)) & AllButTypeMask;
@@ -19123,6 +19574,7 @@
 		/* begin oopFromChunk: */
 		chunk = startOfMemory();
 		startOop = chunk + (headerTypeBytes[(longAt(chunk)) & TypeMask]);
+		stopAddr = GIV(freeStart);
 		if (((VMBIGENDIAN
 	? 1
 	: 0)) == GIV(imageFloatsBigEndian)) {
@@ -19131,7 +19583,7 @@
 		}
 		assert(ClassFloatCompactIndex != 0);
 		oop = startOop;
-		while ((((usqInt) oop)) < (((usqInt) GIV(endOfMemory)))) {
+		while ((((usqInt) oop)) < (((usqInt) stopAddr))) {
 			if (!(((longAt(oop)) & TypeMask) == HeaderTypeFree)) {
 				if (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassFloatCompactIndex) {
 					temp = longAt(oop + BaseHeaderSize);
@@ -19140,10 +19592,8 @@
 				}
 			}
 			/* begin objectAfter: */
-			if (DoAssertionChecks) {
-				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-					error("no objects after the end of memory");
-				}
+			if (!(asserta((((usqInt) oop)) < (((usqInt) GIV(freeStart)))))) {
+				error("no objects after the end of memory");
 			}
 			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
 				sz1 = (longAt(oop)) & AllButTypeMask;
@@ -21082,10 +21532,8 @@
 			}
 		}
 		/* begin objectAfter: */
-		if (DoAssertionChecks) {
-			if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-				error("no objects after the end of memory");
-			}
+		if (!(asserta((((usqInt) oop)) < (((usqInt) GIV(freeStart)))))) {
+			error("no objects after the end of memory");
 		}
 		if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
 			sz = (longAt(oop)) & AllButTypeMask;
@@ -21470,18 +21918,17 @@
 		GIV(traceLog)[GIV(traceLogIndex) + 2] = 0;
 		GIV(traceLogIndex) = (GIV(traceLogIndex) + 3) % TraceBufferSize;
 	}
+	GIV(needGCFlag) = 0;
 	GIV(gcStartUsecs) = ioUTCMicrosecondsNow();
 	GIV(statSweepCount) = (GIV(statMarkCount) = (GIV(statMkFwdCount) = (GIV(statCompMoveCount) = 0)));
 	/* begin clearRootsTable */
 	for (i = 1; i <= GIV(rootTableCount); i += 1) {
-
-		/* clear root bits of current root table entries */
-
 		oop = GIV(rootTable)[i];
 		longAtput(oop, (longAt(oop)) & AllButRootBit);
 		GIV(rootTable)[i] = 0;
 	}
 	GIV(rootTableCount) = 0;
+	GIV(rootTableOverflowed) = 0;
 	/* begin initWeakTableForIncrementalGC: */
 	GIV(weakRootCount) = (0
 		? 0
@@ -21679,11 +22126,17 @@
 static sqInt
 fwdTableInit(sqInt blkSize)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt newEndOfMemory;
+
 	/* begin setSizeOfFree:to: */
 	longAtput(GIV(freeStart), (BaseHeaderSize & AllButTypeMask) | HeaderTypeFree);
 	/* begin setEndOfMemory: */
-	assert(((GIV(freeStart) + BaseHeaderSize) & (BytesPerWord - 1)) == 0);
-	GIV(endOfMemory) = GIV(freeStart) + BaseHeaderSize;
+	newEndOfMemory = GIV(freeStart) + BaseHeaderSize;

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list