1 /*
2 * Copyright (C) 2011 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 #include "dex_cache-inl.h"
18
19 #include "art_method-inl.h"
20 #include "class_linker.h"
21 #include "gc/accounting/card_table-inl.h"
22 #include "gc/heap.h"
23 #include "linear_alloc.h"
24 #include "oat_file.h"
25 #include "object-inl.h"
26 #include "object.h"
27 #include "object_array-inl.h"
28 #include "reflective_value_visitor.h"
29 #include "runtime.h"
30 #include "runtime_globals.h"
31 #include "string.h"
32 #include "thread.h"
33 #include "write_barrier.h"
34
35 namespace art {
36 namespace mirror {
37
Initialize(const DexFile * dex_file,ObjPtr<ClassLoader> class_loader)38 void DexCache::Initialize(const DexFile* dex_file, ObjPtr<ClassLoader> class_loader) {
39 DCHECK(GetDexFile() == nullptr);
40 DCHECK(GetStrings() == nullptr);
41 DCHECK(GetResolvedTypes() == nullptr);
42 DCHECK(GetResolvedMethods() == nullptr);
43 DCHECK(GetResolvedFields() == nullptr);
44 DCHECK(GetResolvedMethodTypes() == nullptr);
45 DCHECK(GetResolvedCallSites() == nullptr);
46
47 ScopedAssertNoThreadSuspension sants(__FUNCTION__);
48
49 SetDexFile(dex_file);
50 SetClassLoader(class_loader);
51 }
52
VisitReflectiveTargets(ReflectiveValueVisitor * visitor)53 void DexCache::VisitReflectiveTargets(ReflectiveValueVisitor* visitor) {
54 bool wrote = false;
55 FieldDexCacheType* fields = GetResolvedFields();
56 size_t num_fields = NumResolvedFields();
57 // Check both the data pointer and count since the array might be initialized
58 // concurrently on other thread, and we might observe just one of the values.
59 for (size_t i = 0; fields != nullptr && i < num_fields; i++) {
60 auto pair(GetNativePair(fields, i));
61 if (pair.index == FieldDexCachePair::InvalidIndexForSlot(i)) {
62 continue;
63 }
64 ArtField* new_val = visitor->VisitField(
65 pair.object, DexCacheSourceInfo(kSourceDexCacheResolvedField, pair.index, this));
66 if (UNLIKELY(new_val != pair.object)) {
67 if (new_val == nullptr) {
68 pair = FieldDexCachePair(nullptr, FieldDexCachePair::InvalidIndexForSlot(i));
69 } else {
70 pair.object = new_val;
71 }
72 SetNativePair(fields, i, pair);
73 wrote = true;
74 }
75 }
76 MethodDexCacheType* methods = GetResolvedMethods();
77 size_t num_methods = NumResolvedMethods();
78 // Check both the data pointer and count since the array might be initialized
79 // concurrently on other thread, and we might observe just one of the values.
80 for (size_t i = 0; methods != nullptr && i < num_methods; i++) {
81 auto pair(GetNativePair(methods, i));
82 if (pair.index == MethodDexCachePair::InvalidIndexForSlot(i)) {
83 continue;
84 }
85 ArtMethod* new_val = visitor->VisitMethod(
86 pair.object, DexCacheSourceInfo(kSourceDexCacheResolvedMethod, pair.index, this));
87 if (UNLIKELY(new_val != pair.object)) {
88 if (new_val == nullptr) {
89 pair = MethodDexCachePair(nullptr, MethodDexCachePair::InvalidIndexForSlot(i));
90 } else {
91 pair.object = new_val;
92 }
93 SetNativePair(methods, i, pair);
94 wrote = true;
95 }
96 }
97 if (wrote) {
98 WriteBarrier::ForEveryFieldWrite(this);
99 }
100 }
101
ResetNativeArrays()102 void DexCache::ResetNativeArrays() {
103 SetStrings(nullptr);
104 SetResolvedTypes(nullptr);
105 SetResolvedMethods(nullptr);
106 SetResolvedFields(nullptr);
107 SetResolvedMethodTypes(nullptr);
108 SetResolvedCallSites(nullptr);
109 SetField32<false>(NumStringsOffset(), 0);
110 SetField32<false>(NumResolvedTypesOffset(), 0);
111 SetField32<false>(NumResolvedMethodsOffset(), 0);
112 SetField32<false>(NumResolvedFieldsOffset(), 0);
113 SetField32<false>(NumResolvedMethodTypesOffset(), 0);
114 SetField32<false>(NumResolvedCallSitesOffset(), 0);
115 }
116
SetLocation(ObjPtr<mirror::String> location)117 void DexCache::SetLocation(ObjPtr<mirror::String> location) {
118 SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, location_), location);
119 }
120
SetClassLoader(ObjPtr<ClassLoader> class_loader)121 void DexCache::SetClassLoader(ObjPtr<ClassLoader> class_loader) {
122 SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, class_loader_), class_loader);
123 }
124
GetClassLoader()125 ObjPtr<ClassLoader> DexCache::GetClassLoader() {
126 return GetFieldObject<ClassLoader>(OFFSET_OF_OBJECT_MEMBER(DexCache, class_loader_));
127 }
128
129 } // namespace mirror
130 } // namespace art
131