Commit eac76676 authored by Elliott Hughes's avatar Elliott Hughes
Browse files

DO NOT MERGE Fix all unsafe caching to be like libcore.

This way, if a runtime is restarted within a process, we re-initialize all
the cached data.

Conflicts:

	src/native/java_lang_Runtime.cc -- nativeExit lost an argument in dalvik-dev

(cherry picked from commit 7756d547)

Change-Id: I6184fc20c2a9ec16c4b053584a4d1c3b64452d0f
parent 3f9ace8d
......@@ -194,6 +194,7 @@ LIBART_COMMON_SRC_FILES := \
src/trace.cc \
src/utf.cc \
src/utils.cc \
src/well_known_classes.cc \
src/zip_archive.cc \
src/verifier/gc_map.cc \
src/verifier/method_verifier.cc \
......
......@@ -52,6 +52,7 @@
#include "thread.h"
#include "UniquePtr.h"
#include "utils.h"
#include "well_known_classes.h"
namespace art {
......@@ -141,24 +142,17 @@ static void WrapExceptionInInitializer() {
env->ExceptionClear();
// TODO: add java.lang.Error to JniConstants?
ScopedLocalRef<jclass> error_class(env, env->FindClass("java/lang/Error"));
CHECK(error_class.get() != NULL);
if (env->IsInstanceOf(cause.get(), error_class.get())) {
if (env->IsInstanceOf(cause.get(), WellKnownClasses::java_lang_Error)) {
// We only wrap non-Error exceptions; an Error can just be used as-is.
env->Throw(cause.get());
return;
}
// TODO: add java.lang.ExceptionInInitializerError to JniConstants?
ScopedLocalRef<jclass> eiie_class(env, env->FindClass("java/lang/ExceptionInInitializerError"));
CHECK(eiie_class.get() != NULL);
jmethodID mid = env->GetMethodID(eiie_class.get(), "<init>" , "(Ljava/lang/Throwable;)V");
jmethodID mid = env->GetMethodID(WellKnownClasses::java_lang_ExceptionInInitializerError, "<init>" , "(Ljava/lang/Throwable;)V");
CHECK(mid != NULL);
ScopedLocalRef<jthrowable> eiie(env,
reinterpret_cast<jthrowable>(env->NewObject(eiie_class.get(), mid, cause.get())));
reinterpret_cast<jthrowable>(env->NewObject(WellKnownClasses::java_lang_ExceptionInInitializerError, mid, cause.get())));
env->Throw(eiie.get());
}
......
......@@ -28,6 +28,7 @@
#include "thread.h"
#include "thread_list.h"
#include "verifier/method_verifier.h"
#include "well_known_classes.h"
#include <algorithm>
#include <cstdarg>
......@@ -729,22 +730,11 @@ void art_proxy_invoke_handler_from_code(Method* proxy_method, ...) {
args->Set(i, val.GetL());
}
// Get the InvocationHandler method and the field that holds it within the Proxy object
static jmethodID inv_hand_invoke_mid = NULL;
static jfieldID proxy_inv_hand_fid = NULL;
if (proxy_inv_hand_fid == NULL) {
ScopedLocalRef<jclass> proxy(env, env->FindClass("java/lang/reflect/Proxy"));
proxy_inv_hand_fid = env->GetFieldID(proxy.get(), "h", "Ljava/lang/reflect/InvocationHandler;");
ScopedLocalRef<jclass> inv_hand_class(env, env->FindClass("java/lang/reflect/InvocationHandler"));
inv_hand_invoke_mid = env->GetMethodID(inv_hand_class.get(), "invoke",
"(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");
}
DCHECK(env->IsInstanceOf(rcvr_jobj, env->FindClass("java/lang/reflect/Proxy")));
DCHECK(env->IsInstanceOf(rcvr_jobj, WellKnownClasses::java_lang_reflect_Proxy));
jobject inv_hand = env->GetObjectField(rcvr_jobj, proxy_inv_hand_fid);
jobject inv_hand = env->GetObjectField(rcvr_jobj, WellKnownClasses::java_lang_reflect_Proxy_h);
// Call InvocationHandler.invoke
jobject result = env->CallObjectMethodA(inv_hand, inv_hand_invoke_mid, args_jobj);
jobject result = env->CallObjectMethodA(inv_hand, WellKnownClasses::java_lang_reflect_InvocationHandler_invoke, args_jobj);
// Place result in stack args
if (!thread->IsExceptionPending()) {
......
......@@ -34,6 +34,7 @@
#include "space.h"
#include "stack_indirect_reference_table.h"
#include "thread_list.h"
#include "well_known_classes.h"
extern "C" void dlmalloc_walk_heap(void(*)(const void*, size_t, const void*, size_t, void*), void*);
#ifndef HAVE_ANDROID_OS
......@@ -2322,14 +2323,6 @@ bool Dbg::DdmHandlePacket(const uint8_t* buf, int dataLen, uint8_t** pReplyBuf,
Thread* self = Thread::Current();
JNIEnv* env = self->GetJniEnv();
static jclass Chunk_class = CacheClass(env, "org/apache/harmony/dalvik/ddmc/Chunk");
static jclass DdmServer_class = CacheClass(env, "org/apache/harmony/dalvik/ddmc/DdmServer");
static jmethodID dispatch_mid = env->GetStaticMethodID(DdmServer_class, "dispatch", "(I[BII)Lorg/apache/harmony/dalvik/ddmc/Chunk;");
static jfieldID data_fid = env->GetFieldID(Chunk_class, "data", "[B");
static jfieldID length_fid = env->GetFieldID(Chunk_class, "length", "I");
static jfieldID offset_fid = env->GetFieldID(Chunk_class, "offset", "I");
static jfieldID type_fid = env->GetFieldID(Chunk_class, "type", "I");
// Create a byte[] corresponding to 'buf'.
ScopedLocalRef<jbyteArray> dataArray(env, env->NewByteArray(dataLen));
if (dataArray.get() == NULL) {
......@@ -2352,7 +2345,9 @@ bool Dbg::DdmHandlePacket(const uint8_t* buf, int dataLen, uint8_t** pReplyBuf,
}
// Call "private static Chunk dispatch(int type, byte[] data, int offset, int length)".
ScopedLocalRef<jobject> chunk(env, env->CallStaticObjectMethod(DdmServer_class, dispatch_mid, type, dataArray.get(), offset, length));
ScopedLocalRef<jobject> chunk(env, env->CallStaticObjectMethod(WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer,
WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer_dispatch,
type, dataArray.get(), offset, length));
if (env->ExceptionCheck()) {
LOG(INFO) << StringPrintf("Exception thrown by dispatcher for 0x%08x", type);
env->ExceptionDescribe();
......@@ -2376,10 +2371,10 @@ bool Dbg::DdmHandlePacket(const uint8_t* buf, int dataLen, uint8_t** pReplyBuf,
*
* So we're pretty much stuck with copying data around multiple times.
*/
ScopedLocalRef<jbyteArray> replyData(env, reinterpret_cast<jbyteArray>(env->GetObjectField(chunk.get(), data_fid)));
length = env->GetIntField(chunk.get(), length_fid);
offset = env->GetIntField(chunk.get(), offset_fid);
type = env->GetIntField(chunk.get(), type_fid);
ScopedLocalRef<jbyteArray> replyData(env, reinterpret_cast<jbyteArray>(env->GetObjectField(chunk.get(), WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk_data)));
length = env->GetIntField(chunk.get(), WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk_length);
offset = env->GetIntField(chunk.get(), WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk_offset);
type = env->GetIntField(chunk.get(), WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk_type);
VLOG(jdwp) << StringPrintf("DDM reply: type=0x%08x data=%p offset=%d length=%d", type, replyData.get(), offset, length);
if (length == 0 || replyData.get() == NULL) {
......@@ -2418,10 +2413,10 @@ void Dbg::DdmBroadcast(bool connect) {
}
JNIEnv* env = self->GetJniEnv();
static jclass DdmServer_class = CacheClass(env, "org/apache/harmony/dalvik/ddmc/DdmServer");
static jmethodID broadcast_mid = env->GetStaticMethodID(DdmServer_class, "broadcast", "(I)V");
jint event = connect ? 1 /*DdmServer.CONNECTED*/ : 2 /*DdmServer.DISCONNECTED*/;
env->CallStaticVoidMethod(DdmServer_class, broadcast_mid, event);
env->CallStaticVoidMethod(WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer,
WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer_broadcast,
event);
if (env->ExceptionCheck()) {
LOG(ERROR) << "DdmServer.broadcast " << event << " failed";
env->ExceptionDescribe();
......
......@@ -38,6 +38,7 @@
#include "UniquePtr.h"
#include "utf.h"
#include "utils.h"
#include "well_known_classes.h"
#include "zip_archive.h"
namespace art {
......@@ -234,19 +235,11 @@ jobject DexFile::GetDexObject(JNIEnv* env) const {
return NULL;
}
jclass c = env->FindClass("com/android/dex/Dex");
if (c == NULL) {
return NULL;
}
jmethodID mid = env->GetStaticMethodID(c, "create", "(Ljava/nio/ByteBuffer;)Lcom/android/dex/Dex;");
if (mid == NULL) {
return NULL;
}
jvalue args[1];
args[0].l = byte_buffer;
jobject local = env->CallStaticObjectMethodA(c, mid, args);
jobject local = env->CallStaticObjectMethodA(WellKnownClasses::com_android_dex_Dex,
WellKnownClasses::com_android_dex_Dex_create,
args);
if (local == NULL) {
return NULL;
}
......
......@@ -35,6 +35,7 @@
#include "thread_list.h"
#include "timing_logger.h"
#include "UniquePtr.h"
#include "well_known_classes.h"
namespace art {
......@@ -854,9 +855,7 @@ void Heap::RequestHeapTrim() {
return;
}
JNIEnv* env = Thread::Current()->GetJniEnv();
static jclass Daemons_class = CacheClass(env, "java/lang/Daemons");
static jmethodID Daemons_requestHeapTrim = env->GetStaticMethodID(Daemons_class, "requestHeapTrim", "()V");
env->CallStaticVoidMethod(Daemons_class, Daemons_requestHeapTrim);
env->CallStaticVoidMethod(WellKnownClasses::java_lang_Daemons, WellKnownClasses::java_lang_Daemons_requestHeapTrim);
CHECK(!env->ExceptionCheck());
}
......
......@@ -37,6 +37,7 @@
#include "stringpiece.h"
#include "thread.h"
#include "UniquePtr.h"
#include "well_known_classes.h"
namespace art {
......@@ -55,6 +56,16 @@ static size_t gGlobalsMax = 51200; // Arbitrary sanity check.
static const size_t kWeakGlobalsInitial = 16; // Arbitrary.
static const size_t kWeakGlobalsMax = 51200; // Arbitrary sanity check.
void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods, size_t method_count) {
ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
if (c.get() == NULL) {
LOG(FATAL) << "Couldn't find class: " << jni_class_name;
}
if (env->RegisterNatives(c.get(), methods, method_count) != JNI_OK) {
LOG(FATAL) << "Failed to register natives methods: " << jni_class_name;
}
}
void SetJniGlobalsMax(size_t max) {
if (max != 0) {
gGlobalsMax = max;
......@@ -511,17 +522,6 @@ static void SetPrimitiveArrayRegion(ScopedJniThreadState& ts, JavaArrayT java_ar
}
}
static jclass InitDirectByteBufferClass(JNIEnv* env) {
ScopedLocalRef<jclass> buffer_class(env, env->FindClass("java/nio/ReadWriteDirectByteBuffer"));
CHECK(buffer_class.get() != NULL);
return reinterpret_cast<jclass>(env->NewGlobalRef(buffer_class.get()));
}
static jclass GetDirectByteBufferClass(JNIEnv* env) {
static jclass buffer_class = InitDirectByteBufferClass(env);
return buffer_class;
}
static jint JII_AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* raw_args, bool as_daemon) {
if (vm == NULL || p_env == NULL) {
return JNI_ERR;
......@@ -2315,32 +2315,26 @@ class JNI {
CHECK(address != NULL); // TODO: ReportJniError
CHECK_GT(capacity, 0); // TODO: ReportJniError
jclass buffer_class = GetDirectByteBufferClass(env);
jmethodID mid = env->GetMethodID(buffer_class, "<init>", "(II)V");
if (mid == NULL) {
return NULL;
}
// At the moment, the Java side is limited to 32 bits.
CHECK_LE(reinterpret_cast<uintptr_t>(address), 0xffffffff);
CHECK_LE(capacity, 0xffffffff);
jint address_arg = reinterpret_cast<jint>(address);
jint capacity_arg = static_cast<jint>(capacity);
jobject result = env->NewObject(buffer_class, mid, address_arg, capacity_arg);
jobject result = env->NewObject(WellKnownClasses::java_nio_ReadWriteDirectByteBuffer,
WellKnownClasses::java_nio_ReadWriteDirectByteBuffer_init,
address_arg, capacity_arg);
return ts.Self()->IsExceptionPending() ? NULL : result;
}
static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
ScopedJniThreadState ts(env);
static jfieldID fid = env->GetFieldID(GetDirectByteBufferClass(env), "effectiveDirectAddress", "I");
return reinterpret_cast<void*>(env->GetIntField(java_buffer, fid));
return reinterpret_cast<void*>(env->GetIntField(java_buffer, WellKnownClasses::java_nio_ReadWriteDirectByteBuffer_effectiveDirectAddress));
}
static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
ScopedJniThreadState ts(env);
static jfieldID fid = env->GetFieldID(GetDirectByteBufferClass(env), "capacity", "I");
return static_cast<jlong>(env->GetIntField(java_buffer, fid));
return static_cast<jlong>(env->GetIntField(java_buffer, WellKnownClasses::java_nio_ReadWriteDirectByteBuffer_capacity));
}
static jobjectRefType GetObjectRefType(JNIEnv* env, jobject java_object) {
......@@ -3011,14 +3005,6 @@ void JavaVMExt::VisitRoots(Heap::RootVisitor* visitor, void* arg) {
// The weak_globals table is visited by the GC itself (because it mutates the table).
}
jclass CacheClass(JNIEnv* env, const char* jni_class_name) {
ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
if (c.get() == NULL) {
return NULL;
}
return reinterpret_cast<jclass>(env->NewGlobalRef(c.get()));
}
} // namespace art
std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
......
......@@ -29,6 +29,13 @@
#include <iosfwd>
#include <string>
#ifndef NATIVE_METHOD
#define NATIVE_METHOD(className, functionName, signature) \
{ #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName) }
#endif
#define REGISTER_NATIVE_METHODS(jni_class_name) \
RegisterNativeMethods(env, jni_class_name, gMethods, arraysize(gMethods))
namespace art {
class ClassLoader;
......@@ -41,7 +48,7 @@ class Thread;
void SetJniGlobalsMax(size_t max);
void JniAbort(const char* jni_function_name);
void* FindNativeMethod(Thread* thread);
jclass CacheClass(JNIEnv* env, const char* jni_class_name);
void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods, size_t method_count);
template<typename T> T Decode(JNIEnv*, jobject);
template<typename T> T AddLocalReference(JNIEnv*, const Object*);
......
......@@ -16,20 +16,19 @@
#include <unistd.h>
#include "class_loader.h"
#include "class_linker.h"
#include "class_loader.h"
#include "dex_file.h"
#include "image.h"
#include "jni_internal.h"
#include "logging.h"
#include "os.h"
#include "runtime.h"
#include "space.h"
#include "zip_archive.h"
#include "toStringArray.h"
#include "ScopedLocalRef.h"
#include "ScopedUtfChars.h"
#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
#include "space.h"
#include "toStringArray.h"
#include "zip_archive.h"
namespace art {
......@@ -98,23 +97,23 @@ static jint DexFile_openDexFile(JNIEnv* env, jclass, jstring javaSourceName, jst
}
if (dex_file == NULL) {
LOG(WARNING) << "Failed to open dex file: " << source;
jniThrowExceptionFmt(env, "java/io/IOException", "unable to open dex file: %s",
source.c_str());
Thread::Current()->ThrowNewExceptionF("Ljava/io/IOException;", "Unable to open dex file: %s",
source.c_str());
return 0;
}
return static_cast<jint>(reinterpret_cast<uintptr_t>(dex_file));
}
static const DexFile* toDexFile(JNIEnv* env, int dex_file_address) {
static const DexFile* toDexFile(int dex_file_address) {
const DexFile* dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(dex_file_address));
if (dex_file == NULL) {
jniThrowNullPointerException(env, "dex_file == null");
Thread::Current()->ThrowNewExceptionF("Ljava/lang/NullPointerException;", "dex_file == null");
}
return dex_file;
}
static void DexFile_closeDexFile(JNIEnv* env, jclass, jint cookie) {
const DexFile* dex_file = toDexFile(env, cookie);
static void DexFile_closeDexFile(JNIEnv*, jclass, jint cookie) {
const DexFile* dex_file = toDexFile(cookie);
if (dex_file == NULL) {
return;
}
......@@ -127,7 +126,7 @@ static void DexFile_closeDexFile(JNIEnv* env, jclass, jint cookie) {
static jclass DexFile_defineClassNative(JNIEnv* env, jclass, jstring javaName, jobject javaLoader,
jint cookie) {
ScopedThreadStateChange tsc(Thread::Current(), kRunnable);
const DexFile* dex_file = toDexFile(env, cookie);
const DexFile* dex_file = toDexFile(cookie);
if (dex_file == NULL) {
return NULL;
}
......@@ -150,7 +149,7 @@ static jclass DexFile_defineClassNative(JNIEnv* env, jclass, jstring javaName, j
}
static jobjectArray DexFile_getClassNameList(JNIEnv* env, jclass, jint cookie) {
const DexFile* dex_file = toDexFile(env, cookie);
const DexFile* dex_file = toDexFile(cookie);
if (dex_file == NULL) {
return NULL;
}
......@@ -175,7 +174,7 @@ static jboolean DexFile_isDexOptNeeded(JNIEnv* env, jclass, jstring javaFilename
if (!OS::FileExists(filename.c_str())) {
LOG(ERROR) << "DexFile_isDexOptNeeded file '" << filename.c_str() << "' does not exist";
jniThrowExceptionFmt(env, "java/io/FileNotFoundException", "%s", filename.c_str());
Thread::Current()->ThrowNewExceptionF("Ljava/io/FileNotFoundException;", "%s", filename.c_str());
return JNI_TRUE;
}
......@@ -265,7 +264,7 @@ static JNINativeMethod gMethods[] = {
};
void register_dalvik_system_DexFile(JNIEnv* env) {
jniRegisterNativeMethods(env, "dalvik/system/DexFile", gMethods, NELEM(gMethods));
REGISTER_NATIVE_METHODS("dalvik/system/DexFile");
}
} // namespace art
......@@ -14,18 +14,16 @@
* limitations under the License.
*/
#include <string.h>
#include <unistd.h>
#include "class_linker.h"
#include "debugger.h"
#include "jni_internal.h"
#include "trace.h"
#include "hprof/hprof.h"
#include "jni_internal.h"
#include "ScopedUtfChars.h"
#include "toStringArray.h"
#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
#include <string.h>
#include <unistd.h>
#include "trace.h"
namespace art {
......@@ -66,7 +64,7 @@ static void VMDebug_startMethodTracingFd(JNIEnv* env, jclass, jstring javaTraceF
int fd = dup(originalFd);
if (fd < 0) {
jniThrowExceptionFmt(env, "java/lang/RuntimeException", "dup(%d) failed: %s", originalFd, strerror(errno));
Thread::Current()->ThrowNewExceptionF("Ljava/lang/RuntimeException;", "dup(%d) failed: %s", originalFd, strerror(errno));
return;
}
......@@ -115,20 +113,20 @@ static jlong VMDebug_lastDebuggerActivity(JNIEnv*, jclass) {
return Dbg::LastDebuggerActivity();
}
static void VMDebug_startInstructionCounting(JNIEnv* env, jclass) {
jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
static void VMDebug_startInstructionCounting(JNIEnv*, jclass) {
Thread::Current()->ThrowNewException("Ljava/lang/UnsupportedOperationException;", "");
}
static void VMDebug_stopInstructionCounting(JNIEnv* env, jclass) {
jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
static void VMDebug_stopInstructionCounting(JNIEnv*, jclass) {
Thread::Current()->ThrowNewException("Ljava/lang/UnsupportedOperationException;", "");
}
static void VMDebug_getInstructionCount(JNIEnv* env, jclass, jintArray /*javaCounts*/) {
jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
static void VMDebug_getInstructionCount(JNIEnv*, jclass, jintArray /*javaCounts*/) {
Thread::Current()->ThrowNewException("Ljava/lang/UnsupportedOperationException;", "");
}
static void VMDebug_resetInstructionCount(JNIEnv* env, jclass) {
jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
static void VMDebug_resetInstructionCount(JNIEnv*, jclass) {
Thread::Current()->ThrowNewException("Ljava/lang/UnsupportedOperationException;", "");
}
static void VMDebug_printLoadedClasses(JNIEnv*, jclass, jint flags) {
......@@ -156,7 +154,7 @@ static jlong VMDebug_threadCpuTimeNanos(JNIEnv*, jclass) {
static void VMDebug_dumpHprofData(JNIEnv* env, jclass, jstring javaFilename, jobject javaFd) {
// Only one of these may be NULL.
if (javaFilename == NULL && javaFd == NULL) {
jniThrowNullPointerException(env, "fileName == null && fd == null");
Thread::Current()->ThrowNewException("Ljava/lang/NullPointerException;", "fileName == null && fd == null");
return;
}
......@@ -175,7 +173,7 @@ static void VMDebug_dumpHprofData(JNIEnv* env, jclass, jstring javaFilename, job
if (javaFd != NULL) {
fd = jniGetFDFromFileDescriptor(env, javaFd);
if (fd < 0) {
jniThrowException(env, "Ljava/lang/RuntimeException;", "Invalid file descriptor");
Thread::Current()->ThrowNewException("Ljava/lang/RuntimeException;", "Invalid file descriptor");
return;
}
}
......@@ -183,16 +181,16 @@ static void VMDebug_dumpHprofData(JNIEnv* env, jclass, jstring javaFilename, job
int result = hprof::DumpHeap(filename.c_str(), fd, false);
if (result != 0) {
// TODO: ideally we'd throw something more specific based on actual failure
jniThrowException(env, "Ljava/lang/RuntimeException;", "Failure during heap dump; check log output for details");
Thread::Current()->ThrowNewExceptionF("Ljava/lang/RuntimeException;", "Failure during heap dump; check log output for details: %d", result);
return;
}
}
static void VMDebug_dumpHprofDataDdms(JNIEnv* env, jclass) {
static void VMDebug_dumpHprofDataDdms(JNIEnv*, jclass) {
int result = hprof::DumpHeap("[DDMS]", -1, true);
if (result != 0) {
// TODO: ideally we'd throw something more specific based on actual failure
jniThrowException(env, "Ljava/lang/RuntimeException;", "Failure during heap dump; check log output for details");
Thread::Current()->ThrowNewExceptionF("Ljava/lang/RuntimeException;", "Failure during heap dump; check log output for details: %d", result);
return;
}
}
......@@ -255,7 +253,7 @@ static JNINativeMethod gMethods[] = {
};
void register_dalvik_system_VMDebug(JNIEnv* env) {
jniRegisterNativeMethods(env, "dalvik/system/VMDebug", gMethods, NELEM(gMethods));
REGISTER_NATIVE_METHODS("dalvik/system/VMDebug");
}
} // namespace art
......@@ -14,6 +14,8 @@
* limitations under the License.
*/
#include <limits.h>
#include "class_linker.h"
#include "debugger.h"
#include "jni_internal.h"
......@@ -24,12 +26,8 @@
#include "space.h"
#include "thread.h"
#include "thread_list.h"
#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
#include "toStringArray.h"
#include <limits.h>
namespace art {
static jfloat VMRuntime_getTargetHeapUtilization(JNIEnv*, jobject) {
......@@ -187,7 +185,7 @@ static JNINativeMethod gMethods[] = {
};
void register_dalvik_system_VMRuntime(JNIEnv* env) {
jniRegisterNativeMethods(env, "dalvik/system/VMRuntime", gMethods, NELEM(gMethods));
REGISTER_NATIVE_METHODS("dalvik/system/VMRuntime");
}
} // namespace art
......@@ -14,16 +14,14 @@
* limitations under the License.
*/
#include "jni_internal.h"
#include "class_loader.h"
#include "jni_internal.h"
#include "nth_caller_visitor.h"
#include "object.h"
#include "scoped_heap_lock.h"
#include "scoped_thread_list_lock.h"
#include "thread_list.h"
#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
namespace art {
static jobject GetThreadStack(JNIEnv* env, jobject javaThread) {
......@@ -99,7 +97,7 @@ static JNINativeMethod gMethods[] = {
};
void register_dalvik_system_VMStack(JNIEnv* env) {
jniRegisterNativeMethods(env, "dalvik/system/VMStack", gMethods, NELEM(gMethods));
REGISTER_NATIVE_METHODS("dalvik/system/VMStack");
}
} // namespace art
......@@ -25,7 +25,6 @@
#include "cutils/sched_policy.h"
#include "debugger.h"
#include "jni_internal.h"
#include "JniConstants.h"
#include "JNIHelp.h"
#include "ScopedLocalRef.h"
#include "ScopedPrimitiveArray.h"
......@@ -375,7 +374,7 @@ static JNINativeMethod gMethods[] = {
};
void register_dalvik_system_Zygote(JNIEnv* env) {
jniRegisterNativeMethods(env, "dalvik/system/Zygote", gMethods, NELEM(gMethods));
REGISTER_NATIVE_METHODS("dalvik/system/Zygote");
}
} // namespace art
......@@ -14,16 +14,15 @@
* limitations under the License.
*/
#include "jni_internal.h"
#include "class_linker.h"
#include "class_loader.h"
#include "jni_internal.h"
#include "nth_caller_visitor.h"
#include "object.h"
#include "object_utils.h"
#include "ScopedLocalRef.h"
#include "ScopedUtfChars.h"
#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
#include "well_known_classes.h"
namespace art {
......@@ -62,9 +61,9 @@ static jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean
if (c == NULL) {
ScopedLocalRef<jthrowable> cause(env, env->ExceptionOccurred());
env->ExceptionClear();
static jclass ClassNotFoundException_class = CacheClass(env, "java/lang/ClassNotFoundException");
static jmethodID ctor = env->GetMethodID(ClassNotFoundException_class, "<init>", "(Ljava/lang/String;Ljava/lang/Throwable;)V");
jthrowable cnfe = reinterpret_cast<jthrowable>(env->NewObject(ClassNotFoundException_class, ctor, javaName, cause.get()));
jthrowable cnfe = reinterpret_cast<jthrowable>(env->NewObject(WellKnownClasses::java_lang_ClassNotFoundException,
WellKnownClasses::java_lang_ClassNotFoundException_init,
javaName, cause.get()));
env->Throw(cnfe);
return NULL;
}
......@@ -89,8 +88,8 @@ static jint Class_getAnnotationDirectoryOffset(JNIEnv* env, jclass javaClass) {
template<typename T>
static jobjectArray ToArray(JNIEnv* env, const char* array_class_name, const std::vector<T*>& objects) {
jclass array_class = env->FindClass(array_class_name);
jobjectArray result = env->NewObjectArray(objects.size(), array_class, NULL);
ScopedLocalRef<jclass> array_class(env, env->FindClass(array_class_name));
jobjectArray result = env->NewObjectArray(objects.size(), array_class.get(), NULL);
for (size_t i = 0; i < objects.size(); ++i) {
ScopedLocalRef<jobject> object(env, AddLocalReference<jobject>(env, objects[i]));
env->SetObjectArrayElement(result, i, object.get());
......@@ -472,7 +471,7 @@ static JNINativeMethod gMethods[] = {
};
void register_java_lang_Class(JNIEnv* env) {
jniRegisterNativeMethods(env, "java/lang/Class", gMethods, NELEM(gMethods));
REGISTER_NATIVE_METHODS("java/lang/Class");
}
} // namespace art
......@@ -17,8 +17,6 @@
#include "jni_internal.h"
#include "object.h"
#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
namespace art {
static jobject Object_internalClone(JNIEnv* env, jobject javaThis) {
......@@ -50,7 +48,7 @@ static JNINativeMethod gMethods[] = {
};
void register_java_lang_Object(JNIEnv* env) {
jniRegisterNativeMethods(env, "java/lang/Object", gMethods, NELEM(gMethods));
REGISTER_NATIVE_METHODS("java/lang/Object");
}
} // namespace art
......@@ -14,15 +14,13 @@
* limitations under the License.
*/
#include <unistd.h>
#include <limits.h>
#include <unistd.h>
#include "heap.h"
#include "jni_internal.h"
#include "object.h"
#include "runtime.h"
#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
#include "ScopedUtfChars.h"
namespace art {
......@@ -77,16 +75,16 @@ static jlong Runtime_freeMemory(JNIEnv*, jclass) {
}
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Runtime, freeMemory, "()J"),
NATIVE_METHOD(Runtime, gc, "()V"),
NATIVE_METHOD(Runtime, maxMemory, "()J"),
NATIVE_METHOD(Runtime, nativeExit, "(IZ)V"),
NATIVE_METHOD(Runtime, nativeLoad, "(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/String;"),
NATIVE_METHOD(Runtime, totalMemory, "()J"),
NATIVE_METHOD(Runtime, freeMemory, "()J"),
NATIVE_METHOD(Runtime, gc, "()V"),
NATIVE_METHOD(Runtime, maxMemory, "()J"),
NATIVE_METHOD(Runtime, nativeExit, "(IZ)V"),
NATIVE_METHOD(Runtime, nativeLoad, "(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/String;"),
NATIVE_METHOD(Runtime, totalMemory, "()J"),
};
void register_java_lang_Runtime(JNIEnv* env) {
jniRegisterNativeMethods(env, "java/lang/Runtime", gMethods, NELEM(gMethods));
REGISTER_NATIVE_METHODS("java/lang/Runtime");
}
} // namespace art
......@@ -17,8 +17,6 @@
#include "jni_internal.h"
#include "object.h"
#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
#ifdef HAVE__MEMCMP16
// "count" is in 16-bit units.
extern "C" uint32_t __memcmp16(const uint16_t* s0, const uint16_t* s1, size_t count);
......@@ -108,7 +106,7 @@ static JNINativeMethod gMethods[] = {
};
void register_java_lang_String(JNIEnv* env) {
jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
REGISTER_NATIVE_METHODS("java/lang/String");
}
} // namespace art
......@@ -17,8 +17,6 @@
#include "jni_internal.h"
#include "object.h"
#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
/*
* We make guarantees about the atomicity of accesses to primitive
* variables. These guarantees also apply to elements of arrays.
......@@ -253,7 +251,7 @@ static JNINativeMethod gMethods[] = {
};
void register_java_lang_System(JNIEnv* env) {
jniRegisterNativeMethods(env, "java/lang/System", gMethods, NELEM(gMethods));
REGISTER_NATIVE_METHODS("java/lang/System");
}
} // namespace art
......@@ -22,8 +22,6 @@
#include "thread.h"
#include "thread_list.h"
#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
namespace art {
static jobject Thread_currentThread(JNIEnv* env, jclass) {
......@@ -145,7 +143,7 @@ static JNINativeMethod gMethods[] = {
};
void register_java_lang_Thread(JNIEnv* env) {
jniRegisterNativeMethods(env, "java/lang/Thread", gMethods, NELEM(gMethods));
REGISTER_NATIVE_METHODS("java/lang/Thread");
}
} // namespace art
......@@ -17,8 +17,6 @@
#include "jni_internal.h"
#include "thread.h"
#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
namespace art {
static jobject Throwable_nativeFillInStackTrace(JNIEnv* env, jclass) {
......@@ -39,7 +37,7 @@ static JNINativeMethod gMethods[] = {
};
void register_java_lang_Throwable(JNIEnv* env) {
jniRegisterNativeMethods(env, "java/lang/Throwable", gMethods, NELEM(gMethods));
REGISTER_NATIVE_METHODS("java/lang/Throwable");
}
} // namespace art
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment