diff options
author | Bill Buzbee <buzbee@google.com> | 2009-12-22 16:15:39 -0800 |
---|---|---|
committer | Bill Buzbee <buzbee@google.com> | 2009-12-22 16:35:35 -0800 |
commit | d0937ef76b41a57d25c084e76aed1bb91c6dfde7 (patch) | |
tree | c5bb13c73331f237fc45a6d75e188b21e73e0a63 /vm/compiler | |
parent | fe91bce011f8a4aa7bd67ff951cf7313510d34f4 (diff) | |
download | android_dalvik-d0937ef76b41a57d25c084e76aed1bb91c6dfde7.tar.gz android_dalvik-d0937ef76b41a57d25c084e76aed1bb91c6dfde7.tar.bz2 android_dalvik-d0937ef76b41a57d25c084e76aed1bb91c6dfde7.zip |
Jit: Update monitor lock/unlock to reflect thinlock changes (I34b20f49)
Diffstat (limited to 'vm/compiler')
-rw-r--r-- | vm/compiler/codegen/arm/ArmLIR.h | 6 | ||||
-rw-r--r-- | vm/compiler/codegen/arm/Assemble.c | 8 | ||||
-rw-r--r-- | vm/compiler/codegen/arm/CodegenDriver.c | 2 | ||||
-rw-r--r-- | vm/compiler/codegen/arm/Thumb2/Gen.c | 24 |
4 files changed, 36 insertions, 4 deletions
diff --git a/vm/compiler/codegen/arm/ArmLIR.h b/vm/compiler/codegen/arm/ArmLIR.h index 15000555a..8772b791c 100644 --- a/vm/compiler/codegen/arm/ArmLIR.h +++ b/vm/compiler/codegen/arm/ArmLIR.h @@ -598,7 +598,11 @@ typedef enum ArmOpCode { 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 8e977c147..26e227fd3 100644 --- a/vm/compiler/codegen/arm/Assemble.c +++ b/vm/compiler/codegen/arm/Assemble.c @@ -859,6 +859,14 @@ ArmEncodingMap EncodingMap[kArmLast] = { 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 249970cbe..f3648b9bd 100644 --- a/vm/compiler/codegen/arm/CodegenDriver.c +++ b/vm/compiler/codegen/arm/CodegenDriver.c @@ -2098,7 +2098,7 @@ static bool handleFmt11x(CompilationUnit *cUnit, MIR *mir) } 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 925136451..d108f922b 100644 --- a/vm/compiler/codegen/arm/Thumb2/Gen.c +++ b/vm/compiler/codegen/arm/Thumb2/Gen.c @@ -177,6 +177,18 @@ static ArmLIR *genExportPC(CompilationUnit *cUnit, MIR *mir) * 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 @@ static void genMonitor(CompilationUnit *cUnit, MIR *mir) 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 @@ static void genMonitor(CompilationUnit *cUnit, MIR *mir) 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 |