Profiler directed clean-up of dex2oat.
Fix bad usage of std::string in: the verifier and compiler driver method
arguments, causing unnecessary boxing and allocations; in creating a symbol for
the dex compilation unit, that is only used in portable builds; in pattern
matching for intrinsics by name.
Make class linker dex and classes locks reader/writer to allow concurrent
dex cache or class querying. Refactor ComputeCompilingMethodsClass to pass in a
dex cache hint, to avoid taking any locks when the dex file of the compiling
method matches that of the field or method being resolved.
Make the RegType's HasClass method virtual to avoid frequent virtual method
dispatch. Make RegTypeCache GetFromId inlinable.
Various other bits of whitespace and formatting clean-up.
Change-Id: Id152e1e5a6fed2961dad0b612b7aa0c48001ef94
diff --git a/src/compiler/dex/quick/gen_invoke.cc b/src/compiler/dex/quick/gen_invoke.cc
index f44272a..733fdc9 100644
--- a/src/compiler/dex/quick/gen_invoke.cc
+++ b/src/compiler/dex/quick/gen_invoke.cc
@@ -15,6 +15,7 @@
*/
#include "compiler/dex/compiler_ir.h"
+#include "dex_file-inl.h"
#include "invoke_type.h"
#include "mirror/array.h"
#include "mirror/string.h"
@@ -1177,6 +1178,10 @@
// TODO - add Mips implementation
return false;
}
+ if (cu_->instruction_set == kX86 && is_object) {
+ // TODO: fix X86, it exhausts registers for card marking.
+ return false;
+ }
// Unused - RegLocation rl_src_unsafe = info->args[0];
RegLocation rl_src_obj = info->args[1]; // Object
RegLocation rl_src_offset = info->args[2]; // long low
@@ -1220,8 +1225,10 @@
* method. By doing this during basic block construction, we can also
* take advantage of/generate new useful dataflow info.
*/
- std::string tgt_method(PrettyMethod(info->index, *cu_->dex_file));
- if (tgt_method.find(" java.lang") != std::string::npos) {
+ const char* tgt_methods_declaring_class =
+ cu_->dex_file->GetMethodDeclaringClassDescriptor(cu_->dex_file->GetMethodId(info->index));
+ if (strstr(tgt_methods_declaring_class, "Ljava/lang") != NULL) {
+ std::string tgt_method(PrettyMethod(info->index, *cu_->dex_file));
if (tgt_method == "long java.lang.Double.doubleToRawLongBits(double)") {
return GenInlinedDoubleCvt(info);
}
@@ -1275,7 +1282,8 @@
if (tgt_method == "java.lang.Thread java.lang.Thread.currentThread()") {
return GenInlinedCurrentThread(info);
}
- } else if (tgt_method.find(" sun.misc.Unsafe") != std::string::npos) {
+ } else if (strstr(tgt_methods_declaring_class, "Lsun/misc/Unsafe;") != NULL) {
+ std::string tgt_method(PrettyMethod(info->index, *cu_->dex_file));
if (tgt_method == "boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)") {
return GenInlinedCas32(info, false);
}
diff --git a/src/compiler/driver/compiler_driver.cc b/src/compiler/driver/compiler_driver.cc
index 85dcdf6..cc65cbe 100644
--- a/src/compiler/driver/compiler_driver.cc
+++ b/src/compiler/driver/compiler_driver.cc
@@ -500,7 +500,7 @@
InitializeClasses(class_loader, dex_files, thread_pool, timings);
}
-bool CompilerDriver::IsImageClass(const std::string& descriptor) const {
+bool CompilerDriver::IsImageClass(const char* descriptor) const {
if (image_classes_ == NULL) {
return false;
}
@@ -610,9 +610,14 @@
}
static mirror::Class* ComputeCompilingMethodsClass(ScopedObjectAccess& soa,
+ mirror::DexCache* dex_cache,
const DexCompilationUnit* mUnit)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::DexCache* dex_cache = mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile());
+ // The passed dex_cache is a hint, sanity check before asking the class linker that will take a
+ // lock.
+ if (dex_cache->GetDexFile() != mUnit->GetDexFile()) {
+ dex_cache = mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile());
+ }
mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader());
const DexFile::MethodId& referrer_method_id = mUnit->GetDexFile()->GetMethodId(mUnit->GetDexMethodIndex());
return mUnit->GetClassLinker()->ResolveType(*mUnit->GetDexFile(), referrer_method_id.class_idx_,
@@ -649,7 +654,9 @@
// Try to resolve field and ignore if an Incompatible Class Change Error (ie is static).
mirror::Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx);
if (resolved_field != NULL && !resolved_field->IsStatic()) {
- mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
+ mirror::Class* referrer_class =
+ ComputeCompilingMethodsClass(soa, resolved_field->GetDeclaringClass()->GetDexCache(),
+ mUnit);
if (referrer_class != NULL) {
mirror::Class* fields_class = resolved_field->GetDeclaringClass();
bool access_ok = referrer_class->CanAccess(fields_class) &&
@@ -698,7 +705,9 @@
// Try to resolve field and ignore if an Incompatible Class Change Error (ie isn't static).
mirror::Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx);
if (resolved_field != NULL && resolved_field->IsStatic()) {
- mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
+ mirror::Class* referrer_class =
+ ComputeCompilingMethodsClass(soa, resolved_field->GetDeclaringClass()->GetDexCache(),
+ mUnit);
if (referrer_class != NULL) {
mirror::Class* fields_class = resolved_field->GetDeclaringClass();
if (fields_class == referrer_class) {
@@ -842,7 +851,9 @@
if (resolved_method != NULL) {
// Don't try to fast-path if we don't understand the caller's class or this appears to be an
// Incompatible Class Change Error.
- mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
+ mirror::Class* referrer_class =
+ ComputeCompilingMethodsClass(soa, resolved_method->GetDeclaringClass()->GetDexCache(),
+ mUnit);
bool icce = resolved_method->CheckIncompatibleClassChange(invoke_type);
if (referrer_class != NULL && !icce) {
mirror::Class* methods_class = resolved_method->GetDeclaringClass();
diff --git a/src/compiler/driver/compiler_driver.h b/src/compiler/driver/compiler_driver.h
index 250532b..c1e449e 100644
--- a/src/compiler/driver/compiler_driver.h
+++ b/src/compiler/driver/compiler_driver.h
@@ -267,7 +267,7 @@
}
// Checks if class specified by type_idx is one of the image_classes_
- bool IsImageClass(const std::string& descriptor) const;
+ bool IsImageClass(const char* descriptor) const;
void RecordClassStatus(ClassReference ref, CompiledClass* compiled_class);
diff --git a/src/compiler/driver/dex_compilation_unit.cc b/src/compiler/driver/dex_compilation_unit.cc
index 962df42..c7a4df6 100644
--- a/src/compiler/driver/dex_compilation_unit.cc
+++ b/src/compiler/driver/dex_compilation_unit.cc
@@ -31,18 +31,17 @@
code_item_(cu->code_item),
class_def_idx_(cu->class_def_idx),
dex_method_idx_(cu->method_idx),
- access_flags_(cu->access_flags),
- symbol_(StringPrintf("dex_%s", MangleForJni(PrettyMethod(dex_method_idx_, *dex_file_)).c_str())) {
+ access_flags_(cu->access_flags) {
}
-DexCompilationUnit:: DexCompilationUnit(CompilationUnit* cu,
- jobject class_loader,
- ClassLinker* class_linker,
- const DexFile& dex_file,
- const DexFile::CodeItem* code_item,
- uint32_t class_def_idx,
- uint32_t method_idx,
- uint32_t access_flags)
+DexCompilationUnit::DexCompilationUnit(CompilationUnit* cu,
+ jobject class_loader,
+ ClassLinker* class_linker,
+ const DexFile& dex_file,
+ const DexFile::CodeItem* code_item,
+ uint32_t class_def_idx,
+ uint32_t method_idx,
+ uint32_t access_flags)
: cu_(cu),
class_loader_(class_loader),
class_linker_(class_linker),
@@ -50,8 +49,15 @@
code_item_(code_item),
class_def_idx_(class_def_idx),
dex_method_idx_(method_idx),
- access_flags_(access_flags),
- symbol_(StringPrintf("dex_%s", MangleForJni(PrettyMethod(dex_method_idx_, *dex_file_)).c_str())) {
+ access_flags_(access_flags) {
+}
+
+const std::string& DexCompilationUnit::GetSymbol() {
+ if (symbol_.empty()) {
+ symbol_ = "dex_";
+ symbol_ += MangleForJni(PrettyMethod(dex_method_idx_, *dex_file_));
+ }
+ return symbol_;
}
} // namespace art
diff --git a/src/compiler/driver/dex_compilation_unit.h b/src/compiler/driver/dex_compilation_unit.h
index 0b90aaa..3c6129d 100644
--- a/src/compiler/driver/dex_compilation_unit.h
+++ b/src/compiler/driver/dex_compilation_unit.h
@@ -92,9 +92,7 @@
return ((access_flags_ & kAccSynchronized) != 0);
}
- const std::string& GetSymbol() const {
- return symbol_;
- }
+ const std::string& GetSymbol();
private:
CompilationUnit* const cu_;
@@ -110,7 +108,7 @@
const uint32_t dex_method_idx_;
const uint32_t access_flags_;
- const std::string symbol_;
+ std::string symbol_;
};
} // namespace art
diff --git a/src/compiler/llvm/llvm_compilation_unit.h b/src/compiler/llvm/llvm_compilation_unit.h
index d96e778..857d924 100644
--- a/src/compiler/llvm/llvm_compilation_unit.h
+++ b/src/compiler/llvm/llvm_compilation_unit.h
@@ -81,10 +81,10 @@
void SetCompilerDriver(CompilerDriver* driver) {
driver_ = driver;
}
- const DexCompilationUnit* GetDexCompilationUnit() {
+ DexCompilationUnit* GetDexCompilationUnit() {
return dex_compilation_unit_;
}
- void SetDexCompilationUnit(const DexCompilationUnit* dex_compilation_unit) {
+ void SetDexCompilationUnit(DexCompilationUnit* dex_compilation_unit) {
dex_compilation_unit_ = dex_compilation_unit;
}
@@ -113,7 +113,7 @@
UniquePtr<IntrinsicHelper> intrinsic_helper_;
UniquePtr<LLVMInfo> llvm_info_;
CompilerDriver* driver_;
- const DexCompilationUnit* dex_compilation_unit_;
+ DexCompilationUnit* dex_compilation_unit_;
std::string bitcode_filename_;