/* used for the GC-internal data structures */ void* mono_sgen_alloc_pinned (SgenPinnedAllocator *alc, size_t size) { int slot; void *res = NULL; HEAVY_STAT (++stat_pinned_alloc); if (size > freelist_sizes [SGEN_PINNED_FREELIST_NUM_SLOTS - 1]) { LargePinnedMemHeader *mh; size += sizeof (LargePinnedMemHeader); mh = mono_sgen_alloc_os_memory (size, TRUE); mh->magic = LARGE_PINNED_MEM_HEADER_MAGIC; mh->size = size; /* FIXME: do a CAS here */ large_pinned_bytes_alloced += size; return mh->data; } slot = slot_for_size (size); g_assert (size <= freelist_sizes [slot]); res = alloc_from_slot (alc, slot); return res; }
void mono_sgen_init_nursery_allocator (void) { mono_sgen_register_fixed_internal_mem_type (INTERNAL_MEM_FRAGMENT, sizeof (Fragment)); #ifdef NALLOC_DEBUG alloc_records = mono_sgen_alloc_os_memory (sizeof (AllocRecord) * ALLOC_RECORD_COUNT, TRUE); #endif }
static void* major_alloc_heap (mword nursery_size, mword nursery_align, int the_nursery_bits) { if (nursery_align) nursery_start = mono_sgen_alloc_os_memory_aligned (nursery_size, nursery_align, TRUE); else nursery_start = mono_sgen_alloc_os_memory (nursery_size, TRUE); nursery_end = nursery_start + nursery_size; nursery_bits = the_nursery_bits; return nursery_start; }
void* mono_sgen_alloc_internal_dynamic (size_t size, int type) { int index; void *p; if (size > allocator_sizes [NUM_ALLOCATORS - 1]) return mono_sgen_alloc_os_memory (size, TRUE); index = index_for_size (size); p = mono_lock_free_alloc (&allocators [index]); memset (p, 0, size); return p; }
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; }
/* 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 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; }