Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ART_RUNTIME_STACK_MAP_H_
     18 #define ART_RUNTIME_STACK_MAP_H_
     19 
     20 #include <limits>
     21 
     22 #include "arch/code_offset.h"
     23 #include "base/bit_vector.h"
     24 #include "base/bit_utils.h"
     25 #include "bit_memory_region.h"
     26 #include "dex_file.h"
     27 #include "memory_region.h"
     28 #include "method_info.h"
     29 #include "leb128.h"
     30 
     31 namespace art {
     32 
     33 class VariableIndentationOutputStream;
     34 
     35 // Size of a frame slot, in bytes.  This constant is a signed value,
     36 // to please the compiler in arithmetic operations involving int32_t
     37 // (signed) values.
     38 static constexpr ssize_t kFrameSlotSize = 4;
     39 
     40 // Size of Dex virtual registers.
     41 static constexpr size_t kVRegSize = 4;
     42 
     43 class ArtMethod;
     44 class CodeInfo;
     45 class StackMapEncoding;
     46 struct CodeInfoEncoding;
     47 
     48 /**
     49  * Classes in the following file are wrapper on stack map information backed
     50  * by a MemoryRegion. As such they read and write to the region, they don't have
     51  * their own fields.
     52  */
     53 
     54 // Dex register location container used by DexRegisterMap and StackMapStream.
     55 class DexRegisterLocation {
     56  public:
     57   /*
     58    * The location kind used to populate the Dex register information in a
     59    * StackMapStream can either be:
     60    * - kStack: vreg stored on the stack, value holds the stack offset;
     61    * - kInRegister: vreg stored in low 32 bits of a core physical register,
     62    *                value holds the register number;
     63    * - kInRegisterHigh: vreg stored in high 32 bits of a core physical register,
     64    *                    value holds the register number;
     65    * - kInFpuRegister: vreg stored in low 32 bits of an FPU register,
     66    *                   value holds the register number;
     67    * - kInFpuRegisterHigh: vreg stored in high 32 bits of an FPU register,
     68    *                       value holds the register number;
     69    * - kConstant: value holds the constant;
     70    *
     71    * In addition, DexRegisterMap also uses these values:
     72    * - kInStackLargeOffset: value holds a "large" stack offset (greater than
     73    *   or equal to 128 bytes);
     74    * - kConstantLargeValue: value holds a "large" constant (lower than 0, or
     75    *   or greater than or equal to 32);
     76    * - kNone: the register has no location, meaning it has not been set.
     77    */
     78   enum class Kind : uint8_t {
     79     // Short location kinds, for entries fitting on one byte (3 bits
     80     // for the kind, 5 bits for the value) in a DexRegisterMap.
     81     kInStack = 0,             // 0b000
     82     kInRegister = 1,          // 0b001
     83     kInRegisterHigh = 2,      // 0b010
     84     kInFpuRegister = 3,       // 0b011
     85     kInFpuRegisterHigh = 4,   // 0b100
     86     kConstant = 5,            // 0b101
     87 
     88     // Large location kinds, requiring a 5-byte encoding (1 byte for the
     89     // kind, 4 bytes for the value).
     90 
     91     // Stack location at a large offset, meaning that the offset value
     92     // divided by the stack frame slot size (4 bytes) cannot fit on a
     93     // 5-bit unsigned integer (i.e., this offset value is greater than
     94     // or equal to 2^5 * 4 = 128 bytes).
     95     kInStackLargeOffset = 6,  // 0b110
     96 
     97     // Large constant, that cannot fit on a 5-bit signed integer (i.e.,
     98     // lower than 0, or greater than or equal to 2^5 = 32).
     99     kConstantLargeValue = 7,  // 0b111
    100 
    101     // Entries with no location are not stored and do not need own marker.
    102     kNone = static_cast<uint8_t>(-1),
    103 
    104     kLastLocationKind = kConstantLargeValue
    105   };
    106 
    107   static_assert(
    108       sizeof(Kind) == 1u,
    109       "art::DexRegisterLocation::Kind has a size different from one byte.");
    110 
    111   static bool IsShortLocationKind(Kind kind) {
    112     switch (kind) {
    113       case Kind::kInStack:
    114       case Kind::kInRegister:
    115       case Kind::kInRegisterHigh:
    116       case Kind::kInFpuRegister:
    117       case Kind::kInFpuRegisterHigh:
    118       case Kind::kConstant:
    119         return true;
    120 
    121       case Kind::kInStackLargeOffset:
    122       case Kind::kConstantLargeValue:
    123         return false;
    124 
    125       case Kind::kNone:
    126         LOG(FATAL) << "Unexpected location kind";
    127     }
    128     UNREACHABLE();
    129   }
    130 
    131   // Convert `kind` to a "surface" kind, i.e. one that doesn't include
    132   // any value with a "large" qualifier.
    133   // TODO: Introduce another enum type for the surface kind?
    134   static Kind ConvertToSurfaceKind(Kind kind) {
    135     switch (kind) {
    136       case Kind::kInStack:
    137       case Kind::kInRegister:
    138       case Kind::kInRegisterHigh:
    139       case Kind::kInFpuRegister:
    140       case Kind::kInFpuRegisterHigh:
    141       case Kind::kConstant:
    142         return kind;
    143 
    144       case Kind::kInStackLargeOffset:
    145         return Kind::kInStack;
    146 
    147       case Kind::kConstantLargeValue:
    148         return Kind::kConstant;
    149 
    150       case Kind::kNone:
    151         return kind;
    152     }
    153     UNREACHABLE();
    154   }
    155 
    156   // Required by art::StackMapStream::LocationCatalogEntriesIndices.
    157   DexRegisterLocation() : kind_(Kind::kNone), value_(0) {}
    158 
    159   DexRegisterLocation(Kind kind, int32_t value) : kind_(kind), value_(value) {}
    160 
    161   static DexRegisterLocation None() {
    162     return DexRegisterLocation(Kind::kNone, 0);
    163   }
    164 
    165   // Get the "surface" kind of the location, i.e., the one that doesn't
    166   // include any value with a "large" qualifier.
    167   Kind GetKind() const {
    168     return ConvertToSurfaceKind(kind_);
    169   }
    170 
    171   // Get the value of the location.
    172   int32_t GetValue() const { return value_; }
    173 
    174   // Get the actual kind of the location.
    175   Kind GetInternalKind() const { return kind_; }
    176 
    177   bool operator==(DexRegisterLocation other) const {
    178     return kind_ == other.kind_ && value_ == other.value_;
    179   }
    180 
    181   bool operator!=(DexRegisterLocation other) const {
    182     return !(*this == other);
    183   }
    184 
    185  private:
    186   Kind kind_;
    187   int32_t value_;
    188 
    189   friend class DexRegisterLocationHashFn;
    190 };
    191 
    192 std::ostream& operator<<(std::ostream& stream, const DexRegisterLocation::Kind& kind);
    193 
    194 /**
    195  * Store information on unique Dex register locations used in a method.
    196  * The information is of the form:
    197  *
    198  *   [DexRegisterLocation+].
    199  *
    200  * DexRegisterLocations are either 1- or 5-byte wide (see art::DexRegisterLocation::Kind).
    201  */
    202 class DexRegisterLocationCatalog {
    203  public:
    204   explicit DexRegisterLocationCatalog(MemoryRegion region) : region_(region) {}
    205 
    206   // Short (compressed) location, fitting on one byte.
    207   typedef uint8_t ShortLocation;
    208 
    209   void SetRegisterInfo(size_t offset, const DexRegisterLocation& dex_register_location) {
    210     DexRegisterLocation::Kind kind = ComputeCompressedKind(dex_register_location);
    211     int32_t value = dex_register_location.GetValue();
    212     if (DexRegisterLocation::IsShortLocationKind(kind)) {
    213       // Short location.  Compress the kind and the value as a single byte.
    214       if (kind == DexRegisterLocation::Kind::kInStack) {
    215         // Instead of storing stack offsets expressed in bytes for
    216         // short stack locations, store slot offsets.  A stack offset
    217         // is a multiple of 4 (kFrameSlotSize).  This means that by
    218         // dividing it by 4, we can fit values from the [0, 128)
    219         // interval in a short stack location, and not just values
    220         // from the [0, 32) interval.
    221         DCHECK_EQ(value % kFrameSlotSize, 0);
    222         value /= kFrameSlotSize;
    223       }
    224       DCHECK(IsShortValue(value)) << value;
    225       region_.StoreUnaligned<ShortLocation>(offset, MakeShortLocation(kind, value));
    226     } else {
    227       // Large location.  Write the location on one byte and the value
    228       // on 4 bytes.
    229       DCHECK(!IsShortValue(value)) << value;
    230       if (kind == DexRegisterLocation::Kind::kInStackLargeOffset) {
    231         // Also divide large stack offsets by 4 for the sake of consistency.
    232         DCHECK_EQ(value % kFrameSlotSize, 0);
    233         value /= kFrameSlotSize;
    234       }
    235       // Data can be unaligned as the written Dex register locations can
    236       // either be 1-byte or 5-byte wide.  Use
    237       // art::MemoryRegion::StoreUnaligned instead of
    238       // art::MemoryRegion::Store to prevent unligned word accesses on ARM.
    239       region_.StoreUnaligned<DexRegisterLocation::Kind>(offset, kind);
    240       region_.StoreUnaligned<int32_t>(offset + sizeof(DexRegisterLocation::Kind), value);
    241     }
    242   }
    243 
    244   // Find the offset of the location catalog entry number `location_catalog_entry_index`.
    245   size_t FindLocationOffset(size_t location_catalog_entry_index) const {
    246     size_t offset = kFixedSize;
    247     // Skip the first `location_catalog_entry_index - 1` entries.
    248     for (uint16_t i = 0; i < location_catalog_entry_index; ++i) {
    249       // Read the first next byte and inspect its first 3 bits to decide
    250       // whether it is a short or a large location.
    251       DexRegisterLocation::Kind kind = ExtractKindAtOffset(offset);
    252       if (DexRegisterLocation::IsShortLocationKind(kind)) {
    253         // Short location.  Skip the current byte.
    254         offset += SingleShortEntrySize();
    255       } else {
    256         // Large location.  Skip the 5 next bytes.
    257         offset += SingleLargeEntrySize();
    258       }
    259     }
    260     return offset;
    261   }
    262 
    263   // Get the internal kind of entry at `location_catalog_entry_index`.
    264   DexRegisterLocation::Kind GetLocationInternalKind(size_t location_catalog_entry_index) const {
    265     if (location_catalog_entry_index == kNoLocationEntryIndex) {
    266       return DexRegisterLocation::Kind::kNone;
    267     }
    268     return ExtractKindAtOffset(FindLocationOffset(location_catalog_entry_index));
    269   }
    270 
    271   // Get the (surface) kind and value of entry at `location_catalog_entry_index`.
    272   DexRegisterLocation GetDexRegisterLocation(size_t location_catalog_entry_index) const {
    273     if (location_catalog_entry_index == kNoLocationEntryIndex) {
    274       return DexRegisterLocation::None();
    275     }
    276     size_t offset = FindLocationOffset(location_catalog_entry_index);
    277     // Read the first byte and inspect its first 3 bits to get the location.
    278     ShortLocation first_byte = region_.LoadUnaligned<ShortLocation>(offset);
    279     DexRegisterLocation::Kind kind = ExtractKindFromShortLocation(first_byte);
    280     if (DexRegisterLocation::IsShortLocationKind(kind)) {
    281       // Short location.  Extract the value from the remaining 5 bits.
    282       int32_t value = ExtractValueFromShortLocation(first_byte);
    283       if (kind == DexRegisterLocation::Kind::kInStack) {
    284         // Convert the stack slot (short) offset to a byte offset value.
    285         value *= kFrameSlotSize;
    286       }
    287       return DexRegisterLocation(kind, value);
    288     } else {
    289       // Large location.  Read the four next bytes to get the value.
    290       int32_t value = region_.LoadUnaligned<int32_t>(offset + sizeof(DexRegisterLocation::Kind));
    291       if (kind == DexRegisterLocation::Kind::kInStackLargeOffset) {
    292         // Convert the stack slot (large) offset to a byte offset value.
    293         value *= kFrameSlotSize;
    294       }
    295       return DexRegisterLocation(kind, value);
    296     }
    297   }
    298 
    299   // Compute the compressed kind of `location`.
    300   static DexRegisterLocation::Kind ComputeCompressedKind(const DexRegisterLocation& location) {
    301     DexRegisterLocation::Kind kind = location.GetInternalKind();
    302     switch (kind) {
    303       case DexRegisterLocation::Kind::kInStack:
    304         return IsShortStackOffsetValue(location.GetValue())
    305             ? DexRegisterLocation::Kind::kInStack
    306             : DexRegisterLocation::Kind::kInStackLargeOffset;
    307 
    308       case DexRegisterLocation::Kind::kInRegister:
    309       case DexRegisterLocation::Kind::kInRegisterHigh:
    310         DCHECK_GE(location.GetValue(), 0);
    311         DCHECK_LT(location.GetValue(), 1 << kValueBits);
    312         return kind;
    313 
    314       case DexRegisterLocation::Kind::kInFpuRegister:
    315       case DexRegisterLocation::Kind::kInFpuRegisterHigh:
    316         DCHECK_GE(location.GetValue(), 0);
    317         DCHECK_LT(location.GetValue(), 1 << kValueBits);
    318         return kind;
    319 
    320       case DexRegisterLocation::Kind::kConstant:
    321         return IsShortConstantValue(location.GetValue())
    322             ? DexRegisterLocation::Kind::kConstant
    323             : DexRegisterLocation::Kind::kConstantLargeValue;
    324 
    325       case DexRegisterLocation::Kind::kConstantLargeValue:
    326       case DexRegisterLocation::Kind::kInStackLargeOffset:
    327       case DexRegisterLocation::Kind::kNone:
    328         LOG(FATAL) << "Unexpected location kind " << kind;
    329     }
    330     UNREACHABLE();
    331   }
    332 
    333   // Can `location` be turned into a short location?
    334   static bool CanBeEncodedAsShortLocation(const DexRegisterLocation& location) {
    335     DexRegisterLocation::Kind kind = location.GetInternalKind();
    336     switch (kind) {
    337       case DexRegisterLocation::Kind::kInStack:
    338         return IsShortStackOffsetValue(location.GetValue());
    339 
    340       case DexRegisterLocation::Kind::kInRegister:
    341       case DexRegisterLocation::Kind::kInRegisterHigh:
    342       case DexRegisterLocation::Kind::kInFpuRegister:
    343       case DexRegisterLocation::Kind::kInFpuRegisterHigh:
    344         return true;
    345 
    346       case DexRegisterLocation::Kind::kConstant:
    347         return IsShortConstantValue(location.GetValue());
    348 
    349       case DexRegisterLocation::Kind::kConstantLargeValue:
    350       case DexRegisterLocation::Kind::kInStackLargeOffset:
    351       case DexRegisterLocation::Kind::kNone:
    352         LOG(FATAL) << "Unexpected location kind " << kind;
    353     }
    354     UNREACHABLE();
    355   }
    356 
    357   static size_t EntrySize(const DexRegisterLocation& location) {
    358     return CanBeEncodedAsShortLocation(location) ? SingleShortEntrySize() : SingleLargeEntrySize();
    359   }
    360 
    361   static size_t SingleShortEntrySize() {
    362     return sizeof(ShortLocation);
    363   }
    364 
    365   static size_t SingleLargeEntrySize() {
    366     return sizeof(DexRegisterLocation::Kind) + sizeof(int32_t);
    367   }
    368 
    369   size_t Size() const {
    370     return region_.size();
    371   }
    372 
    373   void Dump(VariableIndentationOutputStream* vios,
    374             const CodeInfo& code_info);
    375 
    376   // Special (invalid) Dex register location catalog entry index meaning
    377   // that there is no location for a given Dex register (i.e., it is
    378   // mapped to a DexRegisterLocation::Kind::kNone location).
    379   static constexpr size_t kNoLocationEntryIndex = -1;
    380 
    381  private:
    382   static constexpr int kFixedSize = 0;
    383 
    384   // Width of the kind "field" in a short location, in bits.
    385   static constexpr size_t kKindBits = 3;
    386   // Width of the value "field" in a short location, in bits.
    387   static constexpr size_t kValueBits = 5;
    388 
    389   static constexpr uint8_t kKindMask = (1 << kKindBits) - 1;
    390   static constexpr int32_t kValueMask = (1 << kValueBits) - 1;
    391   static constexpr size_t kKindOffset = 0;
    392   static constexpr size_t kValueOffset = kKindBits;
    393 
    394   static bool IsShortStackOffsetValue(int32_t value) {
    395     DCHECK_EQ(value % kFrameSlotSize, 0);
    396     return IsShortValue(value / kFrameSlotSize);
    397   }
    398 
    399   static bool IsShortConstantValue(int32_t value) {
    400     return IsShortValue(value);
    401   }
    402 
    403   static bool IsShortValue(int32_t value) {
    404     return IsUint<kValueBits>(value);
    405   }
    406 
    407   static ShortLocation MakeShortLocation(DexRegisterLocation::Kind kind, int32_t value) {
    408     uint8_t kind_integer_value = static_cast<uint8_t>(kind);
    409     DCHECK(IsUint<kKindBits>(kind_integer_value)) << kind_integer_value;
    410     DCHECK(IsShortValue(value)) << value;
    411     return (kind_integer_value & kKindMask) << kKindOffset
    412         | (value & kValueMask) << kValueOffset;
    413   }
    414 
    415   static DexRegisterLocation::Kind ExtractKindFromShortLocation(ShortLocation location) {
    416     uint8_t kind = (location >> kKindOffset) & kKindMask;
    417     DCHECK_LE(kind, static_cast<uint8_t>(DexRegisterLocation::Kind::kLastLocationKind));
    418     // We do not encode kNone locations in the stack map.
    419     DCHECK_NE(kind, static_cast<uint8_t>(DexRegisterLocation::Kind::kNone));
    420     return static_cast<DexRegisterLocation::Kind>(kind);
    421   }
    422 
    423   static int32_t ExtractValueFromShortLocation(ShortLocation location) {
    424     return (location >> kValueOffset) & kValueMask;
    425   }
    426 
    427   // Extract a location kind from the byte at position `offset`.
    428   DexRegisterLocation::Kind ExtractKindAtOffset(size_t offset) const {
    429     ShortLocation first_byte = region_.LoadUnaligned<ShortLocation>(offset);
    430     return ExtractKindFromShortLocation(first_byte);
    431   }
    432 
    433   MemoryRegion region_;
    434 
    435   friend class CodeInfo;
    436   friend class StackMapStream;
    437 };
    438 
    439 /* Information on Dex register locations for a specific PC, mapping a
    440  * stack map's Dex register to a location entry in a DexRegisterLocationCatalog.
    441  * The information is of the form:
    442  *
    443  *   [live_bit_mask, entries*]
    444  *
    445  * where entries are concatenated unsigned integer values encoded on a number
    446  * of bits (fixed per DexRegisterMap instances of a CodeInfo object) depending
    447  * on the number of entries in the Dex register location catalog
    448  * (see DexRegisterMap::SingleEntrySizeInBits).  The map is 1-byte aligned.
    449  */
    450 class DexRegisterMap {
    451  public:
    452   explicit DexRegisterMap(MemoryRegion region) : region_(region) {}
    453   DexRegisterMap() {}
    454 
    455   bool IsValid() const { return region_.pointer() != nullptr; }
    456 
    457   // Get the surface kind of Dex register `dex_register_number`.
    458   DexRegisterLocation::Kind GetLocationKind(uint16_t dex_register_number,
    459                                             uint16_t number_of_dex_registers,
    460                                             const CodeInfo& code_info,
    461                                             const CodeInfoEncoding& enc) const {
    462     return DexRegisterLocation::ConvertToSurfaceKind(
    463         GetLocationInternalKind(dex_register_number, number_of_dex_registers, code_info, enc));
    464   }
    465 
    466   // Get the internal kind of Dex register `dex_register_number`.
    467   DexRegisterLocation::Kind GetLocationInternalKind(uint16_t dex_register_number,
    468                                                     uint16_t number_of_dex_registers,
    469                                                     const CodeInfo& code_info,
    470                                                     const CodeInfoEncoding& enc) const;
    471 
    472   // Get the Dex register location `dex_register_number`.
    473   DexRegisterLocation GetDexRegisterLocation(uint16_t dex_register_number,
    474                                              uint16_t number_of_dex_registers,
    475                                              const CodeInfo& code_info,
    476                                              const CodeInfoEncoding& enc) const;
    477 
    478   int32_t GetStackOffsetInBytes(uint16_t dex_register_number,
    479                                 uint16_t number_of_dex_registers,
    480                                 const CodeInfo& code_info,
    481                                 const CodeInfoEncoding& enc) const {
    482     DexRegisterLocation location =
    483         GetDexRegisterLocation(dex_register_number, number_of_dex_registers, code_info, enc);
    484     DCHECK(location.GetKind() == DexRegisterLocation::Kind::kInStack);
    485     // GetDexRegisterLocation returns the offset in bytes.
    486     return location.GetValue();
    487   }
    488 
    489   int32_t GetConstant(uint16_t dex_register_number,
    490                       uint16_t number_of_dex_registers,
    491                       const CodeInfo& code_info,
    492                       const CodeInfoEncoding& enc) const {
    493     DexRegisterLocation location =
    494         GetDexRegisterLocation(dex_register_number, number_of_dex_registers, code_info, enc);
    495     DCHECK_EQ(location.GetKind(), DexRegisterLocation::Kind::kConstant);
    496     return location.GetValue();
    497   }
    498 
    499   int32_t GetMachineRegister(uint16_t dex_register_number,
    500                              uint16_t number_of_dex_registers,
    501                              const CodeInfo& code_info,
    502                              const CodeInfoEncoding& enc) const {
    503     DexRegisterLocation location =
    504         GetDexRegisterLocation(dex_register_number, number_of_dex_registers, code_info, enc);
    505     DCHECK(location.GetInternalKind() == DexRegisterLocation::Kind::kInRegister ||
    506            location.GetInternalKind() == DexRegisterLocation::Kind::kInRegisterHigh ||
    507            location.GetInternalKind() == DexRegisterLocation::Kind::kInFpuRegister ||
    508            location.GetInternalKind() == DexRegisterLocation::Kind::kInFpuRegisterHigh)
    509         << location.GetInternalKind();
    510     return location.GetValue();
    511   }
    512 
    513   // Get the index of the entry in the Dex register location catalog
    514   // corresponding to `dex_register_number`.
    515   size_t GetLocationCatalogEntryIndex(uint16_t dex_register_number,
    516                                       uint16_t number_of_dex_registers,
    517                                       size_t number_of_location_catalog_entries) const {
    518     if (!IsDexRegisterLive(dex_register_number)) {
    519       return DexRegisterLocationCatalog::kNoLocationEntryIndex;
    520     }
    521 
    522     if (number_of_location_catalog_entries == 1) {
    523       // We do not allocate space for location maps in the case of a
    524       // single-entry location catalog, as it is useless.  The only valid
    525       // entry index is 0;
    526       return 0;
    527     }
    528 
    529     // The bit offset of the beginning of the map locations.
    530     size_t map_locations_offset_in_bits =
    531         GetLocationMappingDataOffset(number_of_dex_registers) * kBitsPerByte;
    532     size_t index_in_dex_register_map = GetIndexInDexRegisterMap(dex_register_number);
    533     DCHECK_LT(index_in_dex_register_map, GetNumberOfLiveDexRegisters(number_of_dex_registers));
    534     // The bit size of an entry.
    535     size_t map_entry_size_in_bits = SingleEntrySizeInBits(number_of_location_catalog_entries);
    536     // The bit offset where `index_in_dex_register_map` is located.
    537     size_t entry_offset_in_bits =
    538         map_locations_offset_in_bits + index_in_dex_register_map * map_entry_size_in_bits;
    539     size_t location_catalog_entry_index =
    540         region_.LoadBits(entry_offset_in_bits, map_entry_size_in_bits);
    541     DCHECK_LT(location_catalog_entry_index, number_of_location_catalog_entries);
    542     return location_catalog_entry_index;
    543   }
    544 
    545   // Map entry at `index_in_dex_register_map` to `location_catalog_entry_index`.
    546   void SetLocationCatalogEntryIndex(size_t index_in_dex_register_map,
    547                                     size_t location_catalog_entry_index,
    548                                     uint16_t number_of_dex_registers,
    549                                     size_t number_of_location_catalog_entries) {
    550     DCHECK_LT(index_in_dex_register_map, GetNumberOfLiveDexRegisters(number_of_dex_registers));
    551     DCHECK_LT(location_catalog_entry_index, number_of_location_catalog_entries);
    552 
    553     if (number_of_location_catalog_entries == 1) {
    554       // We do not allocate space for location maps in the case of a
    555       // single-entry location catalog, as it is useless.
    556       return;
    557     }
    558 
    559     // The bit offset of the beginning of the map locations.
    560     size_t map_locations_offset_in_bits =
    561         GetLocationMappingDataOffset(number_of_dex_registers) * kBitsPerByte;
    562     // The bit size of an entry.
    563     size_t map_entry_size_in_bits = SingleEntrySizeInBits(number_of_location_catalog_entries);
    564     // The bit offset where `index_in_dex_register_map` is located.
    565     size_t entry_offset_in_bits =
    566         map_locations_offset_in_bits + index_in_dex_register_map * map_entry_size_in_bits;
    567     region_.StoreBits(entry_offset_in_bits, location_catalog_entry_index, map_entry_size_in_bits);
    568   }
    569 
    570   void SetLiveBitMask(uint16_t number_of_dex_registers,
    571                       const BitVector& live_dex_registers_mask) {
    572     size_t live_bit_mask_offset_in_bits = GetLiveBitMaskOffset() * kBitsPerByte;
    573     for (uint16_t i = 0; i < number_of_dex_registers; ++i) {
    574       region_.StoreBit(live_bit_mask_offset_in_bits + i, live_dex_registers_mask.IsBitSet(i));
    575     }
    576   }
    577 
    578   ALWAYS_INLINE bool IsDexRegisterLive(uint16_t dex_register_number) const {
    579     size_t live_bit_mask_offset_in_bits = GetLiveBitMaskOffset() * kBitsPerByte;
    580     return region_.LoadBit(live_bit_mask_offset_in_bits + dex_register_number);
    581   }
    582 
    583   size_t GetNumberOfLiveDexRegisters(uint16_t number_of_dex_registers) const {
    584     size_t number_of_live_dex_registers = 0;
    585     for (size_t i = 0; i < number_of_dex_registers; ++i) {
    586       if (IsDexRegisterLive(i)) {
    587         ++number_of_live_dex_registers;
    588       }
    589     }
    590     return number_of_live_dex_registers;
    591   }
    592 
    593   static size_t GetLiveBitMaskOffset() {
    594     return kFixedSize;
    595   }
    596 
    597   // Compute the size of the live register bit mask (in bytes), for a
    598   // method having `number_of_dex_registers` Dex registers.
    599   static size_t GetLiveBitMaskSize(uint16_t number_of_dex_registers) {
    600     return RoundUp(number_of_dex_registers, kBitsPerByte) / kBitsPerByte;
    601   }
    602 
    603   static size_t GetLocationMappingDataOffset(uint16_t number_of_dex_registers) {
    604     return GetLiveBitMaskOffset() + GetLiveBitMaskSize(number_of_dex_registers);
    605   }
    606 
    607   size_t GetLocationMappingDataSize(uint16_t number_of_dex_registers,
    608                                     size_t number_of_location_catalog_entries) const {
    609     size_t location_mapping_data_size_in_bits =
    610         GetNumberOfLiveDexRegisters(number_of_dex_registers)
    611         * SingleEntrySizeInBits(number_of_location_catalog_entries);
    612     return RoundUp(location_mapping_data_size_in_bits, kBitsPerByte) / kBitsPerByte;
    613   }
    614 
    615   // Return the size of a map entry in bits.  Note that if
    616   // `number_of_location_catalog_entries` equals 1, this function returns 0,
    617   // which is fine, as there is no need to allocate a map for a
    618   // single-entry location catalog; the only valid location catalog entry index
    619   // for a live register in this case is 0 and there is no need to
    620   // store it.
    621   static size_t SingleEntrySizeInBits(size_t number_of_location_catalog_entries) {
    622     // Handle the case of 0, as we cannot pass 0 to art::WhichPowerOf2.
    623     return number_of_location_catalog_entries == 0
    624         ? 0u
    625         : WhichPowerOf2(RoundUpToPowerOfTwo(number_of_location_catalog_entries));
    626   }
    627 
    628   // Return the size of the DexRegisterMap object, in bytes.
    629   size_t Size() const {
    630     return region_.size();
    631   }
    632 
    633   void Dump(VariableIndentationOutputStream* vios,
    634             const CodeInfo& code_info, uint16_t number_of_dex_registers) const;
    635 
    636  private:
    637   // Return the index in the Dex register map corresponding to the Dex
    638   // register number `dex_register_number`.
    639   size_t GetIndexInDexRegisterMap(uint16_t dex_register_number) const {
    640     if (!IsDexRegisterLive(dex_register_number)) {
    641       return kInvalidIndexInDexRegisterMap;
    642     }
    643     return GetNumberOfLiveDexRegisters(dex_register_number);
    644   }
    645 
    646   // Special (invalid) Dex register map entry index meaning that there
    647   // is no index in the map for a given Dex register (i.e., it must
    648   // have been mapped to a DexRegisterLocation::Kind::kNone location).
    649   static constexpr size_t kInvalidIndexInDexRegisterMap = -1;
    650 
    651   static constexpr int kFixedSize = 0;
    652 
    653   MemoryRegion region_;
    654 
    655   friend class CodeInfo;
    656   friend class StackMapStream;
    657 };
    658 
    659 // Represents bit range of bit-packed integer field.
    660 // We reuse the idea from ULEB128p1 to support encoding of -1 (aka 0xFFFFFFFF).
    661 // If min_value is set to -1, we implicitly subtract one from any loaded value,
    662 // and add one to any stored value. This is generalized to any negative values.
    663 // In other words, min_value acts as a base and the stored value is added to it.
    664 struct FieldEncoding {
    665   FieldEncoding(size_t start_offset, size_t end_offset, int32_t min_value = 0)
    666       : start_offset_(start_offset), end_offset_(end_offset), min_value_(min_value) {
    667     DCHECK_LE(start_offset_, end_offset_);
    668     DCHECK_LE(BitSize(), 32u);
    669   }
    670 
    671   ALWAYS_INLINE size_t BitSize() const { return end_offset_ - start_offset_; }
    672 
    673   template <typename Region>
    674   ALWAYS_INLINE int32_t Load(const Region& region) const {
    675     DCHECK_LE(end_offset_, region.size_in_bits());
    676     return static_cast<int32_t>(region.LoadBits(start_offset_, BitSize())) + min_value_;
    677   }
    678 
    679   template <typename Region>
    680   ALWAYS_INLINE void Store(Region region, int32_t value) const {
    681     region.StoreBits(start_offset_, value - min_value_, BitSize());
    682     DCHECK_EQ(Load(region), value);
    683   }
    684 
    685  private:
    686   size_t start_offset_;
    687   size_t end_offset_;
    688   int32_t min_value_;
    689 };
    690 
    691 class StackMapEncoding {
    692  public:
    693   StackMapEncoding()
    694       : dex_pc_bit_offset_(0),
    695         dex_register_map_bit_offset_(0),
    696         inline_info_bit_offset_(0),
    697         register_mask_index_bit_offset_(0),
    698         stack_mask_index_bit_offset_(0),
    699         total_bit_size_(0) {}
    700 
    701   // Set stack map bit layout based on given sizes.
    702   // Returns the size of stack map in bits.
    703   size_t SetFromSizes(size_t native_pc_max,
    704                       size_t dex_pc_max,
    705                       size_t dex_register_map_size,
    706                       size_t number_of_inline_info,
    707                       size_t number_of_register_masks,
    708                       size_t number_of_stack_masks) {
    709     total_bit_size_ = 0;
    710     DCHECK_EQ(kNativePcBitOffset, total_bit_size_);
    711     total_bit_size_ += MinimumBitsToStore(native_pc_max);
    712 
    713     dex_pc_bit_offset_ = total_bit_size_;
    714     total_bit_size_ += MinimumBitsToStore(1 /* kNoDexPc */ + dex_pc_max);
    715 
    716     // We also need +1 for kNoDexRegisterMap, but since the size is strictly
    717     // greater than any offset we might try to encode, we already implicitly have it.
    718     dex_register_map_bit_offset_ = total_bit_size_;
    719     total_bit_size_ += MinimumBitsToStore(dex_register_map_size);
    720 
    721     // We also need +1 for kNoInlineInfo, but since the inline_info_size is strictly
    722     // greater than the offset we might try to encode, we already implicitly have it.
    723     // If inline_info_size is zero, we can encode only kNoInlineInfo (in zero bits).
    724     inline_info_bit_offset_ = total_bit_size_;
    725     total_bit_size_ += MinimumBitsToStore(number_of_inline_info);
    726 
    727     register_mask_index_bit_offset_ = total_bit_size_;
    728     total_bit_size_ += MinimumBitsToStore(number_of_register_masks);
    729 
    730     stack_mask_index_bit_offset_ = total_bit_size_;
    731     total_bit_size_ += MinimumBitsToStore(number_of_stack_masks);
    732 
    733     return total_bit_size_;
    734   }
    735 
    736   ALWAYS_INLINE FieldEncoding GetNativePcEncoding() const {
    737     return FieldEncoding(kNativePcBitOffset, dex_pc_bit_offset_);
    738   }
    739   ALWAYS_INLINE FieldEncoding GetDexPcEncoding() const {
    740     return FieldEncoding(dex_pc_bit_offset_, dex_register_map_bit_offset_, -1 /* min_value */);
    741   }
    742   ALWAYS_INLINE FieldEncoding GetDexRegisterMapEncoding() const {
    743     return FieldEncoding(dex_register_map_bit_offset_, inline_info_bit_offset_, -1 /* min_value */);
    744   }
    745   ALWAYS_INLINE FieldEncoding GetInlineInfoEncoding() const {
    746     return FieldEncoding(inline_info_bit_offset_,
    747                          register_mask_index_bit_offset_,
    748                          -1 /* min_value */);
    749   }
    750   ALWAYS_INLINE FieldEncoding GetRegisterMaskIndexEncoding() const {
    751     return FieldEncoding(register_mask_index_bit_offset_, stack_mask_index_bit_offset_);
    752   }
    753   ALWAYS_INLINE FieldEncoding GetStackMaskIndexEncoding() const {
    754     return FieldEncoding(stack_mask_index_bit_offset_, total_bit_size_);
    755   }
    756   ALWAYS_INLINE size_t BitSize() const {
    757     return total_bit_size_;
    758   }
    759 
    760   // Encode the encoding into the vector.
    761   template<typename Vector>
    762   void Encode(Vector* dest) const {
    763     static_assert(alignof(StackMapEncoding) == 1, "Should not require alignment");
    764     const uint8_t* ptr = reinterpret_cast<const uint8_t*>(this);
    765     dest->insert(dest->end(), ptr, ptr + sizeof(*this));
    766   }
    767 
    768   // Decode the encoding from a pointer, updates the pointer.
    769   void Decode(const uint8_t** ptr) {
    770     *this = *reinterpret_cast<const StackMapEncoding*>(*ptr);
    771     *ptr += sizeof(*this);
    772   }
    773 
    774   void Dump(VariableIndentationOutputStream* vios) const;
    775 
    776  private:
    777   static constexpr size_t kNativePcBitOffset = 0;
    778   uint8_t dex_pc_bit_offset_;
    779   uint8_t dex_register_map_bit_offset_;
    780   uint8_t inline_info_bit_offset_;
    781   uint8_t register_mask_index_bit_offset_;
    782   uint8_t stack_mask_index_bit_offset_;
    783   uint8_t total_bit_size_;
    784 };
    785 
    786 /**
    787  * A Stack Map holds compilation information for a specific PC necessary for:
    788  * - Mapping it to a dex PC,
    789  * - Knowing which stack entries are objects,
    790  * - Knowing which registers hold objects,
    791  * - Knowing the inlining information,
    792  * - Knowing the values of dex registers.
    793  *
    794  * The information is of the form:
    795  *
    796  *   [native_pc_offset, dex_pc, dex_register_map_offset, inlining_info_index, register_mask_index,
    797  *   stack_mask_index].
    798  */
    799 class StackMap {
    800  public:
    801   StackMap() {}
    802   explicit StackMap(BitMemoryRegion region) : region_(region) {}
    803 
    804   ALWAYS_INLINE bool IsValid() const { return region_.pointer() != nullptr; }
    805 
    806   ALWAYS_INLINE uint32_t GetDexPc(const StackMapEncoding& encoding) const {
    807     return encoding.GetDexPcEncoding().Load(region_);
    808   }
    809 
    810   ALWAYS_INLINE void SetDexPc(const StackMapEncoding& encoding, uint32_t dex_pc) {
    811     encoding.GetDexPcEncoding().Store(region_, dex_pc);
    812   }
    813 
    814   ALWAYS_INLINE uint32_t GetNativePcOffset(const StackMapEncoding& encoding,
    815                                            InstructionSet instruction_set) const {
    816     CodeOffset offset(
    817         CodeOffset::FromCompressedOffset(encoding.GetNativePcEncoding().Load(region_)));
    818     return offset.Uint32Value(instruction_set);
    819   }
    820 
    821   ALWAYS_INLINE void SetNativePcCodeOffset(const StackMapEncoding& encoding,
    822                                            CodeOffset native_pc_offset) {
    823     encoding.GetNativePcEncoding().Store(region_, native_pc_offset.CompressedValue());
    824   }
    825 
    826   ALWAYS_INLINE uint32_t GetDexRegisterMapOffset(const StackMapEncoding& encoding) const {
    827     return encoding.GetDexRegisterMapEncoding().Load(region_);
    828   }
    829 
    830   ALWAYS_INLINE void SetDexRegisterMapOffset(const StackMapEncoding& encoding, uint32_t offset) {
    831     encoding.GetDexRegisterMapEncoding().Store(region_, offset);
    832   }
    833 
    834   ALWAYS_INLINE uint32_t GetInlineInfoIndex(const StackMapEncoding& encoding) const {
    835     return encoding.GetInlineInfoEncoding().Load(region_);
    836   }
    837 
    838   ALWAYS_INLINE void SetInlineInfoIndex(const StackMapEncoding& encoding, uint32_t index) {
    839     encoding.GetInlineInfoEncoding().Store(region_, index);
    840   }
    841 
    842   ALWAYS_INLINE uint32_t GetRegisterMaskIndex(const StackMapEncoding& encoding) const {
    843     return encoding.GetRegisterMaskIndexEncoding().Load(region_);
    844   }
    845 
    846   ALWAYS_INLINE void SetRegisterMaskIndex(const StackMapEncoding& encoding, uint32_t mask) {
    847     encoding.GetRegisterMaskIndexEncoding().Store(region_, mask);
    848   }
    849 
    850   ALWAYS_INLINE uint32_t GetStackMaskIndex(const StackMapEncoding& encoding) const {
    851     return encoding.GetStackMaskIndexEncoding().Load(region_);
    852   }
    853 
    854   ALWAYS_INLINE void SetStackMaskIndex(const StackMapEncoding& encoding, uint32_t mask) {
    855     encoding.GetStackMaskIndexEncoding().Store(region_, mask);
    856   }
    857 
    858   ALWAYS_INLINE bool HasDexRegisterMap(const StackMapEncoding& encoding) const {
    859     return GetDexRegisterMapOffset(encoding) != kNoDexRegisterMap;
    860   }
    861 
    862   ALWAYS_INLINE bool HasInlineInfo(const StackMapEncoding& encoding) const {
    863     return GetInlineInfoIndex(encoding) != kNoInlineInfo;
    864   }
    865 
    866   ALWAYS_INLINE bool Equals(const StackMap& other) const {
    867     return region_.pointer() == other.region_.pointer() &&
    868            region_.size() == other.region_.size() &&
    869            region_.BitOffset() == other.region_.BitOffset();
    870   }
    871 
    872   void Dump(VariableIndentationOutputStream* vios,
    873             const CodeInfo& code_info,
    874             const CodeInfoEncoding& encoding,
    875             const MethodInfo& method_info,
    876             uint32_t code_offset,
    877             uint16_t number_of_dex_registers,
    878             InstructionSet instruction_set,
    879             const std::string& header_suffix = "") const;
    880 
    881   // Special (invalid) offset for the DexRegisterMapOffset field meaning
    882   // that there is no Dex register map for this stack map.
    883   static constexpr uint32_t kNoDexRegisterMap = -1;
    884 
    885   // Special (invalid) offset for the InlineDescriptorOffset field meaning
    886   // that there is no inline info for this stack map.
    887   static constexpr uint32_t kNoInlineInfo = -1;
    888 
    889  private:
    890   static constexpr int kFixedSize = 0;
    891 
    892   BitMemoryRegion region_;
    893 
    894   friend class StackMapStream;
    895 };
    896 
    897 class InlineInfoEncoding {
    898  public:
    899   void SetFromSizes(size_t method_index_idx_max,
    900                     size_t dex_pc_max,
    901                     size_t extra_data_max,
    902                     size_t dex_register_map_size) {
    903     total_bit_size_ = kMethodIndexBitOffset;
    904     total_bit_size_ += MinimumBitsToStore(method_index_idx_max);
    905 
    906     dex_pc_bit_offset_ = dchecked_integral_cast<uint8_t>(total_bit_size_);
    907     // Note: We're not encoding the dex pc if there is none. That's the case
    908     // for an intrinsified native method, such as String.charAt().
    909     if (dex_pc_max != DexFile::kDexNoIndex) {
    910       total_bit_size_ += MinimumBitsToStore(1 /* kNoDexPc */ + dex_pc_max);
    911     }
    912 
    913     extra_data_bit_offset_ = dchecked_integral_cast<uint8_t>(total_bit_size_);
    914     total_bit_size_ += MinimumBitsToStore(extra_data_max);
    915 
    916     // We also need +1 for kNoDexRegisterMap, but since the size is strictly
    917     // greater than any offset we might try to encode, we already implicitly have it.
    918     dex_register_map_bit_offset_ = dchecked_integral_cast<uint8_t>(total_bit_size_);
    919     total_bit_size_ += MinimumBitsToStore(dex_register_map_size);
    920   }
    921 
    922   ALWAYS_INLINE FieldEncoding GetMethodIndexIdxEncoding() const {
    923     return FieldEncoding(kMethodIndexBitOffset, dex_pc_bit_offset_);
    924   }
    925   ALWAYS_INLINE FieldEncoding GetDexPcEncoding() const {
    926     return FieldEncoding(dex_pc_bit_offset_, extra_data_bit_offset_, -1 /* min_value */);
    927   }
    928   ALWAYS_INLINE FieldEncoding GetExtraDataEncoding() const {
    929     return FieldEncoding(extra_data_bit_offset_, dex_register_map_bit_offset_);
    930   }
    931   ALWAYS_INLINE FieldEncoding GetDexRegisterMapEncoding() const {
    932     return FieldEncoding(dex_register_map_bit_offset_, total_bit_size_, -1 /* min_value */);
    933   }
    934   ALWAYS_INLINE size_t BitSize() const {
    935     return total_bit_size_;
    936   }
    937 
    938   void Dump(VariableIndentationOutputStream* vios) const;
    939 
    940   // Encode the encoding into the vector.
    941   template<typename Vector>
    942   void Encode(Vector* dest) const {
    943     static_assert(alignof(InlineInfoEncoding) == 1, "Should not require alignment");
    944     const uint8_t* ptr = reinterpret_cast<const uint8_t*>(this);
    945     dest->insert(dest->end(), ptr, ptr + sizeof(*this));
    946   }
    947 
    948   // Decode the encoding from a pointer, updates the pointer.
    949   void Decode(const uint8_t** ptr) {
    950     *this = *reinterpret_cast<const InlineInfoEncoding*>(*ptr);
    951     *ptr += sizeof(*this);
    952   }
    953 
    954  private:
    955   static constexpr uint8_t kIsLastBitOffset = 0;
    956   static constexpr uint8_t kMethodIndexBitOffset = 1;
    957   uint8_t dex_pc_bit_offset_;
    958   uint8_t extra_data_bit_offset_;
    959   uint8_t dex_register_map_bit_offset_;
    960   uint8_t total_bit_size_;
    961 };
    962 
    963 /**
    964  * Inline information for a specific PC. The information is of the form:
    965  *
    966  *   [is_last,
    967  *    method_index (or ArtMethod high bits),
    968  *    dex_pc,
    969  *    extra_data (ArtMethod low bits or 1),
    970  *    dex_register_map_offset]+.
    971  */
    972 class InlineInfo {
    973  public:
    974   explicit InlineInfo(BitMemoryRegion region) : region_(region) {}
    975 
    976   ALWAYS_INLINE uint32_t GetDepth(const InlineInfoEncoding& encoding) const {
    977     size_t depth = 0;
    978     while (!GetRegionAtDepth(encoding, depth++).LoadBit(0)) { }  // Check is_last bit.
    979     return depth;
    980   }
    981 
    982   ALWAYS_INLINE void SetDepth(const InlineInfoEncoding& encoding, uint32_t depth) {
    983     DCHECK_GT(depth, 0u);
    984     for (size_t d = 0; d < depth; ++d) {
    985       GetRegionAtDepth(encoding, d).StoreBit(0, d == depth - 1);  // Set is_last bit.
    986     }
    987   }
    988 
    989   ALWAYS_INLINE uint32_t GetMethodIndexIdxAtDepth(const InlineInfoEncoding& encoding,
    990                                                   uint32_t depth) const {
    991     DCHECK(!EncodesArtMethodAtDepth(encoding, depth));
    992     return encoding.GetMethodIndexIdxEncoding().Load(GetRegionAtDepth(encoding, depth));
    993   }
    994 
    995   ALWAYS_INLINE void SetMethodIndexIdxAtDepth(const InlineInfoEncoding& encoding,
    996                                               uint32_t depth,
    997                                               uint32_t index) {
    998     encoding.GetMethodIndexIdxEncoding().Store(GetRegionAtDepth(encoding, depth), index);
    999   }
   1000 
   1001 
   1002   ALWAYS_INLINE uint32_t GetMethodIndexAtDepth(const InlineInfoEncoding& encoding,
   1003                                                const MethodInfo& method_info,
   1004                                                uint32_t depth) const {
   1005     return method_info.GetMethodIndex(GetMethodIndexIdxAtDepth(encoding, depth));
   1006   }
   1007 
   1008   ALWAYS_INLINE uint32_t GetDexPcAtDepth(const InlineInfoEncoding& encoding,
   1009                                          uint32_t depth) const {
   1010     return encoding.GetDexPcEncoding().Load(GetRegionAtDepth(encoding, depth));
   1011   }
   1012 
   1013   ALWAYS_INLINE void SetDexPcAtDepth(const InlineInfoEncoding& encoding,
   1014                                      uint32_t depth,
   1015                                      uint32_t dex_pc) {
   1016     encoding.GetDexPcEncoding().Store(GetRegionAtDepth(encoding, depth), dex_pc);
   1017   }
   1018 
   1019   ALWAYS_INLINE bool EncodesArtMethodAtDepth(const InlineInfoEncoding& encoding,
   1020                                              uint32_t depth) const {
   1021     return (encoding.GetExtraDataEncoding().Load(GetRegionAtDepth(encoding, depth)) & 1) == 0;
   1022   }
   1023 
   1024   ALWAYS_INLINE void SetExtraDataAtDepth(const InlineInfoEncoding& encoding,
   1025                                          uint32_t depth,
   1026                                          uint32_t extra_data) {
   1027     encoding.GetExtraDataEncoding().Store(GetRegionAtDepth(encoding, depth), extra_data);
   1028   }
   1029 
   1030   ALWAYS_INLINE ArtMethod* GetArtMethodAtDepth(const InlineInfoEncoding& encoding,
   1031                                                uint32_t depth) const {
   1032     uint32_t low_bits = encoding.GetExtraDataEncoding().Load(GetRegionAtDepth(encoding, depth));
   1033     uint32_t high_bits = encoding.GetMethodIndexIdxEncoding().Load(
   1034         GetRegionAtDepth(encoding, depth));
   1035     if (high_bits == 0) {
   1036       return reinterpret_cast<ArtMethod*>(low_bits);
   1037     } else {
   1038       uint64_t address = high_bits;
   1039       address = address << 32;
   1040       return reinterpret_cast<ArtMethod*>(address | low_bits);
   1041     }
   1042   }
   1043 
   1044   ALWAYS_INLINE uint32_t GetDexRegisterMapOffsetAtDepth(const InlineInfoEncoding& encoding,
   1045                                                         uint32_t depth) const {
   1046     return encoding.GetDexRegisterMapEncoding().Load(GetRegionAtDepth(encoding, depth));
   1047   }
   1048 
   1049   ALWAYS_INLINE void SetDexRegisterMapOffsetAtDepth(const InlineInfoEncoding& encoding,
   1050                                                     uint32_t depth,
   1051                                                     uint32_t offset) {
   1052     encoding.GetDexRegisterMapEncoding().Store(GetRegionAtDepth(encoding, depth), offset);
   1053   }
   1054 
   1055   ALWAYS_INLINE bool HasDexRegisterMapAtDepth(const InlineInfoEncoding& encoding,
   1056                                               uint32_t depth) const {
   1057     return GetDexRegisterMapOffsetAtDepth(encoding, depth) != StackMap::kNoDexRegisterMap;
   1058   }
   1059 
   1060   void Dump(VariableIndentationOutputStream* vios,
   1061             const CodeInfo& info,
   1062             const MethodInfo& method_info,
   1063             uint16_t* number_of_dex_registers) const;
   1064 
   1065  private:
   1066   ALWAYS_INLINE BitMemoryRegion GetRegionAtDepth(const InlineInfoEncoding& encoding,
   1067                                                  uint32_t depth) const {
   1068     size_t entry_size = encoding.BitSize();
   1069     DCHECK_GT(entry_size, 0u);
   1070     return region_.Subregion(depth * entry_size, entry_size);
   1071   }
   1072 
   1073   BitMemoryRegion region_;
   1074 };
   1075 
   1076 // Bit sized region encoding, may be more than 255 bits.
   1077 class BitRegionEncoding {
   1078  public:
   1079   uint32_t num_bits = 0;
   1080 
   1081   ALWAYS_INLINE size_t BitSize() const {
   1082     return num_bits;
   1083   }
   1084 
   1085   template<typename Vector>
   1086   void Encode(Vector* dest) const {
   1087     EncodeUnsignedLeb128(dest, num_bits);  // Use leb in case num_bits is greater than 255.
   1088   }
   1089 
   1090   void Decode(const uint8_t** ptr) {
   1091     num_bits = DecodeUnsignedLeb128(ptr);
   1092   }
   1093 };
   1094 
   1095 // A table of bit sized encodings.
   1096 template <typename Encoding>
   1097 struct BitEncodingTable {
   1098   static constexpr size_t kInvalidOffset = static_cast<size_t>(-1);
   1099   // How the encoding is laid out (serialized).
   1100   Encoding encoding;
   1101 
   1102   // Number of entries in the table (serialized).
   1103   size_t num_entries;
   1104 
   1105   // Bit offset for the base of the table (computed).
   1106   size_t bit_offset = kInvalidOffset;
   1107 
   1108   template<typename Vector>
   1109   void Encode(Vector* dest) const {
   1110     EncodeUnsignedLeb128(dest, num_entries);
   1111     encoding.Encode(dest);
   1112   }
   1113 
   1114   ALWAYS_INLINE void Decode(const uint8_t** ptr) {
   1115     num_entries = DecodeUnsignedLeb128(ptr);
   1116     encoding.Decode(ptr);
   1117   }
   1118 
   1119   // Set the bit offset in the table and adds the space used by the table to offset.
   1120   void UpdateBitOffset(size_t* offset) {
   1121     DCHECK(offset != nullptr);
   1122     bit_offset = *offset;
   1123     *offset += encoding.BitSize() * num_entries;
   1124   }
   1125 
   1126   // Return the bit region for the map at index i.
   1127   ALWAYS_INLINE BitMemoryRegion BitRegion(MemoryRegion region, size_t index) const {
   1128     DCHECK_NE(bit_offset, kInvalidOffset) << "Invalid table offset";
   1129     DCHECK_LT(index, num_entries);
   1130     const size_t map_size = encoding.BitSize();
   1131     return BitMemoryRegion(region, bit_offset + index * map_size, map_size);
   1132   }
   1133 };
   1134 
   1135 // A byte sized table of possible variable sized encodings.
   1136 struct ByteSizedTable {
   1137   static constexpr size_t kInvalidOffset = static_cast<size_t>(-1);
   1138 
   1139   // Number of entries in the table (serialized).
   1140   size_t num_entries = 0;
   1141 
   1142   // Number of bytes of the table (serialized).
   1143   size_t num_bytes;
   1144 
   1145   // Bit offset for the base of the table (computed).
   1146   size_t byte_offset = kInvalidOffset;
   1147 
   1148   template<typename Vector>
   1149   void Encode(Vector* dest) const {
   1150     EncodeUnsignedLeb128(dest, num_entries);
   1151     EncodeUnsignedLeb128(dest, num_bytes);
   1152   }
   1153 
   1154   ALWAYS_INLINE void Decode(const uint8_t** ptr) {
   1155     num_entries = DecodeUnsignedLeb128(ptr);
   1156     num_bytes = DecodeUnsignedLeb128(ptr);
   1157   }
   1158 
   1159   // Set the bit offset of the table. Adds the total bit size of the table to offset.
   1160   void UpdateBitOffset(size_t* offset) {
   1161     DCHECK(offset != nullptr);
   1162     DCHECK_ALIGNED(*offset, kBitsPerByte);
   1163     byte_offset = *offset / kBitsPerByte;
   1164     *offset += num_bytes * kBitsPerByte;
   1165   }
   1166 };
   1167 
   1168 // Format is [native pc, invoke type, method index].
   1169 class InvokeInfoEncoding {
   1170  public:
   1171   void SetFromSizes(size_t native_pc_max,
   1172                     size_t invoke_type_max,
   1173                     size_t method_index_max) {
   1174     total_bit_size_ = 0;
   1175     DCHECK_EQ(kNativePcBitOffset, total_bit_size_);
   1176     total_bit_size_ += MinimumBitsToStore(native_pc_max);
   1177     invoke_type_bit_offset_ = total_bit_size_;
   1178     total_bit_size_ += MinimumBitsToStore(invoke_type_max);
   1179     method_index_bit_offset_ = total_bit_size_;
   1180     total_bit_size_ += MinimumBitsToStore(method_index_max);
   1181   }
   1182 
   1183   ALWAYS_INLINE FieldEncoding GetNativePcEncoding() const {
   1184     return FieldEncoding(kNativePcBitOffset, invoke_type_bit_offset_);
   1185   }
   1186 
   1187   ALWAYS_INLINE FieldEncoding GetInvokeTypeEncoding() const {
   1188     return FieldEncoding(invoke_type_bit_offset_, method_index_bit_offset_);
   1189   }
   1190 
   1191   ALWAYS_INLINE FieldEncoding GetMethodIndexEncoding() const {
   1192     return FieldEncoding(method_index_bit_offset_, total_bit_size_);
   1193   }
   1194 
   1195   ALWAYS_INLINE size_t BitSize() const {
   1196     return total_bit_size_;
   1197   }
   1198 
   1199   template<typename Vector>
   1200   void Encode(Vector* dest) const {
   1201     static_assert(alignof(InvokeInfoEncoding) == 1, "Should not require alignment");
   1202     const uint8_t* ptr = reinterpret_cast<const uint8_t*>(this);
   1203     dest->insert(dest->end(), ptr, ptr + sizeof(*this));
   1204   }
   1205 
   1206   void Decode(const uint8_t** ptr) {
   1207     *this = *reinterpret_cast<const InvokeInfoEncoding*>(*ptr);
   1208     *ptr += sizeof(*this);
   1209   }
   1210 
   1211  private:
   1212   static constexpr uint8_t kNativePcBitOffset = 0;
   1213   uint8_t invoke_type_bit_offset_;
   1214   uint8_t method_index_bit_offset_;
   1215   uint8_t total_bit_size_;
   1216 };
   1217 
   1218 class InvokeInfo {
   1219  public:
   1220   explicit InvokeInfo(BitMemoryRegion region) : region_(region) {}
   1221 
   1222   ALWAYS_INLINE uint32_t GetNativePcOffset(const InvokeInfoEncoding& encoding,
   1223                                            InstructionSet instruction_set) const {
   1224     CodeOffset offset(
   1225         CodeOffset::FromCompressedOffset(encoding.GetNativePcEncoding().Load(region_)));
   1226     return offset.Uint32Value(instruction_set);
   1227   }
   1228 
   1229   ALWAYS_INLINE void SetNativePcCodeOffset(const InvokeInfoEncoding& encoding,
   1230                                            CodeOffset native_pc_offset) {
   1231     encoding.GetNativePcEncoding().Store(region_, native_pc_offset.CompressedValue());
   1232   }
   1233 
   1234   ALWAYS_INLINE uint32_t GetInvokeType(const InvokeInfoEncoding& encoding) const {
   1235     return encoding.GetInvokeTypeEncoding().Load(region_);
   1236   }
   1237 
   1238   ALWAYS_INLINE void SetInvokeType(const InvokeInfoEncoding& encoding, uint32_t invoke_type) {
   1239     encoding.GetInvokeTypeEncoding().Store(region_, invoke_type);
   1240   }
   1241 
   1242   ALWAYS_INLINE uint32_t GetMethodIndexIdx(const InvokeInfoEncoding& encoding) const {
   1243     return encoding.GetMethodIndexEncoding().Load(region_);
   1244   }
   1245 
   1246   ALWAYS_INLINE void SetMethodIndexIdx(const InvokeInfoEncoding& encoding,
   1247                                        uint32_t method_index_idx) {
   1248     encoding.GetMethodIndexEncoding().Store(region_, method_index_idx);
   1249   }
   1250 
   1251   ALWAYS_INLINE uint32_t GetMethodIndex(const InvokeInfoEncoding& encoding,
   1252                                         MethodInfo method_info) const {
   1253     return method_info.GetMethodIndex(GetMethodIndexIdx(encoding));
   1254   }
   1255 
   1256   bool IsValid() const { return region_.pointer() != nullptr; }
   1257 
   1258  private:
   1259   BitMemoryRegion region_;
   1260 };
   1261 
   1262 // Most of the fields are encoded as ULEB128 to save space.
   1263 struct CodeInfoEncoding {
   1264   using SizeType = uint32_t;
   1265 
   1266   static constexpr SizeType kInvalidSize = std::numeric_limits<SizeType>::max();
   1267 
   1268   // Byte sized tables go first to avoid unnecessary alignment bits.
   1269   ByteSizedTable dex_register_map;
   1270   ByteSizedTable location_catalog;
   1271   BitEncodingTable<StackMapEncoding> stack_map;
   1272   BitEncodingTable<BitRegionEncoding> register_mask;
   1273   BitEncodingTable<BitRegionEncoding> stack_mask;
   1274   BitEncodingTable<InvokeInfoEncoding> invoke_info;
   1275   BitEncodingTable<InlineInfoEncoding> inline_info;
   1276 
   1277   CodeInfoEncoding() {}
   1278 
   1279   explicit CodeInfoEncoding(const void* data) {
   1280     const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
   1281     dex_register_map.Decode(&ptr);
   1282     location_catalog.Decode(&ptr);
   1283     stack_map.Decode(&ptr);
   1284     register_mask.Decode(&ptr);
   1285     stack_mask.Decode(&ptr);
   1286     invoke_info.Decode(&ptr);
   1287     if (stack_map.encoding.GetInlineInfoEncoding().BitSize() > 0) {
   1288       inline_info.Decode(&ptr);
   1289     } else {
   1290       inline_info = BitEncodingTable<InlineInfoEncoding>();
   1291     }
   1292     cache_header_size =
   1293         dchecked_integral_cast<SizeType>(ptr - reinterpret_cast<const uint8_t*>(data));
   1294     ComputeTableOffsets();
   1295   }
   1296 
   1297   // Compress is not const since it calculates cache_header_size. This is used by PrepareForFillIn.
   1298   template<typename Vector>
   1299   void Compress(Vector* dest) {
   1300     dex_register_map.Encode(dest);
   1301     location_catalog.Encode(dest);
   1302     stack_map.Encode(dest);
   1303     register_mask.Encode(dest);
   1304     stack_mask.Encode(dest);
   1305     invoke_info.Encode(dest);
   1306     if (stack_map.encoding.GetInlineInfoEncoding().BitSize() > 0) {
   1307       inline_info.Encode(dest);
   1308     }
   1309     cache_header_size = dest->size();
   1310   }
   1311 
   1312   ALWAYS_INLINE void ComputeTableOffsets() {
   1313     // Skip the header.
   1314     size_t bit_offset = HeaderSize() * kBitsPerByte;
   1315     // The byte tables must be aligned so they must go first.
   1316     dex_register_map.UpdateBitOffset(&bit_offset);
   1317     location_catalog.UpdateBitOffset(&bit_offset);
   1318     // Other tables don't require alignment.
   1319     stack_map.UpdateBitOffset(&bit_offset);
   1320     register_mask.UpdateBitOffset(&bit_offset);
   1321     stack_mask.UpdateBitOffset(&bit_offset);
   1322     invoke_info.UpdateBitOffset(&bit_offset);
   1323     inline_info.UpdateBitOffset(&bit_offset);
   1324     cache_non_header_size = RoundUp(bit_offset, kBitsPerByte) / kBitsPerByte - HeaderSize();
   1325   }
   1326 
   1327   ALWAYS_INLINE size_t HeaderSize() const {
   1328     DCHECK_NE(cache_header_size, kInvalidSize) << "Uninitialized";
   1329     return cache_header_size;
   1330   }
   1331 
   1332   ALWAYS_INLINE size_t NonHeaderSize() const {
   1333     DCHECK_NE(cache_non_header_size, kInvalidSize) << "Uninitialized";
   1334     return cache_non_header_size;
   1335   }
   1336 
   1337  private:
   1338   // Computed fields (not serialized).
   1339   // Header size in bytes, cached to avoid needing to re-decoding the encoding in HeaderSize.
   1340   SizeType cache_header_size = kInvalidSize;
   1341   // Non header size in bytes, cached to avoid needing to re-decoding the encoding in NonHeaderSize.
   1342   SizeType cache_non_header_size = kInvalidSize;
   1343 };
   1344 
   1345 /**
   1346  * Wrapper around all compiler information collected for a method.
   1347  * The information is of the form:
   1348  *
   1349  *   [CodeInfoEncoding, DexRegisterMap+, DexLocationCatalog+, StackMap+, RegisterMask+, StackMask+,
   1350  *    InlineInfo*]
   1351  *
   1352  * where CodeInfoEncoding is of the form:
   1353  *
   1354  *   [ByteSizedTable(dex_register_map), ByteSizedTable(location_catalog),
   1355  *    BitEncodingTable<StackMapEncoding>, BitEncodingTable<BitRegionEncoding>,
   1356  *    BitEncodingTable<BitRegionEncoding>, BitEncodingTable<InlineInfoEncoding>]
   1357  */
   1358 class CodeInfo {
   1359  public:
   1360   explicit CodeInfo(MemoryRegion region) : region_(region) {
   1361   }
   1362 
   1363   explicit CodeInfo(const void* data) {
   1364     CodeInfoEncoding encoding = CodeInfoEncoding(data);
   1365     region_ = MemoryRegion(const_cast<void*>(data),
   1366                            encoding.HeaderSize() + encoding.NonHeaderSize());
   1367   }
   1368 
   1369   CodeInfoEncoding ExtractEncoding() const {
   1370     CodeInfoEncoding encoding(region_.begin());
   1371     AssertValidStackMap(encoding);
   1372     return encoding;
   1373   }
   1374 
   1375   bool HasInlineInfo(const CodeInfoEncoding& encoding) const {
   1376     return encoding.stack_map.encoding.GetInlineInfoEncoding().BitSize() > 0;
   1377   }
   1378 
   1379   DexRegisterLocationCatalog GetDexRegisterLocationCatalog(const CodeInfoEncoding& encoding) const {
   1380     return DexRegisterLocationCatalog(region_.Subregion(encoding.location_catalog.byte_offset,
   1381                                                         encoding.location_catalog.num_bytes));
   1382   }
   1383 
   1384   ALWAYS_INLINE size_t GetNumberOfStackMaskBits(const CodeInfoEncoding& encoding) const {
   1385     return encoding.stack_mask.encoding.BitSize();
   1386   }
   1387 
   1388   ALWAYS_INLINE StackMap GetStackMapAt(size_t index, const CodeInfoEncoding& encoding) const {
   1389     return StackMap(encoding.stack_map.BitRegion(region_, index));
   1390   }
   1391 
   1392   BitMemoryRegion GetStackMask(size_t index, const CodeInfoEncoding& encoding) const {
   1393     return encoding.stack_mask.BitRegion(region_, index);
   1394   }
   1395 
   1396   BitMemoryRegion GetStackMaskOf(const CodeInfoEncoding& encoding,
   1397                                  const StackMap& stack_map) const {
   1398     return GetStackMask(stack_map.GetStackMaskIndex(encoding.stack_map.encoding), encoding);
   1399   }
   1400 
   1401   BitMemoryRegion GetRegisterMask(size_t index, const CodeInfoEncoding& encoding) const {
   1402     return encoding.register_mask.BitRegion(region_, index);
   1403   }
   1404 
   1405   uint32_t GetRegisterMaskOf(const CodeInfoEncoding& encoding, const StackMap& stack_map) const {
   1406     size_t index = stack_map.GetRegisterMaskIndex(encoding.stack_map.encoding);
   1407     return GetRegisterMask(index, encoding).LoadBits(0u, encoding.register_mask.encoding.BitSize());
   1408   }
   1409 
   1410   uint32_t GetNumberOfLocationCatalogEntries(const CodeInfoEncoding& encoding) const {
   1411     return encoding.location_catalog.num_entries;
   1412   }
   1413 
   1414   uint32_t GetDexRegisterLocationCatalogSize(const CodeInfoEncoding& encoding) const {
   1415     return encoding.location_catalog.num_bytes;
   1416   }
   1417 
   1418   uint32_t GetNumberOfStackMaps(const CodeInfoEncoding& encoding) const {
   1419     return encoding.stack_map.num_entries;
   1420   }
   1421 
   1422   // Get the size of all the stack maps of this CodeInfo object, in bits. Not byte aligned.
   1423   ALWAYS_INLINE size_t GetStackMapsSizeInBits(const CodeInfoEncoding& encoding) const {
   1424     return encoding.stack_map.encoding.BitSize() * GetNumberOfStackMaps(encoding);
   1425   }
   1426 
   1427   InvokeInfo GetInvokeInfo(const CodeInfoEncoding& encoding, size_t index) const {
   1428     return InvokeInfo(encoding.invoke_info.BitRegion(region_, index));
   1429   }
   1430 
   1431   DexRegisterMap GetDexRegisterMapOf(StackMap stack_map,
   1432                                      const CodeInfoEncoding& encoding,
   1433                                      size_t number_of_dex_registers) const {
   1434     if (!stack_map.HasDexRegisterMap(encoding.stack_map.encoding)) {
   1435       return DexRegisterMap();
   1436     }
   1437     const uint32_t offset = encoding.dex_register_map.byte_offset +
   1438         stack_map.GetDexRegisterMapOffset(encoding.stack_map.encoding);
   1439     size_t size = ComputeDexRegisterMapSizeOf(encoding, offset, number_of_dex_registers);
   1440     return DexRegisterMap(region_.Subregion(offset, size));
   1441   }
   1442 
   1443   size_t GetDexRegisterMapsSize(const CodeInfoEncoding& encoding,
   1444                                 uint32_t number_of_dex_registers) const {
   1445     size_t total = 0;
   1446     for (size_t i = 0, e = GetNumberOfStackMaps(encoding); i < e; ++i) {
   1447       StackMap stack_map = GetStackMapAt(i, encoding);
   1448       DexRegisterMap map(GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers));
   1449       total += map.Size();
   1450     }
   1451     return total;
   1452   }
   1453 
   1454   // Return the `DexRegisterMap` pointed by `inline_info` at depth `depth`.
   1455   DexRegisterMap GetDexRegisterMapAtDepth(uint8_t depth,
   1456                                           InlineInfo inline_info,
   1457                                           const CodeInfoEncoding& encoding,
   1458                                           uint32_t number_of_dex_registers) const {
   1459     if (!inline_info.HasDexRegisterMapAtDepth(encoding.inline_info.encoding, depth)) {
   1460       return DexRegisterMap();
   1461     } else {
   1462       uint32_t offset = encoding.dex_register_map.byte_offset +
   1463           inline_info.GetDexRegisterMapOffsetAtDepth(encoding.inline_info.encoding, depth);
   1464       size_t size = ComputeDexRegisterMapSizeOf(encoding, offset, number_of_dex_registers);
   1465       return DexRegisterMap(region_.Subregion(offset, size));
   1466     }
   1467   }
   1468 
   1469   InlineInfo GetInlineInfo(size_t index, const CodeInfoEncoding& encoding) const {
   1470     // Since we do not know the depth, we just return the whole remaining map. The caller may
   1471     // access the inline info for arbitrary depths. To return the precise inline info we would need
   1472     // to count the depth before returning.
   1473     // TODO: Clean this up.
   1474     const size_t bit_offset = encoding.inline_info.bit_offset +
   1475         index * encoding.inline_info.encoding.BitSize();
   1476     return InlineInfo(BitMemoryRegion(region_, bit_offset, region_.size_in_bits() - bit_offset));
   1477   }
   1478 
   1479   InlineInfo GetInlineInfoOf(StackMap stack_map, const CodeInfoEncoding& encoding) const {
   1480     DCHECK(stack_map.HasInlineInfo(encoding.stack_map.encoding));
   1481     uint32_t index = stack_map.GetInlineInfoIndex(encoding.stack_map.encoding);
   1482     return GetInlineInfo(index, encoding);
   1483   }
   1484 
   1485   StackMap GetStackMapForDexPc(uint32_t dex_pc, const CodeInfoEncoding& encoding) const {
   1486     for (size_t i = 0, e = GetNumberOfStackMaps(encoding); i < e; ++i) {
   1487       StackMap stack_map = GetStackMapAt(i, encoding);
   1488       if (stack_map.GetDexPc(encoding.stack_map.encoding) == dex_pc) {
   1489         return stack_map;
   1490       }
   1491     }
   1492     return StackMap();
   1493   }
   1494 
   1495   // Searches the stack map list backwards because catch stack maps are stored
   1496   // at the end.
   1497   StackMap GetCatchStackMapForDexPc(uint32_t dex_pc, const CodeInfoEncoding& encoding) const {
   1498     for (size_t i = GetNumberOfStackMaps(encoding); i > 0; --i) {
   1499       StackMap stack_map = GetStackMapAt(i - 1, encoding);
   1500       if (stack_map.GetDexPc(encoding.stack_map.encoding) == dex_pc) {
   1501         return stack_map;
   1502       }
   1503     }
   1504     return StackMap();
   1505   }
   1506 
   1507   StackMap GetOsrStackMapForDexPc(uint32_t dex_pc, const CodeInfoEncoding& encoding) const {
   1508     size_t e = GetNumberOfStackMaps(encoding);
   1509     if (e == 0) {
   1510       // There cannot be OSR stack map if there is no stack map.
   1511       return StackMap();
   1512     }
   1513     // Walk over all stack maps. If two consecutive stack maps are identical, then we
   1514     // have found a stack map suitable for OSR.
   1515     const StackMapEncoding& stack_map_encoding = encoding.stack_map.encoding;
   1516     for (size_t i = 0; i < e - 1; ++i) {
   1517       StackMap stack_map = GetStackMapAt(i, encoding);
   1518       if (stack_map.GetDexPc(stack_map_encoding) == dex_pc) {
   1519         StackMap other = GetStackMapAt(i + 1, encoding);
   1520         if (other.GetDexPc(stack_map_encoding) == dex_pc &&
   1521             other.GetNativePcOffset(stack_map_encoding, kRuntimeISA) ==
   1522                 stack_map.GetNativePcOffset(stack_map_encoding, kRuntimeISA)) {
   1523           DCHECK_EQ(other.GetDexRegisterMapOffset(stack_map_encoding),
   1524                     stack_map.GetDexRegisterMapOffset(stack_map_encoding));
   1525           DCHECK(!stack_map.HasInlineInfo(stack_map_encoding));
   1526           if (i < e - 2) {
   1527             // Make sure there are not three identical stack maps following each other.
   1528             DCHECK_NE(
   1529                 stack_map.GetNativePcOffset(stack_map_encoding, kRuntimeISA),
   1530                 GetStackMapAt(i + 2, encoding).GetNativePcOffset(stack_map_encoding, kRuntimeISA));
   1531           }
   1532           return stack_map;
   1533         }
   1534       }
   1535     }
   1536     return StackMap();
   1537   }
   1538 
   1539   StackMap GetStackMapForNativePcOffset(uint32_t native_pc_offset,
   1540                                         const CodeInfoEncoding& encoding) const {
   1541     // TODO: Safepoint stack maps are sorted by native_pc_offset but catch stack
   1542     //       maps are not. If we knew that the method does not have try/catch,
   1543     //       we could do binary search.
   1544     for (size_t i = 0, e = GetNumberOfStackMaps(encoding); i < e; ++i) {
   1545       StackMap stack_map = GetStackMapAt(i, encoding);
   1546       if (stack_map.GetNativePcOffset(encoding.stack_map.encoding, kRuntimeISA) ==
   1547           native_pc_offset) {
   1548         return stack_map;
   1549       }
   1550     }
   1551     return StackMap();
   1552   }
   1553 
   1554   InvokeInfo GetInvokeInfoForNativePcOffset(uint32_t native_pc_offset,
   1555                                             const CodeInfoEncoding& encoding) {
   1556     for (size_t index = 0; index < encoding.invoke_info.num_entries; index++) {
   1557       InvokeInfo item = GetInvokeInfo(encoding, index);
   1558       if (item.GetNativePcOffset(encoding.invoke_info.encoding, kRuntimeISA) == native_pc_offset) {
   1559         return item;
   1560       }
   1561     }
   1562     return InvokeInfo(BitMemoryRegion());
   1563   }
   1564 
   1565   // Dump this CodeInfo object on `os`.  `code_offset` is the (absolute)
   1566   // native PC of the compiled method and `number_of_dex_registers` the
   1567   // number of Dex virtual registers used in this method.  If
   1568   // `dump_stack_maps` is true, also dump the stack maps and the
   1569   // associated Dex register maps.
   1570   void Dump(VariableIndentationOutputStream* vios,
   1571             uint32_t code_offset,
   1572             uint16_t number_of_dex_registers,
   1573             bool dump_stack_maps,
   1574             InstructionSet instruction_set,
   1575             const MethodInfo& method_info) const;
   1576 
   1577   // Check that the code info has valid stack map and abort if it does not.
   1578   void AssertValidStackMap(const CodeInfoEncoding& encoding) const {
   1579     if (region_.size() != 0 && region_.size_in_bits() < GetStackMapsSizeInBits(encoding)) {
   1580       LOG(FATAL) << region_.size() << "\n"
   1581                  << encoding.HeaderSize() << "\n"
   1582                  << encoding.NonHeaderSize() << "\n"
   1583                  << encoding.location_catalog.num_entries << "\n"
   1584                  << encoding.stack_map.num_entries << "\n"
   1585                  << encoding.stack_map.encoding.BitSize();
   1586     }
   1587   }
   1588 
   1589  private:
   1590   // Compute the size of the Dex register map associated to the stack map at
   1591   // `dex_register_map_offset_in_code_info`.
   1592   size_t ComputeDexRegisterMapSizeOf(const CodeInfoEncoding& encoding,
   1593                                      uint32_t dex_register_map_offset_in_code_info,
   1594                                      uint16_t number_of_dex_registers) const {
   1595     // Offset where the actual mapping data starts within art::DexRegisterMap.
   1596     size_t location_mapping_data_offset_in_dex_register_map =
   1597         DexRegisterMap::GetLocationMappingDataOffset(number_of_dex_registers);
   1598     // Create a temporary art::DexRegisterMap to be able to call
   1599     // art::DexRegisterMap::GetNumberOfLiveDexRegisters and
   1600     DexRegisterMap dex_register_map_without_locations(
   1601         MemoryRegion(region_.Subregion(dex_register_map_offset_in_code_info,
   1602                                        location_mapping_data_offset_in_dex_register_map)));
   1603     size_t number_of_live_dex_registers =
   1604         dex_register_map_without_locations.GetNumberOfLiveDexRegisters(number_of_dex_registers);
   1605     size_t location_mapping_data_size_in_bits =
   1606         DexRegisterMap::SingleEntrySizeInBits(GetNumberOfLocationCatalogEntries(encoding))
   1607         * number_of_live_dex_registers;
   1608     size_t location_mapping_data_size_in_bytes =
   1609         RoundUp(location_mapping_data_size_in_bits, kBitsPerByte) / kBitsPerByte;
   1610     size_t dex_register_map_size =
   1611         location_mapping_data_offset_in_dex_register_map + location_mapping_data_size_in_bytes;
   1612     return dex_register_map_size;
   1613   }
   1614 
   1615   // Compute the size of a Dex register location catalog starting at offset `origin`
   1616   // in `region_` and containing `number_of_dex_locations` entries.
   1617   size_t ComputeDexRegisterLocationCatalogSize(uint32_t origin,
   1618                                                uint32_t number_of_dex_locations) const {
   1619     // TODO: Ideally, we would like to use art::DexRegisterLocationCatalog::Size or
   1620     // art::DexRegisterLocationCatalog::FindLocationOffset, but the
   1621     // DexRegisterLocationCatalog is not yet built.  Try to factor common code.
   1622     size_t offset = origin + DexRegisterLocationCatalog::kFixedSize;
   1623 
   1624     // Skip the first `number_of_dex_locations - 1` entries.
   1625     for (uint16_t i = 0; i < number_of_dex_locations; ++i) {
   1626       // Read the first next byte and inspect its first 3 bits to decide
   1627       // whether it is a short or a large location.
   1628       DexRegisterLocationCatalog::ShortLocation first_byte =
   1629           region_.LoadUnaligned<DexRegisterLocationCatalog::ShortLocation>(offset);
   1630       DexRegisterLocation::Kind kind =
   1631           DexRegisterLocationCatalog::ExtractKindFromShortLocation(first_byte);
   1632       if (DexRegisterLocation::IsShortLocationKind(kind)) {
   1633         // Short location.  Skip the current byte.
   1634         offset += DexRegisterLocationCatalog::SingleShortEntrySize();
   1635       } else {
   1636         // Large location.  Skip the 5 next bytes.
   1637         offset += DexRegisterLocationCatalog::SingleLargeEntrySize();
   1638       }
   1639     }
   1640     size_t size = offset - origin;
   1641     return size;
   1642   }
   1643 
   1644   MemoryRegion region_;
   1645   friend class StackMapStream;
   1646 };
   1647 
   1648 #undef ELEMENT_BYTE_OFFSET_AFTER
   1649 #undef ELEMENT_BIT_OFFSET_AFTER
   1650 
   1651 }  // namespace art
   1652 
   1653 #endif  // ART_RUNTIME_STACK_MAP_H_
   1654