MonoAotFileFlags flags;
MonoDynamicStream blob;
gboolean blob_closed;
- MonoClass **typespec_classes;
+ GHashTable *typespec_classes;
GString *llc_args;
GString *as_args;
char *assembly_name_sym;
mono_img_writer_emit_byte (acfg->w, val);
}
-#ifdef __native_client_codegen__
-static inline void
-emit_nacl_call_alignment (MonoAotCompile *acfg)
-{
- mono_img_writer_emit_nacl_call_alignment (acfg->w);
-}
-#endif
-
#if defined(TARGET_WIN32) && defined(TARGET_X86)
static G_GNUC_UNUSED void
#else
#define AOT_FUNC_ALIGNMENT 16
#endif
-#if (defined(TARGET_X86) || defined(TARGET_AMD64)) && defined(__native_client_codegen__)
-#undef AOT_FUNC_ALIGNMENT
-#define AOT_FUNC_ALIGNMENT 32
-#endif
#if defined(TARGET_POWERPC64) && !defined(__mono_ilp32__)
#define PPC_LD_OP "ld"
arch_emit_plt_entry (MonoAotCompile *acfg, const char *got_symbol, int offset, int info_offset)
{
#if defined(TARGET_X86)
-#if defined(__default_codegen__)
/* jmp *<offset>(%ebx) */
emit_byte (acfg, 0xff);
emit_byte (acfg, 0xa3);
emit_int32 (acfg, offset);
/* Used by mono_aot_get_plt_info_offset */
emit_int32 (acfg, info_offset);
-#elif defined(__native_client_codegen__)
- const guint8 kSizeOfNaClJmp = 11;
- guint8 bytes[kSizeOfNaClJmp];
- guint8 *pbytes = &bytes[0];
-
- x86_jump_membase32 (pbytes, X86_EBX, offset);
- emit_bytes (acfg, bytes, kSizeOfNaClJmp);
- /* four bytes of data, used by mono_arch_patch_plt_entry */
- /* For Native Client, make this work with data embedded in push. */
- emit_byte (acfg, 0x68); /* hide data in a push */
- emit_int32 (acfg, info_offset);
- emit_alignment (acfg, AOT_FUNC_ALIGNMENT);
-#endif /*__native_client_codegen__*/
#elif defined(TARGET_AMD64)
-#if defined(__default_codegen__)
emit_unset_mode (acfg);
fprintf (acfg->fp, "jmp *%s+%d(%%rip)\n", got_symbol, offset);
/* Used by mono_aot_get_plt_info_offset */
emit_int32 (acfg, info_offset);
acfg->stats.plt_size += 10;
-#elif defined(__native_client_codegen__)
- guint8 buf [256];
- guint8 *buf_aligned = ALIGN_TO(buf, kNaClAlignment);
- guint8 *code = buf_aligned;
-
- /* mov <OFFSET>(%rip), %r11d */
- emit_byte (acfg, '\x45');
- emit_byte (acfg, '\x8b');
- emit_byte (acfg, '\x1d');
- emit_symbol_diff (acfg, got_symbol, ".", offset - 4);
-
- amd64_jump_reg (code, AMD64_R11);
- /* This should be constant for the plt patch */
- g_assert ((size_t)(code-buf_aligned) == 10);
- emit_bytes (acfg, buf_aligned, code - buf_aligned);
-
- /* Hide data in a push imm32 so it passes validation */
- emit_byte (acfg, 0x68); /* push */
- emit_int32 (acfg, info_offset);
- emit_alignment (acfg, AOT_FUNC_ALIGNMENT);
-#endif /*__native_client_codegen__*/
#elif defined(TARGET_ARM)
guint8 buf [256];
guint8 *code;
* - all the trampolines should be of the same length.
*/
#if defined(TARGET_AMD64)
-#if defined(__default_codegen__)
/* This should be exactly 8 bytes long */
*tramp_size = 8;
/* call *<offset>(%rip) */
emit_symbol_diff (acfg, acfg->got_symbol, ".", (offset * sizeof (gpointer)) - 4);
emit_zero_bytes (acfg, 1);
}
-#elif defined(__native_client_codegen__)
- guint8 buf [256];
- guint8 *buf_aligned = ALIGN_TO(buf, kNaClAlignment);
- guint8 *code = buf_aligned;
- guint8 *call_start;
- size_t call_len;
- int got_offset;
-
- /* Emit this call in 'code' so we can find out how long it is. */
- amd64_call_reg (code, AMD64_R11);
- call_start = mono_arch_nacl_skip_nops (buf_aligned);
- call_len = code - call_start;
-
- /* The tramp_size is twice the NaCl alignment because it starts with */
- /* a call which needs to be aligned to the end of the boundary. */
- *tramp_size = kNaClAlignment*2;
- {
- /* Emit nops to align call site below which is 7 bytes plus */
- /* the length of the call sequence emitted above. */
- /* Note: this requires the specific trampoline starts on a */
- /* kNaclAlignedment aligned address, which it does because */
- /* it's its own function that is aligned. */
- guint8 nop_buf[256];
- guint8 *nopbuf_aligned = ALIGN_TO (nop_buf, kNaClAlignment);
- guint8 *nopbuf_end = mono_arch_nacl_pad (nopbuf_aligned, kNaClAlignment - 7 - (call_len));
- emit_bytes (acfg, nopbuf_aligned, nopbuf_end - nopbuf_aligned);
- }
- /* The trampoline is stored at the offset'th pointer, the -4 is */
- /* present because RIP relative addressing starts at the end of */
- /* the current instruction, while the label "." is relative to */
- /* the beginning of the current asm location, which in this case */
- /* is not the mov instruction, but the offset itself, due to the */
- /* way the bytes and ints are emitted here. */
- got_offset = (offset * sizeof(gpointer)) - 4;
-
- /* mov <OFFSET>(%rip), %r11d */
- emit_byte (acfg, '\x45');
- emit_byte (acfg, '\x8b');
- emit_byte (acfg, '\x1d');
- emit_symbol_diff (acfg, acfg->got_symbol, ".", got_offset);
-
- /* naclcall %r11 */
- emit_bytes (acfg, call_start, call_len);
-
- /* The arg is stored at the offset+1 pointer, relative to beginning */
- /* of trampoline: 7 for mov, plus the call length, and 1 for push. */
- got_offset = ((offset + 1) * sizeof(gpointer)) + 7 + call_len + 1;
-
- /* We can't emit this data directly, hide in a "push imm32" */
- emit_byte (acfg, '\x68'); /* push */
- emit_symbol_diff (acfg, acfg->got_symbol, ".", got_offset);
- emit_alignment (acfg, kNaClAlignment);
-#endif /*__native_client_codegen__*/
#elif defined(TARGET_ARM)
guint8 buf [128];
guint8 *code;
/* Branch to generic trampoline */
x86_jump_reg (code, X86_ECX);
-#ifdef __native_client_codegen__
- {
- /* emit nops to next 32 byte alignment */
- int a = (~kNaClAlignmentMask) & ((code - buf) + kNaClAlignment - 1);
- while (code < (buf + a)) x86_nop(code);
- }
-#endif
emit_bytes (acfg, buf, code - buf);
- *tramp_size = NACL_SIZE(17, kNaClAlignment);
+ *tramp_size = 17;
g_assert (code - buf == *tramp_size);
#else
g_assert_not_reached ();
arch_emit_static_rgctx_trampoline (MonoAotCompile *acfg, int offset, int *tramp_size)
{
#if defined(TARGET_AMD64)
-#if defined(__default_codegen__)
/* This should be exactly 13 bytes long */
*tramp_size = 13;
emit_byte (acfg, '\x25');
emit_symbol_diff (acfg, acfg->got_symbol, ".", ((offset + 1) * sizeof (gpointer)) - 4);
}
-#elif defined(__native_client_codegen__)
- guint8 buf [128];
- guint8 *buf_aligned = ALIGN_TO(buf, kNaClAlignment);
- guint8 *code = buf_aligned;
-
- /* mov <OFFSET>(%rip), %r10d */
- emit_byte (acfg, '\x45');
- emit_byte (acfg, '\x8b');
- emit_byte (acfg, '\x15');
- emit_symbol_diff (acfg, acfg->got_symbol, ".", (offset * sizeof (gpointer)) - 4);
-
- /* mov <OFFSET>(%rip), %r11d */
- emit_byte (acfg, '\x45');
- emit_byte (acfg, '\x8b');
- emit_byte (acfg, '\x1d');
- emit_symbol_diff (acfg, acfg->got_symbol, ".", ((offset + 1) * sizeof (gpointer)) - 4);
-
- /* nacljmp *%r11 */
- amd64_jump_reg (code, AMD64_R11);
- emit_bytes (acfg, buf_aligned, code - buf_aligned);
-
- emit_alignment (acfg, kNaClAlignment);
- *tramp_size = kNaClAlignment;
-#endif /*__native_client_codegen__*/
-
#elif defined(TARGET_ARM)
guint8 buf [128];
guint8 *code;
/* Branch to the target address */
x86_jump_membase (code, X86_ECX, (offset + 1) * sizeof (gpointer));
-#ifdef __native_client_codegen__
- {
- /* emit nops to next 32 byte alignment */
- int a = (~kNaClAlignmentMask) & ((code - buf) + kNaClAlignment - 1);
- while (code < (buf + a)) x86_nop(code);
- }
-#endif
-
emit_bytes (acfg, buf, code - buf);
- *tramp_size = NACL_SIZE (15, kNaClAlignment);
+ *tramp_size = 15;
g_assert (code - buf == *tramp_size);
#else
g_assert_not_reached ();
{
#if defined(TARGET_AMD64)
guint8 *buf, *code;
-#if defined(__native_client_codegen__)
- guint8 *buf_alloc;
-#endif
guint8 *labels [16];
guint8 mov_buf[3];
guint8 *mov_buf_ptr = mov_buf;
const int kSizeOfMove = 7;
-#if defined(__default_codegen__)
+
code = buf = (guint8 *)g_malloc (256);
-#elif defined(__native_client_codegen__)
- buf_alloc = g_malloc (256 + kNaClAlignment + kSizeOfMove);
- buf = ((guint)buf_alloc + kNaClAlignment) & ~kNaClAlignmentMask;
- /* The RIP relative move below is emitted first */
- buf += kSizeOfMove;
- code = buf;
-#endif
/* FIXME: Optimize this, i.e. use binary search etc. */
/* Maybe move the body into a separate function (slower, but much smaller) */
emit_bytes (acfg, buf, code - buf);
*tramp_size = code - buf + kSizeOfMove;
-#if defined(__native_client_codegen__)
- /* The tramp will be padded to the next kNaClAlignment bundle. */
- *tramp_size = ALIGN_TO ((*tramp_size), kNaClAlignment);
-#endif
-#if defined(__default_codegen__)
g_free (buf);
-#elif defined(__native_client_codegen__)
- g_free (buf_alloc);
-#endif
#elif defined(TARGET_X86)
guint8 *buf, *code;
-#ifdef __native_client_codegen__
- guint8 *buf_alloc;
-#endif
guint8 *labels [16];
-#if defined(__default_codegen__)
code = buf = g_malloc (256);
-#elif defined(__native_client_codegen__)
- buf_alloc = g_malloc (256 + kNaClAlignment);
- code = buf = ((guint)buf_alloc + kNaClAlignment) & ~kNaClAlignmentMask;
-#endif
/* Allocate a temporary stack slot */
x86_push_reg (code, X86_EAX);
mono_x86_patch (labels [3], code);
x86_breakpoint (code);
-#ifdef __native_client_codegen__
- {
- /* emit nops to next 32 byte alignment */
- int a = (~kNaClAlignmentMask) & ((code - buf) + kNaClAlignment - 1);
- while (code < (buf + a)) x86_nop(code);
- }
-#endif
emit_bytes (acfg, buf, code - buf);
*tramp_size = code - buf;
-#if defined(__default_codegen__)
g_free (buf);
-#elif defined(__native_client_codegen__)
- g_free (buf_alloc);
-#endif
#elif defined(TARGET_ARM)
guint8 buf [128];
/* Branch to the target address */
x86_jump_membase (code, X86_ECX, (offset + 1) * sizeof (gpointer));
-#ifdef __native_client_codegen__
- {
- /* emit nops to next 32 byte alignment */
- int a = (~kNaClAlignmentMask) & ((code - buf) + kNaClAlignment - 1);
- while (code < (buf + a)) x86_nop(code);
- }
-#endif
-
emit_bytes (acfg, buf, code - buf);
- *tramp_size = NACL_SIZE (15, kNaClAlignment);
+ *tramp_size = 15;
g_assert (code - buf == *tramp_size);
#elif defined(TARGET_ARM)
guint8 buf [128];
/* FIXME: Search referenced images as well */
if (!acfg->typespec_classes) {
- acfg->typespec_classes = (MonoClass **)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoClass*) * len);
- for (i = 0; i < len; ++i) {
+ acfg->typespec_classes = g_hash_table_new (NULL, NULL);
+ for (i = 0; i < len; i++) {
MonoError error;
- acfg->typespec_classes [i] = mono_class_get_and_inflate_typespec_checked (acfg->image, MONO_TOKEN_TYPE_SPEC | (i + 1), NULL, &error);
+ int typespec = MONO_TOKEN_TYPE_SPEC | (i + 1);
+ MonoClass *klass_key = mono_class_get_and_inflate_typespec_checked (acfg->image, typespec, NULL, &error);
g_assert (mono_error_ok (&error)); /* FIXME error handling */
+ g_hash_table_insert (acfg->typespec_classes, klass_key, GINT_TO_POINTER (typespec));
}
}
- for (i = 0; i < len; ++i) {
- if (acfg->typespec_classes [i] == klass)
- break;
- }
-
- if (i < len)
- return MONO_TOKEN_TYPE_SPEC | (i + 1);
- else
- return 0;
+ return GPOINTER_TO_INT (g_hash_table_lookup (acfg->typespec_classes, klass));
}
static void
emit_line (acfg);
emit_section_change (acfg, ".text", 0);
- emit_alignment_code (acfg, NACL_SIZE(16, kNaClAlignment));
+ emit_alignment_code (acfg, 16);
emit_info_symbol (acfg, "plt");
emit_label (acfg, acfg->plt_symbol);
ji = info->ji;
unwind_ops = info->unwind_ops;
-#ifdef __native_client_codegen__
- mono_nacl_fix_patches (code, ji);
-#endif
-
/* Emit code */
sprintf (start_symbol, "%s%s", acfg->user_symbol_prefix, name);
default:
g_assert_not_reached ();
}
-#ifdef __native_client_codegen__
- /* align to avoid 32-byte boundary crossings */
- emit_alignment (acfg, AOT_FUNC_ALIGNMENT);
-#endif
-
if (!acfg->trampoline_size [ntype]) {
g_assert (tramp_size);
acfg->trampoline_size [ntype] = tramp_size;
gboolean
mono_aot_is_linkonce_method (MonoMethod *method)
{
- // FIXME:
- // This doesn't work yet, because
- // it can make us call methods which belong
- // to aot modules which haven't been loaded yet,
- // so the init method will read uninitialized got
- // entries.
return FALSE;
#if 0
WrapperInfo *info;
* Emit some padding so the local symbol for the first method doesn't have the
* same address as 'methods'.
*/
-#if defined(__default_codegen__)
emit_padding (acfg, 16);
-#elif defined(__native_client_codegen__)
- {
- const int kPaddingSize = 16;
- guint8 pad_buffer[kPaddingSize];
- mono_arch_nacl_pad (pad_buffer, kPaddingSize);
- emit_bytes (acfg, pad_buffer, kPaddingSize);
- }
-#endif
for (oindex = 0; oindex < acfg->method_order->len; ++oindex) {
MonoCompile *cfg;
sprintf (symbol, "ut_%d", get_method_index (acfg, method));
emit_section_change (acfg, ".text", 0);
-#ifdef __native_client_codegen__
- emit_alignment (acfg, AOT_FUNC_ALIGNMENT);
-#endif
if (acfg->thumb_mixed && cfg->compile_llvm) {
emit_set_thumb_mode (acfg);
g_hash_table_destroy (acfg->image_hash);
g_hash_table_destroy (acfg->unwind_info_offsets);
g_hash_table_destroy (acfg->method_label_hash);
+ if (acfg->typespec_classes)
+ g_hash_table_destroy (acfg->typespec_classes);
g_hash_table_destroy (acfg->export_names);
g_hash_table_destroy (acfg->plt_entry_debug_sym_cache);
g_hash_table_destroy (acfg->klass_blob_hash);