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
parent
41c17f0429
commit
2c8f67851e
|
@ -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
|
||||
|
||||
|
|
|
@ -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_)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
22
vm/gc.cpp
22
vm/gc.cpp
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue