summaryrefslogtreecommitdiff
path: root/openjdkjvmti/ti_extension.cc
diff options
context:
space:
mode:
author Alex Light <allight@google.com> 2019-05-14 14:33:38 -0700
committer Treehugger Robot <treehugger-gerrit@google.com> 2019-05-17 02:35:59 +0000
commit92ed90ca3897ae7861b22aa12740065152839649 (patch)
treefdc54a52ba79635a228b58fe2ad90c58442965b8 /openjdkjvmti/ti_extension.cc
parent82cc9601d657965d9bff7cc0a63a603df0e1eae5 (diff)
Add AddToDexClassloader JVMTI extension functions
It is useful for some agents to be able to add new classes into an already existing classloader. This could be used to, for example, handle new lambdas added during 'edit-and-continue' debugging. This extension should eliminate the need for agents to reach into class-loader internals. These functions are: 'com.android.art.classloader.add_to_dex_class_loader' which has a signature of jvmtiError(jvmtiEnv* env, jobject classloader, const char* segment) and will add the given 'segment' file to the dalvik.system.BaseDexClassLoader 'loader'. 'com.android.art.classloader.add_to_dex_class_loader_in_memory' which has a signature of jvmtiError(jvmtiEnv* env, jobject classloader, const unsigned char* dex, jint dex_size) and will add the dexfile buffer 'dex' to the given dalvik.system.BaseDexClassLoader. ClassLoaders that do not extend dalvik.system.BaseDexClassLoader are not supported. Test: ./test.py --host Bug: 132699522 Bug: 132914283 Change-Id: I3740af4b3b06b9fa64be8ad94238256b7a43536a
Diffstat (limited to 'openjdkjvmti/ti_extension.cc')
-rw-r--r--openjdkjvmti/ti_extension.cc49
1 files changed, 49 insertions, 0 deletions
diff --git a/openjdkjvmti/ti_extension.cc b/openjdkjvmti/ti_extension.cc
index f12cb0a380..08667c34f8 100644
--- a/openjdkjvmti/ti_extension.cc
+++ b/openjdkjvmti/ti_extension.cc
@@ -42,6 +42,7 @@
#include "ti_heap.h"
#include "ti_logging.h"
#include "ti_monitor.h"
+#include "ti_search.h"
#include "thread-inl.h"
@@ -327,6 +328,54 @@ jvmtiError ExtensionUtil::GetExtensionFunctions(jvmtiEnv* env,
return error;
}
+ // AddToDexClassLoader
+ error = add_extension(
+ reinterpret_cast<jvmtiExtensionFunction>(SearchUtil::AddToDexClassLoader),
+ "com.android.art.classloader.add_to_dex_class_loader",
+ "Adds a dexfile to a given dalvik.system.BaseDexClassLoader in a manner similar to"
+ " AddToSystemClassLoader.",
+ {
+ { "classloader", JVMTI_KIND_IN, JVMTI_TYPE_JOBJECT, false },
+ { "segment", JVMTI_KIND_IN_PTR, JVMTI_TYPE_CCHAR, false },
+ },
+ {
+ ERR(NULL_POINTER),
+ ERR(CLASS_LOADER_UNSUPPORTED),
+ ERR(ILLEGAL_ARGUMENT),
+ ERR(WRONG_PHASE),
+ });
+ if (error != ERR(NONE)) {
+ return error;
+ }
+
+ // AddToDexClassLoaderInMemory requires memfd_create which non-linux doesn't have. The code will
+ // still all link but since it will only ever return ERR(INTERNAL) we might as well not even
+ // advertise the extension.
+ // TODO Support non-linux in some way.
+#ifdef __linux__
+ // AddToDexClassLoaderInMemory
+ error = add_extension(
+ reinterpret_cast<jvmtiExtensionFunction>(SearchUtil::AddToDexClassLoaderInMemory),
+ "com.android.art.classloader.add_to_dex_class_loader_in_memory",
+ "Adds a dexfile buffer to a given dalvik.system.BaseDexClassLoader in a manner similar to"
+ " AddToSystemClassLoader. This may only be done during the LIVE phase. The buffer is copied"
+ " and the caller is responsible for deallocating it after this call.",
+ {
+ { "classloader", JVMTI_KIND_IN, JVMTI_TYPE_JOBJECT, false },
+ { "dex_bytes", JVMTI_KIND_IN_BUF, JVMTI_TYPE_CCHAR, false },
+ { "dex_bytes_len", JVMTI_KIND_IN, JVMTI_TYPE_JINT, false },
+ },
+ {
+ ERR(NULL_POINTER),
+ ERR(CLASS_LOADER_UNSUPPORTED),
+ ERR(ILLEGAL_ARGUMENT),
+ ERR(WRONG_PHASE),
+ });
+ if (error != ERR(NONE)) {
+ return error;
+ }
+#endif
+
// Copy into output buffer.
*extension_count_ptr = ext_vector.size();