#include "mono/utils/atomic.h"
#include "mono/utils/mono-os-mutex.h"
#include "mono/utils/mono-coop-mutex.h"
+#include "mono/utils/ward.h"
#include "mono/sgen/sgen-conf.h"
#include "mono/sgen/sgen-hash-table.h"
#include "mono/sgen/sgen-protocol.h"
SGEN_GC_BIT_FINALIZER_AWARE = 4,
};
-void sgen_gc_init (void);
+void sgen_gc_init (void)
+ MONO_PERMIT (need (sgen_lock_gc));
void sgen_os_init (void);
extern SgenHashTable roots_hash [ROOT_TYPE_NUM];
-int sgen_register_root (char *start, size_t size, SgenDescriptor descr, int root_type, int source, const char *msg);
-void sgen_deregister_root (char* addr);
+int sgen_register_root (char *start, size_t size, SgenDescriptor descr, int root_type, int source, const char *msg)
+ MONO_PERMIT (need (sgen_lock_gc));
+void sgen_deregister_root (char* addr)
+ MONO_PERMIT (need (sgen_lock_gc));
typedef void (*IterateObjectCallbackFunc) (GCObject*, size_t, void*);
void sgen_process_togglerefs (void);
void sgen_register_test_toggleref_callback (void);
-void sgen_mark_bridge_object (GCObject *obj);
-void sgen_collect_bridge_objects (int generation, ScanCopyContext ctx);
+void sgen_mark_bridge_object (GCObject *obj)
+ MONO_PERMIT (need (sgen_gc_locked));
+void sgen_collect_bridge_objects (int generation, ScanCopyContext ctx)
+ MONO_PERMIT (need (sgen_gc_locked));
typedef gboolean (*SgenObjectPredicateFunc) (GCObject *obj, void *user_data);
-void sgen_null_links_if (SgenObjectPredicateFunc predicate, void *data, int generation, gboolean track);
+void sgen_null_links_if (SgenObjectPredicateFunc predicate, void *data, int generation, gboolean track)
+ MONO_PERMIT (need (sgen_gc_locked, sgen_world_stopped));
gboolean sgen_gc_is_object_ready_for_finalization (GCObject *object);
-void sgen_gc_lock (void);
-void sgen_gc_unlock (void);
+void sgen_gc_lock (void) MONO_PERMIT (use (sgen_lock_gc), grant (sgen_gc_locked), revoke (sgen_lock_gc));
+void sgen_gc_unlock (void) MONO_PERMIT (use (sgen_gc_locked), revoke (sgen_gc_locked), grant (sgen_lock_gc));
void sgen_queue_finalization_entry (GCObject *obj);
const char* sgen_generation_name (int generation);
-void sgen_finalize_in_range (int generation, ScanCopyContext ctx);
-void sgen_null_link_in_range (int generation, ScanCopyContext ctx, gboolean track);
-void sgen_process_fin_stage_entries (void);
+void sgen_finalize_in_range (int generation, ScanCopyContext ctx)
+ MONO_PERMIT (need (sgen_gc_locked));
+void sgen_null_link_in_range (int generation, ScanCopyContext ctx, gboolean track)
+ MONO_PERMIT (need (sgen_gc_locked, sgen_world_stopped));
+void sgen_process_fin_stage_entries (void)
+ MONO_PERMIT (need (sgen_gc_locked));
gboolean sgen_have_pending_finalizers (void);
-void sgen_object_register_for_finalization (GCObject *obj, void *user_data);
+void sgen_object_register_for_finalization (GCObject *obj, void *user_data)
+ MONO_PERMIT (need (sgen_lock_gc));
-void sgen_finalize_if (SgenObjectPredicateFunc predicate, void *user_data);
+void sgen_finalize_if (SgenObjectPredicateFunc predicate, void *user_data)
+ MONO_PERMIT (need (sgen_lock_gc));
void sgen_remove_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, int generation);
void sgen_set_suspend_finalizers (void);
void sgen_pin_object (GCObject *object, SgenGrayQueue *queue);
void sgen_set_pinned_from_failed_allocation (mword objsize);
-void sgen_ensure_free_space (size_t size, int generation);
-void sgen_gc_collect (int generation);
-void sgen_perform_collection (size_t requested_size, int generation_to_collect, const char *reason, gboolean wait_to_finish, gboolean stw);
+void sgen_ensure_free_space (size_t size, int generation)
+ MONO_PERMIT (need (sgen_gc_locked, sgen_stop_world));
+void sgen_gc_collect (int generation)
+ MONO_PERMIT (need (sgen_lock_gc, sgen_stop_world));
+void sgen_perform_collection (size_t requested_size, int generation_to_collect, const char *reason, gboolean wait_to_finish, gboolean stw)
+ MONO_PERMIT (need (sgen_gc_locked, sgen_stop_world));
int sgen_gc_collection_count (int generation);
/* FIXME: what exactly does this return? */
-size_t sgen_gc_get_used_size (void);
+size_t sgen_gc_get_used_size (void)
+ MONO_PERMIT (need (sgen_lock_gc));
size_t sgen_gc_get_total_heap_allocation (void);
/* STW */
-void sgen_stop_world (int generation);
-void sgen_restart_world (int generation);
+void sgen_stop_world (int generation)
+ MONO_PERMIT (need (sgen_gc_locked), use (sgen_stop_world), grant (sgen_world_stopped), revoke (sgen_stop_world));
+void sgen_restart_world (int generation)
+ MONO_PERMIT (need (sgen_gc_locked), use (sgen_world_stopped), revoke (sgen_world_stopped), grant (sgen_stop_world));
gboolean sgen_is_world_stopped (void);
gboolean sgen_set_allow_synchronous_major (gboolean flag);
extern mword los_memory_usage_total;
void sgen_los_free_object (LOSObject *obj);
-void* sgen_los_alloc_large_inner (GCVTable vtable, size_t size);
+void* sgen_los_alloc_large_inner (GCVTable vtable, size_t size)
+ MONO_PERMIT (need (sgen_gc_locked, sgen_stop_world));
void sgen_los_sweep (void);
gboolean sgen_ptr_is_in_los (char *ptr, char **start);
void sgen_los_iterate_objects (IterateObjectCallbackFunc cb, void *user_data);
GCObject* sgen_alloc_for_promotion (GCObject *obj, size_t objsize, gboolean has_references);
-GCObject* sgen_alloc_obj_nolock (GCVTable vtable, size_t size);
+GCObject* sgen_alloc_obj_nolock (GCVTable vtable, size_t size)
+ MONO_PERMIT (need (sgen_gc_locked, sgen_stop_world));
GCObject* sgen_try_alloc_obj_nolock (GCVTable vtable, size_t size);
/* Threads */
return sgen_major_is_object_alive (object);
}
-int sgen_gc_invoke_finalizers (void);
+int sgen_gc_invoke_finalizers (void)
+ MONO_PERMIT (need (sgen_lock_gc));
/* GC handles */
void sgen_init_gchandles (void);
-void sgen_null_links_if (SgenObjectPredicateFunc predicate, void *data, int generation, gboolean track);
+void sgen_null_links_if (SgenObjectPredicateFunc predicate, void *data, int generation, gboolean track)
+ MONO_PERMIT (need (sgen_gc_locked));
typedef gpointer (*SgenGCHandleIterateCallback) (gpointer hidden, GCHandleType handle_type, int max_generation, gpointer user);
guint32 sgen_gchandle_new (GCObject *obj, gboolean pinned);
guint32 sgen_gchandle_new_weakref (GCObject *obj, gboolean track_resurrection);
-void sgen_gchandle_iterate (GCHandleType handle_type, int max_generation, SgenGCHandleIterateCallback callback, gpointer user);
+void sgen_gchandle_iterate (GCHandleType handle_type, int max_generation, SgenGCHandleIterateCallback callback, gpointer user)
+ MONO_PERMIT (need (sgen_world_stopped));
void sgen_gchandle_set_target (guint32 gchandle, GCObject *obj);
-void sgen_mark_normal_gc_handles (void *addr, SgenUserMarkFunc mark_func, void *gc_data);
+void sgen_mark_normal_gc_handles (void *addr, SgenUserMarkFunc mark_func, void *gc_data)
+ MONO_PERMIT (need (sgen_world_stopped));
gpointer sgen_gchandle_get_metadata (guint32 gchandle);
GCObject *sgen_gchandle_get_target (guint32 gchandle);
void sgen_gchandle_free (guint32 gchandle);
void sgen_clear_tlabs (void);
-GCObject* sgen_alloc_obj (GCVTable vtable, size_t size);
-GCObject* sgen_alloc_obj_pinned (GCVTable vtable, size_t size);
-GCObject* sgen_alloc_obj_mature (GCVTable vtable, size_t size);
+GCObject* sgen_alloc_obj (GCVTable vtable, size_t size)
+ MONO_PERMIT (need (sgen_lock_gc, sgen_stop_world));
+GCObject* sgen_alloc_obj_pinned (GCVTable vtable, size_t size)
+ MONO_PERMIT (need (sgen_lock_gc, sgen_stop_world));
+GCObject* sgen_alloc_obj_mature (GCVTable vtable, size_t size)
+ MONO_PERMIT (need (sgen_lock_gc, sgen_stop_world));
/* Debug support */
void sgen_check_mod_union_consistency (void);
void sgen_check_major_refs (void);
void sgen_check_whole_heap (gboolean allow_missing_pinning);
-void sgen_check_whole_heap_stw (void);
+void sgen_check_whole_heap_stw (void)
+ MONO_PERMIT (need (sgen_gc_locked, sgen_stop_world));
void sgen_check_objref (char *obj);
void sgen_check_heap_marked (gboolean nursery_must_be_pinned);
void sgen_check_nursery_objects_pinned (gboolean pinned);