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, 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