summaryrefslogtreecommitdiffstats
path: root/runtime/mapping_table.h
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2013-08-09 22:05:32 -0700
committerIan Rogers <irogers@google.com>2013-08-12 06:16:03 +0000
commit96faf5b363d922ae91cf25404dee0e87c740c7c5 (patch)
treed397fd63cde72e897490e21b3af3c355db7a36d4 /runtime/mapping_table.h
parent49bded21270e8087e11d933d7b19aee22c0d8649 (diff)
downloadart-96faf5b363d922ae91cf25404dee0e87c740c7c5.zip
art-96faf5b363d922ae91cf25404dee0e87c740c7c5.tar.gz
art-96faf5b363d922ae91cf25404dee0e87c740c7c5.tar.bz2
Uleb128 compression of vmap and mapping table.
Bug 9437697. Change-Id: I30bcb97d12cd8b46d3b2cdcbdd358f08fbb9947a (cherry picked from commit 1809a72a66d245ae598582d658b93a24ac3bf01e)
Diffstat (limited to 'runtime/mapping_table.h')
-rw-r--r--runtime/mapping_table.h196
1 files changed, 196 insertions, 0 deletions
diff --git a/runtime/mapping_table.h b/runtime/mapping_table.h
new file mode 100644
index 0000000..2162008
--- /dev/null
+++ b/runtime/mapping_table.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_MAPPING_TABLE_H_
+#define ART_RUNTIME_MAPPING_TABLE_H_
+
+#include "base/logging.h"
+#include "leb128.h"
+
+namespace art {
+
+// A utility for processing the raw uleb128 encoded mapping table created by the quick compiler.
+class MappingTable {
+ public:
+ explicit MappingTable(const uint8_t* encoded_map) : encoded_table_(encoded_map) {
+ }
+
+ uint32_t TotalSize() const PURE {
+ const uint8_t* table = encoded_table_;
+ if (table == NULL) {
+ return 0;
+ } else {
+ return DecodeUnsignedLeb128(&table);
+ }
+ }
+
+ uint32_t DexToPcSize() const PURE {
+ const uint8_t* table = encoded_table_;
+ if (table == NULL) {
+ return 0;
+ } else {
+ uint32_t total_size = DecodeUnsignedLeb128(&table);
+ uint32_t pc_to_dex_size = DecodeUnsignedLeb128(&table);
+ return total_size - pc_to_dex_size;
+ }
+ }
+
+ const uint8_t* FirstDexToPcPtr() const {
+ const uint8_t* table = encoded_table_;
+ if (table != NULL) {
+ DecodeUnsignedLeb128(&table); // Total_size, unused.
+ uint32_t pc_to_dex_size = DecodeUnsignedLeb128(&table);
+ for (uint32_t i = 0; i < pc_to_dex_size; ++i) {
+ DecodeUnsignedLeb128(&table); // Move ptr past native PC.
+ DecodeUnsignedLeb128(&table); // Move ptr past dex PC.
+ }
+ }
+ return table;
+ }
+
+ class DexToPcIterator {
+ public:
+ DexToPcIterator(const MappingTable* table, uint32_t element) :
+ table_(table), element_(element), end_(table_->DexToPcSize()), encoded_table_ptr_(NULL),
+ native_pc_offset_(0), dex_pc_(0) {
+ if (element == 0) {
+ encoded_table_ptr_ = table_->FirstDexToPcPtr();
+ native_pc_offset_ = DecodeUnsignedLeb128(&encoded_table_ptr_);
+ dex_pc_ = DecodeUnsignedLeb128(&encoded_table_ptr_);
+ } else {
+ DCHECK_EQ(table_->DexToPcSize(), element);
+ }
+ }
+ uint32_t NativePcOffset() const {
+ return native_pc_offset_;
+ }
+ uint32_t DexPc() const {
+ return dex_pc_;
+ }
+ void operator++() {
+ ++element_;
+ if (element_ != end_) { // Avoid reading beyond the end of the table.
+ native_pc_offset_ = DecodeUnsignedLeb128(&encoded_table_ptr_);
+ dex_pc_ = DecodeUnsignedLeb128(&encoded_table_ptr_);
+ }
+ }
+ bool operator==(const DexToPcIterator& rhs) const {
+ CHECK(table_ == rhs.table_);
+ return element_ == rhs.element_;
+ }
+ bool operator!=(const DexToPcIterator& rhs) const {
+ CHECK(table_ == rhs.table_);
+ return element_ != rhs.element_;
+ }
+
+ private:
+ const MappingTable* const table_; // The original table.
+ uint32_t element_; // A value in the range 0 to end_.
+ const uint32_t end_; // Equal to table_->DexToPcSize().
+ const uint8_t* encoded_table_ptr_; // Either NULL or points to encoded data after this entry.
+ uint32_t native_pc_offset_; // The current value of native pc offset.
+ uint32_t dex_pc_; // The current value of dex pc.
+ };
+
+ DexToPcIterator DexToPcBegin() const {
+ return DexToPcIterator(this, 0);
+ }
+
+ DexToPcIterator DexToPcEnd() const {
+ uint32_t size = DexToPcSize();
+ return DexToPcIterator(this, size);
+ }
+
+ uint32_t PcToDexSize() const PURE {
+ const uint8_t* table = encoded_table_;
+ if (table == NULL) {
+ return 0;
+ } else {
+ DecodeUnsignedLeb128(&table); // Total_size, unused.
+ uint32_t pc_to_dex_size = DecodeUnsignedLeb128(&table);
+ return pc_to_dex_size;
+ }
+ }
+
+ const uint8_t* FirstPcToDexPtr() const {
+ const uint8_t* table = encoded_table_;
+ if (table != NULL) {
+ DecodeUnsignedLeb128(&table); // Total_size, unused.
+ DecodeUnsignedLeb128(&table); // PC to Dex size, unused.
+ }
+ return table;
+ }
+
+ class PcToDexIterator {
+ public:
+ PcToDexIterator(const MappingTable* table, uint32_t element) :
+ table_(table), element_(element), end_(table_->PcToDexSize()), encoded_table_ptr_(NULL),
+ native_pc_offset_(0), dex_pc_(0) {
+ if (element == 0) {
+ encoded_table_ptr_ = table_->FirstPcToDexPtr();
+ native_pc_offset_ = DecodeUnsignedLeb128(&encoded_table_ptr_);
+ dex_pc_ = DecodeUnsignedLeb128(&encoded_table_ptr_);
+ } else {
+ DCHECK_EQ(table_->PcToDexSize(), element);
+ }
+ }
+ uint32_t NativePcOffset() const {
+ return native_pc_offset_;
+ }
+ uint32_t DexPc() const {
+ return dex_pc_;
+ }
+ void operator++() {
+ ++element_;
+ if (element_ != end_) { // Avoid reading beyond the end of the table.
+ native_pc_offset_ = DecodeUnsignedLeb128(&encoded_table_ptr_);
+ dex_pc_ = DecodeUnsignedLeb128(&encoded_table_ptr_);
+ }
+ }
+ bool operator==(const PcToDexIterator& rhs) const {
+ CHECK(table_ == rhs.table_);
+ return element_ == rhs.element_;
+ }
+ bool operator!=(const PcToDexIterator& rhs) const {
+ CHECK(table_ == rhs.table_);
+ return element_ != rhs.element_;
+ }
+
+ private:
+ const MappingTable* const table_; // The original table.
+ uint32_t element_; // A value in the range 0 to PcToDexSize.
+ const uint32_t end_; // Equal to table_->PcToDexSize().
+ const uint8_t* encoded_table_ptr_; // Either NULL or points to encoded data after this entry.
+ uint32_t native_pc_offset_; // The current value of native pc offset.
+ uint32_t dex_pc_; // The current value of dex pc.
+ };
+
+ PcToDexIterator PcToDexBegin() const {
+ return PcToDexIterator(this, 0);
+ }
+
+ PcToDexIterator PcToDexEnd() const {
+ uint32_t size = PcToDexSize();
+ return PcToDexIterator(this, size);
+ }
+
+ private:
+ const uint8_t* const encoded_table_;
+};
+
+} // namespace art
+
+#endif // ART_RUNTIME_MAPPING_TABLE_H_