[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