diff options
author | 2019-05-14 14:33:38 -0700 | |
---|---|---|
committer | 2019-05-17 02:35:59 +0000 | |
commit | 92ed90ca3897ae7861b22aa12740065152839649 (patch) | |
tree | fdc54a52ba79635a228b58fe2ad90c58442965b8 /openjdkjvmti/ti_extension.cc | |
parent | 82cc9601d657965d9bff7cc0a63a603df0e1eae5 (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.cc | 49 |
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(); |