#ifndef DALVIK_DVMDEX_H_
#define DALVIK_DVMDEX_H_
+#include "jni.h"
#include "libdex/DexFile.h"
/* extern */
bool isMappedReadOnly;
MemMapping memMap;
+ jobject dex_object;
+
/* lock ensuring mutual exclusion during updates */
pthread_mutex_t modLock;
};
{ &gDvm.methJavaLangStackTraceElement_init, "Ljava/lang/StackTraceElement;",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V" },
{ &gDvm.methJavaLangReflectConstructor_init, "Ljava/lang/reflect/Constructor;",
- "(Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;I)V" },
+ "(Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;II)V" },
{ &gDvm.methJavaLangReflectField_init, "Ljava/lang/reflect/Field;",
- "(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;I)V" },
+ "(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;II)V" },
{ &gDvm.methJavaLangReflectMethod_init, "Ljava/lang/reflect/Method;",
"(Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;Ljava/lang/Class;"
- "Ljava/lang/String;I)V" },
+ "Ljava/lang/String;II)V" },
{ &gDvm.methJavaNioDirectByteBuffer_init, "Ljava/nio/DirectByteBuffer;",
"(JI)V" },
{ &gDvm.methOrgApacheHarmonyLangAnnotationAnnotationMember_init,
*/
#include "Dalvik.h"
#include "native/InternalNativePriv.h"
-
+#include "ScopedPthreadMutexLock.h"
/*
* native public boolean desiredAssertionStatus()
}
}
+JNIEXPORT jobject JNICALL Java_java_lang_Class_getDex(JNIEnv* env, jclass javaClass) {
+ Thread* self = dvmThreadSelf();
+ ClassObject* c = (ClassObject*) dvmDecodeIndirectRef(self, javaClass);
+
+ DvmDex* dvm_dex = c->pDvmDex;
+ if (dvm_dex == NULL) {
+ return NULL;
+ }
+
+ ScopedPthreadMutexLock lock(&dvm_dex->modLock);
+
+ // Already cached?
+ if (dvm_dex->dex_object != NULL) {
+ return dvm_dex->dex_object;
+ }
+
+ jobject byte_buffer = env->NewDirectByteBuffer(dvm_dex->memMap.addr, dvm_dex->memMap.length);
+ if (byte_buffer == NULL) {
+ return NULL;
+ }
+
+ jclass com_android_dex_Dex = env->FindClass("com/android/dex/Dex");
+ if (com_android_dex_Dex == NULL) {
+ return NULL;
+ }
+
+ jmethodID com_android_dex_Dex_create =
+ env->GetStaticMethodID(com_android_dex_Dex,
+ "<init>", "(Ljava/nio/ByteBuffer;)Lcom/android/dex/Dex;");
+ if (com_android_dex_Dex_create == NULL) {
+ return NULL;
+ }
+
+ jvalue args[1];
+ args[0].l = byte_buffer;
+ jobject local_ref = env->CallStaticObjectMethodA(com_android_dex_Dex,
+ com_android_dex_Dex_create,
+ args);
+ if (local_ref == NULL) {
+ return NULL;
+ }
+
+ dvm_dex->dex_object = env->NewGlobalRef(local_ref);
+ return dvm_dex->dex_object;
+}
+
const DalvikNativeMethod dvm_java_lang_Class[] = {
{ "desiredAssertionStatus", "()Z",
Dalvik_java_lang_Class_desiredAssertionStatus },
u4 accessFlags;
};
+u4 dvmGetFieldIdx(const Field* field);
+
/*
* Static field.
*/
bool inProfile;
};
+u4 dvmGetMethodIdx(const Method* method);
+
/*
* Find a method within a class. The superclass is not searched.
* out reasonably well because it's in sorted order, though we're still left
* doing a fair number of string comparisons.
*/
-static u4 getMethodIdx(const Method* method)
+u4 dvmGetMethodIdx(const Method* method)
{
+ if (method->clazz->pDvmDex == NULL) return 0;
+
DexFile* pDexFile = method->clazz->pDvmDex->pDexFile;
u4 hi = pDexFile->pHeader->methodIdsSize -1;
u4 lo = 0;
* find the method definition in the DEX file and perform string
* comparisons on class name, method name, and signature.
*/
- u4 methodIdx = getMethodIdx(method);
+ u4 methodIdx = dvmGetMethodIdx(method);
u4 count = dexGetMethodAnnotationsSize(pDexFile, pAnnoDir);
u4 idx;
/*
* Given a field, determine the field's index.
*
- * This has the same tradeoffs as getMethodIdx.
+ * This has the same tradeoffs as dvmGetMethodIdx.
*/
-static u4 getFieldIdx(const Field* field)
+u4 dvmGetFieldIdx(const Field* field)
{
+ if (field->clazz->pDvmDex == NULL) return 0;
+
DexFile* pDexFile = field->clazz->pDvmDex->pDexFile;
u4 hi = pDexFile->pHeader->fieldIdsSize -1;
u4 lo = 0;
* find the field definition in the DEX file and perform string
* comparisons on class name, field name, and signature.
*/
- u4 fieldIdx = getFieldIdx(field);
+ u4 fieldIdx = dvmGetFieldIdx(field);
u4 count = dexGetFieldAnnotationsSize(pDexFile, pAnnoDir);
u4 idx;
* find the method definition in the DEX file and perform string
* comparisons on class name, method name, and signature.
*/
- u4 methodIdx = getMethodIdx(method);
+ u4 methodIdx = dvmGetMethodIdx(method);
u4 count = dexGetParameterAnnotationsSize(pDexFile, pAnnoDir);
u4 idx;
ClassObject* type;
char* mangle;
char* cp;
- int slot;
+ int slot, field_idx;
assert(dvmIsClassInitialized(gDvm.classJavaLangReflectField));
goto bail;
slot = fieldToSlot(field, clazz);
+ field_idx = dvmGetFieldIdx(field);
JValue unused;
dvmCallMethod(dvmThreadSelf(), gDvm.methJavaLangReflectField_init,
- fieldObj, &unused, clazz, type, nameObj, slot);
+ fieldObj, &unused, clazz, type, nameObj, slot, field_idx);
if (dvmCheckException(dvmThreadSelf())) {
ALOGD("Field class init threw exception");
goto bail;
Object* consObj;
DexStringCache mangle;
char* cp;
- int slot;
+ int slot, method_idx;
dexStringCacheInit(&mangle);
goto bail;
slot = methodToSlot(meth);
+ method_idx = dvmGetMethodIdx(meth);
JValue unused;
dvmCallMethod(dvmThreadSelf(), gDvm.methJavaLangReflectConstructor_init,
- consObj, &unused, meth->clazz, params, exceptions, slot);
+ consObj, &unused, meth->clazz, params, exceptions, slot, method_idx);
if (dvmCheckException(dvmThreadSelf())) {
ALOGD("Constructor class init threw exception");
goto bail;
ClassObject* returnType;
DexStringCache mangle;
char* cp;
- int slot;
+ int slot, method_idx;
if (dvmCheckException(dvmThreadSelf())) {
ALOGW("WARNING: dvmCreateReflectMethodObject called with "
goto bail;
slot = methodToSlot(meth);
+ method_idx = dvmGetMethodIdx(meth);
JValue unused;
dvmCallMethod(dvmThreadSelf(), gDvm.methJavaLangReflectMethod_init,
methObj, &unused, meth->clazz, params, exceptions, returnType,
- nameObj, slot);
+ nameObj, slot, method_idx);
if (dvmCheckException(dvmThreadSelf())) {
ALOGD("Method class init threw exception");
goto bail;