compiler_driver-inl.h revision 8d6768d47b66a688d35399d524ad5a5450e9d9d4
13a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald/*
219690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou * Copyright (C) 2012 The Android Open Source Project
386821b2563915e4f11cde045da8ebe01beffa634Tim Peters *
419690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou * Licensed under the Apache License, Version 2.0 (the "License");
519690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou * you may not use this file except in compliance with the License.
686821b2563915e4f11cde045da8ebe01beffa634Tim Peters * You may obtain a copy of the License at
719690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou *
819690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou *      http://www.apache.org/licenses/LICENSE-2.0
919690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou *
1019690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou * Unless required by applicable law or agreed to in writing, software
1119690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou * distributed under the License is distributed on an "AS IS" BASIS,
1219690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald * See the License for the specific language governing permissions and
143a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald * limitations under the License.
153a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald */
163a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald
173a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#ifndef ART_COMPILER_DRIVER_COMPILER_DRIVER_INL_H_
183a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#define ART_COMPILER_DRIVER_COMPILER_DRIVER_INL_H_
1992abad24d68823dc3c334d05b7bc5375db049b7bNeal Norwitz
2019690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou#include "compiler_driver.h"
2192abad24d68823dc3c334d05b7bc5375db049b7bNeal Norwitz
223a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#include "art_field-inl.h"
233a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#include "art_method-inl.h"
2419690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou#include "base/enums.h"
253a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#include "class_linker-inl.h"
263a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#include "dex_compilation_unit.h"
273a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#include "mirror/class_loader.h"
2819690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou#include "mirror/dex_cache-inl.h"
293a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#include "scoped_thread_state_change-inl.h"
303a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald#include "handle_scope-inl.h"
3119690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou
323a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwaldnamespace art {
3319690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou
343a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwaldinline mirror::Class* CompilerDriver::ResolveClass(
353a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald    const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
363a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald    Handle<mirror::ClassLoader> class_loader, dex::TypeIndex cls_index,
37ea4d2875ac5dc83864a8313d6252e56295598070Serhiy Storchaka    const DexCompilationUnit* mUnit) {
383a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald  DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile());
393a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald  DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get());
4019690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou  mirror::Class* cls = mUnit->GetClassLinker()->ResolveType(
41abd8a336a3ab390a2ea4b15a0ecd187e482001afTim Peters      *mUnit->GetDexFile(), cls_index, dex_cache, class_loader);
423a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald  DCHECK_EQ(cls == nullptr, soa.Self()->IsExceptionPending());
433a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald  if (UNLIKELY(cls == nullptr)) {
443a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald    // Clean up any exception left by type resolution.
453a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald    soa.Self()->ClearException();
463a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald  }
473a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald  return cls;
483a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald}
493a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald
503a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwaldinline mirror::Class* CompilerDriver::ResolveCompilingMethodsClass(
513a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald    const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
523a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald    Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit) {
5319690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou  DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile());
543a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald  DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get());
553a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald  const DexFile::MethodId& referrer_method_id =
563a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald      mUnit->GetDexFile()->GetMethodId(mUnit->GetDexMethodIndex());
573a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald  return ResolveClass(soa, dex_cache, class_loader, referrer_method_id.class_idx_, mUnit);
583a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald}
5919690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou
603a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwaldinline ArtField* CompilerDriver::ResolveFieldWithDexFile(
613a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald    const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
6219690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou    Handle<mirror::ClassLoader> class_loader, const DexFile* dex_file,
6319690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou    uint32_t field_idx, bool is_static) {
6419690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou  DCHECK_EQ(dex_cache->GetDexFile(), dex_file);
6519690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou  ArtField* resolved_field = Runtime::Current()->GetClassLinker()->ResolveField(
6619690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou      *dex_file, field_idx, dex_cache, class_loader, is_static);
6719690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou  DCHECK_EQ(resolved_field == nullptr, soa.Self()->IsExceptionPending());
6819690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou  if (UNLIKELY(resolved_field == nullptr)) {
6919690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou    // Clean up any exception left by type resolution.
7019690593273a5b210a9b9ea72bd59840d02759b0Antoine Pitrou    soa.Self()->ClearException();
71c5ae86b9d3b6e348b6d0ee77c050134749a18cccAntoine Pitrou    return nullptr;
72c5ae86b9d3b6e348b6d0ee77c050134749a18cccAntoine Pitrou  }
73c5ae86b9d3b6e348b6d0ee77c050134749a18cccAntoine Pitrou  if (UNLIKELY(resolved_field->IsStatic() != is_static)) {
743a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald    // ClassLinker can return a field of the wrong kind directly from the DexCache.
753a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald    // Silently return null on such incompatible class change.
76c5ae86b9d3b6e348b6d0ee77c050134749a18cccAntoine Pitrou    return nullptr;
773a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald  }
783a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald  return resolved_field;
793a3d8ea4970a847d83878102dd382275de2988dcWalter Dörwald}
80
81inline ArtField* CompilerDriver::ResolveField(
82    const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
83    Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
84    uint32_t field_idx, bool is_static) {
85  DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get());
86  return ResolveFieldWithDexFile(soa, dex_cache, class_loader, mUnit->GetDexFile(), field_idx,
87                                 is_static);
88}
89
90inline std::pair<bool, bool> CompilerDriver::IsFastInstanceField(
91    mirror::DexCache* dex_cache, mirror::Class* referrer_class,
92    ArtField* resolved_field, uint16_t field_idx) {
93  DCHECK(!resolved_field->IsStatic());
94  ObjPtr<mirror::Class> fields_class = resolved_field->GetDeclaringClass();
95  bool fast_get = referrer_class != nullptr &&
96      referrer_class->CanAccessResolvedField(fields_class,
97                                             resolved_field,
98                                             dex_cache,
99                                             field_idx);
100  bool fast_put = fast_get && (!resolved_field->IsFinal() || fields_class == referrer_class);
101  return std::make_pair(fast_get, fast_put);
102}
103
104template <typename ArtMember>
105inline bool CompilerDriver::CanAccessResolvedMember(mirror::Class* referrer_class ATTRIBUTE_UNUSED,
106                                                    mirror::Class* access_to ATTRIBUTE_UNUSED,
107                                                    ArtMember* member ATTRIBUTE_UNUSED,
108                                                    mirror::DexCache* dex_cache ATTRIBUTE_UNUSED,
109                                                    uint32_t field_idx ATTRIBUTE_UNUSED) {
110  // Not defined for ArtMember values other than ArtField or ArtMethod.
111  UNREACHABLE();
112}
113
114template <>
115inline bool CompilerDriver::CanAccessResolvedMember<ArtField>(mirror::Class* referrer_class,
116                                                              mirror::Class* access_to,
117                                                              ArtField* field,
118                                                              mirror::DexCache* dex_cache,
119                                                              uint32_t field_idx) {
120  return referrer_class->CanAccessResolvedField(access_to, field, dex_cache, field_idx);
121}
122
123template <>
124inline bool CompilerDriver::CanAccessResolvedMember<ArtMethod>(
125    mirror::Class* referrer_class,
126    mirror::Class* access_to,
127    ArtMethod* method,
128    mirror::DexCache* dex_cache,
129    uint32_t field_idx) {
130  return referrer_class->CanAccessResolvedMethod(access_to, method, dex_cache, field_idx);
131}
132
133inline ArtMethod* CompilerDriver::ResolveMethod(
134    ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
135    Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
136    uint32_t method_idx, InvokeType invoke_type, bool check_incompatible_class_change) {
137  DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get());
138  ArtMethod* resolved_method =
139      check_incompatible_class_change
140          ? mUnit->GetClassLinker()->ResolveMethod<ClassLinker::kForceICCECheck>(
141              *dex_cache->GetDexFile(), method_idx, dex_cache, class_loader, nullptr, invoke_type)
142          : mUnit->GetClassLinker()->ResolveMethod<ClassLinker::kNoICCECheckForCache>(
143              *dex_cache->GetDexFile(), method_idx, dex_cache, class_loader, nullptr, invoke_type);
144  if (UNLIKELY(resolved_method == nullptr)) {
145    DCHECK(soa.Self()->IsExceptionPending());
146    // Clean up any exception left by type resolution.
147    soa.Self()->ClearException();
148  }
149  return resolved_method;
150}
151
152}  // namespace art
153
154#endif  // ART_COMPILER_DRIVER_COMPILER_DRIVER_INL_H_
155