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 combinators combinators.smart continuations fry generalizations
generic grouping io io.styles kernel make math math.parser generic grouping io io.styles kernel make math math.parser
math.statistics memory namespaces parser prettyprint sequences math.statistics memory namespaces parser prettyprint sequences
sorting specialized-arrays splitting strings system vm words ; sorting splitting strings system vm words ;
SPECIALIZED-ARRAY: gc-event
IN: tools.memory IN: tools.memory
<PRIVATE <PRIVATE
@ -101,7 +100,7 @@ SYMBOL: gc-events
: collect-gc-events ( quot -- ) : collect-gc-events ( quot -- )
enable-gc-events enable-gc-events
[ ] [ disable-gc-events drop ] cleanup [ ] [ 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 <PRIVATE

View File

@ -3,7 +3,6 @@
namespace factor namespace factor
{ {
/* make a new array with an initial element */
array *factor_vm::allot_array(cell capacity, cell fill_) array *factor_vm::allot_array(cell capacity, cell fill_)
{ {
data_root<object> fill(fill_,this); data_root<object> fill(fill_,this);
@ -12,12 +11,13 @@ array *factor_vm::allot_array(cell capacity, cell fill_)
return new_array; return new_array;
} }
/* push a new array on the stack */
void factor_vm::primitive_array() void factor_vm::primitive_array()
{ {
cell initial = dpop(); data_root<object> fill(dpop(),this);
cell size = unbox_array_size(); cell capacity = unbox_array_size();
dpush(tag<array>(allot_array(size,initial))); 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_) 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() 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(); 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_) 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() 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(); 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) 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) template<typename Type> byte_array *factor_vm::byte_array_from_value(Type *value)
{ {
return byte_array_from_values(value,1); byte_array *data = allot_uninitialized_array<byte_array>(sizeof(Type));
} memcpy(data->data<char>(),value,sizeof(Type));
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);
return data; return data;
} }

View File

@ -270,11 +270,25 @@ void factor_vm::primitive_disable_gc_events()
{ {
if(gc_events) if(gc_events)
{ {
byte_array *data = byte_array_from_values(&gc_events->front(),gc_events->size()); growable_array result(this);
dpush(tag<byte_array>(data));
delete gc_events; std::vector<gc_event> *gc_events = this->gc_events;
gc_events = NULL; 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 else
dpush(false_object); dpush(false_object);

View File

@ -157,9 +157,10 @@ string* factor_vm::reallot_string(string *str_, cell capacity)
void factor_vm::primitive_resize_string() 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(); 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() void factor_vm::primitive_string_nth()

View File

@ -374,7 +374,6 @@ struct factor_vm
void primitive_resize_byte_array(); void primitive_resize_byte_array();
template<typename Type> byte_array *byte_array_from_value(Type *value); 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 //tuples
void primitive_tuple(); void primitive_tuple();