vm: fix GC safety issue in callers of unbox_array_size(), and change how disable-gc-events works so that it doesn't make a byte array that's too large

db4
Slava Pestov 2009-11-11 05:21:03 -06:00
parent 41c17f0429
commit 2c8f67851e
7 changed files with 36 additions and 27 deletions

View File

@ -4,8 +4,7 @@ USING: accessors arrays assocs classes classes.struct
combinators combinators.smart continuations fry generalizations
generic grouping io io.styles kernel make math math.parser
math.statistics memory namespaces parser prettyprint sequences
sorting specialized-arrays splitting strings system vm words ;
SPECIALIZED-ARRAY: gc-event
sorting splitting strings system vm words ;
IN: tools.memory
<PRIVATE
@ -101,7 +100,7 @@ SYMBOL: gc-events
: collect-gc-events ( quot -- )
enable-gc-events
[ ] [ disable-gc-events drop ] cleanup
disable-gc-events byte-array>gc-event-array gc-events set ; inline
disable-gc-events [ gc-event memory>struct ] map gc-events set ; inline
<PRIVATE

View File

@ -3,7 +3,6 @@
namespace factor
{
/* make a new array with an initial element */
array *factor_vm::allot_array(cell capacity, cell fill_)
{
data_root<object> fill(fill_,this);
@ -12,12 +11,13 @@ array *factor_vm::allot_array(cell capacity, cell fill_)
return new_array;
}
/* push a new array on the stack */
void factor_vm::primitive_array()
{
cell initial = dpop();
cell size = unbox_array_size();
dpush(tag<array>(allot_array(size,initial)));
data_root<object> fill(dpop(),this);
cell capacity = unbox_array_size();
array *new_array = allot_uninitialized_array<array>(capacity);
memset_cell(new_array->data(),fill.value(),capacity * sizeof(cell));
dpush(tag<array>(new_array));
}
cell factor_vm::allot_array_1(cell obj_)
@ -54,9 +54,10 @@ cell factor_vm::allot_array_4(cell v1_, cell v2_, cell v3_, cell v4_)
void factor_vm::primitive_resize_array()
{
array *a = untag_check<array>(dpop());
data_root<array> a(dpop(),this);
a.untag_check(this);
cell capacity = unbox_array_size();
dpush(tag<array>(reallot_array(a,capacity)));
dpush(tag<array>(reallot_array(a.untagged(),capacity)));
}
void growable_array::add(cell elt_)

View File

@ -24,9 +24,10 @@ void factor_vm::primitive_uninitialized_byte_array()
void factor_vm::primitive_resize_byte_array()
{
byte_array *array = untag_check<byte_array>(dpop());
data_root<byte_array> array(dpop(),this);
array.untag_check(this);
cell capacity = unbox_array_size();
dpush(tag<byte_array>(reallot_array(array,capacity)));
dpush(tag<byte_array>(reallot_array(array.untagged(),capacity)));
}
void growable_byte_array::append_bytes(void *elts, cell len)

View File

@ -15,14 +15,8 @@ struct growable_byte_array {
template<typename Type> byte_array *factor_vm::byte_array_from_value(Type *value)
{
return byte_array_from_values(value,1);
}
template<typename Type> byte_array *factor_vm::byte_array_from_values(Type *values, cell len)
{
cell size = sizeof(Type) * len;
byte_array *data = allot_uninitialized_array<byte_array>(size);
memcpy(data->data<char>(),values,size);
byte_array *data = allot_uninitialized_array<byte_array>(sizeof(Type));
memcpy(data->data<char>(),value,sizeof(Type));
return data;
}

View File

@ -270,11 +270,25 @@ void factor_vm::primitive_disable_gc_events()
{
if(gc_events)
{
byte_array *data = byte_array_from_values(&gc_events->front(),gc_events->size());
dpush(tag<byte_array>(data));
growable_array result(this);
delete gc_events;
gc_events = NULL;
std::vector<gc_event> *gc_events = this->gc_events;
this->gc_events = NULL;
std::vector<gc_event>::const_iterator iter = gc_events->begin();
std::vector<gc_event>::const_iterator end = gc_events->end();
for(; iter != end; iter++)
{
gc_event event = *iter;
byte_array *obj = byte_array_from_value(&event);
result.add(tag<byte_array>(obj));
}
result.trim();
dpush(result.elements.value());
delete this->gc_events;
}
else
dpush(false_object);

View File

@ -157,9 +157,10 @@ string* factor_vm::reallot_string(string *str_, cell capacity)
void factor_vm::primitive_resize_string()
{
string* str = untag_check<string>(dpop());
data_root<string> str(dpop(),this);
str.untag_check(this);
cell capacity = unbox_array_size();
dpush(tag<string>(reallot_string(str,capacity)));
dpush(tag<string>(reallot_string(str.untagged(),capacity)));
}
void factor_vm::primitive_string_nth()

View File

@ -374,7 +374,6 @@ struct factor_vm
void primitive_resize_byte_array();
template<typename Type> byte_array *byte_array_from_value(Type *value);
template<typename Type> byte_array *byte_array_from_values(Type *values, cell len);
//tuples
void primitive_tuple();