diff options
Diffstat (limited to 'src/compiler/driver')
| -rw-r--r-- | src/compiler/driver/compiler_driver.cc | 106 | ||||
| -rw-r--r-- | src/compiler/driver/compiler_driver.h | 14 |
2 files changed, 104 insertions, 16 deletions
diff --git a/src/compiler/driver/compiler_driver.cc b/src/compiler/driver/compiler_driver.cc index 3dddc751be..40cc4830d4 100644 --- a/src/compiler/driver/compiler_driver.cc +++ b/src/compiler/driver/compiler_driver.cc @@ -24,6 +24,7 @@ #include "base/stl_util.h" #include "base/timing_logger.h" #include "class_linker.h" +#include "compiler/stubs/stubs.h" #include "dex_compilation_unit.h" #include "dex_file-inl.h" #include "jni_internal.h" @@ -448,6 +449,66 @@ CompilerTls* CompilerDriver::GetTls() { return res; } +const std::vector<uint8_t>* CompilerDriver::CreatePortableResolutionTrampoline() const { + switch (instruction_set_) { + case kArm: + case kThumb2: + return arm::CreatePortableResolutionTrampoline(); + case kMips: + return mips::CreatePortableResolutionTrampoline(); + case kX86: + return x86::CreatePortableResolutionTrampoline(); + default: + LOG(FATAL) << "Unknown InstructionSet: " << instruction_set_; + return NULL; + } +} + +const std::vector<uint8_t>* CompilerDriver::CreateQuickResolutionTrampoline() const { + switch (instruction_set_) { + case kArm: + case kThumb2: + return arm::CreateQuickResolutionTrampoline(); + case kMips: + return mips::CreateQuickResolutionTrampoline(); + case kX86: + return x86::CreateQuickResolutionTrampoline(); + default: + LOG(FATAL) << "Unknown InstructionSet: " << instruction_set_; + return NULL; + } +} + +const std::vector<uint8_t>* CompilerDriver::CreateInterpreterToInterpreterEntry() const { + switch (instruction_set_) { + case kArm: + case kThumb2: + return arm::CreateInterpreterToInterpreterEntry(); + case kMips: + return mips::CreateInterpreterToInterpreterEntry(); + case kX86: + return x86::CreateInterpreterToInterpreterEntry(); + default: + LOG(FATAL) << "Unknown InstructionSet: " << instruction_set_; + return NULL; + } +} + +const std::vector<uint8_t>* CompilerDriver::CreateInterpreterToQuickEntry() const { + switch (instruction_set_) { + case kArm: + case kThumb2: + return arm::CreateInterpreterToQuickEntry(); + case kMips: + return mips::CreateInterpreterToQuickEntry(); + case kX86: + return x86::CreateInterpreterToQuickEntry(); + default: + LOG(FATAL) << "Unknown InstructionSet: " << instruction_set_; + return NULL; + } +} + void CompilerDriver::CompileAll(jobject class_loader, const std::vector<const DexFile*>& dex_files) { DCHECK(!Runtime::Current()->IsStarted()); @@ -536,24 +597,19 @@ void CompilerDriver::RecordClassStatus(ClassReference ref, CompiledClass* compil bool CompilerDriver::CanAssumeTypeIsPresentInDexCache(const DexFile& dex_file, uint32_t type_idx) { - ScopedObjectAccess soa(Thread::Current()); - mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); - if (!IsImage()) { - stats_->TypeNotInDexCache(); - return false; - } - mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx); - if (resolved_class == NULL) { - stats_->TypeNotInDexCache(); - return false; - } - bool result = IsImageClass(ClassHelper(resolved_class).GetDescriptor()); - if (result) { + if (IsImage() && IsImageClass(dex_file.GetTypeDescriptor(dex_file.GetTypeId(type_idx)))) { + if (kIsDebugBuild) { + ScopedObjectAccess soa(Thread::Current()); + mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); + mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx); + CHECK(resolved_class != NULL); + } stats_->TypeInDexCache(); + return true; } else { stats_->TypeNotInDexCache(); + return false; } - return result; } bool CompilerDriver::CanAssumeStringIsPresentInDexCache(const DexFile& dex_file, @@ -577,7 +633,18 @@ bool CompilerDriver::CanAssumeStringIsPresentInDexCache(const DexFile& dex_file, } bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file, - uint32_t type_idx) { + uint32_t type_idx, + bool* type_known_final, bool* type_known_abstract, + bool* equals_referrers_class) { + if (type_known_final != NULL) { + *type_known_final = false; + } + if (type_known_abstract != NULL) { + *type_known_abstract = false; + } + if (equals_referrers_class != NULL) { + *equals_referrers_class = false; + } ScopedObjectAccess soa(Thread::Current()); mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); // Get type from dex cache assuming it was populated by the verifier @@ -587,6 +654,9 @@ bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const Dex return false; // Unknown class needs access checks. } const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx); + if (equals_referrers_class != NULL) { + *equals_referrers_class = (method_id.class_idx_ == type_idx); + } mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); if (referrer_class == NULL) { stats_->TypeNeedsAccessCheck(); @@ -597,6 +667,12 @@ bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const Dex bool result = referrer_class->CanAccess(resolved_class); if (result) { stats_->TypeDoesntNeedAccessCheck(); + if (type_known_final != NULL) { + *type_known_final = resolved_class->IsFinal() && !resolved_class->IsArrayClass(); + } + if (type_known_abstract != NULL) { + *type_known_abstract = resolved_class->IsAbstract(); + } } else { stats_->TypeNeedsAccessCheck(); } diff --git a/src/compiler/driver/compiler_driver.h b/src/compiler/driver/compiler_driver.h index 1b5bd0d84c..4f77bdb7a7 100644 --- a/src/compiler/driver/compiler_driver.h +++ b/src/compiler/driver/compiler_driver.h @@ -98,6 +98,16 @@ class CompilerDriver { CompilerTls* GetTls(); + // Generate the trampolines that are invoked by unresolved direct methods. + const std::vector<uint8_t>* CreatePortableResolutionTrampoline() const + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const std::vector<uint8_t>* CreateQuickResolutionTrampoline() const + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const std::vector<uint8_t>* CreateInterpreterToInterpreterEntry() const + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const std::vector<uint8_t>* CreateInterpreterToQuickEntry() const + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + // A class is uniquely located by its DexFile and the class_defs_ table index into that DexFile typedef std::pair<const DexFile*, uint32_t> ClassReference; @@ -138,7 +148,9 @@ class CompilerDriver { // Are runtime access checks necessary in the compiled code? bool CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file, - uint32_t type_idx) + uint32_t type_idx, bool* type_known_final = NULL, + bool* type_known_abstract = NULL, + bool* equals_referrers_class = NULL) LOCKS_EXCLUDED(Locks::mutator_lock_); // Are runtime access and instantiable checks necessary in the code? |