Exemplo n.º 1
0
  /* Moves a link.  Assume the lock is held.    */
  STATIC int GC_move_disappearing_link_inner(
                                struct dl_hashtbl_s *dl_hashtbl,
                                void **link, void **new_link)
  {
    struct disappearing_link *curr_dl, *prev_dl, *new_dl;
    size_t curr_index, new_index;
    word curr_hidden_link;
    word new_hidden_link;

    /* Find current link.       */
    curr_index = HASH2(link, dl_hashtbl -> log_size);
    curr_hidden_link = GC_HIDE_POINTER(link);
    prev_dl = NULL;
    for (curr_dl = dl_hashtbl -> head[curr_index]; curr_dl;
         curr_dl = dl_next(curr_dl)) {
      if (curr_dl -> dl_hidden_link == curr_hidden_link)
        break;
      prev_dl = curr_dl;
    }

    if (NULL == curr_dl) {
      return GC_NOT_FOUND;
    }

    if (link == new_link) {
      return GC_SUCCESS; /* Nothing to do.      */
    }

    /* link found; now check new_link not present.      */
    new_index = HASH2(new_link, dl_hashtbl -> log_size);
    new_hidden_link = GC_HIDE_POINTER(new_link);
    for (new_dl = dl_hashtbl -> head[new_index]; new_dl;
         new_dl = dl_next(new_dl)) {
      if (new_dl -> dl_hidden_link == new_hidden_link) {
        /* Target already registered; bail.     */
        return GC_DUPLICATE;
      }
    }

    /* Remove from old, add to new, update link.        */
    if (NULL == prev_dl) {
      dl_hashtbl -> head[curr_index] = dl_next(curr_dl);
    } else {
      dl_set_next(prev_dl, dl_next(curr_dl));
    }
    curr_dl -> dl_hidden_link = new_hidden_link;
    dl_set_next(curr_dl, dl_hashtbl -> head[new_index]);
    dl_hashtbl -> head[new_index] = curr_dl;
    return GC_SUCCESS;
  }
Exemplo n.º 2
0
int GC_unregister_disappearing_link(void * * link)
{
    struct disappearing_link *curr_dl, *prev_dl;
    size_t index;
    DCL_LOCK_STATE;
    
    LOCK();
    index = HASH2(link, log_dl_table_size);
    if (((word)link & (ALIGNMENT-1))) goto out;
    prev_dl = 0; curr_dl = dl_head[index];
    while (curr_dl != 0) {
        if (curr_dl -> dl_hidden_link == HIDE_POINTER(link)) {
            if (prev_dl == 0) {
                dl_head[index] = dl_next(curr_dl);
            } else {
                dl_set_next(prev_dl, dl_next(curr_dl));
            }
            GC_dl_entries--;
            UNLOCK();
#	    ifdef DBG_HDRS_ALL
	      dl_set_next(curr_dl, 0);
#	    else
              GC_free((void *)curr_dl);
#	    endif
            return(1);
        }
        prev_dl = curr_dl;
        curr_dl = dl_next(curr_dl);
    }
out:
    UNLOCK();
    return(0);
}
Exemplo n.º 3
0
GC_INNER int GC_clone_finalizer(void * src_p, void * dest_p)
{
    struct finalizable_object * curr_fo;
    size_t index;
    ptr_t base, result;
    GC_finalization_proc fn;
    ptr_t cd;
    finalization_mark_proc mp;
    DCL_LOCK_STATE;

    base = (ptr_t)src_p;
    result = (ptr_t)dest_p;
    LOCK();
    index = HASH2(base, log_fo_table_size);
    curr_fo = GC_fo_head[index];
    while (curr_fo != 0) {
      GC_ASSERT(GC_size(curr_fo) >= sizeof(struct finalizable_object));
      if (curr_fo -> fo_hidden_base == GC_HIDE_POINTER(base)) {
          fn = curr_fo -> fo_fn;
          cd = curr_fo -> fo_client_data;
          mp = curr_fo -> fo_mark_proc;
          UNLOCK();
          return GC_register_finalizer_inner(result, fn, cd, 0, 0, mp);
      }
      curr_fo = fo_next(curr_fo);
    }
    UNLOCK();
    return TRUE;
}
Exemplo n.º 4
0
int GC_general_register_disappearing_link(void * * link, void * obj)
{
    struct disappearing_link *curr_dl;
    size_t index;
    struct disappearing_link * new_dl;
    DCL_LOCK_STATE;
    
    if ((word)link & (ALIGNMENT-1))
    	ABORT("Bad arg to GC_general_register_disappearing_link");
#   ifdef THREADS
    	LOCK();
#   endif
    if (log_dl_table_size == -1
        || GC_dl_entries > ((word)1 << log_dl_table_size)) {
    	GC_grow_table((struct hash_chain_entry ***)(&dl_head),
    		      &log_dl_table_size);
	if (GC_print_stats) {
	    GC_log_printf("Grew dl table to %u entries\n",
	    	      (1 << log_dl_table_size));
	}
    }
    index = HASH2(link, log_dl_table_size);
    curr_dl = dl_head[index];
    for (curr_dl = dl_head[index]; curr_dl != 0; curr_dl = dl_next(curr_dl)) {
        if (curr_dl -> dl_hidden_link == HIDE_POINTER(link)) {
            curr_dl -> dl_hidden_obj = HIDE_POINTER(obj);
#	    ifdef THREADS
                UNLOCK();
#	    endif
            return(1);
        }
    }
    new_dl = (struct disappearing_link *)
    	GC_INTERNAL_MALLOC(sizeof(struct disappearing_link),NORMAL);
    if (0 == new_dl) {
#     ifdef THREADS
	UNLOCK();
#     endif
      new_dl = (struct disappearing_link *)
	      GC_oom_fn(sizeof(struct disappearing_link));
      if (0 == new_dl) {
	GC_finalization_failures++;
	return(2);
      }
      /* It's not likely we'll make it here, but ... */
#     ifdef THREADS
	LOCK();
#     endif
    }
    new_dl -> dl_hidden_obj = HIDE_POINTER(obj);
    new_dl -> dl_hidden_link = HIDE_POINTER(link);
    dl_set_next(new_dl, dl_head[index]);
    dl_head[index] = new_dl;
    GC_dl_entries++;
#   ifdef THREADS
        UNLOCK();
#   endif
    return(0);
}
Exemplo n.º 5
0
void uunhash(unit * u)
{
  int key = HASH1(u->no, UMAXHASH), gk = HASH2(u->no, UMAXHASH);
  while (unithash[key] != NULL && unithash[key] != u) {
    key = (key + gk) % UMAXHASH;
  }
  assert(unithash[key] == u || !"trying to remove a unit that is not hashed");
  unithash[key] = delmarker;
}
Exemplo n.º 6
0
void uhash(unit * u)
{
  int key = HASH1(u->no, UMAXHASH), gk = HASH2(u->no, UMAXHASH);
  while (unithash[key] != NULL && unithash[key] != delmarker
    && unithash[key] != u) {
    key = (key + gk) % UMAXHASH;
  }
  assert(unithash[key] != u || !"trying to add the same unit twice");
  unithash[key] = u;
}
Exemplo n.º 7
0
void copy_cache_record_and_overflow(bdd_manager *bddm,
                                    cache_record *old_cache,
                                    unsigned  i,
                                    unsigned (*result_fn)(unsigned r)) {
    unsigned p, q, r, h;
    if (CACHE_FULL_BIN0(old_cache[i])) {
        CACHE_LOAD_BIN0(old_cache[i], p, q, r);
        h = HASH2(p, q, bddm->cache_mask);
        insert_cache(bddm, h, p, q, result_fn(r));
        if (CACHE_FULL_BIN1(old_cache[i])) {
            CACHE_LOAD_BIN1(old_cache[i], p, q, r);
            h = HASH2(p, q, bddm->cache_mask);
            insert_cache(bddm, h, p, q, result_fn(r));
        }
    }
    if (old_cache[i].next != 0) {
        copy_cache_record_and_overflow(bddm, old_cache,
                                       old_cache[i].next, result_fn);
    }
}
Exemplo n.º 8
0
void rhash(region * r)
{
    unsigned int rid = coor_hashkey(r->x, r->y);
    int key = HASH1(rid, RMAXHASH), gk = HASH2(rid, RMAXHASH);
    while (regionhash[key] != NULL && regionhash[key] != DELMARKER
        && regionhash[key] != r) {
        key = (key + gk) % RMAXHASH;
    }
    assert(regionhash[key] != r || !"trying to add the same region twice");
    regionhash[key] = r;
}
Exemplo n.º 9
0
Arquivo: main.c Projeto: Elimut/ALM2
/* ht3: dvojite hasovani
 * viz http://en.wikipedia.org/wiki/Double_hashing
 */
char* ht3_insert (char* key) {
    unsigned hash, idx, i;
    hash = HASH1(key);
    idx = hash % PRIHRADEK;
    i = 1;
    while (ht3[idx]) {
        idx = (idx + i*HASH2(key)) % PRIHRADEK;
        i++;
        //printf("key3: %s, idx=%d, i=%d\n" ,key ,idx, i);
        pocitadlo3 ++;
    }
    return ht3[idx] = strdup(key);
}
Exemplo n.º 10
0
void
bdd_insert_in_cache22(cmu_bdd_manager bddm, int tag, INT_PTR d1, INT_PTR d2, INT_PTR result1, INT_PTR result2)
{
  long hash;
  cache_entry p;

  hash=HASH2(d1, d2);
  BDD_REDUCE(hash, bddm->op_cache.size);
  p=bdd_get_entry(bddm, tag, bddm->op_cache.table[hash].entry);
  p->slot[0]=d1;
  p->slot[1]=d2;
  p->slot[2]=result1;
  p->slot[3]=result2;
  bddm->op_cache.inserts++;
}
Exemplo n.º 11
0
static region *rfindhash(int x, int y)
{
    unsigned int rid = coor_hashkey(x, y);
    int key = HASH1(rid, RMAXHASH), gk = HASH2(rid, RMAXHASH);
#if HASH_STATISTICS
    ++hash_requests;
#endif
    while (regionhash[key] != NULL && (regionhash[key] == DELMARKER
        || regionhash[key]->x != x || regionhash[key]->y != y)) {
        key = (key + gk) % RMAXHASH;
#if HASH_STATISTICS
        ++hash_misses;
#endif
    }
    return regionhash[key];
}
Exemplo n.º 12
0
Uid *new_uid(const char *nick, char *uid)
{
    Uid *u, **list;

    u = scalloc(sizeof(Uid), 1);
    if (!nick || !uid) {
        return NULL;
    }
    strscpy(u->nick, nick, NICKMAX);
    list = &uidlist[HASH2(u->nick)];
    u->next = *list;
    if (*list)
        (*list)->prev = u;
    *list = u;
    u->uid = sstrdup(uid);
    return u;
}
Exemplo n.º 13
0
unit *ufindhash(int uid)
{
  assert(uid >= 0);
#if HASH_STATISTICS
  ++hash_requests;
#endif
  if (uid >= 0) {
    int key = HASH1(uid, UMAXHASH), gk = HASH2(uid, UMAXHASH);
    while (unithash[key] != NULL && (unithash[key] == delmarker
        || unithash[key]->no != uid)) {
      key = (key + gk) % UMAXHASH;
#if HASH_STATISTICS
      ++hash_misses;
#endif
    }
    return unithash[key];
  }
  return NULL;
}
Exemplo n.º 14
0
Arquivo: Hash.c Projeto: TihoElek/lzw
//insert element with prefix and character into hash table
int insertInHashTable(HashTable* h, int prefix, int character){             
    if (rehashCheck(h))                                                     //if rehash is needed, rehash and don't insert
        return 0;

    int position = HASH1 (prefix, character);                               //get position to insert
	int skipper = HASH2 (prefix,character);                                 //skip skipper #slots if full (double hashing)

    while (((((*h)[position]).letter != -1)) || (position == 0)  || (position == 1)) {          //skip full slots
  		position = ((position  + skipper) % SizeOfTable);
   	}

    ((*h)[position]).prefix = prefix;                                       //insert at first empty slot
    ((*h)[position]).letter = character;
    ((*h)[position]).isRehashed = 0;
    NumberOfElements++;

    return position;                                                        //return position where inserted
    
}
Exemplo n.º 15
0
Arquivo: Hash.c Projeto: TihoElek/lzw
//search element in hash table given it's prefix and character(letter)
int searchInHashTable(HashTable *h, int prefix, int letter ){
    int position = HASH1( prefix, letter );
    int skipper = HASH2(prefix, letter);
    int counter = 0;

    while  ((counter < SizeOfTable) &&
           (((*h)[position]).prefix != prefix || 
           ((*h)[position]).letter != letter)){                                 //if not at that position skip

            if(((((*h)[position]).letter == -1)) && (position != 0) && (position != 1)) return -1; //in the same manner as insert was

                position = (position + skipper) % SizeOfTable;
                counter++;
    }

    if (((((*h)[ position ]).prefix == prefix) &&
       ((*h)[ position ]).letter == letter))                                    // return index in hash when found                                               
        return position;

    return -1;
}
Exemplo n.º 16
0
int
bdd_lookup_in_cache22(cmu_bdd_manager bddm, int tag, INT_PTR d1, INT_PTR d2, INT_PTR *result1, INT_PTR *result2)
{
  long hash;
  cache_entry *bin;
  cache_entry p;
  cache_entry q;
  void (*return_fn)(cmu_bdd_manager, cache_entry);

  bddm->op_cache.lookups++;
  hash=HASH2(d1, d2);
  BDD_REDUCE(hash, bddm->op_cache.size);
  bin=bddm->op_cache.table[hash].entry;
  if ((p=bin[0]))
    {
      q=CACHE_POINTER(p);
      if (q->slot[0] != d1 || q->slot[1] != d2 || TAG(p) != tag)
	{
	if ((p=bin[1]))
	  {
	    q=CACHE_POINTER(p);
	    if (q->slot[0] != d1 || q->slot[1] != d2 || TAG(p) != tag)
	      return (0);
	    bin[1]=bin[0];
	    bin[0]=p;
	  }
	else
	  return (0);
	}
    }
  else
    return (0);
  bddm->op_cache.hits++;
  if ((return_fn=bddm->op_cache.return_fn[TAG(p)]))
    (*return_fn)(bddm, q);
  *result1=q->slot[2];
  *result2=q->slot[3];
  return (1);
}
Exemplo n.º 17
0
/* Assume the lock is held.                                     */
GC_INLINE struct disappearing_link *GC_unregister_disappearing_link_inner(
                                struct dl_hashtbl_s *dl_hashtbl, void **link)
{
    struct disappearing_link *curr_dl;
    struct disappearing_link *prev_dl = NULL;
    size_t index = HASH2(link, dl_hashtbl->log_size);

    for (curr_dl = dl_hashtbl -> head[index]; curr_dl;
         curr_dl = dl_next(curr_dl)) {
        if (curr_dl -> dl_hidden_link == GC_HIDE_POINTER(link)) {
            /* Remove found entry from the table. */
            if (NULL == prev_dl) {
                dl_hashtbl -> head[index] = dl_next(curr_dl);
            } else {
                dl_set_next(prev_dl, dl_next(curr_dl));
            }
            dl_hashtbl -> entries--;
            break;
        }
        prev_dl = curr_dl;
    }
    return curr_dl;
}
Exemplo n.º 18
0
void runhash(region * r)
{
    unsigned int rid = coor_hashkey(r->x, r->y);
    int key = HASH1(rid, RMAXHASH), gk = HASH2(rid, RMAXHASH);

#ifdef FAST_CONNECT
    int d, di;
    for (d = 0, di = MAXDIRECTIONS / 2; d != MAXDIRECTIONS; ++d, ++di) {
        region *rc = r->connect[d];
        if (rc != NULL) {
            if (di >= MAXDIRECTIONS)
                di -= MAXDIRECTIONS;
            rc->connect[di] = NULL;
            r->connect[d] = NULL;
        }
    }
#endif
    while (regionhash[key] != NULL && regionhash[key] != r) {
        key = (key + gk) % RMAXHASH;
    }
    assert(regionhash[key] == r || !"trying to remove a unit that is not hashed");
    regionhash[key] = DELMARKER;
}
Exemplo n.º 19
0
native_std::size_t HashUtil::computeHash(const void *key)
{
    return HASH2(key);
}
Exemplo n.º 20
0
native_std::size_t HashUtil::computeHash(double key)
{
    return HASH2(key);
}
Exemplo n.º 21
0
native_std::size_t HashUtil::computeHash(float key)
{
    return HASH2(key);
}
Exemplo n.º 22
0
native_std::size_t HashUtil::computeHash(unsigned long long key)
{
    return HASH2(key);
}
Exemplo n.º 23
0
native_std::size_t HashUtil::computeHash(signed char key)
{
    return HASH2(key);
}
Exemplo n.º 24
0
/* and invoke finalizers.						*/
void GC_finalize(void)
{
    struct disappearing_link * curr_dl, * prev_dl, * next_dl;
    struct finalizable_object * curr_fo, * prev_fo, * next_fo;
    ptr_t real_ptr, real_link;
    size_t i;
    size_t dl_size = (log_dl_table_size == -1 ) ? 0 : (1 << log_dl_table_size);
    size_t fo_size = (log_fo_table_size == -1 ) ? 0 : (1 << log_fo_table_size);
    
  /* Make disappearing links disappear */
    for (i = 0; i < dl_size; i++) {
      curr_dl = dl_head[i];
      prev_dl = 0;
      while (curr_dl != 0) {
        real_ptr = (ptr_t)REVEAL_POINTER(curr_dl -> dl_hidden_obj);
        real_link = (ptr_t)REVEAL_POINTER(curr_dl -> dl_hidden_link);
        if (!GC_is_marked(real_ptr)) {
            *(word *)real_link = 0;
            next_dl = dl_next(curr_dl);
            if (prev_dl == 0) {
                dl_head[i] = next_dl;
            } else {
                dl_set_next(prev_dl, next_dl);
            }
            GC_clear_mark_bit((ptr_t)curr_dl);
            GC_dl_entries--;
            curr_dl = next_dl;
        } else {
            prev_dl = curr_dl;
            curr_dl = dl_next(curr_dl);
        }
      }
    }
  /* Mark all objects reachable via chains of 1 or more pointers	*/
  /* from finalizable objects.						*/
    GC_ASSERT(GC_mark_state == MS_NONE);
    for (i = 0; i < fo_size; i++) {
      for (curr_fo = fo_head[i]; curr_fo != 0; curr_fo = fo_next(curr_fo)) {
        GC_ASSERT(GC_size(curr_fo) >= sizeof(struct finalizable_object));
        real_ptr = (ptr_t)REVEAL_POINTER(curr_fo -> fo_hidden_base);
        if (!GC_is_marked(real_ptr)) {
	    GC_MARKED_FOR_FINALIZATION(real_ptr);
            GC_MARK_FO(real_ptr, curr_fo -> fo_mark_proc);
            if (GC_is_marked(real_ptr)) {
                WARN("Finalization cycle involving %lx\n", real_ptr);
            }
        }
      }
    }
  /* Enqueue for finalization all objects that are still		*/
  /* unreachable.							*/
    GC_bytes_finalized = 0;
    for (i = 0; i < fo_size; i++) {
      curr_fo = fo_head[i];
      prev_fo = 0;
      while (curr_fo != 0) {
        real_ptr = (ptr_t)REVEAL_POINTER(curr_fo -> fo_hidden_base);
        if (!GC_is_marked(real_ptr)) {
	    if (!GC_java_finalization) {
              GC_set_mark_bit(real_ptr);
	    }
            /* Delete from hash table */
              next_fo = fo_next(curr_fo);
              if (prev_fo == 0) {
                fo_head[i] = next_fo;
              } else {
                fo_set_next(prev_fo, next_fo);
              }
              GC_fo_entries--;
            /* Add to list of objects awaiting finalization.	*/
              fo_set_next(curr_fo, GC_finalize_now);
              GC_finalize_now = curr_fo;
              /* unhide object pointer so any future collections will	*/
              /* see it.						*/
              curr_fo -> fo_hidden_base = 
              		(word) REVEAL_POINTER(curr_fo -> fo_hidden_base);
              GC_bytes_finalized +=
                 	curr_fo -> fo_object_size
              		+ sizeof(struct finalizable_object);
	    GC_ASSERT(GC_is_marked(GC_base((ptr_t)curr_fo)));
            curr_fo = next_fo;
        } else {
            prev_fo = curr_fo;
            curr_fo = fo_next(curr_fo);
        }
      }
    }

  if (GC_java_finalization) {
    /* make sure we mark everything reachable from objects finalized
       using the no_order mark_proc */
      for (curr_fo = GC_finalize_now; 
  	 curr_fo != NULL; curr_fo = fo_next(curr_fo)) {
  	real_ptr = (ptr_t)curr_fo -> fo_hidden_base;
  	if (!GC_is_marked(real_ptr)) {
  	    if (curr_fo -> fo_mark_proc == GC_null_finalize_mark_proc) {
  	        GC_MARK_FO(real_ptr, GC_normal_finalize_mark_proc);
  	    }
	    if (curr_fo -> fo_mark_proc != GC_unreachable_finalize_mark_proc) {
		GC_set_mark_bit(real_ptr);
	    }
  	}
      }

    /* now revive finalize-when-unreachable objects reachable from
       other finalizable objects */
      if (need_unreachable_finalization) {
        curr_fo = GC_finalize_now;
        prev_fo = 0;
        while (curr_fo != 0) {
	  next_fo = fo_next(curr_fo);
	  if (curr_fo -> fo_mark_proc == GC_unreachable_finalize_mark_proc) {
	    real_ptr = (ptr_t)curr_fo -> fo_hidden_base;
	    if (!GC_is_marked(real_ptr)) {
	      GC_set_mark_bit(real_ptr);
	    } else {
	      if (prev_fo == 0)
		GC_finalize_now = next_fo;
	      else
		fo_set_next(prev_fo, next_fo);

              curr_fo -> fo_hidden_base =
              		(word) HIDE_POINTER(curr_fo -> fo_hidden_base);
              GC_bytes_finalized -=
                 	curr_fo -> fo_object_size + sizeof(struct finalizable_object);

	      i = HASH2(real_ptr, log_fo_table_size);
	      fo_set_next (curr_fo, fo_head[i]);
	      GC_fo_entries++;
	      fo_head[i] = curr_fo;
	      curr_fo = prev_fo;
	    }
	  }
	  prev_fo = curr_fo;
	  curr_fo = next_fo;
        }
      }
  }

  /* Remove dangling disappearing links. */
    for (i = 0; i < dl_size; i++) {
      curr_dl = dl_head[i];
      prev_dl = 0;
      while (curr_dl != 0) {
        real_link = GC_base((ptr_t)REVEAL_POINTER(curr_dl -> dl_hidden_link));
        if (real_link != 0 && !GC_is_marked(real_link)) {
            next_dl = dl_next(curr_dl);
            if (prev_dl == 0) {
                dl_head[i] = next_dl;
            } else {
                dl_set_next(prev_dl, next_dl);
            }
            GC_clear_mark_bit((ptr_t)curr_dl);
            GC_dl_entries--;
            curr_dl = next_dl;
        } else {
            prev_dl = curr_dl;
            curr_dl = dl_next(curr_dl);
        }
      }
    }
}
Exemplo n.º 25
0
/* finalized when this finalizer is invoked.			*/
GC_API void GC_register_finalizer_inner(void * obj,
					GC_finalization_proc fn, void *cd,
					GC_finalization_proc *ofn, void **ocd,
					finalization_mark_proc mp)
{
    ptr_t base;
    struct finalizable_object * curr_fo, * prev_fo;
    size_t index;
    struct finalizable_object *new_fo;
    hdr *hhdr;
    DCL_LOCK_STATE;

#   ifdef THREADS
	LOCK();
#   endif
    if (log_fo_table_size == -1
        || GC_fo_entries > ((word)1 << log_fo_table_size)) {
    	GC_grow_table((struct hash_chain_entry ***)(&fo_head),
    		      &log_fo_table_size);
	if (GC_print_stats) {
	    GC_log_printf("Grew fo table to %u entries\n",
	    	          (1 << log_fo_table_size));
	}
    }
    /* in the THREADS case signals are disabled and we hold allocation	*/
    /* lock; otherwise neither is true.  Proceed carefully.		*/
    base = (ptr_t)obj;
    index = HASH2(base, log_fo_table_size);
    prev_fo = 0; curr_fo = fo_head[index];
    while (curr_fo != 0) {
        GC_ASSERT(GC_size(curr_fo) >= sizeof(struct finalizable_object));
        if (curr_fo -> fo_hidden_base == HIDE_POINTER(base)) {
            /* Interruption by a signal in the middle of this	*/
            /* should be safe.  The client may see only *ocd	*/
            /* updated, but we'll declare that to be his	*/
            /* problem.						*/
            if (ocd) *ocd = (void *) (curr_fo -> fo_client_data);
            if (ofn) *ofn = curr_fo -> fo_fn;
            /* Delete the structure for base. */
                if (prev_fo == 0) {
                  fo_head[index] = fo_next(curr_fo);
                } else {
                  fo_set_next(prev_fo, fo_next(curr_fo));
                }
            if (fn == 0) {
                GC_fo_entries--;
                  /* May not happen if we get a signal.  But a high	*/
                  /* estimate will only make the table larger than	*/
                  /* necessary.						*/
#		if !defined(THREADS) && !defined(DBG_HDRS_ALL)
                  GC_free((void *)curr_fo);
#		endif
            } else {
                curr_fo -> fo_fn = fn;
                curr_fo -> fo_client_data = (ptr_t)cd;
                curr_fo -> fo_mark_proc = mp;
		/* Reinsert it.  We deleted it first to maintain	*/
		/* consistency in the event of a signal.		*/
		if (prev_fo == 0) {
                  fo_head[index] = curr_fo;
                } else {
                  fo_set_next(prev_fo, curr_fo);
                }
            }
#	    ifdef THREADS
                UNLOCK();
#	    endif
            return;
        }
        prev_fo = curr_fo;
        curr_fo = fo_next(curr_fo);
    }
    if (ofn) *ofn = 0;
    if (ocd) *ocd = 0;
    if (fn == 0) {
#	ifdef THREADS
            UNLOCK();
#	endif
        return;
    }
    GET_HDR(base, hhdr);
    if (0 == hhdr) {
      /* We won't collect it, hence finalizer wouldn't be run. */
#     ifdef THREADS
          UNLOCK();
#     endif
      return;
    }
    new_fo = (struct finalizable_object *)
    	GC_INTERNAL_MALLOC(sizeof(struct finalizable_object),NORMAL);
    if (EXPECT(0 == new_fo, FALSE)) {
#     ifdef THREADS
	UNLOCK();
#     endif
      new_fo = (struct finalizable_object *)
	      GC_oom_fn(sizeof(struct finalizable_object));
      if (0 == new_fo) {
	GC_finalization_failures++;
	return;
      }
      /* It's not likely we'll make it here, but ... */
#     ifdef THREADS
	LOCK();
#     endif
    }
    GC_ASSERT(GC_size(new_fo) >= sizeof(struct finalizable_object));
    new_fo -> fo_hidden_base = (word)HIDE_POINTER(base);
    new_fo -> fo_fn = fn;
    new_fo -> fo_client_data = (ptr_t)cd;
    new_fo -> fo_object_size = hhdr -> hb_sz;
    new_fo -> fo_mark_proc = mp;
    fo_set_next(new_fo, fo_head[index]);
    GC_fo_entries++;
    fo_head[index] = new_fo;
#   ifdef THREADS
        UNLOCK();
#   endif
}
Exemplo n.º 26
0
static
long
bdd_rehash2(cmu_bdd_manager bddm, cache_entry p)
{
  return (HASH2(p->slot[0], p->slot[1]));
}
Exemplo n.º 27
0
STATIC int GC_register_disappearing_link_inner(
                        struct dl_hashtbl_s *dl_hashtbl, void **link,
                        const void *obj, const char *tbl_log_name)
{
    struct disappearing_link *curr_dl;
    size_t index;
    struct disappearing_link * new_dl;
    DCL_LOCK_STATE;

    LOCK();
    GC_ASSERT(obj != NULL && GC_base_C(obj) == obj);
    if (dl_hashtbl -> log_size == -1
        || dl_hashtbl -> entries > ((word)1 << dl_hashtbl -> log_size)) {
        GC_grow_table((struct hash_chain_entry ***)&dl_hashtbl -> head,
                      &dl_hashtbl -> log_size);
        GC_COND_LOG_PRINTF("Grew %s table to %u entries\n", tbl_log_name,
                           1 << (unsigned)dl_hashtbl -> log_size);
    }
    index = HASH2(link, dl_hashtbl -> log_size);
    for (curr_dl = dl_hashtbl -> head[index]; curr_dl != 0;
         curr_dl = dl_next(curr_dl)) {
        if (curr_dl -> dl_hidden_link == GC_HIDE_POINTER(link)) {
            curr_dl -> dl_hidden_obj = GC_HIDE_POINTER(obj);
            UNLOCK();
            return GC_DUPLICATE;
        }
    }
    new_dl = (struct disappearing_link *)
        GC_INTERNAL_MALLOC(sizeof(struct disappearing_link),NORMAL);
    if (0 == new_dl) {
      GC_oom_func oom_fn = GC_oom_fn;
      UNLOCK();
      new_dl = (struct disappearing_link *)
                (*oom_fn)(sizeof(struct disappearing_link));
      if (0 == new_dl) {
        return GC_NO_MEMORY;
      }
      /* It's not likely we'll make it here, but ... */
      LOCK();
      /* Recalculate index since the table may grow.    */
      index = HASH2(link, dl_hashtbl -> log_size);
      /* Check again that our disappearing link not in the table. */
      for (curr_dl = dl_hashtbl -> head[index]; curr_dl != 0;
           curr_dl = dl_next(curr_dl)) {
        if (curr_dl -> dl_hidden_link == GC_HIDE_POINTER(link)) {
          curr_dl -> dl_hidden_obj = GC_HIDE_POINTER(obj);
          UNLOCK();
#         ifndef DBG_HDRS_ALL
            /* Free unused new_dl returned by GC_oom_fn() */
            GC_free((void *)new_dl);
#         endif
          return GC_DUPLICATE;
        }
      }
    }
    new_dl -> dl_hidden_obj = GC_HIDE_POINTER(obj);
    new_dl -> dl_hidden_link = GC_HIDE_POINTER(link);
    dl_set_next(new_dl, dl_hashtbl -> head[index]);
    dl_hashtbl -> head[index] = new_dl;
    dl_hashtbl -> entries++;
    UNLOCK();
    return GC_SUCCESS;
}
Exemplo n.º 28
0
/* finalized when this finalizer is invoked.                    */
STATIC void GC_register_finalizer_inner(void * obj,
                                        GC_finalization_proc fn, void *cd,
                                        GC_finalization_proc *ofn, void **ocd,
                                        finalization_mark_proc mp)
{
    ptr_t base;
    struct finalizable_object * curr_fo, * prev_fo;
    size_t index;
    struct finalizable_object *new_fo = 0;
    hdr *hhdr = NULL; /* initialized to prevent warning. */
    GC_oom_func oom_fn;
    DCL_LOCK_STATE;

    LOCK();
    if (log_fo_table_size == -1
        || GC_fo_entries > ((word)1 << log_fo_table_size)) {
        GC_grow_table((struct hash_chain_entry ***)&GC_fnlz_roots.fo_head,
                      &log_fo_table_size);
        GC_COND_LOG_PRINTF("Grew fo table to %u entries\n",
                           1 << (unsigned)log_fo_table_size);
    }
    /* in the THREADS case we hold allocation lock.             */
    base = (ptr_t)obj;
    for (;;) {
      index = HASH2(base, log_fo_table_size);
      prev_fo = 0;
      curr_fo = GC_fnlz_roots.fo_head[index];
      while (curr_fo != 0) {
        GC_ASSERT(GC_size(curr_fo) >= sizeof(struct finalizable_object));
        if (curr_fo -> fo_hidden_base == GC_HIDE_POINTER(base)) {
          /* Interruption by a signal in the middle of this     */
          /* should be safe.  The client may see only *ocd      */
          /* updated, but we'll declare that to be his problem. */
          if (ocd) *ocd = (void *) (curr_fo -> fo_client_data);
          if (ofn) *ofn = curr_fo -> fo_fn;
          /* Delete the structure for base. */
          if (prev_fo == 0) {
            GC_fnlz_roots.fo_head[index] = fo_next(curr_fo);
          } else {
            fo_set_next(prev_fo, fo_next(curr_fo));
          }
          if (fn == 0) {
            GC_fo_entries--;
            /* May not happen if we get a signal.  But a high   */
            /* estimate will only make the table larger than    */
            /* necessary.                                       */
#           if !defined(THREADS) && !defined(DBG_HDRS_ALL)
              GC_free((void *)curr_fo);
#           endif
          } else {
            curr_fo -> fo_fn = fn;
            curr_fo -> fo_client_data = (ptr_t)cd;
            curr_fo -> fo_mark_proc = mp;
            /* Reinsert it.  We deleted it first to maintain    */
            /* consistency in the event of a signal.            */
            if (prev_fo == 0) {
              GC_fnlz_roots.fo_head[index] = curr_fo;
            } else {
              fo_set_next(prev_fo, curr_fo);
            }
          }
          UNLOCK();
#         ifndef DBG_HDRS_ALL
            if (EXPECT(new_fo != 0, FALSE)) {
              /* Free unused new_fo returned by GC_oom_fn() */
              GC_free((void *)new_fo);
            }
#         endif
          return;
        }
        prev_fo = curr_fo;
        curr_fo = fo_next(curr_fo);
      }
      if (EXPECT(new_fo != 0, FALSE)) {
        /* new_fo is returned by GC_oom_fn(), so fn != 0 and hhdr != 0. */
        break;
      }
      if (fn == 0) {
        if (ocd) *ocd = 0;
        if (ofn) *ofn = 0;
        UNLOCK();
        return;
      }
      GET_HDR(base, hhdr);
      if (EXPECT(0 == hhdr, FALSE)) {
        /* We won't collect it, hence finalizer wouldn't be run. */
        if (ocd) *ocd = 0;
        if (ofn) *ofn = 0;
        UNLOCK();
        return;
      }
      new_fo = (struct finalizable_object *)
        GC_INTERNAL_MALLOC(sizeof(struct finalizable_object),NORMAL);
      if (EXPECT(new_fo != 0, TRUE))
        break;
      oom_fn = GC_oom_fn;
      UNLOCK();
      new_fo = (struct finalizable_object *)
                (*oom_fn)(sizeof(struct finalizable_object));
      if (0 == new_fo) {
        /* No enough memory.  *ocd and *ofn remains unchanged.  */
        return;
      }
      /* It's not likely we'll make it here, but ... */
      LOCK();
      /* Recalculate index since the table may grow and         */
      /* check again that our finalizer is not in the table.    */
    }
    GC_ASSERT(GC_size(new_fo) >= sizeof(struct finalizable_object));
    if (ocd) *ocd = 0;
    if (ofn) *ofn = 0;
    new_fo -> fo_hidden_base = GC_HIDE_POINTER(base);
    new_fo -> fo_fn = fn;
    new_fo -> fo_client_data = (ptr_t)cd;
    new_fo -> fo_object_size = hhdr -> hb_sz;
    new_fo -> fo_mark_proc = mp;
    fo_set_next(new_fo, GC_fnlz_roots.fo_head[index]);
    GC_fo_entries++;
    GC_fnlz_roots.fo_head[index] = new_fo;
    UNLOCK();
}
Exemplo n.º 29
0
/* enqueued for finalization.                                           */
GC_INNER void GC_finalize(void)
{
    struct finalizable_object * curr_fo, * prev_fo, * next_fo;
    ptr_t real_ptr;
    size_t i;
    size_t fo_size = log_fo_table_size == -1 ? 0 :
                                (size_t)1 << log_fo_table_size;

#   ifndef SMALL_CONFIG
      /* Save current GC_[dl/ll]_entries value for stats printing */
      GC_old_dl_entries = GC_dl_hashtbl.entries;
#     ifndef GC_LONG_REFS_NOT_NEEDED
        GC_old_ll_entries = GC_ll_hashtbl.entries;
#     endif
#   endif

#   ifndef GC_TOGGLE_REFS_NOT_NEEDED
      GC_mark_togglerefs();
#   endif
    GC_make_disappearing_links_disappear(&GC_dl_hashtbl);

  /* Mark all objects reachable via chains of 1 or more pointers        */
  /* from finalizable objects.                                          */
    GC_ASSERT(GC_mark_state == MS_NONE);
    for (i = 0; i < fo_size; i++) {
      for (curr_fo = GC_fnlz_roots.fo_head[i];
           curr_fo != NULL; curr_fo = fo_next(curr_fo)) {
        GC_ASSERT(GC_size(curr_fo) >= sizeof(struct finalizable_object));
        real_ptr = GC_REVEAL_POINTER(curr_fo -> fo_hidden_base);
        if (!GC_is_marked(real_ptr)) {
            GC_MARKED_FOR_FINALIZATION(real_ptr);
            GC_MARK_FO(real_ptr, curr_fo -> fo_mark_proc);
            if (GC_is_marked(real_ptr)) {
                WARN("Finalization cycle involving %p\n", real_ptr);
            }
        }
      }
    }
  /* Enqueue for finalization all objects that are still                */
  /* unreachable.                                                       */
    GC_bytes_finalized = 0;
    for (i = 0; i < fo_size; i++) {
      curr_fo = GC_fnlz_roots.fo_head[i];
      prev_fo = 0;
      while (curr_fo != 0) {
        real_ptr = GC_REVEAL_POINTER(curr_fo -> fo_hidden_base);
        if (!GC_is_marked(real_ptr)) {
            if (!GC_java_finalization) {
              GC_set_mark_bit(real_ptr);
            }
            /* Delete from hash table */
              next_fo = fo_next(curr_fo);
              if (NULL == prev_fo) {
                GC_fnlz_roots.fo_head[i] = next_fo;
              } else {
                fo_set_next(prev_fo, next_fo);
              }
              GC_fo_entries--;
              if (GC_object_finalized_proc)
                GC_object_finalized_proc(real_ptr);

            /* Add to list of objects awaiting finalization.    */
              fo_set_next(curr_fo, GC_fnlz_roots.finalize_now);
              GC_fnlz_roots.finalize_now = curr_fo;
              /* unhide object pointer so any future collections will   */
              /* see it.                                                */
              curr_fo -> fo_hidden_base =
                        (word)GC_REVEAL_POINTER(curr_fo -> fo_hidden_base);
              GC_bytes_finalized +=
                        curr_fo -> fo_object_size
                        + sizeof(struct finalizable_object);
            GC_ASSERT(GC_is_marked(GC_base(curr_fo)));
            curr_fo = next_fo;
        } else {
            prev_fo = curr_fo;
            curr_fo = fo_next(curr_fo);
        }
      }
    }

  if (GC_java_finalization) {
    /* make sure we mark everything reachable from objects finalized
       using the no_order mark_proc */
      for (curr_fo = GC_fnlz_roots.finalize_now;
           curr_fo != NULL; curr_fo = fo_next(curr_fo)) {
        real_ptr = (ptr_t)curr_fo -> fo_hidden_base;
        if (!GC_is_marked(real_ptr)) {
            if (curr_fo -> fo_mark_proc == GC_null_finalize_mark_proc) {
                GC_MARK_FO(real_ptr, GC_normal_finalize_mark_proc);
            }
            if (curr_fo -> fo_mark_proc != GC_unreachable_finalize_mark_proc) {
                GC_set_mark_bit(real_ptr);
            }
        }
      }

    /* now revive finalize-when-unreachable objects reachable from
       other finalizable objects */
      if (need_unreachable_finalization) {
        curr_fo = GC_fnlz_roots.finalize_now;
        prev_fo = NULL;
        while (curr_fo != NULL) {
          next_fo = fo_next(curr_fo);
          if (curr_fo -> fo_mark_proc == GC_unreachable_finalize_mark_proc) {
            real_ptr = (ptr_t)curr_fo -> fo_hidden_base;
            if (!GC_is_marked(real_ptr)) {
              GC_set_mark_bit(real_ptr);
            } else {
              if (NULL == prev_fo) {
                GC_fnlz_roots.finalize_now = next_fo;
              } else {
                fo_set_next(prev_fo, next_fo);
              }
              curr_fo -> fo_hidden_base =
                                GC_HIDE_POINTER(curr_fo -> fo_hidden_base);
              GC_bytes_finalized -=
                  curr_fo->fo_object_size + sizeof(struct finalizable_object);

              i = HASH2(real_ptr, log_fo_table_size);
              fo_set_next(curr_fo, GC_fnlz_roots.fo_head[i]);
              GC_fo_entries++;
              GC_fnlz_roots.fo_head[i] = curr_fo;
              curr_fo = prev_fo;
            }
          }
          prev_fo = curr_fo;
          curr_fo = next_fo;
        }
      }
  }

  GC_remove_dangling_disappearing_links(&GC_dl_hashtbl);
# ifndef GC_TOGGLE_REFS_NOT_NEEDED
    GC_clear_togglerefs();
# endif
# ifndef GC_LONG_REFS_NOT_NEEDED
    GC_make_disappearing_links_disappear(&GC_ll_hashtbl);
    GC_remove_dangling_disappearing_links(&GC_ll_hashtbl);
# endif

  if (GC_fail_count) {
    /* Don't prevent running finalizers if there has been an allocation */
    /* failure recently.                                                */
#   ifdef THREADS
      GC_reset_finalizer_nested();
#   else
      GC_finalizer_nested = 0;
#   endif
  }
}