Author: lupus
Date: 2005-03-22 10:41:00 -0500 (Tue, 22 Mar 2005)
New Revision: 42117
Modified:
trunk/mono/mono/metadata/ChangeLog
trunk/mono/mono/metadata/class.c
Log:
Tue Mar 22 16:57:01 CET 2005 Paolo Molaro <[EMAIL PROTECTED]>
* class.c: added locking comments to some functions.
Cache the interface offsets arrays (saves about 20 KB
of runtime memory in a typical app).
Reduce the time overhead in mono_class_setup_supertypes ().
Modified: trunk/mono/mono/metadata/ChangeLog
===================================================================
--- trunk/mono/mono/metadata/ChangeLog 2005-03-22 15:32:20 UTC (rev 42116)
+++ trunk/mono/mono/metadata/ChangeLog 2005-03-22 15:41:00 UTC (rev 42117)
@@ -1,4 +1,11 @@
+Tue Mar 22 16:57:01 CET 2005 Paolo Molaro <[EMAIL PROTECTED]>
+
+ * class.c: added locking comments to some functions.
+ Cache the interface offsets arrays (saves about 20 KB
+ of runtime memory in a typical app).
+ Reduce the time overhead in mono_class_setup_supertypes ().
+
Tue Mar 22 16:35:57 CET 2005 Paolo Molaro <[EMAIL PROTECTED]>
* icall.c: speedup and fix leaks in GetMethodsByName and
Modified: trunk/mono/mono/metadata/class.c
===================================================================
--- trunk/mono/mono/metadata/class.c 2005-03-22 15:32:20 UTC (rev 42116)
+++ trunk/mono/mono/metadata/class.c 2005-03-22 15:41:00 UTC (rev 42117)
@@ -664,6 +664,9 @@
/* useful until we keep track of gc-references in corlib etc. */
#define IS_GC_REFERENCE(t) ((t)->type == MONO_TYPE_U || (t)->type ==
MONO_TYPE_I || (t)->type == MONO_TYPE_PTR)
+/*
+ * LOCKING: this is supposed to be called with the loader lock held.
+ */
void
mono_class_layout_fields (MonoClass *class)
{
@@ -1047,11 +1050,79 @@
return res;
}
+typedef struct _IOffsetInfo IOffsetInfo;
+struct _IOffsetInfo {
+ IOffsetInfo *next;
+ int size;
+ int next_free;
+ int data [MONO_ZERO_LEN_ARRAY];
+};
+
+static IOffsetInfo *cached_offset_info = NULL;
+static int next_offset_info_size = 128;
+
+static int*
+cache_interface_offsets (int max_iid, int *data)
+{
+ IOffsetInfo *cached_info;
+ int *cached;
+ int new_size;
+ for (cached_info = cached_offset_info; cached_info; cached_info =
cached_info->next) {
+ cached = cached_info->data;
+ while (cached < cached_info->data + cached_info->size &&
*cached) {
+ if (*cached == max_iid) {
+ int i, matched = TRUE;
+ cached++;
+ for (i = 0; i < max_iid; ++i) {
+ if (cached [i] != data [i]) {
+ matched = FALSE;
+ break;
+ }
+ }
+ if (matched)
+ return cached;
+ cached += max_iid;
+ } else {
+ cached += *cached + 1;
+ }
+ }
+ }
+ /* find a free slot */
+ for (cached_info = cached_offset_info; cached_info; cached_info =
cached_info->next) {
+ if (cached_info->size - cached_info->next_free >= max_iid + 1) {
+ cached = &cached_info->data [cached_info->next_free];
+ *cached++ = max_iid;
+ memcpy (cached, data, max_iid * sizeof (int));
+ cached_info->next_free += max_iid + 1;
+ return cached;
+ }
+ }
+ /* allocate a new chunk */
+ if (max_iid + 1 < next_offset_info_size) {
+ new_size = next_offset_info_size;
+ if (next_offset_info_size < 4096)
+ next_offset_info_size += next_offset_info_size >> 2;
+ } else {
+ new_size = max_iid + 1;
+ }
+ cached_info = g_malloc0 (sizeof (IOffsetInfo) + sizeof (int) *
new_size);
+ cached_info->size = new_size;
+ /*g_print ("allocated %d offset entries at %p (total: %d)\n", new_size,
cached_info->data, offset_info_total_size);*/
+ cached = &cached_info->data [0];
+ *cached++ = max_iid;
+ memcpy (cached, data, max_iid * sizeof (int));
+ cached_info->next_free += max_iid + 1;
+ cached_info->next = cached_offset_info;
+ cached_offset_info = cached_info;
+ return cached;
+}
+
static int
setup_interface_offsets (MonoClass *class, int cur_slot)
{
MonoClass *k, *ic;
int i, max_iid;
+ int *cached_data;
GPtrArray *ifaces;
/* compute maximum number of slots and maximum interface id */
@@ -1119,6 +1190,10 @@
if (MONO_CLASS_IS_INTERFACE (class))
class->interface_offsets [class->interface_id] = cur_slot;
+ cached_data = cache_interface_offsets (max_iid + 1,
class->interface_offsets);
+ g_free (class->interface_offsets);
+ class->interface_offsets = cached_data;
+
return cur_slot;
}
@@ -1150,6 +1225,9 @@
mono_loader_unlock ();
}
+/*
+ * LOCKING: this is supposed to be called with the loader lock held.
+ */
void
mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int
onum)
{
@@ -1824,6 +1902,9 @@
mono_debugger_class_init_func (class);
}
+/*
+ * LOCKING: this assumes the loader lock is held
+ */
void
mono_class_setup_mono_type (MonoClass *class)
{
@@ -1943,6 +2024,9 @@
}
}
+/*
+ * LOCKING: this assumes the loader lock is held
+ */
void
mono_class_setup_parent (MonoClass *class, MonoClass *parent)
{
@@ -2009,26 +2093,30 @@
}
+/*
+ * LOCKING: this assumes the loader lock is held
+ */
void
mono_class_setup_supertypes (MonoClass *class)
{
- MonoClass *k;
- int ms, i;
+ int ms;
if (class->supertypes)
return;
- class->idepth = 0;
- for (k = class; k ; k = k->parent) {
- class->idepth++;
- }
+ if (class->parent && !class->parent->supertypes)
+ mono_class_setup_supertypes (class->parent);
+ if (class->parent)
+ class->idepth = class->parent->idepth + 1;
+ else
+ class->idepth = 1;
ms = MAX (MONO_DEFAULT_SUPERTABLE_SIZE, class->idepth);
class->supertypes = g_new0 (MonoClass *, ms);
if (class->parent) {
- for (i = class->idepth, k = class; k ; k = k->parent)
- class->supertypes [--i] = k;
+ class->supertypes [class->idepth - 1] = class;
+ memcpy (class->supertypes, class->parent->supertypes,
class->parent->idepth * sizeof (gpointer));
} else {
class->supertypes [0] = class;
}
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches