*
* Copyright 2011 Novell, Inc (http://www.novell.com)
* Copyright 2011 Xamarin Inc (http://www.xamarin.com)
- *
- * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
- * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
- *
- * Permission is hereby granted to use or copy this program
- * for any purpose, provided the above notices are retained on all copies.
- * Permission to modify the code and to distribute modified code is granted,
- * provided the above notices are retained, and a notice that the code was
- * modified is included with the above copyright notice.
- *
- *
* Copyright 2001-2003 Ximian, Inc
* Copyright 2003-2010 Novell, Inc.
- *
- * 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.
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include "config.h"
#include <stdlib.h>
-#include "sgen-gc.h"
-#include "sgen-bridge.h"
-#include "sgen-hash-table.h"
-#include "sgen-qsort.h"
-#include "utils/mono-logger-internal.h"
-#include "utils/mono-time.h"
-#include "utils/mono-compiler.h"
-
+#include "sgen/sgen-gc.h"
+#include "sgen-bridge-internals.h"
+#include "sgen/sgen-hash-table.h"
+#include "sgen/sgen-qsort.h"
+#include "sgen/sgen-client.h"
+#include "utils/mono-logger-internals.h"
typedef struct {
int size;
* just one source, so use the srcs pointer itself.
*/
typedef struct _HashEntry {
- MonoObject *obj; /* This is a duplicate - it's already stored in the hash table */
+ GCObject *obj; /* This is a duplicate - it's already stored in the hash table */
gboolean is_bridge;
gboolean is_visited;
while (capacity > da->capacity)
da->capacity *= 2;
- new_data = sgen_alloc_internal_dynamic (elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA, TRUE);
+ new_data = (char *)sgen_alloc_internal_dynamic (elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA, TRUE);
memcpy (new_data, da->data, elem_size * da->size);
sgen_free_internal_dynamic (da->data, elem_size * old_capacity, INTERNAL_MEM_BRIDGE_DATA);
da->data = new_data;
static void
dyn_array_int_add (DynIntArray *da, int x)
{
- int *p = dyn_array_add (&da->array, sizeof (int));
+ int *p = (int *)dyn_array_add (&da->array, sizeof (int));
*p = x;
}
static void
dyn_array_ptr_add (DynPtrArray *da, void *ptr)
{
- void **p = dyn_array_add (&da->array, sizeof (void*));
+ void **p = (void **)dyn_array_add (&da->array, sizeof (void*));
*p = ptr;
}
static SCC*
dyn_array_scc_add (DynSCCArray *da)
{
- return dyn_array_add (&da->array, sizeof (SCC));
+ return (SCC *)dyn_array_add (&da->array, sizeof (SCC));
}
static SCC*
}
static MonoGCBridgeObjectKind
-class_kind (MonoClass *class)
+class_kind (MonoClass *klass)
{
- return bridge_callbacks.bridge_class_kind (class);
+ return bridge_callbacks.bridge_class_kind (klass);
}
static HashEntry*
-get_hash_entry (MonoObject *obj, gboolean *existing)
+get_hash_entry (GCObject *obj, gboolean *existing)
{
- HashEntry *entry = sgen_hash_table_lookup (&hash_table, obj);
+ HashEntry *entry = (HashEntry *)sgen_hash_table_lookup (&hash_table, obj);
HashEntry new_entry;
if (entry) {
sgen_hash_table_replace (&hash_table, obj, &new_entry, NULL);
- return sgen_hash_table_lookup (&hash_table, obj);
+ return (HashEntry *)sgen_hash_table_lookup (&hash_table, obj);
}
static void
static void
free_data (void)
{
- MonoObject *obj G_GNUC_UNUSED;
+ GCObject *obj G_GNUC_UNUSED;
HashEntry *entry;
int total_srcs = 0;
int max_srcs = 0;
- SGEN_HASH_TABLE_FOREACH (&hash_table, obj, entry) {
+ SGEN_HASH_TABLE_FOREACH (&hash_table, GCObject *, obj, HashEntry *, entry) {
int entry_size = dyn_array_ptr_size (&entry->srcs);
total_srcs += entry_size;
if (entry_size > max_srcs)
}
static HashEntry*
-register_bridge_object (MonoObject *obj)
+register_bridge_object (GCObject *obj)
{
HashEntry *entry = get_hash_entry (obj, NULL);
entry->is_bridge = TRUE;
}
static gboolean
-object_is_live (MonoObject **objp)
+object_is_live (GCObject **objp)
{
- MonoObject *obj = *objp;
- MonoObject *fwd = SGEN_OBJECT_IS_FORWARDED (obj);
+ GCObject *obj = *objp;
+ GCObject *fwd = SGEN_OBJECT_IS_FORWARDED (obj);
if (fwd) {
*objp = fwd;
return sgen_hash_table_lookup (&hash_table, fwd) == NULL;
#undef HANDLE_PTR
#define HANDLE_PTR(ptr,obj) do { \
- MonoObject *dst = (MonoObject*)*(ptr); \
+ GCObject *dst = (GCObject*)*(ptr); \
if (dst && !object_is_live (&dst)) { \
dyn_array_ptr_push (&dfs_stack, obj_entry); \
dyn_array_ptr_push (&dfs_stack, get_hash_entry (dst, NULL)); \
dyn_array_ptr_push (&dfs_stack, obj_entry);
do {
- MonoObject *obj;
- char *start;
+ GCObject *obj;
++dfs1_passes;
- obj_entry = dyn_array_ptr_pop (&dfs_stack);
+ obj_entry = (HashEntry *)dyn_array_ptr_pop (&dfs_stack);
if (obj_entry) {
+ char *start;
mword desc;
- src = dyn_array_ptr_pop (&dfs_stack);
+ src = (HashEntry *)dyn_array_ptr_pop (&dfs_stack);
obj = obj_entry->obj;
- start = (char*)obj;
- desc = sgen_obj_get_descriptor_safe (start);
+ desc = sgen_obj_get_descriptor_safe (obj);
if (src) {
//g_print ("link %s -> %s\n", sgen_safe_name (src->obj), sgen_safe_name (obj));
/* NULL marks that the next entry is to be finished */
dyn_array_ptr_push (&dfs_stack, NULL);
-#include "sgen-scan-object.h"
+ start = (char*)obj;
+#include "sgen/sgen-scan-object.h"
} else {
- obj_entry = dyn_array_ptr_pop (&dfs_stack);
+ obj_entry = (HashEntry *)dyn_array_ptr_pop (&dfs_stack);
//g_print ("finish %s\n", sgen_safe_name (obj_entry->obj));
register_finishing_time (obj_entry, current_time++);
dyn_array_ptr_push (&dfs_stack, entry);
do {
- entry = dyn_array_ptr_pop (&dfs_stack);
+ entry = (HashEntry *)dyn_array_ptr_pop (&dfs_stack);
++dfs2_passes;
if (entry->scc_index >= 0) {
DEF_QSORT_INLINE(hash_entries, HashEntry*, compare_hash_entries)
-static unsigned long step_1, step_2, step_3, step_4, step_5, step_6;
+static gint64 step_1, step_2, step_3, step_4, step_5, step_6;
static int fist_pass_links, second_pass_links, sccs_links;
static int max_sccs_links = 0;
static void
-register_finalized_object (MonoObject *obj)
+register_finalized_object (GCObject *obj)
{
g_assert (sgen_need_bridge_processing ());
dyn_array_ptr_push (®istered_bridges, obj);
*/
bridge_count = dyn_array_ptr_size (®istered_bridges);
for (i = 0; i < bridge_count ; ++i)
- register_bridge_object (dyn_array_ptr_get (®istered_bridges, i));
+ register_bridge_object ((GCObject *)dyn_array_ptr_get (®istered_bridges, i));
for (i = 0; i < bridge_count; ++i)
- dfs1 (get_hash_entry (dyn_array_ptr_get (®istered_bridges, i), NULL));
+ dfs1 (get_hash_entry ((GCObject *)dyn_array_ptr_get (®istered_bridges, i), NULL));
SGEN_TV_GETTIME (atv);
step_2 = SGEN_TV_ELAPSED (btv, atv);
int i, j;
int num_sccs, num_xrefs;
int max_entries, max_xrefs;
- MonoObject *obj G_GNUC_UNUSED;
+ GCObject *obj G_GNUC_UNUSED;
HashEntry *entry;
HashEntry **all_entries;
MonoGCBridgeSCC **api_sccs;
/* alloc and fill array of all entries */
- all_entries = sgen_alloc_internal_dynamic (sizeof (HashEntry*) * hash_table.num_entries, INTERNAL_MEM_BRIDGE_DATA, TRUE);
+ all_entries = (HashEntry **)sgen_alloc_internal_dynamic (sizeof (HashEntry*) * hash_table.num_entries, INTERNAL_MEM_BRIDGE_DATA, TRUE);
j = 0;
- SGEN_HASH_TABLE_FOREACH (&hash_table, obj, entry) {
+ SGEN_HASH_TABLE_FOREACH (&hash_table, GCObject *, obj, HashEntry *, entry) {
g_assert (entry->finishing_time >= 0);
all_entries [j++] = entry;
fist_pass_links += dyn_array_ptr_size (&entry->srcs);
for (i = 0; i < hash_table.num_entries; ++i) {
HashEntryWithAccounting *entry = (HashEntryWithAccounting*)all_entries [i];
if (entry->entry.is_bridge) {
- MonoClass *klass = ((MonoVTable*)SGEN_LOAD_VTABLE (entry->entry.obj))->klass;
+ MonoClass *klass = SGEN_LOAD_VTABLE (entry->entry.obj)->klass;
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "OBJECT %s::%s (%p) weight %f", klass->name_space, klass->name, entry->entry.obj, entry->weight);
}
}
max_sccs_links = MAX (max_sccs_links, dyn_array_int_size (&scc->xrefs));
}
- api_sccs = sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeSCC*) * num_sccs, INTERNAL_MEM_BRIDGE_DATA, TRUE);
+ api_sccs = (MonoGCBridgeSCC **)sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeSCC*) * num_sccs, INTERNAL_MEM_BRIDGE_DATA, TRUE);
num_xrefs = 0;
j = 0;
for (i = 0; i < dyn_array_scc_size (&sccs); ++i) {
if (!scc->num_bridge_entries)
continue;
- api_sccs [j] = sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeSCC) + sizeof (MonoObject*) * scc->num_bridge_entries, INTERNAL_MEM_BRIDGE_DATA, TRUE);
+ api_sccs [j] = (MonoGCBridgeSCC *)sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeSCC) + sizeof (MonoObject*) * scc->num_bridge_entries, INTERNAL_MEM_BRIDGE_DATA, TRUE);
api_sccs [j]->is_alive = FALSE;
api_sccs [j]->num_objs = scc->num_bridge_entries;
scc->num_bridge_entries = 0;
num_xrefs += dyn_array_int_size (&scc->xrefs);
}
- SGEN_HASH_TABLE_FOREACH (&hash_table, obj, entry) {
+ SGEN_HASH_TABLE_FOREACH (&hash_table, GCObject *, obj, HashEntry *, entry) {
if (entry->is_bridge) {
SCC *scc = dyn_array_scc_get_ptr (&sccs, entry->scc_index);
- api_sccs [scc->api_index]->objs [scc->num_bridge_entries++] = entry->obj;
+ api_sccs [scc->api_index]->objs [scc->num_bridge_entries++] = (MonoObject*)entry->obj;
}
} SGEN_HASH_TABLE_FOREACH_END;
- api_xrefs = sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeXRef) * num_xrefs, INTERNAL_MEM_BRIDGE_DATA, TRUE);
+ api_xrefs = (MonoGCBridgeXRef *)sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeXRef) * num_xrefs, INTERNAL_MEM_BRIDGE_DATA, TRUE);
j = 0;
for (i = 0; i < dyn_array_scc_size (&sccs); ++i) {
int k;
if (bridge_accounting_enabled) {
for (i = 0; i < num_sccs; ++i) {
- for (j = 0; j < api_sccs [i]->num_objs; ++j)
+ for (j = 0; j < api_sccs [i]->num_objs; ++j) {
+ GCVTable vtable = SGEN_LOAD_VTABLE (api_sccs [i]->objs [j]);
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC,
- "OBJECT %s (%p) SCC [%d] %s",
- sgen_safe_name (api_sccs [i]->objs [j]), api_sccs [i]->objs [j],
+ "OBJECT %s.%s (%p) SCC [%d] %s",
+ sgen_client_vtable_get_namespace (vtable), sgen_client_vtable_get_name (vtable), api_sccs [i]->objs [j],
i,
api_sccs [i]->is_alive ? "ALIVE" : "DEAD");
+ }
}
}
}
static void
-describe_pointer (MonoObject *obj)
+describe_pointer (GCObject *obj)
{
HashEntry *entry;
int i;
}
}
- entry = sgen_hash_table_lookup (&hash_table, obj);
+ entry = (HashEntry *)sgen_hash_table_lookup (&hash_table, obj);
if (!entry)
return;