NaCl runtime fixes
[mono.git] / mono / utils / mono-codeman.c
index 22284de611372e714dadb49096f901fd40c1dd5a..dcee2a99b3e28e16ecea4ebddc4de6e968b151e8 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "mono-codeman.h"
 #include "mono-mmap.h"
+#include "mono-counters.h"
 #include "dlmalloc.h"
 #include <mono/metadata/class-internals.h>
 #include <mono/metadata/profiler-private.h>
 
 #if defined(__native_client_codegen__) && defined(__native_client__)
 #include <malloc.h>
-#include <sys/nacl_syscalls.h>
+#include <nacl/nacl_dyncode.h>
 #endif
 
+static uintptr_t code_memory_used = 0;
+
 /*
  * AMD64 processors maintain icache coherency only for pages which are 
  * marked executable. Also, windows DEP requires us to obtain executable memory from
@@ -88,7 +91,7 @@ struct _MonoCodeManager {
        CodeChunk *current;
        CodeChunk *full;
 #if defined(__native_client_codegen__) && defined(__native_client__)
-       MonoGHashTable *hash;
+       GHashTable *hash;
 #endif
 };
 
@@ -225,14 +228,16 @@ mono_code_manager_new (void)
        if (next_dynamic_code_addr == NULL) {
                const guint kPageMask = 0xFFFF; /* 64K pages */
                next_dynamic_code_addr = (uintptr_t)(etext + kPageMask) & ~kPageMask;
+#if defined (__GLIBC__)
+               /* TODO: For now, just jump 64MB ahead to avoid dynamic libraries. */
+               next_dynamic_code_addr += (uintptr_t)0x4000000;
+#else
                /* Workaround bug in service runtime, unable to allocate */
                /* from the first page in the dynamic code section.    */
-               /* TODO: remove */
                next_dynamic_code_addr += (uintptr_t)0x10000;
+#endif
        }
-       cman->hash =  mono_g_hash_table_new (NULL, NULL);
-       /* Keep the hash table from being collected */
-       mono_gc_register_root (&cman->hash, sizeof (void*), NULL);
+       cman->hash =  g_hash_table_new (NULL, NULL);
        if (patch_source_base == NULL) {
                patch_source_base = g_malloc (kMaxPatchDepth * sizeof(unsigned char *));
                patch_dest_base = g_malloc (kMaxPatchDepth * sizeof(unsigned char *));
@@ -284,6 +289,7 @@ free_chunklist (CodeChunk *chunk)
                } else if (dead->flags == CODE_FLAG_MALLOC) {
                        dlfree (dead->data);
                }
+               code_memory_used -= dead->size;
                free (dead);
        }
 }
@@ -451,6 +457,8 @@ new_codechunk (int dynamic, int size)
        chunk->bsize = bsize;
        mono_profiler_code_chunk_new((gpointer) chunk->data, chunk->size);
 
+       code_memory_used += chunk_size;
+       mono_runtime_resource_check_limit (MONO_RESOURCE_JIT_CODE, code_memory_used);
        /*printf ("code chunk at: %p\n", ptr);*/
        return chunk;
 }
@@ -540,7 +548,7 @@ mono_code_manager_reserve_align (MonoCodeManager *cman, int size, int alignment)
        /* Allocate code space from the service runtime */
        code_ptr = allocate_code (size);
        /* Insert pointer to code space in hash, keyed by buffer ptr */
-       mono_g_hash_table_insert (cman->hash, temp_ptr, code_ptr);
+       g_hash_table_insert (cman->hash, temp_ptr, code_ptr);
 
        nacl_jit_check_init ();
 
@@ -592,7 +600,7 @@ mono_code_manager_commit (MonoCodeManager *cman, void *data, int size, int newsi
        unsigned char *code;
        int status;
        g_assert (newsize <= size);
-       code = mono_g_hash_table_lookup (cman->hash, data);
+       code = g_hash_table_lookup (cman->hash, data);
        g_assert (code != NULL);
        /* Pad space after code with HLTs */
        /* TODO: this is x86/amd64 specific */
@@ -602,9 +610,15 @@ mono_code_manager_commit (MonoCodeManager *cman, void *data, int size, int newsi
        }
        status = nacl_dyncode_create (code, data, newsize);
        if (status != 0) {
+               unsigned char *codep;
+               fprintf(stderr, "Error creating Native Client dynamic code section attempted to be\n"
+                               "emitted at %p (hex dissasembly of code follows):\n", code);
+               for (codep = data; codep < data + newsize; codep++)
+                       fprintf(stderr, "%02x ", *codep);
+               fprintf(stderr, "\n");
                g_assert_not_reached ();
        }
-       mono_g_hash_table_remove (cman->hash, data);
+       g_hash_table_remove (cman->hash, data);
        g_assert (data == patch_source_base[patch_current_depth]);
        g_assert (code == patch_dest_base[patch_current_depth]);
        patch_current_depth--;
@@ -617,7 +631,7 @@ mono_code_manager_commit (MonoCodeManager *cman, void *data, int size, int newsi
 void *
 nacl_code_manager_get_code_dest (MonoCodeManager *cman, void *data)
 {
-       return mono_g_hash_table_lookup (cman->hash, data);
+       return g_hash_table_lookup (cman->hash, data);
 }
 #endif