Runtime access checks on virtual method calls
At verification time we may not know that an illegal access or method
not found exception should be raised and so we defer the decision to
runtime. When the decision is deferred we perform an appropriate slow
path method invocation that can check for access violations.
This change also attempts to reduce code duplication, improve the
diagnostic information in exceptions, clean up field slow paths slightly
and to move the slow path calls lower in the Thread class so that they
don't effect the offsets of data items when calls are added or removed.
Change-Id: I8376b83dcd7e302cbbddf44c1a55a25687b9dcdb
diff --git a/src/thread.h b/src/thread.h
index b1b8a1e..b21af96 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -89,85 +89,6 @@
static const size_t kDefaultStackSize = 96 * KB;
- // Runtime support function pointers
- void (*pDebugMe)(Method*, uint32_t);
- void* (*pMemcpy)(void*, const void*, size_t);
- uint64_t (*pShlLong)(uint64_t, uint32_t);
- uint64_t (*pShrLong)(uint64_t, uint32_t);
- uint64_t (*pUshrLong)(uint64_t, uint32_t);
- float (*pI2f)(int);
- int (*pF2iz)(float);
- float (*pD2f)(double);
- double (*pF2d)(float);
- double (*pI2d)(int);
- int (*pD2iz)(double);
- float (*pL2f)(long);
- double (*pL2d)(long);
- long long (*pF2l)(float);
- long long (*pD2l)(double);
- float (*pFadd)(float, float);
- float (*pFsub)(float, float);
- float (*pFdiv)(float, float);
- float (*pFmul)(float, float);
- float (*pFmodf)(float, float);
- double (*pDadd)(double, double);
- double (*pDsub)(double, double);
- double (*pDdiv)(double, double);
- double (*pDmul)(double, double);
- double (*pFmod)(double, double);
- int (*pIdivmod)(int, int);
- int (*pIdiv)(int, int);
- long long (*pLmul)(long long, long long);
- long long (*pLdivmod)(long long, long long);
- void (*pCheckSuspendFromCode)(Thread*); // Stub that is called when the suspend count is non-zero
- void (*pTestSuspendFromCode)(); // Stub that is periodically called to test the suspend count
- void* (*pAllocObjectFromCode)(uint32_t, void*);
- void* (*pAllocObjectFromCodeWithAccessCheck)(uint32_t, void*);
- void* (*pAllocArrayFromCode)(uint32_t, void*, int32_t);
- void* (*pAllocArrayFromCodeWithAccessCheck)(uint32_t, void*, int32_t);
- void (*pCanPutArrayElementFromCode)(void*, void*);
- void* (*pCheckAndAllocArrayFromCode)(uint32_t, void*, int32_t);
- void* (*pCheckAndAllocArrayFromCodeWithAccessCheck)(uint32_t, void*, int32_t);
- void (*pCheckCastFromCode)(void*, void*);
- Object* (*pDecodeJObjectInThread)(Thread* thread, jobject obj);
- void (*pDeliverException)(void*);
- Method* (*pFindInterfaceMethodInCache)(Class*, uint32_t, const Method*, struct DvmDex*);
- void* (*pFindNativeMethod)(Thread* thread);
- int32_t (*pGet32Instance)(uint32_t, void*);
- int64_t (*pGet64Instance)(uint32_t, void*);
- void* (*pGetObjInstance)(uint32_t, void*);
- int32_t (*pGet32Static)(uint32_t);
- int64_t (*pGet64Static)(uint32_t);
- void* (*pGetObjStatic)(uint32_t);
- void (*pHandleFillArrayDataFromCode)(void*, void*);
- void* (*pInitializeStaticStorage)(uint32_t, void*);
- uint32_t (*pInstanceofNonTrivialFromCode)(const Class*, const Class*);
- void (*pInvokeInterfaceTrampoline)(uint32_t, void*);
- void* (*pInitializeTypeFromCode)(uint32_t, void*);
- void* (*pInitializeTypeAndVerifyAccessFromCode)(uint32_t, void*);
- void (*pLockObjectFromCode)(void*);
- void (*pObjectInit)(void*);
- void* (*pResolveMethodFromCode)(void*, uint32_t, bool);
- void* (*pResolveStringFromCode)(void*, uint32_t);
- int (*pSet32Instance)(uint32_t, void*, int32_t); // field_idx, obj, src
- int (*pSet64Instance)(uint32_t, void*, int64_t);
- int (*pSetObjInstance)(uint32_t, void*, void*);
- int (*pSet32Static)(uint32_t, int32_t);
- int (*pSet64Static)(uint32_t, int64_t);
- int (*pSetObjStatic)(uint32_t, void*);
- void (*pThrowStackOverflowFromCode)(void*);
- void (*pThrowNullPointerFromCode)();
- void (*pThrowArrayBoundsFromCode)(int32_t, int32_t);
- void (*pThrowDivZeroFromCode)();
- void (*pThrowVerificationErrorFromCode)(int32_t, int32_t);
- void (*pThrowNegArraySizeFromCode)(int32_t);
- void (*pThrowNoSuchMethodFromCode)(int32_t);
- void (*pThrowAbstractMethodErrorFromCode)(Method* method, Thread* thread, Method** sp);
- void (*pUnlockObjectFromCode)(void*);
- void* (*pUnresolvedDirectMethodTrampolineFromCode)(int32_t, Method**, Thread*,
- Runtime::TrampolineType);
- void (*pUpdateDebuggerFromCode)(void*, void*, int32_t, void*);
-
class StackVisitor {
public:
virtual ~StackVisitor() {}
@@ -642,6 +563,90 @@
// A cached copy of the java.lang.Thread's name.
std::string* name_;
+ public:
+ // Runtime support function pointers
+ void (*pDebugMe)(Method*, uint32_t);
+ void* (*pMemcpy)(void*, const void*, size_t);
+ uint64_t (*pShlLong)(uint64_t, uint32_t);
+ uint64_t (*pShrLong)(uint64_t, uint32_t);
+ uint64_t (*pUshrLong)(uint64_t, uint32_t);
+ float (*pI2f)(int);
+ int (*pF2iz)(float);
+ float (*pD2f)(double);
+ double (*pF2d)(float);
+ double (*pI2d)(int);
+ int (*pD2iz)(double);
+ float (*pL2f)(long);
+ double (*pL2d)(long);
+ long long (*pF2l)(float);
+ long long (*pD2l)(double);
+ float (*pFadd)(float, float);
+ float (*pFsub)(float, float);
+ float (*pFdiv)(float, float);
+ float (*pFmul)(float, float);
+ float (*pFmodf)(float, float);
+ double (*pDadd)(double, double);
+ double (*pDsub)(double, double);
+ double (*pDdiv)(double, double);
+ double (*pDmul)(double, double);
+ double (*pFmod)(double, double);
+ int (*pIdivmod)(int, int);
+ int (*pIdiv)(int, int);
+ long long (*pLmul)(long long, long long);
+ long long (*pLdivmod)(long long, long long);
+ void (*pCheckSuspendFromCode)(Thread*); // Stub that is called when the suspend count is non-zero
+ void (*pTestSuspendFromCode)(); // Stub that is periodically called to test the suspend count
+ void* (*pAllocObjectFromCode)(uint32_t, void*);
+ void* (*pAllocObjectFromCodeWithAccessCheck)(uint32_t, void*);
+ void* (*pAllocArrayFromCode)(uint32_t, void*, int32_t);
+ void* (*pAllocArrayFromCodeWithAccessCheck)(uint32_t, void*, int32_t);
+ void (*pCanPutArrayElementFromCode)(void*, void*);
+ void* (*pCheckAndAllocArrayFromCode)(uint32_t, void*, int32_t);
+ void* (*pCheckAndAllocArrayFromCodeWithAccessCheck)(uint32_t, void*, int32_t);
+ void (*pCheckCastFromCode)(void*, void*);
+ Object* (*pDecodeJObjectInThread)(Thread* thread, jobject obj);
+ void (*pDeliverException)(void*);
+ Method* (*pFindInterfaceMethodInCache)(Class*, uint32_t, const Method*, struct DvmDex*);
+ void* (*pFindNativeMethod)(Thread* thread);
+ int32_t (*pGet32Instance)(uint32_t, void*);
+ int64_t (*pGet64Instance)(uint32_t, void*);
+ void* (*pGetObjInstance)(uint32_t, void*);
+ int32_t (*pGet32Static)(uint32_t);
+ int64_t (*pGet64Static)(uint32_t);
+ void* (*pGetObjStatic)(uint32_t);
+ void (*pHandleFillArrayDataFromCode)(void*, void*);
+ void* (*pInitializeStaticStorage)(uint32_t, void*);
+ uint32_t (*pInstanceofNonTrivialFromCode)(const Class*, const Class*);
+ void (*pInvokeInterfaceTrampoline)(uint32_t, void*);
+ void (*pInvokeInterfaceTrampolineWithAccessCheck)(uint32_t, void*);
+ void (*pInvokeSuperTrampolineWithAccessCheck)(uint32_t, void*);
+ void (*pInvokeVirtualTrampolineWithAccessCheck)(uint32_t, void*);
+ void* (*pInitializeTypeFromCode)(uint32_t, void*);
+ void* (*pInitializeTypeAndVerifyAccessFromCode)(uint32_t, void*);
+ void (*pLockObjectFromCode)(void*);
+ void (*pObjectInit)(void*);
+ void* (*pResolveMethodFromCode)(void*, uint32_t, bool);
+ void* (*pResolveStringFromCode)(void*, uint32_t);
+ int (*pSet32Instance)(uint32_t, void*, int32_t); // field_idx, obj, src
+ int (*pSet64Instance)(uint32_t, void*, int64_t);
+ int (*pSetObjInstance)(uint32_t, void*, void*);
+ int (*pSet32Static)(uint32_t, int32_t);
+ int (*pSet64Static)(uint32_t, int64_t);
+ int (*pSetObjStatic)(uint32_t, void*);
+ void (*pThrowStackOverflowFromCode)(void*);
+ void (*pThrowNullPointerFromCode)();
+ void (*pThrowArrayBoundsFromCode)(int32_t, int32_t);
+ void (*pThrowDivZeroFromCode)();
+ void (*pThrowVerificationErrorFromCode)(int32_t, int32_t);
+ void (*pThrowNegArraySizeFromCode)(int32_t);
+ void (*pThrowNoSuchMethodFromCode)(int32_t);
+ void (*pThrowAbstractMethodErrorFromCode)(Method* method, Thread* thread, Method** sp);
+ void (*pUnlockObjectFromCode)(void*);
+ void* (*pUnresolvedDirectMethodTrampolineFromCode)(int32_t, Method**, Thread*,
+ Runtime::TrampolineType);
+ void (*pUpdateDebuggerFromCode)(void*, void*, int32_t, void*);
+
+ private:
DISALLOW_COPY_AND_ASSIGN(Thread);
};