[svn:parrot] r49153 - in branches/gc_massacre: . compilers/imcc config/gen/makefiles docs docs/pdds docs/project include/parrot lib/Parrot/Harness runtime/parrot/library src src/call src/dynpmc src/gc src/ops src/pmc src/string t t/library t/native_pbc t/op t/tools

bacek at svn.parrot.org bacek at svn.parrot.org
Sun Sep 19 08:27:38 UTC 2010


Author: bacek
Date: Sun Sep 19 08:27:37 2010
New Revision: 49153
URL: https://trac.parrot.org/parrot/changeset/49153

Log:
Merge branch 'master' into gc_massacre

Conflicts:
	MANIFEST
	MANIFEST.SKIP
	config/gen/makefiles/root.in
	docs/project/release_manager_guide.pod
	src/gc/alloc_resources.c
	src/gc/gc_ms.c
	src/gc/gc_private.h
	src/hash.c
	t/op/string_cs.t

Added:
   branches/gc_massacre/src/gc/string_gc.c
      - copied, changed from r49124, branches/gc_massacre/src/gc/alloc_resources.c
Modified:
   branches/gc_massacre/DEPRECATED.pod
   branches/gc_massacre/MANIFEST
   branches/gc_massacre/MANIFEST.SKIP
   branches/gc_massacre/NEWS
   branches/gc_massacre/PBC_COMPAT
   branches/gc_massacre/compilers/imcc/Rules.in
   branches/gc_massacre/compilers/imcc/pbc.c
   branches/gc_massacre/config/gen/makefiles/root.in
   branches/gc_massacre/docs/embed.pod
   branches/gc_massacre/docs/pdds/pdd17_pmc.pod
   branches/gc_massacre/docs/project/release_manager_guide.pod
   branches/gc_massacre/docs/vtables.pod
   branches/gc_massacre/include/parrot/debugger.h
   branches/gc_massacre/include/parrot/pobj.h
   branches/gc_massacre/lib/Parrot/Harness/Smoke.pm
   branches/gc_massacre/runtime/parrot/library/distutils.pir
   branches/gc_massacre/src/call/args.c
   branches/gc_massacre/src/debug.c
   branches/gc_massacre/src/dynpmc/Rules.in
   branches/gc_massacre/src/gc/alloc_resources.c
   branches/gc_massacre/src/gc/gc_ms.c
   branches/gc_massacre/src/gc/gc_ms2.c
   branches/gc_massacre/src/gc/gc_private.h
   branches/gc_massacre/src/gc/mark_sweep.c
   branches/gc_massacre/src/ops/cmp.ops
   branches/gc_massacre/src/ops/core_ops.c
   branches/gc_massacre/src/parrot_debugger.c
   branches/gc_massacre/src/pmc/boolean.pmc
   branches/gc_massacre/src/pmc/callcontext.pmc
   branches/gc_massacre/src/pmc/default.pmc
   branches/gc_massacre/src/pmc/filehandle.pmc
   branches/gc_massacre/src/pmc/float.pmc
   branches/gc_massacre/src/pmc/hash.pmc
   branches/gc_massacre/src/pmc/integer.pmc
   branches/gc_massacre/src/pmc/scalar.pmc
   branches/gc_massacre/src/pmc/undef.pmc
   branches/gc_massacre/src/string/api.c
   branches/gc_massacre/src/vtable.tbl
   branches/gc_massacre/t/harness.pir
   branches/gc_massacre/t/library/archive_zip.t
   branches/gc_massacre/t/native_pbc/integer_4.pbc
   branches/gc_massacre/t/native_pbc/number_4.pbc
   branches/gc_massacre/t/native_pbc/string_4.pbc
   branches/gc_massacre/t/op/string_cs.t
   branches/gc_massacre/t/tools/parrot_debugger.t

Modified: branches/gc_massacre/DEPRECATED.pod
==============================================================================
--- branches/gc_massacre/DEPRECATED.pod	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/DEPRECATED.pod	Sun Sep 19 08:27:37 2010	(r49153)
@@ -132,6 +132,9 @@
 These can be replaced by C<get_bool> and intval ops unless you're using them for
 things that aren't really logical ops (don't do that!).
 
+Logical vtables are removed in r49012, and logical ops on PMCs are converted to
+use C<get_bool> internally. Rakudo seems to depend on logical ops on PMCs.
+
 L<https://trac.parrot.org/parrot/ticket/1655>
 
 =item Method getpid on ParrotInterpreter [experimental]

Modified: branches/gc_massacre/MANIFEST
==============================================================================
--- branches/gc_massacre/MANIFEST	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/MANIFEST	Sun Sep 19 08:27:37 2010	(r49153)
@@ -1,7 +1,7 @@
 # ex: set ro:
 # $Id$
 #
-# generated by tools/dev/mk_manifest_and_skip.pl Tue Sep 14 05:49:01 2010 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Thu Sep 16 15:48:25 2010 UT
 #
 # See below for documentation on the format of this file.
 #
@@ -1294,6 +1294,7 @@
 src/gc/malloc.c                                             []
 src/gc/malloc_trace.c                                       []
 src/gc/mark_sweep.c                                         []
+src/gc/string_gc.c                                          []
 src/gc/system.c                                             []
 src/gc/variable_size_pool.c                                 []
 src/gc/variable_size_pool.h                                 []

Modified: branches/gc_massacre/MANIFEST.SKIP
==============================================================================
--- branches/gc_massacre/MANIFEST.SKIP	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/MANIFEST.SKIP	Sun Sep 19 08:27:37 2010	(r49153)
@@ -1,6 +1,6 @@
 # ex: set ro:
 # $Id$
-# generated by tools/dev/mk_manifest_and_skip.pl Sat Sep 18 00:36:11 2010 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Tue Sep 14 05:49:01 2010 UT
 #
 # This file should contain a transcript of the svn:ignore properties
 # of the directories in the Parrot subversion repository. (Needed for
@@ -840,6 +840,8 @@
 ^src/packfile/.*\.o/
 ^src/packfile/.*\.obj$
 ^src/packfile/.*\.obj/
+^src/packfile/.*\.str$
+^src/packfile/.*\.str/
 # generated from svn:ignore of 'src/pmc/'
 ^src/pmc/.*\.c$
 ^src/pmc/.*\.c/
@@ -1025,6 +1027,9 @@
 ^t/op/.*\.pir/
 ^t/op/.*_pbcexe.*$
 ^t/op/.*_pbcexe.*/
+# generated from svn:ignore of 't/op/testlib/'
+^t/op/testlib/.*\.pbc$
+^t/op/testlib/.*\.pbc/
 # generated from svn:ignore of 't/perl/'
 ^t/perl/Parrot_Test_1\.pasm$
 ^t/perl/Parrot_Test_1\.pasm/

Modified: branches/gc_massacre/NEWS
==============================================================================
--- branches/gc_massacre/NEWS	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/NEWS	Sun Sep 19 08:27:37 2010	(r49153)
@@ -1,5 +1,30 @@
 # $Id$
 
+New in 2.8.0
+- Core
+  + Inlined hashing and comparison functions
+  + Hash memory allocation moved from system malloc to lazy allocated
+  + Avoided infinite catching of exceptions while dying from exception
+  + Some svn fixes
+  + Added a check for duplicate vtable entries in PMCs
+  + Building Parrot with Perl 5.12 and gcc-4.5 / g++-4.5
+  + Eliminated cruft left over after dynops_mapping
+  + Improved charset and string encoding
+  + Better organisation of programs by reposition it to "tools/build" and "tools/release"
+  + Implemented Exception clone vtable function
+  + Added experimental function Parrot_getpid and getpid method
+  + Closed a lot of tickets
+- Testing
+  + Added more core pmc tests
+  + Rearranged some tests with C coverage
+  + We now have Smolder back, at http://smolder.parrot.org . Submit reports with "make smoke"
+- GitMigration
+  + Set up a test site for github trac plugin at http://mksig.org/trac/
+  + Code of Trac plugin at github is on http://github.com/cotto/github-trac
+  + Parrot is now mirrored on github at http://github.com/parrot/parrot
+- Compilers
+  + Fixed problem with imcc HLL in load_bytecode difference between loading a pbc and compiling a pir
+ 
 New in 2.7.0
 - Core
   + cleanups in packfile and freeze/thaw handling

Modified: branches/gc_massacre/PBC_COMPAT
==============================================================================
--- branches/gc_massacre/PBC_COMPAT	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/PBC_COMPAT	Sun Sep 19 08:27:37 2010	(r49153)
@@ -28,6 +28,7 @@
 
 # please insert tab separated entries at the top of the list
 
+8.3	2010.09.15	luben	removed logical vtables
 8.2	2010.08.19	cotto	minor version bump for 2.7.0
 8.1	2010.08.10	plobsing	merge dynop_mapping branch
 8.0	2010.07.20	coke	released 2.6.0

Modified: branches/gc_massacre/compilers/imcc/Rules.in
==============================================================================
--- branches/gc_massacre/compilers/imcc/Rules.in	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/compilers/imcc/Rules.in	Sun Sep 19 08:27:37 2010	(r49153)
@@ -10,6 +10,8 @@
     compilers/imcc/symreg.h \
     compilers/imcc/unit.h \
     $(INC_DIR)/oplib/ops.h \
+    $(INC_DIR)/oplib/core_ops.h \
+    $(INC_DIR)/runcore_api.h \
     $(PARROT_H_HEADERS)
 
 compilers/imcc/instructions$(O) : \
@@ -24,6 +26,8 @@
     compilers/imcc/symreg.h \
     compilers/imcc/unit.h \
     $(INC_DIR)/oplib/ops.h \
+    $(INC_DIR)/oplib/core_ops.h \
+    $(INC_DIR)/runcore_api.h \
     $(PARROT_H_HEADERS)
 
 compilers/imcc/pbc$(O) : \
@@ -37,6 +41,8 @@
     compilers/imcc/symreg.h \
     compilers/imcc/unit.h \
     $(INC_DIR)/oplib/ops.h \
+    $(INC_DIR)/oplib/core_ops.h \
+    $(INC_DIR)/runcore_api.h \
     $(PARROT_H_HEADERS) \
     include/pmc/pmc_sub.h
 
@@ -83,6 +89,8 @@
     compilers/imcc/symreg.h \
     compilers/imcc/unit.h \
     $(INC_DIR)/oplib/ops.h \
+    $(INC_DIR)/oplib/core_ops.h \
+    $(INC_DIR)/runcore_api.h \
     $(PARROT_H_HEADERS)
 
 compilers/imcc/debug$(O) : \
@@ -163,6 +171,8 @@
     compilers/imcc/symreg.h \
     compilers/imcc/unit.h \
     $(INC_DIR)/oplib/ops.h \
+    $(INC_DIR)/oplib/core_ops.h \
+    $(INC_DIR)/runcore_api.h \
     $(PARROT_H_HEADERS)
 	$(CC) $(CFLAGS) @optimize::compilers/imcc/optimizer.c@ @ccwarn::compilers/imcc/optimizer.c@ @cc_shared@ -I$(@D) @cc_o_out@$@ -c compilers/imcc/optimizer.c
 

Modified: branches/gc_massacre/compilers/imcc/pbc.c
==============================================================================
--- branches/gc_massacre/compilers/imcc/pbc.c	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/compilers/imcc/pbc.c	Sun Sep 19 08:27:37 2010	(r49153)
@@ -1306,7 +1306,7 @@
         }
     }
 
-    if (!lex_info && (unit->outer || need_lex)) {
+    if (!lex_info && need_lex) {
         lex_info = Parrot_pmc_new_noinit(interp, lex_info_id);
         VTABLE_init_pmc(interp, lex_info, sub_pmc);
     }

Modified: branches/gc_massacre/config/gen/makefiles/root.in
==============================================================================
--- branches/gc_massacre/config/gen/makefiles/root.in	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/config/gen/makefiles/root.in	Sun Sep 19 08:27:37 2010	(r49153)
@@ -469,6 +469,7 @@
     src/gc/system$(O) \
     src/gc/fixed_allocator$(O) \
     src/gc/variable_size_pool$(O) \
+    src/gc/string_gc$(O) \
     src/global_setup$(O) \
     src/hash$(O) \
     src/hll$(O) \
@@ -929,11 +930,17 @@
 src/oo$(O) : $(PARROT_H_HEADERS) include/pmc/pmc_class.h src/oo.c \
     include/pmc/pmc_object.h src/oo.str $(INC_DIR)/oo_private.h
 
-src/scheduler$(O) : $(PARROT_H_HEADERS) src/scheduler.str src/scheduler.c \
-	include/pmc/pmc_scheduler.h include/pmc/pmc_task.h \
-	include/pmc/pmc_timer.h \
-	$(INC_DIR)/scheduler_private.h \
-	$(INC_DIR)/runcore_api.h
+src/scheduler$(O) : \
+    $(PARROT_H_HEADERS) \
+    src/scheduler.str \
+    src/scheduler.c \
+    include/pmc/pmc_scheduler.h \
+    include/pmc/pmc_task.h \
+    include/pmc/pmc_timer.h \
+    $(INC_DIR)/extend.h \
+    $(INC_DIR)/extend_vtable.h \
+    $(INC_DIR)/scheduler_private.h \
+    $(INC_DIR)/runcore_api.h
 
 src/io/core$(O) : $(PARROT_H_HEADERS) src/io/io_private.h src/io/core.c
 
@@ -1055,8 +1062,13 @@
     src/packdump$(O) @rpath_blib@ $(ALL_PARROT_LIBS) $(LINKFLAGS)
 #IF(win32):	if exist $@.manifest mt.exe -nologo -manifest $@.manifest -outputresource:$@;1
 
-src/pbc_dump$(O) : $(INC_DIR)/embed.h  $(INC_DIR)/oplib/ops.h \
-	$(PARROT_H_HEADERS) src/pbc_dump.c
+src/pbc_dump$(O) : \
+    $(INC_DIR)/embed.h \
+    $(INC_DIR)/oplib/ops.h \
+    $(INC_DIR)/oplib/core_ops.h \
+    $(PARROT_H_HEADERS) \
+    $(INC_DIR)/runcore_api.h \
+    src/pbc_dump.c
 
 $(INSTALLABLEPDUMP) : src/pbc_dump$(O) src/packdump$(O) \
 	src/install_config$(O) $(LIBPARROT)
@@ -1261,7 +1273,11 @@
 src/extend_vtable$(O) : $(PARROT_H_HEADERS) \
 	$(INC_DIR)/extend.h $(INC_DIR)/extend_vtable.h src/extend_vtable.c
 
-src/global_setup$(O) : $(PARROT_H_HEADERS) src/global_setup.str src/global_setup.c
+src/global_setup$(O) : $(PARROT_H_HEADERS) \
+    src/global_setup.str \
+    src/global_setup.c \
+    $(INC_DIR)/runcore_api.h \
+    $(INC_DIR)/oplib/core_ops.h
 
 src/namespace$(O) : $(PARROT_H_HEADERS) src/namespace.str src/namespace.c \
 	include/pmc/pmc_sub.h
@@ -1303,6 +1319,8 @@
 src/gc/variable_size_pool$(O) : $(PARROT_H_HEADERS) \
 	src/gc/variable_size_pool.h src/gc/variable_size_pool.c
 
+src/gc/string_gc$(O) : $(PARROT_H_HEADERS) \
+	src/gc/gc_private.h src/gc/string_gc.c
 
 src/hll$(O) : $(PARROT_H_HEADERS) src/hll.str $(INC_DIR)/dynext.h src/hll.c
 
@@ -1319,14 +1337,21 @@
 src/debug$(O) : $(INC_DIR)/embed.h $(INC_DIR)/extend.h \
 	$(PARROT_H_HEADERS) src/debug.c \
 	$(INC_DIR)/oplib/ops.h \
+        $(INC_DIR)/oplib/core_ops.h \
 	$(INC_DIR)/runcore_api.h $(INC_DIR)/runcore_trace.h \
 	src/debug.str include/pmc/pmc_key.h \
 	include/pmc/pmc_continuation.h \
 	$(INC_DIR)/extend_vtable.h
 
-src/sub$(O) : $(PARROT_H_HEADERS) $(INC_DIR)/oplib/ops.h \
-	src/sub.str src/sub.c \
-	include/pmc/pmc_sub.h include/pmc/pmc_continuation.h
+src/sub$(O) : \
+    $(PARROT_H_HEADERS) \
+    $(INC_DIR)/oplib/ops.h \
+    $(INC_DIR)/oplib/core_ops.h \
+    $(INC_DIR)/runcore_api.h \
+    src/sub.str \
+    src/sub.c \
+    include/pmc/pmc_sub.h \
+    include/pmc/pmc_continuation.h
 
 src/string/api$(O) : $(PARROT_H_HEADERS) src/string/api.str \
 	src/string/private_cstring.h src/string/api.c
@@ -1342,10 +1367,15 @@
 	src/exceptions.str src/exceptions.c \
 	include/pmc/pmc_continuation.h
 
-src/thread$(O) : $(PARROT_H_HEADERS) $(INC_DIR)/atomic.h src/thread.c \
-	include/pmc/pmc_sub.h \
-	include/pmc/pmc_parrotinterpreter.h \
-	$(INC_DIR)/runcore_api.h
+src/thread$(O) : \
+    $(PARROT_H_HEADERS) \
+    $(INC_DIR)/atomic.h \
+    $(INC_DIR)/extend.h \
+    $(INC_DIR)/extend_vtable.h \
+    src/thread.c \
+    include/pmc/pmc_sub.h \
+    include/pmc/pmc_parrotinterpreter.h \
+    $(INC_DIR)/runcore_api.h
 
 ## SUFFIX OVERRIDE - dynloaded files need cc_shared
 src/extend$(O) : $(PARROT_H_HEADERS) $(INC_DIR)/extend.h \
@@ -1390,6 +1420,8 @@
 
 src/interp/inter_cb$(O) : $(PARROT_H_HEADERS) \
 	include/pmc/pmc_parrotinterpreter.h \
+        $(INC_DIR)/extend.h \
+        $(INC_DIR)/extend_vtable.h \
 	src/interp/inter_cb.str src/interp/inter_cb.c
 
 src/interp/inter_misc$(O) : $(PARROT_H_HEADERS) \
@@ -1451,27 +1483,41 @@
 	src/main.c
 
 src/multidispatch$(O) : \
-	src/multidispatch.c \
-	src/multidispatch.str \
-	$(INC_DIR)/oplib/ops.h $(PARROT_H_HEADERS) \
-	include/pmc/pmc_nci.h include/pmc/pmc_sub.h
-
-src/packfile$(O) : src/packfile.str \
-	src/packfile.c \
-	include/pmc/pmc_sub.h include/pmc/pmc_key.h \
-	compilers/imcc/imc.h \
-	compilers/imcc/cfg.h \
-	compilers/imcc/debug.h \
-	compilers/imcc/instructions.h \
-	compilers/imcc/sets.h \
-	compilers/imcc/symreg.h \
-	compilers/imcc/unit.h \
-	$(INC_DIR)/oplib/ops.h \
-	$(INC_DIR)/embed.h $(INC_DIR)/extend.h $(INC_DIR)/extend_vtable.h \
-	$(PARROT_H_HEADERS) $(INC_DIR)/runcore_api.h
+    src/multidispatch.c \
+    src/multidispatch.str \
+    $(INC_DIR)/oplib/ops.h \
+    $(PARROT_H_HEADERS) \
+    include/pmc/pmc_nativepccmethod.h \
+    include/pmc/pmc_nci.h \
+    include/pmc/pmc_sub.h
 
-src/packfile/pf_items$(O) : $(PARROT_H_HEADERS) src/packfile/pf_items.str \
-	src/packfile/pf_items.c
+src/packfile$(O) : \
+    src/packfile.str \
+    src/packfile.c \
+    include/pmc/pmc_sub.h \
+    include/pmc/pmc_key.h \
+    include/pmc/pmc_parrotlibrary.h \
+    compilers/imcc/imc.h \
+    compilers/imcc/cfg.h \
+    compilers/imcc/debug.h \
+    compilers/imcc/instructions.h \
+    compilers/imcc/sets.h \
+    compilers/imcc/symreg.h \
+    compilers/imcc/unit.h \
+    $(INC_DIR)/oplib/ops.h \
+    $(INC_DIR)/oplib/core_ops.h \
+    $(INC_DIR)/dynext.h \
+    $(INC_DIR)/embed.h \
+    $(INC_DIR)/extend.h \
+    $(INC_DIR)/extend_vtable.h \
+    $(PARROT_H_HEADERS) \
+    $(INC_DIR)/runcore_api.h
+
+src/packfile/pf_items$(O) : \
+    $(PARROT_H_HEADERS) \
+    src/packfile/byteorder.h \
+    src/packfile/pf_items.str \
+    src/packfile/pf_items.c
 
 src/packout$(O) : $(PARROT_H_HEADERS) include/pmc/pmc_key.h src/packout.c
 
@@ -1488,6 +1534,9 @@
 src/embed$(O) : $(PARROT_H_HEADERS) $(INC_DIR)/embed.h \
         src/embed.c src/embed.str \
         $(INC_DIR)/oplib/ops.h $(INC_DIR)/runcore_api.h \
+        $(INC_DIR)/extend.h \
+        $(INC_DIR)/extend_vtable.h \
+        $(INC_DIR)/oplib/core_ops.h \
         compilers/imcc/imc.h \
         compilers/imcc/cfg.h \
         compilers/imcc/debug.h \
@@ -1530,7 +1579,12 @@
 
 src/misc$(O) : $(PARROT_H_HEADERS) src/misc.c
 
-src/utils$(O) : $(PARROT_H_HEADERS) include/pmc/pmc_nci.h src/utils.c
+src/utils$(O) : \
+    $(PARROT_H_HEADERS) \
+    include/pmc/pmc_nci.h \
+    src/utils.c \
+    $(INC_DIR)/extend.h \
+    $(INC_DIR)/extend_vtable.h
 
 ## SUFFIX OVERRIDE
 src/spf_render$(O) : $(PARROT_H_HEADERS) src/spf_render.str src/spf_render.c
@@ -1573,8 +1627,14 @@
     src/string/encoding/shared.h \
     src/string/unicode.h
 
-src/pbc_merge$(O) : $(INC_DIR)/embed.h src/pbc_merge.c \
-	include/pmc/pmc_sub.h $(INC_DIR)/oplib/ops.h $(PARROT_H_HEADERS)
+src/pbc_merge$(O) : \
+    $(INC_DIR)/embed.h \
+    src/pbc_merge.c \
+    include/pmc/pmc_sub.h \
+    $(INC_DIR)/oplib/ops.h \
+    $(INC_DIR)/oplib/core_ops.h \
+    $(INC_DIR)/runcore_api.h \
+    $(PARROT_H_HEADERS)
 
 src/io/filehandle$(O) : $(PARROT_H_HEADERS) include/pmc/pmc_filehandle.h \
     src/io/io_private.h src/io/filehandle.c
@@ -1716,6 +1776,7 @@
     t/configure/*.t \
     t/steps/*.t
 PBC_TEST_FILES = \
+#IF(has_icu):    t/op/testlib/test_strings.pbc \
     t/pmc/testlib/annotations.pbc \
     t/pmc/testlib/number.pbc \
     t/op/testlib/test_strings.pbc

Modified: branches/gc_massacre/docs/embed.pod
==============================================================================
--- branches/gc_massacre/docs/embed.pod	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/docs/embed.pod	Sun Sep 19 08:27:37 2010	(r49153)
@@ -1141,8 +1141,6 @@
 
 =item C<Parrot_PMC_i_floor_divide_int>
 
-=item C<Parrot_PMC_i_logical_not>
-
 =item C<Parrot_PMC_i_modulus>
 
 =item C<Parrot_PMC_i_modulus_float>
@@ -1199,14 +1197,6 @@
 
 =item C<Parrot_PMC_i_subtract_int>
 
-=item C<Parrot_PMC_logical_and>
-
-=item C<Parrot_PMC_logical_not>
-
-=item C<Parrot_PMC_logical_or>
-
-=item C<Parrot_PMC_logical_xor>
-
 =item C<Parrot_PMC_mark>
 
 =item C<Parrot_PMC_modulus>

Modified: branches/gc_massacre/docs/pdds/pdd17_pmc.pod
==============================================================================
--- branches/gc_massacre/docs/pdds/pdd17_pmc.pod	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/docs/pdds/pdd17_pmc.pod	Sun Sep 19 08:27:37 2010	(r49153)
@@ -1327,40 +1327,6 @@
 greater). The C<_num> version performs a numeric comparison, while the
 C<_string> version performs a string comparison.
 
-=item logical_or
-
-  PMC* logical_or(INTERP, PMC *self, PMC *value, PMC *dest)
-
-Performs a logical OR, returning I<self> if it is true, and I<value>
-otherwise.
-
-=item logical_and
-
-  PMC* logical_and(INTERP, PMC *self, PMC *value, PMC *dest)
-
-Performs a logical AND, returning a true value if both I<self> and
-I<value> are true, and a false value otherwise. (Currently implemented
-as: If I<self> is false, return it, since the entire expression is
-false. If I<self> is true, return value, since the truth or falsehood of
-I<value> will determine the truth or falsehood of the whole expression.)
-
-=item logical_xor
-
-  PMC* logical_xor(INTERP, PMC *self, PMC *value, PMC *dest)
-
-Performs a logical XOR, returning I<self> if it is true and I<value> is
-false, returning I<value> if it is true and I<self> is false, and
-returning a false value (PMC of the same type as I<self>, with the
-boolean value 0) if both are true or neither are true.
-
-=item logical_not
-
-  PMC* logical_not(INTERP, PMC *self, PMC *dest)
-  void i_logical_not(INTERP, PMC *self)
-
-Returns the logical negation of I<self>. The C<i_> variant performs an
-inplace negation, modifying the value of I<self>.
-
 =back
 
 =head4 String Vtable Functions

Modified: branches/gc_massacre/docs/project/release_manager_guide.pod
==============================================================================
--- branches/gc_massacre/docs/project/release_manager_guide.pod	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/docs/project/release_manager_guide.pod	Sun Sep 19 08:27:37 2010	(r49153)
@@ -118,9 +118,10 @@
 
 =item f
 
-Run C<./ops2c --core> (or C<make bootstrap-ops>, ignoring errors) followed by
-C<make reconfig> and C<make> to update the names of version-specific internal
-functions.
+To have parrot configured and have run C<make> with the old version number is
+condition for this step. Run C<./ops2c --core> (or C<make bootstrap-ops>,
+ignoring errors) followed by C<make reconfig> and C<make> to update the names
+of version-specific internal functions.
 
 =item g
 
@@ -410,7 +411,7 @@
  - Oct 19, 2010 - 2.9*  - gerd
  - Nov 16, 2010 - 2.10  - tcurtis
  - Dec 21, 2010 - 2.11  - whiteknight
- - Jan 18, 2011 - 3.0*  - ??
+ - Jan 18, 2011 - 3.0*  - cotto
  - Feb 15, 2011 - 3.1   - mikehh
  - Mar 15, 2011 - 3.2   - ??
  - Apr 19, 2011 - 3.3*  - ??

Modified: branches/gc_massacre/docs/vtables.pod
==============================================================================
--- branches/gc_massacre/docs/vtables.pod	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/docs/vtables.pod	Sun Sep 19 08:27:37 2010	(r49153)
@@ -280,17 +280,6 @@
 result in C<dest>. (Probably by calling its C<set_string> method) This is a
 string multimethod.
 
-=item C<logical_or>
-
-=item C<logical_and>
-
-Perform the given short-circuiting logical operations between your boolean
-value and the value passed in, storing the result in C<dest>.
-
-=item C<logical_not>
-
-Set yourself to be a logical negation of the value passed in.
-
 =item C<repeat>
 
 Repeat your string representation C<value> times and store the result in

Modified: branches/gc_massacre/include/parrot/debugger.h
==============================================================================
--- branches/gc_massacre/include/parrot/debugger.h	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/include/parrot/debugger.h	Sun Sep 19 08:27:37 2010	(r49153)
@@ -129,8 +129,9 @@
 /*  PDB_breakpoint_t
  *      List of breakpoints.
  *
- *  pc:             Where the breakpoint is
  *  id:             The identification number of this breakpoint
+ *  pc:             Where the breakpoint is
+ *  line:           The source file line number
  *  skip:           The number of times to skip this breakpoint
  *  condition:      The condition attached to the breakpoint; may be NULL
  *  prev, next:     The previous & next breakpoints in the list; may be NULL.
@@ -139,8 +140,9 @@
 typedef struct PDB_breakpoint *PDB_breakpoint_ptr;
 
 typedef struct PDB_breakpoint {
-    opcode_t                *pc;
     unsigned long           id;
+    opcode_t                *pc;
+    unsigned long           line;
     long                    skip;
     PDB_condition_t         *condition;
     PDB_breakpoint_ptr      prev;

Modified: branches/gc_massacre/include/parrot/pobj.h
==============================================================================
--- branches/gc_massacre/include/parrot/pobj.h	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/include/parrot/pobj.h	Sun Sep 19 08:27:37 2010	(r49153)
@@ -135,6 +135,8 @@
     PObj_is_string_FLAG         = POBJ_FLAG(8),
     /* PObj is a PMC */
     PObj_is_PMC_FLAG            = POBJ_FLAG(9),
+    /* PObj is a copy of a string that doesn't own the string buffer */
+    PObj_is_string_copy_FLAG    = POBJ_FLAG(10),
     /* the PMC is a shared PMC */
     PObj_is_PMC_shared_FLAG     = POBJ_FLAG(11), /* Same as PObj_is_shared_FLAG */
     /* PObj is otherwise shared */
@@ -252,6 +254,10 @@
 #define PObj_is_string_SET(o) PObj_flag_SET(is_string, o)
 #define PObj_is_string_CLEAR(o) PObj_flag_CLEAR(is_string, o)
 
+#define PObj_is_string_copy_TEST(o) PObj_flag_TEST(is_string_copy, o)
+#define PObj_is_string_copy_SET(o) PObj_flag_SET(is_string_copy, o)
+#define PObj_is_string_copy_CLEAR(o) PObj_flag_CLEAR(is_string_copy, o)
+
 #define PObj_sysmem_TEST(o) PObj_flag_TEST(sysmem, o)
 #define PObj_sysmem_SET(o) PObj_flag_SET(sysmem, o)
 #define PObj_sysmem_CLEAR(o) PObj_flag_CLEAR(sysmem, o)
@@ -324,6 +330,10 @@
         (PObj_sysmem_FLAG | PObj_on_free_list_FLAG | \
          PObj_constant_FLAG | PObj_external_FLAG)))
 
