Author: lupus
Date: 2007-10-10 06:50:50 -0400 (Wed, 10 Oct 2007)
New Revision: 87251
Modified:
trunk/mono/mono/mini/ChangeLog
trunk/mono/mono/mini/tramp-arm.c
Log:
Wed Oct 10 13:05:46 CEST 2007 Paolo Molaro <[EMAIL PROTECTED]>
* tramp-arm.c: reduced the trampoline size.
Modified: trunk/mono/mono/mini/ChangeLog
===================================================================
--- trunk/mono/mono/mini/ChangeLog 2007-10-10 10:50:21 UTC (rev 87250)
+++ trunk/mono/mono/mini/ChangeLog 2007-10-10 10:50:50 UTC (rev 87251)
@@ -1,3 +1,8 @@
+
+Wed Oct 10 13:05:46 CEST 2007 Paolo Molaro <[EMAIL PROTECTED]>
+
+ * tramp-arm.c: reduced the trampoline size.
+
2007-10-10 Mark Probst <[EMAIL PROTECTED]>
* generic-sharing.c, mini.h, mini-amd64.c, mini-x86.c: Moved type
Modified: trunk/mono/mono/mini/tramp-arm.c
===================================================================
--- trunk/mono/mono/mini/tramp-arm.c 2007-10-10 10:50:21 UTC (rev 87250)
+++ trunk/mono/mono/mini/tramp-arm.c 2007-10-10 10:50:50 UTC (rev 87251)
@@ -19,6 +19,26 @@
#include "mini-arm.h"
/*
+ * Return the instruction to jump from code to target, 0 if not
+ * reachable with a single instruction
+ */
+static guint32
+branch_for_target_reachable (guint8 *branch, guint8 *target)
+{
+ gint diff = target - branch - 8;
+ g_assert ((diff & 3) == 0);
+ if (diff >= 0) {
+ if (diff <= 33554431)
+ return (ARMCOND_AL << ARMCOND_SHIFT) | (ARM_BR_TAG) |
(diff >> 2);
+ } else {
+ /* diff between 0 and -33554432 */
+ if (diff >= -33554432)
+ return (ARMCOND_AL << ARMCOND_SHIFT) | (ARM_BR_TAG) |
((diff >> 2) & ~0xff000000);
+ }
+ return 0;
+}
+
+/*
* mono_arch_get_unbox_trampoline:
* @m: method pointer
* @addr: pointer to native code for @m
@@ -127,12 +147,14 @@
code = buf = mono_global_codeman_reserve (GEN_TRAMP_SIZE);
/*
- * At this point r0 has the specific arg and sp points to the saved
- * regs on the stack (all but PC and SP).
+ * At this point lr points to the specific arg and sp points to the
saved
+ * regs on the stack (all but PC and SP). The original LR value has been
+ * saved as sp + LR_OFFSET by the push in the specific trampoline
*/
+#define LR_OFFSET (sizeof (gpointer) * 13)
ARM_MOV_REG_REG (buf, ARMREG_V1, ARMREG_SP);
- ARM_MOV_REG_REG (buf, ARMREG_V2, ARMREG_R0);
- ARM_MOV_REG_REG (buf, ARMREG_V3, ARMREG_LR);
+ ARM_LDR_IMM (buf, ARMREG_V2, ARMREG_LR, 0);
+ ARM_LDR_IMM (buf, ARMREG_V3, ARMREG_SP, LR_OFFSET);
/* ok, now we can continue with the MonoLMF setup, mostly untouched
* from emit_prolog in mini-arm.c
@@ -256,16 +278,23 @@
return code;
}
+#define SPEC_TRAMP_SIZE 24
+
gpointer
mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType
tramp_type, MonoDomain *domain, guint32 *code_len)
{
guint8 *code, *buf, *tramp;
gpointer *constants;
+ guint32 short_branch, size = SPEC_TRAMP_SIZE;
tramp = mono_get_trampoline_code (tramp_type);
mono_domain_lock (domain);
- code = buf = mono_code_manager_reserve (domain->code_mp, 24);
+ code = buf = mono_code_manager_reserve_align (domain->code_mp, size, 4);
+ if ((short_branch = branch_for_target_reachable (code + 8, tramp))) {
+ size = 12;
+ mono_code_manager_commit (domain->code_mp, code,
SPEC_TRAMP_SIZE, size);
+ }
mono_domain_unlock (domain);
/* we could reduce this to 12 bytes if tramp is within reach:
@@ -282,19 +311,26 @@
*/
/* We save all the registers, except PC and SP */
ARM_PUSH (buf, 0x5fff);
- ARM_LDR_IMM (buf, ARMREG_R0, ARMREG_PC, 4); /* arg1 is the only arg */
- ARM_LDR_IMM (buf, ARMREG_R1, ARMREG_PC, 4); /* temp reg */
- ARM_MOV_REG_REG (buf, ARMREG_PC, ARMREG_R1);
+ if (short_branch) {
+ constants = (gpointer*)buf;
+ constants [0] = GUINT_TO_POINTER (short_branch | (1 << 24));
+ constants [1] = arg1;
+ buf += 8;
+ } else {
+ ARM_LDR_IMM (buf, ARMREG_R1, ARMREG_PC, 8); /* temp reg */
+ ARM_MOV_REG_REG (buf, ARMREG_LR, ARMREG_PC);
+ ARM_MOV_REG_REG (buf, ARMREG_PC, ARMREG_R1);
- constants = (gpointer*)buf;
- constants [0] = arg1;
- constants [1] = tramp;
- buf += 8;
+ constants = (gpointer*)buf;
+ constants [0] = arg1;
+ constants [1] = tramp;
+ buf += 8;
+ }
/* Flush instruction cache, since we've generated code */
mono_arch_flush_icache (code, buf - code);
- g_assert ((buf - code) <= 24);
+ g_assert ((buf - code) <= size);
if (code_len)
*code_len = buf - code;
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches