From 21d5994583c679cd5d8573b5d35dbd659bdca2c7 Mon Sep 17 00:00:00 2001 From: Alex Light Date: Wed, 19 Jun 2019 12:58:22 -0700 Subject: Support using opaque JNI ids Currently JNI ids (jmethodID & jfieldID) are created by simply casting the corresponding ART structure pointer. This is great for simplicity but means we are prevented from performing operations that could change these pointer values. To support these use-cases add support for loading the runtime with a layer of indirection between these ids and the internal art data types. Currently the JNI id type can be toggled only by passing the new '-Xopaque-jni-ids:{true,false}' flag during startup. This changes the --debuggable test configuration to pass '-Xopaque-jni-ids:true' in order to get test coverage of this feature using the 'art-jit' configuration. Test: ./test.py --host --debuggable Test: ./test.py --host --debuggable --jit-on-first-use Test: ./test/testrunnner/run_build_test_target.py art-jit Bug: 134162467 Change-Id: Id8c8cb9a5b8ff18dc2f40892fae2d344a7214f44 --- runtime/mirror/class_ext-inl.h | 69 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'runtime/mirror/class_ext-inl.h') diff --git a/runtime/mirror/class_ext-inl.h b/runtime/mirror/class_ext-inl.h index bf51654447..ead02eed3b 100644 --- a/runtime/mirror/class_ext-inl.h +++ b/runtime/mirror/class_ext-inl.h @@ -19,12 +19,81 @@ #include "class_ext.h" +#include "array-inl.h" #include "art_method-inl.h" +#include "handle_scope.h" #include "object-inl.h" namespace art { namespace mirror { +template +inline ObjPtr ClassExt::EnsureJniIdsArrayPresent(MemberOffset off, size_t count) { + ObjPtr existing( + GetFieldObject(off)); + if (!existing.IsNull()) { + return existing; + } + Thread* self = Thread::Current(); + StackHandleScope<2> hs(self); + Handle h_this(hs.NewHandle(this)); + Handle new_arr( + hs.NewHandle(Runtime::Current()->GetClassLinker()->AllocPointerArray(self, count))); + if (new_arr.IsNull()) { + // Fail. + self->AssertPendingOOMException(); + return nullptr; + } + bool set; + // Set the ext_data_ field using CAS semantics. + if (Runtime::Current()->IsActiveTransaction()) { + set = h_this->CasFieldObject( + off, nullptr, new_arr.Get(), CASMode::kStrong, std::memory_order_seq_cst); + } else { + set = h_this->CasFieldObject( + off, nullptr, new_arr.Get(), CASMode::kStrong, std::memory_order_seq_cst); + } + ObjPtr ret( + set ? new_arr.Get() + : h_this->GetFieldObject(off)); + CHECK(!ret.IsNull()); + return ret; +} + +template +inline ObjPtr ClassExt::EnsureJMethodIDsArrayPresent(size_t count) { + return EnsureJniIdsArrayPresent( + MemberOffset(OFFSET_OF_OBJECT_MEMBER(ClassExt, jmethod_ids_)), count); +} +template +inline ObjPtr ClassExt::EnsureStaticJFieldIDsArrayPresent(size_t count) { + return EnsureJniIdsArrayPresent( + MemberOffset(OFFSET_OF_OBJECT_MEMBER(ClassExt, static_jfield_ids_)), count); +} +template +inline ObjPtr ClassExt::EnsureInstanceJFieldIDsArrayPresent(size_t count) { + return EnsureJniIdsArrayPresent( + MemberOffset(OFFSET_OF_OBJECT_MEMBER(ClassExt, instance_jfield_ids_)), count); +} + +template +inline ObjPtr ClassExt::GetInstanceJFieldIDs() { + return GetFieldObject( + OFFSET_OF_OBJECT_MEMBER(ClassExt, instance_jfield_ids_)); +} + +template +inline ObjPtr ClassExt::GetStaticJFieldIDs() { + return GetFieldObject( + OFFSET_OF_OBJECT_MEMBER(ClassExt, static_jfield_ids_)); +} + +template +inline ObjPtr ClassExt::GetJMethodIDs() { + return GetFieldObject( + OFFSET_OF_OBJECT_MEMBER(ClassExt, jmethod_ids_)); +} + inline ObjPtr ClassExt::GetVerifyError() { return GetFieldObject(OFFSET_OF_OBJECT_MEMBER(ClassExt, verify_error_)); } -- cgit v1.2.3-59-g8ed1b