+#define PObj_is_growable_TESTALL(o) (!(PObj_get_FLAGS(o) & \
+        (PObj_sysmem_FLAG | PObj_is_string_copy_FLAG | \
+         PObj_constant_FLAG | PObj_external_FLAG)))
+
 #define PObj_custom_mark_destroy_SETALL(o) do { \
         PObj_custom_mark_SET(o); \
         PObj_custom_destroy_SET(o); \

Modified: branches/gc_massacre/lib/Parrot/Harness/Smoke.pm
==============================================================================
--- branches/gc_massacre/lib/Parrot/Harness/Smoke.pm	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/lib/Parrot/Harness/Smoke.pm	Sun Sep 19 08:27:37 2010	(r49153)
@@ -50,7 +50,7 @@
     send_archive_to_smolder( %env_data );
 
 At the current time, automated smoke reports are collected and displayed via
-the Smolder system at L<http://smolder.plusthree.com>.  Such reports require
+the Smolder system at L<http://smolder.parrot.org>.  Such reports require
 the Perl 5 F<LWP::UserAgent> module, available from CPAN.
 
 On network problem or for offline use you may send tar reports later
@@ -92,10 +92,10 @@
 
 # language implementations have a different project id
 my %SMOLDER_CONFIG = (
-    server       => 'http://smolder.plusthree.com',
+    server       => 'http://smolder.parrot.org',
     username     => 'parrot-autobot',
-    password     => 'squ at wk',
-    project_id   => 8,
+    password     => 'qa_rocks',
+    project_id   => 1,
     report_file  => ['parrot_test_run.tar.gz'],
 );
 

Modified: branches/gc_massacre/runtime/parrot/library/distutils.pir
==============================================================================
--- branches/gc_massacre/runtime/parrot/library/distutils.pir	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/runtime/parrot/library/distutils.pir	Sun Sep 19 08:27:37 2010	(r49153)
@@ -2061,6 +2061,11 @@
 
 a hash
 
+=item smolder_credentials
+
+A string, of the form "USERNAME:PASSWORD" to be used as the credentials for
+the server. The default is "parrot-autobot:qa_rocks"
+
 =back
 
 =cut
@@ -2155,6 +2160,14 @@
     set $P0, 1
     $P0[0] = archive
     push contents, $P0
+    $S0 = get_value('smolder_credentials', "parrot-autobot:qa_rocks" :named('default'), kv :flat :named)
+    $P0 = split ':', $S0
+    $P1 = $P0[0]
+    push contents, 'username'
+    push contents, $P1
+    $P1 = $P0[1]
+    push contents, 'password'
+    push contents, $P1
     load_bytecode 'LWP/UserAgent.pir'
     .local pmc ua, response
     ua = new ['LWP';'UserAgent']

Modified: branches/gc_massacre/src/call/args.c
==============================================================================
--- branches/gc_massacre/src/call/args.c	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/call/args.c	Sun Sep 19 08:27:37 2010	(r49153)
@@ -736,7 +736,7 @@
 {
     ASSERT_ARGS(fill_params)
     INTVAL *raw_params;
-    PMC    *named_used_list = PMCNULL;
+    Hash   *named_used_list = NULL;
     INTVAL  param_index     = 0;
     INTVAL  arg_index       = 0;
     INTVAL  named_count     = 0;
@@ -789,6 +789,8 @@
             else if (err_check) {
                 /* We've used up all the parameters, but have extra positional
                  * args left over. */
+                if (named_used_list != NULL)
+                    parrot_hash_destroy(interp, named_used_list);
                 Parrot_ex_throw_from_c_args(interp, NULL,
                     EXCEPTION_INVALID_OPERATION,
                     "too many positional arguments: %d passed, %d expected",
@@ -813,10 +815,13 @@
                 INTVAL num_positionals = positional_args - arg_index;
                 if (num_positionals < 0)
                     num_positionals = 0;
-                if (named_count > 0)
+                if (named_count > 0){
+                    if (named_used_list != NULL)
+                        parrot_hash_destroy(interp, named_used_list);
                     Parrot_ex_throw_from_c_args(interp, NULL,
                         EXCEPTION_INVALID_OPERATION,
                         "named parameters must follow all positional parameters");
+                }
 
                 collect_positional = Parrot_pmc_new_init_int(interp,
                     Parrot_get_ctx_HLL_type(interp, enum_class_ResizablePMCArray),
@@ -838,10 +843,13 @@
             /* Fill a named parameter with a positional argument. */
             if (param_flags & PARROT_ARG_NAME) {
                 STRING *param_name;
-                if (!(param_flags & PARROT_ARG_STRING))
+                if (!(param_flags & PARROT_ARG_STRING)){
+                    if (named_used_list != NULL)
+                        parrot_hash_destroy(interp, named_used_list);
                     Parrot_ex_throw_from_c_args(interp, NULL,
                         EXCEPTION_INVALID_OPERATION,
                         "named parameters must have a name specified");
+                }
                 param_name = PARROT_ARG_CONSTANT_ISSET(param_flags)
                    ?  accessor->string_constant(interp, arg_info, param_index)
                    : *accessor->string(interp, arg_info, param_index);
@@ -854,15 +862,19 @@
                 param_flags = raw_params[param_index];
 
                 /* Mark the name as used, cannot be filled again. */
-                if (PMC_IS_NULL(named_used_list)) /* Only created if needed. */
-                    named_used_list = Parrot_pmc_new(interp, enum_class_Hash);
+                if (named_used_list==NULL) /* Only created if needed. */
+                    named_used_list = parrot_create_hash(interp,
+                            enum_type_INTVAL, Hash_key_type_STRING);
 
-                VTABLE_set_integer_keyed_str(interp, named_used_list, param_name, 1);
+                parrot_hash_put(interp, named_used_list, param_name, (void *)1);
             }
-            else if (named_count > 0)
+            else if (named_count > 0){
+                if (named_used_list != NULL)
+                    parrot_hash_destroy(interp, named_used_list);
                 Parrot_ex_throw_from_c_args(interp, NULL,
                     EXCEPTION_INVALID_OPERATION,
                     "named parameters must follow all positional parameters");
+            }
 
             /* Check for :lookahead parameter goes here. */
 
@@ -885,6 +897,8 @@
                     VTABLE_get_number_keyed_int(interp, call_object, arg_index);
                 break;
               default:
+                if (named_used_list != NULL)
+                    parrot_hash_destroy(interp, named_used_list);
                 Parrot_ex_throw_from_c_args(interp, NULL,
                     EXCEPTION_INVALID_OPERATION, "invalid parameter type");
                 break;
@@ -931,12 +945,15 @@
             if (param_flags & PARROT_ARG_NAME)
                 break;
 
-            if (err_check)
+            if (err_check){
+                if (named_used_list != NULL)
+                    parrot_hash_destroy(interp, named_used_list);
                 Parrot_ex_throw_from_c_args(interp, NULL,
                     EXCEPTION_INVALID_OPERATION,
                     "too few positional arguments: "
                     "%d passed, %d (or more) expected",
                     positional_args, param_index + 1);
+            }
         }
 
         /* Go on to next argument and parameter. */
@@ -950,22 +967,29 @@
         INTVAL  param_flags = raw_params[param_index];
 
         /* All remaining parameters must be named. */
-        if (!(param_flags & PARROT_ARG_NAME))
+        if (!(param_flags & PARROT_ARG_NAME)){
+            if (named_used_list != NULL)
+                parrot_hash_destroy(interp, named_used_list);
             Parrot_ex_throw_from_c_args(interp, NULL,
                 EXCEPTION_INVALID_OPERATION,
                 "named parameters must follow all positional parameters");
+        }
 
         if (arg_index < positional_args) {
             PMC *arg_sig;
 
             GETATTR_CallContext_arg_flags(interp, call_object, arg_sig);
 
+            if (named_used_list != NULL)
+                parrot_hash_destroy(interp, named_used_list);
+
             /* We've used up all the positional parameters, but have extra
              * positional args left over. */
-            if (VTABLE_get_integer_keyed_int(interp, arg_sig, arg_index) & PARROT_ARG_NAME)
+            if (VTABLE_get_integer_keyed_int(interp, arg_sig, arg_index) & PARROT_ARG_NAME){
                 Parrot_ex_throw_from_c_args(interp, NULL,
                     EXCEPTION_INVALID_OPERATION,
                     "named arguments must follow all positional arguments");
+            }
 
             Parrot_ex_throw_from_c_args(interp, NULL,
                 EXCEPTION_INVALID_OPERATION,
@@ -988,15 +1012,19 @@
                     STRING * const name = VTABLE_get_string_keyed_int(interp,
                             named_arg_list, named_arg_index);
 
-                    if ((PMC_IS_NULL(named_used_list))
-                    || !VTABLE_exists_keyed_str(interp, named_used_list, name)) {
+                    if ((named_used_list == NULL)
+                    || !parrot_hash_exists(interp, named_used_list, name)) {
+
                         VTABLE_set_pmc_keyed_str(interp, collect_named, name,
                                 VTABLE_get_pmc_keyed_str(interp, call_object, name));
+
                         /* Mark the name as used, cannot be filled again. */
-                        /* named_used_list only created if needed. */
-                        if (PMC_IS_NULL(named_used_list))
-                            named_used_list = Parrot_pmc_new(interp, enum_class_Hash);
-                        VTABLE_set_integer_keyed_str(interp, named_used_list, name, 1);
+                        if (named_used_list==NULL) /* Only created if needed. */
+                            named_used_list = parrot_create_hash(interp,
+                                    enum_type_INTVAL, Hash_key_type_STRING);
+
+                        parrot_hash_put(interp, named_used_list, name, (void *)1);
+
                         ++named_count;
                     }
                 }
@@ -1007,10 +1035,13 @@
         }
 
         /* Store the name. */
-        if (!(param_flags & PARROT_ARG_STRING))
+        if (!(param_flags & PARROT_ARG_STRING)){
+            if (named_used_list != NULL)
+                parrot_hash_destroy(interp, named_used_list);
             Parrot_ex_throw_from_c_args(interp, NULL,
                EXCEPTION_INVALID_OPERATION,
                "named parameters must have a name specified");
+        }
 
         param_name = PARROT_ARG_CONSTANT_ISSET(param_flags)
                    ?  accessor->string_constant(interp, arg_info, param_index)
@@ -1026,10 +1057,11 @@
             if (VTABLE_exists_keyed_str(interp, call_object, param_name)) {
 
                 /* Mark the name as used, cannot be filled again. */
-                /* named_used_list only created if needed. */
-                if (PMC_IS_NULL(named_used_list))
-                    named_used_list = Parrot_pmc_new(interp, enum_class_Hash);
-                VTABLE_set_integer_keyed_str(interp, named_used_list, param_name, 1);
+                if (named_used_list==NULL) /* Only created if needed. */
+                    named_used_list = parrot_create_hash(interp,
+                            enum_type_INTVAL, Hash_key_type_STRING);
+
+                parrot_hash_put(interp, named_used_list, param_name, (void *)1);
                 ++named_count;
 
                 /* Fill the named parameter. */
@@ -1051,6 +1083,8 @@
                         VTABLE_get_pmc_keyed_str(interp, call_object, param_name);
                     break;
                   default:
+                    if (named_used_list != NULL)
+                        parrot_hash_destroy(interp, named_used_list);
                     Parrot_ex_throw_from_c_args(interp, NULL,
                         EXCEPTION_INVALID_OPERATION, "invalid parameter type");
                     break;
@@ -1087,31 +1121,42 @@
             /* We don't have an argument for the parameter, and it's not
              * optional, so it's an error. */
             else {
-                if (err_check)
+                if (err_check){
+                    if (named_used_list != NULL)
+                        parrot_hash_destroy(interp, named_used_list);
                     Parrot_ex_throw_from_c_args(interp, NULL,
                         EXCEPTION_INVALID_OPERATION,
                         "too few named arguments: "
                         "no argument for required parameter '%S'", param_name);
+                }
             }
         }
 
         ++param_index;
     }
 
+
     /* Double check that all named arguments were assigned to parameters. */
     if (err_check) {
         PMC  *named_arg_list;
         Hash *h;
         /* Early exit to avoid vtable call */
         GETATTR_CallContext_hash(interp, call_object, h);
-        if (!h || !h->entries)
+        if (!h || !h->entries){
+            if (named_used_list != NULL)
+                parrot_hash_destroy(interp, named_used_list);
             return;
+        }
 
         named_arg_list = VTABLE_get_attr_str(interp, call_object, CONST_STRING(interp, "named"));
 
         if (!PMC_IS_NULL(named_arg_list)) {
             const INTVAL named_arg_count = VTABLE_elements(interp, named_arg_list);
-            if (PMC_IS_NULL(named_used_list))
+
+            if (named_used_list==NULL){
+                if (named_used_list != NULL)
+                    parrot_hash_destroy(interp, named_used_list);
+
                 return;
 
                 /* The 'return' above is a temporary hack to duplicate an old
@@ -1123,6 +1168,7 @@
                     "too many named arguments: %d passed, 0 used",
                     named_arg_count);
                  */
+            }
 
             if (named_arg_count > named_count) {
                 /* At this point we know we have named arguments that weren't
@@ -1136,7 +1182,9 @@
                     STRING * const name = VTABLE_get_string_keyed_int(interp,
                             named_arg_list, named_arg_index);
 
-                    if (!VTABLE_exists_keyed_str(interp, named_used_list, name)) {
+                    if (!parrot_hash_exists(interp, named_used_list, name)) {
+                        if (named_used_list != NULL)
+                            parrot_hash_destroy(interp, named_used_list);
                         Parrot_ex_throw_from_c_args(interp, NULL,
                                 EXCEPTION_INVALID_OPERATION,
                                 "too many named arguments: '%S' not used",
@@ -1146,6 +1194,8 @@
             }
         }
     }
+    if (named_used_list != NULL)
+        parrot_hash_destroy(interp, named_used_list);
 }
 
 

Modified: branches/gc_massacre/src/debug.c
==============================================================================
--- branches/gc_massacre/src/debug.c	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/debug.c	Sun Sep 19 08:27:37 2010	(r49153)
@@ -82,6 +82,12 @@
 static void debugger_cmdline(PARROT_INTERP)
         __attribute__nonnull__(1);
 
+static void display_breakpoint(
+    ARGIN(PDB_t *pdb),
+    ARGIN(const PDB_breakpoint_t *breakpoint))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 PARROT_OBSERVER
@@ -132,6 +138,9 @@
        PARROT_ASSERT_ARG(pdb))
 #define ASSERT_ARGS_debugger_cmdline __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_display_breakpoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(pdb) \
+    , PARROT_ASSERT_ARG(breakpoint))
 #define ASSERT_ARGS_GDB_P __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(s))
@@ -525,6 +534,7 @@
 
 DebuggerCmdList DebCmdList [] = {
     { "assign",      'a',  &cmd_assign },
+    { "blist",       '\0', &cmd_listbreakpoints },
     { "break",       '\0', &cmd_break },
     { "continue",    '\0', &cmd_continue },
     { "delete",      'd',  &cmd_delete },
@@ -1476,8 +1486,8 @@
 {
     ASSERT_ARGS(PDB_set_break)
     PDB_t            * const pdb      = interp->pdb;
-    PDB_breakpoint_t *newbreak;
-    PDB_breakpoint_t **lbreak;
+    PDB_breakpoint_t *newbreak,
+                     *oldbreak;
     PDB_line_t       *line = NULL;
     long              bp_id;
     opcode_t         *breakpos = NULL;
@@ -1558,32 +1568,31 @@
         newbreak->condition = PDB_cond(interp, command);
     }
 
-    /* Set the address where to stop */
+    /* Set the address where to stop and the line number. */
     newbreak->pc   = breakpos;
-
-    /* No next breakpoint */
-    newbreak->next = NULL;
+    newbreak->line = line->number;
 
     /* Don't skip (at least initially) */
     newbreak->skip = 0;
 
-    /* Add the breakpoint to the end of the list */
-    bp_id = 1;
-    lbreak = & pdb->breakpoint;
-    while (*lbreak) {
-        bp_id = (*lbreak)->id + 1;
-        lbreak = & (*lbreak)->next;
-    }
-    newbreak->prev = *lbreak;
-    *lbreak = newbreak;
-    newbreak->id = bp_id;
+    /* Add the breakpoint to the end of the list, dealing with the first
+       breakpoint as a special case. */
+
+    if (!pdb->breakpoint) {
+        newbreak->id = 1;
+        pdb->breakpoint = newbreak;
+    }
+    else {
+        for (oldbreak = pdb->breakpoint; oldbreak->next; oldbreak = oldbreak->next)
+            ;
+        newbreak->id = oldbreak->id + 1;
+        oldbreak->next = newbreak;
+        newbreak->prev = oldbreak;
+    }
 
     /* Show breakpoint position */
 
-    Parrot_io_eprintf(pdb->debugger, "Breakpoint %li at", newbreak->id);
-    if (line)
-        Parrot_io_eprintf(pdb->debugger, " line %li", line->number);
-    Parrot_io_eprintf(pdb->debugger, " pos %li\n", newbreak->pc - interp->code->base.data);
+    display_breakpoint(pdb, newbreak);
 }
 
 /*
@@ -1601,15 +1610,16 @@
 {
     ASSERT_ARGS(list_breakpoints)
 
-    PDB_breakpoint_t **lbreak;
-    for (lbreak = & pdb->breakpoint; *lbreak; lbreak = & (*lbreak)->next) {
-        PDB_breakpoint_t *br = *lbreak;
-        Parrot_io_eprintf(pdb->debugger, "Breakpoint %li at", br->id);
-        Parrot_io_eprintf(pdb->debugger, " pos %li", br->pc - pdb->debugee->code->base.data);
-        if (br->skip == -1)
-            Parrot_io_eprintf(pdb->debugger, " (disabled)");
-        Parrot_io_eprintf(pdb->debugger, "\n");
-    }
+    PDB_breakpoint_t *breakpoint;
+
+    if (pdb->breakpoint)
+        for (breakpoint = pdb->breakpoint;
+             breakpoint;
+             breakpoint = breakpoint->next)
+            display_breakpoint(pdb, breakpoint);
+
+    else
+        Parrot_io_eprintf(pdb->debugger, "No breakpoints set\n");
 }
 
 /*
@@ -1701,7 +1711,7 @@
             breakpoint = breakpoint->next;
 
         if (!breakpoint) {
-            Parrot_io_eprintf(interp->pdb->debugger, "No breakpoint number %ld", n);
+            Parrot_io_eprintf(interp->pdb->debugger, "No breakpoint [%ld]", n);
             return NULL;
         }
 
@@ -1735,16 +1745,17 @@
     PDB_breakpoint_t * const breakpoint = PDB_find_breakpoint(interp, command);
 
     /* if the breakpoint exists, disable it. */
-    if (breakpoint)
+    if (breakpoint) {
         breakpoint->skip = -1;
+        display_breakpoint(interp->pdb, breakpoint);
+    }
 }
 
 /*
 
 =item C<void PDB_enable_breakpoint(PARROT_INTERP, const char *command)>
 
-Reenable a disabled breakpoint; if the breakpoint was not disabled, has
-no effect.
+Reenable a disabled breakpoint.
 
 =cut
 
@@ -1756,9 +1767,19 @@
     ASSERT_ARGS(PDB_enable_breakpoint)
     PDB_breakpoint_t * const breakpoint = PDB_find_breakpoint(interp, command);
 
-    /* if the breakpoint exists, and it was disabled, enable it. */
-    if (breakpoint && breakpoint->skip == -1)
-        breakpoint->skip = 0;
+    /* If there is a breakpoint and it's disabled, re-enable it.
+       If it's not disabled, tell the user. */
+
+    if (breakpoint) {
+        if (breakpoint->skip < 0) {
+            breakpoint->skip = 0;
+            display_breakpoint(interp->pdb, breakpoint);
+        }
+        else
+            Parrot_io_eprintf(interp->pdb->debugger,
+                              "Breakpoint [%d] is not disabled",
+                              breakpoint->id);
+    }
 }
 
 /*
@@ -1775,17 +1796,13 @@
 PDB_delete_breakpoint(PARROT_INTERP, ARGIN(const char *command))
 {
     ASSERT_ARGS(PDB_delete_breakpoint)
+    PDB_t *pdb = interp->pdb;
     PDB_breakpoint_t * const breakpoint = PDB_find_breakpoint(interp, command);
     const PDB_line_t *line;
     long bp_id;
 
     if (breakpoint) {
-        if (!interp->pdb->file)
-            Parrot_ex_throw_from_c_args(interp, NULL, 0, "No file loaded");
-
-        line = interp->pdb->file->line;
-        while (line->opcode != breakpoint->pc)
-            line = line->next;
+        display_breakpoint(pdb, breakpoint);
 
         /* Delete the condition structure, if there is one */
         if (breakpoint->condition) {
@@ -1803,16 +1820,16 @@
         }
         else if (!breakpoint->prev && breakpoint->next) {
             breakpoint->next->prev  = NULL;
-            interp->pdb->breakpoint = breakpoint->next;
+            pdb->breakpoint = breakpoint->next;
         }
         else {
-            interp->pdb->breakpoint = NULL;
+            pdb->breakpoint = NULL;
         }
-        bp_id = breakpoint->id;
+
         /* Kill the breakpoint */
         mem_gc_free(interp, breakpoint);
 
-        Parrot_io_eprintf(interp->pdb->debugger, "Breakpoint %li deleted\n", bp_id);
+        Parrot_io_eprintf(pdb->debugger, "Deleted\n");
     }
 }
 
@@ -1891,7 +1908,7 @@
     /* Remove the RUNNING state */
     pdb->state &= ~PDB_RUNNING;
 
-    Parrot_io_eprintf(pdb->debugger, "Program exited.\n");
+    Parrot_io_eprintf(pdb->debugger, "[program exited]\n");
     return 1;
 }
 
@@ -2095,6 +2112,8 @@
 
         /* Add the STOPPED state and stop */
         pdb->state |= PDB_STOPPED;
+        Parrot_io_eprintf(pdb->debugger, "Stop at ");
+        display_breakpoint(pdb, breakpoint);
         return 1;
     }
 
@@ -2609,14 +2628,17 @@
         ADD_OP_VAR_PART(interp, interp->code, pc, n);
         pc += n;
 
-        /* Prepare for next line */
-        newline              = mem_gc_allocate_zeroed_typed(interp, PDB_line_t);
-        newline->label       = NULL;
-        newline->next        = NULL;
-        newline->number      = pline->number + 1;
-        pline->next          = newline;
-        pline                = newline;
-        pline->source_offset = pfile->size;
+        /* Prepare for next line unless there will be no next line. */
+
+        if (pc < code_end) {
+            newline              = mem_gc_allocate_zeroed_typed(interp, PDB_line_t);
+            newline->label       = NULL;
+            newline->next        = NULL;
+            newline->number      = pline->number + 1;
+            pline->next          = newline;
+            pline                = newline;
+            pline->source_offset = pfile->size;
+        }
     }
 
     /* Add labels to the lines they belong to */
@@ -2753,107 +2775,131 @@
 
 */
 
+#define DEBUG_SOURCE_BUFFER_CHUNK 1024
+
 PARROT_EXPORT
 void
 PDB_load_source(PARROT_INTERP, ARGIN(const char *command))
 {
     ASSERT_ARGS(PDB_load_source)
-    FILE          *file;
-    char           f[DEBUG_CMD_BUFFER_LENGTH + 1];
-    int            i, j, c;
-    PDB_file_t    *pfile;
-    PDB_line_t    *pline;
-    PDB_t         * const pdb = interp->pdb;
-    opcode_t      *pc         = interp->code->base.data;
 
-    unsigned long  size = 0;
+    PDB_t * const pdb = interp->pdb;
+    char file_spec[DEBUG_CMD_BUFFER_LENGTH+1];
+    FILE *file_desc;
+    PDB_file_t *dfile;
+    PDB_line_t *dline,
+               *prev_dline = NULL;
+    size_t buffer_size;
+    ptrdiff_t start_offset;
+    int line = 0;
+    opcode_t *PC = interp->code->base.data;
+    int ci, i, ch;
 
     TRACEDEB_MSG("PDB_load_source");
 
-    /* If there was a file already loaded or the bytecode was
-       disassembled, free it */
+    /* Free any previous source lines. */
+
     if (pdb->file) {
-        PDB_free_file(interp->pdb->debugee, interp->pdb->debugee->pdb->file);
-        interp->pdb->debugee->pdb->file = NULL;
+        PDB_free_file(pdb->debugee, pdb->debugee->pdb->file);
+        pdb->debugee->pdb->file = NULL;
     }
 
-    /* Get the name of the file */
-    for (j = 0; command[j] == ' '; ++j)
-        continue;
-    for (i = 0; command[j]; ++i, ++j)
-        f[i] = command[j];
+    /* Get the source file specification. */
 
-    f[i] = '\0';
+    for (ci = 0; command[ci] == ' '; ++ci) ;
+    for (i = 0; command[ci]; ++i, ++ci)
+        file_spec[i] = command[ci];
+    file_spec[i] = '\0';
 
-    /* open the file */
-    file = fopen(f, "r");
+    /* Open the file for reading. */
 
-    /* abort if fopen failed */
-    if (!file) {
-        Parrot_io_eprintf(pdb->debugger, "Unable to load '%s'\n", f);
+    file_desc = fopen(file_spec, "r");
+    if (!file_desc) {
+        Parrot_io_eprintf(pdb->debugger, "Cannot open '%s' for reading\n",
+                                         file_spec);
         return;
     }
 
-    pfile = mem_gc_allocate_zeroed_typed(interp, PDB_file_t);
-    pline = mem_gc_allocate_zeroed_typed(interp, PDB_line_t);
+    /* Allocate a file block and the source buffer. */
 
-    pfile->source = mem_gc_allocate_n_typed(interp, 1024, char);
-    pfile->line   = pline;
-    pline->number = 1;
+    dfile = mem_gc_allocate_zeroed_typed(interp, PDB_file_t);
+    dfile->source = mem_gc_allocate_n_typed(interp, DEBUG_SOURCE_BUFFER_CHUNK,
+                                                    char);
+    buffer_size = DEBUG_SOURCE_BUFFER_CHUNK;
 
-    PARROT_ASSERT(interp->code);
-    PARROT_ASSERT(interp->code->op_info_table);
-    PARROT_ASSERT(pc);
-
-    while ((c = fgetc(file)) != EOF) {
-        /* Grow it */
-        if (++size == 1024) {
-            pfile->source = mem_gc_realloc_n_typed(interp, pfile->source,
-                                            (size_t)pfile->size + 1024, char);
-            size = 0;
-        }
-        pfile->source[pfile->size] = (char)c;
-
-        ++pfile->size;
-
-        if (c == '\n') {
-            /* If the line has an opcode move to the next one,
-               otherwise leave it with NULL to skip it. */
-            PDB_line_t *newline = mem_gc_allocate_zeroed_typed(interp, PDB_line_t);
-
-            if (PDB_hasinstruction(pfile->source + pline->source_offset)) {
-                size_t n      = interp->code->op_info_table[*pc]->op_count;
-                pline->opcode = pc;
-                ADD_OP_VAR_PART(interp, interp->code, pc, n);
-                pc           += n;
+    /* Load the source lines. */
 
-                /* don't walk off the end of the program into neverland */
-                if (pc >= interp->code->base.data + interp->code->base.size)
-                    break;
+    do {
+
+        /* Load characters until a newline or EOF is found. If the source
+           buffer fills up, extend it. */
+
+        start_offset = dfile->size;
+        do {
+            ch = fgetc(file_desc);
+            if (ch == EOF)
+                break;
+            dfile->source[dfile->size] = (char)ch;
+            if (++dfile->size >= buffer_size) {
+                buffer_size += DEBUG_SOURCE_BUFFER_CHUNK;
+                dfile->source = mem_gc_realloc_n_typed(interp,
+                                                       dfile->source,
+                                                       buffer_size,
+                                                       char);
             }
+        } while (ch != '\n');
 
-            newline->number      = pline->number + 1;
-            pline->next          = newline;
-            pline                = newline;
-            pline->source_offset = pfile->size;
-            pline->opcode        = NULL;
-            pline->label         = NULL;
+        /* We're done at EOF unless the last line didn't end with a newline. */
+
+        if (ch == EOF && (dfile->size == 0 || dfile->source[dfile->size-1] == '\n'))
+            break;
+
+        if (ch == EOF) {
+            dfile->source[dfile->size++] = '\n';
+            Parrot_io_eprintf(pdb->debugger,
+                              "(Newline appended to last line of file)\n");
         }
-    }
 
-    fclose(file);
+        /* Allocate a line block and store information about the line.
+           Attempt to match the line with its opcode PC (does not work). */
 
-    pdb->state |= PDB_SRC_LOADED;
-    pdb->file   = pfile;
+        dline = mem_gc_allocate_zeroed_typed(interp, PDB_line_t);
+        dline->source_offset = start_offset;
+        dline->number        = ++line;
+        if (PDB_hasinstruction(dfile->source + start_offset)) {
+            if (PC < interp->code->base.data + interp->code->base.size) {
+                size_t n = interp->code->op_info_table[*PC]->op_count;
+                dline->opcode = PC;
+                ADD_OP_VAR_PART(interp, interp->code, PC, n);
+                PC += n;
+            }
+        }
+
+        /* Chain the line onto the file block or previous line. */
+
+        if (prev_dline)
+            prev_dline->next = dline;
+        else
+            dfile->line = dline;
+        prev_dline = dline;
 
-    TRACEDEB_MSG("PDB_load_source finished");
+    } while (ch != EOF);
+
+    /* Close the source file, mark the file loaded, and line the file
+       block onto the PDB structure. */
+
+    fclose(file_desc);
+
+    pdb->state |= PDB_SRC_LOADED;
+    pdb->file   = dfile;
 }
 
 /*
 
 =item C<char PDB_hasinstruction(const char *c)>
 
-Return true if the line has an instruction.
+Return true if the line has an instruction. This test does not provide
+the ability to match source lines with opcode PCs.
 
 =cut
 
@@ -2979,7 +3025,7 @@
 
 =item C<void PDB_list(PARROT_INTERP, const char *command)>
 
-Show lines from the source code file.
+Display lines from the source code file.
 
 =cut
 
@@ -2989,59 +3035,72 @@
 PDB_list(PARROT_INTERP, ARGIN(const char *command))
 {
     ASSERT_ARGS(PDB_list)
-    char          *c;
-    unsigned long  line_number;
-    unsigned long  i;
-    PDB_line_t    *line;
     PDB_t         *pdb = interp->pdb;
-    unsigned long  n   = 10;
+    unsigned long start_line;
+    unsigned long line_count;
+    PDB_line_t    *line;
+    unsigned long i;
+    char          *ch;
 
     TRACEDEB_MSG("PDB_list");
+
+    /* Make sure the source file has been loaded. Get the starting
+       line and the number of lines from the command. Quit if zero
+       lines requested. */
+
     if (!pdb->file || !pdb->file->line) {
         Parrot_io_eprintf(pdb->debugger, "No source file loaded\n");
         return;
     }
 
-    /* set the list line if provided */
-    line_number = get_ulong(&command, 0);
-    pdb->file->list_line = (unsigned long) line_number;
+    start_line = get_ulong(&command, 1);
+    pdb->file->list_line = (unsigned long) start_line;
 
-    /* set the number of lines to print */
-    n = get_ulong(&command, 10);
+    line_count = get_ulong(&command, 20);
 
-    /* if n is zero, we simply return, as we don't have to print anything */
-    if (n == 0)
+    if (line_count == 0) {
+        Parrot_io_eprintf(pdb->debugger, "Zero lines were requested");
         return;
+    }
 
-    line = pdb->file->line;
+    /* Run down the line list to the starting line. Quit if the
+       starting line number is too high. */
 
-    for (i = 0; i < pdb->file->list_line && line->next; ++i)
+    for (i = 1, line = pdb->file->line;
+         i < pdb->file->list_line && line->next;
+         ++i)
         line = line->next;
 
-    i = 1;
-    while (line->next) {
-        Parrot_io_eprintf(pdb->debugger, "%li  ", pdb->file->list_line + i);
-        /* If it has a label print it */
-        if (line->label)
-            Parrot_io_eprintf(pdb->debugger, "L%li:\t", line->label->number);
+    if (i < start_line) {
+        Parrot_io_eprintf(pdb->debugger, "Starting line %d not in file\n",
+                                         start_line);
+        return;
+    }
+
+    /* Run down the lines to be displayed. Include the PC, line number,
+       and line text. Quit if we run out of lines. */
+
+    for (i = 0; i < line_count; ++i) {
+        if (line->opcode)
+            Parrot_io_eprintf(pdb->debugger, "%04d  ",
+                              line->opcode - pdb->debugee->code->base.data);
+        else
+            Parrot_io_eprintf(pdb->debugger, "      ");
 
-        c = pdb->file->source + line->source_offset;
+        Parrot_io_eprintf(pdb->debugger, "%4li  ", line->number);
 
-        while (*c != '\n')
-            Parrot_io_eprintf(pdb->debugger, "%c", *(c++));
+        for (ch = pdb->file->source + line->source_offset; *ch != '\n'; ++ch)
+            Parrot_io_eprintf(pdb->debugger, "%c", *ch);
 
         Parrot_io_eprintf(pdb->debugger, "\n");
 
         line = line->next;
-
-        if (i++ == n)
-            break;
+        if (!line) break;
     }
 
-    if (--i != n)
-        pdb->file->list_line = 0;
-    else
-        pdb->file->list_line += n;
+    /* Let the user know if there are any more lines. */
+
+    Parrot_io_eprintf(pdb->debugger, (line) ? "[more]\n" : "[end]\n");
 }
 
 /*
@@ -3109,31 +3168,29 @@
     Parrot_Interp itdeb = interp->pdb ? interp->pdb->debugger : interp;
     Parrot_Interp itp = interp->pdb ? interp->pdb->debugee : interp;
 
-    Parrot_io_eprintf(itdeb, "Total memory allocated = %ld\n",
+    Parrot_io_eprintf(itdeb, "Total memory allocated: %ld\n",
             interpinfo(itp, TOTAL_MEM_ALLOC));
-    Parrot_io_eprintf(itdeb, "GC mark runs = %ld\n",
+    Parrot_io_eprintf(itdeb, "GC mark runs: %ld\n",
             interpinfo(itp, GC_MARK_RUNS));
-    Parrot_io_eprintf(itdeb, "Lazy gc mark runs = %ld\n",
+    Parrot_io_eprintf(itdeb, "Lazy gc mark runs: %ld\n",
             interpinfo(itp, GC_LAZY_MARK_RUNS));
-    Parrot_io_eprintf(itdeb, "GC collect runs = %ld\n",
+    Parrot_io_eprintf(itdeb, "GC collect runs: %ld\n",
             interpinfo(itp, GC_COLLECT_RUNS));
-    Parrot_io_eprintf(itdeb, "Collect memory = %ld\n",
+    Parrot_io_eprintf(itdeb, "Collect memory: %ld\n",
             interpinfo(itp, TOTAL_COPIED));
-    Parrot_io_eprintf(itdeb, "Active PMCs = %ld\n",
+    Parrot_io_eprintf(itdeb, "Active PMCs: %ld\n",
             interpinfo(itp, ACTIVE_PMCS));
-    Parrot_io_eprintf(itdeb, "Extended PMCs = %ld\n",
-            interpinfo(itp, EXTENDED_PMCS));
-    Parrot_io_eprintf(itdeb, "Timely GC PMCs = %ld\n",
+    Parrot_io_eprintf(itdeb, "Timely GC PMCs: %ld\n",
             interpinfo(itp, IMPATIENT_PMCS));
-    Parrot_io_eprintf(itdeb, "Total PMCs = %ld\n",
+    Parrot_io_eprintf(itdeb, "Total PMCs: %ld\n",
             interpinfo(itp, TOTAL_PMCS));
-    Parrot_io_eprintf(itdeb, "Active buffers = %ld\n",
+    Parrot_io_eprintf(itdeb, "Active buffers: %ld\n",
             interpinfo(itp, ACTIVE_BUFFERS));
-    Parrot_io_eprintf(itdeb, "Total buffers = %ld\n",
+    Parrot_io_eprintf(itdeb, "Total buffers: %ld\n",
             interpinfo(itp, TOTAL_BUFFERS));
-    Parrot_io_eprintf(itdeb, "Header allocations since last collect = %ld\n",
+    Parrot_io_eprintf(itdeb, "Header allocations since last collect: %ld\n",
             interpinfo(itp, HEADER_ALLOCS_SINCE_COLLECT));
-    Parrot_io_eprintf(itdeb, "Memory allocations since last collect = %ld\n",
+    Parrot_io_eprintf(itdeb, "Memory allocations since last collect: %ld\n",
             interpinfo(itp, MEM_ALLOCS_SINCE_COLLECT));
 }
 
@@ -3167,7 +3224,7 @@
             for (i= 0; i < sizeof (DebCmdList) / sizeof (DebuggerCmdList); ++i) {
                 const DebuggerCmdList *cmdlist = DebCmdList + i;
                 Parrot_io_eprintf(interp->pdb->debugger,
-                    "    %-12s-- %s\n", cmdlist->name, cmdlist->cmd->shorthelp);
+                    "   %-12s  %s\n", cmdlist->name, cmdlist->cmd->shorthelp);
             }
             Parrot_io_eprintf(interp->pdb->debugger, "\n"
 "Type \"help\" followed by a command name for full documentation.\n\n");
@@ -3422,6 +3479,37 @@
 
 /*
 
+=item C<static void display_breakpoint(PDB_t *pdb, const PDB_breakpoint_t
+*breakpoint)>
+
+Displays a breakpoint.
+
+=cut
+
+*/
+
+static void
+display_breakpoint(ARGIN(PDB_t *pdb), ARGIN(const PDB_breakpoint_t *breakpoint))
+{
+    ASSERT_ARGS(display_breakpoint)
+
+    /* Display the breakpoint id, PC, line number (if known),
+       and disabled flag. */
+
+    Parrot_io_eprintf(pdb->debugger,
+                      "[%d] breakpoint at PC %04d",
+                      breakpoint->id,
+                      breakpoint->pc - pdb->debugee->code->base.data);
+    if (breakpoint->line)
+        Parrot_io_eprintf(pdb->debugger, ", line %d", breakpoint->line);
+    if (breakpoint->skip < 0)
+        Parrot_io_eprintf(pdb->debugger, "  (DISABLED)");
+    Parrot_io_eprintf(pdb->debugger, "\n");
+}
+
+
+/*
+
 =back
 
 =head1 SEE ALSO
@@ -3453,7 +3541,6 @@
 
 */
 
-
 /*
  * Local variables:
  *   c-file-style: "parrot"

Modified: branches/gc_massacre/src/dynpmc/Rules.in
==============================================================================
--- branches/gc_massacre/src/dynpmc/Rules.in	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/dynpmc/Rules.in	Sun Sep 19 08:27:37 2010	(r49153)
@@ -78,8 +78,12 @@
 
 src/dynpmc/pmc_gziphandle.h : src/dynpmc/gziphandle.c
 
-src/dynpmc/gziphandle$(O): src/dynpmc/gziphandle.c $(DYNPMC_H_FILES) \
-    src/dynpmc/pmc_gziphandle.h include/pmc/pmc_fixedintegerarray.h
+src/dynpmc/gziphandle$(O): \
+    src/dynpmc/gziphandle.c \
+    $(DYNPMC_H_FILES) \
+    src/dynpmc/pmc_gziphandle.h \
+    include/pmc/pmc_handle.h \
+    include/pmc/pmc_fixedintegerarray.h
 
 src/dynpmc/gziphandle.c: src/dynpmc/gziphandle.dump
 	$(PMC2CC) src/dynpmc/gziphandle.pmc

Modified: branches/gc_massacre/src/gc/alloc_resources.c
==============================================================================
--- branches/gc_massacre/src/gc/alloc_resources.c	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/gc/alloc_resources.c	Sun Sep 19 08:27:37 2010	(r49153)
@@ -30,26 +30,16 @@
 #define RESOURCE_DEBUG 0
 #define RESOURCE_DEBUG_SIZE 1000000
 
-#define POOL_SIZE (65536 * 2)
-
-typedef void (*compact_f) (Interp *, Memory_Pools * const, Variable_Size_Pool *);
+typedef struct string_callback_data {
+    Memory_Block *new_block;     /* A pointer to our working block */
+    char         *cur_spot;      /* Where we're currently copying to */
+} string_callback_data;
 
 /* HEADERIZER HFILE: src/gc/gc_private.h */
 
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-static void alloc_new_block(
-     ARGMOD(Memory_Pools *mem_pools),
-    size_t size,
-    ARGMOD(Variable_Size_Pool *pool),
-    ARGIN(const char *why))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*mem_pools)
-        FUNC_MODIFIES(*pool);
-
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 static const char * buffer_location(PARROT_INTERP, ARGIN(const Buffer *b))
@@ -76,47 +66,7 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*dest_interp);
 
-static void free_memory_pool(ARGFREE(Variable_Size_Pool *pool));
-static void free_old_mem_blocks(
-     ARGMOD(Memory_Pools *mem_pools),
-    ARGMOD(Variable_Size_Pool *pool),
-    ARGMOD(Memory_Block *new_block),
-    UINTVAL total_size)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*mem_pools)
-        FUNC_MODIFIES(*pool)
-        FUNC_MODIFIES(*new_block);
-
 static void free_pool(ARGFREE(Fixed_Size_Pool *pool));
-static int is_block_almost_full(ARGIN(const Memory_Block *block))
-        __attribute__nonnull__(1);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static char * move_one_buffer(PARROT_INTERP,
-    ARGIN(Memory_Block *pool),
-    ARGMOD(Buffer *old_buf),
-    ARGMOD(char *new_pool_ptr))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*old_buf)
-        FUNC_MODIFIES(*new_pool_ptr);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_MALLOC
-PARROT_CANNOT_RETURN_NULL
-static Variable_Size_Pool * new_memory_pool(
-    size_t min_block,
-    NULLOK(compact_f compact));
-
-PARROT_CANNOT_RETURN_NULL
-static UINTVAL pad_pool_size(ARGIN(const Variable_Size_Pool *pool))
-        __attribute__nonnull__(1);
-
 static void Parrot_gc_merge_buffer_pools(PARROT_INTERP,
     ARGMOD(Memory_Pools *mem_pools),
     ARGMOD(Fixed_Size_Pool *dest),
@@ -148,10 +98,6 @@
         FUNC_MODIFIES(*mem_pools)
         FUNC_MODIFIES(*pool);
 
-#define ASSERT_ARGS_alloc_new_block __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(mem_pools) \
-    , PARROT_ASSERT_ARG(pool) \
-    , PARROT_ASSERT_ARG(why))
 #define ASSERT_ARGS_buffer_location __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(b))
@@ -167,22 +113,7 @@
 #define ASSERT_ARGS_fix_pmc_syncs __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(dest_interp) \
     , PARROT_ASSERT_ARG(pool))
-#define ASSERT_ARGS_free_memory_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
-#define ASSERT_ARGS_free_old_mem_blocks __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(mem_pools) \
-    , PARROT_ASSERT_ARG(pool) \
-    , PARROT_ASSERT_ARG(new_block))
 #define ASSERT_ARGS_free_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
-#define ASSERT_ARGS_is_block_almost_full __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(block))
-#define ASSERT_ARGS_move_one_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(pool) \
-    , PARROT_ASSERT_ARG(old_buf) \
-    , PARROT_ASSERT_ARG(new_pool_ptr))
-#define ASSERT_ARGS_new_memory_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
-#define ASSERT_ARGS_pad_pool_size __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(pool))
 #define ASSERT_ARGS_Parrot_gc_merge_buffer_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(mem_pools) \
@@ -201,165 +132,6 @@
 
 /*
 
-=item C<static void alloc_new_block( Memory_Pools *mem_pools, size_t size,
-Variable_Size_Pool *pool, const char *why)>
-
-Allocate a new memory block. We allocate either the requested size or the
-default size, whichever is larger. Add the new block to the given memory
-pool. The given C<char *why> text is used for debugging.
-
-=cut
-
-*/
-
-static void
-alloc_new_block(
-        ARGMOD(Memory_Pools *mem_pools),
-        size_t size,
-        ARGMOD(Variable_Size_Pool *pool),
-        ARGIN(const char *why))
-{
-    ASSERT_ARGS(alloc_new_block)
-    Memory_Block *new_block;
-
-    const size_t alloc_size = (size > pool->minimum_block_size)
-            ? size : pool->minimum_block_size;
-
-#if RESOURCE_DEBUG
-    fprintf(stderr, "new_block (%s) size %u -> %u\n",
-        why, size, alloc_size);
-#else
-    UNUSED(why)
-#endif
-
-    /* Allocate a new block. Header info's on the front */
-    new_block = (Memory_Block *)mem_internal_allocate_zeroed(
-        sizeof (Memory_Block) + alloc_size);
-
-    if (!new_block) {
-        fprintf(stderr, "out of mem allocsize = %d\n", (int)alloc_size);
-        exit(EXIT_FAILURE);
-    }
-
-    new_block->free  = alloc_size;
-    new_block->size  = alloc_size;
-
-    new_block->next  = NULL;
-    new_block->start = (char *)new_block + sizeof (Memory_Block);
-    new_block->top   = new_block->start;
-
-    /* Note that we've allocated it */
-    mem_pools->stats.memory_allocated += alloc_size;
-
-    /* If this is for a public pool, add it to the list */
-    new_block->prev = pool->top_block;
-
-    /* If we're not first, then tack us on the list */
-    if (pool->top_block)
-        pool->top_block->next = new_block;
-
-    pool->top_block        = new_block;
-    pool->total_allocated += alloc_size;
-}
-
-/*
-
-=item C<void * mem_allocate(PARROT_INTERP, Memory_Pools *mem_pools, size_t size,
-Variable_Size_Pool *pool)>
-
-Allocates memory for headers.
-
-Alignment problems history:
-
-See L<http://archive.develooper.com/perl6-internals%40perl.org/msg12310.html>
-for details.
-
-- return aligned pointer *if needed*
-- return strings et al at unaligned i.e. void* boundaries
-- remember alignment in a buffer header bit
-  use this in compaction code
-- reduce alignment to a reasonable value i.e. MALLOC_ALIGNMENT
-  aka 2*sizeof (size_t) or just 8 (TODO make a config hint)
-
-See pobj.h for a discussion of the Buffer descriptor and the buffer itself,
-including its header.
-
-=cut
-
-*/
-
-PARROT_MALLOC
-PARROT_CANNOT_RETURN_NULL
-void *
-mem_allocate(PARROT_INTERP,
-        ARGMOD(Memory_Pools *mem_pools),
-        size_t size,
-        ARGMOD(Variable_Size_Pool *pool))
-{
-    ASSERT_ARGS(mem_allocate)
-    void *return_val;
-
-    /* we always should have one block at least */
-    PARROT_ASSERT(pool->top_block);
-
-    /* If not enough room, try to find some */
-    if (pool->top_block->free < size) {
-        /*
-         * force a GC mark run to get live flags set
-         * for incremental M&S collection is run from there
-         * but only if there may be something worth collecting!
-         * TODO pass required allocation size to the GC system,
-         *      so that collection can be skipped if needed
-         */
-        size_t new_mem = mem_pools->stats.memory_used -
-                         mem_pools->stats.mem_used_last_collect;
-        if (!mem_pools->gc_mark_block_level
-            && new_mem > (mem_pools->stats.mem_used_last_collect >> 2)
-            && new_mem > GC_SIZE_THRESHOLD) {
-            Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);
-
-            if (interp->gc_sys->sys_type != INF) {
-                /* Compact the pool if allowed and worthwhile */
-                if (pool->compact) {
-                    /* don't bother reclaiming if it's only a small amount */
-                    if ((pool->possibly_reclaimable * pool->reclaim_factor +
-                         pool->guaranteed_reclaimable) > size) {
-                        (*pool->compact) (interp, mem_pools, pool);
-                    }
-                }
-            }
-        }
-        if (pool->top_block->free < size) {
-            if (pool->minimum_block_size < 65536 * 16)
-                pool->minimum_block_size *= 2;
-            /*
-             * TODO - Big blocks
-             *
-             * Mark the block as big block (it has just one item)
-             * And don't set big blocks as the top_block.
-             */
-            alloc_new_block(mem_pools, size, pool, "compact failed");
-
-            ++mem_pools->stats.mem_allocs_since_last_collect;
-
-            if (pool->top_block->free < size) {
-                fprintf(stderr, "out of mem\n");
-                exit(EXIT_FAILURE);
-            }
-        }
-    }
-
-    /* TODO inline the fast path */
-    return_val             = pool->top_block->top;
-    pool->top_block->top  += size;
-    pool->top_block->free -= size;
-    mem_pools->stats.memory_used += size;
-
-    return return_val;
-}
-
-/*
-
 =item C<static const char * buffer_location(PARROT_INTERP, const Buffer *b)>
 
 Recturns a constant string representing the location of the given
@@ -398,6 +170,7 @@
 =item C<static void debug_print_buf(PARROT_INTERP, const Buffer *b)>
 
 Prints a debug statement with information about the given PObj C<b>.
+
 =cut
 
 */
@@ -416,456 +189,10 @@
 
 =back
 
-=head2 Compaction Code
-
-=over 4
-
-=item C<void compact_pool(PARROT_INTERP, Memory_Pools *mem_pools,
-Variable_Size_Pool *pool)>
-
-Compact the string buffer pool. Does not perform a GC scan, or mark items
-as being alive in any way.
-
-=cut
-
-*/
-
-void
-compact_pool(PARROT_INTERP,
-        ARGMOD(Memory_Pools *mem_pools),
-        ARGMOD(Variable_Size_Pool *pool))
-{
-    ASSERT_ARGS(compact_pool)
-    INTVAL        j;
-    UINTVAL       total_size;
-
-    Memory_Block *new_block;     /* A pointer to our working block */
-    char         *cur_spot;      /* Where we're currently copying to */
-
-    Fixed_Size_Arena *cur_buffer_arena;
-
-    /* Bail if we're blocked */
-    if (mem_pools->gc_sweep_block_level)
-        return;
-
-    ++mem_pools->gc_sweep_block_level;
-
-    /* We're collecting */
-    mem_pools->stats.mem_allocs_since_last_collect    = 0;
-    mem_pools->stats.header_allocs_since_last_collect = 0;
-    ++mem_pools->stats.gc_collect_runs;
-
-    /* Snag a block big enough for everything */
-    total_size = pad_pool_size(pool);
-
-    if (total_size == 0) {
-        free_old_mem_blocks(mem_pools, pool, pool->top_block, total_size);
-        --mem_pools->gc_sweep_block_level;
-        return;
-    }
-
-    alloc_new_block(mem_pools, total_size, pool, "inside compact");
-
-    new_block = pool->top_block;
-
-    /* Start at the beginning */
-    cur_spot  = new_block->start;
-
-    /* Run through all the Buffer header pools and copy */
-    for (j = (INTVAL)mem_pools->num_sized - 1; j >= 0; --j) {
-        Fixed_Size_Pool * const header_pool = mem_pools->sized_header_pools[j];
-        UINTVAL       object_size;
-
-        if (!header_pool)
-            continue;
-
-        object_size = header_pool->object_size;
-
-        for (cur_buffer_arena = header_pool->last_Arena;
-                cur_buffer_arena;
-                cur_buffer_arena = cur_buffer_arena->prev) {
-            Buffer *b = (Buffer *) cur_buffer_arena->start_objects;
-            UINTVAL i;
-            const size_t objects_end = cur_buffer_arena->used;
-
-            for (i = objects_end; i; --i) {
-
-                if (Buffer_buflen(b) && PObj_is_movable_TESTALL(b)) {
-                    Memory_Block *old_block = Buffer_pool(b);
-
-                    if (!is_block_almost_full(old_block))
-                        cur_spot = move_one_buffer(interp, new_block, b, cur_spot);
-                }
-
-                b = (Buffer *)((char *)b + object_size);
-            }
-        }
-    }
-
-    /* Okay, we're done with the copy. Set the bits in the pool struct */
-    /* First, where we allocate next */
-    new_block->top = cur_spot;
-
-    PARROT_ASSERT(new_block->size >= (size_t)new_block->top -
-            (size_t)new_block->start);
-
-    /* How much is free. That's the total size minus the amount we used */
-    new_block->free = new_block->size - (cur_spot - new_block->start);
-    mem_pools->stats.memory_collected +=      (cur_spot - new_block->start);
-    mem_pools->stats.memory_used      +=      (cur_spot - new_block->start);
-
-    free_old_mem_blocks(mem_pools, pool, new_block, total_size);
-
-    --mem_pools->gc_sweep_block_level;
-}
-
-/*
-
-=item C<static UINTVAL pad_pool_size(const Variable_Size_Pool *pool)>
-
-Calculate the size of the new pool. The currently used size equals the total
-size minus the reclaimable size. Add a minimum block to the current amount, so
-we can avoid having to allocate it in the future.
-
-Returns 0 if all blocks below the top block are almost full. In this case
-compacting is not needed.
-
-TODO - Big blocks
-
-Currently all available blocks are compacted into one new
-block with total_size. This is suboptimal, if the block has
-just one live item from a big allocation.
-
-But currently it's unknown if the buffer memory is alive
-as the live bits are in Buffer headers. We have to run the
-compaction loop to check liveness. OTOH if this compaction
-is running through all the buffer headers, there is no
-relation to the block.
-
-Moving the live bit into the buffer thus also solves this
-problem easily.
-
-=cut
-
-*/
-
-PARROT_CANNOT_RETURN_NULL
-static UINTVAL
-pad_pool_size(ARGIN(const Variable_Size_Pool *pool))
-{
-    ASSERT_ARGS(pad_pool_size)
-    Memory_Block *cur_block = pool->top_block->prev;
-
-    UINTVAL total_size   = 0;
-#if RESOURCE_DEBUG
-    size_t  total_blocks = 1;
-#endif
-
-    while (cur_block) {
-        if (!is_block_almost_full(cur_block))
-            total_size += cur_block->size - cur_block->freed - cur_block->free;
-        cur_block   = cur_block->prev;
-#if RESOURCE_DEBUG
-        ++total_blocks;
-#endif
-    }
-
-    if (total_size == 0)
-        return 0;
-
-    cur_block = pool->top_block;
-    if (!is_block_almost_full(cur_block))
-        total_size += cur_block->size - cur_block->freed - cur_block->free;
-
-    /* this makes for ever increasing allocations but fewer collect runs */
-#if WE_WANT_EVER_GROWING_ALLOCATIONS
-    total_size += pool->minimum_block_size;
-#endif
-
-#if RESOURCE_DEBUG
-    fprintf(stderr, "Total blocks: %d\n", total_blocks);
-#endif
-
-    return total_size;
-}
-
-/*
-
-=item C<static char * move_one_buffer(PARROT_INTERP, Memory_Block *pool, Buffer
-*old_buf, char *new_pool_ptr)>
-
-The compact_pool operation collects disjointed blocks of memory allocated on a
-given pool's free list into one large block of memory. Once the new larger
-memory block has been allocated, this function moves one buffer from the old
-memory block to the new memory block and marks that it has been moved.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static char *
-move_one_buffer(PARROT_INTERP, ARGIN(Memory_Block *pool),
-        ARGMOD(Buffer *old_buf), ARGMOD(char *new_pool_ptr))
-{
-    ASSERT_ARGS(move_one_buffer)
-
-    INTVAL       *flags     = NULL;
-    ptrdiff_t     offset    = 0;
-    Memory_Block *old_block = NULL;
-#if RESOURCE_DEBUG
-    if (Buffer_buflen(old_buf) >= RESOURCE_DEBUG_SIZE)
-        debug_print_buf(interp, old_buf);
-#else
-    UNUSED(interp);
-#endif
-
-    /* we can't perform the math all the time, because
-        * strstart might be in unallocated memory */
-    if (PObj_is_COWable_TEST(old_buf)) {
-        flags = Buffer_bufflagsptr(old_buf);
-        old_block = Buffer_pool(old_buf);
-
-        if (PObj_is_string_TEST(old_buf)) {
-            offset = (ptrdiff_t)((STRING *)old_buf)->strstart -
-                (ptrdiff_t)Buffer_bufstart(old_buf);
-        }
-    }
-
-    /* buffer has already been moved; just change the header */
-    if (flags && (*flags & Buffer_shared_FLAG)
-              && (*flags & Buffer_moved_FLAG)) {
-        /* Find out who else references our data */
-        Buffer * const hdr = *((Buffer **)Buffer_bufstart(old_buf));
-
-        PARROT_ASSERT(PObj_is_COWable_TEST(old_buf));
-
-        /* Make sure they know that we own it too */
-        /* Set Buffer_shared_FLAG in new buffer */
-        *Buffer_bufflagsptr(hdr) |= Buffer_shared_FLAG;
-
-        /* Now make sure we point to where the other guy does */
-        Buffer_bufstart(old_buf) = Buffer_bufstart(hdr);
-
-        /* And if we're a string, update strstart */
-        /* Somewhat of a hack, but if we get per-pool
-            * collections, it should help ease the pain */
-        if (PObj_is_string_TEST(old_buf))
-            ((STRING *)old_buf)->strstart =
-                (char *)Buffer_bufstart(old_buf) + offset;
-    }
-    else {
-        new_pool_ptr = aligned_mem(old_buf, new_pool_ptr);
-
-        /* Copy our memory to the new pool */
-        memcpy(new_pool_ptr, Buffer_bufstart(old_buf),
-                                Buffer_buflen(old_buf));
-
-        /* If we're shared */
-        if (flags && (*flags & Buffer_shared_FLAG)) {
-            PARROT_ASSERT(PObj_is_COWable_TEST(old_buf));
-
-            /* Let the old buffer know how to find us */
-            *((Buffer **)Buffer_bufstart(old_buf)) = old_buf;
-
-            /* Finally, let the tail know that we've moved, so
-                * that any other references can know to look for
-                * us and not re-copy */
-            *flags |= Buffer_moved_FLAG;
-        }
-
-        Buffer_bufstart(old_buf) = new_pool_ptr;
-
-        /* Remember new pool inside */
-        *Buffer_poolptr(old_buf) = pool;
-
-        if (PObj_is_string_TEST(old_buf))
-            ((STRING *)old_buf)->strstart =
-                    (char *)Buffer_bufstart(old_buf) + offset;
-
-        new_pool_ptr += Buffer_buflen(old_buf);
-    }
-
-    return new_pool_ptr;
-}
-
-/*
-
-=item C<static void free_old_mem_blocks( Memory_Pools *mem_pools,
-Variable_Size_Pool *pool, Memory_Block *new_block, UINTVAL total_size)>
-
-The compact_pool operation collects disjointed blocks of memory allocated on a
-given pool's free list into one large block of memory, setting it as the new
-top block for the pool. Once that is done, and all items have been moved into
-the new block of memory, this function iterates through the old blocks and
-frees each one. It also performs the necessary housekeeping to record the
-freed memory blocks. At the end of this function, the pool will have only one
-block of memory on its free list.
-
-=cut
-
-*/
-
-static void
-free_old_mem_blocks(
-        ARGMOD(Memory_Pools *mem_pools),
-        ARGMOD(Variable_Size_Pool *pool),
-        ARGMOD(Memory_Block *new_block),
-        UINTVAL total_size)
-{
-    ASSERT_ARGS(free_old_mem_blocks)
-    Memory_Block *prev_block = new_block;
-    Memory_Block *cur_block  = new_block->prev;
-
-    PARROT_ASSERT(new_block == pool->top_block);
-
-    while (cur_block) {
-        Memory_Block * const next_block = cur_block->prev;
-
-        if (is_block_almost_full(cur_block)) {
-            /* Skip block */
-            prev_block = cur_block;
-            cur_block  = next_block;
-        }
-        else {
-            /* Note that we don't have it any more */
-            mem_pools->stats.memory_allocated -= cur_block->size;
-            mem_pools->stats.memory_used -= cur_block->size - cur_block->free;
-
-            /* We know the pool body and pool header are a single chunk, so
-             * this is enough to get rid of 'em both */
-            mem_internal_free(cur_block);
-            cur_block        = next_block;
-
-            /* Unlink it from list */
-            prev_block->prev = next_block;
-        }
-    }
-
-    /* Terminate list */
-    prev_block->prev = NULL;
-
-
-    /* ANR: I suspect this should be set to new_block->size, instead of passing
-     * in the raw value of total_size, because alloc_new_block pads the size of
-     * the new block under certain conditions. Leaving it unmodified for now,
-     * so this refactor has no functionality changes, only code cleanups.*/
-    pool->total_allocated        = total_size;
-    pool->guaranteed_reclaimable = 0;
-    pool->possibly_reclaimable   = 0;
-}
-
-/*
-
-=item C<static int is_block_almost_full(const Memory_Block *block)>
-
-Tests if the block is almost full and should be skipped during compacting.
-
-Returns true if less that 20% of block is available
-
-=cut
-
-*/
-
-static int
-is_block_almost_full(ARGIN(const Memory_Block *block))
-{
-    ASSERT_ARGS(is_block_almost_full)
-    return 5 * (block->free + block->freed) < block->size;
-}
-
-/*
-
-=item C<char * aligned_mem(const Buffer *buffer, char *mem)>
-
-Returns a pointer to the aligned allocated storage for Buffer C<buffer>,
-which might not be the same as the pointer to C<buffer> because of
-memory alignment.
-
-=cut
-
-*/
-
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-char *
-aligned_mem(SHIM(const Buffer *buffer), ARGIN(char *mem))
-{
-    ASSERT_ARGS(aligned_mem)
-    mem += sizeof (void *);
-    mem  = (char *)(((unsigned long)(mem + WORD_ALIGN_1)) & WORD_ALIGN_MASK);
-
-    return mem;
-}
-
-/*
-
-=back
-
 =head2 Parrot Re/Allocate Code
 
 =over 4
 
-=item C<static Variable_Size_Pool * new_memory_pool(size_t min_block, compact_f
-compact)>
-
-Allocate a new C<Variable_Size_Pool> structures, and set some initial values.
-return a pointer to the new pool.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_MALLOC
-PARROT_CANNOT_RETURN_NULL
-static Variable_Size_Pool *
-new_memory_pool(size_t min_block, NULLOK(compact_f compact))
-{
-    ASSERT_ARGS(new_memory_pool)
-    Variable_Size_Pool * const pool = mem_internal_allocate_typed(Variable_Size_Pool);
-
-    pool->top_block              = NULL;
-    pool->compact                = compact;
-    pool->minimum_block_size     = min_block;
-    pool->total_allocated        = 0;
-    pool->guaranteed_reclaimable = 0;
-    pool->possibly_reclaimable   = 0;
-    pool->reclaim_factor         = RECLAMATION_FACTOR;
-
-    return pool;
-}
-
-/*
-
-=item C<void initialize_var_size_pools(PARROT_INTERP, Memory_Pools *mem_pools)>
-
-Initialize the managed memory pools. Parrot maintains two C<Variable_Size_Pool>
-structures, the general memory pool and the constant string pool. Create
-and initialize both pool structures, and allocate initial blocks of memory
-for both.
-
-=cut
-
-*/
-
-void
-initialize_var_size_pools(SHIM_INTERP, ARGMOD(Memory_Pools *mem_pools))
-{
-    ASSERT_ARGS(initialize_var_size_pools)
-
-    mem_pools->memory_pool   = new_memory_pool(POOL_SIZE, &compact_pool);
-    alloc_new_block(mem_pools, POOL_SIZE, mem_pools->memory_pool, "init");
-
-    /* Constant strings - not compacted */
-    mem_pools->constant_string_pool = new_memory_pool(POOL_SIZE, NULL);
-    alloc_new_block(mem_pools, POOL_SIZE, mem_pools->constant_string_pool, "init");
-}
-
-
-/*
-
 =item C<void merge_pools(Variable_Size_Pool *dest, Variable_Size_Pool *source)>
 
 Merge two memory pools together. Do this by moving all memory blocks
@@ -925,8 +252,9 @@
     ASSERT_ARGS(check_memory_system)
     size_t i;
 
-    check_var_size_obj_pool(mem_pools->memory_pool);
-    check_var_size_obj_pool(mem_pools->constant_string_pool);
+    check_var_size_obj_pool(mem_pools->string_gc.memory_pool);
+    check_var_size_obj_pool(mem_pools->string_gc.constant_string_pool);
+
     check_fixed_size_obj_pool(mem_pools->pmc_pool);
     check_fixed_size_obj_pool(mem_pools->constant_pmc_pool);
     check_fixed_size_obj_pool(mem_pools->string_header_pool);
@@ -987,10 +315,6 @@
                     PARROT_ASSERT(PObj_on_free_list_TEST((PObj*)pobj_walker));
                 }
             }
-            else if (pool->mem_pool != NULL) {
-                /*then it means we are a buffer*/
-                check_buffer_ptr((Buffer*)object, pool->mem_pool);
-            }
             object = (PObj*)((char *)object + pool->object_size);
             PARROT_ASSERT(--count);
         }
@@ -1249,54 +573,6 @@
 }
 
 
-/*
-
-=item C<static void free_memory_pool(Variable_Size_Pool *pool)>
-
-Frees a memory pool; helper function for C<Parrot_gc_destroy_memory_pools>.
-
-=cut
-
-*/
-
-static void
-free_memory_pool(ARGFREE(Variable_Size_Pool *pool))
-{
-    ASSERT_ARGS(free_memory_pool)
-
-    Memory_Block *cur_block = pool->top_block;
-
-    while (cur_block) {
-        Memory_Block * const next_block = cur_block->prev;
-        mem_internal_free(cur_block);
-        cur_block = next_block;
-    }
-
-    mem_internal_free(pool);
-}
-
-
-/*
-
-=item C<void Parrot_gc_destroy_memory_pools(PARROT_INTERP, Memory_Pools
-*mem_pools)>
-
-Destroys the memory pool and the constant string pool. Loop through both
-pools and destroy all memory blocks contained in them. Once all the
-blocks are freed, free the pools themselves.
-
-=cut
-
-*/
-
-void
-Parrot_gc_destroy_memory_pools(SHIM_INTERP, ARGMOD(Memory_Pools *mem_pools))
-{
-    ASSERT_ARGS(Parrot_gc_destroy_memory_pools)
-
-    free_memory_pool(mem_pools->constant_string_pool);
-    free_memory_pool(mem_pools->memory_pool);
-}
 
 /*
 

Modified: branches/gc_massacre/src/gc/gc_ms.c
==============================================================================
--- branches/gc_massacre/src/gc/gc_ms.c	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/gc/gc_ms.c	Sun Sep 19 08:27:37 2010	(r49153)
@@ -62,13 +62,6 @@
         __attribute__nonnull__(3)
         FUNC_MODIFIES(*pool);
 
-static void gc_ms_allocate_buffer_storage(PARROT_INTERP,
-    ARGOUT(Buffer *buffer),
-    size_t size)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*buffer);
-
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 static Buffer * gc_ms_allocate_bufferlike_header(PARROT_INTERP, size_t size)
@@ -169,6 +162,11 @@
 static int gc_ms_is_string_ptr(PARROT_INTERP, ARGIN_NULLOK(void *ptr))
         __attribute__nonnull__(1);
 
+static void gc_ms_iterate_live_strings(PARROT_INTERP,
+    string_iterator_callback callback,
+    ARGIN_NULLOK(void *data))
+        __attribute__nonnull__(1);
+
 static void gc_ms_mark_and_sweep(PARROT_INTERP, UINTVAL flags)
         __attribute__nonnull__(1);
 
@@ -192,13 +190,6 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*pool);
 
-static void gc_ms_reallocate_buffer_storage(PARROT_INTERP,
-    ARGMOD(Buffer *buffer),
-    size_t newsize)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*buffer);
-
 PARROT_MALLOC
 PARROT_CANNOT_RETURN_NULL
 static void * gc_ms_reallocate_memory_chunk(SHIM_INTERP,
@@ -212,13 +203,6 @@
     size_t newsize,
     size_t oldsize);
 
-static void gc_ms_reallocate_string_storage(PARROT_INTERP,
-    ARGMOD(STRING *str),
-    size_t newsize)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*str);
-
 static int gc_ms_sweep_cb(PARROT_INTERP,
     ARGIN(Memory_Pools *mem_pools),
     ARGMOD(Fixed_Size_Pool *pool),
@@ -286,9 +270,6 @@
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(mem_pools) \
     , PARROT_ASSERT_ARG(pool))
-#define ASSERT_ARGS_gc_ms_allocate_buffer_storage __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(buffer))
 #define ASSERT_ARGS_gc_ms_allocate_bufferlike_header \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
@@ -342,6 +323,8 @@
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_gc_ms_is_string_ptr __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_gc_ms_iterate_live_strings __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_gc_ms_mark_and_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_gc_ms_mark_pobj_header __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -355,17 +338,9 @@
     , PARROT_ASSERT_ARG(pool))
 #define ASSERT_ARGS_gc_ms_pool_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(pool))
-#define ASSERT_ARGS_gc_ms_reallocate_buffer_storage \
-     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(buffer))
 #define ASSERT_ARGS_gc_ms_reallocate_memory_chunk __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 #define ASSERT_ARGS_gc_ms_reallocate_memory_chunk_zeroed \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
-#define ASSERT_ARGS_gc_ms_reallocate_string_storage \
-     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(str))
 #define ASSERT_ARGS_gc_ms_sweep_cb __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(mem_pools) \
@@ -450,10 +425,10 @@
     interp->gc_sys->allocate_pmc_attributes = gc_ms_allocate_pmc_attributes;
     interp->gc_sys->free_pmc_attributes     = gc_ms_free_pmc_attributes;
 
-    interp->gc_sys->allocate_string_storage = gc_ms_allocate_string_storage;
+    interp->gc_sys->allocate_string_storage   = gc_ms_allocate_string_storage;
     interp->gc_sys->reallocate_string_storage = gc_ms_reallocate_string_storage;
 
-    interp->gc_sys->allocate_buffer_storage = gc_ms_allocate_buffer_storage;
+    interp->gc_sys->allocate_buffer_storage   = gc_ms_allocate_buffer_storage;
     interp->gc_sys->reallocate_buffer_storage = gc_ms_reallocate_buffer_storage;
 
     interp->gc_sys->allocate_fixed_size_storage = gc_ms_allocate_fixed_size_storage;
@@ -478,10 +453,13 @@
 
     interp->gc_sys->get_gc_info      = gc_ms_get_gc_info;
 
+    interp->gc_sys->iterate_live_strings = gc_ms_iterate_live_strings;
+
     /* gc_private is @objects */
     interp->gc_sys->gc_private       = Parrot_list_new(interp);
 
-    initialize_var_size_pools(interp, interp->mem_pools);
+
+    Parrot_gc_str_initialize(interp, &interp->mem_pools->string_gc);
     initialize_fixed_size_pools(interp, interp->mem_pools);
     Parrot_gc_initialize_fixed_size_pools(interp, interp->mem_pools,
                                           GC_NUM_INITIAL_FIXED_SIZE_POOLS);
@@ -505,7 +483,7 @@
     Parrot_gc_destroy_header_pools(interp, interp->mem_pools);
 
     /* memory pools in resources */
-    Parrot_gc_destroy_memory_pools(interp, interp->mem_pools);
+    Parrot_gc_str_finalize(interp, &interp->mem_pools->string_gc);
 
     /* mem subsystem is dead now */
     mem_internal_free(interp->mem_pools);
