Skip to content

Commit

Permalink
2010-05-28 Mark Probst <mark.probst@gmail.com>
Browse files Browse the repository at this point in the history
	* sgen-gc.c, sgen-scan-object.h: Value types in arrays are not
	always aligned to ALLOC_ALIGN.  To handle this, shift the size in
	the GC descriptor by one bit, and don't encode the size for value
	types not containing references.  Also get rid of
	DESC_TYPE_STRING.

svn path=/trunk/mono/; revision=158079
  • Loading branch information
schani committed May 28, 2010
1 parent dc03783 commit 790f986
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 22 deletions.
8 changes: 8 additions & 0 deletions mono/metadata/ChangeLog
@@ -1,3 +1,11 @@
2010-05-28 Mark Probst <mark.probst@gmail.com>

* sgen-gc.c, sgen-scan-object.h: Value types in arrays are not
always aligned to ALLOC_ALIGN. To handle this, shift the size in
the GC descriptor by one bit, and don't encode the size for value
types not containing references. Also get rid of
DESC_TYPE_STRING.

2010-05-28 Mark Probst <mark.probst@gmail.com>

* sgen-gc.c: Don't depend on the size encoded in a GC descriptor
Expand Down
47 changes: 34 additions & 13 deletions mono/metadata/sgen-gc.c
Expand Up @@ -953,7 +953,14 @@ static Fragment *nursery_fragments = NULL;
/* freeelist of fragment structures */
static Fragment *fragment_freelist = NULL;

/* objects bigger then this go into the large object space */
/*
* Objects bigger then this go into the large object space. This size
* has a few constraints. It must fit into the major heap, which in
* the case of the copying collector means that it must fit into a
* pinned chunk. It must also play well with the GC descriptors, some
* of which (DESC_TYPE_RUN_LENGTH, DESC_TYPE_SMALL_BITMAP) encode the
* object size.
*/
#define MAX_SMALL_OBJ_SIZE 2040

/* Functions supplied by the runtime to be called by the GC */
Expand Down Expand Up @@ -1090,9 +1097,13 @@ static void null_ephemerons_for_domain (MonoDomain *domain);
* inside complex.
*/
enum {
DESC_TYPE_RUN_LENGTH, /* 16 bits aligned byte size | 1-3 (offset, numptr) bytes tuples */
DESC_TYPE_SMALL_BITMAP, /* 16 bits aligned byte size | 16-48 bit bitmap */
DESC_TYPE_STRING, /* nothing */
/*
* We don't use 0 so that 0 isn't a valid GC descriptor. No
* deep reason for this other than to be able to identify a
* non-inited descriptor for debugging.
*/
DESC_TYPE_RUN_LENGTH = 1, /* 15 bits aligned byte size | 1-3 (offset, numptr) bytes tuples */
DESC_TYPE_SMALL_BITMAP, /* 15 bits aligned byte size | 16-48 bit bitmap */
DESC_TYPE_COMPLEX, /* index for bitmap into complex_descriptors */
DESC_TYPE_VECTOR, /* 10 bits element size | 1 bit array | 2 bits desc | element desc */
DESC_TYPE_ARRAY, /* 10 bits element size | 1 bit array | 2 bits desc | element desc */
Expand Down Expand Up @@ -1195,7 +1206,7 @@ alloc_complex_descriptor (gsize *bitmap, int numbits)
void*
mono_gc_make_descr_for_string (gsize *bitmap, int numbits)
{
return (void*) DESC_TYPE_STRING;
return (void*) DESC_TYPE_RUN_LENGTH;
}

void*
Expand All @@ -1204,8 +1215,6 @@ mono_gc_make_descr_for_object (gsize *bitmap, int numbits, size_t obj_size)
int first_set = -1, num_set = 0, last_set = -1, i;
mword desc = 0;
size_t stored_size = obj_size;
stored_size += ALLOC_ALIGN - 1;
stored_size &= ~(ALLOC_ALIGN - 1);
for (i = 0; i < numbits; ++i) {
if (bitmap [i / GC_BITS_PER_WORD] & ((gsize)1 << (i % GC_BITS_PER_WORD))) {
if (first_set < 0)
Expand All @@ -1214,23 +1223,35 @@ mono_gc_make_descr_for_object (gsize *bitmap, int numbits, size_t obj_size)
num_set++;
}
}
/*
* We don't encode the size of types that don't contain
* references because they might not be aligned, i.e. the
* bottom two bits might be set, which would clash with the
* bits we need to encode the descriptor type. Since we don't
* use the encoded size to skip objects, other than for
* processing remsets, in which case only the positions of
* references are relevant, this is not a problem.
*/
if (first_set < 0)
return DESC_TYPE_RUN_LENGTH;
g_assert (!(stored_size & 0x3));
if (stored_size <= MAX_SMALL_OBJ_SIZE) {
/* check run-length encoding first: one byte offset, one byte number of pointers
* on 64 bit archs, we can have 3 runs, just one on 32.
* It may be better to use nibbles.
*/
if (first_set < 0) {
desc = DESC_TYPE_RUN_LENGTH | stored_size;
desc = DESC_TYPE_RUN_LENGTH | (stored_size << 1);
DEBUG (6, fprintf (gc_debug_file, "Ptrfree descriptor %p, size: %zd\n", (void*)desc, stored_size));
return (void*) desc;
} else if (first_set < 256 && num_set < 256 && (first_set + num_set == last_set + 1)) {
desc = DESC_TYPE_RUN_LENGTH | stored_size | (first_set << 16) | (num_set << 24);
desc = DESC_TYPE_RUN_LENGTH | (stored_size << 1) | (first_set << 16) | (num_set << 24);
DEBUG (6, fprintf (gc_debug_file, "Runlen descriptor %p, size: %zd, first set: %d, num set: %d\n", (void*)desc, stored_size, first_set, num_set));
return (void*) desc;
}
/* we know the 2-word header is ptr-free */
if (last_set < SMALL_BITMAP_SIZE + OBJECT_HEADER_WORDS) {
desc = DESC_TYPE_SMALL_BITMAP | stored_size | ((*bitmap >> OBJECT_HEADER_WORDS) << SMALL_BITMAP_SHIFT);
desc = DESC_TYPE_SMALL_BITMAP | (stored_size << 1) | ((*bitmap >> OBJECT_HEADER_WORDS) << SMALL_BITMAP_SHIFT);
DEBUG (6, fprintf (gc_debug_file, "Smallbitmap descriptor %p, size: %zd, last set: %d\n", (void*)desc, stored_size, last_set));
return (void*) desc;
}
Expand Down Expand Up @@ -1324,11 +1345,11 @@ mono_gc_get_bitmap_for_descr (void *descr, int *numbits)
} while (0)

#define OBJ_RUN_LEN_SIZE(size,desc,obj) do { \
(size) = (desc) & 0xfff8; \
(size) = ((desc) & 0xfff8) >> 1; \
} while (0)

