static void major_finish_major_collection (void) { #ifndef FIXED_HEAP int section_reserve = mono_sgen_get_minor_collection_allowance () / MS_BLOCK_SIZE; /* * FIXME: We don't free blocks on 32 bit platforms because it * can lead to address space fragmentation, since we're * allocating blocks in larger contingents. */ if (sizeof (mword) < 8) return; while (num_empty_blocks > section_reserve) { void *next = *(void**)empty_blocks; mono_sgen_free_os_memory (empty_blocks, MS_BLOCK_SIZE); empty_blocks = next; /* * Needs not be atomic because this is running * single-threaded. */ --num_empty_blocks; ++stat_major_blocks_freed; } #endif }
static void free_sb (gpointer sb) { gpointer sb_header = SB_HEADER_FOR_ADDR (sb); g_assert ((char*)sb_header + SB_HEADER_SIZE == sb); mono_sgen_free_os_memory (sb_header, SB_SIZE); //g_print ("free sb %p\n", sb_header); }
static void free_major_section (GCMemSection *section) { DEBUG (3, fprintf (gc_debug_file, "Freed major section %p (%p-%p)\n", section, section->data, section->end_data)); mono_sgen_free_internal_dynamic (section->scan_starts, (section->size + SGEN_SCAN_START_SIZE - 1) / SGEN_SCAN_START_SIZE * sizeof (char*), INTERNAL_MEM_SCAN_STARTS); mono_sgen_free_os_memory (section, MAJOR_SECTION_SIZE); --num_major_sections; }
/* size must be a power of 2 */ static void* mono_sgen_alloc_os_memory_aligned (size_t size, size_t alignment, gboolean activate) { /* Allocate twice the memory to be able to put the block on an aligned address */ char *mem = mono_sgen_alloc_os_memory (size + alignment, activate); char *aligned; g_assert (mem); aligned = (char*)((gulong)(mem + (alignment - 1)) & ~(alignment - 1)); g_assert (aligned >= mem && aligned + size <= mem + size + alignment && !((gulong)aligned & (alignment - 1))); if (aligned > mem) mono_sgen_free_os_memory (mem, aligned - mem); if (aligned + size < mem + size + alignment) mono_sgen_free_os_memory (aligned + size, (mem + size + alignment) - (aligned + size)); return aligned; }
static void binary_protocol_flush_buffers_rec (BinaryProtocolBuffer *buffer) { if (!buffer) return; binary_protocol_flush_buffers_rec (buffer->next); g_assert (buffer->index > 0); fwrite (buffer->buffer, 1, buffer->index, binary_protocol_file); mono_sgen_free_os_memory (buffer, sizeof (BinaryProtocolBuffer)); }
void mono_sgen_free_internal_dynamic (void *addr, size_t size, int type) { int index; if (!addr) return; if (size > allocator_sizes [NUM_ALLOCATORS - 1]) return mono_sgen_free_os_memory (addr, size); index = index_for_size (size); mono_lock_free_free (addr); }
static Descriptor* desc_alloc (void) { MonoThreadHazardPointers *hp = mono_hazard_pointer_get (); Descriptor *desc; for (;;) { gboolean success; desc = get_hazardous_pointer ((gpointer * volatile)&desc_avail, hp, 1); if (desc) { Descriptor *next = desc->next; success = (InterlockedCompareExchangePointer ((gpointer * volatile)&desc_avail, next, desc) == desc); } else { size_t desc_size = sizeof (Descriptor); Descriptor *d; int i; desc = mono_sgen_alloc_os_memory (desc_size * NUM_DESC_BATCH, TRUE); /* Organize into linked list. */ d = desc; for (i = 0; i < NUM_DESC_BATCH; ++i) { Descriptor *next = (i == (NUM_DESC_BATCH - 1)) ? NULL : (Descriptor*)((char*)desc + ((i + 1) * desc_size)); d->next = next; mono_lock_free_queue_node_init (&d->node, TRUE); d = next; } mono_memory_write_barrier (); success = (InterlockedCompareExchangePointer ((gpointer * volatile)&desc_avail, desc->next, NULL) == NULL); if (!success) mono_sgen_free_os_memory (desc, desc_size * NUM_DESC_BATCH); } mono_hazard_pointer_clear (hp, 1); if (success) break; } g_assert (!desc->in_use); desc->in_use = TRUE; return desc; }
static BinaryProtocolBuffer* binary_protocol_get_buffer (int length) { BinaryProtocolBuffer *buffer, *new_buffer; retry: buffer = binary_protocol_buffers; if (buffer && buffer->index + length <= BINARY_PROTOCOL_BUFFER_SIZE) return buffer; new_buffer = mono_sgen_alloc_os_memory (sizeof (BinaryProtocolBuffer), TRUE); new_buffer->next = buffer; new_buffer->index = 0; if (InterlockedCompareExchangePointer ((void**)&binary_protocol_buffers, new_buffer, buffer) != buffer) { mono_sgen_free_os_memory (new_buffer, sizeof (BinaryProtocolBuffer)); goto retry; } return new_buffer; }
void mono_sgen_free_pinned (SgenPinnedAllocator *alc, void *addr, size_t size) { LargePinnedMemHeader *mh; if (!addr) return; if (size <= freelist_sizes [SGEN_PINNED_FREELIST_NUM_SLOTS - 1]) { int slot = slot_for_size (size); free_from_slot (alc, addr, slot); return; } mh = (LargePinnedMemHeader*)((char*)addr - G_STRUCT_OFFSET (LargePinnedMemHeader, data)); g_assert (mh->magic == LARGE_PINNED_MEM_HEADER_MAGIC); g_assert (mh->size == size + sizeof (LargePinnedMemHeader)); /* FIXME: do a CAS */ large_pinned_bytes_alloced -= mh->size; mono_sgen_free_os_memory (mh, mh->size); }