blob: 90c40f6010467cef1b157fbd516b69aa4529116c [file] [log] [blame]
Andreas Gampe6dee92e2016-09-12 19:58:13 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_RUNTIME_OPENJDKJVMTI_OBJECT_TAGGING_H_
18#define ART_RUNTIME_OPENJDKJVMTI_OBJECT_TAGGING_H_
19
Andreas Gampee54eee12016-10-20 19:03:58 -070020#include <unordered_map>
21
Andreas Gampe6dee92e2016-09-12 19:58:13 -070022#include "base/mutex.h"
23#include "gc/system_weak.h"
24#include "gc_root-inl.h"
Andreas Gampee54eee12016-10-20 19:03:58 -070025#include "globals.h"
Andreas Gampe6dee92e2016-09-12 19:58:13 -070026#include "mirror/object.h"
27#include "thread-inl.h"
28
29namespace openjdkjvmti {
30
Andreas Gampecc13b222016-10-10 19:09:09 -070031class EventHandler;
32
Andreas Gampe6dee92e2016-09-12 19:58:13 -070033class ObjectTagTable : public art::gc::SystemWeakHolder {
34 public:
Andreas Gampecc13b222016-10-10 19:09:09 -070035 explicit ObjectTagTable(EventHandler* event_handler)
36 : art::gc::SystemWeakHolder(art::LockLevel::kAllocTrackerLock),
37 event_handler_(event_handler) {
Andreas Gampe6dee92e2016-09-12 19:58:13 -070038 }
39
40 void Add(art::mirror::Object* obj, jlong tag)
41 REQUIRES_SHARED(art::Locks::mutator_lock_)
Andreas Gampecc13b222016-10-10 19:09:09 -070042 REQUIRES(!allow_disallow_lock_);
Andreas Gampe6dee92e2016-09-12 19:58:13 -070043
Andreas Gampecc13b222016-10-10 19:09:09 -070044 bool Remove(art::mirror::Object* obj, jlong* tag)
45 REQUIRES_SHARED(art::Locks::mutator_lock_)
46 REQUIRES(!allow_disallow_lock_);
Andreas Gampe6dee92e2016-09-12 19:58:13 -070047
Andreas Gampee54d9922016-10-11 19:55:37 -070048 bool Set(art::mirror::Object* obj, jlong tag)
49 REQUIRES_SHARED(art::Locks::mutator_lock_)
50 REQUIRES(!allow_disallow_lock_);
51
Andreas Gampe6dee92e2016-09-12 19:58:13 -070052 bool GetTag(art::mirror::Object* obj, jlong* result)
53 REQUIRES_SHARED(art::Locks::mutator_lock_)
54 REQUIRES(!allow_disallow_lock_) {
55 art::Thread* self = art::Thread::Current();
56 art::MutexLock mu(self, allow_disallow_lock_);
57 Wait(self);
58
Andreas Gampee54eee12016-10-20 19:03:58 -070059 return GetTagLocked(self, obj, result);
Andreas Gampe6dee92e2016-09-12 19:58:13 -070060 }
61
Andreas Gampe6dee92e2016-09-12 19:58:13 -070062 void Sweep(art::IsMarkedVisitor* visitor)
63 REQUIRES_SHARED(art::Locks::mutator_lock_)
Andreas Gampecc13b222016-10-10 19:09:09 -070064 REQUIRES(!allow_disallow_lock_);
Andreas Gampe6dee92e2016-09-12 19:58:13 -070065
66 private:
Andreas Gampee54eee12016-10-20 19:03:58 -070067 bool SetLocked(art::Thread* self, art::mirror::Object* obj, jlong tag)
68 REQUIRES_SHARED(art::Locks::mutator_lock_)
69 REQUIRES(allow_disallow_lock_);
70
71 bool RemoveLocked(art::Thread* self, art::mirror::Object* obj, jlong* tag)
72 REQUIRES_SHARED(art::Locks::mutator_lock_)
73 REQUIRES(allow_disallow_lock_);
74
75 bool GetTagLocked(art::Thread* self, art::mirror::Object* obj, jlong* result)
76 REQUIRES_SHARED(art::Locks::mutator_lock_)
77 REQUIRES(allow_disallow_lock_) {
78 auto it = tagged_objects_.find(art::GcRoot<art::mirror::Object>(obj));
79 if (it != tagged_objects_.end()) {
80 *result = it->second;
81 return true;
82 }
83
84 if (art::kUseReadBarrier &&
85 self != nullptr &&
86 self->GetIsGcMarking()) {
87 return GetTagSlowPath(self, obj, result);
88 }
89
90 return false;
91 }
92
93 // Slow-path for GetTag. We didn't find the object, but we might be storing from-pointers and
94 // are asked to retrieve with a to-pointer.
95 bool GetTagSlowPath(art::Thread* self, art::mirror::Object* obj, jlong* result)
96 REQUIRES_SHARED(art::Locks::mutator_lock_)
97 REQUIRES(allow_disallow_lock_);
98
99 void UpdateTable()
100 REQUIRES_SHARED(art::Locks::mutator_lock_)
101 REQUIRES(allow_disallow_lock_);
Andreas Gampe6dee92e2016-09-12 19:58:13 -0700102
Andreas Gampecc13b222016-10-10 19:09:09 -0700103 template <bool kHandleNull>
104 void SweepImpl(art::IsMarkedVisitor* visitor)
Andreas Gampee54eee12016-10-20 19:03:58 -0700105 REQUIRES_SHARED(art::Locks::mutator_lock_)
106 REQUIRES(!allow_disallow_lock_);
Andreas Gampecc13b222016-10-10 19:09:09 -0700107 void HandleNullSweep(jlong tag);
Andreas Gampe6dee92e2016-09-12 19:58:13 -0700108
Andreas Gampee54eee12016-10-20 19:03:58 -0700109 enum TableUpdateNullTarget {
110 kIgnoreNull,
111 kRemoveNull,
112 kCallHandleNull
113 };
114
115 template <typename T, TableUpdateNullTarget kTargetNull>
116 void UpdateTableWith(T& updater)
117 REQUIRES_SHARED(art::Locks::mutator_lock_)
118 REQUIRES(allow_disallow_lock_);
119
120 struct HashGcRoot {
121 size_t operator()(const art::GcRoot<art::mirror::Object>& r) const
122 REQUIRES_SHARED(art::Locks::mutator_lock_) {
123 return reinterpret_cast<uintptr_t>(r.Read<art::kWithoutReadBarrier>());
124 }
125 };
126
127 struct EqGcRoot {
128 bool operator()(const art::GcRoot<art::mirror::Object>& r1,
129 const art::GcRoot<art::mirror::Object>& r2) const
130 REQUIRES_SHARED(art::Locks::mutator_lock_) {
131 return r1.Read<art::kWithoutReadBarrier>() == r2.Read<art::kWithoutReadBarrier>();
132 }
133 };
134
135 std::unordered_map<art::GcRoot<art::mirror::Object>,
136 jlong,
137 HashGcRoot,
138 EqGcRoot> tagged_objects_
139 GUARDED_BY(allow_disallow_lock_)
140 GUARDED_BY(art::Locks::mutator_lock_);
Andreas Gampecc13b222016-10-10 19:09:09 -0700141
142 EventHandler* event_handler_;
Andreas Gampe6dee92e2016-09-12 19:58:13 -0700143};
144
145} // namespace openjdkjvmti
146
147#endif // ART_RUNTIME_OPENJDKJVMTI_OBJECT_TAGGING_H_