Esempio n. 1
0
static inline Partial_Reveal_Object *get_next_first_src_obj(Mspace *mspace)
{
    Partial_Reveal_Object *first_src_obj;

    while(TRUE) {
        lock(current_dest_block.lock);
        Block_Header *next_dest_block = (Block_Header *)current_dest_block.block;

        if (!next_dest_block || !(first_src_obj = next_dest_block->src)) {
            next_dest_block = get_next_dest_block(mspace);
            if(!next_dest_block) {
                unlock(current_dest_block.lock);
                return NULL;
            } else if(next_dest_block == DEST_NOT_EMPTY) {
                unlock(current_dest_block.lock);
                while(check_dest_block(mspace)==DEST_NOT_EMPTY);
                continue;
            }
            first_src_obj = next_dest_block->src;
            if(next_dest_block->status == BLOCK_DEST) {
                assert(!next_dest_block->dest_counter);
                current_dest_block.block = next_dest_block;
            }
        }

        Partial_Reveal_Object *next_src_obj = GC_BLOCK_HEADER(first_src_obj)->next_src;
        if(next_src_obj && GC_BLOCK_HEADER(ref_to_obj_ptr((REF)get_obj_info_raw(next_src_obj))) != next_dest_block) {
            next_src_obj = NULL;
        }
        next_dest_block->src = next_src_obj;
        unlock(current_dest_block.lock);
        return first_src_obj;
    }
}
Esempio n. 2
0
static Block_Header *check_dest_block(Mspace *mspace)
{
    Block_Header *cur_dest_block;

    if(next_block_for_dest) {
        cur_dest_block = (Block_Header*)next_block_for_dest;
        while(cur_dest_block->status == BLOCK_DEST) {
            cur_dest_block = cur_dest_block->next;
        }
    } else {
        cur_dest_block = blocked_space_block_iterator_get((Blocked_Space*)mspace);
    }

    unsigned int total_dest_counter = 0;
    Block_Header *last_dest_block = (Block_Header *)last_block_for_dest;
    for(; cur_dest_block < last_dest_block; cur_dest_block = cur_dest_block->next) {
        if(cur_dest_block->status == BLOCK_DEST)
            continue;
        if(cur_dest_block->dest_counter == 0 && cur_dest_block->src) {
            return cur_dest_block;
        } else if(cur_dest_block->dest_counter == 1 && GC_BLOCK_HEADER(cur_dest_block->src) == cur_dest_block) {
            return cur_dest_block;
        } else if(cur_dest_block->dest_counter == 0 && !cur_dest_block->src) {
            cur_dest_block->status = BLOCK_DEST;
        } else {
            total_dest_counter += cur_dest_block->dest_counter;
        }
    }

    if(total_dest_counter) return DEST_NOT_EMPTY;
    return NULL;
}
Esempio n. 3
0
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);
    }

}
Esempio n. 4
0
static Block_Header *get_next_dest_block(Mspace *mspace)
{
    Block_Header *cur_dest_block;

    if(next_block_for_dest) {
        cur_dest_block = (Block_Header*)next_block_for_dest;
        while(cur_dest_block->status == BLOCK_DEST) {
            cur_dest_block = cur_dest_block->next;
            if(!cur_dest_block) break;
        }
        next_block_for_dest = cur_dest_block;
    } else {
        cur_dest_block = set_next_block_for_dest(mspace);
    }

    unsigned int total_dest_counter = 0;
    /*For LOS_Shrink: last_dest_block might point to a fake block*/
    Block_Header *last_dest_block =
        (Block_Header *)round_down_to_size((POINTER_SIZE_INT)(last_block_for_dest->base), GC_BLOCK_SIZE_BYTES);
    for(; cur_dest_block <= last_dest_block; cur_dest_block = cur_dest_block->next) {
        if(!cur_dest_block)  return NULL;
        if(cur_dest_block->status == BLOCK_DEST) {
            continue;
        }
        if(cur_dest_block->dest_counter == 0 && cur_dest_block->src) {
            cur_dest_block->status = BLOCK_DEST;
            return cur_dest_block;
        } else if(cur_dest_block->dest_counter == 1 && GC_BLOCK_HEADER(cur_dest_block->src) == cur_dest_block) {
            return cur_dest_block;
        } else if(cur_dest_block->dest_counter == 0 && !cur_dest_block->src) {
            cur_dest_block->status = BLOCK_DEST;
        } else {
            total_dest_counter += cur_dest_block->dest_counter;
        }
    }

    if(total_dest_counter)
        return DEST_NOT_EMPTY;

    return NULL;
}
Esempio n. 5
0
static FORCE_INLINE void scan_object(Heap_Verifier* heap_verifier, Partial_Reveal_Object *p_obj) 
{
  GC_Verifier* gc_verifier = heap_verifier->gc_verifier;

#if !defined(USE_UNIQUE_MARK_SWEEP_GC) && !defined(USE_UNIQUE_MOVE_COMPACT_GC)
  if(gc_verifier->is_before_fallback_collection) {
    if(obj_belongs_to_nos(p_obj) && obj_is_fw_in_oi(p_obj)){
      assert(obj_get_vt(p_obj) == obj_get_vt(obj_get_fw_in_oi(p_obj)));
      p_obj = obj_get_fw_in_oi(p_obj);
      assert(p_obj);
    }
  }
#endif
  
  if(!obj_mark_in_vt(p_obj)) return;

  if( !major_is_marksweep() && p_obj >= los_boundary ){
    Block_Header* block = GC_BLOCK_HEADER(p_obj);
    if( heap_verifier->is_before_gc)  block->num_live_objs++;
    /* we can't set block->num_live_objs = 0 if !is_before_gc, because the some blocks may be freed hence not
        visited after GC. So we should reset it in GC space reset functions. */
  }

  verify_object_header(p_obj, heap_verifier); 
  verifier_update_verify_info(p_obj, heap_verifier);

   /*FIXME: */
  if (!object_has_ref_field(p_obj)) return;
    
  REF* p_ref;

  if (object_is_array(p_obj)) {  
  
    Partial_Reveal_Array* array = (Partial_Reveal_Array*)p_obj;
    unsigned int array_length = array->array_len; 
    p_ref = (REF*)((POINTER_SIZE_INT)array + (int)array_first_element_offset(array));

    for (unsigned int i = 0; i < array_length; i++) {
      scan_slot(heap_verifier, p_ref+i);
    }   

  }else{ 
    
    unsigned int num_refs = object_ref_field_num(p_obj);
    int* ref_iterator = object_ref_iterator_init(p_obj);
 
    for(unsigned int i=0; i<num_refs; i++){  
      p_ref = object_ref_iterator_get(ref_iterator+i, p_obj);  
      scan_slot(heap_verifier, p_ref);
    }

#ifndef BUILD_IN_REFERENT
     WeakReferenceType type = special_reference_type(p_obj);
    if(type == SOFT_REFERENCE && verifier_collect_is_minor(gc_verifier)){
      p_ref = obj_get_referent_field(p_obj);
      scan_slot(heap_verifier, p_ref);
    } 
#endif  
  }
  return;
}