Example #1
0
void*
sgen_nursery_alloc_range (size_t desired_size, size_t minimum_size, size_t *out_alloc_size)
{
	SGEN_LOG (4, "Searching for byte range desired size: %zd minimum size %zd", desired_size, minimum_size);

	HEAVY_STAT (++stat_nursery_alloc_range_requests);

	return sgen_fragment_allocator_par_range_alloc (&mutator_allocator, desired_size, minimum_size, out_alloc_size);
}
Example #2
0
static char*
par_alloc_for_promotion_slow_path (int age, size_t objsize)
{
	char *p;
	size_t allocated_size;
	size_t aligned_objsize = (size_t)align_up (objsize, SGEN_TO_SPACE_GRANULE_BITS);

	mono_mutex_lock (&par_alloc_buffer_refill_mutex);

restart:
	p = age_alloc_buffers [age].next;
	if (G_LIKELY (p + objsize <= age_alloc_buffers [age].end)) {
		if (SGEN_CAS_PTR ((void*)&age_alloc_buffers [age].next, p + objsize, p) != p)
			goto restart;
	} else {
		/* Reclaim remaining space - if we OOMd the nursery nothing to see here. */
		char *end = age_alloc_buffers [age].end;
		if (end) {
			do {
				p = age_alloc_buffers [age].next;
			} while (SGEN_CAS_PTR ((void*)&age_alloc_buffers [age].next, end, p) != p);
				sgen_clear_range (p, end);
		}

		/* By setting end to NULL we make sure no other thread can advance while we're updating.*/
		age_alloc_buffers [age].end = NULL;
		STORE_STORE_FENCE;

		p = sgen_fragment_allocator_par_range_alloc (
			&collector_allocator,
			MAX (aligned_objsize, AGE_ALLOC_BUFFER_DESIRED_SIZE),
			MAX (aligned_objsize, AGE_ALLOC_BUFFER_MIN_SIZE),
			&allocated_size);
		if (p) {
			set_age_in_range (p, p + allocated_size, age);
			age_alloc_buffers [age].next = p + objsize;
			STORE_STORE_FENCE; /* Next must arrive before the new value for next. */
			age_alloc_buffers [age].end = p + allocated_size;
		}
	}

	mono_mutex_unlock (&par_alloc_buffer_refill_mutex);
	return p;
}