#include <mono/utils/mono-mmap.h>
#include <mono/utils/mono-memory-model.h>
#include <mono/utils/mono-hwcap-x86.h>
+#include <mono/utils/mono-threads.h>
#include "trace.h"
#include "mini-x86.h"
x86_ret (code);
break;
}
+ case OP_GET_EX_OBJ:
+ if (ins->dreg != X86_EAX)
+ x86_mov_reg_reg (code, ins->dreg, X86_EAX, sizeof (gpointer));
+ break;
case OP_LABEL:
ins->inst_c0 = code - cfg->native_code;
MONO_VARINFO (cfg, ins->inst_c0)->live_range_end = code - cfg->native_code;
break;
}
- case OP_NACL_GC_SAFE_POINT: {
-#if defined(__native_client_codegen__) && defined(__native_client_gc__)
- if (cfg->compile_aot)
- code = emit_call (cfg, code, MONO_PATCH_INFO_ABS, (gpointer)mono_nacl_gc);
- else {
- guint8 *br [1];
-
- x86_test_mem_imm8 (code, (gpointer)&__nacl_thread_suspension_needed, 0xFFFFFFFF);
- br[0] = code; x86_branch8 (code, X86_CC_EQ, 0, FALSE);
- code = emit_call (cfg, code, MONO_PATCH_INFO_ABS, (gpointer)mono_nacl_gc);
- x86_patch (br[0], code);
- }
+ case OP_GC_SAFE_POINT: {
+ const char *polling_func = NULL;
+ int compare_val = 0;
+ guint8 *br [1];
+
+#if defined (USE_COOP_GC)
+ polling_func = "mono_threads_state_poll";
+ compare_val = 1;
+#elif defined(__native_client_codegen__) && defined(__native_client_gc__)
+ polling_func = "mono_nacl_gc";
+ compare_val = 0xFFFFFFFF;
#endif
+ if (!polling_func)
+ break;
+
+ x86_test_membase_imm (code, ins->sreg1, 0, compare_val);
+ br[0] = code; x86_branch8 (code, X86_CC_EQ, 0, FALSE);
+ code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, polling_func);
+ x86_patch (br [0], code);
+
break;
}
case OP_GC_LIVENESS_DEF:
}
void
-mono_arch_patch_code (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, MonoCodeManager *dyn_code_mp, gboolean run_cctors)
+mono_arch_patch_code_new (MonoCompile *cfg, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, gpointer target)
{
- MonoJumpInfo *patch_info;
- gboolean compile_aot = !run_cctors;
+ unsigned char *ip = ji->ip.i + code;
- for (patch_info = ji; patch_info; patch_info = patch_info->next) {
- unsigned char *ip = patch_info->ip.i + code;
- const unsigned char *target;
-
- if (compile_aot) {
- switch (patch_info->type) {
- case MONO_PATCH_INFO_BB:
- case MONO_PATCH_INFO_LABEL:
- break;
- default:
- /* No need to patch these */
- continue;
- }
+ switch (ji->type) {
+ case MONO_PATCH_INFO_IP:
+ *((gconstpointer *)(ip)) = target;
+ break;
+ case MONO_PATCH_INFO_CLASS_INIT: {
+ guint8 *code = ip;
+ /* Might already been changed to a nop */
+ x86_call_code (code, 0);
+ x86_patch (ip, (unsigned char*)target);
+ break;
+ }
+ case MONO_PATCH_INFO_ABS:
+ case MONO_PATCH_INFO_METHOD:
+ case MONO_PATCH_INFO_METHOD_JUMP:
+ case MONO_PATCH_INFO_INTERNAL_METHOD:
+ case MONO_PATCH_INFO_BB:
+ case MONO_PATCH_INFO_LABEL:
+ case MONO_PATCH_INFO_RGCTX_FETCH:
+ case MONO_PATCH_INFO_MONITOR_ENTER:
+ case MONO_PATCH_INFO_MONITOR_ENTER_V4:
+ case MONO_PATCH_INFO_MONITOR_EXIT:
+ case MONO_PATCH_INFO_JIT_ICALL_ADDR:
+#if defined(__native_client_codegen__) && defined(__native_client__)
+ if (nacl_is_code_address (code)) {
+ /* For tail calls, code is patched after being installed */
+ /* but not through the normal "patch callsite" method. */
+ unsigned char buf[kNaClAlignment];
+ unsigned char *aligned_code = (uintptr_t)code & ~kNaClAlignmentMask;
+ unsigned char *_target = target;
+ int ret;
+ /* All patch targets modified in x86_patch */
+ /* are IP relative. */
+ _target = _target + (uintptr_t)buf - (uintptr_t)aligned_code;
+ memcpy (buf, aligned_code, kNaClAlignment);
+ /* Patch a temp buffer of bundle size, */
+ /* then install to actual location. */
+ x86_patch (buf + ((uintptr_t)code - (uintptr_t)aligned_code), _target);
+ ret = nacl_dyncode_modify (aligned_code, buf, kNaClAlignment);
+ g_assert (ret == 0);
}
-
- target = mono_resolve_patch_target (method, domain, code, patch_info, run_cctors);
-
- switch (patch_info->type) {
- case MONO_PATCH_INFO_IP:
- *((gconstpointer *)(ip)) = target;
- break;
- case MONO_PATCH_INFO_CLASS_INIT: {
- guint8 *code = ip;
- /* Might already been changed to a nop */
- x86_call_code (code, 0);
- x86_patch (ip, target);
- break;
+ else {
+ x86_patch (ip, (unsigned char*)target);
}
- case MONO_PATCH_INFO_ABS:
- case MONO_PATCH_INFO_METHOD:
- case MONO_PATCH_INFO_METHOD_JUMP:
- case MONO_PATCH_INFO_INTERNAL_METHOD:
- case MONO_PATCH_INFO_BB:
- case MONO_PATCH_INFO_LABEL:
- case MONO_PATCH_INFO_RGCTX_FETCH:
- case MONO_PATCH_INFO_GENERIC_CLASS_INIT:
- case MONO_PATCH_INFO_MONITOR_ENTER:
- case MONO_PATCH_INFO_MONITOR_ENTER_V4:
- case MONO_PATCH_INFO_MONITOR_EXIT:
- case MONO_PATCH_INFO_JIT_ICALL_ADDR:
-#if defined(__native_client_codegen__) && defined(__native_client__)
- if (nacl_is_code_address (code)) {
- /* For tail calls, code is patched after being installed */
- /* but not through the normal "patch callsite" method. */
- unsigned char buf[kNaClAlignment];
- unsigned char *aligned_code = (uintptr_t)code & ~kNaClAlignmentMask;
- unsigned char *_target = target;
- int ret;
- /* All patch targets modified in x86_patch */
- /* are IP relative. */
- _target = _target + (uintptr_t)buf - (uintptr_t)aligned_code;
- memcpy (buf, aligned_code, kNaClAlignment);
- /* Patch a temp buffer of bundle size, */
- /* then install to actual location. */
- x86_patch (buf + ((uintptr_t)code - (uintptr_t)aligned_code), _target);
- ret = nacl_dyncode_modify (aligned_code, buf, kNaClAlignment);
- g_assert (ret == 0);
- }
- else {
- x86_patch (ip, target);
- }
#else
- x86_patch (ip, target);
+ x86_patch (ip, (unsigned char*)target);
#endif
- break;
- case MONO_PATCH_INFO_NONE:
- break;
- case MONO_PATCH_INFO_R4:
- case MONO_PATCH_INFO_R8: {
- guint32 offset = mono_arch_get_patch_offset (ip);
- *((gconstpointer *)(ip + offset)) = target;
- break;
- }
- default: {
- guint32 offset = mono_arch_get_patch_offset (ip);
+ break;
+ case MONO_PATCH_INFO_NONE:
+ break;
+ case MONO_PATCH_INFO_R4:
+ case MONO_PATCH_INFO_R8: {
+ guint32 offset = mono_arch_get_patch_offset (ip);
+ *((gconstpointer *)(ip + offset)) = target;
+ break;
+ }
+ default: {
+ guint32 offset = mono_arch_get_patch_offset (ip);
#if !defined(__native_client__)
- *((gconstpointer *)(ip + offset)) = target;
+ *((gconstpointer *)(ip + offset)) = target;
#else
- *((gconstpointer *)(ip + offset)) = nacl_modify_patch_target (target);
+ *((gconstpointer *)(ip + offset)) = nacl_modify_patch_target (target);
#endif
- break;
- }
- }
+ break;
+ }
}
}