vm: 'become' primitive needs to update literal references in code blocks
parent
ce5cf520b3
commit
94c93f0bc7
|
@ -6,7 +6,7 @@ io.streams.string kernel kernel.private math math.constants
|
|||
math.order namespaces parser parser.notes prettyprint
|
||||
quotations random see sequences sequences.private slots
|
||||
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
|
||||
|
||||
TUPLE: rect x y w h ;
|
||||
|
@ -765,3 +765,22 @@ USE: classes.struct
|
|||
[ "prototype" word-prop ] map
|
||||
[ '[ _ hashcode drop f ] [ drop t ] recover ] filter
|
||||
] 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
|
||||
|
|
|
@ -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
|
||||
to coalesce equal but distinct quotations and wrappers. */
|
||||
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 */
|
||||
slot_visitor<slot_become_visitor> workhorse(this,slot_become_visitor(&become_map));
|
||||
workhorse.visit_roots();
|
||||
workhorse.visit_contexts();
|
||||
{
|
||||
slot_visitor<slot_become_visitor> workhorse(this,slot_become_visitor(&become_map));
|
||||
workhorse.visit_roots();
|
||||
workhorse.visit_contexts();
|
||||
|
||||
object_become_visitor object_visitor(&workhorse);
|
||||
each_object(object_visitor);
|
||||
object_become_visitor object_visitor(&workhorse);
|
||||
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
|
||||
all objects on a minor GC. */
|
||||
all objects and code blocks on a minor GC. */
|
||||
data->mark_all_cards();
|
||||
primitive_minor_gc();
|
||||
|
||||
{
|
||||
code_block_write_barrier_visitor code_block_visitor(code);
|
||||
each_code_block(code_block_visitor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue