#include "native/native.h"
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/jit/builtin.hpp"
+#include "vm/class.h"
+#include "vm/field.hpp"
#include "vm/initialize.h"
+#include "vm/options.h"
+#include "vm/references.h"
+#include "vm/resolve.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/methodheader.h"
-#include "vm/jit/patcher-common.h"
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/class.h"
-#include "vmcore/field.h"
-#include "vmcore/options.h"
-#include "vmcore/references.h"
-#include "vm/resolve.h"
+#include "vm/jit/patcher-common.hpp"
/* patcher_patch_code **********************************************************
void patcher_patch_code(patchref_t *pr)
{
- /* patch back original code */
+ // Patch back original code.
+ *((uint32_t*) pr->mpc) = pr->mcode;
- *((u4 *) pr->mpc) = pr->mcode;
-
- /* synchronize instruction cache */
-
- md_icacheflush(pr->mpc, 4);
+ // Synchronize instruction cache.
+ md_icacheflush((void*) pr->mpc, 1 * 4);
}
if (!initialize_class(fi->clazz))
return false;
- /* patch back original code */
-
- *((u4 *) ra) = mcode;
-
- /* synchronize instruction cache */
-
- md_icacheflush(ra, 4);
-
/* patch the field value's address */
*((intptr_t *) datap) = (intptr_t) fi->value;
md_dcacheflush(datap, SIZEOF_VOID_P);
+ // Patch back the original code.
+ patcher_patch_code(pr);
+
return true;
}
if (!(fi = resolve_field_eager(uf)))
return false;
- /* patch back original code */
-
- *((u4 *) ra) = mcode;
+ // Patch the field offset in the patcher. We also need this to
+ // validate patchers.
+ pr->mcode |= (int16_t) (fi->offset & 0x0000ffff);
- /* synchronize instruction cache */
-
- md_icacheflush(ra, 4);
-
- /* if we show disassembly, we have to skip the nop */
-
- if (opt_shownops)
- ra = ra + 4;
-
- /* patch the field's offset */
-
- *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
-
- /* synchronize instruction cache */
-
- md_icacheflush(ra, 8);
+ // Patch back the original code.
+ patcher_patch_code(pr);
return true;
}
if (!(m = resolve_method_eager(um)))
return false;
- /* patch back original code */
-
- *((u4 *) ra) = mcode;
-
- /* synchronize instruction cache */
-
- md_icacheflush(ra, 4);
-
- /* patch stubroutine */
-
+ // Patch stubroutine.
*((ptrint *) datap) = (ptrint) m->stubroutine;
- /* synchronize data cache */
-
+ // Synchronize data cache.
md_dcacheflush(datap, SIZEOF_VOID_P);
+ // Patch back the original code.
+ patcher_patch_code(pr);
+
return true;
}
if (!(m = resolve_method_eager(um)))
return false;
- /* patch back original code */
-
- *((u4 *) ra) = mcode;
-
- /* synchronize instruction cache */
-
- md_icacheflush(ra, 4);
-
- /* if we show disassembly, we have to skip the nop */
-
- if (opt_shownops)
- ra = ra + 4;
-
- /* patch vftbl index */
-
+ // Patch vftbl index.
disp = (OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * m->vftblindex);
- *((s4 *) (ra + 4)) |= (disp & 0x0000ffff);
-
- /* synchronize instruction cache */
+ *((uint32_t*) (ra + 1 * 4)) |= (disp & 0x0000ffff);
+ // Synchronize instruction cache.
md_icacheflush(ra, 2 * 4);
+ // Patch back the original code.
+ patcher_patch_code(pr);
+
return true;
}
if (!(m = resolve_method_eager(um)))
return false;
- /* patch back original code */
-
- *((u4 *) ra) = mcode;
-
- /* synchronize instruction cache */
-
- md_icacheflush(ra, 4);
-
- /* if we show disassembly, we have to skip the nop */
-
- if (opt_shownops)
- ra = ra + 4;
-
- /* patch interfacetable index */
-
+ // Patch interfacetable index.
disp = OFFSET(vftbl_t, interfacetable[0]) -
sizeof(methodptr*) * m->clazz->index;
- /* XXX TWISTI: check displacement */
-
- *((s4 *) (ra + 1 * 4)) |= (disp & 0x0000ffff);
-
- /* patch method offset */
+ // XXX TWISTI: check displacement
+ *((uint32_t*) (ra + 1 * 4)) |= (disp & 0x0000ffff);
+ // Patch method offset.
disp = sizeof(methodptr) * (m - m->clazz->methods);
- /* XXX TWISTI: check displacement */
-
- *((s4 *) (ra + 2 * 4)) |= (disp & 0x0000ffff);
-
- /* synchronize instruction cache */
+ // XXX TWISTI: check displacement
+ *((uint32_t*) (ra + 2 * 4)) |= (disp & 0x0000ffff);
+ // Synchronize instruction cache.
md_icacheflush(ra, 3 * 4);
+ // Patch back the original code.
+ patcher_patch_code(pr);
+
return true;
}
return false;
}
- /* patch back original code */
- *((u4 *) ra) = mcode;
-
- /* synchronize instruction cache */
-
- md_icacheflush(ra, 4);
-
- /* if we show NOPs, we have to skip them */
- if (opt_shownops)
- ra = ra +4;
-
- /* patch super class index */
+ // Patch super class index.
disp = -(c->index);
-
- *((s4*)(ra + 2*4)) |= (disp & 0x0000ffff);
+ *((uint32_t*) (ra + 2 * 4)) |= (disp & 0x0000ffff);
disp = OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*);
+ *((uint32_t*) (ra + 5 * 4)) |= (disp & 0x0000ffff);
- *((s4 *)(ra + 5*4)) |= (disp & 0x0000ffff);
+ // Synchronize instruction cache.
+ md_icacheflush(ra, 6 * 4);
- /* sync instruction cache */
- md_icacheflush(ra, 6*4);
+ // Patch back the original code.
+ patcher_patch_code(pr);
return true;
}
if (!(c = resolve_classref_eager(cr)))
return false;
- /* patch back original code */
-
- *((u4 *) ra) = mcode;
-
- /* synchronize instruction cache */
-
- md_icacheflush(ra, 4);
-
- /* if we show disassembly, we have to skip the nop */
-
- if (opt_shownops)
- ra = ra + 4;
-
- /* patch super class index */
-
+ // Patch super class index.
disp = -(c->index);
-
- *((s4 *) (ra + 2 * 4)) |= (disp & 0x0000ffff);
+ *((uint32_t*) (ra + 2 * 4)) |= (disp & 0x0000ffff);
disp = OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*);
+ *((uint32_t*) (ra + 4 * 4)) |= (disp & 0x0000ffff);
- *((s4 *) (ra + 4 * 4)) |= (disp & 0x0000ffff);
-
- /* synchronize instruction cache */
-
+ // Synchronize instruction cache.
md_icacheflush(ra, 5 * 4);
+ // Patch back the original code.
+ patcher_patch_code(pr);
+
return true;
}
if (!(c = resolve_classref_eager(cr)))
return false;
- /* patch back original code */
-
- *((u4 *) ra) = mcode;
-
- /* synchronize instruction cache */
-
- md_icacheflush(ra, 4);
-
- /* patch the classinfo pointer */
-
- *((ptrint *) datap) = (ptrint) c;
-
- /* synchronize data cache */
+ // Patch the classinfo pointer.
+ *((uintptr_t*) datap) = (uintptr_t) c;
+ // Synchronize data cache.
md_dcacheflush(datap, SIZEOF_VOID_P);
+ // Patch back the original code.
+ patcher_patch_code(pr);
+
return true;
}
if (!(c = resolve_classref_eager(cr)))
return false;
- /* patch back original code */
-
- *((u4 *) ra) = mcode;
-
- /* synchronize instruction cache */
-
- md_icacheflush(ra, 4);
-
- /* patch super class' vftbl */
-
- *((ptrint *) datap) = (ptrint) c->vftbl;
-
- /* synchronize data cache */
+ // Patch super class' vftbl.
+ *((uintptr_t*) datap) = (uintptr_t) c->vftbl;
+ // Synchronize data cache.
md_dcacheflush(datap, SIZEOF_VOID_P);
+ // Patch back the original code.
+ patcher_patch_code(pr);
+
return true;
}
if (!(c = resolve_classref_eager(cr)))
return false;
- /* patch back original code */
-
- *((u4 *) ra) = mcode;
-
- /* synchronize instruction cache */
-
- md_icacheflush(ra, 4);
-
- /* patch class flags */
-
- *((s4 *) datap) = (s4) c->flags;
-
- /* synchronize data cache */
+ // Patch class flags.
+ *((int32_t*) datap) = (int32_t) c->flags;
+ // Synchronize data cache.
md_dcacheflush(datap, SIZEOF_VOID_P);
+ // Patch back the original code.
+ patcher_patch_code(pr);
+
return true;
}