summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Andreas Gampe <agampe@google.com> 2017-03-28 20:12:13 -0700
committer Andreas Gampe <agampe@google.com> 2017-03-28 20:25:31 -0700
commita1705ea3dc57dcdecf1d4295e6ee0d6b85b5eacd (patch)
tree78368c303d93ff15e7743e5cc772abd169c9049f
parent4ba18fdfc2581a2328ab745c2707e3ed375d9e64 (diff)
ART: Fix ObjectFree reporting
Free events should not be dispatched to all registered envs. They are specific to the env that the tag came from. Add a DispatchEvent that takes an env, add an env field to the tagging table, and connect the two. Update the stress test. Make it actually work with a tagging function for the second env. Bug: 36648696 Test: ./test.py --host -r -t 905 Change-Id: I485ef1a6a57e233a2c2128b30cae93532676b3bf
-rw-r--r--runtime/openjdkjvmti/OpenjdkJvmTi.cc4
-rw-r--r--runtime/openjdkjvmti/events-inl.h20
-rw-r--r--runtime/openjdkjvmti/events.h5
-rw-r--r--runtime/openjdkjvmti/object_tagging.cc3
-rw-r--r--runtime/openjdkjvmti/object_tagging.h6
-rw-r--r--test/905-object-free/expected.txt2
-rw-r--r--test/905-object-free/src/Main.java16
-rw-r--r--test/905-object-free/tracking_free.cc8
8 files changed, 45 insertions, 19 deletions
diff --git a/runtime/openjdkjvmti/OpenjdkJvmTi.cc b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
index 448e1ed034..39e603e1e7 100644
--- a/runtime/openjdkjvmti/OpenjdkJvmTi.cc
+++ b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
@@ -1513,8 +1513,8 @@ 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)) {
+ capabilities() {
+ object_tag_table = std::unique_ptr<ObjectTagTable>(new ObjectTagTable(event_handler, this));
functions = &gJvmtiInterface;
}
diff --git a/runtime/openjdkjvmti/events-inl.h b/runtime/openjdkjvmti/events-inl.h
index d88805e987..1ddbb869f9 100644
--- a/runtime/openjdkjvmti/events-inl.h
+++ b/runtime/openjdkjvmti/events-inl.h
@@ -169,15 +169,19 @@ inline void EventHandler::DispatchClassFileLoadHookEvent(art::Thread* thread,
// exactly the argument types of the corresponding Jvmti kEvent function pointer.
template <ArtJvmtiEvent kEvent, typename ...Args>
-inline void EventHandler::DispatchEvent(art::Thread* thread,
- Args... args) const {
- using FnType = void(jvmtiEnv*, Args...);
+inline void EventHandler::DispatchEvent(art::Thread* thread, Args... args) const {
for (ArtJvmTiEnv* env : envs) {
- if (ShouldDispatch<kEvent>(env, thread)) {
- FnType* callback = impl::GetCallback<kEvent>(env);
- if (callback != nullptr) {
- (*callback)(env, args...);
- }
+ DispatchEvent<kEvent, Args...>(env, thread, args...);
+ }
+}
+
+template <ArtJvmtiEvent kEvent, typename ...Args>
+inline void EventHandler::DispatchEvent(ArtJvmTiEnv* env, art::Thread* thread, Args... args) const {
+ using FnType = void(jvmtiEnv*, Args...);
+ if (ShouldDispatch<kEvent>(env, thread)) {
+ FnType* callback = impl::GetCallback<kEvent>(env);
+ if (callback != nullptr) {
+ (*callback)(env, args...);
}
}
}
diff --git a/runtime/openjdkjvmti/events.h b/runtime/openjdkjvmti/events.h
index 4e20d1776b..ae8bf0f803 100644
--- a/runtime/openjdkjvmti/events.h
+++ b/runtime/openjdkjvmti/events.h
@@ -156,9 +156,14 @@ class EventHandler {
ArtJvmtiEvent event,
jvmtiEventMode mode);
+ // Dispatch event to all registered environments.
template <ArtJvmtiEvent kEvent, typename ...Args>
ALWAYS_INLINE
inline void DispatchEvent(art::Thread* thread, Args... args) const;
+ // Dispatch event to the given environment, only.
+ template <ArtJvmtiEvent kEvent, typename ...Args>
+ ALWAYS_INLINE
+ inline void DispatchEvent(ArtJvmTiEnv* env, art::Thread* thread, Args... args) const;
// Tell the event handler capabilities were added/lost so it can adjust the sent events.If
// caps_added is true then caps is all the newly set capabilities of the jvmtiEnv. If it is false
diff --git a/runtime/openjdkjvmti/object_tagging.cc b/runtime/openjdkjvmti/object_tagging.cc
index 4215588a09..dcdd3ede13 100644
--- a/runtime/openjdkjvmti/object_tagging.cc
+++ b/runtime/openjdkjvmti/object_tagging.cc
@@ -33,6 +33,7 @@
#include <limits>
+#include "art_jvmti.h"
#include "events-inl.h"
#include "jvmti_weak_table-inl.h"
@@ -60,7 +61,7 @@ bool ObjectTagTable::DoesHandleNullOnSweep() {
return event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kObjectFree);
}
void ObjectTagTable::HandleNullSweep(jlong tag) {
- event_handler_->DispatchEvent<ArtJvmtiEvent::kObjectFree>(nullptr, tag);
+ event_handler_->DispatchEvent<ArtJvmtiEvent::kObjectFree>(jvmti_env_, nullptr, tag);
}
} // namespace openjdkjvmti
diff --git a/runtime/openjdkjvmti/object_tagging.h b/runtime/openjdkjvmti/object_tagging.h
index b5a601cac9..ca84e442dc 100644
--- a/runtime/openjdkjvmti/object_tagging.h
+++ b/runtime/openjdkjvmti/object_tagging.h
@@ -42,12 +42,13 @@
namespace openjdkjvmti {
+struct ArtJvmTiEnv;
class EventHandler;
class ObjectTagTable FINAL : public JvmtiWeakTable<jlong> {
public:
- explicit ObjectTagTable(EventHandler* event_handler) : event_handler_(event_handler) {
- }
+ ObjectTagTable(EventHandler* event_handler, ArtJvmTiEnv* env)
+ : event_handler_(event_handler), jvmti_env_(env) {}
bool Set(art::mirror::Object* obj, jlong tag) OVERRIDE
REQUIRES_SHARED(art::Locks::mutator_lock_)
@@ -77,6 +78,7 @@ class ObjectTagTable FINAL : public JvmtiWeakTable<jlong> {
private:
EventHandler* event_handler_;
+ ArtJvmTiEnv* jvmti_env_;
};
} // namespace openjdkjvmti
diff --git a/test/905-object-free/expected.txt b/test/905-object-free/expected.txt
index 6594ad8243..c226df7b5a 100644
--- a/test/905-object-free/expected.txt
+++ b/test/905-object-free/expected.txt
@@ -10,4 +10,4 @@
---
[]
---
-Free counts 1000000 1000000
+Free counts 100000 100000
diff --git a/test/905-object-free/src/Main.java b/test/905-object-free/src/Main.java
index 67811c26d5..0d576291cb 100644
--- a/test/905-object-free/src/Main.java
+++ b/test/905-object-free/src/Main.java
@@ -65,20 +65,25 @@ public class Main {
System.out.println("---");
}
+ private static void stressAllocate(int i) {
+ Object obj = new Object();
+ setTag(obj, i);
+ setTag2(obj, i + 1);
+ }
+
private static void stress() {
getCollectedTags(0);
getCollectedTags(1);
- for (int i = 0; i <= 1000000; ++i) {
- Object obj = new Object();
- setTag(obj, i);
- obj = null; // Clear vreg.
+ // Allocate objects.
+ for (int i = 1; i <= 100000; ++i) {
+ stressAllocate(i);
}
Runtime.getRuntime().gc();
long[] freedTags1 = getCollectedTags(0);
long[] freedTags2 = getCollectedTags(1);
System.out.println("Free counts " + freedTags1.length + " " + freedTags2.length);
for (int i = 0; i < freedTags1.length; ++i) {
- if (freedTags1[i] != freedTags2[i]) {
+ if (freedTags1[i] + 1 != freedTags2[i]) {
System.out.println("Mismatched tags " + freedTags1[i] + " " + freedTags2[i]);
}
}
@@ -100,4 +105,5 @@ public class Main {
private static native void enableFreeTracking(boolean enable);
private static native void setTag(Object o, long tag);
private static native long[] getCollectedTags(int index);
+ private static native void setTag2(Object o, long tag);
}
diff --git a/test/905-object-free/tracking_free.cc b/test/905-object-free/tracking_free.cc
index 3baac88968..c48930987c 100644
--- a/test/905-object-free/tracking_free.cc
+++ b/test/905-object-free/tracking_free.cc
@@ -109,5 +109,13 @@ extern "C" JNIEXPORT jlongArray JNICALL Java_Main_getCollectedTags(JNIEnv* env,
return ret;
}
+extern "C" JNIEXPORT void JNICALL Java_Main_setTag2(JNIEnv* env,
+ jclass klass ATTRIBUTE_UNUSED,
+ jobject obj,
+ jlong tag) {
+ jvmtiError ret = jvmti_env2->SetTag(obj, tag);
+ JvmtiErrorToException(env, ret);
+}
+
} // namespace Test905ObjectFree
} // namespace art