Add fast string sharpening
String sharpening changes const strings to PC relative loads instead
of always going through the dex cache. This saves code size and
probably improves performance slightly.
Before: 49602992 system@framework@boot.oat
After: 49385904 system@framework@boot.oat
Pre-cursor to removing dex_cache_strings_ field from ArtMethod.
Bug: 17643507
Change-Id: I1787f48774631eee0accafeea257aa8d0e91e8d6
diff --git a/compiler/elf_patcher.cc b/compiler/elf_patcher.cc
index e8ccd67..1577166 100644
--- a/compiler/elf_patcher.cc
+++ b/compiler/elf_patcher.cc
@@ -96,6 +96,16 @@
return method;
}
+mirror::String* ElfPatcher::GetTargetString(const CompilerDriver::StringPatchInformation* patch) {
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ StackHandleScope<1> hs(Thread::Current());
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(patch->GetDexFile())));
+ mirror::String* string = class_linker->ResolveString(patch->GetDexFile(), patch->GetStringIdx(),
+ dex_cache);
+ CHECK(string != nullptr) << patch->GetDexFile().GetLocation() << " " << patch->GetStringIdx();
+ return string;
+}
+
mirror::Class* ElfPatcher::GetTargetType(const CompilerDriver::TypePatchInformation* patch) {
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
StackHandleScope<2> hs(Thread::Current());
@@ -183,7 +193,8 @@
if (write_patches_) {
patches_.reserve(compiler_driver_->GetCodeToPatch().size() +
compiler_driver_->GetMethodsToPatch().size() +
- compiler_driver_->GetClassesToPatch().size());
+ compiler_driver_->GetClassesToPatch().size() +
+ compiler_driver_->GetStringsToPatch().size());
}
Thread* self = Thread::Current();
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
@@ -248,13 +259,15 @@
SetPatchLocation(patch, PointerToLowMemUInt32(get_image_address_(cb_data_, target)));
}
- const std::vector<const CompilerDriver::TypePatchInformation*>& classes_to_patch =
- compiler_driver_->GetClassesToPatch();
- for (size_t i = 0; i < classes_to_patch.size(); i++) {
- const CompilerDriver::TypePatchInformation* patch = classes_to_patch[i];
+ for (const CompilerDriver::TypePatchInformation* patch : compiler_driver_->GetClassesToPatch()) {
mirror::Class* target = GetTargetType(patch);
SetPatchLocation(patch, PointerToLowMemUInt32(get_image_address_(cb_data_, target)));
}
+ for (const CompilerDriver::StringPatchInformation* patch :
+ compiler_driver_->GetStringsToPatch()) {
+ mirror::String* target = GetTargetString(patch);
+ SetPatchLocation(patch, PointerToLowMemUInt32(get_image_address_(cb_data_, target)));
+ }
self->EndAssertNoThreadSuspension(old_cause);