Exemplo n.º 1
0
gpointer
mono_arch_get_static_rgctx_trampoline (gpointer arg, gpointer addr)
{
	guint8 *code, *start;
	int buf_len;
	GSList *unwind_ops;

	MonoDomain *domain = mono_domain_get ();

	buf_len = 10;

	start = code = mono_domain_code_reserve (domain, buf_len);

	unwind_ops = mono_arch_get_cie_program ();

	x86_mov_reg_imm (code, MONO_ARCH_RGCTX_REG, arg);
	x86_jump_code (code, addr);
	g_assert ((code - start) <= buf_len);

	mono_arch_flush_icache (start, code - start);
	MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL));

	mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);

	return start;
}
Exemplo n.º 2
0
gpointer
mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len)
{
	guint8 *code, *buf, *tramp;
	gint32 displace;

	tramp = mono_get_trampoline_code (tramp_type);

	/*----------------------------------------------------------*/
	/* This is the method-specific part of the trampoline. Its  */
	/* purpose is to provide the generic part with the          */
	/* MonoMethod *method pointer. We'll use r1 to keep it.     */
	/*----------------------------------------------------------*/
	code = buf = mono_domain_code_reserve (domain, SPECIFIC_TRAMPOLINE_SIZE);

	s390_basr (buf, s390_r1, 0);
	s390_j	  (buf, 6);
	s390_llong(buf, arg1);
	s390_lg   (buf, s390_r1, 0, s390_r1, 4);
	displace = (tramp - buf) / 2;
	s390_jcl  (buf, S390_CC_UN, displace);

	/* Flush instruction cache, since we've generated code */
	mono_arch_flush_icache (code, buf - code);

	/* Sanity check */
	g_assert ((buf - code) <= SPECIFIC_TRAMPOLINE_SIZE);

	if (code_len)
		*code_len = buf - code;
	
	return code;
}	
Exemplo n.º 3
0
gpointer
mono_arch_get_static_rgctx_trampoline (MonoMethod *m, 
					MonoMethodRuntimeGenericContext *mrgctx, 
					gpointer addr)
{
	guint8 *code, *start;
	gint32 displace;
	int buf_len;
	char trampName[128];

	MonoDomain *domain = mono_domain_get ();

	buf_len = 32;

	start = code = mono_domain_code_reserve (domain, buf_len);

	S390_SET  (code, MONO_ARCH_RGCTX_REG, mrgctx);
	displace = ((uintptr_t) addr - (uintptr_t) code) / 2;
	s390_jg   (code, displace);
	g_assert ((code - start) < buf_len);

	mono_arch_flush_icache (start, code - start);

	if (mono_profiler_events & MONO_PROFILE_JIT_COMPILATION)
		mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_HELPER, NULL);

	snprintf(trampName, sizeof(trampName), "%s_rgctx_trampoline", m->name);

	mono_tramp_info_register (mono_tramp_info_create (trampName, start, code - start, NULL, NULL), domain);

	return(start);
}	
Exemplo n.º 4
0
gpointer
mono_arch_get_static_rgctx_trampoline (MonoMethod *m, 
					MonoMethodRuntimeGenericContext *mrgctx, 
					gpointer addr)
{
	guint8 *code, *start;
	gint32 displace;
	int buf_len;

	MonoDomain *domain = mono_domain_get ();

	buf_len = 32;

	start = code = mono_domain_code_reserve (domain, buf_len);

	s390_basr (code, s390_r1, 0);
	s390_j    (code, 6);
	s390_llong(code, mrgctx);
	s390_lg   (code, MONO_ARCH_RGCTX_REG, 0, s390_r1, 4);
	displace = ((uintptr_t) addr - (uintptr_t) code) / 2;
	s390_jg   (code, displace);
	g_assert ((code - start) < buf_len);

	mono_arch_flush_icache (start, code - start);

	return(start);
}	
Exemplo n.º 5
0
gpointer
mono_arch_get_unbox_trampoline (MonoMethod *method, gpointer addr)
{
	guint8 *code, *start;
	int this_pos = s390_r2;
	MonoDomain *domain = mono_domain_get ();
	char trampName[128];

	start = code = mono_domain_code_reserve (domain, 28);

	S390_SET  (code, s390_r1, addr);
	s390_aghi (code, this_pos, MONO_ABI_SIZEOF (MonoObject));
	s390_br   (code, s390_r1);

	g_assert ((code - start) <= 28);

	mono_arch_flush_icache (start, code - start);
	MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, method));

	snprintf(trampName, sizeof(trampName), "%s_unbox_trampoline", method->name);

	mono_tramp_info_register (mono_tramp_info_create (trampName, start, code - start, NULL, NULL), domain);

	return start;
}
Exemplo n.º 6
0
gpointer
mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len)
{
	guint32 *code, *buf, *tramp;

	tramp = mono_get_trampoline_code (tramp_type);

	code = buf = mono_domain_code_reserve (domain, TRAMPOLINE_SIZE * 4);

	/* We have to use g5 here because there is no other free register */
	sparc_set (code, tramp, sparc_g5);
	sparc_jmpl (code, sparc_g5, sparc_g0, sparc_g5);
	sparc_nop (code);
#ifdef SPARCV9
	g_assert_not_reached ();
#else
	*code = (guint32)arg1;
	code ++;
#endif

	g_assert ((code - buf) <= TRAMPOLINE_SIZE);

	if (code_len)
		*code_len = (code - buf) * 4;

	mono_arch_flush_icache ((guint8*)buf, (code - buf) * 4);

	return buf;
}	
Exemplo n.º 7
0
gpointer
mono_arch_get_static_rgctx_trampoline (MonoMethod *m, 
					MonoMethodRuntimeGenericContext *mrgctx, 
					gpointer addr)
{
	guint8 *code, *start;
	gint32 displace;
	int buf_len;

	MonoDomain *domain = mono_domain_get ();

	buf_len = 32;

	start = code = mono_domain_code_reserve (domain, buf_len);

	S390_SET  (code, MONO_ARCH_RGCTX_REG, mrgctx);
	displace = ((uintptr_t) addr - (uintptr_t) code) / 2;
	s390_jg   (code, displace);
	g_assert ((code - start) < buf_len);

	mono_arch_flush_icache (start, code - start);
	mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_HELPER, NULL);

	return(start);
}	
Exemplo n.º 8
0
gpointer
mono_arch_get_static_rgctx_trampoline (gpointer arg, gpointer addr)
{
	guint8 *code, *start;
	gint32 displace;
	int buf_len;

	MonoDomain *domain = mono_domain_get ();

	buf_len = 32;

	start = code = mono_domain_code_reserve (domain, buf_len);

	S390_SET  (code, MONO_ARCH_RGCTX_REG, arg);
	displace = ((uintptr_t) addr - (uintptr_t) code) / 2;
	s390_jg   (code, displace);
	g_assert ((code - start) < buf_len);

	mono_arch_flush_icache (start, code - start);
	MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL));

	mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);

	return(start);
}	
Exemplo n.º 9
0
gpointer
mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len)
{
	guint8 *code, *buf, *tramp;
	gint32 displace;

	tramp = mono_get_trampoline_code (tramp_type);

	/*----------------------------------------------------------*/
	/* This is the method-specific part of the trampoline. Its  */
	/* purpose is to provide the generic part with the          */
	/* MonoMethod *method pointer. We'll use r1 to keep it.     */
	/*----------------------------------------------------------*/
	code = buf = mono_domain_code_reserve (domain, SPECIFIC_TRAMPOLINE_SIZE);

	S390_SET  (buf, s390_r1, arg1);
	displace = (tramp - buf) / 2;
	s390_jg   (buf, displace);

	/* Flush instruction cache, since we've generated code */
	mono_arch_flush_icache (code, buf - code);
	MONO_PROFILER_RAISE (jit_code_buffer, (buf, code - buf,
	                     MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE,
	                     (void *) mono_get_generic_trampoline_simple_name (tramp_type)));

	/* Sanity check */
	g_assert ((buf - code) <= SPECIFIC_TRAMPOLINE_SIZE);

	if (code_len)
		*code_len = buf - code;
	
	return code;
}	
Exemplo n.º 10
0
gpointer
mono_arch_get_unbox_trampoline (MonoGenericSharingContext *gsctx, MonoMethod *method, gpointer addr)
{
	guint8 *code, *start;
	int this_pos = s390_r2;
	MonoDomain *domain = mono_domain_get ();

	start = addr;
	if (MONO_TYPE_ISSTRUCT (mono_method_signature (method)->ret))
		this_pos = s390_r3;

	start = code = mono_domain_code_reserve (domain, 28);
    
	s390_basr (code, s390_r13, 0);
	s390_j	  (code, 4);
	s390_word (code, addr);
	s390_l    (code, s390_r1, 0, s390_r13, 4);
	s390_ahi  (code, this_pos, sizeof(MonoObject));
	s390_br   (code, s390_r1);

	g_assert ((code - start) <= 28);

	mono_arch_flush_icache (start, code - start);

	return start;
}
Exemplo n.º 11
0
gpointer
mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
{
	guint8 *buf = mono_domain_code_reserve (mono_domain_get (), 64), *code = buf;

	// Pass the argument in a0.
	code = mono_riscv_emit_imm (code, RISCV_A0, sizeof (MonoObject));
	code = mono_riscv_emit_imm (code, RISCV_T0, (gsize) addr);
	riscv_jalr (code, RISCV_ZERO, RISCV_T0, 0);

	mono_arch_flush_icache (buf, code - buf);

	return buf;
}
Exemplo n.º 12
0
gpointer
mono_arch_get_static_rgctx_trampoline (gpointer arg, gpointer addr)
{
	guint8 *buf = mono_domain_code_reserve (mono_domain_get (), 64), *code = buf;

	// Pass the argument in the RGCTX register.
	code = mono_riscv_emit_imm (code, MONO_ARCH_RGCTX_REG, (gsize) arg);
	code = mono_riscv_emit_imm (code, RISCV_T0, (gsize) addr);
	riscv_jalr (code, RISCV_ZERO, RISCV_T0, 0);

	mono_arch_flush_icache (buf, code - buf);

	return buf;
}
Exemplo n.º 13
0
gpointer
mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len)
{
	guint8 *code, *buf, *tramp;
	gint32 displace;

	tramp = mono_get_trampoline_code (tramp_type);

	/*----------------------------------------------------------*/
	/* This is the method-specific part of the trampoline. Its  */
	/* purpose is to provide the generic part with the          */
	/* MonoMethod *method pointer. We'll use r1 to keep it.     */
	/*----------------------------------------------------------*/
	code = buf = mono_domain_code_reserve (domain, SPECIFIC_TRAMPOLINE_SIZE);

	switch (tramp_type) {
	/*
	 * Monitor tramps have the object in r2
	 */
	case MONO_TRAMPOLINE_MONITOR_ENTER:
	case MONO_TRAMPOLINE_MONITOR_ENTER_V4:
	case MONO_TRAMPOLINE_MONITOR_EXIT:
		s390_lgr (buf, s390_r1, s390_r2);
		break;
	/*
	 * Generic class trampoline arg is in r2
	 */
	case MONO_TRAMPOLINE_GENERIC_CLASS_INIT:
		s390_lgr (buf, s390_r1, s390_r2);
		break;
	default :
		S390_SET  (buf, s390_r1, arg1);
	}
	displace = (tramp - buf) / 2;
	s390_jg   (buf, displace);

	/* Flush instruction cache, since we've generated code */
	mono_arch_flush_icache (code, buf - code);
	mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE, 
				       (void *) mono_get_generic_trampoline_simple_name (tramp_type));

	/* Sanity check */
	g_assert ((buf - code) <= SPECIFIC_TRAMPOLINE_SIZE);

	if (code_len)
		*code_len = buf - code;
	
	return code;
}	
Exemplo n.º 14
0
gpointer
mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type,
                                      MonoDomain *domain, guint32 *code_len)
{
	guint8 *buf = mono_domain_code_reserve (domain, 64), *code = buf;
	guint8 *tramp = mono_get_trampoline_code (tramp_type);

	// Pass the argument in scratch t0.
	code = mono_riscv_emit_imm (code, RISCV_T0, (gsize) arg1);
	code = mono_riscv_emit_imm (code, RISCV_T1, (gsize) tramp);
	riscv_jalr (code, RISCV_ZERO, RISCV_T1, 0);

	mono_arch_flush_icache (buf, code - buf);

	if (code_len)
		*code_len = code - buf;

	return buf;
}
Exemplo n.º 15
0
gpointer
mono_arch_get_unbox_trampoline (MonoMethod *method, gpointer addr)
{
	guint8 *code, *start;
	int this_pos = s390_r2;
	MonoDomain *domain = mono_domain_get ();

	start = code = mono_domain_code_reserve (domain, 28);

	S390_SET  (code, s390_r1, addr);
	s390_aghi (code, this_pos, sizeof(MonoObject));
	s390_br   (code, s390_r1);

	g_assert ((code - start) <= 28);

	mono_arch_flush_icache (start, code - start);

	return start;
}
Exemplo n.º 16
0
gpointer
mono_arch_get_unbox_trampoline (MonoMethod *method, gpointer addr)
{
	guint8 *code, *start;
	int this_pos = s390_r2;
	MonoDomain *domain = mono_domain_get ();

	start = code = mono_domain_code_reserve (domain, 28);

	S390_SET  (code, s390_r1, addr);
	s390_aghi (code, this_pos, sizeof(MonoObject));
	s390_br   (code, s390_r1);

	g_assert ((code - start) <= 28);

	mono_arch_flush_icache (start, code - start);
	mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, method);

	return start;
}
Exemplo n.º 17
0
/*
 * mono_arch_get_gsharedvt_arg_trampoline:
 *
 *   See tramp-x86.c for documentation.
 */
