• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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