#include <assert.h>
#include <glib.h>
+/* For dlmalloc.h */
+#define USE_DL_PREFIX 1
+
#include "mono-codeman.h"
#include "mono-mmap.h"
+#include "dlmalloc.h"
#include <mono/metadata/class-internals.h>
+#include <mono/metadata/profiler-private.h>
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
#endif
+
+/*
+ * AMD64 processors maintain icache coherency only for pages which are
+ * marked executable. Also, windows DEP requires us to obtain executable memory from
+ * malloc when using dynamic code managers. The system malloc can't do this so we use a
+ * slighly modified version of Doug Lea's Malloc package for this purpose:
+ * http://g.oswego.edu/dl/html/malloc.html
+ */
#define MIN_PAGES 16
struct _MonoCodeManager {
int dynamic;
+ int read_only;
CodeChunk *current;
CodeChunk *full;
};
cman->current = NULL;
cman->full = NULL;
cman->dynamic = 0;
+ cman->read_only = 0;
return cman;
}
for (; chunk; ) {
dead = chunk;
+ mono_profiler_code_chunk_destroy ((gpointer) dead->data);
chunk = chunk->next;
if (dead->flags == CODE_FLAG_MMAP) {
mono_vfree (dead->data, dead->size);
/* valgrind_unregister(dead->data); */
} else if (dead->flags == CODE_FLAG_MALLOC) {
- free (dead->data);
+ dlfree (dead->data);
}
free (dead);
}
memset (chunk->data, fill_value, chunk->size);
}
+/**
+ * mono_code_manager_set_read_only:
+ * @cman: a code manager
+ *
+ * Make the code manager read only, so further allocation requests cause an assert.
+ */
+void
+mono_code_manager_set_read_only (MonoCodeManager *cman)
+{
+ cman->read_only = TRUE;
+}
+
/**
* mono_code_manager_foreach:
* @cman: a code manager
}
#endif
- /* does it make sense to use the mmap-like API? */
if (flags == CODE_FLAG_MALLOC) {
- ptr = malloc (chunk_size + MIN_ALIGN - 1);
+ ptr = dlmemalign (MIN_ALIGN, chunk_size + MIN_ALIGN - 1);
if (!ptr)
return NULL;
} else {
}
if (flags == CODE_FLAG_MALLOC) {
- /*
- * AMD64 processors maintain icache coherency only for pages which are
- * marked executable.
- */
-#ifndef PLATFORM_WIN32
- {
- char *page_start = (char *) (((gssize) (ptr)) & ~ (pagesize - 1));
- int pages = ((char*)ptr + chunk_size - page_start + pagesize - 1) / pagesize;
- int err = mono_mprotect (page_start, pages * pagesize, MONO_PROT_RWX);
- assert (!err);
- }
-#endif
-
#ifdef BIND_ROOM
- /* Make sure the thunks area is zeroed */
- memset (ptr, 0, bsize);
+ /* Make sure the thunks area is zeroed */
+ memset (ptr, 0, bsize);
#endif
}
chunk = malloc (sizeof (CodeChunk));
if (!chunk) {
if (flags == CODE_FLAG_MALLOC)
- free (ptr);
+ dlfree (ptr);
else
mono_vfree (ptr, chunk_size);
return NULL;
chunk->flags = flags;
chunk->pos = bsize;
chunk->bsize = bsize;
+ mono_profiler_code_chunk_new((gpointer) chunk->data, chunk->size);
/*printf ("code chunk at: %p\n", ptr);*/
return chunk;
CodeChunk *chunk, *prev;
void *ptr;
+ g_assert (!cman->read_only);
+
/* eventually allow bigger alignments, but we need to fix the dynamic alloc code to
* handle this before
*/