/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ART_RUNTIME_REFLECTIVE_VALUE_VISITOR_H_ #define ART_RUNTIME_REFLECTIVE_VALUE_VISITOR_H_ #include #include #include #include #include #include "android-base/macros.h" #include "base/enums.h" #include "base/globals.h" #include "base/locks.h" #include "base/macros.h" #include "base/value_object.h" #include "dex/dex_file.h" #include "jni.h" #include "mirror/dex_cache.h" #include "obj_ptr.h" namespace art { class ArtField; class ArtMethod; class BaseReflectiveHandleScope; class Thread; class ReflectionSourceInfo; class ReflectiveValueVisitor : public ValueObject { public: virtual ~ReflectiveValueVisitor() {} virtual ArtMethod* VisitMethod(ArtMethod* in, const ReflectionSourceInfo& info) REQUIRES_SHARED(Locks::mutator_lock_) = 0; virtual ArtField* VisitField(ArtField* in, const ReflectionSourceInfo& info) REQUIRES_SHARED(Locks::mutator_lock_) = 0; // Give it an entrypoint through operator() to interact with things that expect lambda-like things template || std::is_same_v>> T* operator()(T* t, const ReflectionSourceInfo& info) REQUIRES_SHARED(Locks::mutator_lock_) { if constexpr (std::is_same_v) { return VisitField(t, info); } else { static_assert(std::is_same_v, "Expected ArtField or ArtMethod"); return VisitMethod(t, info); } } }; template class FunctionReflectiveValueVisitor : public ReflectiveValueVisitor { public: FunctionReflectiveValueVisitor(FieldVis fv, MethodVis mv) : fv_(fv), mv_(mv) {} ArtField* VisitField(ArtField* in, const ReflectionSourceInfo& info) override REQUIRES(Locks::mutator_lock_) { return fv_(in, info); } ArtMethod* VisitMethod(ArtMethod* in, const ReflectionSourceInfo& info) override REQUIRES(Locks::mutator_lock_) { return mv_(in, info); } private: FieldVis fv_; MethodVis mv_; }; enum ReflectionSourceType { kSourceUnknown = 0, kSourceJavaLangReflectExecutable, kSourceJavaLangReflectField, kSourceJavaLangInvokeMethodHandle, kSourceJavaLangInvokeFieldVarHandle, kSourceThreadHandleScope, kSourceJniFieldId, kSourceJniMethodId, kSourceDexCacheResolvedMethod, kSourceDexCacheResolvedField, kSourceMiscInternal, }; std::ostream& operator<<(std::ostream& os, ReflectionSourceType type); class ReflectionSourceInfo : public ValueObject { public: virtual ~ReflectionSourceInfo() {} // Thread id 0 is for non thread roots. explicit ReflectionSourceInfo(ReflectionSourceType type) : type_(type) {} virtual void Describe(std::ostream& os) const { os << "Type=" << type_; } ReflectionSourceType GetType() const { return type_; } private: const ReflectionSourceType type_; DISALLOW_COPY_AND_ASSIGN(ReflectionSourceInfo); }; inline std::ostream& operator<<(std::ostream& os, const ReflectionSourceInfo& info) { info.Describe(os); return os; } class ReflectiveHandleScopeSourceInfo : public ReflectionSourceInfo { public: explicit ReflectiveHandleScopeSourceInfo(BaseReflectiveHandleScope* source) : ReflectionSourceInfo(kSourceThreadHandleScope), source_(source) {} void Describe(std::ostream& os) const override; private: BaseReflectiveHandleScope* source_; }; // TODO Maybe give this the ability to retrieve the type and ref, if it's useful. class HeapReflectiveSourceInfo : public ReflectionSourceInfo { public: HeapReflectiveSourceInfo(ReflectionSourceType t, mirror::Object* src) : ReflectionSourceInfo(t), src_(src) {} void Describe(std::ostream& os) const override; private: ObjPtr src_; }; // TODO Maybe give this the ability to retrieve the id if it's useful. template || std::is_same_v>> class JniIdReflectiveSourceInfo : public ReflectionSourceInfo { public: explicit JniIdReflectiveSourceInfo(T id) : ReflectionSourceInfo(std::is_same_v ? kSourceJniMethodId : kSourceJniFieldId), id_(id) {} void Describe(std::ostream& os) const override; private: T id_; }; class DexCacheSourceInfo : public ReflectionSourceInfo { public: explicit DexCacheSourceInfo(ReflectionSourceType type, size_t index, ObjPtr cache) : ReflectionSourceInfo(type), index_(index), cache_(cache) {} void Describe(std::ostream& os) const override REQUIRES(Locks::mutator_lock_) { ReflectionSourceInfo::Describe(os); os << " index=" << index_ << " cache_=" << cache_.PtrUnchecked() << " files=" << *cache_->GetDexFile(); } private: size_t index_; ObjPtr cache_; }; } // namespace art #endif // ART_RUNTIME_REFLECTIVE_VALUE_VISITOR_H_