ART: Fix tagging
Tagging is local to the jvmtiEnv. Move from a global object tag
table to a table local to the ArtJvmtiEnv.
Bug: 31385027
Test: m test-art-host-run-test-903-hello-tagging
Change-Id: I2faeed87fd0421631fee7cd97bb7d496bf4e6338
diff --git a/runtime/openjdkjvmti/OpenjdkJvmTi.cc b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
index 77ca9ce..450b6b6 100644
--- a/runtime/openjdkjvmti/OpenjdkJvmTi.cc
+++ b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
@@ -73,7 +73,6 @@
namespace openjdkjvmti {
EventHandler gEventHandler;
-ObjectTagTable gObjectTagTable(&gEventHandler);
#define ENSURE_NON_NULL(n) \
do { \
@@ -334,7 +333,7 @@
const jvmtiHeapCallbacks* callbacks,
const void* user_data) {
ENSURE_HAS_CAP(env, can_tag_objects);
- HeapUtil heap_util(&gObjectTagTable);
+ HeapUtil heap_util(ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table.get());
return heap_util.FollowReferences(env,
heap_filter,
klass,
@@ -349,7 +348,7 @@
const jvmtiHeapCallbacks* callbacks,
const void* user_data) {
ENSURE_HAS_CAP(env, can_tag_objects);
- HeapUtil heap_util(&gObjectTagTable);
+ HeapUtil heap_util(ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table.get());
return heap_util.IterateThroughHeap(env, heap_filter, klass, callbacks, user_data);
}
@@ -363,7 +362,7 @@
art::ScopedObjectAccess soa(jni_env);
art::ObjPtr<art::mirror::Object> obj = soa.Decode<art::mirror::Object>(object);
- if (!gObjectTagTable.GetTag(obj.Ptr(), tag_ptr)) {
+ if (!ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table->GetTag(obj.Ptr(), tag_ptr)) {
*tag_ptr = 0;
}
@@ -384,7 +383,7 @@
art::ScopedObjectAccess soa(jni_env);
art::ObjPtr<art::mirror::Object> obj = soa.Decode<art::mirror::Object>(object);
- gObjectTagTable.Set(obj.Ptr(), tag);
+ ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table->Set(obj.Ptr(), tag);
return ERR(NONE);
}
@@ -403,12 +402,12 @@
}
art::ScopedObjectAccess soa(jni_env);
- return gObjectTagTable.GetTaggedObjects(env,
- tag_count,
- tags,
- count_ptr,
- object_result_ptr,
- tag_result_ptr);
+ return ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table->GetTaggedObjects(env,
+ tag_count,
+ tags,
+ count_ptr,
+ object_result_ptr,
+ tag_result_ptr);
}
static jvmtiError ForceGarbageCollection(jvmtiEnv* env) {
@@ -579,7 +578,7 @@
}
static jvmtiError GetLoadedClasses(jvmtiEnv* env, jint* class_count_ptr, jclass** classes_ptr) {
- HeapUtil heap_util(&gObjectTagTable);
+ HeapUtil heap_util(ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table.get());
return heap_util.GetLoadedClasses(env, class_count_ptr, classes_ptr);
}
@@ -678,6 +677,7 @@
ENSURE_HAS_CAP(env, can_retransform_classes);
std::string error_msg;
jvmtiError res = Transformer::RetransformClasses(ArtJvmTiEnv::AsArtJvmTiEnv(env),
+ &gEventHandler,
art::Runtime::Current(),
art::Thread::Current(),
class_count,
@@ -695,6 +695,7 @@
ENSURE_HAS_CAP(env, can_redefine_classes);
std::string error_msg;
jvmtiError res = Redefiner::RedefineClasses(ArtJvmTiEnv::AsArtJvmTiEnv(env),
+ &gEventHandler,
art::Runtime::Current(),
art::Thread::Current(),
class_count,
@@ -1162,6 +1163,8 @@
static jvmtiError DisposeEnvironment(jvmtiEnv* env) {
ENSURE_VALID_ENV(env);
gEventHandler.RemoveArtJvmTiEnv(ArtJvmTiEnv::AsArtJvmTiEnv(env));
+ art::Runtime::Current()->RemoveSystemWeakHolder(
+ ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table.get());
delete env;
return OK;
}
@@ -1333,13 +1336,25 @@
version == JVMTI_VERSION;
}
+extern const jvmtiInterface_1 gJvmtiInterface;
+ArtJvmTiEnv::ArtJvmTiEnv(art::JavaVMExt* runtime, EventHandler* event_handler)
+ : art_vm(runtime),
+ local_data(nullptr),
+ capabilities(),
+ object_tag_table(new ObjectTagTable(event_handler)) {
+ functions = &gJvmtiInterface;
+}
+
// Creates a jvmtiEnv and returns it with the art::ti::Env that is associated with it. new_art_ti
// is a pointer to the uninitialized memory for an art::ti::Env.
static void CreateArtJvmTiEnv(art::JavaVMExt* vm, /*out*/void** new_jvmtiEnv) {
- struct ArtJvmTiEnv* env = new ArtJvmTiEnv(vm);
+ struct ArtJvmTiEnv* env = new ArtJvmTiEnv(vm, &gEventHandler);
*new_jvmtiEnv = env;
gEventHandler.RegisterArtJvmTiEnv(env);
+
+ art::Runtime::Current()->AddSystemWeakHolder(
+ ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table.get());
}
// A hook that the runtime uses to allow plugins to handle GetEnv calls. It returns true and
@@ -1371,7 +1386,6 @@
SearchUtil::Register();
runtime->GetJavaVM()->AddEnvironmentHook(GetEnvHandler);
- runtime->AddSystemWeakHolder(&gObjectTagTable);
return true;
}
diff --git a/runtime/openjdkjvmti/art_jvmti.h b/runtime/openjdkjvmti/art_jvmti.h
index 99139a1..2ff3a47 100644
--- a/runtime/openjdkjvmti/art_jvmti.h
+++ b/runtime/openjdkjvmti/art_jvmti.h
@@ -48,8 +48,7 @@
namespace openjdkjvmti {
-extern const jvmtiInterface_1 gJvmtiInterface;
-extern EventHandler gEventHandler;
+class ObjectTagTable;
// A structure that is a jvmtiEnv with additional information for the runtime.
struct ArtJvmTiEnv : public jvmtiEnv {
@@ -60,10 +59,10 @@
EventMasks event_masks;
std::unique_ptr<jvmtiEventCallbacks> event_callbacks;
- explicit ArtJvmTiEnv(art::JavaVMExt* runtime)
- : art_vm(runtime), local_data(nullptr), capabilities() {
- functions = &gJvmtiInterface;
- }
+ // Tagging is specific to the jvmtiEnv.
+ std::unique_ptr<ObjectTagTable> object_tag_table;
+
+ ArtJvmTiEnv(art::JavaVMExt* runtime, EventHandler* event_handler);
static ArtJvmTiEnv* AsArtJvmTiEnv(jvmtiEnv* env) {
return art::down_cast<ArtJvmTiEnv*>(env);
diff --git a/runtime/openjdkjvmti/ti_redefine.cc b/runtime/openjdkjvmti/ti_redefine.cc
index 7cc7a63..c4d20c0 100644
--- a/runtime/openjdkjvmti/ti_redefine.cc
+++ b/runtime/openjdkjvmti/ti_redefine.cc
@@ -303,6 +303,7 @@
}
jvmtiError Redefiner::RedefineClasses(ArtJvmTiEnv* env,
+ EventHandler* event_handler,
art::Runtime* runtime,
art::Thread* self,
jint class_count,
@@ -350,6 +351,7 @@
}
// Call all the transformation events.
jvmtiError res = Transformer::RetransformClassesDirect(env,
+ event_handler,
self,
&def_vector);
if (res != OK) {
diff --git a/runtime/openjdkjvmti/ti_redefine.h b/runtime/openjdkjvmti/ti_redefine.h
index 65ee291..4e6d05f 100644
--- a/runtime/openjdkjvmti/ti_redefine.h
+++ b/runtime/openjdkjvmti/ti_redefine.h
@@ -88,6 +88,7 @@
// The caller is responsible for freeing it. The runtime makes its own copy of the data.
// TODO This function should call the transformation events.
static jvmtiError RedefineClasses(ArtJvmTiEnv* env,
+ EventHandler* event_handler,
art::Runtime* runtime,
art::Thread* self,
jint class_count,
diff --git a/runtime/openjdkjvmti/transform.cc b/runtime/openjdkjvmti/transform.cc
index 2fec631..36421b9 100644
--- a/runtime/openjdkjvmti/transform.cc
+++ b/runtime/openjdkjvmti/transform.cc
@@ -63,12 +63,13 @@
jvmtiError Transformer::RetransformClassesDirect(
ArtJvmTiEnv* env,
+ EventHandler* event_handler,
art::Thread* self,
/*in-out*/std::vector<ArtClassDefinition>* definitions) {
for (ArtClassDefinition& def : *definitions) {
jint new_len = -1;
unsigned char* new_data = nullptr;
- gEventHandler.DispatchEvent<ArtJvmtiEvent::kClassFileLoadHookRetransformable>(
+ event_handler->DispatchEvent<ArtJvmtiEvent::kClassFileLoadHookRetransformable>(
self,
GetJniEnv(env),
def.klass,
@@ -85,6 +86,7 @@
}
jvmtiError Transformer::RetransformClasses(ArtJvmTiEnv* env,
+ EventHandler* event_handler,
art::Runtime* runtime,
art::Thread* self,
jint class_count,
@@ -114,7 +116,7 @@
}
definitions.push_back(std::move(def));
}
- res = RetransformClassesDirect(env, self, &definitions);
+ res = RetransformClassesDirect(env, event_handler, self, &definitions);
if (res != OK) {
return res;
}
diff --git a/runtime/openjdkjvmti/transform.h b/runtime/openjdkjvmti/transform.h
index 65f2ae1..c6a36e8 100644
--- a/runtime/openjdkjvmti/transform.h
+++ b/runtime/openjdkjvmti/transform.h
@@ -42,14 +42,20 @@
namespace openjdkjvmti {
+class EventHandler;
+
jvmtiError GetClassLocation(ArtJvmTiEnv* env, jclass klass, /*out*/std::string* location);
class Transformer {
public:
static jvmtiError RetransformClassesDirect(
- ArtJvmTiEnv* env, art::Thread* self, /*in-out*/std::vector<ArtClassDefinition>* definitions);
+ ArtJvmTiEnv* env,
+ EventHandler* event_handler,
+ art::Thread* self,
+ /*in-out*/std::vector<ArtClassDefinition>* definitions);
static jvmtiError RetransformClasses(ArtJvmTiEnv* env,
+ EventHandler* event_handler,
art::Runtime* runtime,
art::Thread* self,
jint class_count,