@@ -624,7 +602,54 @@
 gc_ms_compact_memory_pool(PARROT_INTERP)
 {
     ASSERT_ARGS(gc_ms_compact_memory_pool)
-    compact_pool(interp, interp->mem_pools, interp->mem_pools->memory_pool);
+    Parrot_gc_str_compact_pool(interp, &interp->mem_pools->string_gc);
+}
+
+/*
+
+=item C<void gc_ms_allocate_string_storage(PARROT_INTERP, STRING *str, size_t
+size)>
+
+=item C<void gc_ms_reallocate_string_storage(PARROT_INTERP, STRING *str, size_t
+size)>
+
+=item C<void gc_ms_allocate_buffer_storage(PARROT_INTERP, Buffer *str, size_t
+size)>
+
+=item C<void gc_ms_reallocate_buffer_storage(PARROT_INTERP, Buffer *str, size_t
+size)>
+
+Functions for allocating strings/buffers storage.
+
+=cut
+*/
+
+void
+gc_ms_allocate_string_storage(PARROT_INTERP, ARGIN(STRING *str), size_t size)
+{
+    ASSERT_ARGS(gc_ms_allocate_string_storage)
+    Parrot_gc_str_allocate_string_storage(interp, &interp->mem_pools->string_gc, str, size);
+}
+
+void
+gc_ms_reallocate_string_storage(PARROT_INTERP, ARGIN(STRING *str), size_t size)
+{
+    ASSERT_ARGS(gc_ms_reallocate_string_storage)
+    Parrot_gc_str_reallocate_string_storage(interp, &interp->mem_pools->string_gc, str, size);
+}
+
+void
+gc_ms_allocate_buffer_storage(PARROT_INTERP, ARGIN(Buffer *str), size_t size)
+{
+    ASSERT_ARGS(gc_ms_allocate_buffer_storage)
+    Parrot_gc_str_allocate_buffer_storage(interp, &interp->mem_pools->string_gc, str, size);
+}
+
+void
+gc_ms_reallocate_buffer_storage(PARROT_INTERP, ARGIN(Buffer *str), size_t size)
+{
+    ASSERT_ARGS(gc_ms_reallocate_buffer_storage)
+    Parrot_gc_str_reallocate_buffer_storage(interp, &interp->mem_pools->string_gc, str, size);
 }
 
 /*
@@ -1201,233 +1226,6 @@
 
 /*
 
-=item C<static void gc_ms_allocate_buffer_storage(PARROT_INTERP, Buffer *buffer,
-size_t size)>
-
-Allocates a chunk of memory of at least size C<size> for the given Buffer.
-buffer is guaranteed to be properly aligned for things like C<FLOATVALS>,
-so the size may be rounded up or down to guarantee that this alignment holds.
-
-=cut
-
-*/
-
-static void
-gc_ms_allocate_buffer_storage(PARROT_INTERP,
-    ARGOUT(Buffer *buffer), size_t size)
-{
-    ASSERT_ARGS(gc_ms_allocate_buffer_storage)
-    const size_t new_size   = ALIGNED_STRING_SIZE(size);
-
-    Buffer_bufstart(buffer) = (void *)aligned_mem(buffer,
-        (char *)mem_allocate(interp,
-        interp->mem_pools, new_size, interp->mem_pools->memory_pool));
-
-    /* Save pool used to allocate into buffer header */
-    *Buffer_poolptr(buffer) = interp->mem_pools->memory_pool->top_block;
-
-    Buffer_buflen(buffer)   = new_size - sizeof (void *);
-}
-
-/*
-
-=item C<static void gc_ms_reallocate_buffer_storage(PARROT_INTERP, Buffer
-*buffer, size_t newsize)>
-
-Reallocate the Buffer's buffer memory to the given size. The
-allocated buffer will not shrink. If the buffer was allocated with
-L<Parrot_allocate_aligned> the new buffer will also be aligned. As with
-all reallocation, the new buffer might have moved and the additional
-memory is not cleared.
-
-=cut
-
-*/
-
-static void
-gc_ms_reallocate_buffer_storage(PARROT_INTERP, ARGMOD(Buffer *buffer),
-    size_t newsize)
-{
-    ASSERT_ARGS(gc_ms_reallocate_buffer_storage)
-    size_t copysize;
-    char  *mem;
-    Variable_Size_Pool * const pool = interp->mem_pools->memory_pool;
-    size_t new_size, needed, old_size;
-
-    /* we don't shrink buffers */
-    if (newsize <= Buffer_buflen(buffer))
-        return;
-
-    /*
-     * same as below but barely used and tested - only 3 list related
-     * tests do use true reallocation
-     *
-     * list.c, which does _reallocate, has 2 reallocations
-     * normally, which play ping pong with buffers.
-     * The normal case is therefore always to allocate a new block
-     */
-    new_size = ALIGNED_STRING_SIZE(newsize);
-    old_size = ALIGNED_STRING_SIZE(Buffer_buflen(buffer));
-    needed   = new_size - old_size;
-
-    if ((pool->top_block->free >= needed)
-    &&  (pool->top_block->top  == (char *)Buffer_bufstart(buffer) + old_size)) {
-        pool->top_block->free -= needed;
-        pool->top_block->top  += needed;
-        interp->mem_pools->stats.memory_used += needed;
-        Buffer_buflen(buffer)  = newsize;
-        return;
-    }
-
-    copysize = Buffer_buflen(buffer);
-
-    mem = (char *)mem_allocate(interp, interp->mem_pools, new_size, pool);
-    mem = aligned_mem(buffer, mem);
-
-    /* We shouldn't ever have a 0 from size, but we do. If we can track down
-     * those bugs, this can be removed which would make things cheaper */
-    if (copysize)
-        memcpy(mem, Buffer_bufstart(buffer), copysize);
-
-    Buffer_bufstart(buffer) = mem;
-
-    new_size -= sizeof (void *);
-
-    Buffer_buflen(buffer) = new_size;
-
-    /* Save pool used to allocate into buffer header */
-    *Buffer_poolptr(buffer) = interp->mem_pools->memory_pool->top_block;
-}
-
-/*
-
-=item C<void gc_ms_allocate_string_storage(PARROT_INTERP, STRING *str, size_t
-size)>
-
-Allocate the STRING's buffer memory to the given size. The allocated
-buffer maybe slightly bigger than the given C<size>. This function
-sets also C<< str->strstart >> to the new buffer location, C<< str->bufused >>
-is B<not> changed.
-
-=cut
-
-*/
-
-void
-gc_ms_allocate_string_storage(PARROT_INTERP, ARGOUT(STRING *str),
-    size_t size)
-{
-    ASSERT_ARGS(gc_ms_allocate_string_storage)
-    size_t       new_size;
-    Variable_Size_Pool *pool;
-    char        *mem;
-
-    Buffer_buflen(str)   = 0;
-    Buffer_bufstart(str) = NULL;
-
-    if (size == 0)
-        return;
-
-    pool     = PObj_constant_TEST(str)
-                ? interp->mem_pools->constant_string_pool
-                : interp->mem_pools->memory_pool;
-
-    new_size = ALIGNED_STRING_SIZE(size);
-    mem      = (char *)mem_allocate(interp, interp->mem_pools, new_size, pool);
-    mem     += sizeof (void *);
-
-    Buffer_bufstart(str) = str->strstart = mem;
-    Buffer_buflen(str)   = new_size - sizeof (void *);
-
-    /* Save pool used to allocate into buffer header */
-    *Buffer_poolptr(str) = pool->top_block;
-}
-
-/*
-
-=item C<static void gc_ms_reallocate_string_storage(PARROT_INTERP, STRING *str,
-size_t newsize)>
-
-Reallocate the STRING's buffer memory to the given size. The allocated
-buffer will not shrink. This function sets also C<str-E<gt>strstart> to the
-new buffer location, C<str-E<gt>bufused> is B<not> changed.
-
-=cut
-
-*/
-
-static void
-gc_ms_reallocate_string_storage(PARROT_INTERP, ARGMOD(STRING *str),
-    size_t newsize)
-{
-    ASSERT_ARGS(gc_ms_reallocate_string_storage)
-    size_t copysize;
-    char *mem, *oldmem;
-    size_t new_size, needed, old_size;
-
-    Variable_Size_Pool * const pool =
-        PObj_constant_TEST(str)
-            ? interp->mem_pools->constant_string_pool
-            : interp->mem_pools->memory_pool;
-
-    /* if the requested size is smaller then buflen, we are done */
-    if (newsize <= Buffer_buflen(str))
-        return;
-
-    /*
-     * first check, if we can reallocate:
-     * - if the passed strings buffer is the last string in the pool and
-     * - if there is enough size, we can just move the pool's top pointer
-     */
-    new_size = ALIGNED_STRING_SIZE(newsize);
-    old_size = ALIGNED_STRING_SIZE(Buffer_buflen(str));
-    needed   = new_size - old_size;
-
-    if (pool->top_block->free >= needed
-    &&  pool->top_block->top  == (char *)Buffer_bufstart(str) + old_size) {
-        pool->top_block->free -= needed;
-        pool->top_block->top  += needed;
-        interp->mem_pools->stats.memory_used += needed;
-        Buffer_buflen(str) = new_size - sizeof (void *);
-        return;
-    }
-
-    PARROT_ASSERT(str->bufused <= newsize);
-
-    /* only copy used memory, not total string buffer */
-    copysize = str->bufused;
-
-    mem = (char *)mem_allocate(interp, interp->mem_pools, new_size, pool);
-    mem += sizeof (void *);
-
-    /* Update Memory_Block usage */
-    /* We must not reallocate non-movable buffers! */
-    PARROT_ASSERT(PObj_is_movable_TESTALL(str));
-
-    /* We must not reallocate shared buffers! */
-    PARROT_ASSERT(!(*Buffer_bufflagsptr(str) & Buffer_shared_FLAG));
-
-    /* Decrease usage */
-    PARROT_ASSERT(Buffer_pool(str));
-    Buffer_pool(str)->freed += old_size;
-
-    /* copy mem from strstart, *not* bufstart */
-    oldmem             = str->strstart;
-    Buffer_bufstart(str) = (void *)mem;
-    str->strstart      = mem;
-    Buffer_buflen(str)   = new_size - sizeof (void *);
-
-    /* We shouldn't ever have a 0 from size, but we do. If we can track down
-     * those bugs, this can be removed which would make things cheaper */
-    if (copysize)
-        memcpy(mem, oldmem, copysize);
-
-    /* Save pool used to allocate into buffer header */
-    *Buffer_poolptr(str) = pool->top_block;
-}
-
-/*
-
 =item C<void * gc_ms_allocate_fixed_size_storage(PARROT_INTERP, size_t size)>
 
 Allocates a fixed-size chunk of memory for use. This memory is not manually
@@ -2029,6 +1827,56 @@
 }
 
 /*
+=item C<static void gc_ms_iterate_live_strings(PARROT_INTERP,
+string_iterator_callback callback, void *data)>
+
+Iterate over live string invoking callback for each of them. Used during
+compacting of string pool.
+
+=cut
+*/
+static void
+gc_ms_iterate_live_strings(PARROT_INTERP,
+        string_iterator_callback callback,
+        ARGIN_NULLOK(void *data))
+{
+    ASSERT_ARGS(gc_ms_iterate_live_strings)
+
+    Memory_Pools * const mem_pools = interp->mem_pools;
+    INTVAL j;
+
+    /* Run through all the Buffer header pools and invoke callback */
+    for (j = (INTVAL)mem_pools->num_sized - 1; j >= 0; --j) {
+        Fixed_Size_Pool  * const header_pool = mem_pools->sized_header_pools[j];
+        Fixed_Size_Arena       * cur_buffer_arena;
+        UINTVAL       object_size;
+
+        if (!header_pool)
+            continue;
+
+        object_size = header_pool->object_size;
+
+        for (cur_buffer_arena = header_pool->last_Arena;
+                cur_buffer_arena;
+                cur_buffer_arena = cur_buffer_arena->prev) {
+            Buffer *b = (Buffer *) cur_buffer_arena->start_objects;
+            UINTVAL i;
+            const size_t objects_end = cur_buffer_arena->used;
+
+            for (i = objects_end; i; --i) {
+                if (Buffer_buflen(b) && PObj_is_movable_TESTALL(b)) {
+                    Memory_Block *old_block = Buffer_pool(b);
+                    if (5 * (old_block->free + old_block->freed) >= old_block->size)
+                        callback(interp, b, data);
+                }
+                b = (Buffer *)((char *)b + object_size);
+            }
+        }
+    }
+}
+
+
+/*
 
 =back
 

Modified: branches/gc_massacre/src/gc/gc_ms2.c
==============================================================================
--- branches/gc_massacre/src/gc/gc_ms2.c	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/gc/gc_ms2.c	Sun Sep 19 08:27:37 2010	(r49153)
@@ -60,9 +60,10 @@
 PARROT_DOES_NOT_RETURN
 static void failed_allocation(unsigned int line, unsigned long size);
 
-static void gc_ms2_allocate_buffer_storage(SHIM_INTERP,
+static void gc_ms2_allocate_buffer_storage(PARROT_INTERP,
     ARGMOD(Buffer *buffer),
     size_t size)
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*buffer);
 
@@ -101,9 +102,10 @@
     SHIM(UINTVAL flags))
         __attribute__nonnull__(1);
 
-static void gc_ms2_allocate_string_storage(SHIM_INTERP,
+static void gc_ms2_allocate_string_storage(PARROT_INTERP,
     ARGMOD(STRING *str),
     size_t size)
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*str);
 
@@ -189,9 +191,10 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*pmc);
 
-static void gc_ms2_reallocate_buffer_storage(SHIM_INTERP,
+static void gc_ms2_reallocate_buffer_storage(PARROT_INTERP,
     ARGMOD(Buffer *buffer),
     size_t size)
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*buffer);
 
@@ -208,9 +211,10 @@
     size_t newsize,
     size_t oldsize);
 
-static void gc_ms2_reallocate_string_storage(SHIM_INTERP,
+static void gc_ms2_reallocate_string_storage(PARROT_INTERP,
     ARGMOD(STRING *str),
     size_t size)
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*str);
 
@@ -240,7 +244,8 @@
 #define ASSERT_ARGS_failed_allocation __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 #define ASSERT_ARGS_gc_ms2_allocate_buffer_storage \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(buffer))
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(buffer))
 #define ASSERT_ARGS_gc_ms2_allocate_bufferlike_header \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 #define ASSERT_ARGS_gc_ms2_allocate_fixed_size_storage \
@@ -259,7 +264,8 @@
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_gc_ms2_allocate_string_storage \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(str))
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(str))
 #define ASSERT_ARGS_gc_ms2_block_GC_mark __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_gc_ms2_block_GC_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -314,14 +320,16 @@
     , PARROT_ASSERT_ARG(pmc))
 #define ASSERT_ARGS_gc_ms2_reallocate_buffer_storage \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(buffer))
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(buffer))
 #define ASSERT_ARGS_gc_ms2_reallocate_memory_chunk \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 #define ASSERT_ARGS_gc_ms2_reallocate_memory_chunk_zeroed \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 #define ASSERT_ARGS_gc_ms2_reallocate_string_storage \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(str))
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(str))
 #define ASSERT_ARGS_gc_ms2_sweep_pmc_cb __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(obj))

Modified: branches/gc_massacre/src/gc/gc_private.h
==============================================================================
--- branches/gc_massacre/src/gc/gc_private.h	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/gc/gc_private.h	Sun Sep 19 08:27:37 2010	(r49153)
@@ -94,6 +94,9 @@
     GC_NEVER_SKIP       /* unused */
 } gc_skip_type_enum;
 
+/* Callback for live string. Use Buffer for now... */
+typedef void (*string_iterator_callback)(PARROT_INTERP, Buffer *str, void *data);
+
 typedef struct GC_Subsystem {
     /* Which GC subsystem are we using? See PARROT_GC_DEFAULT_TYPE in
      * include/parrot/settings.h for possible values */
@@ -156,15 +159,19 @@
     /* Return by value to simplify memory management */
     size_t (*get_gc_info)(PARROT_INTERP, Interpinfo_enum);
 
+    /* Iterate over _live_ strings. Used for string pool compacting */
+    void (*iterate_live_strings)(PARROT_INTERP, string_iterator_callback callback, void *data);
+
     /*Function hooks that GC systems can CHOOSE to provide if they need them
      *These will be called via the GC API functions Parrot_gc_func_name
      *e.g. read barrier && write barrier hooks can go here later ...*/
 
     /* Holds system-specific data structures */
     void * gc_private;
-
 } GC_Subsystem;
 
+
+
 /* This header structure describes an arena: a block of memory that is part of a
    fixed-sized pool. The arena has enough memory for 'total_objects' objects
    of a particular size specified in the pool. */
@@ -214,9 +221,6 @@
    hang off the Memory_Pools root structure. */
 
 typedef struct Fixed_Size_Pool {
-
-    struct Variable_Size_Pool *mem_pool; /* Pointer to associated variable-size
-                                            pool, or NULL. */
     size_t object_size;                 /* Size in bytes of an individual pool
                                            object. This size may include
                                            a GC system-specific GC header. */
@@ -259,6 +263,13 @@
 
 } Fixed_Size_Pool;
 
+/* String GC subsystem data */
+typedef struct String_GC {
+    Variable_Size_Pool  *memory_pool;           /* General memory pool. */
+    Variable_Size_Pool  *constant_string_pool;  /* Constant string pool (not
+                                                   compacted */
+} String_GC;
+
 /** statistics for GC **/
 typedef struct GC_Statistics {
     size_t  gc_mark_runs;       /* Number of times we've done a mark run */
@@ -292,8 +303,8 @@
 } GC_Statistics;
 
 typedef struct Memory_Pools {
-    Variable_Size_Pool  *memory_pool;
-    Variable_Size_Pool  *constant_string_pool;
+    String_GC            string_gc;
+
     Fixed_Size_Pool     *string_header_pool;
     Fixed_Size_Pool     *pmc_pool;
     Fixed_Size_Pool     *constant_pmc_pool;
@@ -325,6 +336,7 @@
     void *gc_private;             /* GC subsystem data */
 } Memory_Pools;
 
+
 /* HEADERIZER BEGIN: src/gc/system.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
@@ -466,11 +478,6 @@
 /* HEADERIZER BEGIN: src/gc/alloc_resources.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-char * aligned_mem(SHIM(const Buffer *buffer), ARGIN(char *mem))
-        __attribute__nonnull__(2);
-
 void check_buffer_ptr(
     ARGMOD(Buffer * pobj),
     ARGMOD(Variable_Size_Pool * pool))
@@ -479,31 +486,6 @@
         FUNC_MODIFIES(* pobj)
         FUNC_MODIFIES(* pool);
 
-void compact_pool(PARROT_INTERP,
-    ARGMOD(Memory_Pools *mem_pools),
-    ARGMOD(Variable_Size_Pool *pool))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*mem_pools)
-        FUNC_MODIFIES(*pool);
-
-void initialize_var_size_pools(SHIM_INTERP, ARGMOD(Memory_Pools *mem_pools))
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*mem_pools);
-
-PARROT_MALLOC
-PARROT_CANNOT_RETURN_NULL
-void * mem_allocate(PARROT_INTERP,
-    ARGMOD(Memory_Pools *mem_pools),
-    size_t size,
-    ARGMOD(Variable_Size_Pool *pool))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*mem_pools)
-        FUNC_MODIFIES(*pool);
-
 void merge_pools(
     ARGMOD(Variable_Size_Pool *dest),
     ARGMOD(Variable_Size_Pool *source))
@@ -518,11 +500,6 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*mem_pools);
 
-void Parrot_gc_destroy_memory_pools(SHIM_INTERP,
-    ARGMOD(Memory_Pools *mem_pools))
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*mem_pools);
-
 void Parrot_gc_merge_memory_pools(
     ARGMOD(Interp *dest_interp),
     ARGMOD(Memory_Pools *dest_arena),
@@ -533,21 +510,9 @@
         FUNC_MODIFIES(*dest_interp)
         FUNC_MODIFIES(*dest_arena);
 
-#define ASSERT_ARGS_aligned_mem __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(mem))
 #define ASSERT_ARGS_check_buffer_ptr __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(pobj) \
     , PARROT_ASSERT_ARG(pool))
-#define ASSERT_ARGS_compact_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(mem_pools) \
-    , PARROT_ASSERT_ARG(pool))
-#define ASSERT_ARGS_initialize_var_size_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(mem_pools))
-#define ASSERT_ARGS_mem_allocate __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(mem_pools) \
-    , PARROT_ASSERT_ARG(pool))
 #define ASSERT_ARGS_merge_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(dest) \
     , PARROT_ASSERT_ARG(source))
@@ -555,9 +520,6 @@
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(mem_pools))
-#define ASSERT_ARGS_Parrot_gc_destroy_memory_pools \
-     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(mem_pools))
 #define ASSERT_ARGS_Parrot_gc_merge_memory_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(dest_interp) \
     , PARROT_ASSERT_ARG(dest_arena) \
@@ -569,16 +531,21 @@
 /* HEADERIZER BEGIN: src/gc/gc_ms.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
+void gc_ms_allocate_buffer_storage(PARROT_INTERP,
+    ARGIN(Buffer *str),
+    size_t size)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
 PARROT_CANNOT_RETURN_NULL
 void * gc_ms_allocate_fixed_size_storage(PARROT_INTERP, size_t size)
         __attribute__nonnull__(1);
 
 void gc_ms_allocate_string_storage(PARROT_INTERP,
-    ARGOUT(STRING *str),
+    ARGIN(STRING *str),
     size_t size)
         __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*str);
+        __attribute__nonnull__(2);
 
 void gc_ms_compact_memory_pool(PARROT_INTERP)
         __attribute__nonnull__(1);
@@ -604,6 +571,18 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*pmc);
 
+void gc_ms_reallocate_buffer_storage(PARROT_INTERP,
+    ARGIN(Buffer *str),
+    size_t size)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+void gc_ms_reallocate_string_storage(PARROT_INTERP,
+    ARGIN(STRING *str),
+    size_t size)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
 size_t Parrot_gc_get_info(PARROT_INTERP,
     Interpinfo_enum which,
     ARGIN(GC_Statistics *stats))
@@ -613,6 +592,9 @@
 void Parrot_gc_ms_init(PARROT_INTERP)
         __attribute__nonnull__(1);
 
+#define ASSERT_ARGS_gc_ms_allocate_buffer_storage __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(str))
 #define ASSERT_ARGS_gc_ms_allocate_fixed_size_storage \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
@@ -633,6 +615,14 @@
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(pmc))
+#define ASSERT_ARGS_gc_ms_reallocate_buffer_storage \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(str))
+#define ASSERT_ARGS_gc_ms_reallocate_string_storage \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(str))
 #define ASSERT_ARGS_Parrot_gc_get_info __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(stats))
@@ -675,6 +665,100 @@
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: src/gc/gc_ms2.c */
 
+/* HEADERIZER BEGIN: src/gc/string_gc.c */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+
+void Parrot_gc_str_allocate_buffer_storage(PARROT_INTERP,
+    ARGIN(String_GC *gc),
+    ARGOUT(Buffer *buffer),
+    size_t size)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*buffer);
+
+void Parrot_gc_str_allocate_string_storage(PARROT_INTERP,
+    ARGIN(String_GC *gc),
+    ARGOUT(STRING *str),
+    size_t size)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*str);
+
+void Parrot_gc_str_compact_pool(PARROT_INTERP, ARGIN(String_GC *gc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+void Parrot_gc_str_finalize(SHIM_INTERP, ARGMOD(String_GC *gc))
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*gc);
+
+void Parrot_gc_str_free_buffer_storage(SHIM_INTERP,
+    ARGIN(String_GC *gc),
+    ARGMOD(Buffer *b))
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*b);
+
+void Parrot_gc_str_initialize(PARROT_INTERP, ARGMOD(String_GC *gc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*gc);
+
+void Parrot_gc_str_reallocate_buffer_storage(PARROT_INTERP,
+    ARGIN(String_GC *gc),
+    ARGMOD(Buffer *buffer),
+    size_t newsize)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*buffer);
+
+void Parrot_gc_str_reallocate_string_storage(PARROT_INTERP,
+    ARGIN(String_GC *gc),
+    ARGMOD(STRING *str),
+    size_t newsize)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*str);
+
+#define ASSERT_ARGS_Parrot_gc_str_allocate_buffer_storage \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(gc) \
+    , PARROT_ASSERT_ARG(buffer))
+#define ASSERT_ARGS_Parrot_gc_str_allocate_string_storage \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(gc) \
+    , PARROT_ASSERT_ARG(str))
+#define ASSERT_ARGS_Parrot_gc_str_compact_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(gc))
+#define ASSERT_ARGS_Parrot_gc_str_finalize __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(gc))
+#define ASSERT_ARGS_Parrot_gc_str_free_buffer_storage \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(gc) \
+    , PARROT_ASSERT_ARG(b))
+#define ASSERT_ARGS_Parrot_gc_str_initialize __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(gc))
+#define ASSERT_ARGS_Parrot_gc_str_reallocate_buffer_storage \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(gc) \
+    , PARROT_ASSERT_ARG(buffer))
+#define ASSERT_ARGS_Parrot_gc_str_reallocate_string_storage \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(gc) \
+    , PARROT_ASSERT_ARG(str))
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+/* HEADERIZER END: src/gc/string_gc.c */
+
 #endif /* PARROT_GC_PRIVATE_H_GUARD */
 
 /*

Modified: branches/gc_massacre/src/gc/mark_sweep.c
==============================================================================
--- branches/gc_massacre/src/gc/mark_sweep.c	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/gc/mark_sweep.c	Sun Sep 19 08:27:37 2010	(r49153)
@@ -31,13 +31,13 @@
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-static void free_buffer(SHIM_INTERP,
-    SHIM(Memory_Pools *mem_pools),
-    ARGMOD(Fixed_Size_Pool *pool),
+static void free_buffer(PARROT_INTERP,
+    ARGIN(Memory_Pools *mem_pools),
+    SHIM(Fixed_Size_Pool *pool),
     ARGMOD(Buffer *b))
-        __attribute__nonnull__(3)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
         __attribute__nonnull__(4)
-        FUNC_MODIFIES(*pool)
         FUNC_MODIFIES(*b);
 
 static void free_pmc_in_pool(PARROT_INTERP,
@@ -78,7 +78,8 @@
         FUNC_MODIFIES(*mem_pools);
 
 #define ASSERT_ARGS_free_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(pool) \
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(mem_pools) \
     , PARROT_ASSERT_ARG(b))
 #define ASSERT_ARGS_free_pmc_in_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
@@ -510,7 +511,6 @@
     Fixed_Size_Pool * const pmc_pool =
         new_fixed_size_obj_pool(sizeof (PMC), num_headers);
 
-    pmc_pool->mem_pool   = NULL;
     pmc_pool->gc_object  = free_pmc_in_pool;
 
     (interp->gc_sys->init_pool)(interp, pmc_pool);
@@ -575,7 +575,6 @@
 
     pool->gc_object = (gc_object_fn_type)free_buffer;
 
-    pool->mem_pool  = mem_pools->memory_pool;
     (interp->gc_sys->init_pool)(interp, pool);
     return pool;
 }
@@ -604,7 +603,6 @@
 
     pool->last_Arena        = NULL;
     pool->free_list         = NULL;
-    pool->mem_pool          = NULL;
     pool->newfree           = NULL;
     pool->newlast           = NULL;
     pool->object_size       = object_size;
@@ -635,7 +633,6 @@
     if (constant) {
         pool           = new_bufferlike_pool(interp, mem_pools, sizeof (STRING));
         pool->gc_object = NULL;
-        pool->mem_pool = mem_pools->constant_string_pool;
     }
     else
         pool = get_bufferlike_pool(interp, mem_pools, sizeof (STRING));
@@ -658,39 +655,18 @@
 */
 
 static void
-free_buffer(SHIM_INTERP,
-        SHIM(Memory_Pools *mem_pools),
-        ARGMOD(Fixed_Size_Pool *pool),
+free_buffer(PARROT_INTERP,
+        ARGIN(Memory_Pools *mem_pools),
+        SHIM(Fixed_Size_Pool *pool),
         ARGMOD(Buffer *b))
 {
     ASSERT_ARGS(free_buffer)
-    Variable_Size_Pool * const mem_pool = (Variable_Size_Pool *)pool->mem_pool;
 
     /* If there is no allocated buffer - bail out */
     if (!Buffer_buflen(b))
         return;
 
-    /* XXX Jarkko reported that on irix pool->mem_pool was NULL, which really
-     * shouldn't happen */
-    if (mem_pool) {
-        /* Update Memory_Block usage */
-        if (PObj_is_movable_TESTALL(b)) {
-            INTVAL *buffer_flags = Buffer_bufflagsptr(b);
-
-            /* Mask low 2 bits used for flags */
-            Memory_Block * block = Buffer_pool(b);
-
-            PARROT_ASSERT(block);
-
-            /* We can have shared buffers. Don't count them (yet) */
-            if (!(*buffer_flags & Buffer_shared_FLAG)) {
-                block->freed  += ALIGNED_STRING_SIZE(Buffer_buflen(b));
-            }
-
-        }
-    }
-
-    Buffer_buflen(b) = 0;
+    Parrot_gc_str_free_buffer_storage(interp, &mem_pools->string_gc, b);
 }
 
 

Copied and modified: branches/gc_massacre/src/gc/string_gc.c (from r49124, branches/gc_massacre/src/gc/alloc_resources.c)
==============================================================================
--- branches/gc_massacre/src/gc/alloc_resources.c	Sat Sep 18 00:39:15 2010	(r49124, copy source)
+++ branches/gc_massacre/src/gc/string_gc.c	Sun Sep 19 08:27:37 2010	(r49153)
@@ -1,15 +1,14 @@
 /*
-Copyright (C) 2001-2010, Parrot Foundation.
+Copyright (C) 2010, Parrot Foundation.
 $Id$
 
 =head1 NAME
 
-src/gc/alloc_resources.c - Allocate and deallocate buffer resources such as
-STRINGS.
+src/gc/string_gc.c - String GC subsystem.
 
 =head1 DESCRIPTION
 
-Functions to manage non-PObj memory, including strings and buffers.
+GC subsystem to manage STRINGs.
 
 =head2 Parrot Memory Management Code
 
@@ -22,23 +21,32 @@
 #include "parrot/parrot.h"
 #include "gc_private.h"
 
+typedef void (*compact_f) (Interp *, Memory_Pools * const, Variable_Size_Pool *);
 
-#define RECLAMATION_FACTOR 0.20
-#define WE_WANT_EVER_GROWING_ALLOCATIONS 0
+#define POOL_SIZE (65536 * 2)
 
 /* show allocated blocks on stderr */
 #define RESOURCE_DEBUG 0
 #define RESOURCE_DEBUG_SIZE 1000000
 
-#define POOL_SIZE (65536 * 2)
+#define RECLAMATION_FACTOR 0.20
+#define WE_WANT_EVER_GROWING_ALLOCATIONS 0
 
-typedef void (*compact_f) (Interp *, Memory_Pools * const, Variable_Size_Pool *);
+typedef struct string_callback_data {
+    Memory_Block *new_block;     /* A pointer to our working block */
+    char         *cur_spot;      /* Where we're currently copying to */
+} string_callback_data;
 
 /* HEADERIZER HFILE: src/gc/gc_private.h */
 
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+static char * aligned_mem(SHIM(const Buffer *buffer), ARGIN(char *mem))
+        __attribute__nonnull__(2);
+
 static void alloc_new_block(
      ARGMOD(Memory_Pools *mem_pools),
     size_t size,
@@ -56,26 +64,19 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static void check_fixed_size_obj_pool(ARGIN(const Fixed_Size_Pool *pool))
-        __attribute__nonnull__(1);
-
-static void check_memory_system(ARGIN(const Memory_Pools *mem_pools))
-        __attribute__nonnull__(1);
-
-static void check_var_size_obj_pool(ARGIN(const Variable_Size_Pool *pool))
-        __attribute__nonnull__(1);
+static void compact_pool(PARROT_INTERP,
+    ARGMOD(Memory_Pools *mem_pools),
+    ARGMOD(Variable_Size_Pool *pool))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*mem_pools)
+        FUNC_MODIFIES(*pool);
 
 static void debug_print_buf(PARROT_INTERP, ARGIN(const Buffer *b))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static void fix_pmc_syncs(
-    ARGMOD(Interp *dest_interp),
-    ARGIN(const Fixed_Size_Pool *pool))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*dest_interp);
-
 static void free_memory_pool(ARGFREE(Variable_Size_Pool *pool));
 static void free_old_mem_blocks(
      ARGMOD(Memory_Pools *mem_pools),
@@ -89,10 +90,28 @@
         FUNC_MODIFIES(*pool)
         FUNC_MODIFIES(*new_block);
 
-static void free_pool(ARGFREE(Fixed_Size_Pool *pool));
 static int is_block_almost_full(ARGIN(const Memory_Block *block))
         __attribute__nonnull__(1);
 
+PARROT_MALLOC
+PARROT_CANNOT_RETURN_NULL
+static void * mem_allocate(PARROT_INTERP,
+    ARGMOD(Memory_Pools *mem_pools),
+    size_t size,
+    ARGMOD(Variable_Size_Pool *pool))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(4)
+        FUNC_MODIFIES(*mem_pools)
+        FUNC_MODIFIES(*pool);
+
+static void move_buffer_callback(PARROT_INTERP,
+    ARGIN(Buffer *b),
+    ARGIN(void *data))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static char * move_one_buffer(PARROT_INTERP,
@@ -117,37 +136,8 @@
 static UINTVAL pad_pool_size(ARGIN(const Variable_Size_Pool *pool))
         __attribute__nonnull__(1);
 
-static void Parrot_gc_merge_buffer_pools(PARROT_INTERP,
-    ARGMOD(Memory_Pools *mem_pools),
-    ARGMOD(Fixed_Size_Pool *dest),
-    ARGMOD(Fixed_Size_Pool *source))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*mem_pools)
-        FUNC_MODIFIES(*dest)
-        FUNC_MODIFIES(*source);
-
-static int sweep_cb_buf(PARROT_INTERP,
-    ARGIN(Memory_Pools *mem_pools),
-    ARGFREE(Fixed_Size_Pool *pool),
-    SHIM(int flag),
-    SHIM(void *arg))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-static int sweep_cb_pmc(PARROT_INTERP,
-    ARGMOD(Memory_Pools *mem_pools),
-    ARGMOD(Fixed_Size_Pool *pool),
-    SHIM(int flag),
-    SHIM(void *arg))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*mem_pools)
-        FUNC_MODIFIES(*pool);
-
+#define ASSERT_ARGS_aligned_mem __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(mem))
 #define ASSERT_ARGS_alloc_new_block __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(mem_pools) \
     , PARROT_ASSERT_ARG(pool) \
