Example #1
0
/* SSA doesn't work well when there are dead paths */
static void removeDeadBlock(BLOCK *b)
{
    if (b->pred == NULL)
    {
        BLOCKLIST *bl = b->succ;
        while (bl)
        {
            unlinkBlock(bl->block, b);
            bl = bl->next;
        }
        if (b->head != b->tail && b->head->fwd != b->tail)
        {   QUAD *p = b->head->fwd;
            QUAD *q = b->tail->fwd;
            while (q != p)
            {
                if (p->dc.opcode != i_dbgblock && p->dc.opcode != i_dbgblockend 
                    && p->dc.opcode != i_var && p->dc.opcode != i_func)
                {
                    RemoveInstruction(p);
                }
                p = p->fwd;
            }
        }
    }
}
Example #2
0
/* SSA doesn't work well when there are dead paths */
static void removeDeadBlock(BLOCK *b)
{
    if (b->pred == NULL && !b->alwayslive)
    {
        BLOCKLIST *bl = b->succ;
        while (bl)
        {
            unlinkBlock(bl->block, b);
            bl = bl->next;
        }
		if (b->critical)
		{
			b->critical = FALSE;
			blockArray[b->blocknum] = 0;
		}
        if (b->head != b->tail && b->head->fwd != b->tail)
        {   QUAD *p = b->head->fwd;
            QUAD *q = b->tail->fwd;
            while (q != p)
            {
                if (p->dc.opcode != i_dbgblock && p->dc.opcode != i_dbgblockend 
                    && p->dc.opcode != i_var && p->dc.opcode != i_func && p->dc.opcode != i_label)
                {
                    RemoveInstruction(p);
                }
                p = p->fwd;
            }
        }
    }
}
Example #3
0
/* Split an existing free block into two pieces, and put the fragment
   (the second one along in memory) onto the relevant free list.
   req_bszW is the required size of the block which isn't the
   fragment. */
