static inline void verify_o( pvm_object_t o ) { if( o.data ) { verify_p( o.data ); verify_p( o.interface ); } }
void pvm_set_field( struct pvm_object_storage *o, unsigned int slot, struct pvm_object value ) { verify_p(o); verify_o(value); if( PHANTOM_OBJECT_STORAGE_FLAG_IS_INTERNAL & (o->_flags) ) { if( PHANTOM_OBJECT_STORAGE_FLAG_IS_RESIZEABLE & (o->_flags) ) { pvm_set_array_ofield( o, slot, value ); return; } pvm_exec_panic( "attempt to save to internal" ); } if( PHANTOM_OBJECT_STORAGE_FLAG_IS_IMMUTABLE & (o->_flags) ) pvm_exec_panic( "attempt to set_field for immutable" ); if( slot >= da_po_limit(o) ) { pvm_exec_panic( "load: slot index out of bounds" ); } if(da_po_ptr(o->da)[slot].data) ref_dec_o(da_po_ptr(o->da)[slot]); //decr old value da_po_ptr(o->da)[slot] = value; }
void pvm_pop_array(struct pvm_object_storage *array, struct pvm_object value_to_pop ) { struct data_area_4_array *da = (struct data_area_4_array *)&(array->da); verify_p(array); if( !(PHANTOM_OBJECT_STORAGE_FLAG_IS_INTERNAL & (array->_flags) ) || !( PHANTOM_OBJECT_STORAGE_FLAG_IS_RESIZEABLE & (array->_flags) ) ) pvm_exec_panic( "attempt to do an array op to non-array" ); if( PHANTOM_OBJECT_STORAGE_FLAG_IS_IMMUTABLE & (array->_flags) ) pvm_exec_panic( "attempt to pop_array for immutable" ); //swap with last and decrement used_slots struct pvm_object *p = da_po_ptr((da->page.data)->da); unsigned int slot; for( slot = 0; slot < da->used_slots; slot++ ) { if ( ( p[slot] ).data == value_to_pop.data ) //please don't leak refcnt { if (slot != da->used_slots-1) { p[slot] = p[da->used_slots-1]; } da->used_slots--; return; } } pvm_exec_panic( "attempt to remove non existing element from array" ); }
void memcpy_bug() { S *s; double *p = getP(0); if (p) { int intSptr[sizeof(S*)/sizeof(int)]; unsigned i = 0; for (i = 0; i < sizeof(intSptr)/sizeof(*intSptr); ++i) { intSptr[i] = (int) p[i]; } memcpy(&s, intSptr, sizeof(intSptr)); (s)->u.f1 = p; verify_p((s)->u.f1); } else { s = getS(); } verify_p(s->u.f1); }
struct pvm_object pvm_get_array_ofield(struct pvm_object_storage *o, unsigned int slot ) { verify_p(o); if( !(PHANTOM_OBJECT_STORAGE_FLAG_IS_INTERNAL & (o->_flags) ) || !( PHANTOM_OBJECT_STORAGE_FLAG_IS_RESIZEABLE & (o->_flags) ) ) pvm_exec_panic( "attempt to do an array op to non-array" ); struct data_area_4_array *da = (struct data_area_4_array *)&(o->da); if( slot >= da->used_slots ) pvm_exec_panic( "load: array index out of bounds" ); return pvm_get_ofield( da->page, slot); }
// TODO need semaphores here void pvm_set_array_ofield(struct pvm_object_storage *o, unsigned int slot, struct pvm_object value ) { verify_p(o); verify_o(value); if( !(PHANTOM_OBJECT_STORAGE_FLAG_IS_INTERNAL & (o->_flags) ) || !( PHANTOM_OBJECT_STORAGE_FLAG_IS_RESIZEABLE & (o->_flags) ) ) pvm_exec_panic( "attempt to do an array op to non-array" ); if( PHANTOM_OBJECT_STORAGE_FLAG_IS_IMMUTABLE & (o->_flags) ) pvm_exec_panic( "attempt to set_array_ofield for immutable" ); struct data_area_4_array *da = (struct data_area_4_array *)&(o->da); // need resize? if( pvm_is_null(da->page) || slot >= da->page_size ) { const int step = 1024; int new_page_size = slot < (step/2) ? (slot * 2) : (slot+step); if(new_page_size < 16) new_page_size = 16; if( (!pvm_is_null(da->page)) && da->page_size > 0 ) //da->page = pvm_object_storage::create_page( new_page_size, da->page.data()->da_po_ptr(), da->page_size ); da->page = pvm_create_page_object( new_page_size, (void *)&(da->page.data->da), da->page_size ); else da->page = pvm_create_page_object( new_page_size, 0, 0 ); da->page_size = new_page_size; } if( slot >= da->used_slots ) { // set to null all new slots except for indexed //for( int i = da->used_slots; i < index; i++ ) //da->page.save(i, pvm_object()); da->used_slots = slot+1; } pvm_set_ofield( da->page, slot, value ); }
// TODO BUG XXX - races possible, see below struct pvm_object pvm_get_field( struct pvm_object_storage *o, unsigned int slot ) { verify_p(o); if( PHANTOM_OBJECT_STORAGE_FLAG_IS_INTERNAL & (o->_flags) ) { if( PHANTOM_OBJECT_STORAGE_FLAG_IS_RESIZEABLE & (o->_flags) ) { return pvm_get_array_ofield( o, slot ); } pvm_exec_panic( "attempt to load from internal" ); } if( slot >= da_po_limit(o) ) { pvm_exec_panic( "save: slot index out of bounds" ); } verify_o(da_po_ptr(o->da)[slot]); return da_po_ptr(o->da)[slot]; }