diff options
| author | 2011-09-29 14:15:05 -0700 | |
|---|---|---|
| committer | 2011-09-29 14:15:05 -0700 | |
| commit | 12246b82eb9cdc621662a30b3c854d1abd307ec8 (patch) | |
| tree | 974ca2e66c6df38c149693fb0d700f7365d4f29a /src/compiler/codegen/arm/MethodCodegenDriver.cc | |
| parent | 6181f79576e4269937b45e4fce8d0d004107e5b9 (diff) | |
Add memory barriers (Issue 3338450)
Add missing barriers required for volatile access on Arm. Also,
flipped long volatile field accesses to the slow path. The
previous codegen was not only missing barriers, but was not
using 64-bit atomics.
Change-Id: I4aa2be2bf81971e5ae664c762ceaf2ea58ce231b
Diffstat (limited to 'src/compiler/codegen/arm/MethodCodegenDriver.cc')
| -rw-r--r-- | src/compiler/codegen/arm/MethodCodegenDriver.cc | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc index cfeb16aa45..9e026bea9f 100644 --- a/src/compiler/codegen/arm/MethodCodegenDriver.cc +++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc @@ -222,6 +222,11 @@ STATIC void genSput(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc) branchOver->generic.target = (LIR*)skipTarget; rlSrc = oatGetSrc(cUnit, mir, 0); rlSrc = loadValue(cUnit, rlSrc, kAnyReg); +#if ANDROID_SMP != 0 + if (field->IsVolatile()) { + oatGenMemBarrier(cUnit, kST); + } +#endif storeWordDisp(cUnit, rBase, fieldOffset, rlSrc.lowReg); #if ANDROID_SMP != 0 if (field->IsVolatile()) { @@ -241,7 +246,12 @@ STATIC void genSputWide(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc) uint32_t typeIdx; Field* field = FindFieldWithResolvedStaticStorage(cUnit->method, fieldIdx, typeIdx); oatFlushAllRegs(cUnit); - if (SLOW_FIELD_PATH || field == NULL) { +#if ANDROID_SMP != 0 + bool isVolatile = (field == NULL) || field->IsVolatile(); +#else + bool isVolatile = false; +#endif + if (SLOW_FIELD_PATH || field == NULL || isVolatile) { LOG(INFO) << "Field " << fieldNameFromIndex(cUnit->method, fieldIdx) << " unresolved at compile time"; loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pSet64Static), rLR); @@ -276,11 +286,6 @@ STATIC void genSputWide(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc) rlSrc = loadValueWide(cUnit, rlSrc, kAnyReg); storeBaseDispWide(cUnit, rBase, fieldOffset, rlSrc.lowReg, rlSrc.highReg); -#if ANDROID_SMP != 0 - if (field->IsVolatile()) { - oatGenMemBarrier(cUnit, kSY); - } -#endif oatFreeTemp(cUnit, rBase); } } @@ -292,8 +297,13 @@ STATIC void genSgetWide(CompilationUnit* cUnit, MIR* mir, int fieldIdx = mir->dalvikInsn.vB; uint32_t typeIdx; Field* field = FindFieldWithResolvedStaticStorage(cUnit->method, fieldIdx, typeIdx); +#if ANDROID_SMP != 0 + bool isVolatile = (field == NULL) || field->IsVolatile(); +#else + bool isVolatile = false; +#endif oatFlushAllRegs(cUnit); - if (SLOW_FIELD_PATH || field == NULL) { + if (SLOW_FIELD_PATH || field == NULL || isVolatile) { LOG(INFO) << "Field " << fieldNameFromIndex(cUnit->method, fieldIdx) << " unresolved at compile time"; loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pGet64Static), rLR); @@ -327,11 +337,6 @@ STATIC void genSgetWide(CompilationUnit* cUnit, MIR* mir, branchOver->generic.target = (LIR*)skipTarget; rlDest = oatGetDestWide(cUnit, mir, 0, 1); RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true); -#if ANDROID_SMP != 0 - if (field->IsVolatile()) { - oatGenMemBarrier(cUnit, kSY); - } -#endif loadBaseDispWide(cUnit, NULL, rBase, fieldOffset, rlResult.lowReg, rlResult.highReg, INVALID_SREG); oatFreeTemp(cUnit, rBase); |