@@ -155,26 +145,28 @@
 #define ASSERT_ARGS_buffer_location __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(b))
-#define ASSERT_ARGS_check_fixed_size_obj_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(pool))
-#define ASSERT_ARGS_check_memory_system __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(mem_pools))
-#define ASSERT_ARGS_check_var_size_obj_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(pool))
+#define ASSERT_ARGS_compact_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(mem_pools) \
+    , PARROT_ASSERT_ARG(pool))
 #define ASSERT_ARGS_debug_print_buf __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(b))
-#define ASSERT_ARGS_fix_pmc_syncs __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(dest_interp) \
-    , PARROT_ASSERT_ARG(pool))
 #define ASSERT_ARGS_free_memory_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 #define ASSERT_ARGS_free_old_mem_blocks __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(mem_pools) \
     , PARROT_ASSERT_ARG(pool) \
     , PARROT_ASSERT_ARG(new_block))
-#define ASSERT_ARGS_free_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 #define ASSERT_ARGS_is_block_almost_full __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(block))
+#define ASSERT_ARGS_mem_allocate __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(mem_pools) \
+    , PARROT_ASSERT_ARG(pool))
+#define ASSERT_ARGS_move_buffer_callback __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(b) \
+    , PARROT_ASSERT_ARG(data))
 #define ASSERT_ARGS_move_one_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(pool) \
@@ -183,21 +175,380 @@
 #define ASSERT_ARGS_new_memory_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 #define ASSERT_ARGS_pad_pool_size __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(pool))
-#define ASSERT_ARGS_Parrot_gc_merge_buffer_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(mem_pools) \
-    , PARROT_ASSERT_ARG(dest) \
-    , PARROT_ASSERT_ARG(source))
-#define ASSERT_ARGS_sweep_cb_buf __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(mem_pools))
-#define ASSERT_ARGS_sweep_cb_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(mem_pools) \
-    , PARROT_ASSERT_ARG(pool))
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: static */
 
+/*
+
+=item C<void Parrot_gc_str_initialize(PARROT_INTERP, String_GC *gc)>
+
+Initialize the managed memory pools. Parrot maintains two C<Variable_Size_Pool>
+structures, the general memory pool and the constant string pool. Create
+and initialize both pool structures, and allocate initial blocks of memory
+for both.
+
+=cut
+
+*/
+
+void
+Parrot_gc_str_initialize(PARROT_INTERP, ARGMOD(String_GC *gc))
+{
+    ASSERT_ARGS(Parrot_gc_str_initialize)
+
+    gc->memory_pool   = new_memory_pool(POOL_SIZE, &compact_pool);
+    alloc_new_block(interp->mem_pools, POOL_SIZE, gc->memory_pool, "init");
+
+    /* Constant strings - not compacted */
+    gc->constant_string_pool = new_memory_pool(POOL_SIZE, NULL);
+    alloc_new_block(interp->mem_pools, POOL_SIZE, gc->constant_string_pool, "init");
+}
+
+/*
+
+=item C<void Parrot_gc_str_finalize(PARROT_INTERP, String_GC *gc)>
+
+Destroys the memory pool and the constant string pool. Loop through both
+pools and destroy all memory blocks contained in them. Once all the
+blocks are freed, free the pools themselves.
+
+=cut
+
+*/
+
+void
+Parrot_gc_str_finalize(SHIM_INTERP, ARGMOD(String_GC *gc))
+{
+    ASSERT_ARGS(Parrot_gc_str_finalize)
+
+    free_memory_pool(gc->constant_string_pool);
+    free_memory_pool(gc->memory_pool);
+}
+
+/*
+
+=item C<void Parrot_gc_str_allocate_buffer_storage(PARROT_INTERP, String_GC *gc,
+Buffer *buffer, size_t size)>
+
+Allocates a chunk of memory of at least size C<size> for the given Buffer.
+buffer is guaranteed to be properly aligned for things like C<FLOATVALS>,
+so the size may be rounded up or down to guarantee that this alignment holds.
+
+=cut
+
+*/
+
+void
+Parrot_gc_str_allocate_buffer_storage(PARROT_INTERP,
+        ARGIN(String_GC *gc),
+        ARGOUT(Buffer *buffer),
+        size_t size)
+{
+    ASSERT_ARGS(Parrot_gc_str_allocate_buffer_storage)
+    const size_t new_size   = ALIGNED_STRING_SIZE(size);
+
+    Buffer_bufstart(buffer) = (void *)aligned_mem(buffer,
+        (char *)mem_allocate(interp,
+        interp->mem_pools, new_size, gc->memory_pool));
+
+    /* Save pool used to allocate into buffer header */
+    *Buffer_poolptr(buffer) = gc->memory_pool->top_block;
+
+    Buffer_buflen(buffer)   = new_size - sizeof (void *);
+}
+
+/*
+
+=item C<void Parrot_gc_str_reallocate_buffer_storage(PARROT_INTERP, String_GC
+*gc, Buffer *buffer, size_t newsize)>
+
+Reallocate the Buffer's buffer memory to the given size. The
+allocated buffer will not shrink. If the buffer was allocated with
+L<Parrot_allocate_aligned> the new buffer will also be aligned. As with
+all reallocation, the new buffer might have moved and the additional
+memory is not cleared.
+
+=cut
+
+*/
+
+void
+Parrot_gc_str_reallocate_buffer_storage(PARROT_INTERP,
+        ARGIN(String_GC *gc),
+        ARGMOD(Buffer *buffer),
+        size_t newsize)
+{
+    ASSERT_ARGS(Parrot_gc_str_reallocate_buffer_storage)
+    size_t copysize;
+    char  *mem;
+    Variable_Size_Pool * const pool = gc->memory_pool;
+    size_t new_size, needed, old_size;
+
+    /* we don't shrink buffers */
+    if (newsize <= Buffer_buflen(buffer))
+        return;
+
+    /*
+     * same as below but barely used and tested - only 3 list related
+     * tests do use true reallocation
+     *
+     * list.c, which does _reallocate, has 2 reallocations
+     * normally, which play ping pong with buffers.
+     * The normal case is therefore always to allocate a new block
+     */
+    new_size = ALIGNED_STRING_SIZE(newsize);
+    old_size = ALIGNED_STRING_SIZE(Buffer_buflen(buffer));
+    needed   = new_size - old_size;
+
+    if ((pool->top_block->free >= needed)
+    &&  (pool->top_block->top  == (char *)Buffer_bufstart(buffer) + old_size)) {
+        pool->top_block->free -= needed;
+        pool->top_block->top  += needed;
+        interp->mem_pools->stats.memory_used += needed;
+        Buffer_buflen(buffer)  = newsize;
+        return;
+    }
+
+    copysize = Buffer_buflen(buffer);
+
+    mem = (char *)mem_allocate(interp, interp->mem_pools, new_size, pool);
+    mem = aligned_mem(buffer, mem);
+
+    /* We shouldn't ever have a 0 from size, but we do. If we can track down
+     * those bugs, this can be removed which would make things cheaper */
+    if (copysize)
+        memcpy(mem, Buffer_bufstart(buffer), copysize);
+
+    Buffer_bufstart(buffer) = mem;
+
+    new_size -= sizeof (void *);
+
+    Buffer_buflen(buffer) = new_size;
+
+    /* Save pool used to allocate into buffer header */
+    *Buffer_poolptr(buffer) = gc->memory_pool->top_block;
+}
+
+/*
+
+=item C<void Parrot_gc_str_allocate_string_storage(PARROT_INTERP, String_GC *gc,
+STRING *str, size_t size)>
+
+Allocate the STRING's buffer memory to the given size. The allocated
+buffer maybe slightly bigger than the given C<size>. This function
+sets also C<< str->strstart >> to the new buffer location, C<< str->bufused >>
+is B<not> changed.
+
+=cut
+
+*/
+
+void
+Parrot_gc_str_allocate_string_storage(PARROT_INTERP,
+        ARGIN(String_GC *gc),
+        ARGOUT(STRING *str),
+        size_t size)
+{
+    ASSERT_ARGS(Parrot_gc_str_allocate_string_storage)
+    size_t       new_size;
+    Variable_Size_Pool *pool;
+    char        *mem;
+
+    Buffer_buflen(str)   = 0;
+    Buffer_bufstart(str) = NULL;
+
+    if (size == 0)
+        return;
+
+    pool     = PObj_constant_TEST(str)
+                ? gc->constant_string_pool
+                : gc->memory_pool;
+
+    new_size = ALIGNED_STRING_SIZE(size);
+    mem      = (char *)mem_allocate(interp, interp->mem_pools, new_size, pool);
+    mem     += sizeof (void *);
+
+    Buffer_bufstart(str) = str->strstart = mem;
+    Buffer_buflen(str)   = new_size - sizeof (void *);
+
+    /* Save pool used to allocate into buffer header */
+    *Buffer_poolptr(str) = pool->top_block;
+}
+
+/*
+
+=item C<void Parrot_gc_str_reallocate_string_storage(PARROT_INTERP, String_GC
+*gc, STRING *str, size_t newsize)>
+
+Reallocate the STRING's buffer memory to the given size. The allocated
+buffer will not shrink. This function sets also C<str-E<gt>strstart> to the
+new buffer location, C<str-E<gt>bufused> is B<not> changed.
+
+=cut
+
+*/
+
+void
+Parrot_gc_str_reallocate_string_storage(PARROT_INTERP,
+        ARGIN(String_GC *gc),
+        ARGMOD(STRING *str),
+        size_t newsize)
+{
+    ASSERT_ARGS(Parrot_gc_str_reallocate_string_storage)
+    size_t copysize;
+    char *mem, *oldmem;
+    size_t new_size, needed, old_size;
+
+    Variable_Size_Pool * const pool =
+        PObj_constant_TEST(str)
+            ? gc->constant_string_pool
+            : gc->memory_pool;
+
+    /* if the requested size is smaller then buflen, we are done */
+    if (newsize <= Buffer_buflen(str))
+        return;
+
+    /*
+     * first check, if we can reallocate:
+     * - if the passed strings buffer is the last string in the pool and
+     * - if there is enough size, we can just move the pool's top pointer
+     */
+    new_size = ALIGNED_STRING_SIZE(newsize);
+    old_size = ALIGNED_STRING_SIZE(Buffer_buflen(str));
+    needed   = new_size - old_size;
+
+    if (pool->top_block->free >= needed
+    &&  pool->top_block->top  == (char *)Buffer_bufstart(str) + old_size) {
+        pool->top_block->free -= needed;
+        pool->top_block->top  += needed;
+        interp->mem_pools->stats.memory_used += needed;
+        Buffer_buflen(str) = new_size - sizeof (void *);
+        return;
+    }
+
+    PARROT_ASSERT(str->bufused <= newsize);
+
+    /* only copy used memory, not total string buffer */
+    copysize = str->bufused;
+
+    mem = (char *)mem_allocate(interp, interp->mem_pools, new_size, pool);
+    mem += sizeof (void *);
+
+    /* Update Memory_Block usage */
+    /* We must not reallocate non-movable buffers! */
+    PARROT_ASSERT(PObj_is_movable_TESTALL(str));
+
+    /* We must not reallocate shared buffers! */
+    PARROT_ASSERT(!(*Buffer_bufflagsptr(str) & Buffer_shared_FLAG));
+
+    /* Decrease usage */
+    PARROT_ASSERT(Buffer_pool(str));
+    Buffer_pool(str)->freed += old_size;
+
+    /* copy mem from strstart, *not* bufstart */
+    oldmem             = str->strstart;
+    Buffer_bufstart(str) = (void *)mem;
+    str->strstart      = mem;
+    Buffer_buflen(str)   = new_size - sizeof (void *);
+
+    /* We shouldn't ever have a 0 from size, but we do. If we can track down
+     * those bugs, this can be removed which would make things cheaper */
+    if (copysize)
+        memcpy(mem, oldmem, copysize);
+
+    /* Save pool used to allocate into buffer header */
+    *Buffer_poolptr(str) = pool->top_block;
+}
+
+/*
+=item C<void Parrot_gc_str_compact_pool(PARROT_INTERP, String_GC *gc)>
+
+Compact string pool.
+
+=cut
+*/
+void
+Parrot_gc_str_compact_pool(PARROT_INTERP, ARGIN(String_GC *gc))
+{
+    ASSERT_ARGS(Parrot_gc_str_compact_pool)
+    compact_pool(interp, interp->mem_pools, gc->memory_pool);
+}
+
+/*
+
+=item C<void Parrot_gc_str_free_buffer_storage(PARROT_INTERP, String_GC *gc,
+Buffer *b)>
+
+Frees a buffer, returning it to the memory pool for Parrot to possibly
+reuse later.
+
+=cut
+
+*/
+
+void
+Parrot_gc_str_free_buffer_storage(SHIM_INTERP,
+        ARGIN(String_GC *gc),
+        ARGMOD(Buffer *b))
+{
+    ASSERT_ARGS(Parrot_gc_str_free_buffer_storage)
+    Variable_Size_Pool * const mem_pool = gc->memory_pool;
+
+    /* If there is no allocated buffer - bail out */
+    if (!Buffer_buflen(b))
+        return;
+
+    if (mem_pool) {
+        /* Update Memory_Block usage */
+        if (PObj_is_movable_TESTALL(b)) {
+            INTVAL *buffer_flags = Buffer_bufflagsptr(b);
+
+            /* Mask low 2 bits used for flags */
+            Memory_Block * block = Buffer_pool(b);
+
+            PARROT_ASSERT(block);
+
+            /* We can have shared buffers. Don't count them (yet) */
+            if (!(*buffer_flags & Buffer_shared_FLAG)) {
+                block->freed  += ALIGNED_STRING_SIZE(Buffer_buflen(b));
+            }
+
+        }
+    }
+
+    Buffer_buflen(b) = 0;
+}
+
+/*
+=item C<static Variable_Size_Pool * new_memory_pool(size_t min_block, compact_f
+compact)>
+
+Allocate a new C<Variable_Size_Pool> structures, and set some initial values.
+return a pointer to the new pool.
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_MALLOC
+PARROT_CANNOT_RETURN_NULL
+static Variable_Size_Pool *
+new_memory_pool(size_t min_block, NULLOK(compact_f compact))
+{
+    ASSERT_ARGS(new_memory_pool)
+    Variable_Size_Pool * const pool = mem_internal_allocate_typed(Variable_Size_Pool);
+
+    pool->top_block              = NULL;
+    pool->compact                = compact;
+    pool->minimum_block_size     = min_block;
+    pool->total_allocated        = 0;
+    pool->guaranteed_reclaimable = 0;
+    pool->possibly_reclaimable   = 0;
+    pool->reclaim_factor         = RECLAMATION_FACTOR;
+
+    return pool;
+}
 
 /*
 
@@ -264,8 +615,8 @@
 
 /*
 
-=item C<void * mem_allocate(PARROT_INTERP, Memory_Pools *mem_pools, size_t size,
-Variable_Size_Pool *pool)>
+=item C<static void * mem_allocate(PARROT_INTERP, Memory_Pools *mem_pools,
+size_t size, Variable_Size_Pool *pool)>
 
 Allocates memory for headers.
 
@@ -290,7 +641,7 @@
 
 PARROT_MALLOC
 PARROT_CANNOT_RETURN_NULL
-void *
+static void *
 mem_allocate(PARROT_INTERP,
         ARGMOD(Memory_Pools *mem_pools),
         size_t size,
@@ -360,10 +711,34 @@
 
 /*
 
-=item C<static const char * buffer_location(PARROT_INTERP, const Buffer *b)>
+=item C<static char * aligned_mem(const Buffer *buffer, char *mem)>
 
-Recturns a constant string representing the location of the given
-Buffer C<b> in one of the PMC registers. If the PMC is not located
+Returns a pointer to the aligned allocated storage for Buffer C<buffer>,
+which might not be the same as the pointer to C<buffer> because of
+memory alignment.
+
+=cut
+
+*/
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+static char *
+aligned_mem(SHIM(const Buffer *buffer), ARGIN(char *mem))
+{
+    ASSERT_ARGS(aligned_mem)
+    mem += sizeof (void *);
+    mem  = (char *)(((unsigned long)(mem + WORD_ALIGN_1)) & WORD_ALIGN_MASK);
+
+    return mem;
+}
+
+/*
+
+=item C<static const char * buffer_location(PARROT_INTERP, const Buffer *b)>
+
+Recturns a constant string representing the location of the given
+Buffer C<b> in one of the PMC registers. If the PMC is not located
 in one of the PMC registers of the current context, returns the
 string C<"???">.
 
@@ -420,7 +795,7 @@
 
 =over 4
 
-=item C<void compact_pool(PARROT_INTERP, Memory_Pools *mem_pools,
+=item C<static void compact_pool(PARROT_INTERP, Memory_Pools *mem_pools,
 Variable_Size_Pool *pool)>
 
 Compact the string buffer pool. Does not perform a GC scan, or mark items
@@ -430,7 +805,7 @@
 
 */
 
-void
+static void
 compact_pool(PARROT_INTERP,
         ARGMOD(Memory_Pools *mem_pools),
         ARGMOD(Variable_Size_Pool *pool))
@@ -439,11 +814,12 @@
     INTVAL        j;
     UINTVAL       total_size;
 
-    Memory_Block *new_block;     /* A pointer to our working block */
-    char         *cur_spot;      /* Where we're currently copying to */
-
     Fixed_Size_Arena *cur_buffer_arena;
 
+    /* Contains new_block and cur_spot */
+    string_callback_data cb_data;
+
+
     /* Bail if we're blocked */
     if (mem_pools->gc_sweep_block_level)
         return;
@@ -466,57 +842,53 @@
 
     alloc_new_block(mem_pools, total_size, pool, "inside compact");
 
-    new_block = pool->top_block;
+    cb_data.new_block = pool->top_block;
 
     /* Start at the beginning */
-    cur_spot  = new_block->start;
+    cb_data.cur_spot  = cb_data.new_block->start;
 
     /* Run through all the Buffer header pools and copy */
-    for (j = (INTVAL)mem_pools->num_sized - 1; j >= 0; --j) {
-        Fixed_Size_Pool * const header_pool = mem_pools->sized_header_pools[j];
-        UINTVAL       object_size;
+    interp->gc_sys->iterate_live_strings(interp, move_buffer_callback, &cb_data);
 
-        if (!header_pool)
-            continue;
-
-        object_size = header_pool->object_size;
+    /* Okay, we're done with the copy. Set the bits in the pool struct */
+    /* First, where we allocate next */
+    cb_data.new_block->top = cb_data.cur_spot;
 
-        for (cur_buffer_arena = header_pool->last_Arena;
-                cur_buffer_arena;
-                cur_buffer_arena = cur_buffer_arena->prev) {
-            Buffer *b = (Buffer *) cur_buffer_arena->start_objects;
-            UINTVAL i;
-            const size_t objects_end = cur_buffer_arena->used;
+    PARROT_ASSERT(cb_data.new_block->size
+                  >=
+                  (size_t)cb_data.new_block->top - (size_t)cb_data.new_block->start);
 
-            for (i = objects_end; i; --i) {
+    /* How much is free. That's the total size minus the amount we used */
+    cb_data.new_block->free     = cb_data.new_block->size
+                                  - (cb_data.cur_spot - cb_data.new_block->start);
+    mem_pools->stats.memory_collected += (cb_data.cur_spot - cb_data.new_block->start);
+    mem_pools->stats.memory_used      += (cb_data.cur_spot - cb_data.new_block->start);
 
-                if (Buffer_buflen(b) && PObj_is_movable_TESTALL(b)) {
-                    Memory_Block *old_block = Buffer_pool(b);
+    free_old_mem_blocks(mem_pools, pool, cb_data.new_block, total_size);
 
-                    if (!is_block_almost_full(old_block))
-                        cur_spot = move_one_buffer(interp, new_block, b, cur_spot);
-                }
+    --mem_pools->gc_sweep_block_level;
+}
 
-                b = (Buffer *)((char *)b + object_size);
-            }
-        }
-    }
+/*
+=item C<static void move_buffer_callback(PARROT_INTERP, Buffer *b, void *data)>
 
-    /* Okay, we're done with the copy. Set the bits in the pool struct */
-    /* First, where we allocate next */
-    new_block->top = cur_spot;
+Callback for live STRING/Buffer for compating.
 
-    PARROT_ASSERT(new_block->size >= (size_t)new_block->top -
-            (size_t)new_block->start);
+=cut
+*/
+static void
+move_buffer_callback(PARROT_INTERP, ARGIN(Buffer *b), ARGIN(void *data))
+{
+    ASSERT_ARGS(move_buffer_callback)
+    string_callback_data *cb = (string_callback_data*)data;
 
-    /* How much is free. That's the total size minus the amount we used */
-    new_block->free = new_block->size - (cur_spot - new_block->start);
-    mem_pools->stats.memory_collected +=      (cur_spot - new_block->start);
-    mem_pools->stats.memory_used      +=      (cur_spot - new_block->start);
+    if (Buffer_buflen(b) && PObj_is_movable_TESTALL(b)) {
+        Memory_Block *old_block = Buffer_pool(b);
 
-    free_old_mem_blocks(mem_pools, pool, new_block, total_size);
+        if (!is_block_almost_full(old_block))
+            cb->cur_spot = move_one_buffer(interp, cb->new_block, b, cb->cur_spot);
+    }
 
-    --mem_pools->gc_sweep_block_level;
 }
 
 /*
@@ -777,480 +1149,6 @@
 
 /*
 
-=item C<char * aligned_mem(const Buffer *buffer, char *mem)>
-
-Returns a pointer to the aligned allocated storage for Buffer C<buffer>,
-which might not be the same as the pointer to C<buffer> because of
-memory alignment.
-
-=cut
-
-*/
-
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-char *
-aligned_mem(SHIM(const Buffer *buffer), ARGIN(char *mem))
-{
-    ASSERT_ARGS(aligned_mem)
-    mem += sizeof (void *);
-    mem  = (char *)(((unsigned long)(mem + WORD_ALIGN_1)) & WORD_ALIGN_MASK);
-
-    return mem;
-}
-
-/*
-
-=back
-
-=head2 Parrot Re/Allocate Code
-
-=over 4
-
-=item C<static Variable_Size_Pool * new_memory_pool(size_t min_block, compact_f
-compact)>
-
-Allocate a new C<Variable_Size_Pool> structures, and set some initial values.
-return a pointer to the new pool.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_MALLOC
-PARROT_CANNOT_RETURN_NULL
-static Variable_Size_Pool *
-new_memory_pool(size_t min_block, NULLOK(compact_f compact))
-{
-    ASSERT_ARGS(new_memory_pool)
-    Variable_Size_Pool * const pool = mem_internal_allocate_typed(Variable_Size_Pool);
-
-    pool->top_block              = NULL;
-    pool->compact                = compact;
-    pool->minimum_block_size     = min_block;
-    pool->total_allocated        = 0;
-    pool->guaranteed_reclaimable = 0;
-    pool->possibly_reclaimable   = 0;
-    pool->reclaim_factor         = RECLAMATION_FACTOR;
-
-    return pool;
-}
-
-/*
-
-=item C<void initialize_var_size_pools(PARROT_INTERP, Memory_Pools *mem_pools)>
-
-Initialize the managed memory pools. Parrot maintains two C<Variable_Size_Pool>
-structures, the general memory pool and the constant string pool. Create
-and initialize both pool structures, and allocate initial blocks of memory
-for both.
-
-=cut
-
-*/
-
-void
-initialize_var_size_pools(SHIM_INTERP, ARGMOD(Memory_Pools *mem_pools))
-{
-    ASSERT_ARGS(initialize_var_size_pools)
-
-    mem_pools->memory_pool   = new_memory_pool(POOL_SIZE, &compact_pool);
-    alloc_new_block(mem_pools, POOL_SIZE, mem_pools->memory_pool, "init");
-
-    /* Constant strings - not compacted */
-    mem_pools->constant_string_pool = new_memory_pool(POOL_SIZE, NULL);
-    alloc_new_block(mem_pools, POOL_SIZE, mem_pools->constant_string_pool, "init");
-}
-
-
-/*
-
-=item C<void merge_pools(Variable_Size_Pool *dest, Variable_Size_Pool *source)>
-
-Merge two memory pools together. Do this by moving all memory blocks
-from the C<*source> pool into the C<*dest> pool. The C<source> pool
-is emptied, but is not destroyed here.
-
-=cut
-
-*/
-
-void
-merge_pools(ARGMOD(Variable_Size_Pool *dest), ARGMOD(Variable_Size_Pool *source))
-{
-    ASSERT_ARGS(merge_pools)
-    Memory_Block *cur_block;
-
-    cur_block = source->top_block;
-
-    while (cur_block) {
-        Memory_Block * const next_block = cur_block->prev;
-
-        if (cur_block->free == cur_block->size)
-            mem_internal_free(cur_block);
-        else {
-            cur_block->next        = NULL;
-            cur_block->prev        = dest->top_block;
-
-            dest->top_block        = cur_block;
-            dest->total_allocated += cur_block->size;
-        }
-        cur_block = next_block;
-    }
-
-    dest->guaranteed_reclaimable += source->guaranteed_reclaimable;
-    dest->possibly_reclaimable   += source->possibly_reclaimable;
-
-    source->top_block              = NULL;
-    source->total_allocated        = 0;
-    source->possibly_reclaimable   = 0;
-    source->guaranteed_reclaimable = 0;
-}
-
-/*
-
-=item C<static void check_memory_system(const Memory_Pools *mem_pools)>
-
-Checks the memory system of parrot on any corruptions, including
-the string system.
-
-=cut
-
-*/
-
-static void
-check_memory_system(ARGIN(const Memory_Pools *mem_pools))
-{
-    ASSERT_ARGS(check_memory_system)
-    size_t i;
-
-    check_var_size_obj_pool(mem_pools->memory_pool);
-    check_var_size_obj_pool(mem_pools->constant_string_pool);
-    check_fixed_size_obj_pool(mem_pools->pmc_pool);
-    check_fixed_size_obj_pool(mem_pools->constant_pmc_pool);
-    check_fixed_size_obj_pool(mem_pools->string_header_pool);
-    check_fixed_size_obj_pool(mem_pools->constant_string_header_pool);
-
-    for (i = 0; i < mem_pools->num_sized; ++i) {
-        const Fixed_Size_Pool * const pool = mem_pools->sized_header_pools[i];
-        if (pool != NULL && pool != mem_pools->string_header_pool)
-            check_fixed_size_obj_pool(pool);
-    }
-}
-
-/*
-
-=item C<static void check_fixed_size_obj_pool(const Fixed_Size_Pool *pool)>
-
-Checks a small object pool, if it contains buffer it checks the buffers also.
-
-=cut
-
-*/
-
-static void
-check_fixed_size_obj_pool(ARGIN(const Fixed_Size_Pool *pool))
-{
-    ASSERT_ARGS(check_fixed_size_obj_pool)
-    size_t total_objects;
-    size_t last_free_list_count;
-    Fixed_Size_Arena * arena_walker;
-    size_t free_objects;
-    size_t count;
-    GC_MS_PObj_Wrapper * pobj_walker;
-
-    count = 10000000; /*detect unendless loop just use big enough number*/
-
-    total_objects = pool->total_objects;
-    last_free_list_count = 1;
-    free_objects = 0;
-
-    arena_walker = pool->last_Arena;
-    while (arena_walker != NULL) {
-        size_t i;
-        PObj * object;
-
-        total_objects -= arena_walker->total_objects;
-        object = (PObj*)arena_walker->start_objects;
-
-        for (i = 0; i < arena_walker->total_objects; ++i) {
-            if (PObj_on_free_list_TEST(object)) {
-                ++free_objects;
-                pobj_walker = (GC_MS_PObj_Wrapper*)object;
-                if (pobj_walker->next_ptr == NULL)
-                    /* should happen only once at the end */
-                    --last_free_list_count;
-                else {
-                    /* next item on free list should also be flaged as free item */
-                    pobj_walker = (GC_MS_PObj_Wrapper*)pobj_walker->next_ptr;
-                    PARROT_ASSERT(PObj_on_free_list_TEST((PObj*)pobj_walker));
-                }
-            }
-            else if (pool->mem_pool != NULL) {
-                /*then it means we are a buffer*/
-                check_buffer_ptr((Buffer*)object, pool->mem_pool);
-            }
-            object = (PObj*)((char *)object + pool->object_size);
-            PARROT_ASSERT(--count);
-        }
-        /*check the list*/
-        if (arena_walker->prev != NULL)
-            PARROT_ASSERT(arena_walker->prev->next == arena_walker);
-        arena_walker = arena_walker->prev;
-        PARROT_ASSERT(--count);
-    }
-
-    count = 10000000;
-
-    PARROT_ASSERT(free_objects == pool->num_free_objects);
-
-    pobj_walker = (GC_MS_PObj_Wrapper*)pool->free_list;
-    while (pobj_walker != NULL) {
-        PARROT_ASSERT(pool->start_arena_memory <= (size_t)pobj_walker);
-        PARROT_ASSERT(pool->end_arena_memory > (size_t)pobj_walker);
-        PARROT_ASSERT(PObj_on_free_list_TEST((PObj*)pobj_walker));
-        --free_objects;
-        pobj_walker = (GC_MS_PObj_Wrapper*)pobj_walker->next_ptr;
-        PARROT_ASSERT(--count);
-    }
-
-    PARROT_ASSERT(total_objects == 0);
-    PARROT_ASSERT(last_free_list_count == 0 || pool->num_free_objects == 0);
-    PARROT_ASSERT(free_objects == 0);
-}
-
-/*
-
-=item C<static void check_var_size_obj_pool(const Variable_Size_Pool *pool)>
-
-Checks a memory pool, containing buffer data
-
-=cut
-
-*/
-
-static void
-check_var_size_obj_pool(ARGIN(const Variable_Size_Pool *pool))
-{
-    ASSERT_ARGS(check_var_size_obj_pool)
-    size_t count;
-    Memory_Block * block_walker;
-    count = 10000000; /*detect unendless loop just use big enough number*/
-
-    block_walker = (Memory_Block *)pool->top_block;
-    while (block_walker != NULL) {
-        PARROT_ASSERT(block_walker->start == (char *)block_walker +
-            sizeof (Memory_Block));
-        PARROT_ASSERT((size_t)(block_walker->top -
-            block_walker->start) == block_walker->size - block_walker->free);
-
-        /*check the list*/
-        if (block_walker->prev != NULL)
-            PARROT_ASSERT(block_walker->prev->next == block_walker);
-        block_walker = block_walker->prev;
-        PARROT_ASSERT(--count);
-    }
-}
-
-/*
-
-=item C<void check_buffer_ptr(Buffer * pobj, Variable_Size_Pool * pool)>
-
-Checks wether the buffer is within the bounds of the memory pool
-
-=cut
-
-*/
-
-void
-check_buffer_ptr(ARGMOD(Buffer * pobj), ARGMOD(Variable_Size_Pool * pool))
-{
-    ASSERT_ARGS(check_buffer_ptr)
-    Memory_Block * cur_block = pool->top_block;
-    char * bufstart;
-
-    bufstart = (char*)Buffer_bufstart(pobj);
-
-    if (bufstart == NULL && Buffer_buflen(pobj) == 0)
-        return;
-
-    if (PObj_external_TEST(pobj) || PObj_sysmem_TEST(pobj)) {
-        /*buffer does not come from the memory pool*/
-        if (PObj_is_string_TEST(pobj)) {
-            PARROT_ASSERT(((STRING *) pobj)->strstart >=
-                (char *) Buffer_bufstart(pobj));
-            PARROT_ASSERT(((STRING *) pobj)->strstart +
-                ((STRING *) pobj)->strlen <=
-                (char *) Buffer_bufstart(pobj) + Buffer_buflen(pobj));
-        }
-        return;
-    }
-
-    if (PObj_is_COWable_TEST(pobj))
-        bufstart -= sizeof (void*);
-
-    while (cur_block) {
-        if ((char *)bufstart >= cur_block->start &&
-            (char *)Buffer_bufstart(pobj) +
-            Buffer_buflen(pobj) < cur_block->start + cur_block->size) {
-            if (PObj_is_string_TEST(pobj)) {
-                PARROT_ASSERT(((STRING *)pobj)->strstart >=
-                    (char *)Buffer_bufstart(pobj));
-                PARROT_ASSERT(((STRING *)pobj)->strstart +
-                    ((STRING *)pobj)->strlen <= (char *)Buffer_bufstart(pobj) +
-                    Buffer_buflen(pobj));
-            }
-            return;
-        }
-        cur_block = cur_block->prev;
-    }
-    PARROT_ASSERT(0);
-}
-
-
-/*
-
-=item C<void Parrot_gc_destroy_header_pools(PARROT_INTERP, Memory_Pools
-*mem_pools)>
-
-Performs a garbage collection sweep on all pools, then frees them.  Calls
-C<header_pools_iterate_callback> to loop over all the pools, passing
-C<sweep_cb_pmc> and C<sweep_cb_buf> callback routines. Frees the array of sized
-header pointers in the C<Memory_Pools> structure too.
-
-=cut
-
-*/
-
-void
-Parrot_gc_destroy_header_pools(PARROT_INTERP, ARGMOD(Memory_Pools *mem_pools))
-{
-    ASSERT_ARGS(Parrot_gc_destroy_header_pools)
-
-    /* const/non const COW strings life in different pools
-     * so in first pass
-     * COW refcount is done, in 2. refcounting
-     * in 3rd freeing
-     */
-    const INTVAL start = 2;
-
-    header_pools_iterate_callback(interp, mem_pools, POOL_PMC, NULL, sweep_cb_pmc);
-    header_pools_iterate_callback(interp, mem_pools, POOL_PMC | POOL_CONST, NULL,
-            sweep_cb_pmc);
-
-    header_pools_iterate_callback(interp, mem_pools, POOL_BUFFER | POOL_CONST,
-            (void *)start, sweep_cb_buf);
-
-    mem_internal_free(mem_pools->sized_header_pools);
-
-    if (mem_pools->attrib_pools) {
-        unsigned int i;
-        for (i = 0; i < mem_pools->num_attribs; ++i) {
-            PMC_Attribute_Pool  *pool  = mem_pools->attrib_pools[i];
-            PMC_Attribute_Arena *arena;
-
-            if (!pool)
-                continue;
-
-            arena = pool->top_arena;
-
-            while (arena) {
-                PMC_Attribute_Arena *next = arena->next;
-                mem_internal_free(arena);
-                arena = next;
-            }
-            mem_internal_free(pool);
-        }
-
-        mem_internal_free(mem_pools->attrib_pools);
-    }
-
-    mem_pools->attrib_pools       = NULL;
-    mem_pools->sized_header_pools = NULL;
-}
-
-/*
-
-=item C<static int sweep_cb_pmc(PARROT_INTERP, Memory_Pools *mem_pools,
-Fixed_Size_Pool *pool, int flag, void *arg)>
-
-Performs a garbage collection sweep of the given pmc pool, then frees it. Calls
-C<Parrot_gc_sweep_pool> to perform the sweep, and C<free_pool> to free the pool and
-all its arenas. Always returns C<0>.
-
-=cut
-
-*/
-
-static int
-sweep_cb_pmc(PARROT_INTERP,
-        ARGMOD(Memory_Pools *mem_pools),
-        ARGMOD(Fixed_Size_Pool *pool),
-        SHIM(int flag), SHIM(void *arg))
-{
-    ASSERT_ARGS(sweep_cb_pmc)
-    Parrot_gc_sweep_pool(interp, mem_pools, pool);
-    free_pool(pool);
-    return 0;
-}
-
-/*
-
-=item C<static int sweep_cb_buf(PARROT_INTERP, Memory_Pools *mem_pools,
-Fixed_Size_Pool *pool, int flag, void *arg)>
-
-Performs a final garbage collection sweep, then frees the pool. Calls
-C<Parrot_gc_sweep_pool> to perform the sweep, and C<free_pool> to free the pool and
-all its arenas.
-
-=cut
-
-*/
-
-static int
-sweep_cb_buf(PARROT_INTERP,
-        ARGIN(Memory_Pools *mem_pools),
-        ARGFREE(Fixed_Size_Pool *pool),
-        SHIM(int flag), SHIM(void *arg))
-{
-    ASSERT_ARGS(sweep_cb_buf)
-
-    Parrot_gc_sweep_pool(interp, mem_pools, pool);
-    free_pool(pool);
-
-    return 0;
-}
-
-/*
-
-=item C<static void free_pool(Fixed_Size_Pool *pool)>
-
-Frees a pool and all of its arenas. Loops through the list of arenas backwards
-and returns each to the memory manager. Then, frees the pool structure itself.
-
-=cut
-
-*/
-
-static void
-free_pool(ARGFREE(Fixed_Size_Pool *pool))
-{
-    ASSERT_ARGS(free_pool)
-    Fixed_Size_Arena *cur_arena;
-
-    for (cur_arena = pool->last_Arena; cur_arena;) {
-        Fixed_Size_Arena * const next = cur_arena->prev;
-        mem_internal_free(cur_arena->start_objects);
-        mem_internal_free(cur_arena);
-        cur_arena = next;
-    }
-    mem_internal_free(pool);
-}
-
-
-/*
-
 =item C<static void free_memory_pool(Variable_Size_Pool *pool)>
 
 Frees a memory pool; helper function for C<Parrot_gc_destroy_memory_pools>.
@@ -1275,184 +1173,6 @@
     mem_internal_free(pool);
 }
 
-
-/*
-
-=item C<void Parrot_gc_destroy_memory_pools(PARROT_INTERP, Memory_Pools
-*mem_pools)>
-
-Destroys the memory pool and the constant string pool. Loop through both
-pools and destroy all memory blocks contained in them. Once all the
-blocks are freed, free the pools themselves.
-
-=cut
-
-*/
-
-void
-Parrot_gc_destroy_memory_pools(SHIM_INTERP, ARGMOD(Memory_Pools *mem_pools))
-{
-    ASSERT_ARGS(Parrot_gc_destroy_memory_pools)
-
-    free_memory_pool(mem_pools->constant_string_pool);
-    free_memory_pool(mem_pools->memory_pool);
-}
-
-/*
-
-=item C<void Parrot_gc_merge_memory_pools(Interp *dest_interp, Memory_Pools
-*dest_arena, const Memory_Pools *source_arena)>
-
-Merges the header pools of C<source_interp> into those of C<dest_interp>.
-(Used to deal with shared objects left after interpreter destruction.)
-
-=cut
-
-*/
-
-void
-Parrot_gc_merge_memory_pools(ARGMOD(Interp *dest_interp),
-    ARGMOD(Memory_Pools *dest_arena),
-    ARGIN(const Memory_Pools *source_arena))
-{
-    ASSERT_ARGS(Parrot_gc_merge_memory_pools)
-
-    UINTVAL        i;
-
-    /* heavily borrowed from forall_header_pools */
-    fix_pmc_syncs(dest_interp, source_arena->constant_pmc_pool);
-    Parrot_gc_merge_buffer_pools(dest_interp, dest_arena,
-            dest_arena->constant_pmc_pool, source_arena->constant_pmc_pool);
-
-    fix_pmc_syncs(dest_interp, source_arena->pmc_pool);
-    Parrot_gc_merge_buffer_pools(dest_interp, dest_arena,
-            dest_arena->pmc_pool, source_arena->pmc_pool);
-
-    Parrot_gc_merge_buffer_pools(dest_interp, dest_arena,
-            dest_arena->constant_string_header_pool,
-            source_arena->constant_string_header_pool);
-
-    for (i = 0; i < source_arena->num_sized; ++i) {
-        if (!source_arena->sized_header_pools[i])
-            continue;
-
-        if (i >= dest_arena->num_sized
-        || !dest_arena->sized_header_pools[i]) {
-            Fixed_Size_Pool *ignored = get_bufferlike_pool(dest_interp,
-                    dest_arena, i * sizeof (void *));
-            UNUSED(ignored);
-            PARROT_ASSERT(dest_arena->sized_header_pools[i]);
-        }
-
-        Parrot_gc_merge_buffer_pools(dest_interp, dest_arena,
-            dest_arena->sized_header_pools[i],
-            source_arena->sized_header_pools[i]);
-    }
-}
-
-/*
-
-=item C<static void Parrot_gc_merge_buffer_pools(PARROT_INTERP, Memory_Pools
-*mem_pools, Fixed_Size_Pool *dest, Fixed_Size_Pool *source)>
-
-Merge pool C<source> into pool C<dest>. Combines the free lists directly,
-moves all arenas to the new pool, and remove the old pool. To merge, the
-two pools must have the same object size, and the same name (if they have
-names).
-
-=cut
-
-*/
-
-static void
-Parrot_gc_merge_buffer_pools(PARROT_INTERP,
-        ARGMOD(Memory_Pools *mem_pools),
-        ARGMOD(Fixed_Size_Pool *dest), ARGMOD(Fixed_Size_Pool *source))
-{
-    ASSERT_ARGS(Parrot_gc_merge_buffer_pools)
-    Fixed_Size_Arena  *cur_arena;
-
-    PARROT_ASSERT(dest->object_size == source->object_size);
-    PARROT_ASSERT((dest->name == NULL && source->name == NULL)
-                || STREQ(dest->name, source->name));
-
-    dest->total_objects += source->total_objects;
-
-    /* append new free_list to old */
-    /* XXX this won't work with, e.g., gc_gms */
-    if (dest->free_list == NULL)
-        dest->free_list = source->free_list;
-    else {
-        GC_MS_PObj_Wrapper  *free_list_end = dest->free_list;
-        while (free_list_end->next_ptr)
-            free_list_end = free_list_end->next_ptr;
-
-        free_list_end->next_ptr = source->free_list;
-    }
-
-    /* now append source arenas */
-    cur_arena = source->last_Arena;
-
-    while (cur_arena) {
-        Fixed_Size_Arena * const next_arena = cur_arena->prev;
-        const size_t total_objects          = cur_arena->total_objects;
-
-        cur_arena->next = cur_arena->prev = NULL;
-
-        Parrot_append_arena_in_pool(interp, mem_pools, dest, cur_arena,
-            cur_arena->total_objects);
-
-        /* XXX needed? */
-        cur_arena->total_objects = total_objects;
-
-        cur_arena = next_arena;
-    }
-
-    /* remove things from source */
-    source->last_Arena       = NULL;
-    source->free_list        = NULL;
-    source->total_objects    = 0;
-    source->num_free_objects = 0;
-}
-
-/*
-
-=item C<static void fix_pmc_syncs(Interp *dest_interp, const Fixed_Size_Pool
-*pool)>
-
-Walks through the given arena, looking for all live and shared PMCs,
-transferring their sync values to the destination interpreter.
-
-=cut
-
-*/
-
-static void
-fix_pmc_syncs(ARGMOD(Interp *dest_interp), ARGIN(const Fixed_Size_Pool *pool))
-{
-    ASSERT_ARGS(fix_pmc_syncs)
-    Fixed_Size_Arena *cur_arena;
-    const UINTVAL       object_size = pool->object_size;
-
-    for (cur_arena = pool->last_Arena; cur_arena; cur_arena = cur_arena->prev) {
-        PMC   *p = (PMC *)((char*)cur_arena->start_objects);
-        size_t i;
-
-        for (i = 0; i < cur_arena->used; ++i) {
-            if (!PObj_on_free_list_TEST(p) && PObj_is_PMC_TEST(p)) {
-                Parrot_ex_throw_from_c_args(dest_interp, NULL,
-                    EXCEPTION_INTERP_ERROR,
-                    "Unshared PMC still alive after interpreter"
-                    "destruction. address=%p, base_type=%d\n",
-                    p, p->vtable->base_type);
-            }
-
-            p = (PMC *)((char *)p + object_size);
-        }
-    }
-}
-
-
 /*
 
 =back
@@ -1460,6 +1180,7 @@
 =head1 SEE ALSO
 
 F<src/gc/memory.c>.
+F<src/gc/alloc_resources.c>.
 
 =cut
 

Modified: branches/gc_massacre/src/ops/cmp.ops
==============================================================================
--- branches/gc_massacre/src/ops/cmp.ops	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/ops/cmp.ops	Sun Sep 19 08:27:37 2010	(r49153)
@@ -928,7 +928,7 @@
 }
 
 inline op and(invar PMC, invar PMC, invar PMC) :base_core {
-    $1 = VTABLE_logical_and(interp, $2, $3, $1);
+    $1 = VTABLE_get_bool(interp, $2) ? $3 : $2;
 }
 
 ########################################
@@ -954,11 +954,14 @@
 }
 
 inline op not(invar PMC) :base_core {
-    VTABLE_i_logical_not(interp, $1);
+    VTABLE_set_bool(interp, $1, !VTABLE_get_bool(interp, $1));
 }
 
 inline op not(out PMC, invar PMC) :base_core {
-    $1 = VTABLE_logical_not(interp, $2, $1);
+    const INTVAL a = ! VTABLE_get_bool(interp, $2);
+    if (PMC_IS_NULL($1))
+        $1 = Parrot_pmc_new(interp, VTABLE_type(interp, $2));
+    VTABLE_set_bool(interp, $1, a);
 }
 
 ########################################
@@ -976,7 +979,7 @@
 }
 
 inline op or(invar PMC, invar PMC, invar PMC) :base_core {
-    $1 = VTABLE_logical_or(interp, $2, $3, $1);
+    $1 = VTABLE_get_bool(interp, $2) ? $2 : $3;
 }
 
 ########################################
@@ -995,7 +998,17 @@
 }
 
 inline op xor(invar PMC, invar PMC, invar PMC) :base_core {
-    $1 = VTABLE_logical_xor(interp, $2, $3, $1);
+    const INTVAL a = VTABLE_get_bool(interp, $2);
+    const INTVAL b = VTABLE_get_bool(interp, $3);
+    if (a && ! b)
+        $1 = $2;
+    else
+        if (b && ! a)
+            $1 = $3 ;
+        else{
+            $1 = Parrot_pmc_new(interp, VTABLE_type(interp, $2));
+            VTABLE_set_bool(interp, $1, 0);
+        }
 }
 
 =back

Modified: branches/gc_massacre/src/ops/core_ops.c
==============================================================================
--- branches/gc_massacre/src/ops/core_ops.c	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/ops/core_ops.c	Sun Sep 19 08:27:37 2010	(r49153)
@@ -18211,7 +18211,7 @@
 opcode_t *
 Parrot_and_p_p_p(opcode_t *cur_opcode, PARROT_INTERP)  {
     const Parrot_Context * const CUR_CTX = Parrot_pcc_get_context_struct(interp, interp->ctx);
-    PREG(1) = VTABLE_logical_and(interp, PREG(2), PREG(3), PREG(1));
+    PREG(1) = VTABLE_get_bool(interp, PREG(2)) ? PREG(3) : PREG(2);
 
 return (opcode_t *)cur_opcode + 4;}
 
@@ -18232,14 +18232,17 @@
 opcode_t *
 Parrot_not_p(opcode_t *cur_opcode, PARROT_INTERP)  {
     const Parrot_Context * const CUR_CTX = Parrot_pcc_get_context_struct(interp, interp->ctx);
-    VTABLE_i_logical_not(interp, PREG(1));
+    VTABLE_set_bool(interp, PREG(1), !VTABLE_get_bool(interp, PREG(1)));
 
 return (opcode_t *)cur_opcode + 2;}
 
 opcode_t *
 Parrot_not_p_p(opcode_t *cur_opcode, PARROT_INTERP)  {
     const Parrot_Context * const CUR_CTX = Parrot_pcc_get_context_struct(interp, interp->ctx);
-    PREG(1) = VTABLE_logical_not(interp, PREG(2), PREG(1));
+    const INTVAL a = ! VTABLE_get_bool(interp, PREG(2));
+    if (PMC_IS_NULL(PREG(1)))
+        PREG(1) = Parrot_pmc_new(interp, VTABLE_type(interp, PREG(2)));
+    VTABLE_set_bool(interp, PREG(1), a);
 
 return (opcode_t *)cur_opcode + 3;}
 
@@ -18267,7 +18270,7 @@
 opcode_t *
 Parrot_or_p_p_p(opcode_t *cur_opcode, PARROT_INTERP)  {
     const Parrot_Context * const CUR_CTX = Parrot_pcc_get_context_struct(interp, interp->ctx);
-    PREG(1) = VTABLE_logical_or(interp, PREG(2), PREG(3), PREG(1));
+    PREG(1) = VTABLE_get_bool(interp, PREG(2)) ? PREG(2) : PREG(3);
 
 return (opcode_t *)cur_opcode + 4;}
 
@@ -18295,7 +18298,17 @@
 opcode_t *
 Parrot_xor_p_p_p(opcode_t *cur_opcode, PARROT_INTERP)  {
     const Parrot_Context * const CUR_CTX = Parrot_pcc_get_context_struct(interp, interp->ctx);
-    PREG(1) = VTABLE_logical_xor(interp, PREG(2), PREG(3), PREG(1));
+    const INTVAL a = VTABLE_get_bool(interp, PREG(2));
+    const INTVAL b = VTABLE_get_bool(interp, PREG(3));
+    if (a && ! b)
+        PREG(1) = PREG(2);
+    else
+        if (b && ! a)
+            PREG(1) = PREG(3) ;
+        else{
+            PREG(1) = Parrot_pmc_new(interp, VTABLE_type(interp, PREG(2)));
+            VTABLE_set_bool(interp, PREG(1), 0);
+        }
 
 return (opcode_t *)cur_opcode + 4;}
 

Modified: branches/gc_massacre/src/parrot_debugger.c
==============================================================================
--- branches/gc_massacre/src/parrot_debugger.c	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/parrot_debugger.c	Sun Sep 19 08:27:37 2010	(r49153)
@@ -294,7 +294,7 @@
 {
     fprintf(stderr,
         "Parrot " PARROT_VERSION " Debugger\n"
-        "\nPlease note: the debugger is currently under reconstruction\n");
+        "(Please note: the debugger is currently under reconstruction)\n");
 }
 
 /*

Modified: branches/gc_massacre/src/pmc/boolean.pmc
==============================================================================
--- branches/gc_massacre/src/pmc/boolean.pmc	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/pmc/boolean.pmc	Sun Sep 19 08:27:37 2010	(r49153)
@@ -163,12 +163,6 @@
         SELF.set_bool(Parrot_str_boolean(INTERP, value));
     }
 
-    /* No POD documentation, since the reader should see Scalar. */
-
-    VTABLE void i_logical_not() {
-        flip_boolean_FLAG(SELF);
-    }
-
 /*
 
 =item C<void freeze(PMC *info)>

Modified: branches/gc_massacre/src/pmc/callcontext.pmc
==============================================================================
--- branches/gc_massacre/src/pmc/callcontext.pmc	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/pmc/callcontext.pmc	Sun Sep 19 08:27:37 2010	(r49153)
@@ -1344,7 +1344,8 @@
     }
 
     VTABLE INTVAL get_integer_keyed_str(STRING *key) {
-        Hash * const hash = get_hash(INTERP, SELF);
+        Hash *hash;
+        GETATTR_CallContext_hash(INTERP, SELF, hash);
 
         if (hash) {
             void     * const k    = hash_key_from_string(INTERP, hash, key);
@@ -1358,7 +1359,8 @@
     }
 
     VTABLE FLOATVAL get_number_keyed_str(STRING *key) {
-        Hash * const hash = get_hash(INTERP, SELF);
+        Hash *hash;
+        GETATTR_CallContext_hash(INTERP, SELF, hash);
 
         if (hash) {
             void     * const k    = hash_key_from_string(INTERP, hash, key);
@@ -1373,7 +1375,8 @@
 
 
     VTABLE STRING * get_string_keyed_str(STRING *key) {
-        Hash * const hash = get_hash(INTERP, SELF);
+        Hash *hash;
+        GETATTR_CallContext_hash(INTERP, SELF, hash);
 
         if (hash) {
             void     * const k    = hash_key_from_string(INTERP, hash, key);
@@ -1387,7 +1390,8 @@
     }
 
     VTABLE PMC * get_pmc_keyed_str(STRING *key) {
-        Hash * const hash = get_hash(INTERP, SELF);
+        Hash *hash;
+        GETATTR_CallContext_hash(INTERP, SELF, hash);
 
         if (hash) {
             void     * const k    = hash_key_from_string(INTERP, hash, key);
@@ -1405,7 +1409,8 @@
     }
 
     VTABLE INTVAL get_integer_keyed(PMC *key) {
-        Hash * const hash = get_hash(INTERP, SELF);
+        Hash *hash;
+        GETATTR_CallContext_hash(INTERP, SELF, hash);
 
         if (hash) {
             void     * const k    = hash_key_from_pmc(INTERP, hash, key);
@@ -1419,7 +1424,8 @@
     }
 
     VTABLE FLOATVAL get_number_keyed(PMC *key) {
-        Hash * const hash = get_hash(INTERP, SELF);
+        Hash *hash;
+        GETATTR_CallContext_hash(INTERP, SELF, hash);
 
         if (hash) {
             void     * const k    = hash_key_from_pmc(INTERP, hash, key);
@@ -1433,7 +1439,8 @@
     }
 
     VTABLE STRING * get_string_keyed(PMC *key) {
-        Hash * const hash = get_hash(INTERP, SELF);
+        Hash *hash;
+        GETATTR_CallContext_hash(INTERP, SELF, hash);
 
         if (hash) {
             void     * const k    = hash_key_from_pmc(INTERP, hash, key);
@@ -1447,7 +1454,8 @@
     }
 
     VTABLE PMC * get_pmc_keyed(PMC *key) {
-        Hash * const hash = get_hash(INTERP, SELF);
+        Hash *hash;
+        GETATTR_CallContext_hash(INTERP, SELF, hash);
 
         if (hash) {
             void     * const k    = hash_key_from_pmc(INTERP, hash, key);
@@ -1465,7 +1473,8 @@
     }
 
     VTABLE INTVAL exists_keyed(PMC *key) {
-        Hash * const hash = get_hash(INTERP, SELF);
+        Hash *hash;
+        GETATTR_CallContext_hash(INTERP, SELF, hash);
 
         if (hash) {
             void * const k = hash_key_from_pmc(INTERP, hash, key);
@@ -1476,7 +1485,8 @@
     }
 
     VTABLE INTVAL exists_keyed_str(STRING *key) {
-        Hash * const hash = get_hash(INTERP, SELF);
+        Hash *hash;
+        GETATTR_CallContext_hash(INTERP, SELF, hash);
 
         if (hash) {
             void * const k = hash_key_from_string(INTERP, hash, key);
@@ -1512,6 +1522,7 @@
         PMC * const  dest = Parrot_pmc_new(INTERP, SELF->vtable->base_type);
         INTVAL       num;
         Pcc_cell    *our_cells, *dest_cells;
+        Hash        *hash;
 
         GET_ATTR_num_positionals(INTERP, SELF, num);
         /* Copy positionals */
