OSDN Git Service

Merge "Remove testing of prebuilt npic boot images."
[android-x86/art.git] / runtime / mirror / dex_cache.cc
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 "base/logging.h"
21 #include "class_linker.h"
22 #include "gc/accounting/card_table-inl.h"
23 #include "gc/heap.h"
24 #include "globals.h"
25 #include "linear_alloc.h"
26 #include "object.h"
27 #include "object-inl.h"
28 #include "object_array-inl.h"
29 #include "runtime.h"
30 #include "string.h"
31 #include "thread.h"
32 #include "utils/dex_cache_arrays_layout-inl.h"
33
34 namespace art {
35 namespace mirror {
36
37 void DexCache::InitializeDexCache(Thread* self,
38                                   ObjPtr<mirror::DexCache> dex_cache,
39                                   ObjPtr<mirror::String> location,
40                                   const DexFile* dex_file,
41                                   LinearAlloc* linear_alloc,
42                                   PointerSize image_pointer_size) {
43   DCHECK(dex_file != nullptr);
44   ScopedAssertNoThreadSuspension sants(__FUNCTION__);
45   DexCacheArraysLayout layout(image_pointer_size, dex_file);
46   uint8_t* raw_arrays = nullptr;
47
48   const OatDexFile* const oat_dex = dex_file->GetOatDexFile();
49   if (oat_dex != nullptr && oat_dex->GetDexCacheArrays() != nullptr) {
50     raw_arrays = oat_dex->GetDexCacheArrays();
51   } else if (dex_file->NumStringIds() != 0u ||
52              dex_file->NumTypeIds() != 0u ||
53              dex_file->NumMethodIds() != 0u ||
54              dex_file->NumFieldIds() != 0u) {
55     // Zero-initialized.
56     raw_arrays = reinterpret_cast<uint8_t*>(linear_alloc->Alloc(self, layout.Size()));
57   }
58
59   mirror::StringDexCacheType* strings = (dex_file->NumStringIds() == 0u) ? nullptr :
60       reinterpret_cast<mirror::StringDexCacheType*>(raw_arrays + layout.StringsOffset());
61   mirror::TypeDexCacheType* types = (dex_file->NumTypeIds() == 0u) ? nullptr :
62       reinterpret_cast<mirror::TypeDexCacheType*>(raw_arrays + layout.TypesOffset());
63   ArtMethod** methods = (dex_file->NumMethodIds() == 0u) ? nullptr :
64       reinterpret_cast<ArtMethod**>(raw_arrays + layout.MethodsOffset());
65   ArtField** fields = (dex_file->NumFieldIds() == 0u) ? nullptr :
66       reinterpret_cast<ArtField**>(raw_arrays + layout.FieldsOffset());
67
68   size_t num_strings = mirror::DexCache::kDexCacheStringCacheSize;
69   if (dex_file->NumStringIds() < num_strings) {
70     num_strings = dex_file->NumStringIds();
71   }
72   size_t num_types = mirror::DexCache::kDexCacheTypeCacheSize;
73   if (dex_file->NumTypeIds() < num_types) {
74     num_types = dex_file->NumTypeIds();
75   }
76
77   // Note that we allocate the method type dex caches regardless of this flag,
78   // and we make sure here that they're not used by the runtime. This is in the
79   // interest of simplicity and to avoid extensive compiler and layout class changes.
80   //
81   // If this needs to be mitigated in a production system running this code,
82   // DexCache::kDexCacheMethodTypeCacheSize can be set to zero.
83   mirror::MethodTypeDexCacheType* method_types = nullptr;
84   size_t num_method_types = 0;
85
86   if (dex_file->NumProtoIds() < mirror::DexCache::kDexCacheMethodTypeCacheSize) {
87     num_method_types = dex_file->NumProtoIds();
88   } else {
89     num_method_types = mirror::DexCache::kDexCacheMethodTypeCacheSize;
90   }
91
92   if (num_method_types > 0) {
93     method_types = reinterpret_cast<mirror::MethodTypeDexCacheType*>(
94         raw_arrays + layout.MethodTypesOffset());
95   }
96
97   GcRoot<mirror::CallSite>* call_sites = (dex_file->NumCallSiteIds() == 0)
98       ? nullptr
99       : reinterpret_cast<GcRoot<mirror::CallSite>*>(raw_arrays + layout.CallSitesOffset());
100
101   DCHECK_ALIGNED(raw_arrays, alignof(mirror::StringDexCacheType)) <<
102                  "Expected raw_arrays to align to StringDexCacheType.";
103   DCHECK_ALIGNED(layout.StringsOffset(), alignof(mirror::StringDexCacheType)) <<
104                  "Expected StringsOffset() to align to StringDexCacheType.";
105   DCHECK_ALIGNED(strings, alignof(mirror::StringDexCacheType)) <<
106                  "Expected strings to align to StringDexCacheType.";
107   static_assert(alignof(mirror::StringDexCacheType) == 8u,
108                 "Expected StringDexCacheType to have align of 8.");
109   if (kIsDebugBuild) {
110     // Sanity check to make sure all the dex cache arrays are empty. b/28992179
111     for (size_t i = 0; i < num_strings; ++i) {
112       CHECK_EQ(strings[i].load(std::memory_order_relaxed).index, 0u);
113       CHECK(strings[i].load(std::memory_order_relaxed).object.IsNull());
114     }
115     for (size_t i = 0; i < num_types; ++i) {
116       CHECK_EQ(types[i].load(std::memory_order_relaxed).index, 0u);
117       CHECK(types[i].load(std::memory_order_relaxed).object.IsNull());
118     }
119     for (size_t i = 0; i < dex_file->NumMethodIds(); ++i) {
120       CHECK(mirror::DexCache::GetElementPtrSize(methods, i, image_pointer_size) == nullptr);
121     }
122     for (size_t i = 0; i < dex_file->NumFieldIds(); ++i) {
123       CHECK(mirror::DexCache::GetElementPtrSize(fields, i, image_pointer_size) == nullptr);
124     }
125     for (size_t i = 0; i < num_method_types; ++i) {
126       CHECK_EQ(method_types[i].load(std::memory_order_relaxed).index, 0u);
127       CHECK(method_types[i].load(std::memory_order_relaxed).object.IsNull());
128     }
129     for (size_t i = 0; i < dex_file->NumCallSiteIds(); ++i) {
130       CHECK(call_sites[i].IsNull());
131     }
132   }
133   if (strings != nullptr) {
134     mirror::StringDexCachePair::Initialize(strings);
135   }
136   if (types != nullptr) {
137     mirror::TypeDexCachePair::Initialize(types);
138   }
139   if (method_types != nullptr) {
140     mirror::MethodTypeDexCachePair::Initialize(method_types);
141   }
142   dex_cache->Init(dex_file,
143                   location,
144                   strings,
145                   num_strings,
146                   types,
147                   num_types,
148                   methods,
149                   dex_file->NumMethodIds(),
150                   fields,
151                   dex_file->NumFieldIds(),
152                   method_types,
153                   num_method_types,
154                   call_sites,
155                   dex_file->NumCallSiteIds(),
156                   image_pointer_size);
157 }
158
159 void DexCache::Init(const DexFile* dex_file,
160                     ObjPtr<String> location,
161                     StringDexCacheType* strings,
162                     uint32_t num_strings,
163                     TypeDexCacheType* resolved_types,
164                     uint32_t num_resolved_types,
165                     ArtMethod** resolved_methods,
166                     uint32_t num_resolved_methods,
167                     ArtField** resolved_fields,
168                     uint32_t num_resolved_fields,
169                     MethodTypeDexCacheType* resolved_method_types,
170                     uint32_t num_resolved_method_types,
171                     GcRoot<CallSite>* resolved_call_sites,
172                     uint32_t num_resolved_call_sites,
173                     PointerSize pointer_size) {
174   CHECK(dex_file != nullptr);
175   CHECK(location != nullptr);
176   CHECK_EQ(num_strings != 0u, strings != nullptr);
177   CHECK_EQ(num_resolved_types != 0u, resolved_types != nullptr);
178   CHECK_EQ(num_resolved_methods != 0u, resolved_methods != nullptr);
179   CHECK_EQ(num_resolved_fields != 0u, resolved_fields != nullptr);
180   CHECK_EQ(num_resolved_method_types != 0u, resolved_method_types != nullptr);
181   CHECK_EQ(num_resolved_call_sites != 0u, resolved_call_sites != nullptr);
182
183   SetDexFile(dex_file);
184   SetLocation(location);
185   SetStrings(strings);
186   SetResolvedTypes(resolved_types);
187   SetResolvedMethods(resolved_methods);
188   SetResolvedFields(resolved_fields);
189   SetResolvedMethodTypes(resolved_method_types);
190   SetResolvedCallSites(resolved_call_sites);
191   SetField32<false>(NumStringsOffset(), num_strings);
192   SetField32<false>(NumResolvedTypesOffset(), num_resolved_types);
193   SetField32<false>(NumResolvedMethodsOffset(), num_resolved_methods);
194   SetField32<false>(NumResolvedFieldsOffset(), num_resolved_fields);
195   SetField32<false>(NumResolvedMethodTypesOffset(), num_resolved_method_types);
196   SetField32<false>(NumResolvedCallSitesOffset(), num_resolved_call_sites);
197
198   Runtime* const runtime = Runtime::Current();
199   if (runtime->HasResolutionMethod()) {
200     // Initialize the resolve methods array to contain trampolines for resolution.
201     Fixup(runtime->GetResolutionMethod(), pointer_size);
202   }
203 }
204
205 void DexCache::Fixup(ArtMethod* trampoline, PointerSize pointer_size) {
206   // Fixup the resolve methods array to contain trampoline for resolution.
207   CHECK(trampoline != nullptr);
208   CHECK(trampoline->IsRuntimeMethod());
209   auto* resolved_methods = GetResolvedMethods();
210   for (size_t i = 0, length = NumResolvedMethods(); i < length; i++) {
211     if (GetElementPtrSize<ArtMethod*>(resolved_methods, i, pointer_size) == nullptr) {
212       SetElementPtrSize(resolved_methods, i, trampoline, pointer_size);
213     }
214   }
215 }
216
217 void DexCache::SetLocation(ObjPtr<mirror::String> location) {
218   SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, location_), location);
219 }
220
221 }  // namespace mirror
222 }  // namespace art