summaryrefslogtreecommitdiff
path: root/openjdkjvmti/ti_extension.cc
diff options
context:
space:
mode:
Diffstat (limited to 'openjdkjvmti/ti_extension.cc')
-rw-r--r--openjdkjvmti/ti_extension.cc62
1 files changed, 62 insertions, 0 deletions
diff --git a/openjdkjvmti/ti_extension.cc b/openjdkjvmti/ti_extension.cc
index 9666562ceb..5dc7445681 100644
--- a/openjdkjvmti/ti_extension.cc
+++ b/openjdkjvmti/ti_extension.cc
@@ -34,6 +34,8 @@
#include "art_jvmti.h"
#include "events.h"
+#include "jni_id_type.h"
+#include "runtime-inl.h"
#include "ti_allocator.h"
#include "ti_class.h"
#include "ti_ddms.h"
@@ -41,6 +43,7 @@
#include "ti_heap.h"
#include "ti_logging.h"
#include "ti_monitor.h"
+#include "ti_redefine.h"
#include "ti_search.h"
#include "thread-inl.h"
@@ -391,6 +394,65 @@ jvmtiError ExtensionUtil::GetExtensionFunctions(jvmtiEnv* env,
return error;
}
+ // These require index-ids and debuggable to function
+ art::Runtime* runtime = art::Runtime::Current();
+ if (runtime->GetJniIdType() == art::JniIdType::kIndices &&
+ (runtime->GetInstrumentation()->IsForcedInterpretOnly() || runtime->IsJavaDebuggable())) {
+ // IsStructurallyModifiableClass
+ error = add_extension(
+ reinterpret_cast<jvmtiExtensionFunction>(Redefiner::IsStructurallyModifiableClass),
+ "com.android.art.class.is_structurally_modifiable_class",
+ "Returns whether a class can potentially be 'structurally' redefined using the various"
+ " structural redefinition extensions provided.",
+ {
+ { "klass", JVMTI_KIND_IN, JVMTI_TYPE_JCLASS, false },
+ { "result", JVMTI_KIND_OUT, JVMTI_TYPE_JBOOLEAN, false },
+ },
+ {
+ ERR(INVALID_CLASS),
+ ERR(NULL_POINTER),
+ });
+ if (error != ERR(NONE)) {
+ return error;
+ }
+
+ // StructurallyRedefineClass
+ error = add_extension(
+ reinterpret_cast<jvmtiExtensionFunction>(Redefiner::StructurallyRedefineClassDirect),
+ "com.android.art.UNSAFE.class.structurally_redefine_class_direct",
+ "Temporary prototype entrypoint for redefining a single class structurally. Currently this"
+ " only supports adding new static fields to a class without any instances."
+ " ClassFileLoadHook events will NOT be triggered. This does not currently support creating"
+ " obsolete methods. This function only has rudimentary error checking. This should not be"
+ " used except for testing.",
+ {
+ { "klass", JVMTI_KIND_IN, JVMTI_TYPE_JCLASS, false },
+ { "new_def", JVMTI_KIND_IN_BUF, JVMTI_TYPE_CCHAR, false },
+ { "new_def_len", JVMTI_KIND_IN, JVMTI_TYPE_JINT, false },
+ },
+ {
+ ERR(CLASS_LOADER_UNSUPPORTED),
+ ERR(FAILS_VERIFICATION),
+ ERR(ILLEGAL_ARGUMENT),
+ ERR(INVALID_CLASS),
+ ERR(MUST_POSSESS_CAPABILITY),
+ ERR(MUST_POSSESS_CAPABILITY),
+ ERR(NULL_POINTER),
+ ERR(OUT_OF_MEMORY),
+ ERR(UNMODIFIABLE_CLASS),
+ ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED),
+ ERR(UNSUPPORTED_REDEFINITION_METHOD_ADDED),
+ ERR(UNSUPPORTED_REDEFINITION_METHOD_DELETED),
+ ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED),
+ });
+ if (error != ERR(NONE)) {
+ return error;
+ }
+ } else {
+ LOG(INFO) << "debuggable & jni-type indices are required to implement structural "
+ << "class redefinition extensions.";
+ }
+
// Copy into output buffer.
*extension_count_ptr = ext_vector.size();