Jit: Update monitor lock/unlock to reflect thinlock changes (I34b20f49)
diff --git a/vm/compiler/codegen/arm/ArmLIR.h b/vm/compiler/codegen/arm/ArmLIR.h
index 1500055..8772b79 100644
--- a/vm/compiler/codegen/arm/ArmLIR.h
+++ b/vm/compiler/codegen/arm/ArmLIR.h
@@ -598,7 +598,11 @@
imm8[7-0] */
kThumb2Strex, /* strex [111010000100] rn[19-16] rt[11-8] rd[11-8]
imm8[7-0] */
- kThumb2Clrex, /* clrex [111100111011111110000111100101111\ */
+ kThumb2Clrex, /* clrex [111100111011111110000111100101111] */
+ kThumb2Bfi, /* bfi [111100110110] rn[19-16] [0] imm3[14-12]
+ rd[11-8] imm2[7-6] [0] msb[4-0] */
+ kThumb2Bfc, /* bfc [11110011011011110] [0] imm3[14-12]
+ rd[11-8] imm2[7-6] [0] msb[4-0] */
kArmLast,
} ArmOpCode;
diff --git a/vm/compiler/codegen/arm/Assemble.c b/vm/compiler/codegen/arm/Assemble.c
index 8e977c1..26e227f 100644
--- a/vm/compiler/codegen/arm/Assemble.c
+++ b/vm/compiler/codegen/arm/Assemble.c
@@ -859,6 +859,14 @@
ENCODING_MAP(kThumb2Clrex, 0xf3bf8f2f,
kFmtUnused, -1, -1, kFmtUnused, -1, -1, kFmtUnused, -1, -1,
kFmtUnused, -1, -1, NO_OPERAND, "clrex", "", 2),
+ ENCODING_MAP(kThumb2Bfi, 0xf3600000,
+ kFmtBitBlt, 11, 8, kFmtBitBlt, 19, 16, kFmtShift5, -1, -1,
+ kFmtBitBlt, 4, 0, IS_QUAD_OP | REG_DEF0_USE1,
+ "bfi", "r!0d,r!1d,#!2d,#!3d", 2),
+ ENCODING_MAP(kThumb2Bfc, 0xf36f0000,
+ kFmtBitBlt, 11, 8, kFmtShift5, -1, -1, kFmtBitBlt, 4, 0,
+ kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_DEF0,
+ "bfc", "r!0d,#!1d,#!2d", 2),
};
/*
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c
index 249970c..f3648b9 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.c
+++ b/vm/compiler/codegen/arm/CodegenDriver.c
@@ -2098,7 +2098,7 @@
}
case OP_MONITOR_EXIT:
case OP_MONITOR_ENTER:
-#if 1 || defined(WITH_DEADLOCK_PREDICTION) || defined(WITH_MONITOR_TRACKING)
+#if defined(WITH_DEADLOCK_PREDICTION) || defined(WITH_MONITOR_TRACKING)
genMonitorPortable(cUnit, mir);
#else
genMonitor(cUnit, mir);
diff --git a/vm/compiler/codegen/arm/Thumb2/Gen.c b/vm/compiler/codegen/arm/Thumb2/Gen.c
index 9251364..d108f92 100644
--- a/vm/compiler/codegen/arm/Thumb2/Gen.c
+++ b/vm/compiler/codegen/arm/Thumb2/Gen.c
@@ -177,6 +177,18 @@
* r4 -> allow to be used by utilities as general temp
*
* The result of the strex is 0 if we acquire the lock.
+ *
+ * See comments in Sync.c for the layout of the lock word.
+ * Of particular interest to this code is the test for the
+ * simple case - which we handle inline. For monitor enter, the
+ * simple case is thin lock, held by no-one. For monitor exit,
+ * the simple case is thin lock, held by the unlocking thread with
+ * a recurse count of 0.
+ *
+ * A minor complication is that there is a field in the lock word
+ * unrelated to locking: the hash state. This field must be ignored, but
+ * preserved.
+ *
*/
static void genMonitor(CompilationUnit *cUnit, MIR *mir)
{
@@ -185,6 +197,7 @@
ArmLIR *target;
ArmLIR *branch;
+ assert(LW_SHAPE_THIN == 0);
loadValueDirectFixed(cUnit, rlSrc, r1); // Get obj
lockAllTemps(cUnit); // Prepare for explicit register usage
freeTemp(cUnit, r4PC); // Free up r4 for general use
@@ -193,11 +206,18 @@
loadWordDisp(cUnit, r0, offsetof(Thread, threadId), r3); // Get threadId
newLIR3(cUnit, kThumb2Ldrex, r2, r1,
offsetof(Object, lock.thin) >> 2); // Get object->lock.thin
+ opRegImm(cUnit, kOpLsl, r3, LW_LOCK_OWNER_SHIFT); // Align owner
// Is lock.thin unheld on lock or held by us (==threadId) on unlock?
if (enter) {
- opRegImm(cUnit, kOpSub, r2, DVM_LOCK_INITIAL_THIN_VALUE);
+ newLIR4(cUnit, kThumb2Bfi, r3, r2, 0, LW_LOCK_OWNER_SHIFT - 1);
+ newLIR3(cUnit, kThumb2Bfc, r2, LW_HASH_STATE_SHIFT,
+ LW_LOCK_OWNER_SHIFT - 1);
+ opRegImm(cUnit, kOpCmp, r2, 0);
} else {
- loadConstant(cUnit, r7, DVM_LOCK_INITIAL_THIN_VALUE);
+ opRegRegImm(cUnit, kOpAnd, r7, r2,
+ (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT));
+ newLIR3(cUnit, kThumb2Bfc, r2, LW_HASH_STATE_SHIFT,
+ LW_LOCK_OWNER_SHIFT - 1);
opRegReg(cUnit, kOpSub, r2, r3);
}
// Note: start of IT block. If last sub result != clear, else strex