Encode VmapTable entries offset by 2 to reduce size.
We're using special values 0xffff and 0xfffe for an
fp register marker and for method pointer, respectively.
These values were being encoded as 3 bytes each and
this changes their encoding to 1 byte.
Bug: 9437697
Change-Id: Ic1720e898b131a5d3f6ca87d8e1ecdf76fb4160a
diff --git a/runtime/exception_test.cc b/runtime/exception_test.cc
index c7f537a..910a817 100644
--- a/runtime/exception_test.cc
+++ b/runtime/exception_test.cc
@@ -28,6 +28,7 @@
#include "sirt_ref.h"
#include "thread.h"
#include "UniquePtr.h"
+#include "vmap_table.h"
namespace art {
@@ -66,7 +67,7 @@
fake_mapping_data_.PushBackUnsigned(3 - 0); // offset 3
fake_mapping_data_.PushBackSigned(3 - 0); // maps to dex offset 3
- fake_vmap_table_data_.PushBackUnsigned(0);
+ fake_vmap_table_data_.PushBackUnsigned(0 + VmapTable::kEntryAdjustment);
fake_gc_map_.push_back(0); // 0 bytes to encode references and native pc offsets.
fake_gc_map_.push_back(0);
diff --git a/runtime/oat.cc b/runtime/oat.cc
index 81d4540..945cd77 100644
--- a/runtime/oat.cc
+++ b/runtime/oat.cc
@@ -22,7 +22,7 @@
namespace art {
const uint8_t OatHeader::kOatMagic[] = { 'o', 'a', 't', '\n' };
-const uint8_t OatHeader::kOatVersion[] = { '0', '1', '4', '\0' };
+const uint8_t OatHeader::kOatVersion[] = { '0', '1', '5', '\0' };
OatHeader::OatHeader() {
memset(this, 0, sizeof(*this));
diff --git a/runtime/vmap_table.h b/runtime/vmap_table.h
index abc50b9..2fbaebe 100644
--- a/runtime/vmap_table.h
+++ b/runtime/vmap_table.h
@@ -25,6 +25,10 @@
class VmapTable {
public:
+ // For efficient encoding of special values, entries are adjusted by 2.
+ static constexpr uint16_t kEntryAdjustment = 2u;
+ static constexpr uint16_t kAdjustedFpMarker = static_cast<uint16_t>(0xffffu + kEntryAdjustment);
+
explicit VmapTable(const uint8_t* table) : table_(table) {
}
@@ -33,11 +37,11 @@
const uint8_t* table = table_;
size_t size = DecodeUnsignedLeb128(&table);
CHECK_LT(n, size);
- uint16_t entry = DecodeUnsignedLeb128(&table);
+ uint16_t adjusted_entry = DecodeUnsignedLeb128(&table);
for (size_t i = 0; i < n; ++i) {
- entry = DecodeUnsignedLeb128(&table);
+ adjusted_entry = DecodeUnsignedLeb128(&table);
}
- return entry;
+ return adjusted_entry - kEntryAdjustment;
}
size_t Size() const {
@@ -58,16 +62,17 @@
bool is_float = (kind == kFloatVReg) || (kind == kDoubleLoVReg) || (kind == kDoubleHiVReg);
bool in_floats = false;
const uint8_t* table = table_;
+ uint16_t adjusted_vreg = vreg + kEntryAdjustment;
size_t end = DecodeUnsignedLeb128(&table);
for (size_t i = 0; i < end; ++i) {
// Stop if we find what we are are looking for.
- uint16_t entry = DecodeUnsignedLeb128(&table);
- if ((entry == vreg) && (in_floats == is_float)) {
+ uint16_t adjusted_entry = DecodeUnsignedLeb128(&table);
+ if ((adjusted_entry == adjusted_vreg) && (in_floats == is_float)) {
*vmap_offset = i;
return true;
}
// 0xffff is the marker for LR (return PC on x86), following it are spilled float registers.
- if (entry == 0xffff) {
+ if (adjusted_entry == kAdjustedFpMarker) {
in_floats = true;
}
}
@@ -89,7 +94,7 @@
if (UNLIKELY(is_float)) {
const uint8_t* table = table_;
DecodeUnsignedLeb128(&table); // Skip size.
- while (DecodeUnsignedLeb128(&table) != 0xffff) {
+ while (DecodeUnsignedLeb128(&table) != kAdjustedFpMarker) {
matches++;
}
matches++;