diff options
| author | 2017-03-28 20:12:13 -0700 | |
|---|---|---|
| committer | 2017-03-28 20:25:31 -0700 | |
| commit | a1705ea3dc57dcdecf1d4295e6ee0d6b85b5eacd (patch) | |
| tree | 78368c303d93ff15e7743e5cc772abd169c9049f | |
| parent | 4ba18fdfc2581a2328ab745c2707e3ed375d9e64 (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.cc | 4 | ||||
| -rw-r--r-- | runtime/openjdkjvmti/events-inl.h | 20 | ||||
| -rw-r--r-- | runtime/openjdkjvmti/events.h | 5 | ||||
| -rw-r--r-- | runtime/openjdkjvmti/object_tagging.cc | 3 | ||||
| -rw-r--r-- | runtime/openjdkjvmti/object_tagging.h | 6 | ||||
| -rw-r--r-- | test/905-object-free/expected.txt | 2 | ||||
| -rw-r--r-- | test/905-object-free/src/Main.java | 16 | ||||
| -rw-r--r-- | test/905-object-free/tracking_free.cc | 8 |
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 |