StringPiece clean up.
Profile guided clean up.
Try to avoid creating StringPieces with the contents of a dex file where
the length is known.
Try to avoid RegTypeCache::FromDescriptor when there's a class available.
Make ConstantType::ConstantValue inlinable.
Saving of about 50ms from a 2 threaded ThinkFree compile on host.
Change-Id: I47a12c3c76f46e2c9805be1c3a3e3870fe1f5d85
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc
index 72ae91e..ed83863 100644
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -1219,8 +1219,10 @@
* method. By doing this during basic block construction, we can also
* take advantage of/generate new useful dataflow info.
*/
+ const DexFile::MethodId& target_mid = cu_->dex_file->GetMethodId(info->index);
+ const DexFile::TypeId& declaring_type = cu_->dex_file->GetTypeId(target_mid.class_idx_);
StringPiece tgt_methods_declaring_class(
- cu_->dex_file->GetMethodDeclaringClassDescriptor(cu_->dex_file->GetMethodId(info->index)));
+ cu_->dex_file->StringDataAsStringPieceByIdx(declaring_type.descriptor_idx_));
if (tgt_methods_declaring_class.starts_with("Ljava/lang/Double;")) {
std::string tgt_method(PrettyMethod(info->index, *cu_->dex_file));
if (tgt_method == "long java.lang.Double.doubleToRawLongBits(double)") {
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index c12a7d9..e227715 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -600,12 +600,11 @@
UpdateImageClasses(timings);
}
-bool CompilerDriver::IsImageClass(const char* descriptor) const {
- DCHECK(descriptor != NULL);
+bool CompilerDriver::IsImageClass(const StringPiece& descriptor) const {
if (!IsImage()) {
return true;
} else {
- return image_classes_->find(descriptor) != image_classes_->end();
+ return image_classes_->find(descriptor.data()) != image_classes_->end();
}
}
@@ -780,7 +779,8 @@
bool CompilerDriver::CanAssumeTypeIsPresentInDexCache(const DexFile& dex_file,
uint32_t type_idx) {
- if (IsImage() && IsImageClass(dex_file.GetTypeDescriptor(dex_file.GetTypeId(type_idx)))) {
+ if (IsImage() &&
+ IsImageClass(dex_file.StringDataAsStringPieceByIdx(dex_file.GetTypeId(type_idx).descriptor_idx_))) {
if (kIsDebugBuild) {
ScopedObjectAccess soa(Thread::Current());
mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
@@ -1098,7 +1098,7 @@
if (compiling_boot) {
if (support_boot_image_fixup_) {
MethodHelper mh(method);
- if (IsImageClass(mh.GetDeclaringClassDescriptor())) {
+ if (IsImageClass(mh.GetDeclaringClassDescriptorAsStringPiece())) {
// We can only branch directly to Methods that are resolved in the DexCache.
// Otherwise we won't invoke the resolution trampoline.
*direct_method = -1;
@@ -1572,8 +1572,8 @@
CHECK(soa.Self()->IsExceptionPending());
mirror::Throwable* exception = soa.Self()->GetException(NULL);
VLOG(compiler) << "Exception during type resolution: " << exception->Dump();
- if (strcmp(ClassHelper(exception->GetClass()).GetDescriptor(),
- "Ljava/lang/OutOfMemoryError;") == 0) {
+ if (ClassHelper(exception->GetClass()).GetDescriptorAsStringPiece() ==
+ "Ljava/lang/OutOfMemoryError;") {
// There's little point continuing compilation if the heap is exhausted.
LOG(FATAL) << "Out of memory during type resolution for compilation";
}
@@ -2084,11 +2084,14 @@
static void InitializeClass(const ParallelCompilationManager* manager, size_t class_def_index)
LOCKS_EXCLUDED(Locks::mutator_lock_) {
ATRACE_CALL();
- const DexFile::ClassDef& class_def = manager->GetDexFile()->GetClassDef(class_def_index);
+ const DexFile* dex_file = manager->GetDexFile();
+ const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index);
+ const DexFile::TypeId& class_type_id = dex_file->GetTypeId(class_def.class_idx_);
+ StringPiece descriptor(dex_file->StringDataAsStringPieceByIdx(class_type_id.descriptor_idx_));
+
ScopedObjectAccess soa(Thread::Current());
mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader());
- const char* descriptor = manager->GetDexFile()->GetClassDescriptor(class_def);
- mirror::Class* klass = manager->GetClassLinker()->FindClass(descriptor, class_loader);
+ mirror::Class* klass = manager->GetClassLinker()->FindClass(descriptor.data(), class_loader);
if (klass != NULL) {
// Only try to initialize classes that were successfully verified.
if (klass->IsVerified()) {
@@ -2118,7 +2121,7 @@
bool is_black_listed = StringPiece(descriptor).ends_with("$NoPreloadHolder;");
if (!is_black_listed) {
for (size_t i = 0; i < arraysize(class_initializer_black_list); ++i) {
- if (StringPiece(descriptor) == class_initializer_black_list[i]) {
+ if (descriptor == class_initializer_black_list[i]) {
is_black_listed = true;
break;
}
@@ -2126,7 +2129,7 @@
}
if (!is_black_listed) {
VLOG(compiler) << "Initializing: " << descriptor;
- if (StringPiece(descriptor) == "Ljava/lang/Void;") {
+ if (descriptor == "Ljava/lang/Void;") {
// Hand initialize j.l.Void to avoid Dex file operations in un-started runtime.
ObjectLock lock(soa.Self(), klass);
mirror::ObjectArray<mirror::ArtField>* fields = klass->GetSFields();
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 66c9cbf..7657af5 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -309,7 +309,7 @@
}
// Checks if class specified by type_idx is one of the image_classes_
- bool IsImageClass(const char* descriptor) const;
+ bool IsImageClass(const StringPiece& descriptor) const;
void RecordClassStatus(ClassReference ref, mirror::Class::Status status)
LOCKS_EXCLUDED(compiled_classes_lock_);
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index f82c6fb..bcdc1c1 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -241,7 +241,7 @@
}
bool ImageWriter::IsImageClass(const Class* klass) {
- return compiler_driver_.IsImageClass(ClassHelper(klass).GetDescriptor());
+ return compiler_driver_.IsImageClass(ClassHelper(klass).GetDescriptorAsStringPiece());
}
struct NonImageClasses {
@@ -296,7 +296,7 @@
bool ImageWriter::NonImageClassesVisitor(Class* klass, void* arg) {
NonImageClasses* context = reinterpret_cast<NonImageClasses*>(arg);
if (!context->image_writer->IsImageClass(klass)) {
- context->non_image_classes->insert(ClassHelper(klass).GetDescriptor());
+ context->non_image_classes->insert(ClassHelper(klass).GetDescriptorAsStringPiece().as_string());
}
return true;
}