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#ifndef ART_RUNTIME_CLASS_LINKER_INL_H_
18#define ART_RUNTIME_CLASS_LINKER_INL_H_
19
20#include "class_linker.h"
21
22#include "mirror/art_field.h"
23#include "mirror/dex_cache.h"
24#include "mirror/iftable.h"
25#include "mirror/object_array.h"
26
27namespace art {
28
29inline mirror::String* ClassLinker::ResolveString(uint32_t string_idx,
30                                           const mirror::ArtMethod* referrer) {
31  mirror::String* resolved_string = referrer->GetDexCacheStrings()->Get(string_idx);
32  if (UNLIKELY(resolved_string == NULL)) {
33    mirror::Class* declaring_class = referrer->GetDeclaringClass();
34    mirror::DexCache* dex_cache = declaring_class->GetDexCache();
35    const DexFile& dex_file = *dex_cache->GetDexFile();
36    resolved_string = ResolveString(dex_file, string_idx, dex_cache);
37  }
38  return resolved_string;
39}
40
41inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx,
42                                               const mirror::ArtMethod* referrer) {
43  mirror::Class* resolved_type = referrer->GetDexCacheResolvedTypes()->Get(type_idx);
44  if (UNLIKELY(resolved_type == NULL)) {
45    mirror::Class* declaring_class = referrer->GetDeclaringClass();
46    mirror::DexCache* dex_cache = declaring_class->GetDexCache();
47    mirror::ClassLoader* class_loader = declaring_class->GetClassLoader();
48    const DexFile& dex_file = *dex_cache->GetDexFile();
49    resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader);
50  }
51  return resolved_type;
52}
53
54inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, const mirror::ArtField* referrer) {
55  mirror::Class* declaring_class = referrer->GetDeclaringClass();
56  mirror::DexCache* dex_cache = declaring_class->GetDexCache();
57  mirror::Class* resolved_type = dex_cache->GetResolvedType(type_idx);
58  if (UNLIKELY(resolved_type == NULL)) {
59    mirror::ClassLoader* class_loader = declaring_class->GetClassLoader();
60    const DexFile& dex_file = *dex_cache->GetDexFile();
61    resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader);
62  }
63  return resolved_type;
64}
65
66inline mirror::ArtMethod* ClassLinker::ResolveMethod(uint32_t method_idx,
67                                                     const mirror::ArtMethod* referrer,
68                                                     InvokeType type) {
69  mirror::ArtMethod* resolved_method =
70      referrer->GetDexCacheResolvedMethods()->Get(method_idx);
71  if (UNLIKELY(resolved_method == NULL || resolved_method->IsRuntimeMethod())) {
72    mirror::Class* declaring_class = referrer->GetDeclaringClass();
73    mirror::DexCache* dex_cache = declaring_class->GetDexCache();
74    mirror::ClassLoader* class_loader = declaring_class->GetClassLoader();
75    const DexFile& dex_file = *dex_cache->GetDexFile();
76    resolved_method = ResolveMethod(dex_file, method_idx, dex_cache, class_loader, referrer, type);
77  }
78  return resolved_method;
79}
80
81inline mirror::ArtField* ClassLinker::ResolveField(uint32_t field_idx,
82                                                   const mirror::ArtMethod* referrer,
83                                                   bool is_static) {
84  mirror::ArtField* resolved_field =
85      referrer->GetDeclaringClass()->GetDexCache()->GetResolvedField(field_idx);
86  if (UNLIKELY(resolved_field == NULL)) {
87    mirror::Class* declaring_class = referrer->GetDeclaringClass();
88    mirror::DexCache* dex_cache = declaring_class->GetDexCache();
89    mirror::ClassLoader* class_loader = declaring_class->GetClassLoader();
90    const DexFile& dex_file = *dex_cache->GetDexFile();
91    resolved_field = ResolveField(dex_file, field_idx, dex_cache, class_loader, is_static);
92  }
93  return resolved_field;
94}
95
96template <class T>
97inline mirror::ObjectArray<T>* ClassLinker::AllocObjectArray(Thread* self, size_t length) {
98  return mirror::ObjectArray<T>::Alloc(self, GetClassRoot(kObjectArrayClass), length);
99}
100
101inline mirror::ObjectArray<mirror::Class>* ClassLinker::AllocClassArray(Thread* self,
102                                                                        size_t length) {
103  return mirror::ObjectArray<mirror::Class>::Alloc(self, GetClassRoot(kClassArrayClass), length);
104}
105
106inline mirror::ObjectArray<mirror::String>* ClassLinker::AllocStringArray(Thread* self,
107                                                                          size_t length) {
108  return mirror::ObjectArray<mirror::String>::Alloc(self, GetClassRoot(kJavaLangStringArrayClass),
109                                                    length);
110}
111
112inline mirror::ObjectArray<mirror::ArtMethod>* ClassLinker::AllocArtMethodArray(Thread* self,
113                                                                                size_t length) {
114  return mirror::ObjectArray<mirror::ArtMethod>::Alloc(self,
115      GetClassRoot(kJavaLangReflectArtMethodArrayClass), length);
116}
117
118inline mirror::IfTable* ClassLinker::AllocIfTable(Thread* self, size_t ifcount) {
119  return down_cast<mirror::IfTable*>(
120      mirror::IfTable::Alloc(self, GetClassRoot(kObjectArrayClass), ifcount * mirror::IfTable::kMax));
121}
122
123inline mirror::ObjectArray<mirror::ArtField>* ClassLinker::AllocArtFieldArray(Thread* self,
124                                                                              size_t length) {
125  return mirror::ObjectArray<mirror::ArtField>::Alloc(self,
126                                                      GetClassRoot(kJavaLangReflectArtFieldArrayClass),
127                                                      length);
128}
129
130inline mirror::Class* ClassLinker::GetClassRoot(ClassRoot class_root)
131    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
132  DCHECK(class_roots_ != NULL);
133  mirror::Class* klass = class_roots_->Get(class_root);
134  DCHECK(klass != NULL);
135  return klass;
136}
137
138}  // namespace art
139
140#endif  // ART_RUNTIME_CLASS_LINKER_INL_H_
141