namespace art {
-inline mirror::DexCache* CompilerDriver::GetDexCache(const DexCompilationUnit* mUnit) {
- return mUnit->GetClassLinker()->FindDexCache(Thread::Current(), *mUnit->GetDexFile(), false);
-}
-
inline mirror::ClassLoader* CompilerDriver::GetClassLoader(const ScopedObjectAccess& soa,
const DexCompilationUnit* mUnit) {
return soa.Decode<mirror::ClassLoader>(mUnit->GetClassLoader()).Decode();
return resolved_field;
}
-inline mirror::DexCache* CompilerDriver::FindDexCache(const DexFile* dex_file) {
- return Runtime::Current()->GetClassLinker()->FindDexCache(Thread::Current(), *dex_file, false);
-}
-
inline ArtField* CompilerDriver::ResolveField(
const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
is_static);
}
-inline void CompilerDriver::GetResolvedFieldDexFileLocation(
- ArtField* resolved_field, const DexFile** declaring_dex_file,
- uint16_t* declaring_class_idx, uint16_t* declaring_field_idx) {
- ObjPtr<mirror::Class> declaring_class = resolved_field->GetDeclaringClass();
- *declaring_dex_file = declaring_class->GetDexCache()->GetDexFile();
- *declaring_class_idx = declaring_class->GetDexTypeIndex();
- *declaring_field_idx = resolved_field->GetDexFieldIndex();
-}
-
-inline bool CompilerDriver::IsFieldVolatile(ArtField* field) {
- return field->IsVolatile();
-}
-
-inline MemberOffset CompilerDriver::GetFieldOffset(ArtField* field) {
- return field->GetOffset();
-}
-
inline std::pair<bool, bool> CompilerDriver::IsFastInstanceField(
mirror::DexCache* dex_cache, mirror::Class* referrer_class,
ArtField* resolved_field, uint16_t field_idx) {
return result.first;
}
-inline bool CompilerDriver::IsStaticFieldInReferrerClass(mirror::Class* referrer_class,
- ArtField* resolved_field) {
- DCHECK(resolved_field->IsStatic());
- ObjPtr<mirror::Class> fields_class = resolved_field->GetDeclaringClass();
- return referrer_class == fields_class;
-}
-
-inline bool CompilerDriver::CanAssumeClassIsInitialized(mirror::Class* klass) {
- // Being loaded is a pre-requisite for being initialized but let's do the cheap check first.
- //
- // NOTE: When AOT compiling an app, we eagerly initialize app classes (and potentially their
- // super classes in the boot image) but only those that have a trivial initialization, i.e.
- // without <clinit>() or static values in the dex file for that class or any of its super
- // classes. So while we could see the klass as initialized during AOT compilation and have
- // it only loaded at runtime, the needed initialization would have to be trivial and
- // unobservable from Java, so we may as well treat it as initialized.
- if (!klass->IsInitialized()) {
- return false;
- }
- return CanAssumeClassIsLoaded(klass);
-}
-
-inline bool CompilerDriver::CanReferrerAssumeClassIsInitialized(mirror::Class* referrer_class,
- mirror::Class* klass) {
- return (referrer_class != nullptr
- && !referrer_class->IsInterface()
- && referrer_class->IsSubClass(klass))
- || CanAssumeClassIsInitialized(klass);
-}
-
-inline bool CompilerDriver::IsStaticFieldsClassInitialized(mirror::Class* referrer_class,
- ArtField* resolved_field) {
- DCHECK(resolved_field->IsStatic());
- ObjPtr<mirror::Class> fields_class = resolved_field->GetDeclaringClass();
- return CanReferrerAssumeClassIsInitialized(referrer_class, fields_class.Decode());
-}
-
inline ArtMethod* CompilerDriver::ResolveMethod(
ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
return resolved_method;
}
-inline void CompilerDriver::GetResolvedMethodDexFileLocation(
- ArtMethod* resolved_method, const DexFile** declaring_dex_file,
- uint16_t* declaring_class_idx, uint16_t* declaring_method_idx) {
- mirror::Class* declaring_class = resolved_method->GetDeclaringClass();
- *declaring_dex_file = declaring_class->GetDexCache()->GetDexFile();
- *declaring_class_idx = declaring_class->GetDexTypeIndex();
- *declaring_method_idx = resolved_method->GetDexMethodIndex();
-}
-
-inline uint16_t CompilerDriver::GetResolvedMethodVTableIndex(
- ArtMethod* resolved_method, InvokeType type) {
- if (type == kVirtual || type == kSuper) {
- return resolved_method->GetMethodIndex();
- } else if (type == kInterface) {
- return resolved_method->GetDexMethodIndex();
- } else {
- return DexFile::kDexNoIndex16;
- }
-}
-
-inline bool CompilerDriver::IsMethodsClassInitialized(mirror::Class* referrer_class,
- ArtMethod* resolved_method) {
- if (!resolved_method->IsStatic()) {
- return true;
- }
- mirror::Class* methods_class = resolved_method->GetDeclaringClass();
- return CanReferrerAssumeClassIsInitialized(referrer_class, methods_class);
-}
-
} // namespace art
#endif // ART_COMPILER_DRIVER_COMPILER_DRIVER_INL_H_
public:
AOTCompilationStats()
: stats_lock_("AOT compilation statistics lock"),
- types_in_dex_cache_(0), types_not_in_dex_cache_(0),
- strings_in_dex_cache_(0), strings_not_in_dex_cache_(0),
resolved_types_(0), unresolved_types_(0),
resolved_instance_fields_(0), unresolved_instance_fields_(0),
resolved_local_static_fields_(0), resolved_static_fields_(0), unresolved_static_fields_(0),
}
void Dump() {
- DumpStat(types_in_dex_cache_, types_not_in_dex_cache_, "types known to be in dex cache");
- DumpStat(strings_in_dex_cache_, strings_not_in_dex_cache_, "strings known to be in dex cache");
DumpStat(resolved_types_, unresolved_types_, "types resolved");
DumpStat(resolved_instance_fields_, unresolved_instance_fields_, "instance fields resolved");
DumpStat(resolved_local_static_fields_ + resolved_static_fields_, unresolved_static_fields_,
#define STATS_LOCK()
#endif
- void TypeInDexCache() REQUIRES(!stats_lock_) {
- STATS_LOCK();
- types_in_dex_cache_++;
- }
-
- void TypeNotInDexCache() REQUIRES(!stats_lock_) {
- STATS_LOCK();
- types_not_in_dex_cache_++;
- }
-
- void StringInDexCache() REQUIRES(!stats_lock_) {
- STATS_LOCK();
- strings_in_dex_cache_++;
- }
-
- void StringNotInDexCache() REQUIRES(!stats_lock_) {
- STATS_LOCK();
- strings_not_in_dex_cache_++;
- }
-
void TypeDoesntNeedAccessCheck() REQUIRES(!stats_lock_) {
STATS_LOCK();
resolved_types_++;
type_based_devirtualization_++;
}
- // Indicate that a method of the given type was resolved at compile time.
- void ResolvedMethod(InvokeType type) REQUIRES(!stats_lock_) {
- DCHECK_LE(type, kMaxInvokeType);
- STATS_LOCK();
- resolved_methods_[type]++;
- }
-
- // Indicate that a method of the given type was unresolved at compile time as it was in an
- // unknown dex file.
- void UnresolvedMethod(InvokeType type) REQUIRES(!stats_lock_) {
- DCHECK_LE(type, kMaxInvokeType);
- STATS_LOCK();
- unresolved_methods_[type]++;
- }
-
- // Indicate that a type of virtual method dispatch has been converted into a direct method
- // dispatch.
- void VirtualMadeDirect(InvokeType type) REQUIRES(!stats_lock_) {
- DCHECK(type == kVirtual || type == kInterface || type == kSuper);
- STATS_LOCK();
- virtual_made_direct_[type]++;
- }
-
- // Indicate that a method of the given type was able to call directly into boot.
- void DirectCallsToBoot(InvokeType type) REQUIRES(!stats_lock_) {
- DCHECK_LE(type, kMaxInvokeType);
- STATS_LOCK();
- direct_calls_to_boot_[type]++;
- }
-
- // Indicate that a method of the given type was able to be resolved directly from boot.
- void DirectMethodsToBoot(InvokeType type) REQUIRES(!stats_lock_) {
- DCHECK_LE(type, kMaxInvokeType);
- STATS_LOCK();
- direct_methods_to_boot_[type]++;
- }
-
- void ProcessedInvoke(InvokeType type, int flags) REQUIRES(!stats_lock_) {
- STATS_LOCK();
- if (flags == 0) {
- unresolved_methods_[type]++;
- } else {
- DCHECK_NE((flags & kFlagMethodResolved), 0);
- resolved_methods_[type]++;
- if ((flags & kFlagVirtualMadeDirect) != 0) {
- virtual_made_direct_[type]++;
- if ((flags & kFlagPreciseTypeDevirtualization) != 0) {
- type_based_devirtualization_++;
- }
- } else {
- DCHECK_EQ((flags & kFlagPreciseTypeDevirtualization), 0);
- }
- if ((flags & kFlagDirectCallToBoot) != 0) {
- direct_calls_to_boot_[type]++;
- }
- if ((flags & kFlagDirectMethodToBoot) != 0) {
- direct_methods_to_boot_[type]++;
- }
- }
- }
-
// A check-cast could be eliminated due to verifier type analysis.
void SafeCast() REQUIRES(!stats_lock_) {
STATS_LOCK();
private:
Mutex stats_lock_;
- size_t types_in_dex_cache_;
- size_t types_not_in_dex_cache_;
-
- size_t strings_in_dex_cache_;
- size_t strings_not_in_dex_cache_;
-
size_t resolved_types_;
size_t unresolved_types_;
// TODO: Collect the relevant string indices in parallel, then allocate them sequentially in a
// stable order.
-static void ResolveConstStrings(CompilerDriver* driver,
+static void ResolveConstStrings(Handle<mirror::DexCache> dex_cache,
const DexFile& dex_file,
- const DexFile::CodeItem* code_item) {
+ const DexFile::CodeItem* code_item)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
if (code_item == nullptr) {
// Abstract or native method.
return;
const uint16_t* code_ptr = code_item->insns_;
const uint16_t* code_end = code_item->insns_ + code_item->insns_size_in_code_units_;
+ ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
while (code_ptr < code_end) {
const Instruction* inst = Instruction::At(code_ptr);
switch (inst->Opcode()) {
case Instruction::CONST_STRING: {
uint32_t string_index = inst->VRegB_21c();
- driver->CanAssumeStringIsPresentInDexCache(dex_file, string_index);
+ class_linker->ResolveString(dex_file, string_index, dex_cache);
break;
}
case Instruction::CONST_STRING_JUMBO: {
uint32_t string_index = inst->VRegB_31c();
- driver->CanAssumeStringIsPresentInDexCache(dex_file, string_index);
+ class_linker->ResolveString(dex_file, string_index, dex_cache);
break;
}
static void ResolveConstStrings(CompilerDriver* driver,
const std::vector<const DexFile*>& dex_files,
TimingLogger* timings) {
+ ScopedObjectAccess soa(Thread::Current());
+ StackHandleScope<1> hs(soa.Self());
+ ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
+ MutableHandle<mirror::DexCache> dex_cache(hs.NewHandle<mirror::DexCache>(nullptr));
+
for (const DexFile* dex_file : dex_files) {
+ dex_cache.Assign(class_linker->FindDexCache(soa.Self(), *dex_file, false));
TimingLogger::ScopedTiming t("Resolve const-string Strings", timings);
size_t class_def_count = dex_file->NumClassDefs();
continue;
}
previous_direct_method_idx = method_idx;
- ResolveConstStrings(driver, *dex_file, it.GetMethodCodeItem());
+ ResolveConstStrings(dex_cache, *dex_file, it.GetMethodCodeItem());
it.Next();
}
// Virtual methods.
continue;
}
previous_virtual_method_idx = method_idx;
- ResolveConstStrings(driver, *dex_file, it.GetMethodCodeItem());
+ ResolveConstStrings(dex_cache, *dex_file, it.GetMethodCodeItem());
it.Next();
}
DCHECK(!it.HasNext());
dex_to_dex_references_.back().GetMethodIndexes().SetBit(method_ref.dex_method_index);
}
-bool CompilerDriver::CanAssumeTypeIsPresentInDexCache(Handle<mirror::DexCache> dex_cache,
- uint32_t type_idx) {
- bool result = false;
- if ((IsBootImage() &&
- IsImageClass(dex_cache->GetDexFile()->StringDataByIdx(
- dex_cache->GetDexFile()->GetTypeId(type_idx).descriptor_idx_))) ||
- Runtime::Current()->UseJitCompilation()) {
- mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
- result = (resolved_class != nullptr);
- }
-
- if (result) {
- stats_->TypeInDexCache();
- } else {
- stats_->TypeNotInDexCache();
- }
- return result;
-}
-
-bool CompilerDriver::CanAssumeStringIsPresentInDexCache(const DexFile& dex_file,
- uint32_t string_idx) {
- // See also Compiler::ResolveDexFile
-
- bool result = false;
- if (IsBootImage() || Runtime::Current()->UseJitCompilation()) {
- ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<1> hs(soa.Self());
- ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(
- soa.Self(), dex_file, false)));
- if (IsBootImage()) {
- // We resolve all const-string strings when building for the image.
- class_linker->ResolveString(dex_file, string_idx, dex_cache);
- result = true;
- } else {
- // Just check whether the dex cache already has the string.
- DCHECK(Runtime::Current()->UseJitCompilation());
- result = (dex_cache->GetResolvedString(string_idx) != nullptr);
- }
- }
- if (result) {
- stats_->StringInDexCache();
- } else {
- stats_->StringNotInDexCache();
- }
- return result;
-}
-
bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx,
Handle<mirror::DexCache> dex_cache,
uint32_t type_idx) {
return result;
}
-bool CompilerDriver::CanEmbedTypeInCode(const DexFile& dex_file, uint32_t type_idx,
- bool* is_type_initialized, bool* use_direct_type_ptr,
- uintptr_t* direct_type_ptr, bool* out_is_finalizable) {
- ScopedObjectAccess soa(Thread::Current());
- Runtime* runtime = Runtime::Current();
- mirror::DexCache* dex_cache = runtime->GetClassLinker()->FindDexCache(
- soa.Self(), dex_file, false);
- mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
- if (resolved_class == nullptr) {
- return false;
- }
- if (GetCompilerOptions().GetCompilePic()) {
- // Do not allow a direct class pointer to be used when compiling for position-independent
- return false;
- }
- *out_is_finalizable = resolved_class->IsFinalizable();
- gc::Heap* heap = runtime->GetHeap();
- const bool compiling_boot = heap->IsCompilingBoot();
- const bool support_boot_image_fixup = GetSupportBootImageFixup();
- if (compiling_boot) {
- // boot -> boot class pointers.
- // True if the class is in the image at boot compiling time.
- const bool is_image_class = IsBootImage() && IsImageClass(
- dex_file.StringDataByIdx(dex_file.GetTypeId(type_idx).descriptor_idx_));
- // True if pc relative load works.
- if (is_image_class && support_boot_image_fixup) {
- *is_type_initialized = resolved_class->IsInitialized();
- *use_direct_type_ptr = false;
- *direct_type_ptr = 0;
- return true;
- } else {
- return false;
- }
- } else if (runtime->UseJitCompilation() && !heap->IsMovableObject(resolved_class)) {
- *is_type_initialized = resolved_class->IsInitialized();
- // If the class may move around, then don't embed it as a direct pointer.
- *use_direct_type_ptr = true;
- *direct_type_ptr = reinterpret_cast<uintptr_t>(resolved_class);
- return true;
- } else {
- // True if the class is in the image at app compiling time.
- const bool class_in_image = heap->FindSpaceFromObject(resolved_class, false)->IsImageSpace();
- if (class_in_image && support_boot_image_fixup) {
- // boot -> app class pointers.
- *is_type_initialized = resolved_class->IsInitialized();
- // TODO This is somewhat hacky. We should refactor all of this invoke codepath.
- *use_direct_type_ptr = !GetCompilerOptions().GetIncludePatchInformation();
- *direct_type_ptr = reinterpret_cast<uintptr_t>(resolved_class);
- return true;
- } else {
- // app -> app class pointers.
- // Give up because app does not have an image and class
- // isn't created at compile time. TODO: implement this
- // if/when each app gets an image.
- return false;
- }
- }
-}
-
-bool CompilerDriver::CanEmbedReferenceTypeInCode(ClassReference* ref,
- bool* use_direct_ptr,
- uintptr_t* direct_type_ptr) {
- CHECK(ref != nullptr);
- CHECK(use_direct_ptr != nullptr);
- CHECK(direct_type_ptr != nullptr);
-
- ScopedObjectAccess soa(Thread::Current());
- mirror::Class* reference_class = mirror::Reference::GetJavaLangRefReference();
- bool is_initialized = false;
- bool unused_finalizable;
- // Make sure we have a finished Reference class object before attempting to use it.
- if (!CanEmbedTypeInCode(*reference_class->GetDexCache()->GetDexFile(),
- reference_class->GetDexTypeIndex(), &is_initialized,
- use_direct_ptr, direct_type_ptr, &unused_finalizable) ||
- !is_initialized) {
- return false;
- }
- ref->first = &reference_class->GetDexFile();
- ref->second = reference_class->GetDexClassDefIndex();
- return true;
-}
-
-uint32_t CompilerDriver::GetReferenceSlowFlagOffset() const {
- ScopedObjectAccess soa(Thread::Current());
- mirror::Class* klass = mirror::Reference::GetJavaLangRefReference();
- DCHECK(klass->IsInitialized());
- return klass->GetSlowPathFlagOffset().Uint32Value();
-}
-
-uint32_t CompilerDriver::GetReferenceDisableFlagOffset() const {
- ScopedObjectAccess soa(Thread::Current());
- mirror::Class* klass = mirror::Reference::GetJavaLangRefReference();
- DCHECK(klass->IsInitialized());
- return klass->GetDisableIntrinsicFlagOffset().Uint32Value();
-}
-
-DexCacheArraysLayout CompilerDriver::GetDexCacheArraysLayout(const DexFile* dex_file) {
- return ContainsElement(GetDexFilesForOatFile(), dex_file)
- ? DexCacheArraysLayout(GetInstructionSetPointerSize(instruction_set_), dex_file)
- : DexCacheArraysLayout();
-}
-
void CompilerDriver::ProcessedInstanceField(bool resolved) {
if (!resolved) {
stats_->UnresolvedInstanceField();
}
}
-void CompilerDriver::ProcessedInvoke(InvokeType invoke_type, int flags) {
- stats_->ProcessedInvoke(invoke_type, flags);
-}
-
ArtField* CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx,
const DexCompilationUnit* mUnit, bool is_put,
const ScopedObjectAccess& soa) {
uint16_t class_def_index)
REQUIRES(!requires_constructor_barrier_lock_);
- // Callbacks from compiler to see what runtime checks must be generated.
-
- bool CanAssumeTypeIsPresentInDexCache(Handle<mirror::DexCache> dex_cache,
- uint32_t type_idx)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- bool CanAssumeStringIsPresentInDexCache(const DexFile& dex_file, uint32_t string_idx)
- REQUIRES(!Locks::mutator_lock_);
-
// Are runtime access checks necessary in the compiled code?
bool CanAccessTypeWithoutChecks(uint32_t referrer_idx,
Handle<mirror::DexCache> dex_cache,
bool* out_is_finalizable)
REQUIRES_SHARED(Locks::mutator_lock_);
- bool CanEmbedTypeInCode(const DexFile& dex_file, uint32_t type_idx,
- bool* is_type_initialized, bool* use_direct_type_ptr,
- uintptr_t* direct_type_ptr, bool* out_is_finalizable);
-
- // Query methods for the java.lang.ref.Reference class.
- bool CanEmbedReferenceTypeInCode(ClassReference* ref,
- bool* use_direct_type_ptr, uintptr_t* direct_type_ptr);
- uint32_t GetReferenceSlowFlagOffset() const;
- uint32_t GetReferenceDisableFlagOffset() const;
-
- // Get the DexCache for the
- mirror::DexCache* GetDexCache(const DexCompilationUnit* mUnit)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- mirror::ClassLoader* GetClassLoader(const ScopedObjectAccess& soa,
- const DexCompilationUnit* mUnit)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
// Resolve compiling method's class. Returns null on failure.
mirror::Class* ResolveCompilingMethodsClass(
const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
uint32_t field_idx, bool is_static)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Get declaration location of a resolved field.
- void GetResolvedFieldDexFileLocation(
- ArtField* resolved_field, const DexFile** declaring_dex_file,
- uint16_t* declaring_class_idx, uint16_t* declaring_field_idx)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- bool IsFieldVolatile(ArtField* field) REQUIRES_SHARED(Locks::mutator_lock_);
- MemberOffset GetFieldOffset(ArtField* field) REQUIRES_SHARED(Locks::mutator_lock_);
-
- // Find a dex cache for a dex file.
- inline mirror::DexCache* FindDexCache(const DexFile* dex_file)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
// Can we fast-path an IGET/IPUT access to an instance field? If yes, compute the field offset.
std::pair<bool, bool> IsFastInstanceField(
mirror::DexCache* dex_cache, mirror::Class* referrer_class,
uint32_t* storage_index)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Is static field's in referrer's class?
- bool IsStaticFieldInReferrerClass(mirror::Class* referrer_class, ArtField* resolved_field)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- // Is static field's class initialized?
- bool IsStaticFieldsClassInitialized(mirror::Class* referrer_class,
- ArtField* resolved_field)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
// Resolve a method. Returns null on failure, including incompatible class change.
ArtMethod* ResolveMethod(
ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
uint32_t method_idx, InvokeType invoke_type, bool check_incompatible_class_change = true)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Get declaration location of a resolved field.
- void GetResolvedMethodDexFileLocation(
- ArtMethod* resolved_method, const DexFile** declaring_dex_file,
- uint16_t* declaring_class_idx, uint16_t* declaring_method_idx)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- // Get the index in the vtable of the method.
- uint16_t GetResolvedMethodVTableIndex(
- ArtMethod* resolved_method, InvokeType type)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- // Is method's class initialized for an invoke?
- // For static invokes to determine whether we need to consider potential call to <clinit>().
- // For non-static invokes, assuming a non-null reference, the class is always initialized.
- bool IsMethodsClassInitialized(mirror::Class* referrer_class, ArtMethod* resolved_method)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- // Get the layout of dex cache arrays for a dex file. Returns invalid layout if the
- // dex cache arrays don't have a fixed layout.
- DexCacheArraysLayout GetDexCacheArraysLayout(const DexFile* dex_file);
-
void ProcessedInstanceField(bool resolved);
void ProcessedStaticField(bool resolved, bool local);
- void ProcessedInvoke(InvokeType invoke_type, int flags);
-
- void ComputeFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit,
- const ScopedObjectAccess& soa, bool is_static,
- ArtField** resolved_field,
- mirror::Class** referrer_class,
- mirror::DexCache** dex_cache)
- REQUIRES_SHARED(Locks::mutator_lock_);
// Can we fast path instance field access? Computes field's offset and volatility.
bool ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit, bool is_put,
void SetDedupeEnabled(bool dedupe_enabled) {
compiled_method_storage_.SetDedupeEnabled(dedupe_enabled);
}
+
bool DedupeEnabled() const {
return compiled_method_storage_.DedupeEnabled();
}
return current_dex_to_dex_methods_;
}
+ // Compute constant code and method pointers when possible.
+ void GetCodeAndMethodForDirectCall(const mirror::Class* referrer_class,
+ ArtMethod* method,
+ /* out */ uintptr_t* direct_code,
+ /* out */ uintptr_t* direct_method)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
private:
// Return whether the declaring class of `resolved_member` is
// available to `referrer_class` for read or write access using two
uint32_t field_idx)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Can we assume that the klass is initialized?
- bool CanAssumeClassIsInitialized(mirror::Class* klass)
- REQUIRES_SHARED(Locks::mutator_lock_);
- bool CanReferrerAssumeClassIsInitialized(mirror::Class* referrer_class, mirror::Class* klass)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- // These flags are internal to CompilerDriver for collecting INVOKE resolution statistics.
- // The only external contract is that unresolved method has flags 0 and resolved non-0.
- enum {
- kBitMethodResolved = 0,
- kBitVirtualMadeDirect,
- kBitPreciseTypeDevirtualization,
- kBitDirectCallToBoot,
- kBitDirectMethodToBoot
- };
- static constexpr int kFlagMethodResolved = 1 << kBitMethodResolved;
- static constexpr int kFlagVirtualMadeDirect = 1 << kBitVirtualMadeDirect;
- static constexpr int kFlagPreciseTypeDevirtualization = 1 << kBitPreciseTypeDevirtualization;
- static constexpr int kFlagDirectCallToBoot = 1 << kBitDirectCallToBoot;
- static constexpr int kFlagDirectMethodToBoot = 1 << kBitDirectMethodToBoot;
- static constexpr int kFlagsMethodResolvedVirtualMadeDirect =
- kFlagMethodResolved | kFlagVirtualMadeDirect;
- static constexpr int kFlagsMethodResolvedPreciseTypeDevirtualization =
- kFlagsMethodResolvedVirtualMadeDirect | kFlagPreciseTypeDevirtualization;
-
- public: // TODO make private or eliminate.
- // Compute constant code and method pointers when possible.
- void GetCodeAndMethodForDirectCall(const mirror::Class* referrer_class,
- ArtMethod* method,
- /* out */ uintptr_t* direct_code,
- /* out */ uintptr_t* direct_method)
- REQUIRES_SHARED(Locks::mutator_lock_);
+ mirror::ClassLoader* GetClassLoader(const ScopedObjectAccess& soa,
+ const DexCompilationUnit* mUnit)
+ REQUIRES_SHARED(Locks::mutator_lock_);
private:
void PreCompile(jobject class_loader,
REQUIRES(!Locks::mutator_lock_, !compiled_classes_lock_);
void UpdateImageClasses(TimingLogger* timings) REQUIRES(!Locks::mutator_lock_);
- static void FindClinitImageClassesCallback(mirror::Object* object, void* arg)
- REQUIRES_SHARED(Locks::mutator_lock_);
void Compile(jobject class_loader,
const std::vector<const DexFile*>& dex_files,