#include <glib.h>
#include <mono/metadata/handle.h>
-#include <mono/metadata/handle-private.h>
#include <mono/metadata/object-internals.h>
#include <mono/metadata/gc-internals.h>
#include <mono/utils/atomic.h>
#include <mono/utils/mono-lazy-init.h>
+#include <mono/utils/mono-threads.h>
-#define HANDLES_PER_CHUNK (16 - 3)
+#define HANDLES_PER_CHUNK (16 - 2)
typedef struct _MonoHandleArenaChunk MonoHandleArenaChunk;
struct _MonoHandleArenaChunk {
MonoHandleArenaChunk *next;
- gsize handles_capacity;
gsize handles_size;
- MonoHandleStorage handles [MONO_ZERO_LEN_ARRAY];
+ MonoHandleStorage handles [HANDLES_PER_CHUNK];
};
struct _MonoHandleArena {
static mono_lazy_init_t arena_status = MONO_LAZY_INIT_STATUS_NOT_INITIALIZED;
-#ifdef HAVE_SGEN_GC
static MonoGCDescriptor arena_desc = MONO_GC_DESCRIPTOR_NULL;
-#endif
static MonoHandleArenaChunk *chunk_free_list = NULL;
if (!old) {
MonoHandleArenaChunk *chunk;
- chunk = g_malloc0 (sizeof (MonoHandleArenaChunk) + sizeof (MonoHandleStorage) * (HANDLES_PER_CHUNK - MONO_ZERO_LEN_ARRAY));
- chunk->handles_capacity = HANDLES_PER_CHUNK;
+ chunk = g_malloc0 (sizeof (MonoHandleArenaChunk));
+ g_assert (chunk);
return chunk;
}
chunk = arena->chunk_last;
- if (chunk->handles_size < chunk->handles_capacity) {
- chunk->handles [chunk->handles_size].obj = obj;
+ if (chunk->handles_size < HANDLES_PER_CHUNK) {
+ chunk->handles [chunk->handles_size].__private_obj = obj;
chunk->handles_size += 1;
return &chunk->handles [chunk->handles_size - 1];
chunk = chunk->next = chunk_alloc ();
- chunk->handles [0].obj = obj;
+ chunk->handles [0].__private_obj = obj;
chunk->handles_size = 1;
arena->chunk_last = chunk;
return handle_new (arena, obj);
}
-MonoHandle
-mono_handle_new (MonoObject *obj)
-{
- /* TODO: finish implementation by placing an arena somewhere
- * in the current thread */
- g_assert_not_reached ();
- MonoHandleArena *arena = NULL;
- return mono_handle_arena_new (arena, obj);
-}
-
/*
* Elevate the handle to the parent arena
*/
g_assert (arena);
g_assert (arena->prev);
- return handle_new (arena->prev, handle->obj);
-}
-
-MonoHandle
-mono_handle_elevate (MonoHandle handle)
-{
- /* TODO: finish implementation by placing an arena somewhere
- * in the current thread */
- g_assert_not_reached ();
- MonoHandleArena *arena = NULL;
- return mono_handle_arena_elevate (arena, handle);
+ return handle_new (arena->prev, handle->__private_obj);
}
gsize
-mono_handle_arena_size (gsize nb_handles)
+mono_handle_arena_size (void)
{
- g_assert (nb_handles > 0);
- return sizeof (MonoHandleArena) + sizeof (MonoHandleArenaChunk) + sizeof (MonoHandle) * (MAX (nb_handles, HANDLES_PER_CHUNK) - MONO_ZERO_LEN_ARRAY);
+ return sizeof (MonoHandleArena) + sizeof (MonoHandleArenaChunk);
}
void
-mono_handle_arena_stack_push(MonoHandleArena **arena_stack, MonoHandleArena *arena, gsize nb_handles)
+mono_handle_arena_stack_push(MonoHandleArena **arena_stack, MonoHandleArena *arena)
{
g_assert (arena_stack);
g_assert (arena);
arena->chunk = arena->chunk_last = (MonoHandleArenaChunk*) (((char*) arena) + sizeof (MonoHandleArena));
arena->chunk->next = NULL;
- arena->chunk->handles_capacity = MAX (nb_handles, HANDLES_PER_CHUNK);
arena->chunk->handles_size = 0;
- memset (&arena->chunk->handles [0], 0, sizeof (MonoHandle) * arena->chunk->handles_capacity);
+ memset (&arena->chunk->handles [0], 0, sizeof (MonoHandleStorage) * HANDLES_PER_CHUNK);
*arena_stack = arena;
}
void
-mono_handle_arena_stack_pop(MonoHandleArena **arena_stack, MonoHandleArena *arena, gsize nb_handles)
+mono_handle_arena_stack_pop(MonoHandleArena **arena_stack, MonoHandleArena *arena)
{
MonoHandleArenaChunk *chunk, *next;
for (chunk = arena->chunk; chunk; chunk = next) {
next = chunk->next;
- memset (&chunk->handles [0], 0, sizeof (MonoHandle) * chunk->handles_capacity);
+ memset (&chunk->handles [0], 0, sizeof (MonoHandleStorage) * HANDLES_PER_CHUNK);
if (chunk != arena->chunk)
chunk_free (chunk);
}
for (arena = *(MonoHandleArena**) addr; arena; arena = arena->prev) {
for (chunk = arena->chunk; chunk; chunk = chunk->next) {
for (i = 0; i < chunk->handles_size; ++i) {
- if (chunk->handles [i].obj != NULL)
- mark_func (&chunk->handles [i].obj, gc_data);
+ if (chunk->handles [i].__private_obj != NULL)
+ mark_func (&chunk->handles [i].__private_obj, gc_data);
}
}
}
static void
initialize (void)
{
-#ifdef HAVE_SGEN_GC
arena_desc = mono_gc_make_root_descr_user (arena_scan);
-#endif
}
void
mono_handle_arena_initialize (MonoHandleArena **arena_stack)
{
-#ifdef HAVE_SGEN_GC
mono_lazy_initialize (&arena_status, initialize);
mono_gc_register_root ((char*) arena_stack, sizeof (MonoHandleArena*), arena_desc, MONO_ROOT_SOURCE_HANDLE, "runtime threads handle arena");
-#endif
}
void
mono_handle_arena_deinitialize (MonoHandleArena **arena_stack)
{
-#ifdef HAVE_SGEN_GC
mono_gc_deregister_root ((char*) arena_stack);
-#endif
}
+MonoHandleArena*
+mono_handle_arena_current (void)
+{
+ return (MonoHandleArena*) mono_thread_info_current ()->handle_arena;
+}
+
+MonoHandleArena**
+mono_handle_arena_current_addr (void)
+{
+ return (MonoHandleArena**) &mono_thread_info_current ()->handle_arena;
+}