gpointer
mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpointer addr)
{
	guint8 *code, *start;
	int buf_len;

	buf_len = 32;

	start = code = mono_domain_code_reserve (domain, buf_len);

	amd64_mov_reg_imm (code, AMD64_RAX, arg);
	amd64_jump_code (code, addr);
	g_assert ((code - start) < buf_len);

	mono_arch_flush_icache (start, code - start);
	mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL);

	mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);

	return start;
}
Exemplo n.º 18
0
gpointer
mono_arch_get_unbox_trampoline (MonoGenericSharingContext *gsctx, MonoMethod *method, gpointer addr)
{
	guint8 *code, *start;
	int this_pos = s390_r2;
	MonoDomain *domain = mono_domain_get ();

	start = code = mono_domain_code_reserve (domain, 28);

	s390_basr (code, s390_r1, 0);
	s390_j	  (code, 6);
	s390_llong(code, addr);
	s390_lg   (code, s390_r1, 0, s390_r1, 4);
	s390_aghi (code, this_pos, sizeof(MonoObject));
	s390_br   (code, s390_r1);

	g_assert ((code - start) <= 28);

	mono_arch_flush_icache (start, code - start);

	return start;
}
Exemplo n.º 19
0
/*
 * mono_arch_get_unbox_trampoline:
 * @m: method pointer
 * @addr: pointer to native code for @m
 *
 * when value type methods are called through the vtable we need to unbox the
 * this argument. This method returns a pointer to a trampoline which does
 * unboxing before calling the method
 */
