diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/compiler/RuntimeUtilities.cc | 11 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/ArchFactory.cc | 11 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/MethodCodegenDriver.cc | 40 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Thumb2/Gen.cc | 113 | ||||
| -rw-r--r-- | src/compiler_test.cc | 14 | ||||
| -rw-r--r-- | src/java_lang_System.cc | 4 | ||||
| -rw-r--r-- | src/object.cc | 2 | ||||
| -rw-r--r-- | src/object.h | 2 | ||||
| -rw-r--r-- | src/runtime_support.h | 8 | ||||
| -rw-r--r-- | src/thread.cc | 51 | ||||
| -rw-r--r-- | src/thread.h | 22 |
11 files changed, 185 insertions, 93 deletions
diff --git a/src/compiler/RuntimeUtilities.cc b/src/compiler/RuntimeUtilities.cc index 53bd20e008..298cef1805 100644 --- a/src/compiler/RuntimeUtilities.cc +++ b/src/compiler/RuntimeUtilities.cc @@ -17,13 +17,14 @@ #include "Dalvik.h" #include "CompilerInternals.h" +namespace art { /* FIXME - codegen helper functions, move to art runtime proper */ /* * Float/double conversion requires clamping to min and max of integer form. If * target doesn't support this normally, use these. */ -int64_t artD2L(double d) +int64_t D2L(double d) { static const double kMaxLong = (double)(s8)0x7fffffffffffffffULL; static const double kMinLong = (double)(s8)0x8000000000000000ULL; @@ -37,7 +38,7 @@ int64_t artD2L(double d) return (s8)d; } -int64_t artF2L(float f) +int64_t F2L(float f) { static const float kMaxLong = (float)(s8)0x7fffffffffffffffULL; static const float kMinLong = (float)(s8)0x8000000000000000ULL; @@ -54,7 +55,7 @@ int64_t artF2L(float f) /* * Temporary placeholder. Should include run-time checks for size * of fill data <= size of array. If not, throw arrayOutOfBoundsException. - * As with other new "NoThrow" routines, this should return to the caller + * As with other new "FromCode" routines, this should return to the caller * only if no exception has been thrown. * * NOTE: When dealing with a raw dex file, the data to be copied uses @@ -68,7 +69,7 @@ int64_t artF2L(float f) * ubyte data[size*width] table of data values (may contain a single-byte * padding at the end) */ -void artHandleFillArrayDataNoThrow(Array* array, const uint16_t* table) +void HandleFillArrayDataFromCode(Array* array, const uint16_t* table) { uint32_t size = (uint32_t)table[2] | (((uint32_t)table[3]) << 16); uint32_t size_in_bytes = size * table[1]; @@ -76,3 +77,5 @@ void artHandleFillArrayDataNoThrow(Array* array, const uint16_t* table) memcpy((char*)array + art::Array::DataOffset().Int32Value(), (char*)&table[4], size_in_bytes); } + +} // namespace art diff --git a/src/compiler/codegen/arm/ArchFactory.cc b/src/compiler/codegen/arm/ArchFactory.cc index c8c7e349d2..243871910a 100644 --- a/src/compiler/codegen/arm/ArchFactory.cc +++ b/src/compiler/codegen/arm/ArchFactory.cc @@ -36,6 +36,17 @@ static void loadCurrMethodDirect(CompilationUnit *cUnit, int rTgt) #endif } +static int loadCurrMethod(CompilationUnit *cUnit) +{ +#if defined(METHOD_IN_REG) + return rMETHOD; +#else + int mReg = oatAllocTemp(cUnit); + loadCurrMethodDirect(cUnit, mReg); + return mReg; +#endif +} + /* * Perform a "reg cmp imm" operation and jump to the PCR region if condition * satisfies. diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc index c4b30b2e6b..c69a27e77c 100644 --- a/src/compiler/codegen/arm/MethodCodegenDriver.cc +++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc @@ -559,6 +559,8 @@ static int loadArgRegs(CompilationUnit* cUnit, MIR* mir, for (int i = 0; i < 3; i++) { if (args[i] != INVALID_REG) { RegLocation rlArg = oatGetSrc(cUnit, mir, i); + // Arguments are treated as a series of untyped 32-bit values. + rlArg.wide = false; loadValueDirectFixed(cUnit, rlArg, r1 + i); callState = nextCallInsn(cUnit, mir, dInsn, callState); } @@ -579,7 +581,7 @@ static int loadArgRegs(CompilationUnit* cUnit, MIR* mir, static int nextInterfaceCallInsn(CompilationUnit* cUnit, MIR* mir, DecodedInstruction* dInsn, int state) { - UNIMPLEMENTED(FATAL) << "Update with new cache model"; + UNIMPLEMENTED(FATAL) << "Need findInterfaceMethodInCache"; #if 0 RegLocation rlArg; switch(state) { @@ -628,7 +630,7 @@ static int nextInterfaceCallInsn(CompilationUnit* cUnit, MIR* mir, static int nextSuperCallInsn(CompilationUnit* cUnit, MIR* mir, DecodedInstruction* dInsn, int state) { - UNIMPLEMENTED(FATAL) << "Update with new cache model"; + UNIMPLEMENTED(FATAL) << "Need INVOKE_SUPER implementation"; #if 0 RegLocation rlArg; switch(state) { @@ -763,10 +765,10 @@ static int genDalvikArgsRange(CompilationUnit* cUnit, MIR* mir, * Make sure range list doesn't span the break between in normal * Dalvik vRegs and the ins. */ - int highestVreg = oatGetSrc(cUnit, mir, numArgs-1).sRegLow; - if (highestVreg >= cUnit->method->num_registers_ - - cUnit->method->num_ins_) { - LOG(FATAL) << "Wide argument spanned locals & args"; + int highestArg = oatGetSrc(cUnit, mir, numArgs-1).sRegLow; + int boundaryReg = cUnit->method->num_registers_ - cUnit->method->num_ins_; + if ((firstArg < boundaryReg) && (highestArg >= boundaryReg)) { + LOG(FATAL) << "Argument list spanned locals & args"; } /* @@ -777,11 +779,21 @@ static int genDalvikArgsRange(CompilationUnit* cUnit, MIR* mir, */ // Scan the rest of the args - if in physReg flush to memory for (int i = 4; i < numArgs; i++) { - RegLocation loc = oatUpdateLoc(cUnit, - oatGetSrc(cUnit, mir, i)); - if (loc.location == kLocPhysReg) { // TUNING: if dirty? - storeBaseDisp(cUnit, rSP, loc.spOffset, loc.lowReg, kWord); - callState = nextCallInsn(cUnit, mir, dInsn, callState); + RegLocation loc = oatGetSrc(cUnit, mir, i); + //TODO: generic loc flushing routine + if (loc.wide) { + loc = oatUpdateLocWide(cUnit, loc); + if (loc.location == kLocPhysReg) { // TUNING: if dirty? + storeBaseDispWide(cUnit, rSP, loc.spOffset, loc.lowReg, + loc.highReg); + callState = nextCallInsn(cUnit, mir, dInsn, callState); + } + } else { + loc = oatUpdateLoc(cUnit, loc); + if (loc.location == kLocPhysReg) { // TUNING: if dirty? + storeBaseDisp(cUnit, rSP, loc.spOffset, loc.lowReg, kWord); + callState = nextCallInsn(cUnit, mir, dInsn, callState); + } } } @@ -799,11 +811,11 @@ static int genDalvikArgsRange(CompilationUnit* cUnit, MIR* mir, int regsLeft = std::min(numArgs - 3, 16); callState = nextCallInsn(cUnit, mir, dInsn, callState); opRegRegImm(cUnit, kOpAdd, r3, rSP, startOffset); - newLIR3(cUnit, kThumb2Vldms, r3, fr0 & FP_REG_MASK, regsLeft); + newLIR3(cUnit, kThumb2Vldms, r3, fr0, regsLeft); callState = nextCallInsn(cUnit, mir, dInsn, callState); opRegRegImm(cUnit, kOpAdd, r3, rSP, 4 /* Method* */ + (3 * 4)); callState = nextCallInsn(cUnit, mir, dInsn, callState); - newLIR3(cUnit, kThumb2Vstms, r3, fr0 & FP_REG_MASK, regsLeft); + newLIR3(cUnit, kThumb2Vstms, r3, fr0, regsLeft); callState = nextCallInsn(cUnit, mir, dInsn, callState); } @@ -1287,7 +1299,7 @@ static bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir, genArrayPut(cUnit, mir, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2); break; case OP_APUT_OBJECT: - genArrayPut(cUnit, mir, rlSrc[1], rlSrc[2], rlSrc[0], 2); + genArrayObjPut(cUnit, mir, rlSrc[1], rlSrc[2], rlSrc[0], 2); break; case OP_APUT_SHORT: case OP_APUT_CHAR: diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc index 258b57be78..11146f7ba7 100644 --- a/src/compiler/codegen/arm/Thumb2/Gen.cc +++ b/src/compiler/codegen/arm/Thumb2/Gen.cc @@ -40,6 +40,14 @@ static inline s4 s4FromSwitchData(const void* switchData) { } #endif +/* Generate unconditional branch instructions */ +static ArmLIR* genUnconditionalBranch(CompilationUnit* cUnit, ArmLIR* target) +{ + ArmLIR* branch = opNone(cUnit, kOpUncondBr); + branch->generic.target = (LIR*) target; + return branch; +} + /* * Generate a Thumb2 IT instruction, which can nullify up to * four subsequent instructions based on a condition and its @@ -341,7 +349,7 @@ static void genFillArrayData(CompilationUnit* cUnit, MIR* mir, oatFlushAllRegs(cUnit); /* Everything to home location */ loadValueDirectFixed(cUnit, rlSrc, r0); loadWordDisp(cUnit, rSELF, - OFFSETOF_MEMBER(Thread, pArtHandleFillArrayDataNoThrow), rLR); + OFFSETOF_MEMBER(Thread, pHandleFillArrayDataFromCode), rLR); // Materialize a pointer to the fill data image newLIR3(cUnit, kThumb2AdrST, r1, 0, (intptr_t)tabRec); opReg(cUnit, kOpBlx, rLR); @@ -496,33 +504,60 @@ static void genIPutWideX(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc, static void genConstClass(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, RegLocation rlSrc) { - Class* classPtr = cUnit->method->GetDeclaringClass()->GetDexCache()-> - GetResolvedType(mir->dalvikInsn.vB); - - if (classPtr == NULL) { - LOG(FATAL) << "Unexpected null class pointer"; - } - - UNIMPLEMENTED(WARNING) << "Not position independent. Fix"; + art::Class* classPtr = cUnit->method->dex_cache_resolved_types_-> + Get(mir->dalvikInsn.vB); + int mReg = loadCurrMethod(cUnit); + int resReg = oatAllocTemp(cUnit); RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); - loadConstantNoClobber(cUnit, rlResult.lowReg, (int) classPtr ); - storeValue(cUnit, rlDest, rlResult); + loadWordDisp(cUnit, mReg, OFFSETOF_MEMBER(Method, dex_cache_strings_), + resReg); + loadWordDisp(cUnit, resReg, Array::DataOffset().Int32Value() + + (sizeof(String*) * mir->dalvikInsn.vB), rlResult.lowReg); + if (classPtr != NULL) { + // Fast path, we're done - just store result + storeValue(cUnit, rlDest, rlResult); + } else { + // Slow path. Must test at runtime + ArmLIR* branch1 = genCmpImmBranch(cUnit, kArmCondEq, rlResult.lowReg, + 0); + // Resolved, store and hop over following code + storeValue(cUnit, rlDest, rlResult); + ArmLIR* branch2 = genUnconditionalBranch(cUnit,0); + // TUNING: move slow path to end & remove unconditional branch + ArmLIR* target1 = newLIR0(cUnit, kArmPseudoTargetLabel); + target1->defMask = ENCODE_ALL; + // Call out to helper, which will return resolved type in r0 + loadWordDisp(cUnit, rSELF, + OFFSETOF_MEMBER(Thread, pInitializeTypeFromCode), rLR); + genRegCopy(cUnit, r1, mReg); + loadConstant(cUnit, r0, mir->dalvikInsn.vB); + opReg(cUnit, kOpBlx, rLR); // resolveTypeFromCode(idx, method) + oatClobberCallRegs(cUnit); + RegLocation rlResult = oatGetReturn(cUnit); + storeValue(cUnit, rlDest, rlResult); + // Rejoin code paths + ArmLIR* target2 = newLIR0(cUnit, kArmPseudoTargetLabel); + target2->defMask = ENCODE_ALL; + branch1->generic.target = (LIR*)target1; + branch2->generic.target = (LIR*)target2; + } } static void genConstString(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, RegLocation rlSrc) { - const String* strPtr = cUnit->method->GetDeclaringClass()->GetDexCache()-> - GetResolvedString(mir->dalvikInsn.vB); + /* All strings should be available at compile time */ + const art::String* str = cUnit->method->dex_cache_strings_-> + Get(mir->dalvikInsn.vB); + DCHECK(str != NULL); - if (strPtr == NULL) { - /* Shouldn't happen */ - LOG(FATAL) << "Unexpected null const string pointer"; - } - - UNIMPLEMENTED(WARNING) << "Not position indendent. Fix"; + int mReg = loadCurrMethod(cUnit); + int resReg = oatAllocTemp(cUnit); RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); - loadConstantNoClobber(cUnit, rlResult.lowReg, (int) strPtr ); + loadWordDisp(cUnit, mReg, OFFSETOF_MEMBER(Method, dex_cache_strings_), + resReg); + loadWordDisp(cUnit, resReg, Array::DataOffset().Int32Value() + + (sizeof(String*) * mir->dalvikInsn.vB), rlResult.lowReg); storeValue(cUnit, rlDest, rlResult); } @@ -547,10 +582,10 @@ static void genNewInstance(CompilationUnit* cUnit, MIR* mir, void genThrow(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc) { loadWordDisp(cUnit, rSELF, - OFFSETOF_MEMBER(Thread, pArtAllocObjectNoThrow), rLR); - loadValueDirectFixed(cUnit, rlSrc, r1); /* Exception object */ + OFFSETOF_MEMBER(Thread, pThrowException), rLR); + loadValueDirectFixed(cUnit, rlSrc, r1); // Get exception object genRegCopy(cUnit, r0, rSELF); - opReg(cUnit, kOpBlx, rLR); + opReg(cUnit, kOpBlx, rLR); // artThrowException(thread, exception); } static void genInstanceof(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, @@ -574,7 +609,7 @@ static void genInstanceof(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, loadWordDisp(cUnit, r0, OFFSETOF_MEMBER(Object, klass_), r1); /* r1 now contains object->clazz */ loadWordDisp(cUnit, rSELF, - OFFSETOF_MEMBER(Thread, pArtInstanceofNonTrivial), rLR); + OFFSETOF_MEMBER(Thread, pInstanceofNonTrivialFromCode), rLR); loadConstant(cUnit, r0, 1); /* Assume true */ opRegReg(cUnit, kOpCmp, r1, r2); ArmLIR* branch2 = opCondBranch(cUnit, kArmCondEq); @@ -614,7 +649,7 @@ static void genCheckCast(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc) /* r0 now contains object->clazz */ loadWordDisp(cUnit, rlSrc.lowReg, OFFSETOF_MEMBER(Object, klass_), r0); loadWordDisp(cUnit, rSELF, - OFFSETOF_MEMBER(Thread, pArtInstanceofNonTrivialNoThrow), rLR); + OFFSETOF_MEMBER(Thread, pInstanceofNonTrivialFromCode), rLR); opRegReg(cUnit, kOpCmp, r0, r1); ArmLIR* branch2 = opCondBranch(cUnit, kArmCondEq); // Assume success - if not, artInstanceOfNonTrivial will handle throw @@ -782,8 +817,8 @@ static void genMonitorEnter(CompilationUnit* cUnit, MIR* mir, hopTarget->defMask = ENCODE_ALL; hopBranch->generic.target = (LIR*)hopTarget; - // Go expensive route - artLockObjectNoThrow(self, obj); - loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pArtLockObjectNoThrow), + // Go expensive route - artLockObjectFromCode(self, obj); + loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pLockObjectFromCode), rLR); genRegCopy(cUnit, r0, rSELF); newLIR1(cUnit, kThumbBlxR, rLR); @@ -832,8 +867,8 @@ static void genMonitorExit(CompilationUnit* cUnit, MIR* mir, hopTarget->defMask = ENCODE_ALL; hopBranch->generic.target = (LIR*)hopTarget; - // Go expensive route - artUnlockObjectNoThrow(self, obj); - loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pArtUnlockObjectNoThrow), + // Go expensive route - UnlockObjectFromCode(self, obj); + loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pUnlockObjectFromCode), rLR); genRegCopy(cUnit, r0, rSELF); newLIR1(cUnit, kThumbBlxR, rLR); @@ -1057,13 +1092,13 @@ static bool genConversionPortable(CompilationUnit* cUnit, MIR* mir) 2, 1); case OP_FLOAT_TO_LONG: return genConversionCall(cUnit, mir, OFFSETOF_MEMBER(Thread, - pArtF2l), 1, 2); + pF2l), 1, 2); case OP_LONG_TO_FLOAT: return genConversionCall(cUnit, mir, OFFSETOF_MEMBER(Thread, pL2f), 2, 1); case OP_DOUBLE_TO_LONG: return genConversionCall(cUnit, mir, OFFSETOF_MEMBER(Thread, - pArtD2l), 2, 2); + pD2l), 2, 2); case OP_LONG_TO_DOUBLE: return genConversionCall(cUnit, mir, OFFSETOF_MEMBER(Thread, pL2d), 2, 2); @@ -1095,9 +1130,9 @@ static inline ArmLIR* genTrap(CompilationUnit* cUnit, int dOffset, * Generate array store * */ -static void genArrayPut(CompilationUnit* cUnit, MIR* mir, - RegLocation rlArray, RegLocation rlIndex, - RegLocation rlSrc, int scale) +static void genArrayObjPut(CompilationUnit* cUnit, MIR* mir, + RegLocation rlArray, RegLocation rlIndex, + RegLocation rlSrc, int scale) { RegisterClass regClass = oatRegClassBySize(kWord); int lenOffset = Array::LengthOffset().Int32Value(); @@ -1115,7 +1150,7 @@ static void genArrayPut(CompilationUnit* cUnit, MIR* mir, mir->offset, NULL); } loadWordDisp(cUnit, rSELF, - OFFSETOF_MEMBER(Thread, pArtCanPutArrayElementNoThrow), rLR); + OFFSETOF_MEMBER(Thread, pCanPutArrayElementFromCode), rLR); /* Get the array's clazz */ loadWordDisp(cUnit, r1, OFFSETOF_MEMBER(Object, klass_), r1); /* Get the object's clazz */ @@ -1546,14 +1581,6 @@ static bool genArithOpInt(CompilationUnit* cUnit, MIR* mir, return false; } -/* Generate unconditional branch instructions */ -static ArmLIR* genUnconditionalBranch(CompilationUnit* cUnit, ArmLIR* target) -{ - ArmLIR* branch = opNone(cUnit, kOpUncondBr); - branch->generic.target = (LIR*) target; - return branch; -} - /* * Fetch *self->info.breakFlags. If the breakFlags are non-zero, * punt to the interpreter. diff --git a/src/compiler_test.cc b/src/compiler_test.cc index eca5b2a96d..305b0d88a9 100644 --- a/src/compiler_test.cc +++ b/src/compiler_test.cc @@ -165,6 +165,20 @@ TEST_F(CompilerTest, BasicCodegen) { 10); } +TEST_F(CompilerTest, ConstStringTest) { + AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "constStringTest", + "(I)I", 2468, 1234); +} + +TEST_F(CompilerTest, DISABLED_CatchTest) { + CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V"); + CompileDirectMethod(NULL, "java.lang.NullPointerException", "<init>", "()V"); + const ClassLoader* class_loader = LoadDex("IntMath"); + CompileDirectMethod(class_loader, "IntMath", "throwNullPointerException", "()V"); + AssertStaticIntMethod(class_loader, "IntMath", "catchBlock", "(I)I", 1579, + 1000); +} + TEST_F(CompilerTest, StaticFieldTest) { AssertStaticIntMethod(LoadDex("IntMath"), "IntMath", "staticFieldTest", "(I)I", 1404, 404); diff --git a/src/java_lang_System.cc b/src/java_lang_System.cc index e874987a1e..43335ac205 100644 --- a/src/java_lang_System.cc +++ b/src/java_lang_System.cc @@ -213,14 +213,14 @@ void System_arraycopy(JNIEnv* env, jclass, jobject javaSrc, jint srcPos, jobject Class* initialElementClass = NULL; if (length > 0 && srcObj[0] != NULL) { initialElementClass = srcObj[0]->GetClass(); - if (!Class::CanPutArrayElementNoThrow(initialElementClass, dstClass)) { + if (!Class::CanPutArrayElementFromCode(initialElementClass, dstClass)) { initialElementClass = NULL; } } int copyCount; for (copyCount = 0; copyCount < length; copyCount++) { - if (srcObj[copyCount] != NULL && srcObj[copyCount]->GetClass() != initialElementClass && !Class::CanPutArrayElementNoThrow(srcObj[copyCount]->GetClass(), dstClass)) { + if (srcObj[copyCount] != NULL && srcObj[copyCount]->GetClass() != initialElementClass && !Class::CanPutArrayElementFromCode(srcObj[copyCount]->GetClass(), dstClass)) { // Can't put this element into the array. // We'll copy up to this point, then throw. break; diff --git a/src/object.cc b/src/object.cc index b71707fe21..cdc0e69100 100644 --- a/src/object.cc +++ b/src/object.cc @@ -63,7 +63,7 @@ Object* Class::AllocObject() { return Heap::AllocObject(this, this->object_size_); } -bool Class::CanPutArrayElementNoThrow(const Class* elementClass, const Class* arrayClass) { +bool Class::CanPutArrayElementFromCode(const Class* elementClass, const Class* arrayClass) { UNIMPLEMENTED(FATAL); return false; } diff --git a/src/object.h b/src/object.h index 5ae90c9655..bc6e7e515b 100644 --- a/src/object.h +++ b/src/object.h @@ -1123,7 +1123,7 @@ class Class : public Object, public StaticStorageBase { return that->IsPublic() || this->IsInSamePackage(that); } - static bool CanPutArrayElementNoThrow(const Class* elementClass, const Class* arrayClass); + static bool CanPutArrayElementFromCode(const Class* elementClass, const Class* arrayClass); // Returns the number of static, private, and constructor methods. size_t NumDirectMethods() const { diff --git a/src/runtime_support.h b/src/runtime_support.h index b586042d4f..8d65aaaacf 100644 --- a/src/runtime_support.h +++ b/src/runtime_support.h @@ -8,8 +8,6 @@ extern "C" uint64_t art_shl_long(uint64_t, uint32_t); extern "C" uint64_t art_shr_long(uint64_t, uint32_t); extern "C" uint64_t art_ushr_long(uint64_t, uint32_t); - extern int64_t artD2L(double); - extern int64_t artF2L(float); /* Conversions */ extern "C" float __aeabi_i2f(int op1); // OP_INT_TO_FLOAT @@ -45,6 +43,10 @@ extern "C" long long __aeabi_lmul(long long op1, long long op2); #endif - extern void artHandleFillArrayDataNoThrow(art::Array*, const uint16_t*); +namespace art { + int64_t D2L(double); + int64_t F2L(float); + void HandleFillArrayDataFromCode(art::Array*, const uint16_t*); +} #endif // ART_SRC_RUNTIME_SUPPORT_H_ diff --git a/src/thread.cc b/src/thread.cc index e3157f8983..89ec844c69 100644 --- a/src/thread.cc +++ b/src/thread.cc @@ -32,6 +32,30 @@ pid_t gettid() { return syscall(__NR_gettid);} pthread_key_t Thread::pthread_key_self_; +// TODO: placeholder. This is what generated code will call to throw +static void ThrowException(Thread* thread, Throwable* exception) { + /* + * exception may be NULL, in which case this routine should + * throw NPE. NOTE: this is a convenience for generated code, + * which previuosly did the null check inline and constructed + * and threw a NPE if NULL. This routine responsible for setting + * exception_ in thread. + */ + UNIMPLEMENTED(FATAL) << "Unimplemented exception throw"; +} + +// TODO: placeholder. Helper function to type +static Class* InitializeTypeFromCode(uint32_t type_idx, Method* method) { + /* + * Should initialize & fix up method->dex_cache_resolved_types_[]. + * Returns initialized type. Does not return normally if an exception + * is thrown, but instead initiates the catch. Should be similar to + * ClassLinker::InitializeStaticStorageFromCode. + */ + UNIMPLEMENTED(FATAL); + return NULL; +} + void Thread::InitFunctionPointers() { #if defined(__arm__) pShlLong = art_shl_long; @@ -56,32 +80,33 @@ void Thread::InitFunctionPointers() { pDdiv = __aeabi_ddiv; pDmul = __aeabi_dmul; pFmod = fmod; - pArtF2l = artF2L; - pArtD2l = artD2L; + pF2l = F2L; + pD2l = D2L; pLdivmod = __aeabi_ldivmod; pLmul = __aeabi_lmul; #endif pAllocFromCode = Array::AllocFromCode; pAllocObjectFromCode = Class::AllocObjectFromCode; pMemcpy = memcpy; - pArtHandleFillArrayDataNoThrow = artHandleFillArrayDataNoThrow; + pHandleFillArrayDataFromCode = HandleFillArrayDataFromCode; pGet32Static = Field::Get32StaticFromCode; pSet32Static = Field::Set32StaticFromCode; pGet64Static = Field::Get64StaticFromCode; pSet64Static = Field::Set64StaticFromCode; pGetObjStatic = Field::GetObjStaticFromCode; pSetObjStatic = Field::SetObjStaticFromCode; - pArtCanPutArrayElementNoThrow = Class::CanPutArrayElementNoThrow; + pCanPutArrayElementFromCode = Class::CanPutArrayElementFromCode; + pThrowException = ThrowException; + pInitializeTypeFromCode = InitializeTypeFromCode; #if 0 -bool (Thread::*pArtUnlockObject)(Thread*, Object*); -int (Thread::*pArtInstanceofNonTrivialNoThrow)(const Class*, const Class*); -int (Thread::*pArtInstanceofNonTrivial) (const Class*, const Class*); -Method* (Thread::*pArtFindInterfaceMethodInCache)(Class*, uint32_t, const Method*, DvmDex*); -bool (Thread::*pArtUnlockObjectNoThrow)(Thread*, Object*); -void (Thread::*pArtLockObjectNoThrow)(Thread*, Object*); -Object* (Thread::*pArtAllocObjectNoThrow)(Class*, int); -void (Thread::*pArtThrowException)(Thread*, Object*); -bool (Thread::*pArtHandleFillArrayDataNoThrow)(Array*, const uint16_t*); +bool (Thread::*pUnlockObject)(Thread*, Object*); +int (Thread::*pInstanceofNonTrivialFromCode)(const Class*, const Class*); +Method* (Thread::*pFindInterfaceMethodInCache)(Class*, uint32_t, const Method*, DvmDex*); +bool (Thread::*pUnlockObjectFromCode)(Thread*, Object*); +void (Thread::*pLockObjectFromCode)(Thread*, Object*); +Object* (Thread::*pAllocObjectFromCode)(Class*, int); +void (Thread::*pThrowException)(Thread*, Object*); +bool (Thread::*pHandleFillArrayDataFromCode)(Array*, const uint16_t*); #endif } diff --git a/src/thread.h b/src/thread.h index 4f2d8c843a..ab0660e40e 100644 --- a/src/thread.h +++ b/src/thread.h @@ -184,8 +184,8 @@ class Thread { int (*pD2iz)(double); float (*pL2f)(long); double (*pL2d)(long); - long long (*pArtF2l)(float); - long long (*pArtD2l)(double); + long long (*pF2l)(float); + long long (*pD2l)(double); float (*pFadd)(float, float); float (*pFsub)(float, float); float (*pFdiv)(float, float); @@ -208,16 +208,14 @@ class Thread { void (*pSet64Static)(uint32_t, const Method*, uint64_t); Object* (*pGetObjStatic)(uint32_t, const Method*); void (*pSetObjStatic)(uint32_t, const Method*, Object*); - bool (*pArtUnlockObject)(Thread*, Object*); - bool (*pArtCanPutArrayElementNoThrow)(const Class*, const Class*); - int (*pArtInstanceofNonTrivialNoThrow) (const Class*, const Class*); - int (*pArtInstanceofNonTrivial) (const Class*, const Class*); - Method* (*pArtFindInterfaceMethodInCache)(Class*, uint32_t, const Method*, struct DvmDex*); - bool (*pArtUnlockObjectNoThrow)(Thread*, Object*); - void (*pArtLockObjectNoThrow)(Thread*, Object*); - Object* (*pArtAllocObjectNoThrow)(Class*, int); - void (*pArtThrowException)(Thread*, Object*); - void (*pArtHandleFillArrayDataNoThrow)(Array*, const uint16_t*); + bool (*pCanPutArrayElementFromCode)(const Class*, const Class*); + int (*pInstanceofNonTrivialFromCode) (const Class*, const Class*); + Method* (*pFindInterfaceMethodInCache)(Class*, uint32_t, const Method*, struct DvmDex*); + bool (*pUnlockObjectFromCode)(Thread*, Object*); + void (*pLockObjectFromCode)(Thread*, Object*); + void (*pThrowException)(Thread*, Throwable*); + void (*pHandleFillArrayDataFromCode)(Array*, const uint16_t*); + Class* (*pInitializeTypeFromCode)(uint32_t, Method*); class StackVisitor { public: |