static void mspace_sliding_compact(Collector* collector, Mspace* mspace) { void *start_pos; while(Partial_Reveal_Object *p_obj = get_next_first_src_obj(mspace)) { Block_Header *src_block = GC_BLOCK_HEADER(p_obj); assert(src_block->dest_counter); Partial_Reveal_Object *p_target_obj = obj_get_fw_in_oi(p_obj); Block_Header *dest_block = GC_BLOCK_HEADER(p_target_obj); /* We don't set start_pos as p_obj in case that memmove of this obj may overlap itself. * In that case we can't get the correct vt and obj_info. */ #ifdef USE_32BITS_HASHCODE start_pos = obj_end_extend(p_obj); #else start_pos = obj_end(p_obj); #endif do { assert(obj_is_marked_in_vt(p_obj)); #ifdef USE_32BITS_HASHCODE obj_clear_dual_bits_in_vt(p_obj); #else obj_unmark_in_vt(p_obj); #endif unsigned int obj_size = (unsigned int)((POINTER_SIZE_INT)start_pos - (POINTER_SIZE_INT)p_obj); if(p_obj != p_target_obj) { assert((((POINTER_SIZE_INT)p_target_obj) % GC_OBJECT_ALIGNMENT) == 0); memmove(p_target_obj, p_obj, obj_size); } set_obj_info(p_target_obj, 0); p_obj = block_get_next_marked_obj_after_prefetch(src_block, &start_pos); if(!p_obj) break; p_target_obj = obj_get_fw_in_oi(p_obj); } while(GC_BLOCK_HEADER(p_target_obj) == dest_block); atomic_dec32(&src_block->dest_counter); } }
void lspace_sliding_compact(Collector* collector, Lspace* lspace) { unsigned int iterate_index = 0; Partial_Reveal_Object* p_obj; POINTER_SIZE_INT last_one=(POINTER_SIZE_INT) lspace->heap_start; p_obj = lspace_get_first_marked_object(lspace, &iterate_index); if(!LOS_ADJUST_BOUNDARY) lspace->last_surviving_size=0; if(!p_obj) return; while( p_obj ){ assert( obj_is_marked_in_vt(p_obj)); #ifdef USE_32BITS_HASHCODE obj_clear_dual_bits_in_vt(p_obj); #else obj_unmark_in_vt(p_obj); #endif unsigned int obj_size = vm_object_size(p_obj); #ifdef USE_32BITS_HASHCODE obj_size += (obj_is_sethash_in_vt(p_obj))?GC_OBJECT_ALIGNMENT:0; #endif Partial_Reveal_Object *p_target_obj = obj_get_fw_in_oi(p_obj); POINTER_SIZE_INT target_obj_end = (POINTER_SIZE_INT)p_target_obj + obj_size; last_one = target_obj_end; if( p_obj != p_target_obj){ memmove(p_target_obj, p_obj, obj_size); } set_obj_info(p_target_obj, 0); p_obj = lspace_get_next_marked_object(lspace, &iterate_index); } if(!LOS_ADJUST_BOUNDARY) lspace->last_surviving_size = ALIGN_UP_TO_KILO(last_one) - (POINTER_SIZE_INT) lspace->heap_start; return; }
void marshall_PackageStructurePtr(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { break; } case Marshall::ToVALUE: { KSharedPtr<Plasma::PackageStructure> *ptr = new KSharedPtr<Plasma::PackageStructure>(*(KSharedPtr<Plasma::PackageStructure>*)m->item().s_voidp); if (ptr == 0) { *(m->var()) = Qnil; break; } Plasma::PackageStructure * package = ptr->data(); VALUE obj = getPointerObject(package); if (obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = m->smoke()->idClass("Plasma::PackageStructure").index; o->ptr = package; o->allocated = false; obj = set_obj_info("Plasma::PackageStructure", o); } *(m->var()) = obj; if (m->cleanup()) { } break; } default: m->unsupported(); break; } }
void marshall_QHashQStringQVariant(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE hash = *(m->var()); if (TYPE(hash) != T_HASH) { m->item().s_voidp = 0; break; } QHash<QString,QVariant> * map = new QHash<QString,QVariant>; // Convert the ruby hash to an array of key/value arrays VALUE temp = rb_funcall(hash, rb_intern("to_a"), 0); for (long i = 0; i < RARRAY_LEN(temp); i++) { VALUE key = rb_ary_entry(rb_ary_entry(temp, i), 0); VALUE value = rb_ary_entry(rb_ary_entry(temp, i), 1); smokeruby_object *o = value_obj_info(value); if (o == 0 || o->ptr == 0) { continue; } (*map)[QString(StringValuePtr(key))] = (QVariant)*(QVariant*)o->ptr; } m->item().s_voidp = map; m->next(); if(m->cleanup()) delete map; } break; case Marshall::ToVALUE: { QHash<QString,QVariant> *map = (QHash<QString,QVariant>*)m->item().s_voidp; if (!map) { *(m->var()) = Qnil; break; } VALUE hv = rb_hash_new(); QHash<QString,QVariant>::Iterator it; for (it = map->begin(); it != map->end(); ++it) { void *p = new QVariant(it.value()); VALUE obj = getPointerObject(p); if (obj == Qnil) { smokeruby_object * o = alloc_smokeruby_object( true, qtcore_Smoke, qtcore_Smoke->idClass("QVariant").index, p ); obj = set_obj_info("Qt::Variant", o); } rb_hash_aset(hv, rb_str_new2(((QString*)&(it.key()))->toLatin1()), obj); } *(m->var()) = hv; m->next(); // if(m->cleanup()) // delete map; } break; default: m->unsupported(); break; } }
static inline void move_obj_between_chunks(Wspace *wspace, Chunk_Header **dest_ptr, Chunk_Header *src) { Chunk_Header *dest = *dest_ptr; assert(dest->slot_size == src->slot_size); unsigned int slot_size = dest->slot_size; unsigned int alloc_num = src->alloc_num; assert(alloc_num); #ifdef USE_32BITS_HASHCODE Hashcode_Buf* old_hashcode_buf = src->hashcode_buf; Hashcode_Buf* new_hashcode_buf = dest->hashcode_buf; #endif while(alloc_num && dest){ Partial_Reveal_Object *p_obj = next_alloc_slot_in_chunk(src); Partial_Reveal_Object *target = (Partial_Reveal_Object *)alloc_in_chunk(dest); if(dest->slot_index == MAX_SLOT_INDEX){ dest->status = CHUNK_USED | CHUNK_NORMAL; wspace_reg_used_chunk(wspace,dest); dest = NULL; } assert(p_obj && target); memcpy(target, p_obj, slot_size); #ifdef USE_32BITS_HASHCODE if(hashcode_is_set(p_obj)){ int hashcode; if(new_hashcode_buf == NULL) { new_hashcode_buf = hashcode_buf_create(); hashcode_buf_init(new_hashcode_buf); dest->hashcode_buf = new_hashcode_buf; } if(hashcode_is_buffered(p_obj)){ /*already buffered objects;*/ hashcode = hashcode_buf_lookup(p_obj, old_hashcode_buf); hashcode_buf_update(target, hashcode, new_hashcode_buf); }else{ /*objects need buffering.*/ hashcode = hashcode_gen(p_obj); hashcode_buf_update(target, hashcode, new_hashcode_buf); Obj_Info_Type oi = get_obj_info_raw(target); set_obj_info(target, oi | HASHCODE_BUFFERED_BIT); } } #endif #ifdef SSPACE_VERIFY wspace_modify_mark_in_compact(target, p_obj, slot_size); #endif obj_set_fw_in_oi(p_obj, target); --alloc_num; } #ifdef USE_32BITS_HASHCODE if(alloc_num == 0) { if(old_hashcode_buf) hashcode_buf_destory(old_hashcode_buf); src->hashcode_buf = NULL; } #endif /* dest might be set to NULL, so we use *dest_ptr here */ assert((*dest_ptr)->alloc_num <= (*dest_ptr)->slot_num); src->alloc_num = alloc_num; if(!dest){ assert((*dest_ptr)->alloc_num == (*dest_ptr)->slot_num); *dest_ptr = NULL; clear_free_slot_in_table(src->table, src->slot_index); } }