1 /*
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 
38 namespace art {
39 
40 class ArtField;
41 class ArtMethod;
42 class BaseReflectiveHandleScope;
43 class Thread;
44 
45 class ReflectionSourceInfo;
46 
47 class ReflectiveValueVisitor : public ValueObject {
48  public:
~ReflectiveValueVisitor()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>>>
operator()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 
70 template <typename FieldVis, typename MethodVis>
71 class FunctionReflectiveValueVisitor : public ReflectiveValueVisitor {
72  public:
FunctionReflectiveValueVisitor(FieldVis fv,MethodVis mv)73   FunctionReflectiveValueVisitor(FieldVis fv, MethodVis mv) : fv_(fv), mv_(mv) {}
VisitField(ArtField * in,const ReflectionSourceInfo & info)74   ArtField* VisitField(ArtField* in, const ReflectionSourceInfo& info) override
75       REQUIRES(Locks::mutator_lock_) {
76     return fv_(in, info);
77   }
VisitMethod(ArtMethod * in,const ReflectionSourceInfo & info)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 
88 enum 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 };
101 std::ostream& operator<<(std::ostream& os, const ReflectionSourceType& type);
102 
103 class ReflectionSourceInfo : public ValueObject {
104  public:
~ReflectionSourceInfo()105   virtual ~ReflectionSourceInfo() {}
106   // Thread id 0 is for non thread roots.
ReflectionSourceInfo(ReflectionSourceType type)107   explicit ReflectionSourceInfo(ReflectionSourceType type) : type_(type) {}
Describe(std::ostream & os)108   virtual void Describe(std::ostream& os) const {
109     os << "Type=" << type_;
110   }
111 
GetType()112   ReflectionSourceType GetType() const {
113     return type_;
114   }
115 
116  private:
117   const ReflectionSourceType type_;
118 
119   DISALLOW_COPY_AND_ASSIGN(ReflectionSourceInfo);
120 };
121 inline std::ostream& operator<<(std::ostream& os, const ReflectionSourceInfo& info) {
122   info.Describe(os);
123   return os;
124 }
125 
126 class ReflectiveHandleScopeSourceInfo : public ReflectionSourceInfo {
127  public:
ReflectiveHandleScopeSourceInfo(BaseReflectiveHandleScope * source)128   explicit ReflectiveHandleScopeSourceInfo(BaseReflectiveHandleScope* source)
129       : ReflectionSourceInfo(kSourceThreadHandleScope), source_(source) {}
130 
131   void Describe(std::ostream& os) const override;
132 
133  private:
134   BaseReflectiveHandleScope* source_;
135 };
136 
137 // TODO Maybe give this the ability to retrieve the type and ref, if it's useful.
138 class HeapReflectiveSourceInfo : public ReflectionSourceInfo {
139  public:
HeapReflectiveSourceInfo(ReflectionSourceType t,mirror::Object * src)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.
149 template <typename T,
150           typename = typename std::enable_if_t<std::is_same_v<T, jmethodID> ||
151                                                std::is_same_v<T, jfieldID>>>
152 class JniIdReflectiveSourceInfo : public ReflectionSourceInfo {
153  public:
JniIdReflectiveSourceInfo(T id)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 
163 class DexCacheSourceInfo : public ReflectionSourceInfo {
164  public:
DexCacheSourceInfo(ReflectionSourceType type,size_t index,ObjPtr<mirror::DexCache> cache)165   explicit DexCacheSourceInfo(ReflectionSourceType type,
166                               size_t index,
167                               ObjPtr<mirror::DexCache> cache)
168       : ReflectionSourceInfo(type), index_(index), cache_(cache) {}
169 
Describe(std::ostream & os)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_
183