summaryrefslogtreecommitdiff
path: root/openjdkjvmti/transform.cc
diff options
context:
space:
mode:
Diffstat (limited to 'openjdkjvmti/transform.cc')
-rw-r--r--openjdkjvmti/transform.cc79
1 files changed, 51 insertions, 28 deletions
diff --git a/openjdkjvmti/transform.cc b/openjdkjvmti/transform.cc
index bccdcb18af..d3448d9e65 100644
--- a/openjdkjvmti/transform.cc
+++ b/openjdkjvmti/transform.cc
@@ -76,20 +76,23 @@ void Transformer::Register(EventHandler* eh) {
}
// Initialize templates.
-template
-void Transformer::TransformSingleClassDirect<ArtJvmtiEvent::kClassFileLoadHookNonRetransformable>(
- EventHandler* event_handler, art::Thread* self, /*in-out*/ArtClassDefinition* def);
-template
-void Transformer::TransformSingleClassDirect<ArtJvmtiEvent::kClassFileLoadHookRetransformable>(
- EventHandler* event_handler, art::Thread* self, /*in-out*/ArtClassDefinition* def);
-template
-void Transformer::TransformSingleClassDirect<ArtJvmtiEvent::kStructuralDexFileLoadHook>(
- EventHandler* event_handler, art::Thread* self, /*in-out*/ArtClassDefinition* def);
+template void Transformer::CallClassFileLoadHooksSingleClass<
+ ArtJvmtiEvent::kClassFileLoadHookNonRetransformable>(EventHandler* event_handler,
+ art::Thread* self,
+ /*in-out*/ ArtClassDefinition* def);
+template void Transformer::CallClassFileLoadHooksSingleClass<
+ ArtJvmtiEvent::kClassFileLoadHookRetransformable>(EventHandler* event_handler,
+ art::Thread* self,
+ /*in-out*/ ArtClassDefinition* def);
+template void Transformer::CallClassFileLoadHooksSingleClass<
+ ArtJvmtiEvent::kStructuralDexFileLoadHook>(EventHandler* event_handler,
+ art::Thread* self,
+ /*in-out*/ ArtClassDefinition* def);
-template<ArtJvmtiEvent kEvent>
-void Transformer::TransformSingleClassDirect(EventHandler* event_handler,
- art::Thread* self,
- /*in-out*/ArtClassDefinition* def) {
+template <ArtJvmtiEvent kEvent>
+void Transformer::CallClassFileLoadHooksSingleClass(EventHandler* event_handler,
+ art::Thread* self,
+ /*in-out*/ ArtClassDefinition* def) {
static_assert(kEvent == ArtJvmtiEvent::kClassFileLoadHookNonRetransformable ||
kEvent == ArtJvmtiEvent::kClassFileLoadHookRetransformable ||
kEvent == ArtJvmtiEvent::kStructuralDexFileLoadHook,
@@ -115,21 +118,41 @@ void Transformer::TransformSingleClassDirect(EventHandler* event_handler,
}
template <RedefinitionType kType>
-void Transformer::RetransformClassesDirect(
- art::Thread* self,
- /*in-out*/ std::vector<ArtClassDefinition>* definitions) {
- constexpr ArtJvmtiEvent kEvent = kType == RedefinitionType::kNormal
- ? ArtJvmtiEvent::kClassFileLoadHookRetransformable
- : ArtJvmtiEvent::kStructuralDexFileLoadHook;
- for (ArtClassDefinition& def : *definitions) {
- TransformSingleClassDirect<kEvent>(gEventHandler, self, &def);
+void Transformer::CallClassFileLoadHooks(art::Thread* self,
+ /*in-out*/ std::vector<ArtClassDefinition>* definitions) {
+ if (kType == RedefinitionType::kNormal) {
+ // For normal redefinition we have to call ClassFileLoadHook according to the spec. We use an
+ // internal event "ClassFileLoadHookRetransformable" for agents that can redefine and a
+ // "ClassFileLoadHookNonRetransformable" for agents that cannot redefine. When an agent is
+ // attached to a non-debuggable environment, we cannot redefine any classes. Splitting the
+ // ClassFileLoadHooks allows us to differentiate between these two cases. This method is only
+ // called when redefinition is allowed so just run ClassFileLoadHookRetransformable hooks.
+ for (ArtClassDefinition& def : *definitions) {
+ CallClassFileLoadHooksSingleClass<ArtJvmtiEvent::kClassFileLoadHookRetransformable>(
+ gEventHandler, self, &def);
+ }
+ } else {
+ // For structural redefinition we call StructualDexFileLoadHook in addition to the
+ // ClassFileLoadHooks. This let's us specify if structural modifications are allowed.
+ // TODO(mythria): The spec only specifies we need to call ClassFileLoadHooks, the
+ // StructuralDexFileLoadHooks is internal to ART. It is not clear if we need to run all
+ // StructuralDexFileHooks before ClassFileLoadHooks. Doing it this way to keep the existing
+ // behaviour.
+ for (ArtClassDefinition& def : *definitions) {
+ CallClassFileLoadHooksSingleClass<ArtJvmtiEvent::kStructuralDexFileLoadHook>(
+ gEventHandler, self, &def);
+ }
+ for (ArtClassDefinition& def : *definitions) {
+ CallClassFileLoadHooksSingleClass<ArtJvmtiEvent::kClassFileLoadHookRetransformable>(
+ gEventHandler, self, &def);
+ }
}
}
-template void Transformer::RetransformClassesDirect<RedefinitionType::kNormal>(
- art::Thread* self, /*in-out*/std::vector<ArtClassDefinition>* definitions);
-template void Transformer::RetransformClassesDirect<RedefinitionType::kStructural>(
- art::Thread* self, /*in-out*/std::vector<ArtClassDefinition>* definitions);
+template void Transformer::CallClassFileLoadHooks<RedefinitionType::kNormal>(
+ art::Thread* self, /*in-out*/ std::vector<ArtClassDefinition>* definitions);
+template void Transformer::CallClassFileLoadHooks<RedefinitionType::kStructural>(
+ art::Thread* self, /*in-out*/ std::vector<ArtClassDefinition>* definitions);
jvmtiError Transformer::RetransformClasses(jvmtiEnv* env,
jint class_count,
@@ -151,7 +174,7 @@ jvmtiError Transformer::RetransformClasses(jvmtiEnv* env,
std::vector<ArtClassDefinition> definitions;
jvmtiError res = OK;
for (jint i = 0; i < class_count; i++) {
- res = Redefiner::GetClassRedefinitionError<RedefinitionType::kNormal>(classes[i], &error_msg);
+ res = Redefiner::CanRedefineClass<RedefinitionType::kNormal>(classes[i], &error_msg);
if (res != OK) {
JVMTI_LOG(WARNING, env) << "FAILURE TO RETRANSFORM " << error_msg;
return res;
@@ -164,8 +187,8 @@ jvmtiError Transformer::RetransformClasses(jvmtiEnv* env,
}
definitions.push_back(std::move(def));
}
- RetransformClassesDirect<RedefinitionType::kStructural>(self, &definitions);
- RetransformClassesDirect<RedefinitionType::kNormal>(self, &definitions);
+
+ CallClassFileLoadHooks<RedefinitionType::kStructural>(self, &definitions);
RedefinitionType redef_type =
std::any_of(definitions.cbegin(),
definitions.cend(),