/* A load which can cause a nullref */
#define NEW_LOAD_MEMBASE_FAULT(cfg,dest,op,dr,base,offset) do { \
MONO_EMIT_NULL_CHECK ((cfg), (base)); \
- NEW_LOAD_MEMBASE_FLAGS ((cfg), (dest), (op), (dr), (base), (offset), MONO_INST_FAULT); \
+ if (cfg->explicit_null_checks) { \
+ NEW_LOAD_MEMBASE ((cfg), (dest), (op), (dr), (base), (offset)); \
+ } else { \
+ NEW_LOAD_MEMBASE_FLAGS ((cfg), (dest), (op), (dr), (base), (offset), MONO_INST_FAULT); \
+ } \
} while (0)
#define EMIT_NEW_LOAD_MEMBASE_FAULT(cfg,dest,op,dr,base,offset) do { \
#define MONO_EMIT_NEW_LOAD_MEMBASE_OP_FAULT(cfg,op,dr,base,offset) do { \
MONO_EMIT_NULL_CHECK (cfg, base); \
- MONO_EMIT_NEW_LOAD_MEMBASE_OP_FLAGS ((cfg), (op), (dr), (base), (offset), MONO_INST_FAULT); \
+ if (cfg->explicit_null_checks) { \
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP ((cfg), (op), (dr), (base), (offset)); \
+ } else { \
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP_FLAGS ((cfg), (op), (dr), (base), (offset), MONO_INST_FAULT); \
+ } \
} while (0)
#define MONO_EMIT_NEW_LOAD_MEMBASE_FAULT(cfg,dr,base,offset) MONO_EMIT_NEW_LOAD_MEMBASE_OP_FAULT ((cfg), (OP_LOAD_MEMBASE), (dr), (base), (offset))
return res;
} else {
+ LLVMValueRef res, md_arg;
+ int md_kind;
+
/*
* We emit volatile loads for loads which can fault, because otherwise
* LLVM will generate invalid code when encountering a load from a
* NULL address.
*/
- return mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
+ res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
+
+ /* Mark it with a custom metadata */
+ if (is_faulting) {
+ md_kind = LLVMGetMDKindID ("mono.faulting.load", strlen ("mono.faulting.load"));
+ md_arg = LLVMMDString ("mono", 4);
+ LLVMSetMetadata (res, md_kind, LLVMMDNode (&md_arg, 1));
+ }
+ return res;
}
}
g_assert (ins->inst_offset % size == 0);
index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
- lhs = emit_load (ctx, bb, &builder, 4, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), &index, 1, ""), "", TRUE);
+ lhs = emit_load (ctx, bb, &builder, 4, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), &index, 1, ""), "", !cfg->explicit_null_checks);
}
if (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_IMM) {
lhs = convert (ctx, lhs, LLVMInt32Type ());