#define OBJ_BITMAP_SIZE(size,desc,obj) do { \
(size) = (desc) & 0xfff8; \
(size) = ((desc) & 0xfff8) >> 1; \
} while (0)

//#define PREFETCH(addr) __asm__ __volatile__ (" prefetchnta %0": : "m"(*(char *)(addr)))
Expand Down Expand Up @@ -6554,7 +6575,7 @@ mono_gc_wbarrier_value_copy (gpointer dest, gpointer src, int count, MonoClass *
LOCK_GC;
memmove (dest, src, count * mono_class_value_size (klass, NULL));
rs = REMEMBERED_SET;
if (ptr_in_nursery (dest) || ptr_on_stack (dest)) {
if (ptr_in_nursery (dest) || ptr_on_stack (dest) || !klass->has_references) {
UNLOCK_GC;
return;
}
Expand Down
12 changes: 3 additions & 9 deletions mono/metadata/sgen-scan-object.h
Expand Up @@ -24,7 +24,9 @@
*
* Scans one object, using the OBJ_XXX macros. The start of the
* object must be given in the variable "char* start". Afterwards,
* "start" will point to the start of the next object.
* "start" will point to the start of the next object, if the scanned
* object contained references. If not, the value of "start" should
* be considered undefined after executing this code.
*
* Modifiers (automatically undefined):
*
Expand Down Expand Up @@ -53,16 +55,8 @@
/* gcc should be smart enough to remove the bounds check, but it isn't:( */
desc = vt->desc;
switch (desc & 0x7) {
case DESC_TYPE_STRING:
STRING_SIZE (skip_size, start);
#define SCAN
SCAN_OBJECT_ACTION;
#undef SCAN
start += skip_size;
break;
case DESC_TYPE_RUN_LENGTH:
OBJ_RUN_LEN_SIZE (skip_size, desc, start);
g_assert (skip_size);
#define SCAN OBJ_RUN_LEN_FOREACH_PTR (desc, start)
#ifndef SCAN_OBJECT_NOSCAN
SCAN;
Expand Down

0 comments on commit 790f986

Please sign in to comment.