# New Ticket Created by François PERRAD
# Please include the string: [perl #49328]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=49328 >
I've isolated one problem between PBC loading and garbage collection.
(remember: on Lua, LuaFunction extends Sub, LuaClosure extends Closure)
$ cat outer.pir # a small script
.HLL 'Lua', 'lua_group'
.sub 'foo' :lex
print "foo\n"
.end
.sub 'bar' :lex :outer(foo) # closure
print "bar\n"
.end
.sub '__start' :main
print "__start\n"
sweep 1
bar()
foo()
.end
$ parrot outer.pir # With PIR, all is fine
init LuaFunction 6ca8c8
init LuaClosure 6ca8a8
init LuaFunction 6ca888
__start
mark LuaFunction 6ca888 __start
mark LuaFunction 6ca8c8 foo
mark LuaClosure 6ca8a8 bar
outer: 6ca8c8 foo
bar
foo
destroy LuaFunction 6ca888 __start
destroy LuaClosure 6ca8a8 bar
destroy LuaFunction 6ca8c8 foo
$ parrot -o outer.pbc outer.pir
...
$ parrot outer.pbc # Now, the problem
init LuaFunction 6ca568
init LuaClosure 6ca4c8
init LuaFunction 6ca4a8
init LuaFunction 6ca408
__start
mark LuaFunction 6ca408 __start
mark LuaFunction 6ca568 foo
mark LuaClosure 6ca4c8 bar
outer: 6ca568 foo
destroy LuaFunction 6ca4a8 foo
bar
foo
destroy LuaFunction 6ca408 __start
destroy LuaClosure 6ca4c8 bar
destroy LuaFunction 6ca568 foo
During the PBC loading, 'foo' is created two times :
- first as the outer of LuaClosure 'bar' (6ca568)
- second as the LuaFunction 'foo' (6ca4a8)
During the mark stage, only one is marked (the outer one),
so the second is destroyed.
With the full implementation of Lua, this behavior causes a crash
when 'foo' is called because the call references the instance that
is really destroyed (and/or its memory is reused ?).
(without specific HLL, the behavior is same with Sub & Closure).
Francois.
NB: attached files :
- outer.pir
- a patch for Lua PMC instrumentation
.HLL 'Lua', 'lua_group'
.sub 'foo' :lex
print "foo\n"
.end
.sub 'bar' :lex :outer(foo)
print "bar\n"
.end
.sub '__start' :main
print "__start\n"
sweep 1
bar()
foo()
.end
Index: languages/lua/pmc/luaclosure.pmc
===================================================================
--- languages/lua/pmc/luaclosure.pmc (revision 24441)
+++ languages/lua/pmc/luaclosure.pmc (working copy)
@@ -36,6 +36,17 @@
hll Lua
maps Closure {
+ void init() {
+ PIO_eprintf(INTERP, "\tinit LuaClosure %p\n", SELF);
+ SUPER();
+ }
+
+ void destroy() {
+ const Parrot_sub * const sub = PMC_sub(SELF);
+ PIO_eprintf(INTERP, "\tdestroy LuaClosure %p %s\n", SELF, Parrot_string_cstring(INTERP, sub->name));
+ SUPER();
+ }
+
/*
=item C<void init_pmc(PMC *sub)>
@@ -44,6 +55,7 @@
*/
void init_pmc(PMC* sub) {
+ PIO_eprintf(INTERP, "\tinit_pmc LuaCLosure %p\n", SELF);
if (VTABLE_isa(INTERP, sub, const_string(INTERP, "Closure"))) {
PMC_struct_val(SELF) = mem_allocate_typed(struct Parrot_sub);
PMC_pmc_val(SELF) = PMCNULL;
@@ -68,6 +80,10 @@
*/
void mark() {
+ const Parrot_sub * const sub = PMC_sub(SELF);
+ PMC *outer_sub = sub->outer_sub;
+ PIO_eprintf(INTERP, "\tmark LuaClosure %p %s\n", SELF, Parrot_string_cstring(INTERP, sub->name));
+ PIO_eprintf(INTERP, "\t\touter: %p %s\n", outer_sub, Parrot_string_cstring(INTERP, PMC_sub(sub->outer_sub)->name));
SUPER();
if (PMC_metadata(SELF))
pobject_lives(INTERP, (PObj *)PMC_metadata(SELF));
Index: languages/lua/pmc/luafunction.pmc
===================================================================
--- languages/lua/pmc/luafunction.pmc (revision 24441)
+++ languages/lua/pmc/luafunction.pmc (working copy)
@@ -37,6 +37,17 @@
hll Lua
maps Sub {
+ void init() {
+ PIO_eprintf(INTERP, "\tinit LuaFunction %p\n", SELF);
+ SUPER();
+ }
+
+ void destroy() {
+ const Parrot_sub * const sub = PMC_sub(SELF);
+ PIO_eprintf(INTERP, "\tdestroy LuaFunction %p %s\n", SELF, Parrot_string_cstring(INTERP, sub->name));
+ SUPER();
+ }
+
/*
=item C<void mark()>
@@ -47,6 +58,8 @@
*/
void mark() {
+ const Parrot_sub * const sub = PMC_sub(SELF);
+ PIO_eprintf(INTERP, "\tmark LuaFunction %p %s\n", SELF, Parrot_string_cstring(INTERP, sub->name));
SUPER();
if (PMC_metadata(SELF))
pobject_lives(INTERP, (PObj *)PMC_metadata(SELF));