blob: 3a727603454c9c96fce804b9e569182ccc5e94d7 [file] [log] [blame]
Alex Lightc18eba32019-09-24 14:36:27 -07001/*
2 * Copyright (C) 2019 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_REFLECTIVE_VALUE_VISITOR_H_
18#define ART_RUNTIME_REFLECTIVE_VALUE_VISITOR_H_
19
20#include <android-base/logging.h>
21
22#include <array>
23#include <compare>
24#include <functional>
25#include <stack>
26
27#include "android-base/macros.h"
28#include "base/enums.h"
29#include "base/globals.h"
30#include "base/locks.h"
31#include "base/macros.h"
32#include "base/value_object.h"
33#include "dex/dex_file.h"
34#include "jni.h"
35#include "mirror/dex_cache.h"
36#include "obj_ptr.h"
37
38namespace art {
39
40class ArtField;
41class ArtMethod;
42class BaseReflectiveHandleScope;
43class Thread;
44
45class ReflectionSourceInfo;
46
47class ReflectiveValueVisitor : public ValueObject {
48 public:
49 virtual ~ReflectiveValueVisitor() {}
50
51 virtual ArtMethod* VisitMethod(ArtMethod* in, const ReflectionSourceInfo& info)
52 REQUIRES_SHARED(Locks::mutator_lock_) = 0;
53 virtual ArtField* VisitField(ArtField* in, const ReflectionSourceInfo& info)
54 REQUIRES_SHARED(Locks::mutator_lock_) = 0;
55
56 // Give it an entrypoint through operator() to interact with things that expect lambda-like things
57 template <typename T,
58 typename = typename std::enable_if<std::is_same_v<T, ArtField> ||
59 std::is_same_v<T, ArtMethod>>>
60 T* operator()(T* t, const ReflectionSourceInfo& info) REQUIRES_SHARED(Locks::mutator_lock_) {
61 if constexpr (std::is_same_v<T, ArtField>) {
62 return VisitField(t, info);
63 } else {
64 static_assert(std::is_same_v<T, ArtMethod>, "Expected ArtField or ArtMethod");
65 return VisitMethod(t, info);
66 }
67 }
68};
69
70template <typename FieldVis, typename MethodVis>
71class FunctionReflectiveValueVisitor : public ReflectiveValueVisitor {
72 public:
73 FunctionReflectiveValueVisitor(FieldVis fv, MethodVis mv) : fv_(fv), mv_(mv) {}
74 ArtField* VisitField(ArtField* in, const ReflectionSourceInfo& info) override
75 REQUIRES(Locks::mutator_lock_) {
76 return fv_(in, info);
77 }
78 ArtMethod* VisitMethod(ArtMethod* in, const ReflectionSourceInfo& info) override
79 REQUIRES(Locks::mutator_lock_) {
80 return mv_(in, info);
81 }
82
83 private:
84 FieldVis fv_;
85 MethodVis mv_;
86};
87
88enum ReflectionSourceType {
89 kSourceUnknown = 0,
90 kSourceJavaLangReflectExecutable,
91 kSourceJavaLangReflectField,
92 kSourceJavaLangInvokeMethodHandle,
93 kSourceJavaLangInvokeFieldVarHandle,
94 kSourceThreadHandleScope,
95 kSourceJniFieldId,
96 kSourceJniMethodId,
97 kSourceDexCacheResolvedMethod,
98 kSourceDexCacheResolvedField,
99 kSourceMiscInternal,
100};
101std::ostream& operator<<(std::ostream& os, const ReflectionSourceType& type);
102
103class ReflectionSourceInfo : public ValueObject {
104 public:
105 virtual ~ReflectionSourceInfo() {}
106 // Thread id 0 is for non thread roots.
107 explicit ReflectionSourceInfo(ReflectionSourceType type) : type_(type) {}
108 virtual void Describe(std::ostream& os) const {
109 os << "Type=" << type_;
110 }
111
Alex Light24627892019-11-06 10:28:21 -0800112 ReflectionSourceType GetType() const {
113 return type_;
114 }
115
Alex Lightc18eba32019-09-24 14:36:27 -0700116 private:
117 const ReflectionSourceType type_;
118
119 DISALLOW_COPY_AND_ASSIGN(ReflectionSourceInfo);
120};
121inline std::ostream& operator<<(std::ostream& os, const ReflectionSourceInfo& info) {
122 info.Describe(os);
123 return os;
124}
125
126class ReflectiveHandleScopeSourceInfo : public ReflectionSourceInfo {
127 public:
128 explicit ReflectiveHandleScopeSourceInfo(BaseReflectiveHandleScope* source)
129 : ReflectionSourceInfo(kSourceThreadHandleScope), source_(source) {}
130
Alex Light55eccdf2019-10-07 13:51:13 +0000131 void Describe(std::ostream& os) const override;
Alex Lightc18eba32019-09-24 14:36:27 -0700132
133 private:
134 BaseReflectiveHandleScope* source_;
135};
136
137// TODO Maybe give this the ability to retrieve the type and ref, if it's useful.
138class HeapReflectiveSourceInfo : public ReflectionSourceInfo {
139 public:
140 HeapReflectiveSourceInfo(ReflectionSourceType t, mirror::Object* src)
141 : ReflectionSourceInfo(t), src_(src) {}
142 void Describe(std::ostream& os) const override;
143
144 private:
145 ObjPtr<mirror::Object> src_;
146};
147
148// TODO Maybe give this the ability to retrieve the id if it's useful.
149template <typename T,
150 typename = typename std::enable_if_t<std::is_same_v<T, jmethodID> ||
151 std::is_same_v<T, jfieldID>>>
152class JniIdReflectiveSourceInfo : public ReflectionSourceInfo {
153 public:
154 explicit JniIdReflectiveSourceInfo(T id)
155 : ReflectionSourceInfo(std::is_same_v<T, jmethodID> ? kSourceJniMethodId : kSourceJniFieldId),
156 id_(id) {}
157 void Describe(std::ostream& os) const override;
158
159 private:
160 T id_;
161};
162
163class DexCacheSourceInfo : public ReflectionSourceInfo {
164 public:
165 explicit DexCacheSourceInfo(ReflectionSourceType type,
166 size_t index,
167 ObjPtr<mirror::DexCache> cache)
168 : ReflectionSourceInfo(type), index_(index), cache_(cache) {}
169
170 void Describe(std::ostream& os) const override REQUIRES(Locks::mutator_lock_) {
171 ReflectionSourceInfo::Describe(os);
172 os << " index=" << index_ << " cache_=" << cache_.PtrUnchecked()
173 << " files=" << *cache_->GetDexFile();
174 }
175
176 private:
177 size_t index_;
178 ObjPtr<mirror::DexCache> cache_;
179};
180} // namespace art
181
182#endif // ART_RUNTIME_REFLECTIVE_VALUE_VISITOR_H_