vm: 'become' primitive needs to update literal references in code blocks

db4
Slava Pestov 2010-01-27 18:42:31 +13:00
parent ce5cf520b3
commit 94c93f0bc7
2 changed files with 61 additions and 8 deletions

View File

@ -6,7 +6,7 @@ io.streams.string kernel kernel.private math math.constants
math.order namespaces parser parser.notes prettyprint math.order namespaces parser parser.notes prettyprint
quotations random see sequences sequences.private slots quotations random see sequences sequences.private slots
slots.private splitting strings summary threads tools.test slots.private splitting strings summary threads tools.test
vectors vocabs words words.symbol fry literals ; vectors vocabs words words.symbol fry literals memory ;
IN: classes.tuple.tests IN: classes.tuple.tests
TUPLE: rect x y w h ; TUPLE: rect x y w h ;
@ -765,3 +765,22 @@ USE: classes.struct
[ "prototype" word-prop ] map [ "prototype" word-prop ] map
[ '[ _ hashcode drop f ] [ drop t ] recover ] filter [ '[ _ hashcode drop f ] [ drop t ] recover ] filter
] unit-test ] unit-test
! Make sure that tuple reshaping updates code heap roots
TUPLE: code-heap-ref ;
: code-heap-ref' ( -- a ) T{ code-heap-ref } ;
! Push foo's literal to tenured space
[ ] [ gc ] unit-test
! Reshape!
[ ] [ "IN: classes.tuple.tests USE: math TUPLE: code-heap-ref { x integer initial: 5 } ;" eval( -- ) ] unit-test
! Code heap reference
[ t ] [ code-heap-ref' code-heap-ref? ] unit-test
[ 5 ] [ code-heap-ref' x>> ] unit-test
! Data heap reference
[ t ] [ \ code-heap-ref' def>> first code-heap-ref? ] unit-test
[ 5 ] [ \ code-heap-ref' def>> first x>> ] unit-test

View File

@ -110,6 +110,31 @@ struct object_become_visitor {
} }
}; };
struct code_block_become_visitor {
slot_visitor<slot_become_visitor> *workhorse;
explicit code_block_become_visitor(slot_visitor<slot_become_visitor> *workhorse_) :
workhorse(workhorse_) {}
void operator()(code_block *compiled, cell size)
{
workhorse->visit_code_block_objects(compiled);
workhorse->visit_embedded_literals(compiled);
}
};
struct code_block_write_barrier_visitor {
code_heap *code;
explicit code_block_write_barrier_visitor(code_heap *code_) :
code(code_) {}
void operator()(code_block *compiled, cell size)
{
code->write_barrier(compiled);
}
};
/* classes.tuple uses this to reshape tuples; tools.deploy.shaker uses this /* classes.tuple uses this to reshape tuples; tools.deploy.shaker uses this
to coalesce equal but distinct quotations and wrappers. */ to coalesce equal but distinct quotations and wrappers. */
void factor_vm::primitive_become() void factor_vm::primitive_become()
@ -134,17 +159,26 @@ void factor_vm::primitive_become()
} }
/* Update all references to old objects to point to new objects */ /* Update all references to old objects to point to new objects */
slot_visitor<slot_become_visitor> workhorse(this,slot_become_visitor(&become_map)); {
workhorse.visit_roots(); slot_visitor<slot_become_visitor> workhorse(this,slot_become_visitor(&become_map));
workhorse.visit_contexts(); workhorse.visit_roots();
workhorse.visit_contexts();
object_become_visitor object_visitor(&workhorse); object_become_visitor object_visitor(&workhorse);
each_object(object_visitor); each_object(object_visitor);
code_block_become_visitor code_block_visitor(&workhorse);
each_code_block(code_block_visitor);
}
/* Since we may have introduced old->new references, need to revisit /* Since we may have introduced old->new references, need to revisit
all objects on a minor GC. */ all objects and code blocks on a minor GC. */
data->mark_all_cards(); data->mark_all_cards();
primitive_minor_gc();
{
code_block_write_barrier_visitor code_block_visitor(code);
each_code_block(code_block_visitor);
}
} }
} }