diff options
Diffstat (limited to 'src/compiler/codegen/arm')
| -rw-r--r-- | src/compiler/codegen/arm/ArchFactory.cc | 20 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Thumb2/Gen.cc | 30 |
2 files changed, 36 insertions, 14 deletions
diff --git a/src/compiler/codegen/arm/ArchFactory.cc b/src/compiler/codegen/arm/ArchFactory.cc index 79a62ad30b..bdadf6e881 100644 --- a/src/compiler/codegen/arm/ArchFactory.cc +++ b/src/compiler/codegen/arm/ArchFactory.cc @@ -229,6 +229,10 @@ STATIC void genFilledNewArray(CompilationUnit* cUnit, MIR* mir, bool isRange) */ oatLockTemp(cUnit, r0); + // TODO: use the correct component size, currently all supported types share array alignment + // with ints (see comment at head of function) + size_t component_size = sizeof(int32_t); + // Having a range of 0 is legal if (isRange && (dInsn->vA > 0)) { /* @@ -262,7 +266,7 @@ STATIC void genFilledNewArray(CompilationUnit* cUnit, MIR* mir, bool isRange) oatSRegOffset(cUnit, rlFirst.sRegLow)); // Set up the target pointer opRegRegImm(cUnit, kOpAdd, rDst, r0, - Array::DataOffset().Int32Value()); + Array::DataOffset(component_size).Int32Value()); // Set up the loop counter (known to be > 0) loadConstant(cUnit, rIdx, dInsn->vA - 1); // Generate the copy loop. Going backwards for convenience @@ -281,7 +285,7 @@ STATIC void genFilledNewArray(CompilationUnit* cUnit, MIR* mir, bool isRange) RegLocation rlArg = loadValue(cUnit, oatGetSrc(cUnit, mir, i), kCoreReg); storeBaseDisp(cUnit, r0, - Array::DataOffset().Int32Value() + + Array::DataOffset(component_size).Int32Value() + i * 4, rlArg.lowReg, kWord); // If the loadValue caused a temp to be allocated, free it if (oatIsTemp(cUnit, rlArg.lowReg)) { @@ -330,7 +334,7 @@ STATIC void genSput(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc, Method::DexCacheInitializedStaticStorageOffset().Int32Value(), rBase); loadWordDisp(cUnit, rBase, - Array::DataOffset().Int32Value() + sizeof(int32_t*) * + Array::DataOffset(sizeof(Object*)).Int32Value() + sizeof(int32_t*) * ssbIndex, rBase); // rBase now points at appropriate static storage base (Class*) // or NULL if not initialized. Check for NULL and call helper if NULL. @@ -424,7 +428,8 @@ STATIC void genSget(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, Method::DexCacheInitializedStaticStorageOffset().Int32Value(), rBase); loadWordDisp(cUnit, rBase, - Array::DataOffset().Int32Value() + sizeof(int32_t*) * ssbIndex, + Array::DataOffset(sizeof(Object*)).Int32Value() + + sizeof(int32_t*) * ssbIndex, rBase); // rBase now points at appropriate static storage base (Class*) // or NULL if not initialized. Check for NULL and call helper if NULL. @@ -497,7 +502,8 @@ STATIC int nextSDCallInsn(CompilationUnit* cUnit, MIR* mir, break; case 2: // Grab target method* loadWordDisp(cUnit, r0, - Array::DataOffset().Int32Value() + dexIdx * 4, r0); + Array::DataOffset(sizeof(Object*)).Int32Value() + dexIdx * 4, + r0); break; case 3: // Grab the code from the method* loadWordDisp(cUnit, r0, Method::GetCodeOffset().Int32Value(), rLR); @@ -538,7 +544,7 @@ STATIC int nextVCallInsn(CompilationUnit* cUnit, MIR* mir, break; case 3: // Get target method [use rLR, set r0] loadWordDisp(cUnit, rLR, (methodIdx * 4) + - Array::DataOffset().Int32Value(), r0); + Array::DataOffset(sizeof(Object*)).Int32Value(), r0); break; case 4: // Get the target compiled code address [uses r0, sets rLR] loadWordDisp(cUnit, r0, Method::GetCodeOffset().Int32Value(), rLR); @@ -584,7 +590,7 @@ STATIC int nextSuperCallInsn(CompilationUnit* cUnit, MIR* mir, break; case 3: // Get target method [use rLR, set r0] loadWordDisp(cUnit, rLR, (methodIdx * 4) + - Array::DataOffset().Int32Value(), r0); + Array::DataOffset(sizeof(Object*)).Int32Value(), r0); break; case 4: // Get the target compiled code address [uses r0, sets rLR] loadWordDisp(cUnit, r0, Method::GetCodeOffset().Int32Value(), rLR); diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc index c385f358fc..5a9750a3ac 100644 --- a/src/compiler/codegen/arm/Thumb2/Gen.cc +++ b/src/compiler/codegen/arm/Thumb2/Gen.cc @@ -510,7 +510,8 @@ STATIC void genConstClass(CompilationUnit* cUnit, MIR* mir, // We're don't need access checks, load type from dex cache int32_t dex_cache_offset = Method::DexCacheResolvedTypesOffset().Int32Value(); loadWordDisp(cUnit, mReg, dex_cache_offset, resReg); - int32_t offset_of_type = Array::DataOffset().Int32Value() + (sizeof(Class*) * type_idx); + int32_t offset_of_type = Array::DataOffset(sizeof(Class*)).Int32Value() + + (sizeof(Class*) * type_idx); loadWordDisp(cUnit, resReg, offset_of_type, rlResult.lowReg); if (!cUnit->compiler->CanAssumeTypeIsPresentInDexCache(cUnit->dex_cache, type_idx) || @@ -571,7 +572,8 @@ STATIC void genConstString(CompilationUnit* cUnit, MIR* mir, { /* NOTE: Most strings should be available at compile time */ uint32_t string_idx = mir->dalvikInsn.vB; - int32_t offset_of_string = Array::DataOffset().Int32Value() + (sizeof(String*) * string_idx); + int32_t offset_of_string = Array::DataOffset(sizeof(String*)).Int32Value() + + (sizeof(String*) * string_idx); if (!cUnit->compiler->CanAssumeStringIsPresentInDexCache(cUnit->dex_cache, string_idx) || SLOW_STRING_PATH) { // slow path, resolve string if not in dex cache @@ -664,7 +666,8 @@ STATIC void genInstanceof(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, // Load dex cache entry into classReg (r2) loadValueDirectFixed(cUnit, rlSrc, r0); // r0 <= ref loadWordDisp(cUnit, r1, Method::DexCacheResolvedTypesOffset().Int32Value(), classReg); - int32_t offset_of_type = Array::DataOffset().Int32Value() + (sizeof(Class*) * type_idx); + int32_t offset_of_type = Array::DataOffset(sizeof(Class*)).Int32Value() + + (sizeof(Class*) * type_idx); loadWordDisp(cUnit, classReg, offset_of_type, classReg); if (!cUnit->compiler->CanAssumeTypeIsPresentInDexCache(cUnit->dex_cache, type_idx)) { // Need to test presence of type in dex cache at runtime @@ -728,7 +731,8 @@ STATIC void genCheckCast(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc) } else { // Load dex cache entry into classReg (r2) loadWordDisp(cUnit, r1, Method::DexCacheResolvedTypesOffset().Int32Value(), classReg); - int32_t offset_of_type = Array::DataOffset().Int32Value() + (sizeof(Class*) * type_idx); + int32_t offset_of_type = Array::DataOffset(sizeof(Class*)).Int32Value() + + (sizeof(Class*) * type_idx); loadWordDisp(cUnit, classReg, offset_of_type, classReg); if (!cUnit->compiler->CanAssumeTypeIsPresentInDexCache(cUnit->dex_cache, type_idx)) { // Need to test presence of type in dex cache at runtime @@ -1253,7 +1257,7 @@ STATIC void genArrayObjPut(CompilationUnit* cUnit, MIR* mir, { RegisterClass regClass = oatRegClassBySize(kWord); int lenOffset = Array::LengthOffset().Int32Value(); - int dataOffset = Array::DataOffset().Int32Value(); + int dataOffset = Array::DataOffset(sizeof(Object*)).Int32Value(); oatFlushAllRegs(cUnit); /* Make sure it's a legal object Put. Use direct regs at first */ @@ -1313,12 +1317,18 @@ STATIC void genArrayGet(CompilationUnit* cUnit, MIR* mir, OpSize size, { RegisterClass regClass = oatRegClassBySize(size); int lenOffset = Array::LengthOffset().Int32Value(); - int dataOffset = Array::DataOffset().Int32Value(); + int dataOffset; RegLocation rlResult; rlArray = loadValue(cUnit, rlArray, kCoreReg); rlIndex = loadValue(cUnit, rlIndex, kCoreReg); int regPtr; + if (size == kLong || size == kDouble) { + dataOffset = Array::DataOffset(sizeof(int64_t)).Int32Value(); + } else { + dataOffset = Array::DataOffset(sizeof(int32_t)).Int32Value(); + } + /* null object? */ genNullCheck(cUnit, rlArray.sRegLow, rlArray.lowReg, mir); @@ -1375,7 +1385,13 @@ STATIC void genArrayPut(CompilationUnit* cUnit, MIR* mir, OpSize size, { RegisterClass regClass = oatRegClassBySize(size); int lenOffset = Array::LengthOffset().Int32Value(); - int dataOffset = Array::DataOffset().Int32Value(); + int dataOffset; + + if (size == kLong || size == kDouble) { + dataOffset = Array::DataOffset(sizeof(int64_t)).Int32Value(); + } else { + dataOffset = Array::DataOffset(sizeof(int32_t)).Int32Value(); + } int regPtr; rlArray = loadValue(cUnit, rlArray, kCoreReg); |