Home | History | Annotate | Download | only in verifier
      1 /*
      2  * Copyright (C) 2012 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_VERIFIER_DEX_GC_MAP_H_
     18 #define ART_RUNTIME_VERIFIER_DEX_GC_MAP_H_
     19 
     20 #include <stdint.h>
     21 
     22 #include "base/logging.h"
     23 #include "base/macros.h"
     24 
     25 namespace art {
     26 namespace verifier {
     27 
     28 /*
     29  * Format enumeration for RegisterMap data area.
     30  */
     31 enum RegisterMapFormat {
     32   kRegMapFormatUnknown = 0,
     33   kRegMapFormatNone = 1,       // Indicates no map data follows.
     34   kRegMapFormatCompact8 = 2,   // Compact layout, 8-bit addresses.
     35   kRegMapFormatCompact16 = 3,  // Compact layout, 16-bit addresses.
     36 };
     37 
     38 // Lightweight wrapper for Dex PC to reference bit maps.
     39 class DexPcToReferenceMap {
     40  public:
     41   DexPcToReferenceMap(const uint8_t* data, size_t data_length) : data_(data) {
     42     CHECK(data_ != NULL);
     43     // Check the size of the table agrees with the number of entries
     44     size_t data_size = data_length - 4;
     45     DCHECK_EQ(EntryWidth() * NumEntries(), data_size);
     46   }
     47 
     48   // The number of entries in the table
     49   size_t NumEntries() const {
     50     return GetData()[2] | (GetData()[3] << 8);
     51   }
     52 
     53   // Get the Dex PC at the given index
     54   uint16_t GetDexPc(size_t index) const {
     55     size_t entry_offset = index * EntryWidth();
     56     if (DexPcWidth() == 1) {
     57       return Table()[entry_offset];
     58     } else {
     59       return Table()[entry_offset] | (Table()[entry_offset + 1] << 8);
     60     }
     61   }
     62 
     63   // Return address of bitmap encoding what are live references
     64   const uint8_t* GetBitMap(size_t index) const {
     65     size_t entry_offset = index * EntryWidth();
     66     return &Table()[entry_offset + DexPcWidth()];
     67   }
     68 
     69   // Find the bitmap associated with the given dex pc
     70   const uint8_t* FindBitMap(uint16_t dex_pc, bool error_if_not_present = true) const;
     71 
     72   // The number of bytes used to encode registers
     73   size_t RegWidth() const {
     74     return GetData()[1] | ((GetData()[0] & ~kRegMapFormatMask) << kRegMapFormatShift);
     75   }
     76 
     77  private:
     78   // Table of num_entries * (dex pc, bitmap)
     79   const uint8_t* Table() const {
     80     return GetData() + 4;
     81   }
     82 
     83   // The format of the table of the PCs for the table
     84   RegisterMapFormat Format() const {
     85     return static_cast<RegisterMapFormat>(GetData()[0] & kRegMapFormatMask);
     86   }
     87 
     88   // Number of bytes used to encode a dex pc
     89   size_t DexPcWidth() const {
     90     RegisterMapFormat format = Format();
     91     switch (format) {
     92       case kRegMapFormatCompact8:
     93         return 1;
     94       case kRegMapFormatCompact16:
     95         return 2;
     96       default:
     97         LOG(FATAL) << "Invalid format " << static_cast<int>(format);
     98         return -1;
     99     }
    100   }
    101 
    102   // The width of an entry in the table
    103   size_t EntryWidth() const {
    104     return DexPcWidth() + RegWidth();
    105   }
    106 
    107   const uint8_t* GetData() const {
    108     return data_;
    109   }
    110 
    111   friend class MethodVerifier;
    112 
    113   static const int kRegMapFormatShift = 5;
    114   static const uint8_t kRegMapFormatMask = 0x7;
    115 
    116   const uint8_t* const data_;  // The header and table data
    117 };
    118 
    119 }  // namespace verifier
    120 }  // namespace art
    121 
    122 #endif  // ART_RUNTIME_VERIFIER_DEX_GC_MAP_H_
    123