Remove DexFile direct accesses to CodeItem
Motivation: StandardDexFile and CompactDexFile should be able to a
have different layout for code items.
Also addressed comments from a previous CL.
Bug: 63756964
Test: test-art-host
Change-Id: I5ea7a853b8095f68b4443ded0f599f2ac5efbd3a
diff --git a/compiler/dex/dex_to_dex_decompiler_test.cc b/compiler/dex/dex_to_dex_decompiler_test.cc
index 89a63c0..8bccd3b 100644
--- a/compiler/dex/dex_to_dex_decompiler_test.cc
+++ b/compiler/dex/dex_to_dex_decompiler_test.cc
@@ -99,7 +99,7 @@
if (compiled_method != nullptr) {
table = compiled_method->GetVmapTable();
}
- optimizer::ArtDecompileDEX(updated_dex_file,
+ optimizer::ArtDecompileDEX(*updated_dex_file,
*it.GetMethodCodeItem(),
table,
/* decompile_return_instruction */ true);
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 5d4ed46..43e0db5 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -702,7 +702,7 @@
// stable order.
static void ResolveConstStrings(Handle<mirror::DexCache> dex_cache,
- const DexFile* dex_file,
+ const DexFile& dex_file,
const DexFile::CodeItem* code_item)
REQUIRES_SHARED(Locks::mutator_lock_) {
if (code_item == nullptr) {
@@ -711,7 +711,7 @@
}
ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
- for (const DexInstructionPcPair& inst : CodeItemInstructionAccessor(dex_file, code_item)) {
+ for (const DexInstructionPcPair& inst : CodeItemInstructionAccessor(&dex_file, code_item)) {
switch (inst->Opcode()) {
case Instruction::CONST_STRING:
case Instruction::CONST_STRING_JUMBO: {
@@ -773,7 +773,7 @@
continue;
}
previous_method_idx = method_idx;
- ResolveConstStrings(dex_cache, dex_file, it.GetMethodCodeItem());
+ ResolveConstStrings(dex_cache, *dex_file, it.GetMethodCodeItem());
it.Next();
}
DCHECK(!it.HasNext());
diff --git a/dexlayout/dex_ir.cc b/dexlayout/dex_ir.cc
index 157d4ef..d4a7395 100644
--- a/dexlayout/dex_ir.cc
+++ b/dexlayout/dex_ir.cc
@@ -669,7 +669,7 @@
}
}
- uint32_t size = DexFile::GetCodeItemSize(disk_code_item);
+ uint32_t size = dex_file.GetCodeItemSize(disk_code_item);
CodeItem* code_item = new CodeItem(
registers_size, ins_size, outs_size, debug_info, insns_size, insns, tries, handler_list);
code_item->SetSize(size);
diff --git a/runtime/cdex/compact_dex_file.cc b/runtime/cdex/compact_dex_file.cc
index a92ab28..8f90e09 100644
--- a/runtime/cdex/compact_dex_file.cc
+++ b/runtime/cdex/compact_dex_file.cc
@@ -16,6 +16,9 @@
#include "compact_dex_file.h"
+#include "dex_file-inl.h"
+#include "leb128.h"
+
namespace art {
constexpr uint8_t CompactDexFile::kDexMagic[kDexMagicSize];
@@ -51,4 +54,37 @@
static_cast<uint32_t>(FeatureFlags::kDefaultMethods)) != 0;
}
+uint32_t CompactDexFile::GetCodeItemSize(const DexFile::CodeItem& item) const {
+ // TODO: Clean up this temporary code duplication with StandardDexFile. Eventually the
+ // implementations will differ.
+ DCHECK(HasAddress(&item));
+ const CodeItem& code_item = down_cast<const CodeItem&>(item);
+ uintptr_t code_item_start = reinterpret_cast<uintptr_t>(&code_item);
+ uint32_t insns_size = code_item.insns_size_in_code_units_;
+ uint32_t tries_size = code_item.tries_size_;
+ const uint8_t* handler_data = GetCatchHandlerData(
+ DexInstructionIterator(code_item.insns_, code_item.insns_size_in_code_units_),
+ code_item.tries_size_,
+ 0);
+
+ if (tries_size == 0 || handler_data == nullptr) {
+ uintptr_t insns_end = reinterpret_cast<uintptr_t>(&code_item.insns_[insns_size]);
+ return insns_end - code_item_start;
+ } else {
+ // Get the start of the handler data.
+ uint32_t handlers_size = DecodeUnsignedLeb128(&handler_data);
+ // Manually read each handler.
+ for (uint32_t i = 0; i < handlers_size; ++i) {
+ int32_t uleb128_count = DecodeSignedLeb128(&handler_data) * 2;
+ if (uleb128_count <= 0) {
+ uleb128_count = -uleb128_count + 1;
+ }
+ for (int32_t j = 0; j < uleb128_count; ++j) {
+ DecodeUnsignedLeb128(&handler_data);
+ }
+ }
+ return reinterpret_cast<uintptr_t>(handler_data) - code_item_start;
+ }
+}
+
} // namespace art
diff --git a/runtime/cdex/compact_dex_file.h b/runtime/cdex/compact_dex_file.h
index e47f97e..4343229 100644
--- a/runtime/cdex/compact_dex_file.h
+++ b/runtime/cdex/compact_dex_file.h
@@ -47,6 +47,7 @@
struct CodeItem : public DexFile::CodeItem {
private:
// TODO: Insert compact dex specific fields here.
+ friend class CompactDexFile;
DISALLOW_COPY_AND_ASSIGN(CodeItem);
};
@@ -70,6 +71,8 @@
virtual bool SupportsDefaultMethods() const OVERRIDE;
+ uint32_t GetCodeItemSize(const DexFile::CodeItem& item) const OVERRIDE;
+
private:
// Not supported yet.
CompactDexFile(const uint8_t* base,
diff --git a/runtime/dex_file-inl.h b/runtime/dex_file-inl.h
index 7cc8b87..90b3c8d 100644
--- a/runtime/dex_file-inl.h
+++ b/runtime/dex_file-inl.h
@@ -507,6 +507,15 @@
return down_cast<const StandardDexFile*>(this);
}
+// Get the base of the encoded data for the given DexCode.
+inline const uint8_t* DexFile::GetCatchHandlerData(const DexInstructionIterator& code_item_end,
+ uint32_t tries_size,
+ uint32_t offset) {
+ const uint8_t* handler_data =
+ reinterpret_cast<const uint8_t*>(GetTryItems(code_item_end, tries_size));
+ return handler_data + offset;
+}
+
} // namespace art
#endif // ART_RUNTIME_DEX_FILE_INL_H_
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index d6469c6..16325b8 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -217,35 +217,6 @@
UNREACHABLE();
}
-uint32_t DexFile::GetCodeItemSize(const DexFile::CodeItem& code_item) {
- uintptr_t code_item_start = reinterpret_cast<uintptr_t>(&code_item);
- uint32_t insns_size = code_item.insns_size_in_code_units_;
- uint32_t tries_size = code_item.tries_size_;
- const uint8_t* handler_data = GetCatchHandlerData(
- DexInstructionIterator(code_item.insns_, code_item.insns_size_in_code_units_),
- code_item.tries_size_,
- 0);
-
- if (tries_size == 0 || handler_data == nullptr) {
- uintptr_t insns_end = reinterpret_cast<uintptr_t>(&code_item.insns_[insns_size]);
- return insns_end - code_item_start;
- } else {
- // Get the start of the handler data.
- uint32_t handlers_size = DecodeUnsignedLeb128(&handler_data);
- // Manually read each handler.
- for (uint32_t i = 0; i < handlers_size; ++i) {
- int32_t uleb128_count = DecodeSignedLeb128(&handler_data) * 2;
- if (uleb128_count <= 0) {
- uleb128_count = -uleb128_count + 1;
- }
- for (int32_t j = 0; j < uleb128_count; ++j) {
- DecodeUnsignedLeb128(&handler_data);
- }
- }
- return reinterpret_cast<uintptr_t>(handler_data) - code_item_start;
- }
-}
-
const DexFile::FieldId* DexFile::FindFieldId(const DexFile::TypeId& declaring_klass,
const DexFile::StringId& name,
const DexFile::TypeId& type) const {
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index b9bf119..6e11f09 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -308,7 +308,11 @@
debug_info_off_ = new_offset;
}
- private:
+ uint32_t GetDebugInfoOffset() const {
+ return debug_info_off_;
+ }
+
+ protected:
uint16_t registers_size_; // the number of registers used by this code
// (locals + parameters)
uint16_t ins_size_; // the number of words of incoming arguments to the method
@@ -333,7 +337,6 @@
friend class CodeItemDataAccessor;
friend class CodeItemDebugInfoAccessor;
friend class CodeItemInstructionAccessor;
- friend class DexFile; // TODO: Remove this one when it's cleaned up.
friend class VdexFile; // TODO: Remove this one when it's cleaned up.
DISALLOW_COPY_AND_ASSIGN(CodeItem);
};
@@ -583,7 +586,7 @@
uint32_t FindCodeItemOffset(const DexFile::ClassDef& class_def,
uint32_t dex_method_idx) const;
- static uint32_t GetCodeItemSize(const DexFile::CodeItem& disk_code_item);
+ virtual uint32_t GetCodeItemSize(const DexFile::CodeItem& disk_code_item) const = 0;
// Returns the declaring class descriptor string of a field id.
const char* GetFieldDeclaringClassDescriptor(const FieldId& field_id) const {
@@ -715,7 +718,7 @@
}
CHECK(oat_dex_file_ == nullptr)
<< "Should only use GetDebugInfoOffset in a non runtime setup";
- return code_item->debug_info_off_;
+ return code_item->GetDebugInfoOffset();
}
const char* GetReturnTypeDescriptor(const ProtoId& proto_id) const;
@@ -778,11 +781,7 @@
// Get the base of the encoded data for the given DexCode.
static const uint8_t* GetCatchHandlerData(const DexInstructionIterator& code_item_end,
uint32_t tries_size,
- uint32_t offset) {
- const uint8_t* handler_data =
- reinterpret_cast<const uint8_t*>(GetTryItems(code_item_end, tries_size));
- return handler_data + offset;
- }
+ uint32_t offset);
// Find which try region is associated with the given address (ie dex pc). Returns -1 if none.
static int32_t FindTryItem(const TryItem* try_items, uint32_t tries_size, uint32_t address);
diff --git a/runtime/dex_file_tracking_registrar.cc b/runtime/dex_file_tracking_registrar.cc
index c157ddc..bffca55 100644
--- a/runtime/dex_file_tracking_registrar.cc
+++ b/runtime/dex_file_tracking_registrar.cc
@@ -164,7 +164,7 @@
const DexFile::CodeItem* code_item = cdit.GetMethodCodeItem();
if (code_item != nullptr) {
const void* code_item_begin = reinterpret_cast<const void*>(code_item);
- size_t code_item_size = DexFile::GetCodeItemSize(*code_item);
+ size_t code_item_size = dex_file_->GetCodeItemSize(*code_item);
range_values_.push_back(std::make_tuple(code_item_begin, code_item_size, should_poison));
}
cdit.Next();
@@ -233,7 +233,7 @@
const DexFile::CodeItem* code_item = cdit.GetMethodCodeItem();
if (code_item != nullptr && strcmp(methodid_name, class_name) == 0) {
const void* code_item_begin = reinterpret_cast<const void*>(code_item);
- size_t code_item_size = DexFile::GetCodeItemSize(*code_item);
+ size_t code_item_size = dex_file_->GetCodeItemSize(*code_item);
range_values_.push_back(std::make_tuple(code_item_begin, code_item_size, should_poison));
}
cdit.Next();
diff --git a/runtime/dex_to_dex_decompiler.cc b/runtime/dex_to_dex_decompiler.cc
index dc7e11b..7f36c4e 100644
--- a/runtime/dex_to_dex_decompiler.cc
+++ b/runtime/dex_to_dex_decompiler.cc
@@ -31,11 +31,11 @@
class DexDecompiler {
public:
- DexDecompiler(const DexFile* dex_file,
+ DexDecompiler(const DexFile& dex_file,
const DexFile::CodeItem& code_item,
const ArrayRef<const uint8_t>& quickened_info,
bool decompile_return_instruction)
- : code_item_accessor_(dex_file, &code_item),
+ : code_item_accessor_(&dex_file, &code_item),
quicken_info_(quickened_info.data()),
quicken_info_number_of_indices_(QuickenInfoTable::NumberOfIndices(quickened_info.size())),
decompile_return_instruction_(decompile_return_instruction) {}
@@ -196,7 +196,7 @@
return true;
}
-bool ArtDecompileDEX(const DexFile* dex_file,
+bool ArtDecompileDEX(const DexFile& dex_file,
const DexFile::CodeItem& code_item,
const ArrayRef<const uint8_t>& quickened_info,
bool decompile_return_instruction) {
diff --git a/runtime/dex_to_dex_decompiler.h b/runtime/dex_to_dex_decompiler.h
index 804b7e8..a2e3f28 100644
--- a/runtime/dex_to_dex_decompiler.h
+++ b/runtime/dex_to_dex_decompiler.h
@@ -29,7 +29,7 @@
// to non-const has too many repercussions on the code base. We make it
// consistent with DexToDexCompiler, but we should really change it to
// DexFile::CodeItem*.
-bool ArtDecompileDEX(const DexFile* dex_file,
+bool ArtDecompileDEX(const DexFile& dex_file,
const DexFile::CodeItem& code_item,
const ArrayRef<const uint8_t>& quickened_data,
bool decompile_return_instruction);
diff --git a/runtime/standard_dex_file.cc b/runtime/standard_dex_file.cc
index b608341..843508d 100644
--- a/runtime/standard_dex_file.cc
+++ b/runtime/standard_dex_file.cc
@@ -16,6 +16,10 @@
#include "standard_dex_file.h"
+#include "base/casts.h"
+#include "dex_file-inl.h"
+#include "leb128.h"
+
namespace art {
const uint8_t StandardDexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' };
@@ -67,4 +71,35 @@
return GetDexVersion() >= DexFile::kDefaultMethodsVersion;
}
+uint32_t StandardDexFile::GetCodeItemSize(const DexFile::CodeItem& item) const {
+ DCHECK(HasAddress(&item));
+ const CodeItem& code_item = down_cast<const CodeItem&>(item);
+ uintptr_t code_item_start = reinterpret_cast<uintptr_t>(&code_item);
+ uint32_t insns_size = code_item.insns_size_in_code_units_;
+ uint32_t tries_size = code_item.tries_size_;
+ const uint8_t* handler_data = GetCatchHandlerData(
+ DexInstructionIterator(code_item.insns_, code_item.insns_size_in_code_units_),
+ code_item.tries_size_,
+ 0);
+
+ if (tries_size == 0 || handler_data == nullptr) {
+ uintptr_t insns_end = reinterpret_cast<uintptr_t>(&code_item.insns_[insns_size]);
+ return insns_end - code_item_start;
+ } else {
+ // Get the start of the handler data.
+ uint32_t handlers_size = DecodeUnsignedLeb128(&handler_data);
+ // Manually read each handler.
+ for (uint32_t i = 0; i < handlers_size; ++i) {
+ int32_t uleb128_count = DecodeSignedLeb128(&handler_data) * 2;
+ if (uleb128_count <= 0) {
+ uleb128_count = -uleb128_count + 1;
+ }
+ for (int32_t j = 0; j < uleb128_count; ++j) {
+ DecodeUnsignedLeb128(&handler_data);
+ }
+ }
+ return reinterpret_cast<uintptr_t>(handler_data) - code_item_start;
+ }
+}
+
} // namespace art
diff --git a/runtime/standard_dex_file.h b/runtime/standard_dex_file.h
index 80c406e..74749d2 100644
--- a/runtime/standard_dex_file.h
+++ b/runtime/standard_dex_file.h
@@ -35,6 +35,7 @@
struct CodeItem : public DexFile::CodeItem {
private:
// TODO: Insert standard dex specific fields here.
+ friend class StandardDexFile;
DISALLOW_COPY_AND_ASSIGN(CodeItem);
};
@@ -58,6 +59,8 @@
virtual bool SupportsDefaultMethods() const OVERRIDE;
+ uint32_t GetCodeItemSize(const DexFile::CodeItem& item) const OVERRIDE;
+
private:
StandardDexFile(const uint8_t* base,
size_t size,
diff --git a/runtime/vdex_file.cc b/runtime/vdex_file.cc
index a9af97d..6d37d06 100644
--- a/runtime/vdex_file.cc
+++ b/runtime/vdex_file.cc
@@ -254,7 +254,7 @@
quickening_info));
}
optimizer::ArtDecompileDEX(
- &target_dex_file,
+ target_dex_file,
*code_item,
GetQuickeningInfoAt(quickening_info, quickening_offset),
decompile_return_instruction);