196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers/* 296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers * Copyright (C) 2013 The Android Open Source Project 396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers * 496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers * you may not use this file except in compliance with the License. 696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers * You may obtain a copy of the License at 796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers * 896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers * http://www.apache.org/licenses/LICENSE-2.0 996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers * 1096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers * Unless required by applicable law or agreed to in writing, software 1196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers * distributed under the License is distributed on an "AS IS" BASIS, 1296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers * See the License for the specific language governing permissions and 1496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers * limitations under the License. 1596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers */ 1696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 1796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers#ifndef ART_RUNTIME_MAPPING_TABLE_H_ 1896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers#define ART_RUNTIME_MAPPING_TABLE_H_ 1996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 2096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers#include "base/logging.h" 2196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers#include "leb128.h" 2296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 2396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogersnamespace art { 2496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 2596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers// A utility for processing the raw uleb128 encoded mapping table created by the quick compiler. 2696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogersclass MappingTable { 2796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers public: 2896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers explicit MappingTable(const uint8_t* encoded_map) : encoded_table_(encoded_map) { 2996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 3096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 3196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t TotalSize() const PURE { 3296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers const uint8_t* table = encoded_table_; 33159aa95e1e23cd585ac305b44b4cd65ae72048a4Ian Rogers if (table == nullptr) { 3496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return 0; 3596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } else { 3696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return DecodeUnsignedLeb128(&table); 3796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 3896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 3996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 4096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t DexToPcSize() const PURE { 4196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers const uint8_t* table = encoded_table_; 42159aa95e1e23cd585ac305b44b4cd65ae72048a4Ian Rogers if (table == nullptr) { 4396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return 0; 4496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } else { 4596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t total_size = DecodeUnsignedLeb128(&table); 4696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t pc_to_dex_size = DecodeUnsignedLeb128(&table); 4796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return total_size - pc_to_dex_size; 4896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 4996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 5096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 5196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers const uint8_t* FirstDexToPcPtr() const { 5296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers const uint8_t* table = encoded_table_; 53159aa95e1e23cd585ac305b44b4cd65ae72048a4Ian Rogers if (table != nullptr) { 54159aa95e1e23cd585ac305b44b4cd65ae72048a4Ian Rogers uint32_t total_size = DecodeUnsignedLeb128(&table); 5596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t pc_to_dex_size = DecodeUnsignedLeb128(&table); 56159aa95e1e23cd585ac305b44b4cd65ae72048a4Ian Rogers // We must have dex to pc entries or else the loop will go beyond the end of the table. 57159aa95e1e23cd585ac305b44b4cd65ae72048a4Ian Rogers DCHECK_GT(total_size, pc_to_dex_size); 5896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers for (uint32_t i = 0; i < pc_to_dex_size; ++i) { 5912d16ad924836cad46419a0f7eb57e13363139efVladimir Marko DecodeUnsignedLeb128(&table); // Move ptr past native PC delta. 6012d16ad924836cad46419a0f7eb57e13363139efVladimir Marko DecodeSignedLeb128(&table); // Move ptr past dex PC delta. 6196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 6296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 6396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return table; 6496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 6596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 6696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers class DexToPcIterator { 6796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers public: 6896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers DexToPcIterator(const MappingTable* table, uint32_t element) : 69159aa95e1e23cd585ac305b44b4cd65ae72048a4Ian Rogers table_(table), element_(element), end_(table_->DexToPcSize()), encoded_table_ptr_(nullptr), 7096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers native_pc_offset_(0), dex_pc_(0) { 71159aa95e1e23cd585ac305b44b4cd65ae72048a4Ian Rogers if (element == 0) { // An iterator wanted from the start. 7220ab6c861d248ae2822b5f38d5c09dff7506fc3aIan Rogers if (end_ > 0) { 73159aa95e1e23cd585ac305b44b4cd65ae72048a4Ian Rogers encoded_table_ptr_ = table_->FirstDexToPcPtr(); 7420ab6c861d248ae2822b5f38d5c09dff7506fc3aIan Rogers native_pc_offset_ = DecodeUnsignedLeb128(&encoded_table_ptr_); 751e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko // First delta is always positive. 761e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex_pc_ = static_cast<uint32_t>(DecodeSignedLeb128(&encoded_table_ptr_)); 7720ab6c861d248ae2822b5f38d5c09dff7506fc3aIan Rogers } 78159aa95e1e23cd585ac305b44b4cd65ae72048a4Ian Rogers } else { // An iterator wanted from the end. 7996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers DCHECK_EQ(table_->DexToPcSize(), element); 8096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 8196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 8296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t NativePcOffset() const { 8396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return native_pc_offset_; 8496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 8596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t DexPc() const { 8696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return dex_pc_; 8796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 8896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers void operator++() { 8996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers ++element_; 9096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers if (element_ != end_) { // Avoid reading beyond the end of the table. 911e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko native_pc_offset_ += DecodeUnsignedLeb128(&encoded_table_ptr_); 921e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko // For negative delta, unsigned overflow after static_cast does exactly what we need. 931e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex_pc_ += static_cast<uint32_t>(DecodeSignedLeb128(&encoded_table_ptr_)); 9496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 9596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 9696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers bool operator==(const DexToPcIterator& rhs) const { 9796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers CHECK(table_ == rhs.table_); 9896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return element_ == rhs.element_; 9996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 10096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers bool operator!=(const DexToPcIterator& rhs) const { 10196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers CHECK(table_ == rhs.table_); 10296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return element_ != rhs.element_; 10396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 10496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 10596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers private: 10696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers const MappingTable* const table_; // The original table. 10796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t element_; // A value in the range 0 to end_. 10896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers const uint32_t end_; // Equal to table_->DexToPcSize(). 1092cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier const uint8_t* encoded_table_ptr_; // Either null or points to encoded data after this entry. 11096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t native_pc_offset_; // The current value of native pc offset. 11196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t dex_pc_; // The current value of dex pc. 11296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers }; 11396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 11496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers DexToPcIterator DexToPcBegin() const { 11596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return DexToPcIterator(this, 0); 11696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 11796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 11896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers DexToPcIterator DexToPcEnd() const { 11996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t size = DexToPcSize(); 12096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return DexToPcIterator(this, size); 12196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 12296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 12396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t PcToDexSize() const PURE { 12496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers const uint8_t* table = encoded_table_; 125159aa95e1e23cd585ac305b44b4cd65ae72048a4Ian Rogers if (table == nullptr) { 12696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return 0; 12796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } else { 12896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers DecodeUnsignedLeb128(&table); // Total_size, unused. 12996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t pc_to_dex_size = DecodeUnsignedLeb128(&table); 13096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return pc_to_dex_size; 13196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 13296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 13396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 13496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers const uint8_t* FirstPcToDexPtr() const { 13596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers const uint8_t* table = encoded_table_; 136159aa95e1e23cd585ac305b44b4cd65ae72048a4Ian Rogers if (table != nullptr) { 13796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers DecodeUnsignedLeb128(&table); // Total_size, unused. 13896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers DecodeUnsignedLeb128(&table); // PC to Dex size, unused. 13996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 14096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return table; 14196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 14296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 14396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers class PcToDexIterator { 14496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers public: 14596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers PcToDexIterator(const MappingTable* table, uint32_t element) : 146159aa95e1e23cd585ac305b44b4cd65ae72048a4Ian Rogers table_(table), element_(element), end_(table_->PcToDexSize()), encoded_table_ptr_(nullptr), 14796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers native_pc_offset_(0), dex_pc_(0) { 148159aa95e1e23cd585ac305b44b4cd65ae72048a4Ian Rogers if (element == 0) { // An iterator wanted from the start. 14920ab6c861d248ae2822b5f38d5c09dff7506fc3aIan Rogers if (end_ > 0) { 150159aa95e1e23cd585ac305b44b4cd65ae72048a4Ian Rogers encoded_table_ptr_ = table_->FirstPcToDexPtr(); 15120ab6c861d248ae2822b5f38d5c09dff7506fc3aIan Rogers native_pc_offset_ = DecodeUnsignedLeb128(&encoded_table_ptr_); 1521e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko // First delta is always positive. 1531e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex_pc_ = static_cast<uint32_t>(DecodeSignedLeb128(&encoded_table_ptr_)); 15420ab6c861d248ae2822b5f38d5c09dff7506fc3aIan Rogers } 155159aa95e1e23cd585ac305b44b4cd65ae72048a4Ian Rogers } else { // An iterator wanted from the end. 15696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers DCHECK_EQ(table_->PcToDexSize(), element); 15796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 15896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 15996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t NativePcOffset() const { 16096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return native_pc_offset_; 16196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 16296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t DexPc() const { 16396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return dex_pc_; 16496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 16596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers void operator++() { 16696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers ++element_; 16796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers if (element_ != end_) { // Avoid reading beyond the end of the table. 1681e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko native_pc_offset_ += DecodeUnsignedLeb128(&encoded_table_ptr_); 1691e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko // For negative delta, unsigned overflow after static_cast does exactly what we need. 1701e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex_pc_ += static_cast<uint32_t>(DecodeSignedLeb128(&encoded_table_ptr_)); 17196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 17296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 17396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers bool operator==(const PcToDexIterator& rhs) const { 17496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers CHECK(table_ == rhs.table_); 17596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return element_ == rhs.element_; 17696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 17796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers bool operator!=(const PcToDexIterator& rhs) const { 17896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers CHECK(table_ == rhs.table_); 17996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return element_ != rhs.element_; 18096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 18196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 18296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers private: 18396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers const MappingTable* const table_; // The original table. 18496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t element_; // A value in the range 0 to PcToDexSize. 18596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers const uint32_t end_; // Equal to table_->PcToDexSize(). 186159aa95e1e23cd585ac305b44b4cd65ae72048a4Ian Rogers const uint8_t* encoded_table_ptr_; // Either null or points to encoded data after this entry. 18796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t native_pc_offset_; // The current value of native pc offset. 18896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t dex_pc_; // The current value of dex pc. 18996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers }; 19096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 19196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers PcToDexIterator PcToDexBegin() const { 19296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return PcToDexIterator(this, 0); 19396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 19496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 19596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers PcToDexIterator PcToDexEnd() const { 19696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers uint32_t size = PcToDexSize(); 19796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers return PcToDexIterator(this, size); 19896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 19996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 20096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers private: 20196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers const uint8_t* const encoded_table_; 20296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers}; 20396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 20496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers} // namespace art 20596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers 20696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers#endif // ART_RUNTIME_MAPPING_TABLE_H_ 207