gpointer
mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
{
	guint8 *code, *start;
	int this_pos = 4, size = 16;
	MonoDomain *domain = mono_domain_get ();
	GSList *unwind_ops;

	start = code = mono_domain_code_reserve (domain, size);

	unwind_ops = mono_arch_get_cie_program ();

	x86_alu_membase_imm (code, X86_ADD, X86_ESP, this_pos, MONO_ABI_SIZEOF (MonoObject));
	x86_jump_code (code, addr);
	g_assert ((code - start) < size);

	MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, m));

	mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);

	return start;
}
Exemplo n.º 20
0
gpointer
mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len)
{
	guint8 *buf, *tramp;
	gint64 disp;
	Ia64CodegenState code;

	tramp = mono_get_trampoline_code (tramp_type);

	buf = mono_domain_code_reserve (domain, TRAMPOLINE_SIZE);

	/* FIXME: Optimize this */

	ia64_codegen_init (code, buf);

	ia64_movl (code, GP_SCRATCH_REG, arg1);

	ia64_begin_bundle (code);
	disp = (tramp - code.buf) >> 4;
	if (ia64_is_imm21 (disp)) {
		ia64_br_cond (code, disp);
	}
	else {
		ia64_movl (code, GP_SCRATCH_REG2, tramp);
		ia64_mov_to_br (code, IA64_B6, GP_SCRATCH_REG2);
		ia64_br_cond_reg (code, IA64_B6);
	}

	ia64_codegen_close (code);

	g_assert (code.buf - buf <= TRAMPOLINE_SIZE);

	mono_arch_flush_icache (buf, code.buf - buf);

	if (code_len)
		*code_len = code.buf - buf;

	return buf;
}
Exemplo n.º 21
0
/*
 * mono_arch_get_unbox_trampoline:
 * @m: method pointer
 * @addr: pointer to native code for @m
 *
 * when value type methods are called through the vtable we need to unbox the
 * this argument. This method returns a pointer to a trampoline which does
 * unboxing before calling the method
 */
gpointer
mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
{
	guint8 *buf;
	gpointer func_addr, func_gp;
	Ia64CodegenState code;
	int this_reg = 0;
	gpointer *desc;
	MonoDomain *domain = mono_domain_get ();

	/* FIXME: Optimize this */

	func_addr = ((gpointer*)addr) [0];
	func_gp = ((gpointer*)addr) [1];

	buf = mono_domain_code_reserve (domain, 256);

	/* Since the this reg is a stacked register, its a bit hard to access it */
	ia64_codegen_init (code, buf);
	ia64_alloc (code, 40, 8, 1, 0, 0);
	ia64_adds_imm (code, 32 + this_reg, sizeof (MonoObject), 32 + this_reg);
	ia64_mov_to_ar_i (code, IA64_PFS, 40);	
	ia64_movl (code, GP_SCRATCH_REG, func_addr);
	ia64_mov_to_br (code, IA64_B6, GP_SCRATCH_REG);
	ia64_br_cond_reg (code, IA64_B6);
	ia64_codegen_close (code);

	g_assert (code.buf - buf < 256);

	mono_arch_flush_icache (buf, code.buf - buf);

	/* FIXME: */
	desc = g_malloc0 (sizeof (gpointer) * 2);
	desc [0] = buf;
	desc [1] = func_gp;

	return desc;
}