1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_LIBDEXFILE_DEX_COMPACT_DEX_FILE_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_LIBDEXFILE_DEX_COMPACT_DEX_FILE_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include <memory> 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker #include "base/casts.h" 23*795d594fSAndroid Build Coastguard Worker #include "dex/compact_offset_table.h" 24*795d594fSAndroid Build Coastguard Worker #include "dex_file.h" 25*795d594fSAndroid Build Coastguard Worker 26*795d594fSAndroid Build Coastguard Worker namespace art { 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker // CompactDex is a currently ART internal dex file format that aims to reduce storage/RAM usage. 29*795d594fSAndroid Build Coastguard Worker class CompactDexFile : public DexFile { 30*795d594fSAndroid Build Coastguard Worker public: 31*795d594fSAndroid Build Coastguard Worker static constexpr uint8_t kDexMagic[kDexMagicSize] = { 'c', 'd', 'e', 'x' }; 32*795d594fSAndroid Build Coastguard Worker // Last change: remove code item deduping. 33*795d594fSAndroid Build Coastguard Worker static constexpr uint8_t kDexMagicVersion[] = {'0', '0', '1', '\0'}; 34*795d594fSAndroid Build Coastguard Worker 35*795d594fSAndroid Build Coastguard Worker enum class FeatureFlags : uint32_t { 36*795d594fSAndroid Build Coastguard Worker kDefaultMethods = 0x1, 37*795d594fSAndroid Build Coastguard Worker }; 38*795d594fSAndroid Build Coastguard Worker 39*795d594fSAndroid Build Coastguard Worker class Header : public DexFile::Header { 40*795d594fSAndroid Build Coastguard Worker public: At(const void * at)41*795d594fSAndroid Build Coastguard Worker static const Header* At(const void* at) { 42*795d594fSAndroid Build Coastguard Worker return reinterpret_cast<const Header*>(at); 43*795d594fSAndroid Build Coastguard Worker } 44*795d594fSAndroid Build Coastguard Worker GetFeatureFlags()45*795d594fSAndroid Build Coastguard Worker uint32_t GetFeatureFlags() const { 46*795d594fSAndroid Build Coastguard Worker return feature_flags_; 47*795d594fSAndroid Build Coastguard Worker } 48*795d594fSAndroid Build Coastguard Worker GetDataOffset()49*795d594fSAndroid Build Coastguard Worker uint32_t GetDataOffset() const { 50*795d594fSAndroid Build Coastguard Worker return data_off_; 51*795d594fSAndroid Build Coastguard Worker } 52*795d594fSAndroid Build Coastguard Worker GetDataSize()53*795d594fSAndroid Build Coastguard Worker uint32_t GetDataSize() const { 54*795d594fSAndroid Build Coastguard Worker return data_size_; 55*795d594fSAndroid Build Coastguard Worker } 56*795d594fSAndroid Build Coastguard Worker 57*795d594fSAndroid Build Coastguard Worker // Range of the shared data section owned by the dex file. Owned in this context refers to data 58*795d594fSAndroid Build Coastguard Worker // for this DEX that was not deduplicated to another DEX. OwnedDataBegin()59*795d594fSAndroid Build Coastguard Worker uint32_t OwnedDataBegin() const { 60*795d594fSAndroid Build Coastguard Worker return owned_data_begin_; 61*795d594fSAndroid Build Coastguard Worker } 62*795d594fSAndroid Build Coastguard Worker OwnedDataEnd()63*795d594fSAndroid Build Coastguard Worker uint32_t OwnedDataEnd() const { 64*795d594fSAndroid Build Coastguard Worker return owned_data_end_; 65*795d594fSAndroid Build Coastguard Worker } 66*795d594fSAndroid Build Coastguard Worker 67*795d594fSAndroid Build Coastguard Worker private: 68*795d594fSAndroid Build Coastguard Worker uint32_t feature_flags_ = 0u; 69*795d594fSAndroid Build Coastguard Worker 70*795d594fSAndroid Build Coastguard Worker // Position in the compact dex file for the debug info table data starts. 71*795d594fSAndroid Build Coastguard Worker uint32_t debug_info_offsets_pos_ = 0u; 72*795d594fSAndroid Build Coastguard Worker 73*795d594fSAndroid Build Coastguard Worker // Offset into the debug info table data where the lookup table is. 74*795d594fSAndroid Build Coastguard Worker uint32_t debug_info_offsets_table_offset_ = 0u; 75*795d594fSAndroid Build Coastguard Worker 76*795d594fSAndroid Build Coastguard Worker // Base offset of where debug info starts in the dex file. 77*795d594fSAndroid Build Coastguard Worker uint32_t debug_info_base_ = 0u; 78*795d594fSAndroid Build Coastguard Worker 79*795d594fSAndroid Build Coastguard Worker // Range of the shared data section owned by the dex file. 80*795d594fSAndroid Build Coastguard Worker uint32_t owned_data_begin_ = 0u; 81*795d594fSAndroid Build Coastguard Worker uint32_t owned_data_end_ = 0u; 82*795d594fSAndroid Build Coastguard Worker 83*795d594fSAndroid Build Coastguard Worker friend class CompactDexFile; 84*795d594fSAndroid Build Coastguard Worker friend class CompactDexWriter; 85*795d594fSAndroid Build Coastguard Worker }; 86*795d594fSAndroid Build Coastguard Worker 87*795d594fSAndroid Build Coastguard Worker // Like the standard code item except without a debug info offset. Each code item may have a 88*795d594fSAndroid Build Coastguard Worker // preheader to encode large methods. In 99% of cases, the preheader is not used. This enables 89*795d594fSAndroid Build Coastguard Worker // smaller size with a good fast path case in the accessors. 90*795d594fSAndroid Build Coastguard Worker struct CodeItem : public dex::CodeItem { 91*795d594fSAndroid Build Coastguard Worker static constexpr size_t kAlignment = sizeof(uint16_t); 92*795d594fSAndroid Build Coastguard Worker // Max preheader size in uint16_ts. 93*795d594fSAndroid Build Coastguard Worker static constexpr size_t kMaxPreHeaderSize = 6; 94*795d594fSAndroid Build Coastguard Worker FieldsOffsetCodeItem95*795d594fSAndroid Build Coastguard Worker static constexpr size_t FieldsOffset() { 96*795d594fSAndroid Build Coastguard Worker return OFFSETOF_MEMBER(CodeItem, fields_); 97*795d594fSAndroid Build Coastguard Worker } 98*795d594fSAndroid Build Coastguard Worker InsnsCountAndFlagsOffsetCodeItem99*795d594fSAndroid Build Coastguard Worker static constexpr size_t InsnsCountAndFlagsOffset() { 100*795d594fSAndroid Build Coastguard Worker return OFFSETOF_MEMBER(CodeItem, insns_count_and_flags_); 101*795d594fSAndroid Build Coastguard Worker } 102*795d594fSAndroid Build Coastguard Worker InsnsOffsetCodeItem103*795d594fSAndroid Build Coastguard Worker static constexpr size_t InsnsOffset() { 104*795d594fSAndroid Build Coastguard Worker return OFFSETOF_MEMBER(CodeItem, insns_); 105*795d594fSAndroid Build Coastguard Worker } 106*795d594fSAndroid Build Coastguard Worker 107*795d594fSAndroid Build Coastguard Worker static constexpr size_t kRegistersSizeShift = 12; 108*795d594fSAndroid Build Coastguard Worker static constexpr size_t kInsSizeShift = 8; 109*795d594fSAndroid Build Coastguard Worker static constexpr size_t kOutsSizeShift = 4; 110*795d594fSAndroid Build Coastguard Worker static constexpr size_t kTriesSizeSizeShift = 0; 111*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kBitPreHeaderRegistersSize = 0; 112*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kBitPreHeaderInsSize = 1; 113*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kBitPreHeaderOutsSize = 2; 114*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kBitPreHeaderTriesSize = 3; 115*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kBitPreHeaderInsnsSize = 4; 116*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kFlagPreHeaderRegistersSize = 0x1 << kBitPreHeaderRegistersSize; 117*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kFlagPreHeaderInsSize = 0x1 << kBitPreHeaderInsSize; 118*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kFlagPreHeaderOutsSize = 0x1 << kBitPreHeaderOutsSize; 119*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kFlagPreHeaderTriesSize = 0x1 << kBitPreHeaderTriesSize; 120*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kFlagPreHeaderInsnsSize = 0x1 << kBitPreHeaderInsnsSize; 121*795d594fSAndroid Build Coastguard Worker static constexpr size_t kInsnsSizeShift = 5; 122*795d594fSAndroid Build Coastguard Worker static constexpr size_t kInsnsSizeBits = sizeof(uint16_t) * kBitsPerByte - kInsnsSizeShift; 123*795d594fSAndroid Build Coastguard Worker 124*795d594fSAndroid Build Coastguard Worker private: 125*795d594fSAndroid Build Coastguard Worker CodeItem() = default; 126*795d594fSAndroid Build Coastguard Worker 127*795d594fSAndroid Build Coastguard Worker // Combined preheader flags for fast testing if we need to go slow path. 128*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kFlagPreHeaderCombined = 129*795d594fSAndroid Build Coastguard Worker kFlagPreHeaderRegistersSize | 130*795d594fSAndroid Build Coastguard Worker kFlagPreHeaderInsSize | 131*795d594fSAndroid Build Coastguard Worker kFlagPreHeaderOutsSize | 132*795d594fSAndroid Build Coastguard Worker kFlagPreHeaderTriesSize | 133*795d594fSAndroid Build Coastguard Worker kFlagPreHeaderInsnsSize; 134*795d594fSAndroid Build Coastguard Worker 135*795d594fSAndroid Build Coastguard Worker // Create a code item and associated preheader if required based on field values. 136*795d594fSAndroid Build Coastguard Worker // Returns the start of the preheader. The preheader buffer must be at least as large as 137*795d594fSAndroid Build Coastguard Worker // kMaxPreHeaderSize; CreateCodeItem138*795d594fSAndroid Build Coastguard Worker uint16_t* Create(uint16_t registers_size, 139*795d594fSAndroid Build Coastguard Worker uint16_t ins_size, 140*795d594fSAndroid Build Coastguard Worker uint16_t outs_size, 141*795d594fSAndroid Build Coastguard Worker uint16_t tries_size, 142*795d594fSAndroid Build Coastguard Worker uint32_t insns_size_in_code_units, 143*795d594fSAndroid Build Coastguard Worker uint16_t* out_preheader) { 144*795d594fSAndroid Build Coastguard Worker // Dex verification ensures that registers size > ins_size, so we can subtract the registers 145*795d594fSAndroid Build Coastguard Worker // size accordingly to reduce how often we need to use the preheader. 146*795d594fSAndroid Build Coastguard Worker DCHECK_GE(registers_size, ins_size); 147*795d594fSAndroid Build Coastguard Worker registers_size -= ins_size; 148*795d594fSAndroid Build Coastguard Worker fields_ = (registers_size & 0xF) << kRegistersSizeShift; 149*795d594fSAndroid Build Coastguard Worker fields_ |= (ins_size & 0xF) << kInsSizeShift; 150*795d594fSAndroid Build Coastguard Worker fields_ |= (outs_size & 0xF) << kOutsSizeShift; 151*795d594fSAndroid Build Coastguard Worker fields_ |= (tries_size & 0xF) << kTriesSizeSizeShift; 152*795d594fSAndroid Build Coastguard Worker registers_size &= ~0xF; 153*795d594fSAndroid Build Coastguard Worker ins_size &= ~0xF; 154*795d594fSAndroid Build Coastguard Worker outs_size &= ~0xF; 155*795d594fSAndroid Build Coastguard Worker tries_size &= ~0xF; 156*795d594fSAndroid Build Coastguard Worker insns_count_and_flags_ = 0; 157*795d594fSAndroid Build Coastguard Worker const size_t masked_count = insns_size_in_code_units & ((1 << kInsnsSizeBits) - 1); 158*795d594fSAndroid Build Coastguard Worker insns_count_and_flags_ |= masked_count << kInsnsSizeShift; 159*795d594fSAndroid Build Coastguard Worker insns_size_in_code_units -= masked_count; 160*795d594fSAndroid Build Coastguard Worker 161*795d594fSAndroid Build Coastguard Worker // Since the preheader case is rare (1% of code items), use a suboptimally large but fast 162*795d594fSAndroid Build Coastguard Worker // decoding format. 163*795d594fSAndroid Build Coastguard Worker if (insns_size_in_code_units != 0) { 164*795d594fSAndroid Build Coastguard Worker insns_count_and_flags_ |= kFlagPreHeaderInsnsSize; 165*795d594fSAndroid Build Coastguard Worker --out_preheader; 166*795d594fSAndroid Build Coastguard Worker *out_preheader = static_cast<uint16_t>(insns_size_in_code_units); 167*795d594fSAndroid Build Coastguard Worker --out_preheader; 168*795d594fSAndroid Build Coastguard Worker *out_preheader = static_cast<uint16_t>(insns_size_in_code_units >> 16); 169*795d594fSAndroid Build Coastguard Worker } 170*795d594fSAndroid Build Coastguard Worker auto preheader_encode = [&](uint16_t size, uint16_t flag) { 171*795d594fSAndroid Build Coastguard Worker if (size != 0) { 172*795d594fSAndroid Build Coastguard Worker insns_count_and_flags_ |= flag; 173*795d594fSAndroid Build Coastguard Worker --out_preheader; 174*795d594fSAndroid Build Coastguard Worker *out_preheader = size; 175*795d594fSAndroid Build Coastguard Worker } 176*795d594fSAndroid Build Coastguard Worker }; 177*795d594fSAndroid Build Coastguard Worker preheader_encode(registers_size, kFlagPreHeaderRegistersSize); 178*795d594fSAndroid Build Coastguard Worker preheader_encode(ins_size, kFlagPreHeaderInsSize); 179*795d594fSAndroid Build Coastguard Worker preheader_encode(outs_size, kFlagPreHeaderOutsSize); 180*795d594fSAndroid Build Coastguard Worker preheader_encode(tries_size, kFlagPreHeaderTriesSize); 181*795d594fSAndroid Build Coastguard Worker return out_preheader; 182*795d594fSAndroid Build Coastguard Worker } 183*795d594fSAndroid Build Coastguard Worker HasPreHeaderCodeItem184*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE bool HasPreHeader(uint16_t flag) const { 185*795d594fSAndroid Build Coastguard Worker return (insns_count_and_flags_ & flag) != 0; 186*795d594fSAndroid Build Coastguard Worker } 187*795d594fSAndroid Build Coastguard Worker 188*795d594fSAndroid Build Coastguard Worker // Return true if the code item has any preheaders. HasAnyPreHeaderCodeItem189*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE static bool HasAnyPreHeader(uint16_t insns_count_and_flags) { 190*795d594fSAndroid Build Coastguard Worker return (insns_count_and_flags & kFlagPreHeaderCombined) != 0; 191*795d594fSAndroid Build Coastguard Worker } 192*795d594fSAndroid Build Coastguard Worker GetPreHeaderCodeItem193*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE uint16_t* GetPreHeader() { 194*795d594fSAndroid Build Coastguard Worker return reinterpret_cast<uint16_t*>(this); 195*795d594fSAndroid Build Coastguard Worker } 196*795d594fSAndroid Build Coastguard Worker GetPreHeaderCodeItem197*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE const uint16_t* GetPreHeader() const { 198*795d594fSAndroid Build Coastguard Worker return reinterpret_cast<const uint16_t*>(this); 199*795d594fSAndroid Build Coastguard Worker } 200*795d594fSAndroid Build Coastguard Worker 201*795d594fSAndroid Build Coastguard Worker // Decode fields and read the preheader if necessary. If kDecodeOnlyInstructionCount is 202*795d594fSAndroid Build Coastguard Worker // specified then only the instruction count is decoded. 203*795d594fSAndroid Build Coastguard Worker template <bool kDecodeOnlyInstructionCount> DecodeFieldsCodeItem204*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE void DecodeFields(uint32_t* insns_count, 205*795d594fSAndroid Build Coastguard Worker uint16_t* registers_size, 206*795d594fSAndroid Build Coastguard Worker uint16_t* ins_size, 207*795d594fSAndroid Build Coastguard Worker uint16_t* outs_size, 208*795d594fSAndroid Build Coastguard Worker uint16_t* tries_size) const { 209*795d594fSAndroid Build Coastguard Worker *insns_count = insns_count_and_flags_ >> kInsnsSizeShift; 210*795d594fSAndroid Build Coastguard Worker if (!kDecodeOnlyInstructionCount) { 211*795d594fSAndroid Build Coastguard Worker const uint16_t fields = fields_; 212*795d594fSAndroid Build Coastguard Worker *registers_size = (fields >> kRegistersSizeShift) & 0xF; 213*795d594fSAndroid Build Coastguard Worker *ins_size = (fields >> kInsSizeShift) & 0xF; 214*795d594fSAndroid Build Coastguard Worker *outs_size = (fields >> kOutsSizeShift) & 0xF; 215*795d594fSAndroid Build Coastguard Worker *tries_size = (fields >> kTriesSizeSizeShift) & 0xF; 216*795d594fSAndroid Build Coastguard Worker } 217*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(HasAnyPreHeader(insns_count_and_flags_))) { 218*795d594fSAndroid Build Coastguard Worker const uint16_t* preheader = GetPreHeader(); 219*795d594fSAndroid Build Coastguard Worker if (HasPreHeader(kFlagPreHeaderInsnsSize)) { 220*795d594fSAndroid Build Coastguard Worker --preheader; 221*795d594fSAndroid Build Coastguard Worker *insns_count += static_cast<uint32_t>(*preheader); 222*795d594fSAndroid Build Coastguard Worker --preheader; 223*795d594fSAndroid Build Coastguard Worker *insns_count += static_cast<uint32_t>(*preheader) << 16; 224*795d594fSAndroid Build Coastguard Worker } 225*795d594fSAndroid Build Coastguard Worker if (!kDecodeOnlyInstructionCount) { 226*795d594fSAndroid Build Coastguard Worker if (HasPreHeader(kFlagPreHeaderRegistersSize)) { 227*795d594fSAndroid Build Coastguard Worker --preheader; 228*795d594fSAndroid Build Coastguard Worker *registers_size += preheader[0]; 229*795d594fSAndroid Build Coastguard Worker } 230*795d594fSAndroid Build Coastguard Worker if (HasPreHeader(kFlagPreHeaderInsSize)) { 231*795d594fSAndroid Build Coastguard Worker --preheader; 232*795d594fSAndroid Build Coastguard Worker *ins_size += preheader[0]; 233*795d594fSAndroid Build Coastguard Worker } 234*795d594fSAndroid Build Coastguard Worker if (HasPreHeader(kFlagPreHeaderOutsSize)) { 235*795d594fSAndroid Build Coastguard Worker --preheader; 236*795d594fSAndroid Build Coastguard Worker *outs_size += preheader[0]; 237*795d594fSAndroid Build Coastguard Worker } 238*795d594fSAndroid Build Coastguard Worker if (HasPreHeader(kFlagPreHeaderTriesSize)) { 239*795d594fSAndroid Build Coastguard Worker --preheader; 240*795d594fSAndroid Build Coastguard Worker *tries_size += preheader[0]; 241*795d594fSAndroid Build Coastguard Worker } 242*795d594fSAndroid Build Coastguard Worker } 243*795d594fSAndroid Build Coastguard Worker } 244*795d594fSAndroid Build Coastguard Worker if (!kDecodeOnlyInstructionCount) { 245*795d594fSAndroid Build Coastguard Worker *registers_size += *ins_size; 246*795d594fSAndroid Build Coastguard Worker } 247*795d594fSAndroid Build Coastguard Worker } 248*795d594fSAndroid Build Coastguard Worker 249*795d594fSAndroid Build Coastguard Worker // Packed code item data, 4 bits each: [registers_size, ins_size, outs_size, tries_size] 250*795d594fSAndroid Build Coastguard Worker uint16_t fields_; 251*795d594fSAndroid Build Coastguard Worker 252*795d594fSAndroid Build Coastguard Worker // 5 bits for if either of the fields required preheader extension, 11 bits for the number of 253*795d594fSAndroid Build Coastguard Worker // instruction code units. 254*795d594fSAndroid Build Coastguard Worker uint16_t insns_count_and_flags_; 255*795d594fSAndroid Build Coastguard Worker 256*795d594fSAndroid Build Coastguard Worker uint16_t insns_[1]; // actual array of bytecode. 257*795d594fSAndroid Build Coastguard Worker 258*795d594fSAndroid Build Coastguard Worker ART_FRIEND_TEST(CodeItemAccessorsTest, TestDexInstructionsAccessor); 259*795d594fSAndroid Build Coastguard Worker ART_FRIEND_TEST(CompactDexFileTest, CodeItemFields); 260*795d594fSAndroid Build Coastguard Worker friend class CodeItemDataAccessor; 261*795d594fSAndroid Build Coastguard Worker friend class CodeItemDebugInfoAccessor; 262*795d594fSAndroid Build Coastguard Worker friend class CodeItemInstructionAccessor; 263*795d594fSAndroid Build Coastguard Worker friend class CompactDexFile; 264*795d594fSAndroid Build Coastguard Worker friend class CompactDexWriter; 265*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(CodeItem); 266*795d594fSAndroid Build Coastguard Worker }; 267*795d594fSAndroid Build Coastguard Worker 268*795d594fSAndroid Build Coastguard Worker // Write the compact dex specific magic. 269*795d594fSAndroid Build Coastguard Worker static void WriteMagic(uint8_t* magic); 270*795d594fSAndroid Build Coastguard Worker 271*795d594fSAndroid Build Coastguard Worker // Write the current version, note that the input is the address of the magic. 272*795d594fSAndroid Build Coastguard Worker static void WriteCurrentVersion(uint8_t* magic); 273*795d594fSAndroid Build Coastguard Worker 274*795d594fSAndroid Build Coastguard Worker // Returns true if the byte string points to the magic value. 275*795d594fSAndroid Build Coastguard Worker static bool IsMagicValid(const uint8_t* magic); IsMagicValid(DexFile::Magic magic)276*795d594fSAndroid Build Coastguard Worker static bool IsMagicValid(DexFile::Magic magic) { return IsMagicValid(magic.data()); } 277*795d594fSAndroid Build Coastguard Worker bool IsMagicValid() const override; 278*795d594fSAndroid Build Coastguard Worker 279*795d594fSAndroid Build Coastguard Worker // Returns true if the byte string after the magic is the correct value. 280*795d594fSAndroid Build Coastguard Worker static bool IsVersionValid(const uint8_t* magic); 281*795d594fSAndroid Build Coastguard Worker bool IsVersionValid() const override; 282*795d594fSAndroid Build Coastguard Worker 283*795d594fSAndroid Build Coastguard Worker // TODO This is completely a guess. We really need to do better. b/72402467 284*795d594fSAndroid Build Coastguard Worker // We ask for 64 megabytes which should be big enough for any realistic dex file. GetDequickenedSize()285*795d594fSAndroid Build Coastguard Worker size_t GetDequickenedSize() const override { 286*795d594fSAndroid Build Coastguard Worker return 64 * MB; 287*795d594fSAndroid Build Coastguard Worker } 288*795d594fSAndroid Build Coastguard Worker GetHeader()289*795d594fSAndroid Build Coastguard Worker const Header& GetHeader() const { 290*795d594fSAndroid Build Coastguard Worker return down_cast<const Header&>(DexFile::GetHeader()); 291*795d594fSAndroid Build Coastguard Worker } 292*795d594fSAndroid Build Coastguard Worker 293*795d594fSAndroid Build Coastguard Worker bool SupportsDefaultMethods() const override; 294*795d594fSAndroid Build Coastguard Worker 295*795d594fSAndroid Build Coastguard Worker uint32_t GetCodeItemSize(const dex::CodeItem& item) const override; 296*795d594fSAndroid Build Coastguard Worker GetDebugInfoOffset(uint32_t dex_method_index)297*795d594fSAndroid Build Coastguard Worker uint32_t GetDebugInfoOffset(uint32_t dex_method_index) const { 298*795d594fSAndroid Build Coastguard Worker return debug_info_offsets_.GetOffset(dex_method_index); 299*795d594fSAndroid Build Coastguard Worker } 300*795d594fSAndroid Build Coastguard Worker 301*795d594fSAndroid Build Coastguard Worker static uint32_t CalculateChecksum(const uint8_t* base_begin, 302*795d594fSAndroid Build Coastguard Worker size_t base_size, 303*795d594fSAndroid Build Coastguard Worker const uint8_t* data_begin, 304*795d594fSAndroid Build Coastguard Worker size_t data_size); 305*795d594fSAndroid Build Coastguard Worker uint32_t CalculateChecksum() const override; 306*795d594fSAndroid Build Coastguard Worker 307*795d594fSAndroid Build Coastguard Worker private: 308*795d594fSAndroid Build Coastguard Worker CompactDexFile(const uint8_t* base, 309*795d594fSAndroid Build Coastguard Worker const std::string& location, 310*795d594fSAndroid Build Coastguard Worker uint32_t location_checksum, 311*795d594fSAndroid Build Coastguard Worker const OatDexFile* oat_dex_file, 312*795d594fSAndroid Build Coastguard Worker // Shared since several dex files may be stored in the same logical container. 313*795d594fSAndroid Build Coastguard Worker std::shared_ptr<DexFileContainer> container); 314*795d594fSAndroid Build Coastguard Worker 315*795d594fSAndroid Build Coastguard Worker CompactOffsetTable::Accessor debug_info_offsets_; 316*795d594fSAndroid Build Coastguard Worker 317*795d594fSAndroid Build Coastguard Worker friend class DexFile; 318*795d594fSAndroid Build Coastguard Worker friend class DexFileLoader; 319*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(CompactDexFile); 320*795d594fSAndroid Build Coastguard Worker }; 321*795d594fSAndroid Build Coastguard Worker 322*795d594fSAndroid Build Coastguard Worker } // namespace art 323*795d594fSAndroid Build Coastguard Worker 324*795d594fSAndroid Build Coastguard Worker #endif // ART_LIBDEXFILE_DEX_COMPACT_DEX_FILE_H_ 325