static
void splitChunk ( Arena* a, UInt* b, Int b_listno, UInt req_bszW )
{
   Int b_bszW, frag_bszW;
   b_bszW = mk_plain_bszW(get_bszW_lo(b));
   vg_assert(req_bszW < b_bszW);
   frag_bszW = b_bszW - req_bszW;
   vg_assert(frag_bszW >= overhead_szW(a));
   /*
   printf( "split %d into %d and %d\n", 
                   b_bszW,req_bszW,frag_bszW  );
   */
   vg_assert(bszW_to_pszW(a, frag_bszW) > 0);
   unlinkBlock(a, b, b_listno);
   mkInuseBlock(a, b, req_bszW);
   mkFreeBlock(a, &b[req_bszW], frag_bszW, 
                  pszW_to_listNo(bszW_to_pszW(a, frag_bszW)));
}
Example #4
0
void* VG_(arena_malloc) ( ArenaId aid, Int req_pszB )
{
   Int         req_pszW, req_bszW, frag_bszW, b_bszW, lno;
   Superblock* new_sb;
   Word*       b;
   Arena*      a;
   void*       v;

   VGP_PUSHCC(VgpMalloc);

   ensure_mm_init();
   a = arenaId_to_ArenaP(aid);

   vg_assert(req_pszB >= 0);
   vg_assert(req_pszB < 0x7FFFFFF0);

   req_pszW = req_pszB_to_req_pszW(req_pszB);

   /* Keep gcc -O happy: */
   b = NULL;

   /* Start searching at this list. */
   lno = pszW_to_listNo(req_pszW);

   /* This loop finds a list which has a block big enough, or sets
      req_listno to N_LISTS if no such block exists. */
   while (True) {
      if (lno == VG_N_MALLOC_LISTS) break;
      /* If this list is empty, try the next one. */
      if (a->freelist[lno] == NULL) {
         lno++;
         continue;
      }
      /* Scan a->list[lno] to find a big-enough chunk. */
      b = a->freelist[lno];
      b_bszW = mk_plain_bszW(get_bszW_lo(b));
      while (True) {
         if (bszW_to_pszW(a, b_bszW) >= req_pszW) break;
         b = get_next_p(b);
         b_bszW = mk_plain_bszW(get_bszW_lo(b));
         if (b == a->freelist[lno]) break;
      }
      if (bszW_to_pszW(a, b_bszW) >= req_pszW) break;
      /* No luck?  Try a larger list. */
      lno++;
   }

   /* Either lno < VG_N_MALLOC_LISTS and b points to the selected
      block, or lno == VG_N_MALLOC_LISTS, and we have to allocate a
      new superblock. */

   if (lno == VG_N_MALLOC_LISTS) {
      req_bszW = pszW_to_bszW(a, req_pszW);      
      new_sb = newSuperblock(a, req_bszW);
      if (NULL == new_sb) {
         // Should only fail if for client, otherwise, should have aborted
         // already.
         vg_assert(VG_AR_CLIENT == aid);
         return NULL;
      }
      new_sb->next = a->sblocks;
      a->sblocks = new_sb;
      b = &(new_sb->payload_words[0]);
      lno = pszW_to_listNo(bszW_to_pszW(a, new_sb->n_payload_words));
      mkFreeBlock ( a, b, new_sb->n_payload_words, lno);
   }

   /* Ok, we can allocate from b, which lives in list req_listno. */
   vg_assert(b != NULL);
   vg_assert(lno >= 0 && lno < VG_N_MALLOC_LISTS);
   vg_assert(a->freelist[lno] != NULL);
   b_bszW = mk_plain_bszW(get_bszW_lo(b));
   req_bszW = pszW_to_bszW(a, req_pszW);
   /* req_bszW is the size of the block we are after.  b_bszW is the
      size of what we've actually got. */
   vg_assert(b_bszW >= req_bszW);

   /* Could we split this block and still get a useful fragment?
      Where "useful" means that the payload size of the frag is at
      least one word.  */
   frag_bszW = b_bszW - req_bszW;
   if (frag_bszW > overhead_szW(a)) {
      splitChunk(a, b, lno, req_bszW);
   } else {
      /* No, mark as in use and use as-is. */
      unlinkBlock(a, b, lno);
      /*
      set_bszW_lo(b, mk_inuse_bszW(b_bszW));
      set_bszW_hi(b, mk_inuse_bszW(b_bszW));
      */
      mkInuseBlock(a, b, b_bszW);
   }
   vg_assert(req_bszW <= mk_plain_bszW(get_bszW_lo(b)));

   a->bytes_on_loan 
      += sizeof(Word) 
         * bszW_to_pszW(a, mk_plain_bszW(get_bszW_lo(b)));
   if (a->bytes_on_loan > a->bytes_on_loan_max)
      a->bytes_on_loan_max = a->bytes_on_loan;

#  ifdef DEBUG_MALLOC
   mallocSanityCheckArena(aid);
#  endif

   VGP_POPCC(VgpMalloc);
   v = first_to_payload(a, b);
   vg_assert( (((UInt)v) & 7) == 0 );
   return v;
}
Example #5
0
void VG_(arena_free) ( ArenaId aid, void* ptr )
{
   Superblock* sb;
   UInt*       sb_payl_firstw;
   UInt*       sb_payl_lastw;
   UInt*       other;
   UInt*       ch;
   Int         ch_bszW, ch_pszW, other_bszW, ch_listno;
   Arena*      a;

   VGP_PUSHCC(VgpMalloc);

   ensure_mm_init();
   a = arenaId_to_ArenaP(aid);

   if (ptr == NULL) {
      VGP_POPCC(VgpMalloc);
      return;
   }
      
   ch = payload_to_first(a, ptr);

#  ifdef DEBUG_MALLOC
   vg_assert(blockSane(a,ch));
#  endif

   a->bytes_on_loan 
      -= sizeof(Word) 
         * bszW_to_pszW(a, mk_plain_bszW(get_bszW_lo(ch)));

   sb             = findSb( a, ch );
   sb_payl_firstw = &(sb->payload_words[0]);
   sb_payl_lastw  = &(sb->payload_words[sb->n_payload_words-1]);

   /* Put this chunk back on a list somewhere. */
   ch_bszW    = get_bszW_lo(ch);
   ch_pszW    = bszW_to_pszW(a, ch_bszW);
   ch_listno  = pszW_to_listNo(ch_pszW);
   mkFreeBlock( a, ch, ch_bszW, ch_listno );

   /* See if this block can be merged with the following one. */
   other = ch + ch_bszW;
   /* overhead_szW(a) is the smallest possible bszW for this arena.
      So the nearest possible end to the block beginning at other is
      other+overhead_szW(a)-1.  Hence the test below. */
   if (other+overhead_szW(a)-1 <= sb_payl_lastw) {
      other_bszW = get_bszW_lo(other);
      if (!is_inuse_bszW(other_bszW)) {
         /* VG_(printf)( "merge-successor\n"); */
         other_bszW = mk_plain_bszW(other_bszW);
#        ifdef DEBUG_MALLOC
         vg_assert(blockSane(a, other));
#        endif
         unlinkBlock( a, ch, ch_listno );
         unlinkBlock( a, other, pszW_to_listNo(bszW_to_pszW(a,other_bszW)) );
         ch_bszW += other_bszW; 
         ch_listno = pszW_to_listNo(bszW_to_pszW(a, ch_bszW));
         mkFreeBlock( a, ch, ch_bszW, ch_listno );
      }
   }

   /* See if this block can be merged with its predecessor. */
   if (ch-overhead_szW(a) >= sb_payl_firstw) {
      other_bszW = get_bszW_hi_from_last_word( ch-1 );
      if (!is_inuse_bszW(other_bszW)) {
         /* VG_(printf)( "merge-predecessor\n"); */
         other = last_to_first( ch-1 );
         other_bszW = mk_plain_bszW(other_bszW);         
         unlinkBlock( a, ch, ch_listno );
         unlinkBlock( a, other, pszW_to_listNo(bszW_to_pszW(a, other_bszW)) );
         ch = other;
         ch_bszW += other_bszW;
         ch_listno = pszW_to_listNo(bszW_to_pszW(a, ch_bszW));
         mkFreeBlock( a, ch, ch_bszW, ch_listno );
      }
   }

#  ifdef DEBUG_MALLOC
   mallocSanityCheckArena(aid);
#  endif

   VGP_POPCC(VgpMalloc);
}