guint8 *code;
int this_pos = 4;
- if (MONO_TYPE_ISSTRUCT (mono_method_signature (method)->ret))
- this_pos = 8;
-
code = buf;
x86_alu_membase_imm (code, X86_ADD, X86_ESP, this_pos, sizeof (MonoObject));
#elif defined(TARGET_ARM)
guint8 buf [128];
guint8 *code;
- int this_pos = 0;
code = buf;
- if (MONO_TYPE_ISSTRUCT (mono_method_signature (method)->ret))
- this_pos = 1;
-
- ARM_ADD_REG_IMM8 (code, this_pos, this_pos, sizeof (MonoObject));
+ ARM_ADD_REG_IMM8 (code, ARMREG_R0, ARMREG_R0, sizeof (MonoObject));
emit_bytes (acfg, buf, code - buf);
/* jump to method */
#elif defined(TARGET_POWERPC)
int this_pos = 3;
- if (MONO_TYPE_ISSTRUCT (mono_method_signature (method)->ret))
- this_pos = 4;
-
g_assert (!acfg->use_bin_writer);
fprintf (acfg->fp, "\n\taddi %d, %d, %d\n", this_pos, this_pos, (int)sizeof (MonoObject));
/* FIXME: Optimize this, i.e. use binary search etc. */
/* Maybe move the body into a separate function (slower, but much smaller) */
- /* R10 is a free register */
+ /* R11 is a free register */
labels [0] = code;
- amd64_alu_membase_imm (code, X86_CMP, AMD64_R10, 0, 0);
+ amd64_alu_membase_imm (code, X86_CMP, AMD64_R11, 0, 0);
labels [1] = code;
amd64_branch8 (code, X86_CC_Z, FALSE, 0);
/* Check key */
- amd64_alu_membase_reg (code, X86_CMP, AMD64_R10, 0, MONO_ARCH_IMT_REG);
+ amd64_alu_membase_reg (code, X86_CMP, AMD64_R11, 0, MONO_ARCH_IMT_REG);
labels [2] = code;
amd64_branch8 (code, X86_CC_Z, FALSE, 0);
/* Loop footer */
- amd64_alu_reg_imm (code, X86_ADD, AMD64_R10, 2 * sizeof (gpointer));
+ amd64_alu_reg_imm (code, X86_ADD, AMD64_R11, 2 * sizeof (gpointer));
amd64_jump_code (code, labels [0]);
/* Match */
mono_amd64_patch (labels [2], code);
- amd64_mov_reg_membase (code, AMD64_R10, AMD64_R10, sizeof (gpointer), 8);
- amd64_jump_membase (code, AMD64_R10, 0);
+ amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, sizeof (gpointer), 8);
+ amd64_jump_membase (code, AMD64_R11, 0);
/* No match */
/* FIXME: */
mono_amd64_patch (labels [1], code);
x86_breakpoint (code);
- /* mov <OFFSET>(%rip), %r10 */
+ amd64_mov_reg_membase (code, AMD64_R11, AMD64_RIP, 12345678, 8);
+
+ /* mov <OFFSET>(%rip), %r11 */
emit_byte (acfg, '\x4d');
emit_byte (acfg, '\x8b');
- emit_byte (acfg, '\x15');
+ emit_byte (acfg, '\x1d');
emit_symbol_diff (acfg, acfg->got_symbol, ".", (offset * sizeof (gpointer)) - 4);
emit_bytes (acfg, buf, code - buf);
return 0;
}
+static G_GNUC_UNUSED char*
+patch_to_string (MonoJumpInfo *patch_info)
+{
+ GString *str;
+
+ str = g_string_new ("");
+
+ g_string_append_printf (str, "%s(", get_patch_name (patch_info->type));
+
+ switch (patch_info->type) {
+ case MONO_PATCH_INFO_VTABLE:
+ mono_type_get_desc (str, &patch_info->data.klass->byval_arg, TRUE);
+ break;
+ default:
+ break;
+ }
+ g_string_append_printf (str, ")");
+ return g_string_free (str, FALSE);
+}
+
/*
* is_plt_patch:
*
return FALSE;
}
+static void add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth);
+
+static void
+add_generic_class (MonoAotCompile *acfg, MonoClass *klass)
+{
+ add_generic_class_with_depth (acfg, klass, 0);
+}
+
/*
* add_generic_class:
*
* Add all methods of a generic class.
*/
static void
-add_generic_class (MonoAotCompile *acfg, MonoClass *klass)
+add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth)
{
MonoMethod *method;
gpointer iter;
* FIXME: Instances which are referenced by these methods are not added,
* for example Array.Resize<int> for List<int>.Add ().
*/
- add_extra_method (acfg, method);
+ add_extra_method_with_depth (acfg, method, depth);
}
if (klass->delegate) {
while ((method = mono_class_get_methods (array_class, &iter))) {
if (strstr (method->name, name_prefix)) {
MonoMethod *m = mono_aot_get_array_helper_from_wrapper (method);
- add_extra_method (acfg, m);
+ add_extra_method_with_depth (acfg, m, depth);
}
}
method = cfg->orig_method;
code = cfg->native_code;
- header = mono_method_get_header (method);
+ header = cfg->header;
method_index = get_method_index (acfg, method);
method = cfg->orig_method;
code = cfg->native_code;
- header = mono_method_get_header (method);
+ header = cfg->header;
method_index = get_method_index (acfg, method);
/* Exception table */
if (cfg->compile_llvm) {
+ /*
+ * When using LLVM, we can't emit some data, like pc offsets, this reg/offset etc.,
+ * since the information is only available to llc. Instead, we let llc save the data
+ * into the LSDA, and read it from there at runtime.
+ */
/* The assembly might be CIL stripped so emit the data ourselves */
if (header->num_clauses)
encode_value (header->num_clauses, p, &p);
} else {
encode_value (0, p, &p);
}
+
+ /* Emit a list of nesting clauses */
+ for (i = 0; i < header->num_clauses; ++i) {
+ gint32 cindex1 = k;
+ MonoExceptionClause *clause1 = &header->clauses [cindex1];
+ gint32 cindex2 = i;
+ MonoExceptionClause *clause2 = &header->clauses [cindex2];
+
+ if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
+ encode_value (i, p, &p);
+ }
+ encode_value (-1, p, &p);
}
} else {
if (jinfo->num_clauses)
if (jinfo->has_generic_jit_info) {
MonoGenericJitInfo *gi = mono_jit_info_get_generic_jit_info (jinfo);
- encode_value (gi->has_this ? 1 : 0, p, &p);
- encode_value (gi->this_reg, p, &p);
- encode_value (gi->this_offset, p, &p);
+ if (!cfg->compile_llvm) {
+ encode_value (gi->has_this ? 1 : 0, p, &p);
+ encode_value (gi->this_reg, p, &p);
+ encode_value (gi->this_offset, p, &p);
+ }
/*
* Need to encode jinfo->method too, since it is not equal to 'method'
gboolean no_special_static, cant_encode;
gpointer iter = NULL;
+ if (!klass) {
+ buf_size = 16;
+
+ p = buf = g_malloc (buf_size);
+
+ /* Mark as unusable */
+ encode_value (-1, p, &p);
+
+ res = add_to_blob (acfg, buf, p - buf);
+ g_free (buf);
+
+ return res;
+ }
+
buf_size = 10240 + (klass->vtable_size * 16);
p = buf = g_malloc (buf_size);
add_extra_method_with_depth (acfg, m, depth + 1);
}
}
- add_generic_class (acfg, m->klass);
+ add_generic_class_with_depth (acfg, m->klass, depth + 5);
}
if (m->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED && !strcmp (m->name, "ElementAddr"))
add_extra_method_with_depth (acfg, m, depth + 1);
MonoClass *klass = patch_info->data.klass;
if (klass->generic_class && !mono_generic_context_is_sharable (&klass->generic_class->context, FALSE))
- add_generic_class (acfg, klass);
+ add_generic_class_with_depth (acfg, klass, depth + 5);
break;
}
default:
* a lot of time, and doesn't seem to save much space.
* The following optimizations cannot be enabled:
* - 'tailcallelim'
+ * - 'jump-threading' changes our blockaddress references to int constants.
* The opt list below was produced by taking the output of:
* llvm-as < /dev/null | opt -O2 -disable-output -debug-pass=Arguments
* then removing tailcallelim + the global opts, and adding a second gvn.
*/
opts = g_strdup ("-instcombine -simplifycfg");
- opts = g_strdup ("-simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -basiccg -prune-eh -inline -functionattrs -domtree -domfrontier -scalarrepl -simplify-libcalls -instcombine -jump-threading -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loopsimplify -domfrontier -loopsimplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loopsimplify -lcssa -iv-users -indvars -loop-deletion -loopsimplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -jump-threading -domtree -memdep -dse -adce -gvn -simplifycfg -preverify -domtree -verify");
+ opts = g_strdup ("-simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -basiccg -prune-eh -inline -functionattrs -domtree -domfrontier -scalarrepl -simplify-libcalls -instcombine -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loopsimplify -domfrontier -loopsimplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loopsimplify -lcssa -iv-users -indvars -loop-deletion -loopsimplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -domtree -memdep -dse -adce -gvn -simplifycfg -preverify -domtree -verify");
#if 1
command = g_strdup_printf ("opt -f %s -o temp.opt.bc temp.bc", opts);
printf ("Executing opt: %s\n", command);
if (!cfg)
continue;
- buf_size = 512;
+ buf_size = 1024;
p = buf = g_malloc (buf_size);
nmethods ++;
for (i = 0; i < acfg->image->tables [MONO_TABLE_TYPEDEF].rows; ++i) {
token = MONO_TOKEN_TYPE_DEF | (i + 1);
klass = mono_class_get (acfg->image, token);
+ if (!klass)
+ continue;
full_name = mono_type_get_name_full (mono_class_get_type (klass), MONO_TYPE_NAME_FORMAT_FULL_NAME);
hash = mono_metadata_str_hash (full_name) % table_size;
g_free (full_name);