diff options
author | Mathieu Chartier <mathieuc@google.com> | 2014-11-10 11:08:06 -0800 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2014-11-18 12:27:37 -0800 |
commit | 2d7210188805292e463be4bcf7a133b654d7e0ea (patch) | |
tree | 7705a3bf841ae44b2396728fa22ed0b5dcb44dbf /patchoat | |
parent | e0491682d101c69bf88c3c24a965312129cbfa38 (diff) | |
download | art-2d7210188805292e463be4bcf7a133b654d7e0ea.zip art-2d7210188805292e463be4bcf7a133b654d7e0ea.tar.gz art-2d7210188805292e463be4bcf7a133b654d7e0ea.tar.bz2 |
Change 64 bit ArtMethod fields to be pointer sized
Changed the 64 bit entrypoint and gc map fields in ArtMethod to be
pointer sized. This saves a large amount of memory on 32 bit systems.
Reduces ArtMethod size by 16 bytes on 32 bit.
Total number of ArtMethod on low memory mako: 169957
Image size: 49203 methods -> 787248 image size reduction.
Zygote space size: 1070 methods -> 17120 size reduction.
App methods: ~120k -> 2 MB savings.
Savings per app on low memory mako: 125K+ per app
(less active apps -> more image methods per app).
Savings depend on how often the shared methods are on dirty pages vs
shared.
TODO in another CL, delete gc map field from ArtMethod since we
should be able to get it from the Oat method header.
Bug: 17643507
Change-Id: Ie9508f05907a9f693882d4d32a564460bf273ee8
(cherry picked from commit e832e64a7e82d7f72aedbd7d798fb929d458ee8f)
Diffstat (limited to 'patchoat')
-rw-r--r-- | patchoat/patchoat.cc | 35 | ||||
-rw-r--r-- | patchoat/patchoat.h | 19 |
2 files changed, 31 insertions, 23 deletions
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc index 6b6d11e..281649e 100644 --- a/patchoat/patchoat.cc +++ b/patchoat/patchoat.cc @@ -175,7 +175,7 @@ bool PatchOat::Patch(const std::string& image_location, off_t delta, } gc::space::ImageSpace* ispc = Runtime::Current()->GetHeap()->GetImageSpace(); - PatchOat p(image.release(), ispc->GetLiveBitmap(), ispc->GetMemMap(), + PatchOat p(isa, image.release(), ispc->GetLiveBitmap(), ispc->GetMemMap(), delta, timings); t.NewTiming("Patching files"); if (!p.PatchImage()) { @@ -297,7 +297,7 @@ bool PatchOat::Patch(File* input_oat, const std::string& image_location, off_t d CHECK(is_oat_pic == NOT_PIC); } - PatchOat p(elf.release(), image.release(), ispc->GetLiveBitmap(), ispc->GetMemMap(), + PatchOat p(isa, elf.release(), image.release(), ispc->GetLiveBitmap(), ispc->GetMemMap(), delta, timings); t.NewTiming("Patching files"); if (!skip_patching_oat && !p.PatchElf()) { @@ -532,39 +532,44 @@ void PatchOat::VisitObject(mirror::Object* object) { PatchOat::PatchVisitor visitor(this, copy); object->VisitReferences<true, kVerifyNone>(visitor, visitor); if (object->IsArtMethod<kVerifyNone>()) { - FixupMethod(static_cast<mirror::ArtMethod*>(object), - static_cast<mirror::ArtMethod*>(copy)); + FixupMethod(down_cast<mirror::ArtMethod*>(object), down_cast<mirror::ArtMethod*>(copy)); } } void PatchOat::FixupMethod(mirror::ArtMethod* object, mirror::ArtMethod* copy) { + const size_t pointer_size = InstructionSetPointerSize(isa_); // Just update the entry points if it looks like we should. // TODO: sanity check all the pointers' values uintptr_t portable = reinterpret_cast<uintptr_t>( - object->GetEntryPointFromPortableCompiledCode<kVerifyNone>()); + object->GetEntryPointFromPortableCompiledCodePtrSize<kVerifyNone>(pointer_size)); if (portable != 0) { - copy->SetEntryPointFromPortableCompiledCode(reinterpret_cast<void*>(portable + delta_)); + copy->SetEntryPointFromPortableCompiledCodePtrSize(reinterpret_cast<void*>(portable + delta_), + pointer_size); } uintptr_t quick= reinterpret_cast<uintptr_t>( - object->GetEntryPointFromQuickCompiledCode<kVerifyNone>()); + object->GetEntryPointFromQuickCompiledCodePtrSize<kVerifyNone>(pointer_size)); if (quick != 0) { - copy->SetEntryPointFromQuickCompiledCode(reinterpret_cast<void*>(quick + delta_)); + copy->SetEntryPointFromQuickCompiledCodePtrSize(reinterpret_cast<void*>(quick + delta_), + pointer_size); } uintptr_t interpreter = reinterpret_cast<uintptr_t>( - object->GetEntryPointFromInterpreter<kVerifyNone>()); + object->GetEntryPointFromInterpreterPtrSize<kVerifyNone>(pointer_size)); if (interpreter != 0) { - copy->SetEntryPointFromInterpreter( - reinterpret_cast<mirror::EntryPointFromInterpreter*>(interpreter + delta_)); + copy->SetEntryPointFromInterpreterPtrSize( + reinterpret_cast<mirror::EntryPointFromInterpreter*>(interpreter + delta_), pointer_size); } - uintptr_t native_method = reinterpret_cast<uintptr_t>(object->GetNativeMethod()); + uintptr_t native_method = reinterpret_cast<uintptr_t>( + object->GetEntryPointFromJniPtrSize(pointer_size)); if (native_method != 0) { - copy->SetNativeMethod(reinterpret_cast<void*>(native_method + delta_)); + copy->SetEntryPointFromJniPtrSize(reinterpret_cast<void*>(native_method + delta_), + pointer_size); } - uintptr_t native_gc_map = reinterpret_cast<uintptr_t>(object->GetNativeGcMap()); + uintptr_t native_gc_map = reinterpret_cast<uintptr_t>( + object->GetNativeGcMapPtrSize(pointer_size)); if (native_gc_map != 0) { - copy->SetNativeGcMap(reinterpret_cast<uint8_t*>(native_gc_map + delta_)); + copy->SetNativeGcMapPtrSize(reinterpret_cast<uint8_t*>(native_gc_map + delta_), pointer_size); } } diff --git a/patchoat/patchoat.h b/patchoat/patchoat.h index 5a3545b..578df3a 100644 --- a/patchoat/patchoat.h +++ b/patchoat/patchoat.h @@ -61,15 +61,16 @@ class PatchOat { // Takes ownership only of the ElfFile. All other pointers are only borrowed. PatchOat(ElfFile* oat_file, off_t delta, TimingLogger* timings) : oat_file_(oat_file), image_(nullptr), bitmap_(nullptr), heap_(nullptr), delta_(delta), - timings_(timings) {} - PatchOat(MemMap* image, gc::accounting::ContinuousSpaceBitmap* bitmap, + isa_(kNone), timings_(timings) {} + PatchOat(InstructionSet isa, MemMap* image, gc::accounting::ContinuousSpaceBitmap* bitmap, MemMap* heap, off_t delta, TimingLogger* timings) : image_(image), bitmap_(bitmap), heap_(heap), - delta_(delta), timings_(timings) {} - PatchOat(ElfFile* oat_file, MemMap* image, gc::accounting::ContinuousSpaceBitmap* bitmap, - MemMap* heap, off_t delta, TimingLogger* timings) + delta_(delta), isa_(isa), timings_(timings) {} + PatchOat(InstructionSet isa, ElfFile* oat_file, MemMap* image, + gc::accounting::ContinuousSpaceBitmap* bitmap, MemMap* heap, off_t delta, + TimingLogger* timings) : oat_file_(oat_file), image_(image), bitmap_(bitmap), heap_(heap), - delta_(delta), timings_(timings) {} + delta_(delta), isa_(isa), timings_(timings) {} ~PatchOat() {} // Was the .art image at image_path made with --compile-pic ? @@ -156,8 +157,10 @@ class PatchOat { const MemMap* const heap_; // The amount we are changing the offset by. const off_t delta_; - // Timing splits. - TimingLogger* const timings_; + // Active instruction set, used to know the entrypoint size. + const InstructionSet isa_; + + TimingLogger* timings_; DISALLOW_IMPLICIT_CONSTRUCTORS(PatchOat); }; |