+ if (i == -1) {
+ guint32 *new_bitmap;
+ guint32 new_size = handles->size * 2; /* always double: we memset to 0 based on this below */
+
+ /* resize and copy the bitmap */
+ new_bitmap = g_malloc0 (new_size / 8);
+ memcpy (new_bitmap, handles->bitmap, handles->size / 8);
+ g_free (handles->bitmap);
+ handles->bitmap = new_bitmap;
+
+ /* resize and copy the entries */
+ if (handles->type > HANDLE_WEAK_TRACK) {
+ gpointer *entries;
+ entries = mono_gc_alloc_fixed (sizeof (gpointer) * new_size, NULL);
+ memcpy (entries, handles->entries, sizeof (gpointer) * handles->size);
+ handles->entries = entries;
+ } else {
+ gpointer *entries;
+ guint16 *domain_ids;
+ domain_ids = g_malloc0 (sizeof (guint16) * new_size);
+ entries = g_malloc (sizeof (gpointer) * new_size);
+ /* we disable GC because we could lose some disappearing link updates */
+ mono_gc_disable ();
+ memcpy (entries, handles->entries, sizeof (gpointer) * handles->size);
+ memset (entries + handles->size, 0, sizeof (gpointer) * handles->size);
+ memcpy (domain_ids, handles->domain_ids, sizeof (guint16) * handles->size);
+ for (i = 0; i < handles->size; ++i) {
+ MonoObject *obj = mono_gc_weak_link_get (&(handles->entries [i]));
+ if (handles->entries [i])
+ mono_gc_weak_link_remove (&(handles->entries [i]));
+ /*g_print ("reg/unreg entry %d of type %d at %p to object %p (%p), was: %p\n", i, handles->type, &(entries [i]), obj, entries [i], handles->entries [i]);*/
+ if (obj) {
+ mono_gc_weak_link_add (&(entries [i]), obj);
+ }
+ }
+ g_free (handles->entries);
+ g_free (handles->domain_ids);
+ handles->entries = entries;
+ handles->domain_ids = domain_ids;
+ mono_gc_enable ();
+ }
+
+ /* set i and slot to the next free position */
+ i = 0;
+ slot = (handles->size + 1) / 32;
+ handles->slot_hint = handles->size + 1;
+ handles->size = new_size;
+ }
+ handles->bitmap [slot] |= 1 << i;
+ slot = slot * 32 + i;
+ handles->entries [slot] = obj;
+ if (handles->type <= HANDLE_WEAK_TRACK) {
+ if (obj)
+ mono_gc_weak_link_add (&(handles->entries [slot]), obj);
+ }
+
+ unlock_handles (handles);
+ /*g_print ("allocated entry %d of type %d to object %p (in slot: %p)\n", slot, handles->type, obj, handles->entries [slot]);*/
+ return (slot << 3) | (handles->type + 1);