blob: ead02eed3b7ec4dc0e7ce3bc7c08ed7571ed4f7c [file] [log] [blame]
Alex Light4f2e9572017-03-16 13:13:31 -07001/*
2 * Copyright (C) 2017 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_MIRROR_CLASS_EXT_INL_H_
18#define ART_RUNTIME_MIRROR_CLASS_EXT_INL_H_
19
20#include "class_ext.h"
21
Alex Light79d6c802019-06-27 15:50:11 +000022#include "array-inl.h"
Alex Light4f2e9572017-03-16 13:13:31 -070023#include "art_method-inl.h"
Alex Light79d6c802019-06-27 15:50:11 +000024#include "handle_scope.h"
Vladimir Markobb206de2019-03-28 10:30:32 +000025#include "object-inl.h"
Alex Light4f2e9572017-03-16 13:13:31 -070026
27namespace art {
28namespace mirror {
29
Alex Light79d6c802019-06-27 15:50:11 +000030template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
31inline ObjPtr<PointerArray> ClassExt::EnsureJniIdsArrayPresent(MemberOffset off, size_t count) {
32 ObjPtr<PointerArray> existing(
33 GetFieldObject<PointerArray, kVerifyFlags, kReadBarrierOption>(off));
34 if (!existing.IsNull()) {
35 return existing;
36 }
37 Thread* self = Thread::Current();
38 StackHandleScope<2> hs(self);
39 Handle<ClassExt> h_this(hs.NewHandle(this));
40 Handle<PointerArray> new_arr(
41 hs.NewHandle(Runtime::Current()->GetClassLinker()->AllocPointerArray(self, count)));
42 if (new_arr.IsNull()) {
43 // Fail.
44 self->AssertPendingOOMException();
45 return nullptr;
46 }
47 bool set;
48 // Set the ext_data_ field using CAS semantics.
49 if (Runtime::Current()->IsActiveTransaction()) {
50 set = h_this->CasFieldObject<true>(
51 off, nullptr, new_arr.Get(), CASMode::kStrong, std::memory_order_seq_cst);
52 } else {
53 set = h_this->CasFieldObject<false>(
54 off, nullptr, new_arr.Get(), CASMode::kStrong, std::memory_order_seq_cst);
55 }
56 ObjPtr<PointerArray> ret(
57 set ? new_arr.Get()
58 : h_this->GetFieldObject<PointerArray, kVerifyFlags, kReadBarrierOption>(off));
59 CHECK(!ret.IsNull());
60 return ret;
61}
62
63template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
64inline ObjPtr<PointerArray> ClassExt::EnsureJMethodIDsArrayPresent(size_t count) {
65 return EnsureJniIdsArrayPresent<kVerifyFlags, kReadBarrierOption>(
66 MemberOffset(OFFSET_OF_OBJECT_MEMBER(ClassExt, jmethod_ids_)), count);
67}
68template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
69inline ObjPtr<PointerArray> ClassExt::EnsureStaticJFieldIDsArrayPresent(size_t count) {
70 return EnsureJniIdsArrayPresent<kVerifyFlags, kReadBarrierOption>(
71 MemberOffset(OFFSET_OF_OBJECT_MEMBER(ClassExt, static_jfield_ids_)), count);
72}
73template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
74inline ObjPtr<PointerArray> ClassExt::EnsureInstanceJFieldIDsArrayPresent(size_t count) {
75 return EnsureJniIdsArrayPresent<kVerifyFlags, kReadBarrierOption>(
76 MemberOffset(OFFSET_OF_OBJECT_MEMBER(ClassExt, instance_jfield_ids_)), count);
77}
78
79template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
80inline ObjPtr<PointerArray> ClassExt::GetInstanceJFieldIDs() {
81 return GetFieldObject<PointerArray, kVerifyFlags, kReadBarrierOption>(
82 OFFSET_OF_OBJECT_MEMBER(ClassExt, instance_jfield_ids_));
83}
84
85template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
86inline ObjPtr<PointerArray> ClassExt::GetStaticJFieldIDs() {
87 return GetFieldObject<PointerArray, kVerifyFlags, kReadBarrierOption>(
88 OFFSET_OF_OBJECT_MEMBER(ClassExt, static_jfield_ids_));
89}
90
91template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
92inline ObjPtr<PointerArray> ClassExt::GetJMethodIDs() {
93 return GetFieldObject<PointerArray, kVerifyFlags, kReadBarrierOption>(
94 OFFSET_OF_OBJECT_MEMBER(ClassExt, jmethod_ids_));
95}
96
Vladimir Markobb206de2019-03-28 10:30:32 +000097inline ObjPtr<Object> ClassExt::GetVerifyError() {
98 return GetFieldObject<ClassExt>(OFFSET_OF_OBJECT_MEMBER(ClassExt, verify_error_));
99}
100
101inline ObjPtr<ObjectArray<DexCache>> ClassExt::GetObsoleteDexCaches() {
102 return GetFieldObject<ObjectArray<DexCache>>(
103 OFFSET_OF_OBJECT_MEMBER(ClassExt, obsolete_dex_caches_));
104}
105
106template<VerifyObjectFlags kVerifyFlags,
107 ReadBarrierOption kReadBarrierOption>
108inline ObjPtr<PointerArray> ClassExt::GetObsoleteMethods() {
109 return GetFieldObject<PointerArray, kVerifyFlags, kReadBarrierOption>(
110 OFFSET_OF_OBJECT_MEMBER(ClassExt, obsolete_methods_));
111}
112
113inline ObjPtr<Object> ClassExt::GetOriginalDexFile() {
114 return GetFieldObject<Object>(OFFSET_OF_OBJECT_MEMBER(ClassExt, original_dex_file_));
115}
116
Alex Light4f2e9572017-03-16 13:13:31 -0700117template<ReadBarrierOption kReadBarrierOption, class Visitor>
118void ClassExt::VisitNativeRoots(Visitor& visitor, PointerSize pointer_size) {
119 ObjPtr<PointerArray> arr(GetObsoleteMethods<kDefaultVerifyFlags, kReadBarrierOption>());
120 if (arr.IsNull()) {
121 return;
122 }
123 int32_t len = arr->GetLength();
124 for (int32_t i = 0; i < len; i++) {
Vladimir Marko104883b2018-11-09 17:12:23 +0000125 ArtMethod* method = arr->GetElementPtrSize<ArtMethod*, kDefaultVerifyFlags>(i, pointer_size);
Alex Light4f2e9572017-03-16 13:13:31 -0700126 if (method != nullptr) {
127 method->VisitRoots<kReadBarrierOption>(visitor, pointer_size);
128 }
129 }
130}
131
132} // namespace mirror
133} // namespace art
134
135#endif // ART_RUNTIME_MIRROR_CLASS_EXT_INL_H_