diff options
author | 2014-02-25 17:53:53 +0000 | |
---|---|---|
committer | 2014-02-25 19:03:17 +0000 | |
commit | 2e589aa58a1372909f95e731fd6b8895f6359c3a (patch) | |
tree | 6337f7e4765a6c6c1ba5d21e9f3f7c4ebe4971ee | |
parent | 661425e1f90d4f4ed44c66f5e74f48b92a3798df (diff) |
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
-rw-r--r-- | compiler/dex/quick/codegen_util.cc | 43 | ||||
-rw-r--r-- | runtime/exception_test.cc | 3 | ||||
-rw-r--r-- | runtime/oat.cc | 2 | ||||
-rw-r--r-- | runtime/vmap_table.h | 19 |
4 files changed, 38 insertions, 29 deletions
diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc index c5dccda228..31854496ab 100644 --- a/compiler/dex/quick/codegen_util.cc +++ b/compiler/dex/quick/codegen_util.cc @@ -25,6 +25,7 @@ #include "dex/verified_method.h" #include "verifier/dex_gc_map.h" #include "verifier/method_verifier.h" +#include "vmap_table.h" namespace art { @@ -1042,30 +1043,32 @@ void Mir2Lir::Materialize() { } CompiledMethod* Mir2Lir::GetCompiledMethod() { - // Combine vmap tables - core regs, then fp regs - into vmap_table - std::vector<uint16_t> raw_vmap_table; - // Core regs may have been inserted out of order - sort first - std::sort(core_vmap_table_.begin(), core_vmap_table_.end()); - for (size_t i = 0 ; i < core_vmap_table_.size(); ++i) { - // Copy, stripping out the phys register sort key - raw_vmap_table.push_back(~(-1 << VREG_NUM_WIDTH) & core_vmap_table_[i]); - } - // If we have a frame, push a marker to take place of lr + // Combine vmap tables - core regs, then fp regs - into vmap_table. + Leb128EncodingVector vmap_encoder; if (frame_size_ > 0) { - raw_vmap_table.push_back(INVALID_VREG); + // Prefix the encoded data with its size. + size_t size = core_vmap_table_.size() + 1 /* marker */ + fp_vmap_table_.size(); + vmap_encoder.Reserve(size + 1u); // All values are likely to be one byte in ULEB128 (<128). + vmap_encoder.PushBackUnsigned(size); + // Core regs may have been inserted out of order - sort first. + std::sort(core_vmap_table_.begin(), core_vmap_table_.end()); + for (size_t i = 0 ; i < core_vmap_table_.size(); ++i) { + // Copy, stripping out the phys register sort key. + vmap_encoder.PushBackUnsigned( + ~(-1 << VREG_NUM_WIDTH) & (core_vmap_table_[i] + VmapTable::kEntryAdjustment)); + } + // Push a marker to take place of lr. + vmap_encoder.PushBackUnsigned(VmapTable::kAdjustedFpMarker); + // fp regs already sorted. + for (uint32_t i = 0; i < fp_vmap_table_.size(); i++) { + vmap_encoder.PushBackUnsigned(fp_vmap_table_[i] + VmapTable::kEntryAdjustment); + } } else { DCHECK_EQ(__builtin_popcount(core_spill_mask_), 0); DCHECK_EQ(__builtin_popcount(fp_spill_mask_), 0); - } - // Combine vmap tables - core regs, then fp regs. fp regs already sorted - for (uint32_t i = 0; i < fp_vmap_table_.size(); i++) { - raw_vmap_table.push_back(fp_vmap_table_[i]); - } - Leb128EncodingVector vmap_encoder; - // Prefix the encoded data with its size. - vmap_encoder.PushBackUnsigned(raw_vmap_table.size()); - for (uint16_t cur : raw_vmap_table) { - vmap_encoder.PushBackUnsigned(cur); + DCHECK_EQ(core_vmap_table_.size(), 0u); + DCHECK_EQ(fp_vmap_table_.size(), 0u); + vmap_encoder.PushBackUnsigned(0u); // Size is 0. } CompiledMethod* result = new CompiledMethod(*cu_->compiler_driver, cu_->instruction_set, code_buffer_, frame_size_, diff --git a/runtime/exception_test.cc b/runtime/exception_test.cc index c7f537a785..910a817b2e 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 @@ class ExceptionTest : public CommonTest { 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 81d45405a7..945cd77703 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 abc50b973c..2fbaebe0c9 100644 --- a/runtime/vmap_table.h +++ b/runtime/vmap_table.h @@ -25,6 +25,10 @@ namespace art { 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 @@ class VmapTable { 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 @@ class VmapTable { 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 @@ class VmapTable { if (UNLIKELY(is_float)) { const uint8_t* table = table_; DecodeUnsignedLeb128(&table); // Skip size. - while (DecodeUnsignedLeb128(&table) != 0xffff) { + while (DecodeUnsignedLeb128(&table) != kAdjustedFpMarker) { matches++; } matches++; |