diff options
author | Hiroshi Yamauchi <yamauchi@google.com> | 2014-01-15 11:46:48 -0800 |
---|---|---|
committer | Hiroshi Yamauchi <yamauchi@google.com> | 2014-01-23 15:29:12 -0800 |
commit | be1ca55db3362f5b100c4c65da5342fd299520bb (patch) | |
tree | b9df6f5562d884698ed15f21764a704bb51e359e /compiler/image_writer.cc | |
parent | 9d8918fe97c235fdc6eb2c7f2d50a6673ab50329 (diff) | |
download | art-be1ca55db3362f5b100c4c65da5342fd299520bb.zip art-be1ca55db3362f5b100c4c65da5342fd299520bb.tar.gz art-be1ca55db3362f5b100c4c65da5342fd299520bb.tar.bz2 |
Use direct class pointers at allocation sites in the compiled code.
- Rather than looking up a class from its type ID (and checking if
it's resolved/initialized, resolving/initializing if not), use
direct class pointers, if possible (boot-code-to-boot-class pointers
and app-code-to-boot-class pointers.)
- This results in a 1-2% speedup in Ritz MemAllocTest on Nexus 4.
- Embedding the object size (along with class pointers) caused a 1-2%
slowdown in MemAllocTest and isn't implemented in this change.
- TODO: do the same for array allocations.
- TODO: when/if an application gets its own image, implement
app-code-to-app-class pointers.
- Fix a -XX:gc bug.
cf. https://android-review.googlesource.com/79460/
- Add /tmp/android-data/dalvik-cache to the list of locations to
remove oat files in clean-oat-host.
cf. https://android-review.googlesource.com/79550
- Add back a dropped UNLIKELY in FindMethodFromCode().
cf. https://android-review.googlesource.com/74205
Bug: 9986565
Change-Id: I590b96bd21f7a7472f88e36752e675547559a5b1
Diffstat (limited to 'compiler/image_writer.cc')
-rw-r--r-- | compiler/image_writer.cc | 66 |
1 files changed, 53 insertions, 13 deletions
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index 556dec2..09bb70c 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -734,7 +734,7 @@ void ImageWriter::FixupFields(const Object* orig, } } -static ArtMethod* GetTargetMethod(const CompilerDriver::PatchInformation* patch) +static ArtMethod* GetTargetMethod(const CompilerDriver::CallPatchInformation* patch) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); Thread* self = Thread::Current(); @@ -757,15 +757,34 @@ static ArtMethod* GetTargetMethod(const CompilerDriver::PatchInformation* patch) return method; } +static Class* GetTargetType(const CompilerDriver::TypePatchInformation* patch) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); + Thread* self = Thread::Current(); + SirtRef<mirror::DexCache> dex_cache(self, class_linker->FindDexCache(patch->GetDexFile())); + SirtRef<mirror::ClassLoader> class_loader(self, nullptr); + Class* klass = class_linker->ResolveType(patch->GetDexFile(), + patch->GetTargetTypeIdx(), + dex_cache, + class_loader); + CHECK(klass != NULL) + << patch->GetDexFile().GetLocation() << " " << patch->GetTargetTypeIdx(); + CHECK(dex_cache->GetResolvedTypes()->Get(patch->GetTargetTypeIdx()) == klass) + << patch->GetDexFile().GetLocation() << " " << patch->GetReferrerMethodIdx() << " " + << PrettyClass(dex_cache->GetResolvedTypes()->Get(patch->GetTargetTypeIdx())) << " " + << PrettyClass(klass); + return klass; +} + void ImageWriter::PatchOatCodeAndMethods() { Thread* self = Thread::Current(); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); const char* old_cause = self->StartAssertNoThreadSuspension("ImageWriter"); - typedef std::vector<const CompilerDriver::PatchInformation*> Patches; - const Patches& code_to_patch = compiler_driver_.GetCodeToPatch(); + typedef std::vector<const CompilerDriver::CallPatchInformation*> CallPatches; + const CallPatches& code_to_patch = compiler_driver_.GetCodeToPatch(); for (size_t i = 0; i < code_to_patch.size(); i++) { - const CompilerDriver::PatchInformation* patch = code_to_patch[i]; + const CompilerDriver::CallPatchInformation* patch = code_to_patch[i]; ArtMethod* target = GetTargetMethod(patch); uint32_t code = reinterpret_cast<uint32_t>(class_linker->GetOatCodeFor(target)); uint32_t code_base = reinterpret_cast<uint32_t>(&oat_file_->GetOatHeader()); @@ -773,13 +792,21 @@ void ImageWriter::PatchOatCodeAndMethods() { SetPatchLocation(patch, reinterpret_cast<uint32_t>(GetOatAddress(code_offset))); } - const Patches& methods_to_patch = compiler_driver_.GetMethodsToPatch(); + const CallPatches& methods_to_patch = compiler_driver_.GetMethodsToPatch(); for (size_t i = 0; i < methods_to_patch.size(); i++) { - const CompilerDriver::PatchInformation* patch = methods_to_patch[i]; + const CompilerDriver::CallPatchInformation* patch = methods_to_patch[i]; ArtMethod* target = GetTargetMethod(patch); SetPatchLocation(patch, reinterpret_cast<uint32_t>(GetImageAddress(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]; + Class* target = GetTargetType(patch); + SetPatchLocation(patch, reinterpret_cast<uint32_t>(GetImageAddress(target))); + } + // Update the image header with the new checksum after patching ImageHeader* image_header = reinterpret_cast<ImageHeader*>(image_->Begin()); image_header->SetOatChecksum(oat_file_->GetOatHeader().GetChecksum()); @@ -796,13 +823,26 @@ void ImageWriter::SetPatchLocation(const CompilerDriver::PatchInformation* patch uint8_t* base = reinterpret_cast<uint8_t*>(reinterpret_cast<uint32_t>(oat_code) & ~0x1); uint32_t* patch_location = reinterpret_cast<uint32_t*>(base + patch->GetLiteralOffset()); if (kIsDebugBuild) { - const DexFile::MethodId& id = patch->GetDexFile().GetMethodId(patch->GetTargetMethodIdx()); - uint32_t expected = reinterpret_cast<uint32_t>(&id); - uint32_t actual = *patch_location; - CHECK(actual == expected || actual == value) << std::hex - << "actual=" << actual - << "expected=" << expected - << "value=" << value; + if (patch->IsCall()) { + const CompilerDriver::CallPatchInformation* cpatch = patch->AsCall(); + const DexFile::MethodId& id = cpatch->GetDexFile().GetMethodId(cpatch->GetTargetMethodIdx()); + uint32_t expected = reinterpret_cast<uint32_t>(&id); + uint32_t actual = *patch_location; + CHECK(actual == expected || actual == value) << std::hex + << "actual=" << actual + << "expected=" << expected + << "value=" << value; + } + if (patch->IsType()) { + const CompilerDriver::TypePatchInformation* tpatch = patch->AsType(); + const DexFile::TypeId& id = tpatch->GetDexFile().GetTypeId(tpatch->GetTargetTypeIdx()); + uint32_t expected = reinterpret_cast<uint32_t>(&id); + uint32_t actual = *patch_location; + CHECK(actual == expected || actual == value) << std::hex + << "actual=" << actual + << "expected=" << expected + << "value=" << value; + } } *patch_location = value; oat_header.UpdateChecksum(patch_location, sizeof(value)); |