@@ -1526,6 +1537,8 @@
         GET_ATTR_arg_flags(INTERP, SELF, arg_flags);
         GET_ATTR_return_flags(INTERP, SELF, return_flags);
 
+        GET_ATTR_hash(INTERP, SELF, hash);
+
         if (!PMC_IS_NULL(type_tuple))
             SET_ATTR_type_tuple(INTERP, dest, VTABLE_clone(INTERP, type_tuple));
 
@@ -1538,8 +1551,8 @@
         if (!PMC_IS_NULL(return_flags))
             SET_ATTR_return_flags(INTERP, dest, VTABLE_clone(INTERP, return_flags));
 
-        parrot_hash_clone(INTERP, get_hash(INTERP, SELF),
-            get_hash(INTERP, dest));
+        if (hash)
+            parrot_hash_clone(INTERP, hash, get_hash(INTERP, dest));
 
         return dest;
     }

Modified: branches/gc_massacre/src/pmc/default.pmc
==============================================================================
--- branches/gc_massacre/src/pmc/default.pmc	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/pmc/default.pmc	Sun Sep 19 08:27:37 2010	(r49153)
@@ -1855,56 +1855,6 @@
 
         return retval;
     }
-/*
-
-=item C<PMC *logical_or(PMC *value, PMC *dest)>
-
-Default fallback. Performs a multiple dispatch call for 'logical_or'.
-
-=cut
-
-*/
-
-    VTABLE PMC *logical_or(PMC *value, PMC *dest) {
-        PMC *result = PMCNULL;
-        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
-                "logical_or", "PPP->P", SELF, value, dest, &result);
-        return result;
-    }
-
-/*
-
-=item C<PMC *logical_and(PMC *value, PMC *dest)>
-
-Default fallback. Performs a multiple dispatch call for 'logical_and'.
-
-=cut
-
-*/
-
-    VTABLE PMC *logical_and(PMC *value, PMC *dest) {
-        PMC *result = PMCNULL;
-        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
-                "logical_and", "PPP->P", SELF, value, dest, &result);
-        return result;
-    }
-
-/*
-
-=item C<PMC *logical_xor(PMC *value, PMC *dest)>
-
-Default fallback. Performs a multiple dispatch call for 'logical_xor'.
-
-=cut
-
-*/
-
-    VTABLE PMC *logical_xor(PMC *value, PMC *dest) {
-        PMC *result = PMCNULL;
-        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
-                "logical_xor", "PPP->P", SELF, value, dest, &result);
-        return result;
-    }
 
 /*
 

Modified: branches/gc_massacre/src/pmc/filehandle.pmc
==============================================================================
--- branches/gc_massacre/src/pmc/filehandle.pmc	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/pmc/filehandle.pmc	Sun Sep 19 08:27:37 2010	(r49153)
@@ -373,18 +373,24 @@
 
 #ifdef PARROT_HAS_READLINE
     /* 4-column indent to get c_indent.t to DTRT */
-        char * const r = readline(got_prompt ? prompt->strstart : NULL);
+        char *prompt_cstring =
+            (got_prompt ? Parrot_str_to_cstring(INTERP, prompt) : NULL);
+        char * const r = readline(prompt_cstring);
+        Parrot_str_free_cstring(prompt_cstring);
 
         if (r) {
             if (*r)
                 add_history(r);
 
             string_result = Parrot_str_new(INTERP, r, 0);
-            mem_internal_free(r);
+            free(r);
         }
 #else
-        if (got_prompt)
-            fprintf(stderr, "%s", prompt->strstart);
+        if (got_prompt) {
+            char *prompt_cstring = Parrot_str_to_cstring(INTERP, prompt);
+            fprintf(stderr, "%s", prompt_cstring);
+            Parrot_str_free_cstring(prompt_cstring);
+        }
 
         if (!(PARROT_FILEHANDLE(SELF)->flags & PIO_F_LINEBUF))
             Parrot_io_setlinebuf(INTERP, SELF);

Modified: branches/gc_massacre/src/pmc/float.pmc
==============================================================================
--- branches/gc_massacre/src/pmc/float.pmc	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/pmc/float.pmc	Sun Sep 19 08:27:37 2010	(r49153)
@@ -139,12 +139,14 @@
 */
 
     VTABLE void set_integer_native(INTVAL value) {
-        Parrot_pmc_reuse(INTERP, SELF, enum_class_Integer, 0);
+        Parrot_pmc_reuse(INTERP, SELF,
+            Parrot_get_ctx_HLL_type(INTERP, enum_class_Integer), 0);
         SELF.set_integer_native(value);
     }
 
     VTABLE void set_bool(INTVAL value) {
-        Parrot_pmc_reuse(INTERP, SELF, enum_class_Boolean, 0);
+        Parrot_pmc_reuse(INTERP, SELF,
+            Parrot_get_ctx_HLL_type(INTERP, enum_class_Boolean), 0);
         SELF.set_bool(value);
     }
 
@@ -175,7 +177,8 @@
 */
 
     VTABLE void set_string_native(STRING *value) {
-        Parrot_pmc_reuse(INTERP, SELF, enum_class_String, 0);
+        Parrot_pmc_reuse(INTERP, SELF,
+            Parrot_get_ctx_HLL_type(INTERP, enum_class_String), 0);
         SELF.set_string_native(value);
     }
 

Modified: branches/gc_massacre/src/pmc/hash.pmc
==============================================================================
--- branches/gc_massacre/src/pmc/hash.pmc	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/pmc/hash.pmc	Sun Sep 19 08:27:37 2010	(r49153)
@@ -1189,7 +1189,6 @@
 */
 
     VTABLE void freeze(PMC *info) {
-        SUPER(info);
         Parrot_hash_freeze(INTERP, (Hash *)SELF.get_pointer(), info);
     }
 
@@ -1204,7 +1203,6 @@
 */
 
     VTABLE void thaw(PMC *info) {
-        SUPER(info);
         SELF.set_pointer((void *)Parrot_hash_thaw(INTERP, info));
     }
 }

Modified: branches/gc_massacre/src/pmc/integer.pmc
==============================================================================
--- branches/gc_massacre/src/pmc/integer.pmc	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/pmc/integer.pmc	Sun Sep 19 08:27:37 2010	(r49153)
@@ -286,20 +286,23 @@
 */
 
     VTABLE void set_number_native(FLOATVAL value) {
-        Parrot_pmc_reuse(INTERP, SELF, enum_class_Float, 0);
+        Parrot_pmc_reuse(INTERP, SELF,
+            Parrot_get_ctx_HLL_type(INTERP, enum_class_Float), 0);
         SELF.set_number_native(value);
     }
 
 
     VTABLE void set_bool(INTVAL value) {
-        Parrot_pmc_reuse(INTERP, SELF, enum_class_Boolean, 0);
+        Parrot_pmc_reuse(INTERP, SELF,
+            Parrot_get_ctx_HLL_type(INTERP, enum_class_Boolean), 0);
         SELF.set_bool(value);
     }
 
 
 
     VTABLE void set_string_native(STRING *value) {
-        Parrot_pmc_reuse(INTERP, SELF, enum_class_String, 0);
+        Parrot_pmc_reuse(INTERP, SELF,
+            Parrot_get_ctx_HLL_type(INTERP, enum_class_String), 0);
         SELF.set_string_native(value);
     }
 
@@ -1228,7 +1231,7 @@
         else {
             maybe_throw_overflow_error(INTERP);
             SELF = upgrade_self_to_bignum(INTERP, SELF);
-            return VTABLE_i_neg(INTERP, SELF);
+            VTABLE_i_neg(INTERP, SELF);
         }
     }
 

Modified: branches/gc_massacre/src/pmc/scalar.pmc
==============================================================================
--- branches/gc_massacre/src/pmc/scalar.pmc	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/pmc/scalar.pmc	Sun Sep 19 08:27:37 2010	(r49153)
@@ -807,98 +807,6 @@
 
 /*
 
-=back
-
-=head2 Logical Methods
-
-=over 4
-
-=item C<PMC *logical_or(PMC *value, PMC *dest)>
-
-Returns the result of the logical C<OR> of C<SELF> and C<value>, i.e. returns
-C<SELF> it is true or C<value>: C<dest> is alway ignored.
-
-=cut
-
-*/
-
-    VTABLE PMC *logical_or(PMC *value, PMC *dest) {
-        if (SELF.get_bool())
-            return SELF;
-
-        return value;
-    }
-
-/*
-
-=item C< PMC *logical_and(PMC *value, PMC *dest)>
-
-Returns the result of the logical C<AND> of C<SELF> and C<value>, i.e.
-returns C<value> if C<SELF> is true else C<SELF>. C<dest> is always ignored.
-
-=cut
-
-*/
-
-    VTABLE PMC *logical_and(PMC *value, PMC *dest) {
-        if (SELF.get_bool())
-            return value;
-
-        return SELF;
-    }
-
-/*
-
-=item C<PMC *logical_xor(PMC *value, PMC *dest)>
-
-Returns the result of the logical C<XOR> of C<SELF> and C<*value>.
-
-=cut
-
-*/
-
-    VTABLE PMC *logical_xor(PMC *value, PMC *dest) {
-        const INTVAL my_bool    = SELF.get_bool();
-        const INTVAL value_bool = VTABLE_get_bool(INTERP, value);
-
-        if (my_bool && ! value_bool)
-            return SELF;
-        else if (value_bool && ! my_bool)
-            return value;
-
-        dest = Parrot_pmc_new(INTERP, VTABLE_type(INTERP, SELF));
-        VTABLE_set_bool(INTERP, dest, 0);
-        return dest;
-    }
-
-/*
-
-=item C<PMC *logical_not(PMC *dest)>
-
-=item C<void i_logical_not()>
-
-Returns in C<*dest> the result of the logical negation of the scalar and
-C<*value>.
-
-=cut
-
-*/
-
-    VTABLE PMC *logical_not(PMC *dest) {
-        const INTVAL a = ! SELF.get_bool();
-
-        dest = Parrot_pmc_new(INTERP, VTABLE_type(INTERP, SELF));
-
-        VTABLE_set_bool(INTERP, dest, a);
-        return dest;
-    }
-
-    VTABLE void i_logical_not() {
-        VTABLE_set_bool(INTERP, SELF, ! SELF.get_bool());
-    }
-
-/*
-
 =item C<INTVAL defined()>
 
 Always returns true.

Modified: branches/gc_massacre/src/pmc/undef.pmc
==============================================================================
--- branches/gc_massacre/src/pmc/undef.pmc	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/pmc/undef.pmc	Sun Sep 19 08:27:37 2010	(r49153)
@@ -212,22 +212,6 @@
 
 /*
 
-=item C<INTVAL logical_not()>
-
-Returns 1.
-
-=cut
-
-*/
-
-    VTABLE PMC *logical_not(PMC *dest) {
-        dest = Parrot_pmc_new(INTERP, VTABLE_type(INTERP, SELF));
-        VTABLE_set_bool(INTERP, dest, 1);
-        return dest;
-    }
-
-/*
-
 =item C<void share()>
 
 Unknown. (TODO)

Modified: branches/gc_massacre/src/string/api.c
==============================================================================
--- branches/gc_massacre/src/string/api.c	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/string/api.c	Sun Sep 19 08:27:37 2010	(r49153)
@@ -23,6 +23,8 @@
 
 */
 
+#include <stdio.h>
+
 #include "parrot/parrot.h"
 #include "private_cstring.h"
 #include "api.str"
@@ -382,6 +384,9 @@
     /* Clear live flag. It might be set on constant strings */
     PObj_live_CLEAR(d);
 
+    /* Set the string copy flag */
+    PObj_is_string_copy_SET(d);
+
     /* Now check that buffer allocated from pool and affected by compacting */
     if (is_movable && Buffer_bufstart(s)) {
         /* If so, mark it as shared */
@@ -455,16 +460,43 @@
     /* calc usable and total bytes */
     total_length = a->bufused + b->bufused;
 
-    dest = Parrot_str_new_noinit(interp, total_length);
-    PARROT_ASSERT(enc);
-    dest->encoding = enc;
+    if (PObj_is_growable_TESTALL(a)
+    &&  a->strstart + total_length <=
+        (char *)Buffer_bufstart(a) + Buffer_buflen(a)) {
+        /* String a is growable and there's enough space in the buffer */
+        DECL_CONST_CAST;
 
-    /* Copy A first */
-    mem_sys_memcopy(dest->strstart, a->strstart, a->bufused);
+        dest = Parrot_str_copy(interp, a);
 
-    /* Tack B on the end of A */
-    mem_sys_memcopy((void *)((ptrcast_t)dest->strstart + a->bufused),
-            b->strstart, b->bufused);
+        /* Switch string copy flags */
+        PObj_is_string_copy_SET(PARROT_const_cast(STRING *, a));
+        PObj_is_string_copy_CLEAR(dest);
+
+        /* Append b */
+        mem_sys_memcopy(dest->strstart + dest->bufused,
+                b->strstart, b->bufused);
+
+        dest->encoding = enc;
+        dest->hashval = 0;
+    }
+    else {
+        if (4 * b->bufused < a->bufused) {
+            /* Preallocate more memory if we're appending a short string to
+               a long string */
+            total_length += total_length >> 1;
+        }
+
+        dest = Parrot_str_new_noinit(interp, total_length);
+        PARROT_ASSERT(enc);
+        dest->encoding = enc;
+
+        /* Copy A first */
+        mem_sys_memcopy(dest->strstart, a->strstart, a->bufused);
+
+        /* Tack B on the end of A */
+        mem_sys_memcopy((void *)((ptrcast_t)dest->strstart + a->bufused),
+                b->strstart, b->bufused);
+    }
 
     dest->bufused = a->bufused + b->bufused;
     dest->strlen  = a->strlen + b->strlen;
@@ -1860,59 +1892,34 @@
         int                 sign      = 1;
         UINTVAL             i         = 0;
         String_iter         iter;
-        number_parse_state  state = parse_start;
+        INTVAL              count = (INTVAL)s->strlen;
+        UINTVAL             c;
 
         STRING_ITER_INIT(interp, &iter);
 
-        while (state != parse_end && iter.charpos < s->strlen) {
-            const UINTVAL c = STRING_iter_get_and_advance(interp, s, &iter);
-            /* Check for overflow */
-            if (c > 255)
-                break;
-
-            switch (state) {
-              case parse_start:
-                if (isdigit((unsigned char)c)) {
-                    const UINTVAL nextval = c - '0';
-                    if (i < max_safe || (i == max_safe && nextval <= last_dig))
-                        i = i * 10 + nextval;
-                    else
-                        Parrot_ex_throw_from_c_args(interp, NULL,
-                            EXCEPTION_ERR_OVERFLOW,
-                            "Integer value of String '%S' too big", s);
-                    state = parse_before_dot;
-                }
-                else if (c == '-') {
-                    sign      = -1;
-                    state = parse_before_dot;
-                }
-                else if (c == '+')
-                    state = parse_before_dot;
-                else if (isspace((unsigned char)c))
-                    ; /* Do nothing */
-                else
-                    state = parse_end;
-
-                break;
-
-              case parse_before_dot:
-                if (isdigit((unsigned char)c)) {
-                    const UINTVAL nextval = c - '0';
-                    if (i < max_safe || (i == max_safe && nextval <= last_dig))
-                        i = i * 10 + nextval;
-                    else
-                        Parrot_ex_throw_from_c_args(interp, NULL,
-                            EXCEPTION_ERR_OVERFLOW,
-                            "Integer value of String '%S' too big", s);
-                }
-                else
-                    state = parse_end;
-                break;
-
-              default:
-                /* Pacify compiler */
+        c = count-- > 0 ? STRING_iter_get_and_advance(interp, s, &iter) : 0;
+        while (c == ' ')
+            c = count-- > 0 ? STRING_iter_get_and_advance(interp, s, &iter) : 0;
+        switch (c) {
+          case '-':
+            sign = -1;
+          case '+':
+            c = count-- > 0 ? STRING_iter_get_and_advance(interp, s, &iter) : 0;
+            break;
+          default:
+            ; /* nothing */
+        }
+        while (c) {
+            const UINTVAL nextval = c - (UINTVAL)'0';
+            if (nextval > 9)
                 break;
-            }
+            if (i < max_safe || (i == max_safe && nextval <= last_dig))
+                i = i * 10 + nextval;
+            else
+                Parrot_ex_throw_from_c_args(interp, NULL,
+                    EXCEPTION_ERR_OVERFLOW,
+                    "Integer value of String '%S' too big", s);
+            c = count-- > 0 ? STRING_iter_get_and_advance(interp, s, &iter) : 0;
         }
 
         if (sign == 1 && i > (UINTVAL)PARROT_INTVAL_MAX)
@@ -2384,10 +2391,12 @@
         ARGIN_NULLOK(const STRING *src), UINTVAL limit)
 {
     ASSERT_ARGS(Parrot_str_escape_truncate)
-    STRING *result, *hex;
-    UINTVAL i, len, charlen;
-    String_iter iter;
-    unsigned char *dp;
+    STRING      *result;
+    UINTVAL      i, len, charlen;
+    String_iter  iter;
+    char         hex_buf[16];
+    int          hex_len;
+    char        *dp;
 
     if (STRING_IS_NULL(src))
         return STRINGNULL;
@@ -2409,18 +2418,19 @@
 
     /* more work TODO */
     STRING_ITER_INIT(interp, &iter);
-    dp = (unsigned char *)result->strstart;
+    dp = result->strstart;
 
     for (i = 0; len > 0; --len) {
-        UINTVAL c = STRING_iter_get_and_advance(interp, src, &iter);
+        unsigned c = STRING_iter_get_and_advance(interp, src, &iter);
         if (c < 0x7f) {
             /* process ASCII chars */
             if (i >= charlen - 2) {
                 /* resize - still len codepoints to go */
                 charlen += len * 2 + 16;
+                result->bufused = i;
                 Parrot_gc_reallocate_string_storage(interp, result, charlen);
                 /* start can change */
-                dp = (unsigned char *)result->strstart;
+                dp = result->strstart;
             }
             switch (c) {
               case '\\':
@@ -2462,28 +2472,34 @@
                 break;
             }
             if (c >= 0x20) {
-                dp[i++]         = (unsigned char)c;
-                result->bufused = result->strlen = i;
+                dp[i++] = c;
                 continue;
             }
         }
 
         /* escape by appending either \uhhhh or \x{hh...} */
-        result->bufused = result->strlen = i;
 
         if (c < 0x0100 || c >= 0x10000)
-            hex = Parrot_sprintf_c(interp, "\\x{%x}", c);
+            hex_len = snprintf(hex_buf, 15, "\\x{%x}", c);
         else
-            hex = Parrot_sprintf_c(interp, "\\u%04x", c);
+            hex_len = snprintf(hex_buf, 15, "\\u%04x", c);
 
-        result = Parrot_str_concat(interp, result, hex);
+        if (hex_len < 0)
+            hex_len = 0;
 
-        /* adjust our insert idx */
-        i += hex->strlen;
+        if (i + hex_len > charlen) {
+            /* resize - still len codepoints to go */
+            charlen += len * 2 + 16;
+            result->bufused = i;
+            Parrot_gc_reallocate_string_storage(interp, result, charlen);
+            /* start can change */
+            dp = result->strstart;
+        }
 
-        /* and usable len */
-        charlen = Buffer_buflen(result);
-        dp      = (unsigned char *)result->strstart;
+        mem_sys_memcopy(dp + i, hex_buf, hex_len);
+
+        /* adjust our insert idx */
+        i += hex_len;
 
         PARROT_ASSERT(i <= charlen);
     }

Modified: branches/gc_massacre/src/vtable.tbl
==============================================================================
--- branches/gc_massacre/src/vtable.tbl	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/src/vtable.tbl	Sun Sep 19 08:27:37 2010	(r49153)
@@ -192,16 +192,6 @@
 INTVAL cmp_string(PMC* value)
 PMC* cmp_pmc(PMC* value)
 
-PMC* logical_or(PMC* value, PMC* dest)
-
-PMC* logical_and(PMC* value, PMC* dest)
-
-PMC* logical_xor(PMC* value, PMC* dest)
-
-PMC* logical_not(PMC* dest)
-void i_logical_not() :write
-
-
 [STRING]
 PMC* concatenate(PMC* value, PMC* dest)
 PMC* concatenate_str(STRING* value, PMC* dest)

Modified: branches/gc_massacre/t/harness.pir
==============================================================================
--- branches/gc_massacre/t/harness.pir	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/t/harness.pir	Sun Sep 19 08:27:37 2010	(r49153)
@@ -353,7 +353,7 @@
     push contents, 'username'
     push contents, 'parrot-autobot'
     push contents, 'password'
-    push contents, 'squ at wk'
+    push contents, 'qa_rocks'
     push contents, 'comments'
     push contents, "EXPERIMENTAL t/harness.pir with LWP.pir"
     push contents, 'report_file'
@@ -362,7 +362,7 @@
     $P0[0] = 'parrot_test_run.tar.gz'
     push contents, $P0
     load_bytecode 'LWP/UserAgent.pir'
-    .const string url = 'http://smolder.plusthree.com/app/projects/process_add_report/8'
+    .const string url = 'http://smolder.parrot.org/app/projects/process_add_report/1'
     .local pmc ua, response
     ua = new ['LWP';'UserAgent']
     ua.'env_proxy'()

Modified: branches/gc_massacre/t/library/archive_zip.t
==============================================================================
--- branches/gc_massacre/t/library/archive_zip.t	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/t/library/archive_zip.t	Sun Sep 19 08:27:37 2010	(r49153)
@@ -18,12 +18,23 @@
 
 .sub 'main' :main
     .include 'test_more.pir'
+    .include 'iglobals.pasm'
+    .local pmc config_hash, interp
 
-    load_bytecode 'Archive/Zip.pir'
+    interp = getinterp
+    config_hash = interp[.IGLOBALS_CONFIG_HASH]
+    $S0 = config_hash['has_zlib']
+    unless $S0 goto no_zlib
 
     plan(14)
+    load_bytecode 'Archive/Zip.pir'
     test_new()
     test_pack()
+    .return()
+
+  no_zlib:
+    skip_all('No zlib library available')
+    .return()
 .end
 
 .sub 'test_new'

Modified: branches/gc_massacre/t/native_pbc/integer_4.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: branches/gc_massacre/t/native_pbc/number_4.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: branches/gc_massacre/t/native_pbc/string_4.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: branches/gc_massacre/t/op/string_cs.t
==============================================================================
--- branches/gc_massacre/t/op/string_cs.t	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/t/op/string_cs.t	Sun Sep 19 08:27:37 2010	(r49153)
@@ -6,7 +6,7 @@
 use warnings;
 use lib qw( . lib ../lib ../../lib );
 use Test::More;
-use Parrot::Test tests => 49;
+use Parrot::Test tests => 50;
 use Parrot::Config;
 
 =head1 NAME
@@ -480,8 +480,109 @@
 abcdefg
 OUTPUT
 
+pir_output_is( <<'CODE', <<OUTPUT, "concat ascii, utf8 preallocated" );
+.sub main
+    .local string s, t
+    s = repeat "abcd", 100
+    t = "efg"
+    s = s . t
+    s = s . t
+    s = s . t
+    s = s . t
+    t = utf8:"hi\xa9jk"
+    s = s . t
+    $I0 = encoding s
+    $S0 = encodingname $I0
+    print $S0
+    print "\n"
+    $I0 = length s
+    print $I0
+    print "\n"
+    s = substr s, -21
+    print s
+    print "\n"
+.end
+CODE
+utf8
+417
+abcdefgefgefgefghi\xc2\xa9jk
+OUTPUT
+
 SKIP: {
-    skip( 'no ICU lib', 17 ) unless $PConfig{has_icu};
+    skip( 'no ICU lib', 19 ) unless $PConfig{has_icu};
+
+    pir_output_is( <<'CODE', <<OUTPUT, "literal encoding persistence - TT #468" );
+.include 'stdio.pasm'
+.sub main
+    # set output encoding to normalize printed strings
+    $P0 = getinterp
+    $P1 = $P0.'stdhandle'(.PIO_STDOUT_FILENO)
+    $P1.'encoding'('utf8')
+
+    load_bytecode 't/op/testlib/test_strings.pbc'
+    $P0 = 'get_hellos'()
+    $P1 = iter $P0
+
+  loop:
+    unless $P1 goto end_loop
+    $S0 = shift $P1
+    show($S0)
+    goto loop
+  end_loop:
+.end
+
+.sub show
+    .param string s
+    print s
+    $I0 = bytelength s
+    print '('
+    print $I0
+    print "): "
+    $I0 = encoding s
+    $S0 = encodingname $I0
+    say $S0
+.end
+CODE
+hello(5): ascii
+hello(5): utf8
+hello(5): utf8
+hello(10): utf16
+hello(10): ucs2
+OUTPUT
+
+    pir_output_is( <<'CODE', <<OUTPUT, "empty literal encoding persistence - TT #1791");
+.sub main
+    load_bytecode 't/op/testlib/test_strings.pbc'
+    $P0 = 'get_empties'()
+    $P1 = iter $P0
+
+  loop:
+    unless $P1 goto end_loop
+    $S0 = shift $P1
+    show($S0)
+    goto loop
+  end_loop:
+.end
+
+.sub show
+    .param string s
+    print s
+    $I0 = bytelength s
+    print '('
+    print $I0
+    print "): "
+    $I0 = encoding s
+    $S0 = encodingname $I0
+    say $S0
+.end
+CODE
+(0): ascii
+(0): utf8
+(0): utf8
+(0): utf16
+(0): ucs2
+OUTPUT
+
     pir_output_is( <<'CODE', <<"OUTPUT", "unicode downcase" );
 .sub main :main
     set $S0, iso-8859-1:"TÖTSCH"

Modified: branches/gc_massacre/t/tools/parrot_debugger.t
==============================================================================
--- branches/gc_massacre/t/tools/parrot_debugger.t	Sun Sep 19 08:04:17 2010	(r49152)
+++ branches/gc_massacre/t/tools/parrot_debugger.t	Sun Sep 19 08:27:37 2010	(r49153)
@@ -45,6 +45,8 @@
         plan skip_all => "parrot_debugger hasn't been built. Run make parrot_utils";
         exit(0);
     }
+    plan skip_all => "parrot_debugger changes have rendered these tests obsolete.";
+    exit(0);
 }
 
 my $tests = 0;
@@ -99,12 +101,15 @@
     \$I1 = 242
 .end
 PIR
+
 pdb_output_like( <<PASM, "pasm", "s", qr/current instr.: '\(null\)'/, 'show stack (pasm)');
     set I1, 242
 PASM
+
 pdb_output_like( <<PASM, "pasm", "info", qr/Total memory allocated =/, 'info (pasm)');
     set I1, 242
 PASM
+
 pdb_output_like( <<PASM, "pasm", "b", qr/Breakpoint 1 at.*pos 0/, 'set breakpoint');
     set I1, 242
 PASM


More information about the parrot-commits mailing list