Example #1
0
static void *wspace_alloc_normal_obj(Wspace *wspace, unsigned size, Allocator *allocator)
{
  Size_Segment *size_seg = wspace_get_size_seg(wspace, size);
  unsigned int seg_index = size_seg->seg_index;
  
  size = (unsigned int)NORMAL_SIZE_ROUNDUP(size, size_seg);
  unsigned int index = NORMAL_SIZE_TO_INDEX(size, size_seg);
  
  Chunk_Header *chunk = NULL;
  void *p_obj = NULL;
  
  if(size_seg->local_alloc){
    Chunk_Header **chunks = allocator->local_chunks[seg_index];
    chunk = chunks[index];
    if(!chunk){
      mutator_post_signal((Mutator*) allocator,HSIG_DISABLE_SWEEP_LOCAL_CHUNKS);
      chunk = wspace_get_pfc(wspace, seg_index, index);
      if(!chunk){
        chunk = (Chunk_Header*)wspace_get_normal_free_chunk(wspace);
        if(chunk) normal_chunk_init(chunk, size);
      }
      //if(!chunk) chunk = wspace_steal_pfc(wspace, seg_index, index);
      if(!chunk){
        mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_SAFE);
	 //INFO2("gc.wspace", "[Local Alloc Failed] alloc obj with size" << size << " bytes" );
        return NULL;
      }
      chunk->status |= CHUNK_IN_USE;
      chunks[index] = chunk;
      mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_SAFE);
    }    
    
    mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_ENTER_ALLOC_MARK);
    p_obj = alloc_in_chunk(chunks[index]);
    mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_SAFE);
    
    if(chunk->slot_index == MAX_SLOT_INDEX){
      chunk->status = CHUNK_USED | CHUNK_NORMAL;
      /*register to used chunk list.*/
      wspace_reg_used_chunk(wspace,chunk);
      chunks[index] = NULL;
    }
    
  } else {  
    mutator_post_signal((Mutator*) allocator,HSIG_DISABLE_SWEEP_GLOBAL_CHUNKS);

    if(gc_is_specify_con_sweep()){
      while(gc_is_sweep_global_normal_chunk()){
        mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_SAFE);
      }  
    }

    chunk = wspace_get_pfc(wspace, seg_index, index);
    if(!chunk){
      chunk = (Chunk_Header*)wspace_get_normal_free_chunk(wspace);
      if(chunk) normal_chunk_init(chunk, size);
    }
    //if(!chunk) chunk = wspace_steal_pfc(wspace, seg_index, index);
    if(!chunk) {
      mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_SAFE);
      //INFO2("gc.wspace", "[Non-Local Alloc Failed] alloc obj with size" << size << " bytes" );
      return NULL;
    }
    p_obj = alloc_in_chunk(chunk);

    if(chunk->slot_index == MAX_SLOT_INDEX){
      chunk->status = CHUNK_USED | CHUNK_NORMAL;
      /*register to used chunk list.*/
      wspace_reg_used_chunk(wspace,chunk);
      chunk = NULL;
    }
    
    if(chunk){
      wspace_put_pfc(wspace, chunk);
    }
    
    mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_SAFE);
  }
  if(p_obj) {
  	((Mutator*)allocator)->new_obj_occupied_size+=size;
  }
  return p_obj;
}
Example #2
0
/* Alloc small without-fin object in wspace without getting new free chunk */
void *wspace_thread_local_alloc(unsigned size, Allocator *allocator)
{
  if(size > LARGE_OBJ_THRESHOLD) return NULL;
  
  Wspace *wspace = gc_get_wspace(allocator->gc);
  
  /* Flexible alloc mechanism:
  Size_Segment *size_seg = wspace_get_size_seg(wspace, size);
  unsigned int seg_index = size_seg->seg_index;
  */
  unsigned int seg_index = (size-GC_OBJECT_ALIGNMENT) / MEDIUM_OBJ_THRESHOLD;
  assert(seg_index <= 2);
  Size_Segment *size_seg = wspace->size_segments[seg_index];
  assert(size_seg->local_alloc);
  
  size = (unsigned int)NORMAL_SIZE_ROUNDUP(size, size_seg);
  unsigned int index = NORMAL_SIZE_TO_INDEX(size, size_seg);
  
  Chunk_Header **chunks = allocator->local_chunks[seg_index];
  Chunk_Header *chunk = chunks[index];  
  if(!chunk){
    mutator_post_signal((Mutator*) allocator,HSIG_DISABLE_SWEEP_LOCAL_CHUNKS);
    
    chunk = wspace_get_pfc(wspace, seg_index, index);
    //if(!chunk) chunk = wspace_steal_pfc(wspace, seg_index, index);
    if(!chunk){
      mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_SAFE);
      return NULL;
    }
    chunk->status |= CHUNK_IN_USE;
    chunks[index] = chunk;
    
    mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_SAFE);
  }
  
  mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_ENTER_ALLOC_MARK);
  void *p_obj = alloc_in_chunk(chunks[index]);
  mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_SAFE);

  if(chunk->slot_index == MAX_SLOT_INDEX){
    chunk->status = CHUNK_USED | CHUNK_NORMAL;
    /*register to used chunk list.*/
    wspace_reg_used_chunk(wspace,chunk);
    chunks[index] = NULL;
    chunk = NULL;
  }
  
  assert(!chunk || chunk->slot_index <= chunk->alloc_num);
  assert(!chunk || chunk->slot_index < chunk->slot_num);
  assert(p_obj);

#ifdef SSPACE_ALLOC_INFO
  wspace_alloc_info(size);
#endif
#ifdef SSPACE_VERIFY
  wspace_verify_alloc(p_obj, size);
#endif
 if(p_obj) {
   ((Mutator*)allocator)->new_obj_occupied_size+=size;
 }
  return p_obj;
}
Example #3
0
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);
  }
}