#include "metadata/sgen-gc.h"
#include "metadata/sgen-cardtable.h"
+#include "metadata/sgen-memory-governor.h"
#include "utils/mono-counters.h"
#include "utils/mono-time.h"
#include "utils/mono-memory-model.h"
#include "metadata/sgen-cardtable.h"
#include "metadata/sgen-ssb.h"
#include "metadata/sgen-protocol.h"
+#include "metadata/sgen-memory-governor.h"
#define LOAD_VTABLE SGEN_LOAD_VTABLE
static mword bytes_pinned_from_failed_allocation = 0;
-static mword total_alloc = 0;
/* use this to tune when to do a major/minor collection */
static mword memory_pressure = 0;
static mword minor_collection_allowance;
} while (SGEN_CAS_PTR ((gpointer*)&highest_heap_address, (gpointer)high, (gpointer)old) != (gpointer)old);
}
-static unsigned long
-prot_flags_for_activate (int activate)
-{
- unsigned long prot_flags = activate? MONO_MMAP_READ|MONO_MMAP_WRITE: MONO_MMAP_NONE;
- return prot_flags | MONO_MMAP_PRIVATE | MONO_MMAP_ANON;
-}
-
-/*
- * Allocate a big chunk of memory from the OS (usually 64KB to several megabytes).
- * This must not require any lock.
- */
-void*
-sgen_alloc_os_memory (size_t size, int activate)
-{
- void *ptr = mono_valloc (0, size, prot_flags_for_activate (activate));
- if (ptr) {
- /* FIXME: CAS */
- total_alloc += size;
- }
- return ptr;
-}
-
-/* size must be a power of 2 */
-void*
-sgen_alloc_os_memory_aligned (mword size, mword alignment, gboolean activate)
-{
- void *ptr = mono_valloc_aligned (size, alignment, prot_flags_for_activate (activate));
- if (ptr) {
- /* FIXME: CAS */
- total_alloc += size;
- }
- return ptr;
-}
-
-/*
- * Free the memory returned by sgen_alloc_os_memory (), returning it to the OS.
- */
-void
-sgen_free_os_memory (void *addr, size_t size)
-{
- mono_vfree (addr, size);
- /* FIXME: CAS */
- total_alloc -= size;
-}
-
/*
* Allocate and setup the data structures needed to be able to allocate objects
* in the nursery. The nursery is stored in nursery_section.
section = sgen_alloc_internal (INTERNAL_MEM_SECTION);
alloc_size = sgen_nursery_size;
+
+ /* If there isn't enough space even for the nursery we should simply abort. */
+ g_assert (sgen_memgov_try_alloc_space (alloc_size, SPACE_NURSERY));
+
#ifdef SGEN_ALIGN_NURSERY
data = major_collector.alloc_heap (alloc_size, alloc_size, DEFAULT_NURSERY_BITS);
#else
data = major_collector.alloc_heap (alloc_size, 0, DEFAULT_NURSERY_BITS);
#endif
sgen_update_heap_boundaries ((mword)data, (mword)(data + sgen_nursery_size));
- DEBUG (4, fprintf (gc_debug_file, "Expanding nursery size (%p-%p): %lu, total: %lu\n", data, data + alloc_size, (unsigned long)sgen_nursery_size, (unsigned long)total_alloc));
+ DEBUG (4, fprintf (gc_debug_file, "Expanding nursery size (%p-%p): %lu, total: %lu\n", data, data + alloc_size, (unsigned long)sgen_nursery_size, (unsigned long)mono_gc_get_heap_size ()));
section->data = section->next_data = data;
section->size = alloc_size;
section->end_data = data + sgen_nursery_size;
major_gc_time = mono_100ns_ticks () - major_gc_time;
mono_profiler_gc_event (MONO_GC_EVENT_END, 1);
}
- DEBUG (2, fprintf (gc_debug_file, "Heap size: %lu, LOS size: %lu\n", (unsigned long)total_alloc, (unsigned long)los_memory_usage));
+ DEBUG (2, fprintf (gc_debug_file, "Heap size: %lu, LOS size: %lu\n", (unsigned long)mono_gc_get_heap_size (), (unsigned long)los_memory_usage));
restart_world (0);
total_gc_time = mono_100ns_ticks () - total_gc_time;
return tot;
}
-int64_t
-mono_gc_get_heap_size (void)
-{
- return total_alloc;
-}
-
void
mono_gc_disable (void)
{
typedef void (*IterateObjectCallbackFunc) (char*, size_t, void*);
-void* sgen_alloc_os_memory (size_t size, int activate) MONO_INTERNAL;
-void* sgen_alloc_os_memory_aligned (mword size, mword alignment, gboolean activate) MONO_INTERNAL;
-void sgen_free_os_memory (void *addr, size_t size) MONO_INTERNAL;
-
int sgen_thread_handshake (BOOL suspend) MONO_INTERNAL;
gboolean sgen_suspend_thread (SgenThreadInfo *info) MONO_INTERNAL;
gboolean sgen_resume_thread (SgenThreadInfo *info) MONO_INTERNAL;
void sgen_gc_unlock (void) MONO_INTERNAL;
enum {
+ SPACE_NURSERY,
SPACE_MAJOR,
SPACE_LOS
};
#include "utils/mono-counters.h"
#include "metadata/sgen-gc.h"
#include "utils/lock-free-alloc.h"
+#include "metadata/sgen-memory-governor.h"
/* keep each size a multiple of ALLOC_ALIGN */
static const int allocator_sizes [] = {
#include "metadata/mono-gc.h"
#include "metadata/object-internals.h"
#include "metadata/profiler-private.h"
+#include "metadata/sgen-memory-governor.h"
#define MAJOR_SECTION_SIZE SGEN_PINNED_CHUNK_SIZE
#define BLOCK_FOR_OBJECT(o) SGEN_PINNED_CHUNK_FOR_PTR ((o))
#include "metadata/sgen-gc.h"
#include "metadata/sgen-memory-governor.h"
+#include "metadata/mono-gc.h"
+
#include "utils/mono-counters.h"
+#include "utils/mono-mmap.h"
#define MIN_MINOR_COLLECTION_ALLOWANCE ((mword)(DEFAULT_NURSERY_SIZE * SGEN_MIN_ALLOWANCE_NURSERY_SIZE_RATIO))
static mword soft_heap_limit = ((mword)0) - ((mword)1);
static mword allocated_heap;
+/*Memory usage tracking */
+static mword total_alloc = 0;
+
+/*
+Global GC memory tracking.
+This tracks the total usage of memory by the GC. This includes
+managed and unmanaged memory.
+*/
+
+static unsigned long
+prot_flags_for_activate (int activate)
+{
+ unsigned long prot_flags = activate? MONO_MMAP_READ|MONO_MMAP_WRITE: MONO_MMAP_NONE;
+ return prot_flags | MONO_MMAP_PRIVATE | MONO_MMAP_ANON;
+}
+
+/*
+ * Allocate a big chunk of memory from the OS (usually 64KB to several megabytes).
+ * This must not require any lock.
+ */
+void*
+sgen_alloc_os_memory (size_t size, int activate)
+{
+ void *ptr = mono_valloc (0, size, prot_flags_for_activate (activate));
+ if (ptr)
+ SGEN_ATOMIC_ADD_P (total_alloc, size);
+ return ptr;
+}
+
+/* size must be a power of 2 */
+void*
+sgen_alloc_os_memory_aligned (size_t size, mword alignment, gboolean activate)
+{
+ void *ptr = mono_valloc_aligned (size, alignment, prot_flags_for_activate (activate));
+ if (ptr)
+ SGEN_ATOMIC_ADD_P (total_alloc, size);
+ return ptr;
+}
+
+/*
+ * Free the memory returned by sgen_alloc_os_memory (), returning it to the OS.
+ */
+void
+sgen_free_os_memory (void *addr, size_t size)
+{
+ mono_vfree (addr, size);
+ SGEN_ATOMIC_ADD_P (total_alloc, -size);
+}
+int64_t
+mono_gc_get_heap_size (void)
+{
+ return total_alloc;
+}
+
+
+/*
+Heap Sizing limits.
+This limit the max size of the heap. It takes into account
+only memory actively in use to hold heap objects and not
+for other parts of the GC.
+ */
mword
sgen_memgov_available_free_space (void)
{
mword sgen_memgov_min_allowance (void) MONO_INTERNAL;
mword sgen_memgov_available_free_space (void) MONO_INTERNAL;
+/* OS memory allocation */
+void* sgen_alloc_os_memory (size_t size, int activate) MONO_INTERNAL;
+void* sgen_alloc_os_memory_aligned (size_t size, mword alignment, gboolean activate) MONO_INTERNAL;
+void sgen_free_os_memory (void *addr, size_t size) MONO_INTERNAL;
+
#endif
#include "utils/mono-counters.h"
#include "metadata/sgen-gc.h"
+#include "metadata/sgen-memory-governor.h"
/* Pinned objects are allocated in the LOS space if bigger than half a page
* or from freelists otherwise. We assume that pinned objects are relatively few