Beispiel #1
0
 */void
mono_gc_memmove_aligned (void *dest, const void *src, size_t size)
{
	g_assert (unaligned_bytes (dest) == 0);
	g_assert (unaligned_bytes (src) == 0);

	/*
	If we're copying less than a word we don't need to worry about word tearing
	so we bailout to memmove early.
	*/
	if (size < sizeof(void*)) {
		memmove (dest, src, size);
		return;
	}

	/*
	 * A bit of explanation on why we align only dest before doing word copies.
	 * Pointers to managed objects must always be stored in word aligned addresses, so
	 * even if dest is misaligned, src will be by the same amount - this ensure proper atomicity of reads.
	 *
	 * We don't need to case when source and destination have different alignments since we only do word stores
	 * using memmove, which must handle it.
	 */
	if (dest > src && ((size_t)((char*)dest - (char*)src) < size)) { /*backward copy*/
			volatile char *p = (char*)dest + size;
			char *s = (char*)src + size;
			char *start = (char*)dest;
			char *align_end = MAX((char*)dest, (char*)align_down (p));
			char *word_start;
			size_t bytes_to_memmove;

			while (p > align_end)
			        *--p = *--s;

			word_start = (char *)align_up (start);
			bytes_to_memmove = p - word_start;
			p -= bytes_to_memmove;
			s -= bytes_to_memmove;
			MEMMOVE_WORDS_DOWNWARD (p, s, bytes_to_words (bytes_to_memmove));
	} else {
		volatile char *d = (char*)dest;
		const char *s = (const char*)src;
		size_t tail_bytes;

		/* copy all words with memmove */
		MEMMOVE_WORDS_UPWARD (d, s, bytes_to_words (align_down (size)));

		tail_bytes = unaligned_bytes (size);
		if (tail_bytes) {
			d += (size_t)align_down (size);
			s += (size_t)align_down (size);
			do {
				*d++ = *s++;
			} while (--tail_bytes);
		}
	}
}
Beispiel #2
0
void begin_bit_run_iteration_on_page(gc_heap* heap,
				     gc_bit_table* table,
				     gc_bit_run_iterator* itr,
				     os_pointer start,
				     os_pointer end) {
  gc_page* page = page_for_pointer(heap, start);
  os_pointer base = pointer_for_page(heap, page);
  os_pointer limit = end ? pmin(base + GC_PAGE_SIZE, end) : base + GC_PAGE_SIZE;

  long start_idx = bytes_to_words(start - heap->heap_memory);
  long limit_idx = bytes_to_words(limit - heap->heap_memory);

  begin_run_iteration(table, itr, start_idx, limit_idx);
}
Beispiel #3
0
/**
 * mono_gc_bzero_aligned:
 * @dest: address to start to clear
 * @size: size of the region to clear
 *
 * Zero @size bytes starting at @dest.
 * The address of @dest MUST be aligned to word boundaries
 *
 * FIXME borrow faster code from some BSD libc or bionic
 */
void
mono_gc_bzero_aligned (void *dest, size_t size)
{
	volatile char *d = (char*)dest;
	size_t tail_bytes, word_bytes;

	g_assert (unaligned_bytes (dest) == 0);

	/* copy all words with memmove */
	word_bytes = (size_t)align_down (size);
	switch (word_bytes) {
	case sizeof (void*) * 1:
		BZERO_WORDS (d, 1);
		break;
	case sizeof (void*) * 2:
		BZERO_WORDS (d, 2);
		break;
	case sizeof (void*) * 3:
		BZERO_WORDS (d, 3);
		break;
	case sizeof (void*) * 4:
		BZERO_WORDS (d, 4);
		break;
	default:
		BZERO_WORDS (d, bytes_to_words (word_bytes));
	}

	tail_bytes = unaligned_bytes (size);
	if (tail_bytes) {
		d += word_bytes;
		do {
			*d++ = 0;
		} while (--tail_bytes);
	}
}
Beispiel #4
0
const char* test_mark_table_iterator() {
  gc_heap* heap = gc_make_heap(8192, GC_POLICY_NONGEN, false);
  populate_bit_table(&heap->mark_table, 
		     g_fake_obj_table, 
		     GC_FAKE_OBJ_TABLE_LENGTH);

  gc_page_queue queue;
  queue_even_pages(heap, &queue);

  gc_mark_table_iterator itr;
  begin_mark_table_iteration(heap, 
			     &queue, 
			     &heap->mark_table,
			     &itr,
			     heap->heap_memory,
			     heap->heap_memory + words_to_bytes(779));
  
  os_pointer obj_base = 0;
  os_word obj_len;

  while(find_next_marked_object(&itr, &obj_base, &obj_len)) {
    long obj_offt = bytes_to_words(obj_base - heap->heap_memory);
    long obj_len_words = bytes_to_words(obj_len);
    long page_idx = obj_offt / bytes_to_words(GC_PAGE_SIZE);

    if(page_idx % 2 != 0)
      return "find next marked object base failed";

    int i = 0;
    while((i < GC_FAKE_OBJ_TABLE_LENGTH) && (g_fake_obj_table[i] != obj_offt)) 
      i += 2;

    if(i == GC_FAKE_OBJ_TABLE_LENGTH)
      return "find next marked object base failed";

    if((obj_offt + obj_len_words) > 779)
      return "find next marked object base failed";

    if(g_fake_obj_table[i + 1] != obj_len_words)
      return "find next marked object length failed";
  }

  gc_destroy_heap(heap);

  return "passed";
}