X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fsgen-descriptor.h;h=f07ad4a6ba00b214189b2b51e470daea9ad21ac7;hb=c39718bbb394fe97281e6e64945b4572bef29121;hp=4753e1c2454d467024e71fa22ad3313edecb2e02;hpb=218df8c4a8613697f9231fbf41938781121a1e61;p=mono.git diff --git a/mono/metadata/sgen-descriptor.h b/mono/metadata/sgen-descriptor.h index 4753e1c2454..f07ad4a6ba0 100644 --- a/mono/metadata/sgen-descriptor.h +++ b/mono/metadata/sgen-descriptor.h @@ -1,26 +1,24 @@ /* + * sgen-descriptor.h: GC descriptors describe object layout. + * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. * Copyright 2011 Xamarin Inc (http://www.xamarin.com) - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __MONO_SGEN_DESCRIPTOR_H__ #define __MONO_SGEN_DESCRIPTOR_H__ @@ -38,9 +36,11 @@ */ #define OBJECT_HEADER_WORDS (sizeof(MonoObject)/sizeof(gpointer)) #define LOW_TYPE_BITS 3 +#define MAX_RUNLEN_OBJECT_SIZE 0xFFFF #define SMALL_BITMAP_SHIFT 16 #define SMALL_BITMAP_SIZE (GC_BITS_PER_WORD - SMALL_BITMAP_SHIFT) #define VECTOR_INFO_SHIFT 14 +#define VECTOR_KIND_SHIFT 13 #define VECTOR_ELSIZE_SHIFT 3 #define LARGE_BITMAP_SIZE (GC_BITS_PER_WORD - LOW_TYPE_BITS) #define MAX_ELEMENT_SIZE 0x3ff @@ -49,6 +49,9 @@ #define VECTOR_SUBTYPE_RUN_LEN (DESC_TYPE_V_RUN_LEN << VECTOR_INFO_SHIFT) #define VECTOR_SUBTYPE_BITMAP (DESC_TYPE_V_BITMAP << VECTOR_INFO_SHIFT) +#define VECTOR_KIND_SZARRAY (DESC_TYPE_V_SZARRAY << VECTOR_KIND_SHIFT) +#define VECTOR_KIND_ARRAY (DESC_TYPE_V_ARRAY << VECTOR_KIND_SHIFT) + /* objects are aligned to 8 bytes boundaries * A descriptor is a pointer in MonoVTable, so 32 or 64 bits of size. * The low 3 bits define the type of the descriptor. The other bits @@ -79,12 +82,16 @@ enum { * copy_object_no_checks(), without having to fetch the * object's class. */ - DESC_TYPE_RUN_LENGTH = 1, /* 15 bits aligned byte size | 1-3 (offset, numptr) bytes tuples */ + DESC_TYPE_RUN_LENGTH = 1, /* 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_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 */ + DESC_TYPE_VECTOR, /* 10 bits element size | 1 bit kind | 2 bits desc | element desc */ DESC_TYPE_LARGE_BITMAP, /* | 29-61 bitmap bits */ DESC_TYPE_COMPLEX_ARR, /* index for bitmap into complex_descriptors */ + DESC_TYPE_COMPLEX_PTRFREE, /*Nothing, used to encode large ptr objects. */ + /* values for array kind */ + DESC_TYPE_V_SZARRAY = 0, /*vector with no bounds data */ + DESC_TYPE_V_ARRAY = 1, /* array with bounds data */ /* subtypes for arrays and vectors */ DESC_TYPE_V_PTRFREE = 0,/* there are no refs: keep first so it has a zero value */ DESC_TYPE_V_REFS, /* all the array elements are refs */ @@ -106,29 +113,39 @@ enum { ROOT_DESC_TYPE_SHIFT = 3, }; -enum { - SIZE_DESC_FIXED_SIZE = 1, /* 30 bits size */ - SIZE_DESC_STRING = 2, /* nothing */ - SIZE_DESC_ARRAY = 3, /* 30 bits element size */ - SIZE_DESC_TYPE_SHIFT = 2, - SIZE_DESC_TYPE_MASK = 0x3, -}; +gsize* sgen_get_complex_descriptor (mword desc) MONO_INTERNAL; +void* sgen_get_complex_descriptor_bitmap (mword desc) MONO_INTERNAL; +MonoGCRootMarkFunc sgen_get_user_descriptor_func (mword desc) MONO_INTERNAL; -gsize* mono_sgen_get_complex_descriptor (mword desc) MONO_INTERNAL; -void* mono_sgen_get_complex_descriptor_bitmap (mword desc) MONO_INTERNAL; -MonoGCRootMarkFunc mono_sgen_get_user_descriptor_func (mword desc) MONO_INTERNAL; +static inline gboolean +sgen_gc_descr_has_references (mword desc) +{ + /*Both string and fixed size objects are encoded using a zero run RUN_LEN*/ + if ((desc & 0xffff0007) == DESC_TYPE_RUN_LENGTH) + return FALSE; -#define SGEN_VTABLE_HAS_REFERENCES(vt) (((MonoVTable*)(vt))->gc_descr != (void*)DESC_TYPE_RUN_LENGTH) -#define SGEN_CLASS_HAS_REFERENCES(c) ((c)->gc_descr != (void*)DESC_TYPE_RUN_LENGTH) + /*The array is ptr-free*/ + if ((desc & 0xC007) == (DESC_TYPE_VECTOR | VECTOR_SUBTYPE_PTRFREE)) + return FALSE; + + if ((desc & 0x7) == DESC_TYPE_COMPLEX_PTRFREE) + return FALSE; + + return TRUE; +} + +#define SGEN_VTABLE_HAS_REFERENCES(vt) (sgen_gc_descr_has_references ((mword)((MonoVTable*)(vt))->gc_descr)) +#define SGEN_CLASS_HAS_REFERENCES(c) (sgen_gc_descr_has_references ((mword)(c)->gc_descr)) +#define SGEN_OBJECT_HAS_REFERENCES(o) (SGEN_VTABLE_HAS_REFERENCES (SGEN_LOAD_VTABLE ((o)))) /* helper macros to scan and traverse objects, macros because we resue them in many functions */ #define OBJ_RUN_LEN_SIZE(size,desc,obj) do { \ - (size) = ((desc) & 0xfff8) >> 1; \ + (size) = ((desc) & 0xfff8); \ } while (0) #define OBJ_BITMAP_SIZE(size,desc,obj) do { \ - (size) = ((desc) & 0xfff8) >> 1; \ + (size) = ((desc) & 0xfff8); \ } while (0) #ifdef __GNUC__ @@ -137,6 +154,12 @@ MonoGCRootMarkFunc mono_sgen_get_user_descriptor_func (mword desc) MONO_INTERNAL #define PREFETCH(addr) #endif +#if defined(__GNUC__) && SIZEOF_VOID_P==4 +#define GNUC_BUILTIN_CTZ(bmap) __builtin_ctz(bmap) +#elif defined(__GNUC__) && SIZEOF_VOID_P==8 +#define GNUC_BUILTIN_CTZ(bmap) __builtin_ctzl(bmap) +#endif + /* code using these macros must define a HANDLE_PTR(ptr) macro that does the work */ #define OBJ_RUN_LEN_FOREACH_PTR(desc,obj) do { \ if ((desc) & 0xffff0000) { \ @@ -145,6 +168,8 @@ MonoGCRootMarkFunc mono_sgen_get_user_descriptor_func (mword desc) MONO_INTERNAL void **_objptr = (void**)(obj); \ _objptr += ((desc) >> 16) & 0xff; \ _objptr_end = _objptr + (((desc) >> 24) & 0xff); \ + HANDLE_PTR (_objptr, (obj)); \ + _objptr ++; \ while (_objptr < _objptr_end) { \ HANDLE_PTR (_objptr, (obj)); \ _objptr++; \ @@ -152,6 +177,43 @@ MonoGCRootMarkFunc mono_sgen_get_user_descriptor_func (mword desc) MONO_INTERNAL } \ } while (0) +#if defined(__GNUC__) +#define OBJ_BITMAP_FOREACH_PTR(desc,obj) do { \ + /* there are pointers */ \ + void **_objptr = (void**)(obj); \ + gsize _bmap = (desc) >> 16; \ + _objptr += OBJECT_HEADER_WORDS; \ + { \ + int _index = GNUC_BUILTIN_CTZ (_bmap); \ + _objptr += _index; \ + _bmap >>= (_index + 1); \ + HANDLE_PTR (_objptr, (obj)); \ + _objptr ++; \ + } \ + while (_bmap) { \ + int _index = GNUC_BUILTIN_CTZ (_bmap); \ + _objptr += _index; \ + _bmap >>= (_index + 1); \ + HANDLE_PTR (_objptr, (obj)); \ + _objptr ++; \ + } \ + } while (0) +#else +#define OBJ_BITMAP_FOREACH_PTR(desc,obj) do { \ + /* there are pointers */ \ + void **_objptr = (void**)(obj); \ + gsize _bmap = (desc) >> 16; \ + _objptr += OBJECT_HEADER_WORDS; \ + while (_bmap) { \ + if ((_bmap & 1)) { \ + HANDLE_PTR (_objptr, (obj)); \ + } \ + _bmap >>= 1; \ + ++_objptr; \ + } \ + } while (0) +#endif + /* a bitmap desc means that there are pointer references or we'd have * choosen run-length, instead: add an assert to check. */ @@ -172,7 +234,7 @@ MonoGCRootMarkFunc mono_sgen_get_user_descriptor_func (mword desc) MONO_INTERNAL #define OBJ_COMPLEX_FOREACH_PTR(vt,obj) do { \ /* there are pointers */ \ void **_objptr = (void**)(obj); \ - gsize *bitmap_data = mono_sgen_get_complex_descriptor ((desc)); \ + gsize *bitmap_data = sgen_get_complex_descriptor ((desc)); \ int bwords = (*bitmap_data) - 1; \ void **start_run = _objptr; \ bitmap_data++; \ @@ -198,7 +260,7 @@ MonoGCRootMarkFunc mono_sgen_get_user_descriptor_func (mword desc) MONO_INTERNAL /* this one is untested */ #define OBJ_COMPLEX_ARR_FOREACH_PTR(vt,obj) do { \ /* there are pointers */ \ - gsize *mbitmap_data = mono_sgen_get_complex_descriptor ((vt)->desc); \ + gsize *mbitmap_data = sgen_get_complex_descriptor ((vt)->desc); \ int mbwords = (*mbitmap_data++) - 1; \ int el_size = mono_array_element_size (vt->klass); \ char *e_start = (char*)(obj) + G_STRUCT_OFFSET (MonoArray, vector); \ @@ -275,4 +337,4 @@ MonoGCRootMarkFunc mono_sgen_get_user_descriptor_func (mword desc) MONO_INTERNAL } while (0) -#endif \ No newline at end of file +#endif