summaryrefslogtreecommitdiff
path: root/src/compiler/driver
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/driver')
-rw-r--r--src/compiler/driver/compiler_driver.cc106
-rw-r--r--src/compiler/driver/compiler_driver.h14
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?