From 6cfbdbc359ec5414d3e49f70d28f8c0e65b98d63 Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Tue, 25 Jul 2017 13:26:39 +0100 Subject: Use mmapped boot image intern table for PIC app HLoadString. Implement new HLoadString load kind for boot image strings referenced by PIC-compiled apps (i.e. prebuilts) that uses PC-relative load from a boot image InternTable mmapped into the apps .bss. This reduces the size of the PIC prebuilts that reference boot image strings compared to the kBssEntry as we can completely avoid the slow path and stack map. We separate the InternedStrings and ClassTable sections of the boot image (.art) file from the rest, aligning the start of the InternedStrings section to a page boundary. This may actually increase the size of the boot image file by a page but it also allows mprotecting() these tables as read-only. The ClassTable section is included in anticipation of a similar load kind for HLoadClass. Prebuilt services.odex for aosp_angler-userdebug (arm64): - before: 20862776 - after: 20308512 (-541KiB) Note that 92KiB savings could have been achieved by simply avoiding the read barrier, similar to the HLoadClass flag IsInBootImage(). Such flag is now unnecessary. Test: m test-art-host-gtest Test: testrunner.py --host Test: testrunner.py --host --pictest Test: testrunner.py --target on Nexus 6P. Test: testrunner.py --target --pictest on Nexus 6P. Test: Nexus 6P boots. Bug: 31951624 Change-Id: I5f2bf1fc0bb36a8483244317cfdfa69e192ef6c5 --- compiler/compiled_method.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'compiler/compiled_method.h') diff --git a/compiler/compiled_method.h b/compiler/compiled_method.h index 97127f58ed..c67c523eb3 100644 --- a/compiler/compiled_method.h +++ b/compiler/compiled_method.h @@ -126,6 +126,7 @@ class LinkerPatch { kTypeRelative, // NOTE: Actual patching is instruction_set-dependent. kTypeBssEntry, // NOTE: Actual patching is instruction_set-dependent. kStringRelative, // NOTE: Actual patching is instruction_set-dependent. + kStringInternTable, // NOTE: Actual patching is instruction_set-dependent. kStringBssEntry, // NOTE: Actual patching is instruction_set-dependent. kBakerReadBarrierBranch, // NOTE: Actual patching is instruction_set-dependent. }; @@ -196,6 +197,16 @@ class LinkerPatch { return patch; } + static LinkerPatch StringInternTablePatch(size_t literal_offset, + const DexFile* target_dex_file, + uint32_t pc_insn_offset, + uint32_t target_string_idx) { + LinkerPatch patch(literal_offset, Type::kStringInternTable, target_dex_file); + patch.string_idx_ = target_string_idx; + patch.pc_insn_offset_ = pc_insn_offset; + return patch; + } + static LinkerPatch StringBssEntryPatch(size_t literal_offset, const DexFile* target_dex_file, uint32_t pc_insn_offset, @@ -234,6 +245,7 @@ class LinkerPatch { case Type::kTypeRelative: case Type::kTypeBssEntry: case Type::kStringRelative: + case Type::kStringInternTable: case Type::kStringBssEntry: case Type::kBakerReadBarrierBranch: return true; @@ -264,12 +276,14 @@ class LinkerPatch { const DexFile* TargetStringDexFile() const { DCHECK(patch_type_ == Type::kStringRelative || + patch_type_ == Type::kStringInternTable || patch_type_ == Type::kStringBssEntry); return target_dex_file_; } dex::StringIndex TargetStringIndex() const { DCHECK(patch_type_ == Type::kStringRelative || + patch_type_ == Type::kStringInternTable || patch_type_ == Type::kStringBssEntry); return dex::StringIndex(string_idx_); } @@ -280,6 +294,7 @@ class LinkerPatch { patch_type_ == Type::kTypeRelative || patch_type_ == Type::kTypeBssEntry || patch_type_ == Type::kStringRelative || + patch_type_ == Type::kStringInternTable || patch_type_ == Type::kStringBssEntry); return pc_insn_offset_; } -- cgit v1.2.3-59-g8ed1b