Merge "Add -verbose:startup" into dalvik-dev
diff --git a/src/check_jni.cc b/src/check_jni.cc
index 2208d14..4989f23 100644
--- a/src/check_jni.cc
+++ b/src/check_jni.cc
@@ -134,16 +134,16 @@
public:
// For JNIEnv* functions.
explicit ScopedCheck(JNIEnv* env, int flags, const char* functionName) {
- init(env, reinterpret_cast<JNIEnvExt*>(env)->vm, flags, functionName, true);
- checkThread(flags);
+ Init(env, reinterpret_cast<JNIEnvExt*>(env)->vm, flags, functionName, true);
+ CheckThread(flags);
}
// For JavaVM* functions.
explicit ScopedCheck(JavaVM* vm, bool hasMethod, const char* functionName) {
- init(NULL, vm, kFlag_Invocation, functionName, hasMethod);
+ Init(NULL, vm, kFlag_Invocation, functionName, hasMethod);
}
- bool forceCopy() {
+ bool ForceCopy() {
return Runtime::Current()->GetJavaVM()->force_copy;
}
@@ -160,9 +160,9 @@
* We expect "fully-qualified" class names, like "java/lang/Thread" or
* "[Ljava/lang/Object;".
*/
- void checkClassName(const char* className) {
+ void CheckClassName(const char* className) {
if (!IsValidClassName(className, true, false)) {
- LOG(ERROR) << "JNI ERROR: illegal class name '" << className << "' (" << mFunctionName << ")\n"
+ LOG(ERROR) << "JNI ERROR: illegal class name '" << className << "' (" << function_name_ << ")\n"
<< " (should be of the form 'java/lang/String', [Ljava/lang/String;' or '[[B')\n";
JniAbort();
}
@@ -174,15 +174,12 @@
*
* Works for both static and instance fields.
*/
- void checkFieldType(jobject java_object, jfieldID fid, char prim, bool isStatic) {
- if (fid == NULL) {
- LOG(ERROR) << "JNI ERROR: null jfieldID";
- JniAbort();
+ void CheckFieldType(jobject java_object, jfieldID fid, char prim, bool isStatic) {
+ ScopedJniThreadState ts(env_);
+ Field* f = CheckFieldID(fid);
+ if (f == NULL) {
return;
}
-
- ScopedJniThreadState ts(mEnv);
- Field* f = DecodeField(fid);
Class* field_type = f->GetType();
if (!field_type->IsPrimitive()) {
if (java_object != NULL) {
@@ -226,18 +223,20 @@
*
* Assumes "jobj" has already been validated.
*/
- void checkInstanceFieldID(jobject java_object, jfieldID fid) {
- ScopedJniThreadState ts(mEnv);
+ void CheckInstanceFieldID(jobject java_object, jfieldID fid) {
+ ScopedJniThreadState ts(env_);
Object* o = Decode<Object*>(ts, java_object);
- if (!Heap::IsHeapAddress(o)) {
+ if (o == NULL || !Heap::IsHeapAddress(o)) {
LOG(ERROR) << "JNI ERROR: field operation on invalid " << GetIndirectRefKind(java_object) << ": " << java_object;
JniAbort();
return;
}
- CHECK(fid != NULL) << PrettyTypeOf(o);
- Field* f = DecodeField(fid);
+ Field* f = CheckFieldID(fid);
+ if (f == NULL) {
+ return;
+ }
Class* f_type = f->GetType();
// check invariant that all jfieldIDs have resolved types
DCHECK(f_type != NULL);
@@ -251,7 +250,7 @@
/*
* Verify that the pointer value is non-NULL.
*/
- void checkNonNull(const void* ptr) {
+ void CheckNonNull(const void* ptr) {
if (ptr == NULL) {
LOG(ERROR) << "JNI ERROR: invalid null pointer";
JniAbort();
@@ -262,9 +261,12 @@
* Verify that the method's return type matches the type of call.
* 'expectedType' will be "L" for all objects, including arrays.
*/
- void checkSig(jmethodID mid, const char* expectedType, bool isStatic) {
- ScopedJniThreadState ts(mEnv);
- const Method* m = DecodeMethod(mid);
+ void CheckSig(jmethodID mid, const char* expectedType, bool isStatic) {
+ ScopedJniThreadState ts(env_);
+ const Method* m = CheckMethodID(mid);
+ if (m == NULL) {
+ return;
+ }
if (*expectedType != m->GetShorty()->CharAt(0)) {
LOG(ERROR) << "JNI ERROR: expected return type '" << *expectedType << "' calling " << PrettyMethod(m);
JniAbort();
@@ -283,10 +285,13 @@
*
* Assumes "java_class" has already been validated.
*/
- void checkStaticFieldID(jclass java_class, jfieldID fid) {
- ScopedJniThreadState ts(mEnv);
+ void CheckStaticFieldID(jclass java_class, jfieldID fid) {
+ ScopedJniThreadState ts(env_);
Class* c = Decode<Class*>(ts, java_class);
- const Field* f = DecodeField(fid);
+ const Field* f = CheckFieldID(fid);
+ if (f == NULL) {
+ return;
+ }
if (f->GetDeclaringClass() != c) {
LOG(ERROR) << "JNI ERROR: static jfieldID " << fid << " not valid for class " << PrettyClass(c);
JniAbort();
@@ -302,10 +307,13 @@
*
* Instances of "jclazz" must be instances of the method's declaring class.
*/
- void checkStaticMethod(jclass java_class, jmethodID mid) {
- ScopedJniThreadState ts(mEnv);
+ void CheckStaticMethod(jclass java_class, jmethodID mid) {
+ ScopedJniThreadState ts(env_);
+ const Method* m = CheckMethodID(mid);
+ if (m == NULL) {
+ return;
+ }
Class* c = Decode<Class*>(ts, java_class);
- const Method* m = DecodeMethod(mid);
if (!c->IsAssignableFrom(m->GetDeclaringClass())) {
LOG(ERROR) << "JNI ERROR: can't call static " << PrettyMethod(m) << " on class " << PrettyClass(c);
JniAbort();
@@ -319,10 +327,13 @@
* (Note the mid might point to a declaration in an interface; this
* will be handled automatically by the instanceof check.)
*/
- void checkVirtualMethod(jobject java_object, jmethodID mid) {
- ScopedJniThreadState ts(mEnv);
+ void CheckVirtualMethod(jobject java_object, jmethodID mid) {
+ ScopedJniThreadState ts(env_);
+ const Method* m = CheckMethodID(mid);
+ if (m == NULL) {
+ return;
+ }
Object* o = Decode<Object*>(ts, java_object);
- const Method* m = DecodeMethod(mid);
if (!o->InstanceOf(m->GetDeclaringClass())) {
LOG(ERROR) << "JNI ERROR: can't call " << PrettyMethod(m) << " on instance of " << PrettyTypeOf(o);
JniAbort();
@@ -365,20 +376,20 @@
*
* Use the kFlag_NullableUtf flag where 'u' field(s) are nullable.
*/
- void check(bool entry, const char* fmt0, ...) {
+ void Check(bool entry, const char* fmt0, ...) {
va_list ap;
const Method* traceMethod = NULL;
- if ((!mVm->trace.empty() || mVm->log_third_party_jni) && mHasMethod) {
+ if ((!vm_->trace.empty() || vm_->log_third_party_jni) && has_method_) {
// We need to guard some of the invocation interface's calls: a bad caller might
// use DetachCurrentThread or GetEnv on a thread that's not yet attached.
Thread* self = Thread::Current();
- if ((mFlags & kFlag_Invocation) == 0 || self != NULL) {
+ if ((flags_ & kFlag_Invocation) == 0 || self != NULL) {
traceMethod = self->GetCurrentMethod();
}
}
- if (traceMethod != NULL && ShouldTrace(mVm, traceMethod)) {
+ if (traceMethod != NULL && ShouldTrace(vm_, traceMethod)) {
va_start(ap, fmt0);
std::string msg;
for (const char* fmt = fmt0; *fmt;) {
@@ -496,16 +507,16 @@
va_end(ap);
if (entry) {
- if (mHasMethod) {
+ if (has_method_) {
std::string methodName(PrettyMethod(traceMethod, false));
- LOG(INFO) << "JNI: " << methodName << " -> " << mFunctionName << "(" << msg << ")";
- mIndent = methodName.size() + 1;
+ LOG(INFO) << "JNI: " << methodName << " -> " << function_name_ << "(" << msg << ")";
+ indent_ = methodName.size() + 1;
} else {
- LOG(INFO) << "JNI: -> " << mFunctionName << "(" << msg << ")";
- mIndent = 0;
+ LOG(INFO) << "JNI: -> " << function_name_ << "(" << msg << ")";
+ indent_ = 0;
}
} else {
- LOG(INFO) << StringPrintf("JNI: %*s<- %s returned %s", mIndent, "", mFunctionName, msg.c_str());
+ LOG(INFO) << StringPrintf("JNI: %*s<- %s returned %s", indent_, "", function_name_, msg.c_str());
}
}
@@ -515,24 +526,24 @@
for (const char* fmt = fmt0; *fmt; ++fmt) {
char ch = *fmt;
if (ch == 'a') {
- checkArray(va_arg(ap, jarray));
+ CheckArray(va_arg(ap, jarray));
} else if (ch == 'c') {
- checkInstance(kClass, va_arg(ap, jclass));
+ CheckInstance(kClass, va_arg(ap, jclass));
} else if (ch == 'L') {
- checkObject(va_arg(ap, jobject));
+ CheckObject(va_arg(ap, jobject));
} else if (ch == 'r') {
- checkReleaseMode(va_arg(ap, jint));
+ CheckReleaseMode(va_arg(ap, jint));
} else if (ch == 's') {
- checkInstance(kString, va_arg(ap, jstring));
+ CheckInstance(kString, va_arg(ap, jstring));
} else if (ch == 'u') {
- if ((mFlags & kFlag_Release) != 0) {
- checkNonNull(va_arg(ap, const char*));
+ if ((flags_ & kFlag_Release) != 0) {
+ CheckNonNull(va_arg(ap, const char*));
} else {
- bool nullable = ((mFlags & kFlag_NullableUtf) != 0);
- checkUtfString(va_arg(ap, const char*), nullable);
+ bool nullable = ((flags_ & kFlag_NullableUtf) != 0);
+ CheckUtfString(va_arg(ap, const char*), nullable);
}
} else if (ch == 'z') {
- checkLengthPositive(va_arg(ap, jsize));
+ CheckLengthPositive(va_arg(ap, jsize));
} else if (strchr("BCISZbfmpEv", ch) != NULL) {
va_arg(ap, int); // Skip this argument.
} else if (ch == 'D' || ch == 'F') {
@@ -549,16 +560,16 @@
}
private:
- void init(JNIEnv* env, JavaVM* vm, int flags, const char* functionName, bool hasMethod) {
- mEnv = reinterpret_cast<JNIEnvExt*>(env);
- mVm = reinterpret_cast<JavaVMExt*>(vm);
- mFlags = flags;
- mFunctionName = functionName;
+ void Init(JNIEnv* env, JavaVM* vm, int flags, const char* functionName, bool hasMethod) {
+ env_ = reinterpret_cast<JNIEnvExt*>(env);
+ vm_ = reinterpret_cast<JavaVMExt*>(vm);
+ flags_ = flags;
+ function_name_ = functionName;
// Set "hasMethod" to true if we have a valid thread with a method pointer.
// We won't have one before attaching a thread, after detaching a thread, or
// after destroying the VM.
- mHasMethod = hasMethod;
+ has_method_ = hasMethod;
}
/*
@@ -566,14 +577,14 @@
*
* Since we're dealing with objects, switch to "running" mode.
*/
- void checkArray(jarray java_array) {
+ void CheckArray(jarray java_array) {
if (java_array == NULL) {
LOG(ERROR) << "JNI ERROR: received null array";
JniAbort();
return;
}
- ScopedJniThreadState ts(mEnv);
+ ScopedJniThreadState ts(env_);
Array* a = Decode<Array*>(ts, java_array);
if (!Heap::IsHeapAddress(a)) {
LOG(ERROR) << "JNI ERROR: jarray is an invalid " << GetIndirectRefKind(java_array) << ": " << reinterpret_cast<void*>(java_array);
@@ -584,25 +595,55 @@
}
}
- void checkLengthPositive(jsize length) {
+ void CheckLengthPositive(jsize length) {
if (length < 0) {
LOG(ERROR) << "JNI ERROR: negative jsize: " << length;
JniAbort();
}
}
+ Field* CheckFieldID(jfieldID fid) {
+ if (fid == NULL) {
+ LOG(ERROR) << "JNI ERROR: null jfieldID";
+ JniAbort();
+ return NULL;
+ }
+ Field* f = DecodeField(fid);
+ if (!Heap::IsHeapAddress(f)) {
+ LOG(ERROR) << "JNI ERROR: invalid jfieldID: " << fid;
+ JniAbort();
+ return NULL;
+ }
+ return f;
+ }
+
+ Method* CheckMethodID(jmethodID mid) {
+ if (mid == NULL) {
+ LOG(ERROR) << "JNI ERROR: null jmethodID";
+ JniAbort();
+ return NULL;
+ }
+ Method* m = DecodeMethod(mid);
+ if (!Heap::IsHeapAddress(m)) {
+ LOG(ERROR) << "JNI ERROR: invalid jmethodID: " << mid;
+ JniAbort();
+ return NULL;
+ }
+ return m;
+ }
+
/*
* Verify that "jobj" is a valid object, and that it's an object that JNI
* is allowed to know about. We allow NULL references.
*
* Switches to "running" mode before performing checks.
*/
- void checkObject(jobject java_object) {
+ void CheckObject(jobject java_object) {
if (java_object == NULL) {
return;
}
- ScopedJniThreadState ts(mEnv);
+ ScopedJniThreadState ts(env_);
Object* o = Decode<Object*>(ts, java_object);
if (o != NULL && !Heap::IsHeapAddress(o)) {
@@ -616,14 +657,14 @@
* Verify that the "mode" argument passed to a primitive array Release
* function is one of the valid values.
*/
- void checkReleaseMode(jint mode) {
+ void CheckReleaseMode(jint mode) {
if (mode != 0 && mode != JNI_COMMIT && mode != JNI_ABORT) {
LOG(ERROR) << "JNI ERROR: bad value for release mode: " << mode;
JniAbort();
}
}
- void checkThread(int flags) {
+ void CheckThread(int flags) {
Thread* self = Thread::Current();
if (self == NULL) {
LOG(ERROR) << "JNI ERROR: non-VM thread making JNI calls";
@@ -638,10 +679,10 @@
* Verify that the current thread is (a) attached and (b) associated with
* this particular instance of JNIEnv.
*/
- if (mEnv != threadEnv) {
- LOG(ERROR) << "JNI ERROR: thread " << *self << " using JNIEnv* from thread " << *mEnv->self;
+ if (env_ != threadEnv) {
+ LOG(ERROR) << "JNI ERROR: thread " << *self << " using JNIEnv* from thread " << *env_->self;
// If we're keeping broken code limping along, we need to suppress the abort...
- if (!mEnv->work_around_app_jni_bugs) {
+ if (!env_->work_around_app_jni_bugs) {
JniAbort();
return;
}
@@ -684,7 +725,7 @@
if ((flags & kFlag_ExcepOkay) == 0 && self->IsExceptionPending()) {
LOG(ERROR) << "JNI ERROR: JNI method called with exception pending";
LOG(ERROR) << "Pending exception is:";
- LOG(ERROR) << jniGetStackTrace(mEnv);
+ LOG(ERROR) << jniGetStackTrace(env_);
JniAbort();
return;
}
@@ -693,7 +734,7 @@
/*
* Verify that "bytes" points to valid "modified UTF-8" data.
*/
- void checkUtfString(const char* bytes, bool nullable) {
+ void CheckUtfString(const char* bytes, bool nullable) {
if (bytes == NULL) {
if (!nullable) {
LOG(ERROR) << "JNI ERROR: non-nullable const char* was NULL";
@@ -704,7 +745,7 @@
}
const char* errorKind = NULL;
- uint8_t utf8 = checkUtfBytes(bytes, &errorKind);
+ uint8_t utf8 = CheckUtfBytes(bytes, &errorKind);
if (errorKind != NULL) {
LOG(ERROR) << "JNI ERROR: input is not valid UTF-8: illegal " << errorKind << " byte " << StringPrintf("%#x", utf8);
LOG(ERROR) << " string: '" << bytes << "'";
@@ -727,7 +768,7 @@
* Because we're looking at an object on the GC heap, we have to switch
* to "running" mode before doing the checks.
*/
- void checkInstance(InstanceKind kind, jobject java_object) {
+ void CheckInstance(InstanceKind kind, jobject java_object) {
const char* what = NULL;
switch (kind) {
case kClass:
@@ -752,7 +793,7 @@
return;
}
- ScopedJniThreadState ts(mEnv);
+ ScopedJniThreadState ts(env_);
Object* obj = Decode<Object*>(ts, java_object);
if (!Heap::IsHeapAddress(obj)) {
LOG(ERROR) << "JNI ERROR: " << what << " is an invalid " << GetIndirectRefKind(java_object) << ": " << java_object;
@@ -781,7 +822,7 @@
}
}
- static uint8_t checkUtfBytes(const char* bytes, const char** errorKind) {
+ static uint8_t CheckUtfBytes(const char* bytes, const char** errorKind) {
while (*bytes != '\0') {
uint8_t utf8 = *(bytes++);
// Switch on the high four bits.
@@ -831,29 +872,29 @@
}
void JniAbort() {
- ::art::JniAbort(mFunctionName);
+ ::art::JniAbort(function_name_);
}
- JNIEnvExt* mEnv;
- JavaVMExt* mVm;
- const char* mFunctionName;
- int mFlags;
- bool mHasMethod;
- size_t mIndent;
+ JNIEnvExt* env_;
+ JavaVMExt* vm_;
+ const char* function_name_;
+ int flags_;
+ bool has_method_;
+ size_t indent_;
DISALLOW_COPY_AND_ASSIGN(ScopedCheck);
};
#define CHECK_JNI_ENTRY(flags, types, args...) \
ScopedCheck sc(env, flags, __FUNCTION__); \
- sc.check(true, types, ##args)
+ sc.Check(true, types, ##args)
#define CHECK_JNI_EXIT(type, exp) ({ \
typeof (exp) _rc = (exp); \
- sc.check(false, type, _rc); \
+ sc.Check(false, type, _rc); \
_rc; })
#define CHECK_JNI_EXIT_VOID() \
- sc.check(false, "V")
+ sc.Check(false, "V")
/*
* ===========================================================================
@@ -869,12 +910,12 @@
struct GuardedCopy {
uint32_t magic;
uLong adler;
- size_t originalLen;
- const void* originalPtr;
+ size_t original_length;
+ const void* original_ptr;
/* find the GuardedCopy given the pointer into the "live" data */
- static inline const GuardedCopy* fromData(const void* dataBuf) {
- return reinterpret_cast<const GuardedCopy*>(actualBuffer(dataBuf));
+ static inline const GuardedCopy* FromData(const void* dataBuf) {
+ return reinterpret_cast<const GuardedCopy*>(ActualBuffer(dataBuf));
}
/*
@@ -883,9 +924,9 @@
*
* We use a 16-bit pattern to make a rogue memset less likely to elude us.
*/
- static void* create(const void* buf, size_t len, bool modOkay) {
- size_t newLen = actualLength(len);
- uint8_t* newBuf = debugAlloc(newLen);
+ static void* Create(const void* buf, size_t len, bool modOkay) {
+ size_t newLen = ActualLength(len);
+ uint8_t* newBuf = DebugAlloc(newLen);
/* fill it in with a pattern */
uint16_t* pat = (uint16_t*) newBuf;
@@ -907,8 +948,8 @@
GuardedCopy* pExtra = reinterpret_cast<GuardedCopy*>(newBuf);
pExtra->magic = kGuardMagic;
pExtra->adler = adler;
- pExtra->originalPtr = buf;
- pExtra->originalLen = len;
+ pExtra->original_ptr = buf;
+ pExtra->original_length = len;
return newBuf + kGuardLen / 2;
}
@@ -916,12 +957,12 @@
/*
* Free up the guard buffer, scrub it, and return the original pointer.
*/
- static void* destroy(void* dataBuf) {
- const GuardedCopy* pExtra = GuardedCopy::fromData(dataBuf);
- void* originalPtr = (void*) pExtra->originalPtr;
- size_t len = pExtra->originalLen;
- debugFree(dataBuf, len);
- return originalPtr;
+ static void* Destroy(void* dataBuf) {
+ const GuardedCopy* pExtra = GuardedCopy::FromData(dataBuf);
+ void* original_ptr = (void*) pExtra->original_ptr;
+ size_t len = pExtra->original_length;
+ DebugFree(dataBuf, len);
+ return original_ptr;
}
/*
@@ -930,10 +971,10 @@
*
* The caller has already checked that "dataBuf" is non-NULL.
*/
- static void check(const char* functionName, const void* dataBuf, bool modOkay) {
+ static void Check(const char* functionName, const void* dataBuf, bool modOkay) {
static const uint32_t kMagicCmp = kGuardMagic;
- const uint8_t* fullBuf = actualBuffer(dataBuf);
- const GuardedCopy* pExtra = GuardedCopy::fromData(dataBuf);
+ const uint8_t* fullBuf = ActualBuffer(dataBuf);
+ const GuardedCopy* pExtra = GuardedCopy::FromData(dataBuf);
/*
* Before we do anything with "pExtra", check the magic number. We
@@ -950,7 +991,7 @@
JniAbort(functionName);
}
- size_t len = pExtra->originalLen;
+ size_t len = pExtra->original_length;
/* check bottom half of guard; skip over optional checksum storage */
const uint16_t* pat = (uint16_t*) fullBuf;
@@ -999,7 +1040,7 @@
}
private:
- static uint8_t* debugAlloc(size_t len) {
+ static uint8_t* DebugAlloc(size_t len) {
void* result = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
if (result == MAP_FAILED) {
PLOG(FATAL) << "GuardedCopy::create mmap(" << len << ") failed";
@@ -1007,9 +1048,9 @@
return reinterpret_cast<uint8_t*>(result);
}
- static void debugFree(void* dataBuf, size_t len) {
- uint8_t* fullBuf = actualBuffer(dataBuf);
- size_t totalByteCount = actualLength(len);
+ static void DebugFree(void* dataBuf, size_t len) {
+ uint8_t* fullBuf = ActualBuffer(dataBuf);
+ size_t totalByteCount = ActualLength(len);
// TODO: we could mprotect instead, and keep the allocation around for a while.
// This would be even more expensive, but it might catch more errors.
// if (mprotect(fullBuf, totalByteCount, PROT_NONE) != 0) {
@@ -1020,16 +1061,16 @@
}
}
- static const uint8_t* actualBuffer(const void* dataBuf) {
+ static const uint8_t* ActualBuffer(const void* dataBuf) {
return reinterpret_cast<const uint8_t*>(dataBuf) - kGuardLen / 2;
}
- static uint8_t* actualBuffer(void* dataBuf) {
+ static uint8_t* ActualBuffer(void* dataBuf) {
return reinterpret_cast<uint8_t*>(dataBuf) - kGuardLen / 2;
}
// Underlying length of a user allocation of 'length' bytes.
- static size_t actualLength(size_t length) {
+ static size_t ActualLength(size_t length) {
return (length + kGuardLen + 1) & ~0x01;
}
};
@@ -1043,7 +1084,7 @@
Array* a = Decode<Array*>(ts, java_array);
size_t byte_count = a->GetLength() * a->GetClass()->GetComponentSize();
- void* result = GuardedCopy::create(a->GetRawData(), byte_count, true);
+ void* result = GuardedCopy::Create(a->GetRawData(), byte_count, true);
if (isCopy != NULL) {
*isCopy = JNI_TRUE;
}
@@ -1062,14 +1103,14 @@
ScopedJniThreadState ts(env);
Array* a = Decode<Array*>(ts, java_array);
- GuardedCopy::check(__FUNCTION__, dataBuf, true);
+ GuardedCopy::Check(__FUNCTION__, dataBuf, true);
if (mode != JNI_ABORT) {
- size_t len = GuardedCopy::fromData(dataBuf)->originalLen;
+ size_t len = GuardedCopy::FromData(dataBuf)->original_length;
memcpy(a->GetRawData(), dataBuf, len);
}
if (mode != JNI_COMMIT) {
- GuardedCopy::destroy(dataBuf);
+ GuardedCopy::Destroy(dataBuf);
}
}
@@ -1088,13 +1129,13 @@
static jclass DefineClass(JNIEnv* env, const char* name, jobject loader, const jbyte* buf, jsize bufLen) {
CHECK_JNI_ENTRY(kFlag_Default, "EuLpz", env, name, loader, buf, bufLen);
- sc.checkClassName(name);
+ sc.CheckClassName(name);
return CHECK_JNI_EXIT("c", baseEnv(env)->DefineClass(env, name, loader, buf, bufLen));
}
static jclass FindClass(JNIEnv* env, const char* name) {
CHECK_JNI_ENTRY(kFlag_Default, "Eu", env, name);
- sc.checkClassName(name);
+ sc.CheckClassName(name);
return CHECK_JNI_EXIT("c", baseEnv(env)->FindClass(env, name));
}
@@ -1284,27 +1325,27 @@
#define FIELD_ACCESSORS(_ctype, _jname, _type) \
static _ctype GetStatic##_jname##Field(JNIEnv* env, jclass clazz, jfieldID fid) { \
CHECK_JNI_ENTRY(kFlag_Default, "Ecf", env, clazz, fid); \
- sc.checkStaticFieldID(clazz, fid); \
+ sc.CheckStaticFieldID(clazz, fid); \
return CHECK_JNI_EXIT(_type, baseEnv(env)->GetStatic##_jname##Field(env, clazz, fid)); \
} \
static _ctype Get##_jname##Field(JNIEnv* env, jobject obj, jfieldID fid) { \
CHECK_JNI_ENTRY(kFlag_Default, "ELf", env, obj, fid); \
- sc.checkInstanceFieldID(obj, fid); \
+ sc.CheckInstanceFieldID(obj, fid); \
return CHECK_JNI_EXIT(_type, baseEnv(env)->Get##_jname##Field(env, obj, fid)); \
} \
static void SetStatic##_jname##Field(JNIEnv* env, jclass clazz, jfieldID fid, _ctype value) { \
CHECK_JNI_ENTRY(kFlag_Default, "Ecf" _type, env, clazz, fid, value); \
- sc.checkStaticFieldID(clazz, fid); \
+ sc.CheckStaticFieldID(clazz, fid); \
/* "value" arg only used when type == ref */ \
- sc.checkFieldType((jobject)(uint32_t)value, fid, _type[0], true); \
+ sc.CheckFieldType((jobject)(uint32_t)value, fid, _type[0], true); \
baseEnv(env)->SetStatic##_jname##Field(env, clazz, fid, value); \
CHECK_JNI_EXIT_VOID(); \
} \
static void Set##_jname##Field(JNIEnv* env, jobject obj, jfieldID fid, _ctype value) { \
CHECK_JNI_ENTRY(kFlag_Default, "ELf" _type, env, obj, fid, value); \
- sc.checkInstanceFieldID(obj, fid); \
+ sc.CheckInstanceFieldID(obj, fid); \
/* "value" arg only used when type == ref */ \
- sc.checkFieldType((jobject)(uint32_t) value, fid, _type[0], false); \
+ sc.CheckFieldType((jobject)(uint32_t) value, fid, _type[0], false); \
baseEnv(env)->Set##_jname##Field(env, obj, fid, value); \
CHECK_JNI_EXIT_VOID(); \
}
@@ -1325,8 +1366,8 @@
jmethodID mid, ...) \
{ \
CHECK_JNI_ENTRY(kFlag_Default, "ELm.", env, obj, mid); /* TODO: args! */ \
- sc.checkSig(mid, _retsig, false); \
- sc.checkVirtualMethod(obj, mid); \
+ sc.CheckSig(mid, _retsig, false); \
+ sc.CheckVirtualMethod(obj, mid); \
_retdecl; \
va_list args; \
va_start(args, mid); \
@@ -1338,8 +1379,8 @@
jmethodID mid, va_list args) \
{ \
CHECK_JNI_ENTRY(kFlag_Default, "ELm.", env, obj, mid); /* TODO: args! */ \
- sc.checkSig(mid, _retsig, false); \
- sc.checkVirtualMethod(obj, mid); \
+ sc.CheckSig(mid, _retsig, false); \
+ sc.CheckVirtualMethod(obj, mid); \
_retdecl; \
_retasgn baseEnv(env)->Call##_jname##MethodV(env, obj, mid, args); \
_retok; \
@@ -1348,8 +1389,8 @@
jmethodID mid, jvalue* args) \
{ \
CHECK_JNI_ENTRY(kFlag_Default, "ELm.", env, obj, mid); /* TODO: args! */ \
- sc.checkSig(mid, _retsig, false); \
- sc.checkVirtualMethod(obj, mid); \
+ sc.CheckSig(mid, _retsig, false); \
+ sc.CheckVirtualMethod(obj, mid); \
_retdecl; \
_retasgn baseEnv(env)->Call##_jname##MethodA(env, obj, mid, args); \
_retok; \
@@ -1359,8 +1400,8 @@
jobject obj, jclass clazz, jmethodID mid, ...) \
{ \
CHECK_JNI_ENTRY(kFlag_Default, "ELcm.", env, obj, clazz, mid); /* TODO: args! */ \
- sc.checkSig(mid, _retsig, false); \
- sc.checkVirtualMethod(obj, mid); \
+ sc.CheckSig(mid, _retsig, false); \
+ sc.CheckVirtualMethod(obj, mid); \
_retdecl; \
va_list args; \
va_start(args, mid); \
@@ -1372,8 +1413,8 @@
jobject obj, jclass clazz, jmethodID mid, va_list args) \
{ \
CHECK_JNI_ENTRY(kFlag_Default, "ELcm.", env, obj, clazz, mid); /* TODO: args! */ \
- sc.checkSig(mid, _retsig, false); \
- sc.checkVirtualMethod(obj, mid); \
+ sc.CheckSig(mid, _retsig, false); \
+ sc.CheckVirtualMethod(obj, mid); \
_retdecl; \
_retasgn baseEnv(env)->CallNonvirtual##_jname##MethodV(env, obj, clazz, mid, args); \
_retok; \
@@ -1382,8 +1423,8 @@
jobject obj, jclass clazz, jmethodID mid, jvalue* args) \
{ \
CHECK_JNI_ENTRY(kFlag_Default, "ELcm.", env, obj, clazz, mid); /* TODO: args! */ \
- sc.checkSig(mid, _retsig, false); \
- sc.checkVirtualMethod(obj, mid); \
+ sc.CheckSig(mid, _retsig, false); \
+ sc.CheckVirtualMethod(obj, mid); \
_retdecl; \
_retasgn baseEnv(env)->CallNonvirtual##_jname##MethodA(env, obj, clazz, mid, args); \
_retok; \
@@ -1393,8 +1434,8 @@
jclass clazz, jmethodID mid, ...) \
{ \
CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, clazz, mid); /* TODO: args! */ \
- sc.checkSig(mid, _retsig, true); \
- sc.checkStaticMethod(clazz, mid); \
+ sc.CheckSig(mid, _retsig, true); \
+ sc.CheckStaticMethod(clazz, mid); \
_retdecl; \
va_list args; \
va_start(args, mid); \
@@ -1406,8 +1447,8 @@
jclass clazz, jmethodID mid, va_list args) \
{ \
CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, clazz, mid); /* TODO: args! */ \
- sc.checkSig(mid, _retsig, true); \
- sc.checkStaticMethod(clazz, mid); \
+ sc.CheckSig(mid, _retsig, true); \
+ sc.CheckStaticMethod(clazz, mid); \
_retdecl; \
_retasgn baseEnv(env)->CallStatic##_jname##MethodV(env, clazz, mid, args); \
_retok; \
@@ -1416,8 +1457,8 @@
jclass clazz, jmethodID mid, jvalue* args) \
{ \
CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, clazz, mid); /* TODO: args! */ \
- sc.checkSig(mid, _retsig, true); \
- sc.checkStaticMethod(clazz, mid); \
+ sc.CheckSig(mid, _retsig, true); \
+ sc.CheckStaticMethod(clazz, mid); \
_retdecl; \
_retasgn baseEnv(env)->CallStatic##_jname##MethodA(env, clazz, mid, args); \
_retok; \
@@ -1450,11 +1491,11 @@
static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* isCopy) {
CHECK_JNI_ENTRY(kFlag_CritOkay, "Esp", env, java_string, isCopy);
const jchar* result = baseEnv(env)->GetStringChars(env, java_string, isCopy);
- if (sc.forceCopy() && result != NULL) {
+ if (sc.ForceCopy() && result != NULL) {
ScopedJniThreadState ts(env);
String* s = Decode<String*>(ts, java_string);
int byteCount = s->GetLength() * 2;
- result = (const jchar*) GuardedCopy::create(result, byteCount, false);
+ result = (const jchar*) GuardedCopy::Create(result, byteCount, false);
if (isCopy != NULL) {
*isCopy = JNI_TRUE;
}
@@ -1464,10 +1505,10 @@
static void ReleaseStringChars(JNIEnv* env, jstring string, const jchar* chars) {
CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "Esp", env, string, chars);
- sc.checkNonNull(chars);
- if (sc.forceCopy()) {
- GuardedCopy::check(__FUNCTION__, chars, false);
- chars = (const jchar*) GuardedCopy::destroy((jchar*)chars);
+ sc.CheckNonNull(chars);
+ if (sc.ForceCopy()) {
+ GuardedCopy::Check(__FUNCTION__, chars, false);
+ chars = (const jchar*) GuardedCopy::Destroy((jchar*)chars);
}
baseEnv(env)->ReleaseStringChars(env, string, chars);
CHECK_JNI_EXIT_VOID();
@@ -1486,8 +1527,8 @@
static const char* GetStringUTFChars(JNIEnv* env, jstring string, jboolean* isCopy) {
CHECK_JNI_ENTRY(kFlag_CritOkay, "Esp", env, string, isCopy);
const char* result = baseEnv(env)->GetStringUTFChars(env, string, isCopy);
- if (sc.forceCopy() && result != NULL) {
- result = (const char*) GuardedCopy::create(result, strlen(result) + 1, false);
+ if (sc.ForceCopy() && result != NULL) {
+ result = (const char*) GuardedCopy::Create(result, strlen(result) + 1, false);
if (isCopy != NULL) {
*isCopy = JNI_TRUE;
}
@@ -1497,9 +1538,9 @@
static void ReleaseStringUTFChars(JNIEnv* env, jstring string, const char* utf) {
CHECK_JNI_ENTRY(kFlag_ExcepOkay | kFlag_Release, "Esu", env, string, utf); // TODO: show pointer and truncate string.
- if (sc.forceCopy()) {
- GuardedCopy::check(__FUNCTION__, utf, false);
- utf = (const char*) GuardedCopy::destroy((char*)utf);
+ if (sc.ForceCopy()) {
+ GuardedCopy::Check(__FUNCTION__, utf, false);
+ utf = (const char*) GuardedCopy::Destroy((char*)utf);
}
baseEnv(env)->ReleaseStringUTFChars(env, string, utf);
CHECK_JNI_EXIT_VOID();
@@ -1540,43 +1581,43 @@
NEW_PRIMITIVE_ARRAY(jfloatArray, Float);
NEW_PRIMITIVE_ARRAY(jdoubleArray, Double);
-class ForceCopyGetChecker {
+struct ForceCopyGetChecker {
public:
ForceCopyGetChecker(ScopedCheck& sc, jboolean* isCopy) {
- forceCopy = sc.forceCopy();
- noCopy = 0;
- if (forceCopy && isCopy != NULL) {
+ force_copy = sc.ForceCopy();
+ no_copy = 0;
+ if (force_copy && isCopy != NULL) {
/* capture this before the base call tramples on it */
- noCopy = *(uint32_t*) isCopy;
+ no_copy = *(uint32_t*) isCopy;
}
}
template<typename ResultT>
- ResultT check(JNIEnv* env, jarray array, jboolean* isCopy, ResultT result) {
- if (forceCopy && result != NULL) {
- if (noCopy != kNoCopyMagic) {
+ ResultT Check(JNIEnv* env, jarray array, jboolean* isCopy, ResultT result) {
+ if (force_copy && result != NULL) {
+ if (no_copy != kNoCopyMagic) {
result = reinterpret_cast<ResultT>(CreateGuardedPACopy(env, array, isCopy));
}
}
return result;
}
- uint32_t noCopy;
- bool forceCopy;
+ uint32_t no_copy;
+ bool force_copy;
};
#define GET_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname) \
static _ctype* Get##_jname##ArrayElements(JNIEnv* env, _ctype##Array array, jboolean* isCopy) { \
CHECK_JNI_ENTRY(kFlag_Default, "Eap", env, array, isCopy); \
- _ctype* result = ForceCopyGetChecker(sc, isCopy).check(env, array, isCopy, baseEnv(env)->Get##_jname##ArrayElements(env, array, isCopy)); \
+ _ctype* result = ForceCopyGetChecker(sc, isCopy).Check(env, array, isCopy, baseEnv(env)->Get##_jname##ArrayElements(env, array, isCopy)); \
return CHECK_JNI_EXIT("p", result); \
}
#define RELEASE_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname) \
static void Release##_jname##ArrayElements(JNIEnv* env, _ctype##Array array, _ctype* elems, jint mode) { \
CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "Eapr", env, array, elems, mode); \
- sc.checkNonNull(elems); \
- if (sc.forceCopy()) { \
+ sc.CheckNonNull(elems); \
+ if (sc.ForceCopy()) { \
ReleaseGuardedPACopy(env, array, elems, mode); \
} \
baseEnv(env)->Release##_jname##ArrayElements(env, array, elems, mode); \
@@ -1653,7 +1694,7 @@
static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray array, jboolean* isCopy) {
CHECK_JNI_ENTRY(kFlag_CritGet, "Eap", env, array, isCopy);
void* result = baseEnv(env)->GetPrimitiveArrayCritical(env, array, isCopy);
- if (sc.forceCopy() && result != NULL) {
+ if (sc.ForceCopy() && result != NULL) {
result = CreateGuardedPACopy(env, array, isCopy);
}
return CHECK_JNI_EXIT("p", result);
@@ -1661,8 +1702,8 @@
static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray array, void* carray, jint mode) {
CHECK_JNI_ENTRY(kFlag_CritRelease | kFlag_ExcepOkay, "Eapr", env, array, carray, mode);
- sc.checkNonNull(carray);
- if (sc.forceCopy()) {
+ sc.CheckNonNull(carray);
+ if (sc.ForceCopy()) {
ReleaseGuardedPACopy(env, array, carray, mode);
}
baseEnv(env)->ReleasePrimitiveArrayCritical(env, array, carray, mode);
@@ -1672,11 +1713,11 @@
static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* isCopy) {
CHECK_JNI_ENTRY(kFlag_CritGet, "Esp", env, java_string, isCopy);
const jchar* result = baseEnv(env)->GetStringCritical(env, java_string, isCopy);
- if (sc.forceCopy() && result != NULL) {
+ if (sc.ForceCopy() && result != NULL) {
ScopedJniThreadState ts(env);
String* s = Decode<String*>(ts, java_string);
int byteCount = s->GetLength() * 2;
- result = (const jchar*) GuardedCopy::create(result, byteCount, false);
+ result = (const jchar*) GuardedCopy::Create(result, byteCount, false);
if (isCopy != NULL) {
*isCopy = JNI_TRUE;
}
@@ -1686,10 +1727,10 @@
static void ReleaseStringCritical(JNIEnv* env, jstring string, const jchar* carray) {
CHECK_JNI_ENTRY(kFlag_CritRelease | kFlag_ExcepOkay, "Esp", env, string, carray);
- sc.checkNonNull(carray);
- if (sc.forceCopy()) {
- GuardedCopy::check(__FUNCTION__, carray, false);
- carray = (const jchar*) GuardedCopy::destroy((jchar*)carray);
+ sc.CheckNonNull(carray);
+ if (sc.ForceCopy()) {
+ GuardedCopy::Check(__FUNCTION__, carray, false);
+ carray = (const jchar*) GuardedCopy::Destroy((jchar*)carray);
}
baseEnv(env)->ReleaseStringCritical(env, string, carray);
CHECK_JNI_EXIT_VOID();
@@ -1988,36 +2029,36 @@
public:
static jint DestroyJavaVM(JavaVM* vm) {
ScopedCheck sc(vm, false, __FUNCTION__);
- sc.check(true, "v", vm);
- return CHECK_JNI_EXIT("I", baseVm(vm)->DestroyJavaVM(vm));
+ sc.Check(true, "v", vm);
+ return CHECK_JNI_EXIT("I", BaseVm(vm)->DestroyJavaVM(vm));
}
static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
ScopedCheck sc(vm, false, __FUNCTION__);
- sc.check(true, "vpp", vm, p_env, thr_args);
- return CHECK_JNI_EXIT("I", baseVm(vm)->AttachCurrentThread(vm, p_env, thr_args));
+ sc.Check(true, "vpp", vm, p_env, thr_args);
+ return CHECK_JNI_EXIT("I", BaseVm(vm)->AttachCurrentThread(vm, p_env, thr_args));
}
static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
ScopedCheck sc(vm, false, __FUNCTION__);
- sc.check(true, "vpp", vm, p_env, thr_args);
- return CHECK_JNI_EXIT("I", baseVm(vm)->AttachCurrentThreadAsDaemon(vm, p_env, thr_args));
+ sc.Check(true, "vpp", vm, p_env, thr_args);
+ return CHECK_JNI_EXIT("I", BaseVm(vm)->AttachCurrentThreadAsDaemon(vm, p_env, thr_args));
}
static jint DetachCurrentThread(JavaVM* vm) {
ScopedCheck sc(vm, true, __FUNCTION__);
- sc.check(true, "v", vm);
- return CHECK_JNI_EXIT("I", baseVm(vm)->DetachCurrentThread(vm));
+ sc.Check(true, "v", vm);
+ return CHECK_JNI_EXIT("I", BaseVm(vm)->DetachCurrentThread(vm));
}
static jint GetEnv(JavaVM* vm, void** env, jint version) {
ScopedCheck sc(vm, true, __FUNCTION__);
- sc.check(true, "v", vm);
- return CHECK_JNI_EXIT("I", baseVm(vm)->GetEnv(vm, env, version));
+ sc.Check(true, "v", vm);
+ return CHECK_JNI_EXIT("I", BaseVm(vm)->GetEnv(vm, env, version));
}
private:
- static inline const JNIInvokeInterface* baseVm(JavaVM* vm) {
+ static inline const JNIInvokeInterface* BaseVm(JavaVM* vm) {
return reinterpret_cast<JavaVMExt*>(vm)->unchecked_functions;
}
};
diff --git a/src/dex_verifier.cc b/src/dex_verifier.cc
index 329508f..2268772 100644
--- a/src/dex_verifier.cc
+++ b/src/dex_verifier.cc
@@ -105,16 +105,14 @@
for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
Method* method = klass->GetDirectMethod(i);
if (!VerifyMethod(method)) {
- LOG(ERROR) << "Verifier rejected class "
- << klass->GetDescriptor()->ToModifiedUtf8();
+ LOG(ERROR) << "Verifier rejected class " << PrettyClass(klass);
return false;
}
}
for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
Method* method = klass->GetVirtualMethod(i);
if (!VerifyMethod(method)) {
- LOG(ERROR) << "Verifier rejected class "
- << klass->GetDescriptor()->ToModifiedUtf8();
+ LOG(ERROR) << "Verifier rejected class " << PrettyClass(klass);
return false;
}
}
@@ -336,10 +334,7 @@
/* Initialize register types of method arguments. */
if (!SetTypesFromSignature(vdata, reg_table.register_lines_[0].reg_types_.get())) {
- LOG(ERROR) << "VFY: bad signature '"
- << method->GetSignature()->ToModifiedUtf8() << "' for "
- << method->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
- << "." << method->GetName()->ToModifiedUtf8();
+ LOG(ERROR) << "VFY: bad signature in " << PrettyMethod(method);
return false;
}
@@ -1298,21 +1293,13 @@
RegisterLine* register_line = GetRegisterLine(reg_table, insn_idx);
if (register_line->reg_types_.get() != NULL && CompareLineToTable(reg_table,
insn_idx, ®_table->work_line_) != 0) {
- Class* klass = method->GetDeclaringClass();
- LOG(ERROR) << "HUH? work_line diverged in "
- << klass->GetDescriptor()->ToModifiedUtf8() << "."
- << method->GetName()->ToModifiedUtf8() << " "
- << method->GetSignature()->ToModifiedUtf8();
+ LOG(ERROR) << "HUH? work_line diverged in " << PrettyMethod(method);
}
#endif
}
if (!CodeFlowVerifyInstruction(vdata, reg_table, insn_idx, &start_guess)) {
- Class* klass = method->GetDeclaringClass();
- LOG(ERROR) << "VFY: failure to verify "
- << klass->GetDescriptor()->ToModifiedUtf8() << "."
- << method->GetName()->ToModifiedUtf8() << " "
- << method->GetSignature()->ToModifiedUtf8();
+ LOG(ERROR) << "VFY: failure to verify " << PrettyMethod(method);
return false;
}
@@ -1351,22 +1338,14 @@
if (dead_start < 0)
dead_start = insn_idx;
} else if (dead_start >= 0) {
- Class* klass = method->GetDeclaringClass();
LOG(INFO) << "VFY: dead code 0x" << std::hex << dead_start << "-"
- << insn_idx - 1 << std::dec << " in "
- << klass->GetDescriptor()->ToModifiedUtf8() << "."
- << method->GetName()->ToModifiedUtf8() << " "
- << method->GetSignature()->ToModifiedUtf8();
+ << insn_idx - 1 << std::dec << " in " << PrettyMethod(method);
dead_start = -1;
}
}
if (dead_start >= 0) {
- Class* klass = method->GetDeclaringClass();
LOG(INFO) << "VFY: dead code 0x" << std::hex << dead_start << "-"
- << insn_idx - 1 << std::dec << " in "
- << klass->GetDescriptor()->ToModifiedUtf8() << "."
- << method->GetName()->ToModifiedUtf8() << " "
- << method->GetSignature()->ToModifiedUtf8();
+ << insn_idx - 1 << std::dec << " in " << PrettyMethod(method);
}
}
@@ -1381,8 +1360,6 @@
InsnFlags* insn_flags = vdata->insn_flags_.get();
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
UninitInstanceMap* uninit_map = vdata->uninit_map_.get();
- const ClassLoader* class_loader =
- method->GetDeclaringClass()->GetClassLoader();
const uint16_t* insns = code_item->insns_ + insn_idx;
uint32_t insns_size = code_item->insns_size_;
uint32_t registers_size = code_item->registers_size_;
@@ -1651,12 +1628,11 @@
LOG(ERROR) << "VFY: unable to resolve const-class " << dec_insn.vB_
<< " (" << bad_class_desc << ") in "
<< klass->GetDescriptor()->ToModifiedUtf8();
- if (failure != VERIFY_ERROR_NONE) {
- break;
- }
+ DCHECK(failure != VERIFY_ERROR_GENERIC);
+ } else {
+ SetRegisterType(work_line, dec_insn.vA_, RegTypeFromClass(
+ class_linker->FindSystemClass("Ljava/lang/Class;")));
}
- SetRegisterType(work_line, dec_insn.vA_, RegTypeFromClass(
- class_linker->FindSystemClass("Ljava/lang/Class;")));
break;
case Instruction::MONITOR_ENTER:
@@ -1703,21 +1679,16 @@
LOG(ERROR) << "VFY: unable to resolve check-cast " << dec_insn.vB_
<< " (" << bad_class_desc << ") in "
<< klass->GetDescriptor()->ToModifiedUtf8();
- if (failure != VERIFY_ERROR_NONE) {
+ DCHECK(failure != VERIFY_ERROR_GENERIC);
+ } else {
+ RegType orig_type = GetRegisterType(work_line, dec_insn.vA_);
+ if (!RegTypeIsReference(orig_type)) {
+ LOG(ERROR) << "VFY: check-cast on non-reference in v" << dec_insn.vA_;
+ failure = VERIFY_ERROR_GENERIC;
break;
}
- /* if the class is unresolvable, treat it as an object */
- res_class = class_linker->FindClass("Ljava/lang/Object;", class_loader);
+ SetRegisterType(work_line, dec_insn.vA_, RegTypeFromClass(res_class));
}
- RegType orig_type;
-
- orig_type = GetRegisterType(work_line, dec_insn.vA_);
- if (!RegTypeIsReference(orig_type)) {
- LOG(ERROR) << "VFY: check-cast on non-reference in v" << dec_insn.vA_;
- failure = VERIFY_ERROR_GENERIC;
- break;
- }
- SetRegisterType(work_line, dec_insn.vA_, RegTypeFromClass(res_class));
break;
case Instruction::INSTANCE_OF:
/* make sure we're checking a reference type */
@@ -1735,12 +1706,11 @@
LOG(ERROR) << "VFY: unable to resolve instanceof " << dec_insn.vC_
<< " (" << bad_class_desc << ") in "
<< klass->GetDescriptor()->ToModifiedUtf8();
- if (failure != VERIFY_ERROR_NONE) {
- break;
- }
+ DCHECK(failure != VERIFY_ERROR_GENERIC);
+ } else {
+ /* result is boolean */
+ SetRegisterType(work_line, dec_insn.vA_, kRegTypeBoolean);
}
- /* result is boolean */
- SetRegisterType(work_line, dec_insn.vA_, kRegTypeBoolean);
break;
case Instruction::ARRAY_LENGTH:
@@ -1756,19 +1726,14 @@
break;
case Instruction::NEW_INSTANCE:
- {
- res_class = ResolveClassAndCheckAccess(dex_file, dec_insn.vB_, klass, &failure);
- if (res_class == NULL) {
- const char* bad_class_desc = dex_file->dexStringByTypeIdx(dec_insn.vB_);
- LOG(ERROR) << "VFY: unable to resolve new-instance " << dec_insn.vB_
- << " (" << bad_class_desc << ") in "
- << klass->GetDescriptor()->ToModifiedUtf8();
- if (failure != VERIFY_ERROR_NONE) {
- break;
- }
- /* if the class is unresolvable, treat it as an object */
- res_class = class_linker->FindClass("Ljava/lang/Object;", class_loader);
- }
+ res_class = ResolveClassAndCheckAccess(dex_file, dec_insn.vB_, klass, &failure);
+ if (res_class == NULL) {
+ const char* bad_class_desc = dex_file->dexStringByTypeIdx(dec_insn.vB_);
+ LOG(ERROR) << "VFY: unable to resolve new-instance " << dec_insn.vB_
+ << " (" << bad_class_desc << ") in "
+ << klass->GetDescriptor()->ToModifiedUtf8();
+ DCHECK(failure != VERIFY_ERROR_GENERIC);
+ } else {
RegType uninit_type;
/* can't create an instance of an interface or abstract class */
@@ -1793,8 +1758,8 @@
/* add the new uninitialized reference to the register ste */
SetRegisterType(work_line, dec_insn.vA_, uninit_type);
- break;
}
+ break;
case Instruction::NEW_ARRAY:
res_class = ResolveClassAndCheckAccess(dex_file, dec_insn.vC_, klass, &failure);
if (res_class == NULL) {
@@ -1802,13 +1767,8 @@
LOG(ERROR) << "VFY: unable to resolve new-array " << dec_insn.vC_
<< " (" << bad_class_desc << ") in "
<< klass->GetDescriptor()->ToModifiedUtf8();
- if (failure != VERIFY_ERROR_NONE) {
- break;
- }
- /* if the class is unresolvable, treat it as an object array */
- res_class = class_linker->FindClass("[Ljava/lang/Object;", class_loader);
- }
- if (!res_class->IsArrayClass()) {
+ DCHECK(failure != VERIFY_ERROR_GENERIC);
+ } else if (!res_class->IsArrayClass()) {
LOG(ERROR) << "VFY: new-array on non-array class";
failure = VERIFY_ERROR_GENERIC;
} else {
@@ -1826,13 +1786,8 @@
LOG(ERROR) << "VFY: unable to resolve filled-array " << dec_insn.vB_
<< " (" << bad_class_desc << ") in "
<< klass->GetDescriptor()->ToModifiedUtf8();
- if (failure != VERIFY_ERROR_NONE) {
- break;
- }
- /* if the class is unresolvable, treat it as an object array */
- res_class = class_linker->FindClass("[Ljava/lang/Object;", class_loader);
- }
- if (!res_class->IsArrayClass()) {
+ DCHECK(failure != VERIFY_ERROR_GENERIC);
+ } else if (!res_class->IsArrayClass()) {
LOG(ERROR) << "VFY: filled-new-array on non-array class";
failure = VERIFY_ERROR_GENERIC;
} else {
@@ -2363,18 +2318,14 @@
break;
/* make sure the field's type is compatible with expectation */
- field_type =
- PrimitiveTypeToRegType(inst_field->GetType()->GetPrimitiveType());
+ field_type = PrimitiveTypeToRegType(inst_field->GetType()->GetPrimitiveType());
/* correct if float */
if (field_type == kRegTypeFloat)
tmp_type = kRegTypeFloat;
if (field_type == kRegTypeUnknown || tmp_type != field_type) {
- Class* inst_field_class = inst_field->GetDeclaringClass();
- LOG(ERROR) << "VFY: invalid iget-1nr of "
- << inst_field_class->GetDescriptor()->ToModifiedUtf8()
- << "." << inst_field->GetName()->ToModifiedUtf8()
+ LOG(ERROR) << "VFY: invalid iget-1nr of " << PrettyField(inst_field)
<< " (inst=" << tmp_type << " field=" << field_type << ")";
failure = VERIFY_ERROR_GENERIC;
break;
@@ -2385,34 +2336,26 @@
break;
case Instruction::IGET_WIDE:
{
- RegType dst_type;
Field* inst_field;
RegType obj_type;
obj_type = GetRegisterType(work_line, dec_insn.vB_);
inst_field = GetInstField(vdata, obj_type, dec_insn.vC_, &failure);
- Class* inst_field_class = inst_field->GetDeclaringClass();
if (failure != VERIFY_ERROR_NONE)
break;
/* check the type, which should be prim */
switch (inst_field->GetType()->GetPrimitiveType()) {
case Class::kPrimDouble:
- dst_type = kRegTypeDoubleLo;
+ SetRegisterType(work_line, dec_insn.vA_, kRegTypeDoubleLo);
break;
case Class::kPrimLong:
- dst_type = kRegTypeLongLo;
+ SetRegisterType(work_line, dec_insn.vA_, kRegTypeLongLo);
break;
default:
- LOG(ERROR) << "VFY: invalid iget-wide of "
- << inst_field_class->GetDescriptor()->ToModifiedUtf8()
- << "." << inst_field->GetName()->ToModifiedUtf8();
- dst_type = kRegTypeUnknown;
+ LOG(ERROR) << "VFY: invalid iget-wide of " << PrettyField(inst_field);
failure = VERIFY_ERROR_GENERIC;
break;
}
- if (failure == VERIFY_ERROR_NONE) {
- SetRegisterType(work_line, dec_insn.vA_, dst_type);
- }
}
break;
case Instruction::IGET_OBJECT:
@@ -2433,11 +2376,8 @@
failure = VERIFY_ERROR_GENERIC;
break;
}
- if (failure == VERIFY_ERROR_NONE) {
- DCHECK(!field_class->IsPrimitive()) << PrettyClass(field_class);
- SetRegisterType(work_line, dec_insn.vA_,
- RegTypeFromClass(field_class));
- }
+ DCHECK(!field_class->IsPrimitive()) << PrettyClass(field_class);
+ SetRegisterType(work_line, dec_insn.vA_, RegTypeFromClass(field_class));
}
break;
case Instruction::IPUT:
@@ -2469,8 +2409,7 @@
break;
/* get type of field we're storing into */
- field_type =
- PrimitiveTypeToRegType(inst_field->GetType()->GetPrimitiveType());
+ field_type = PrimitiveTypeToRegType(inst_field->GetType()->GetPrimitiveType());
src_type = GetRegisterType(work_line, dec_insn.vA_);
/* correct if float */
@@ -2498,10 +2437,7 @@
if (failure != VERIFY_ERROR_NONE || field_type == kRegTypeUnknown ||
tmp_type != field_type) {
- Class* inst_field_class = inst_field->GetDeclaringClass();
- LOG(ERROR) << "VFY: invalid iput-1nr of "
- << inst_field_class->GetDescriptor()->ToModifiedUtf8()
- << "." << inst_field->GetName()->ToModifiedUtf8()
+ LOG(ERROR) << "VFY: invalid iput-1nr of " << PrettyField(inst_field)
<< " (inst=" << tmp_type << " field=" << field_type << ")";
failure = VERIFY_ERROR_GENERIC;
break;
@@ -2509,34 +2445,34 @@
}
break;
case Instruction::IPUT_WIDE:
- Field* inst_field;
- RegType obj_type;
+ {
+ Field* inst_field;
+ RegType obj_type;
- obj_type = GetRegisterType(work_line, dec_insn.vB_);
- inst_field = GetInstField(vdata, obj_type, dec_insn.vC_, &failure);
- if (failure != VERIFY_ERROR_NONE)
- break;
- CheckFinalFieldAccess(method, inst_field, &failure);
- if (failure != VERIFY_ERROR_NONE)
- break;
+ obj_type = GetRegisterType(work_line, dec_insn.vB_);
+ inst_field = GetInstField(vdata, obj_type, dec_insn.vC_, &failure);
+ if (failure != VERIFY_ERROR_NONE)
+ break;
+ CheckFinalFieldAccess(method, inst_field, &failure);
+ if (failure != VERIFY_ERROR_NONE)
+ break;
- /* check the type, which should be prim */
- switch (inst_field->GetType()->GetPrimitiveType()) {
- case Class::kPrimDouble:
- VerifyRegisterType(work_line, dec_insn.vA_, kRegTypeDoubleLo,
- &failure);
- break;
- case Class::kPrimLong:
- VerifyRegisterType(work_line, dec_insn.vA_, kRegTypeLongLo, &failure);
- break;
- default:
- LOG(ERROR) << "VFY: invalid iput-wide of "
- << inst_field->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
- << "." << inst_field->GetName()->ToModifiedUtf8();
- failure = VERIFY_ERROR_GENERIC;
- break;
+ /* check the type, which should be prim */
+ switch (inst_field->GetType()->GetPrimitiveType()) {
+ case Class::kPrimDouble:
+ VerifyRegisterType(work_line, dec_insn.vA_, kRegTypeDoubleLo,
+ &failure);
+ break;
+ case Class::kPrimLong:
+ VerifyRegisterType(work_line, dec_insn.vA_, kRegTypeLongLo, &failure);
+ break;
+ default:
+ LOG(ERROR) << "VFY: invalid iput-wide of " << PrettyField(inst_field);
+ failure = VERIFY_ERROR_GENERIC;
+ break;
}
- break;
+ break;
+ }
case Instruction::IPUT_OBJECT:
{
Class* field_class;
@@ -2581,14 +2517,11 @@
/* allow if field is any interface or field is base class */
if (!field_class->IsInterface() &&
!field_class->IsAssignableFrom(value_class)) {
- Class* inst_field_class = inst_field->GetDeclaringClass();
LOG(ERROR) << "VFY: storing type '"
<< value_class->GetDescriptor()->ToModifiedUtf8()
<< "' into field type '"
<< field_class->GetDescriptor()->ToModifiedUtf8()
- << "' ("
- << inst_field_class->GetDescriptor()->ToModifiedUtf8()
- << "." << inst_field->GetName()->ToModifiedUtf8() << ")";
+ << "' (" << PrettyField(inst_field) << ")";
failure = VERIFY_ERROR_GENERIC;
break;
}
@@ -2635,10 +2568,7 @@
tmp_type = kRegTypeFloat;
if (tmp_type != field_type) {
- Class* static_field_class = static_field->GetDeclaringClass();
- LOG(ERROR) << "VFY: invalid sget-1nr of "
- << static_field_class->GetDescriptor()->ToModifiedUtf8()
- << "." << static_field->GetName()->ToModifiedUtf8()
+ LOG(ERROR) << "VFY: invalid sget-1nr of " << PrettyField(static_field)
<< " (inst=" << tmp_type << " actual=" << field_type
<< ")";
failure = VERIFY_ERROR_GENERIC;
@@ -2650,43 +2580,30 @@
break;
case Instruction::SGET_WIDE:
{
- Field* static_field;
- RegType dst_type;
-
- static_field = GetStaticField(vdata, dec_insn.vB_, &failure);
- Class* static_field_class = static_field->GetDeclaringClass();
+ Field* static_field = GetStaticField(vdata, dec_insn.vB_, &failure);
if (failure != VERIFY_ERROR_NONE)
break;
/* check the type, which should be prim */
switch (static_field->GetType()->GetPrimitiveType()) {
case Class::kPrimDouble:
- dst_type = kRegTypeDoubleLo;
+ SetRegisterType(work_line, dec_insn.vA_, kRegTypeDoubleLo);
break;
case Class::kPrimLong:
- dst_type = kRegTypeLongLo;
+ SetRegisterType(work_line, dec_insn.vA_, kRegTypeLongLo);
break;
default:
- LOG(ERROR) << "VFY: invalid sget-wide of "
- << static_field_class->GetDescriptor()->ToModifiedUtf8()
- << "." << static_field->GetName()->ToModifiedUtf8();
- dst_type = kRegTypeUnknown;
+ LOG(ERROR) << "VFY: invalid sget-wide of " << PrettyField(static_field);
failure = VERIFY_ERROR_GENERIC;
break;
}
- if (failure == VERIFY_ERROR_NONE) {
- SetRegisterType(work_line, dec_insn.vA_, dst_type);
- }
}
break;
case Instruction::SGET_OBJECT:
{
- Field* static_field;
- Class* field_class;
-
- static_field = GetStaticField(vdata, dec_insn.vB_, &failure);
+ Field* static_field = GetStaticField(vdata, dec_insn.vB_, &failure);
if (failure != VERIFY_ERROR_NONE)
break;
- field_class = static_field->GetType();
+ Class* field_class = static_field->GetType();
if (field_class == NULL) {
LOG(ERROR) << "VFY: unable to recover field class from '"
<< static_field->GetName()->ToModifiedUtf8() << "'";
@@ -2764,10 +2681,7 @@
if (failure != VERIFY_ERROR_NONE || field_type == kRegTypeUnknown ||
tmp_type != field_type) {
- Class* static_field_class = static_field->GetDeclaringClass();
- LOG(ERROR) << "VFY: invalid sput-1nr of "
- << static_field_class->GetDescriptor()->ToModifiedUtf8()
- << "." << static_field->GetName()->ToModifiedUtf8()
+ LOG(ERROR) << "VFY: invalid sput-1nr of " << PrettyField(static_field)
<< " (inst=" << tmp_type << " actual=" << field_type
<< ")";
failure = VERIFY_ERROR_GENERIC;
@@ -2795,9 +2709,7 @@
VerifyRegisterType(work_line, dec_insn.vA_, kRegTypeLongLo, &failure);
break;
default:
- LOG(ERROR) << "VFY: invalid sput-wide of "
- << static_field->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
- << "." << static_field->GetName()->ToModifiedUtf8();
+ LOG(ERROR) << "VFY: invalid sput-wide of " << PrettyField(static_field);
failure = VERIFY_ERROR_GENERIC;
break;
}
@@ -2844,15 +2756,11 @@
/* allow if field is any interface or field is base class */
if (!field_class->IsInterface() &&
!field_class->IsAssignableFrom(value_class)) {
- Class* static_field_class = static_field->GetDeclaringClass();
LOG(ERROR) << "VFY: storing type '"
<< value_class->GetDescriptor()->ToModifiedUtf8()
<< "' into field type '"
<< field_class->GetDescriptor()->ToModifiedUtf8()
- << "' ("
- << static_field_class->GetDescriptor()->ToModifiedUtf8()
- << "." << static_field->GetName()->ToModifiedUtf8()
- << ")",
+ << "' (" << PrettyField(static_field) << ")";
failure = VERIFY_ERROR_GENERIC;
break;
}
@@ -2957,7 +2865,7 @@
this_type, &failure);
if (failure != VERIFY_ERROR_NONE)
break;
- }
+ }
return_type = GetMethodReturnType(dex_file, called_method);
SetResultRegisterType(work_line, registers_size, return_type);
just_set_result = true;
@@ -3803,8 +3711,7 @@
method->GetDeclaringClass(), failure, false);
if (field == NULL) {
LOG(ERROR) << "VFY: unable to resolve instance field " << field_idx;
- *failure = VERIFY_ERROR_GENERIC;
- return field;
+ return NULL;
}
if (obj_type == kRegTypeZero)
@@ -3827,10 +3734,9 @@
}
if (!field->GetDeclaringClass()->IsAssignableFrom(obj_class)) {
- LOG(ERROR) << "VFY: invalid field access (field "
- << field->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
- << "." << field->GetName()->ToModifiedUtf8() << ", through "
- << obj_class->GetDescriptor()->ToModifiedUtf8() << " ref)";
+ LOG(ERROR) << "VFY: invalid field access (field " << PrettyField(field)
+ << ", through " << obj_class->GetDescriptor()->ToModifiedUtf8()
+ << " ref)";
*failure = VERIFY_ERROR_NO_FIELD;
return field;
}
@@ -3878,6 +3784,7 @@
Class* common_super = NULL;
uint32_t handlers_size;
const byte* handlers_ptr = DexFile::dexGetCatchHandlerData(*code_item, 0);
+ VerifyError local_failure;
if (code_item->tries_size_ != 0) {
handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
@@ -3898,7 +3805,7 @@
klass = class_linker->FindSystemClass("Ljava/lang/Throwable;");
} else {
klass = ResolveClassAndCheckAccess(dex_file, handler.type_idx_,
- method->GetDeclaringClass(), failure);
+ method->GetDeclaringClass(), &local_failure);
}
if (klass == NULL) {
@@ -4363,12 +4270,9 @@
Class* res_class = class_linker->ResolveType(*dex_file, class_idx, referrer);
if (res_class == NULL) {
- //*failure = VERIFY_ERROR_NO_CLASS;
-#if 1
- // FIXME - is this correct? Inserted as a workaround?
Thread::Current()->ClearException();
-#endif
LOG(ERROR) << "VFY: can't find class with index 0x" << std::hex << class_idx << std::dec;
+ *failure = VERIFY_ERROR_NO_CLASS;
return NULL;
}
@@ -4420,11 +4324,8 @@
/* Check if access is allowed. */
if (!referrer->CanAccessMember(res_method->GetDeclaringClass(), res_method->GetAccessFlags())) {
- LOG(ERROR) << "VFY: illegal method access (call "
- << res_method->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
- << "." << res_method->GetName()->ToModifiedUtf8() << " "
- << res_method->GetSignature()->ToModifiedUtf8() << " from "
- << referrer->GetDescriptor()->ToModifiedUtf8() << ")";
+ LOG(ERROR) << "VFY: illegal method access (call " << PrettyMethod(res_method)
+ << " from " << referrer->GetDescriptor()->ToModifiedUtf8() << ")";
*failure = VERIFY_ERROR_ACCESS_METHOD;
return NULL;
}
@@ -4448,8 +4349,7 @@
Class* field_type = ResolveClassAndCheckAccess(dex_file, field_id.type_idx_, referrer, failure);
if (field_type == NULL) {
- // TODO: restore this assert?
- // DCHECK(*failure != VERIFY_ERROR_NONE) << PrettyClass(referrer) << " " << PrettyClass(klass);
+ DCHECK(*failure != VERIFY_ERROR_NONE) << PrettyClass(referrer) << " " << PrettyClass(klass);
return NULL;
}
@@ -4473,8 +4373,7 @@
if (!referrer->CanAccessMember(res_field->GetDeclaringClass(), res_field->GetAccessFlags())) {
LOG(ERROR) << "VFY: access denied from "
<< referrer->GetDescriptor()->ToModifiedUtf8() << " to field "
- << res_field->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
- << "." << res_field->GetName()->ToModifiedUtf8();
+ << PrettyField(res_field);
*failure = VERIFY_ERROR_ACCESS_FIELD;
return NULL;
}
@@ -4706,9 +4605,7 @@
/* make sure we're in the same class */
if (method->GetDeclaringClass() != field->GetDeclaringClass()) {
- LOG(ERROR) << "VFY: can't modify final field "
- << field->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
- << "." << field->GetName()->ToModifiedUtf8();
+ LOG(ERROR) << "VFY: can't modify final field " << PrettyField(field);
*failure = VERIFY_ERROR_ACCESS_FIELD;
return;
}
@@ -5042,22 +4939,16 @@
LOG(ERROR) << "VFY: unable to resolve method " << dec_insn->vB_ << ": "
<< class_descriptor << "." << method_name << " " << method_proto;
- *failure = VERIFY_ERROR_NO_METHOD;
return NULL;
}
/*
- * Only time you can explicitly call a method starting with '<' is when
- * making a "direct" invocation on "<init>". There are additional
- * restrictions but we don't enforce them here.
+ * Make sure calls to "<init>" are "direct". There are additional restrictions
+ * but we don't enfore them here.
*/
- if (res_method->GetName()->Equals("<init>")) {
- if (method_type != METHOD_DIRECT || !IsInitMethod(res_method)) {
- LOG(ERROR) << "VFY: invalid call to "
- << res_method->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
- << "." << res_method->GetName();
- goto bad_sig;
- }
+ if (res_method->GetName()->Equals("<init>") && method_type != METHOD_DIRECT) {
+ LOG(ERROR) << "VFY: invalid call to " << PrettyMethod(res_method);
+ goto bad_sig;
}
/*
@@ -5066,9 +4957,7 @@
*/
if (!IsCorrectInvokeKind(method_type, res_method)) {
LOG(ERROR) << "VFY: invoke type does not match method type of "
- << res_method->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
- << "." << res_method->GetName()->ToModifiedUtf8();
-
+ << PrettyMethod(res_method);
*failure = VERIFY_ERROR_GENERIC;
return NULL;
}
@@ -5082,16 +4971,12 @@
Class* super = method->GetDeclaringClass()->GetSuperClass();
if (super == NULL || res_method->GetMethodIndex() > super->GetVTable()->GetLength()) {
if (super == NULL) {
- LOG(ERROR) << "VFY: invalid invoke-super from "
- << method->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
- << "." << method->GetName()->ToModifiedUtf8() << " to super -."
- << res_method->GetName()->ToModifiedUtf8()
+ LOG(ERROR) << "VFY: invalid invoke-super from " << PrettyMethod(method)
+ << " to super -." << res_method->GetName()->ToModifiedUtf8()
<< " " << res_method->GetSignature()->ToModifiedUtf8();
} else {
- LOG(ERROR) << "VFY: invalid invoke-super from "
- << method->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
- << "." << method->GetName()->ToModifiedUtf8() << " to super "
- << super->GetDescriptor()->ToModifiedUtf8()
+ LOG(ERROR) << "VFY: invalid invoke-super from " << PrettyMethod(method)
+ << " to super " << super->GetDescriptor()->ToModifiedUtf8()
<< "." << res_method->GetName()->ToModifiedUtf8()
<< " " << res_method->GetSignature()->ToModifiedUtf8();
}
@@ -5271,13 +5156,7 @@
return res_method;
bad_sig:
- if (res_method != NULL) {
- LOG(ERROR) << "VFY: rejecting call to "
- << res_method->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
- << "." << res_method->GetName()->ToModifiedUtf8() << " "
- << res_method->GetSignature()->ToModifiedUtf8();
- }
-
+ LOG(ERROR) << "VFY: rejecting call to " << PrettyMethod(res_method);
if (*failure == VERIFY_ERROR_NONE)
*failure = VERIFY_ERROR_GENERIC;
return NULL;
@@ -5373,18 +5252,14 @@
*/
UniquePtr<RegisterMap> uncompressed_map(UncompressMapDifferential(compress_map));
if (uncompressed_map.get() == NULL) {
- LOG(ERROR) << "Map failed to uncompress - "
- << vdata->method_->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
- << "." << vdata->method_->GetName()->ToModifiedUtf8();
+ LOG(ERROR) << "Map failed to uncompress - " << PrettyMethod(vdata->method_);
delete map;
delete compress_map;
/* bad - compression is broken or we're out of memory */
return NULL;
} else {
if (!CompareMaps(map, uncompressed_map.get())) {
- LOG(ERROR) << "Map comparison failed - "
- << vdata->method_->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
- << "." << vdata->method_->GetName()->ToModifiedUtf8();
+ LOG(ERROR) << "Map comparison failed - " << PrettyMethod(vdata->method_);
delete map;
delete compress_map;
/* bad - compression is broken */
@@ -5425,8 +5300,7 @@
if (new_map == NULL) {
LOG(ERROR) << "Map failed to uncompress (fmt=" << format << ") "
- << method->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
- << "." << method->GetName();
+ << PrettyMethod(method);
return NULL;
}