Make CodeItem fields private
Make code item fields private and use accessors. Added a hand full of
friend classes to reduce the size of the change.
Changed default to be nullable and removed CreateNullable.
CreateNullable was a bad API since it defaulted to the unsafe, may
add a CreateNonNullable if it's important for performance.
Motivation:
Have a different layout for code items in cdex.
Bug: 63756964
Test: test-art-host-gtest
Test: test/testrunner/testrunner.py --host
Test: art/tools/run-jdwp-tests.sh '--mode=host' '--variant=X32' --debug
Change-Id: I42bc7435e20358682075cb6de52713b595f95bf9
diff --git a/compiler/compiler.cc b/compiler/compiler.cc
index bb614ae..47f44ff 100644
--- a/compiler/compiler.cc
+++ b/compiler/compiler.cc
@@ -19,6 +19,7 @@
#include <android-base/logging.h>
#include "base/macros.h"
+#include "code_item_accessors-inl.h"
#include "driver/compiler_driver.h"
#include "optimizing/optimizing_compiler.h"
#include "utils.h"
@@ -46,15 +47,16 @@
* Dalvik uses 16-bit uints for instruction and register counts. We'll limit to a quarter
* of that, which also guarantees we cannot overflow our 16-bit internal Quick SSA name space.
*/
- if (code_item.insns_size_in_code_units_ >= UINT16_MAX / 4) {
+ CodeItemDataAccessor accessor(&dex_file, &code_item);
+ if (accessor.InsnsSizeInCodeUnits() >= UINT16_MAX / 4) {
LOG(INFO) << "Method exceeds compiler instruction limit: "
- << code_item.insns_size_in_code_units_
+ << accessor.InsnsSizeInCodeUnits()
<< " in " << dex_file.PrettyMethod(method_idx);
return true;
}
- if (code_item.registers_size_ >= UINT16_MAX / 4) {
+ if (accessor.RegistersSize() >= UINT16_MAX / 4) {
LOG(INFO) << "Method exceeds compiler virtual register limit: "
- << code_item.registers_size_ << " in " << dex_file.PrettyMethod(method_idx);
+ << accessor.RegistersSize() << " in " << dex_file.PrettyMethod(method_idx);
return true;
}
return false;
diff --git a/compiler/debug/elf_debug_info_writer.h b/compiler/debug/elf_debug_info_writer.h
index 107ed48..0e11e32 100644
--- a/compiler/debug/elf_debug_info_writer.h
+++ b/compiler/debug/elf_debug_info_writer.h
@@ -260,14 +260,10 @@
// Write local variables.
LocalInfos local_infos;
- if (dex->DecodeDebugLocalInfo(accessor.RegistersSize(),
- accessor.InsSize(),
- accessor.InsnsSizeInCodeUnits(),
- accessor.DebugInfoOffset(),
- is_static,
- mi->dex_method_index,
- LocalInfoCallback,
- &local_infos)) {
+ if (accessor.DecodeDebugLocalInfo(is_static,
+ mi->dex_method_index,
+ LocalInfoCallback,
+ &local_infos)) {
for (const DexFile::LocalInfo& var : local_infos) {
if (var.reg_ < accessor.RegistersSize() - accessor.InsSize()) {
info_.StartTag(DW_TAG_variable);
diff --git a/compiler/debug/elf_debug_loc_writer.h b/compiler/debug/elf_debug_loc_writer.h
index 1d609af..34c2919 100644
--- a/compiler/debug/elf_debug_loc_writer.h
+++ b/compiler/debug/elf_debug_loc_writer.h
@@ -149,11 +149,12 @@
DCHECK_LT(stack_map_index, dex_register_maps.size());
DexRegisterMap dex_register_map = dex_register_maps[stack_map_index];
DCHECK(dex_register_map.IsValid());
+ CodeItemDataAccessor accessor(method_info->dex_file, method_info->code_item);
reg_lo = dex_register_map.GetDexRegisterLocation(
- vreg, method_info->code_item->registers_size_, code_info, encoding);
+ vreg, accessor.RegistersSize(), code_info, encoding);
if (is64bitValue) {
reg_hi = dex_register_map.GetDexRegisterLocation(
- vreg + 1, method_info->code_item->registers_size_, code_info, encoding);
+ vreg + 1, accessor.RegistersSize(), code_info, encoding);
}
// Add location entry for this address range.
diff --git a/compiler/dex/inline_method_analyser.cc b/compiler/dex/inline_method_analyser.cc
index b409eb2..80677b9 100644
--- a/compiler/dex/inline_method_analyser.cc
+++ b/compiler/dex/inline_method_analyser.cc
@@ -141,8 +141,11 @@
ArtMethod* GetTargetConstructor(ArtMethod* method, const Instruction* invoke_direct)
REQUIRES_SHARED(Locks::mutator_lock_) {
DCHECK_EQ(invoke_direct->Opcode(), Instruction::INVOKE_DIRECT);
- DCHECK_EQ(invoke_direct->VRegC_35c(),
- method->GetCodeItem()->registers_size_ - method->GetCodeItem()->ins_size_);
+ if (kIsDebugBuild) {
+ CodeItemDataAccessor accessor(method);
+ DCHECK_EQ(invoke_direct->VRegC_35c(),
+ accessor.RegistersSize() - accessor.InsSize());
+ }
uint32_t method_index = invoke_direct->VRegB_35c();
ArtMethod* target_method = Runtime::Current()->GetClassLinker()->LookupResolvedMethod(
method_index, method->GetDexCache(), method->GetClassLoader());
@@ -323,7 +326,7 @@
if (target_method->GetDeclaringClass()->IsObjectClass()) {
DCHECK_EQ(CodeItemDataAccessor(target_method).begin()->Opcode(), Instruction::RETURN_VOID);
} else {
- CodeItemDataAccessor target_code_item = CodeItemDataAccessor::CreateNullable(target_method);
+ CodeItemDataAccessor target_code_item(target_method);
if (!target_code_item.HasCodeItem()) {
return false; // Native constructor?
}
@@ -427,7 +430,7 @@
InlineMethodAnalyser::IPutVariant(Instruction::IPUT_SHORT), "iget/iput_short variant");
bool InlineMethodAnalyser::AnalyseMethodCode(ArtMethod* method, InlineMethod* result) {
- CodeItemDataAccessor code_item = CodeItemDataAccessor::CreateNullable(method);
+ CodeItemDataAccessor code_item(method);
if (!code_item.HasCodeItem()) {
// Native or abstract.
return false;
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 0631c0f..68f963e 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -949,14 +949,14 @@
ArtMethod* method,
std::set<std::pair<dex::TypeIndex, const DexFile*>>* exceptions_to_resolve)
REQUIRES_SHARED(Locks::mutator_lock_) {
- const DexFile::CodeItem* code_item = method->GetCodeItem();
- if (code_item == nullptr) {
+ if (method->GetCodeItem() == nullptr) {
return; // native or abstract method
}
- if (code_item->tries_size_ == 0) {
+ CodeItemDataAccessor accessor(method);
+ if (accessor.TriesSize() == 0) {
return; // nothing to process
}
- const uint8_t* encoded_catch_handler_list = DexFile::GetCatchHandlerData(*code_item, 0);
+ const uint8_t* encoded_catch_handler_list = accessor.GetCatchHandlerData();
size_t num_encoded_catch_handlers = DecodeUnsignedLeb128(&encoded_catch_handler_list);
for (size_t i = 0; i < num_encoded_catch_handlers; i++) {
int32_t encoded_catch_handler_size = DecodeSignedLeb128(&encoded_catch_handler_list);
diff --git a/compiler/exception_test.cc b/compiler/exception_test.cc
index 897b50b..4dbef0d 100644
--- a/compiler/exception_test.cc
+++ b/compiler/exception_test.cc
@@ -20,6 +20,7 @@
#include "base/callee_save_type.h"
#include "base/enums.h"
#include "class_linker.h"
+#include "code_item_accessors-inl.h"
#include "common_runtime_test.h"
#include "dex_file-inl.h"
#include "dex_file.h"
@@ -129,11 +130,12 @@
TEST_F(ExceptionTest, FindCatchHandler) {
ScopedObjectAccess soa(Thread::Current());
const DexFile::CodeItem* code_item = dex_->GetCodeItem(method_f_->GetCodeItemOffset());
+ CodeItemDataAccessor accessor(dex_, code_item);
ASSERT_TRUE(code_item != nullptr);
- ASSERT_EQ(2u, code_item->tries_size_);
- ASSERT_NE(0u, code_item->insns_size_in_code_units_);
+ ASSERT_EQ(2u, accessor.TriesSize());
+ ASSERT_NE(0u, accessor.InsnsSizeInCodeUnits());
const DexFile::TryItem *t0, *t1;
t0 = dex_->GetTryItems(*code_item, 0);
diff --git a/compiler/optimizing/block_builder.cc b/compiler/optimizing/block_builder.cc
index 58f591b..c505efa 100644
--- a/compiler/optimizing/block_builder.cc
+++ b/compiler/optimizing/block_builder.cc
@@ -18,10 +18,31 @@
#include "base/logging.h" // FOR VLOG.
#include "bytecode_utils.h"
+#include "code_item_accessors-inl.h"
#include "quicken_info.h"
namespace art {
+HBasicBlockBuilder::HBasicBlockBuilder(HGraph* graph,
+ const DexFile* const dex_file,
+ const CodeItemDebugInfoAccessor& accessor,
+ ScopedArenaAllocator* local_allocator)
+ : allocator_(graph->GetAllocator()),
+ graph_(graph),
+ dex_file_(dex_file),
+ code_item_accessor_(accessor),
+ local_allocator_(local_allocator),
+ branch_targets_(code_item_accessor_.HasCodeItem()
+ ? code_item_accessor_.InsnsSizeInCodeUnits()
+ : /* fake dex_pc=0 for intrinsic graph */ 1u,
+ nullptr,
+ local_allocator->Adapter(kArenaAllocGraphBuilder)),
+ throwing_blocks_(kDefaultNumberOfThrowingBlocks,
+ local_allocator->Adapter(kArenaAllocGraphBuilder)),
+ number_of_branches_(0u),
+ quicken_index_for_dex_pc_(std::less<uint32_t>(),
+ local_allocator->Adapter(kArenaAllocGraphBuilder)) {}
+
HBasicBlock* HBasicBlockBuilder::MaybeCreateBlockAt(uint32_t dex_pc) {
return MaybeCreateBlockAt(dex_pc, dex_pc);
}
@@ -41,20 +62,19 @@
// Create the first block for the dex instructions, single successor of the entry block.
MaybeCreateBlockAt(0u);
- if (code_item_->tries_size_ != 0) {
+ if (code_item_accessor_.TriesSize() != 0) {
// Create branch targets at the start/end of the TryItem range. These are
// places where the program might fall through into/out of the a block and
// where TryBoundary instructions will be inserted later. Other edges which
// enter/exit the try blocks are a result of branches/switches.
- for (size_t idx = 0; idx < code_item_->tries_size_; ++idx) {
- const DexFile::TryItem* try_item = DexFile::GetTryItems(*code_item_, idx);
- uint32_t dex_pc_start = try_item->start_addr_;
- uint32_t dex_pc_end = dex_pc_start + try_item->insn_count_;
+ for (const DexFile::TryItem& try_item : code_item_accessor_.TryItems()) {
+ uint32_t dex_pc_start = try_item.start_addr_;
+ uint32_t dex_pc_end = dex_pc_start + try_item.insn_count_;
MaybeCreateBlockAt(dex_pc_start);
- if (dex_pc_end < code_item_->insns_size_in_code_units_) {
+ if (dex_pc_end < code_item_accessor_.InsnsSizeInCodeUnits()) {
// TODO: Do not create block if the last instruction cannot fall through.
MaybeCreateBlockAt(dex_pc_end);
- } else if (dex_pc_end == code_item_->insns_size_in_code_units_) {
+ } else if (dex_pc_end == code_item_accessor_.InsnsSizeInCodeUnits()) {
// The TryItem spans until the very end of the CodeItem and therefore
// cannot have any code afterwards.
} else {
@@ -65,7 +85,7 @@
}
// Create branch targets for exception handlers.
- const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(*code_item_, 0);
+ const uint8_t* handlers_ptr = code_item_accessor_.GetCatchHandlerData();
uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
for (uint32_t idx = 0; idx < handlers_size; ++idx) {
CatchHandlerIterator iterator(handlers_ptr);
@@ -78,8 +98,7 @@
// Iterate over all instructions and find branching instructions. Create blocks for
// the locations these instructions branch to.
- IterationRange<DexInstructionIterator> instructions = code_item_->Instructions();
- for (const DexInstructionPcPair& pair : instructions) {
+ for (const DexInstructionPcPair& pair : code_item_accessor_) {
const uint32_t dex_pc = pair.DexPc();
const Instruction& instruction = pair.Inst();
@@ -109,7 +128,7 @@
if (instruction.CanFlowThrough()) {
DexInstructionIterator next(std::next(DexInstructionIterator(pair)));
- if (next == instructions.end()) {
+ if (next == code_item_accessor_.end()) {
// In the normal case we should never hit this but someone can artificially forge a dex
// file to fall-through out the method code. In this case we bail out compilation.
VLOG(compiler) << "Not compiled: Fall-through beyond the CodeItem";
@@ -130,7 +149,7 @@
bool is_throwing_block = false;
// Calculate the qucikening index here instead of CreateBranchTargets since it's easier to
// calculate in dex_pc order.
- for (const DexInstructionPcPair& pair : code_item_->Instructions()) {
+ for (const DexInstructionPcPair& pair : code_item_accessor_) {
const uint32_t dex_pc = pair.DexPc();
const Instruction& instruction = pair.Inst();
@@ -213,10 +232,12 @@
// successors matches the order in which runtime exception delivery searches
// for a handler.
static void LinkToCatchBlocks(HTryBoundary* try_boundary,
- const DexFile::CodeItem& code_item,
+ const CodeItemDataAccessor& accessor,
const DexFile::TryItem* try_item,
const ScopedArenaSafeMap<uint32_t, HBasicBlock*>& catch_blocks) {
- for (CatchHandlerIterator it(code_item, *try_item); it.HasNext(); it.Next()) {
+ for (CatchHandlerIterator it(accessor.GetCatchHandlerData(try_item->handler_off_));
+ it.HasNext();
+ it.Next()) {
try_boundary->AddExceptionHandler(catch_blocks.Get(it.GetHandlerAddress()));
}
}
@@ -232,7 +253,7 @@
}
}
- const Instruction& first = code_item_->InstructionAt(catch_block->GetDexPc());
+ const Instruction& first = code_item_accessor_.InstructionAt(catch_block->GetDexPc());
if (first.Opcode() == Instruction::MOVE_EXCEPTION) {
// Verifier guarantees that if a catch block begins with MOVE_EXCEPTION then
// it has no live normal predecessors.
@@ -250,7 +271,7 @@
}
void HBasicBlockBuilder::InsertTryBoundaryBlocks() {
- if (code_item_->tries_size_ == 0) {
+ if (code_item_accessor_.TriesSize() == 0) {
return;
}
@@ -272,12 +293,10 @@
// loop for synchronized blocks.
if (ContainsElement(throwing_blocks_, block)) {
// Try to find a TryItem covering the block.
- const int32_t try_item_idx = DexFile::FindTryItem(DexFile::GetTryItems(*code_item_, 0u),
- code_item_->tries_size_,
- block->GetDexPc());
- if (try_item_idx != -1) {
+ const DexFile::TryItem* try_item = code_item_accessor_.FindTryItem(block->GetDexPc());
+ if (try_item != nullptr) {
// Block throwing and in a TryItem. Store the try block information.
- try_block_info.Put(block->GetBlockId(), DexFile::GetTryItems(*code_item_, try_item_idx));
+ try_block_info.Put(block->GetBlockId(), try_item);
}
}
}
@@ -288,7 +307,7 @@
// Iterate over catch blocks, create artifical landing pads if necessary to
// simplify the CFG, and set metadata.
- const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(*code_item_, 0);
+ const uint8_t* handlers_ptr = code_item_accessor_.GetCatchHandlerData();
uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
for (uint32_t idx = 0; idx < handlers_size; ++idx) {
CatchHandlerIterator iterator(handlers_ptr);
@@ -336,7 +355,7 @@
HTryBoundary* try_entry = new (allocator_) HTryBoundary(
HTryBoundary::BoundaryKind::kEntry, try_block->GetDexPc());
try_block->CreateImmediateDominator()->AddInstruction(try_entry);
- LinkToCatchBlocks(try_entry, *code_item_, try_item, catch_blocks);
+ LinkToCatchBlocks(try_entry, code_item_accessor_, try_item, catch_blocks);
break;
}
}
@@ -364,13 +383,13 @@
HTryBoundary* try_exit =
new (allocator_) HTryBoundary(HTryBoundary::BoundaryKind::kExit, successor->GetDexPc());
graph_->SplitEdge(try_block, successor)->AddInstruction(try_exit);
- LinkToCatchBlocks(try_exit, *code_item_, try_item, catch_blocks);
+ LinkToCatchBlocks(try_exit, code_item_accessor_, try_item, catch_blocks);
}
}
}
bool HBasicBlockBuilder::Build() {
- DCHECK(code_item_ != nullptr);
+ DCHECK(code_item_accessor_.HasCodeItem());
DCHECK(graph_->GetBlocks().empty());
graph_->SetEntryBlock(new (allocator_) HBasicBlock(graph_, kNoDexPc));
@@ -388,7 +407,7 @@
}
void HBasicBlockBuilder::BuildIntrinsic() {
- DCHECK(code_item_ == nullptr);
+ DCHECK(!code_item_accessor_.HasCodeItem());
DCHECK(graph_->GetBlocks().empty());
// Create blocks.
diff --git a/compiler/optimizing/block_builder.h b/compiler/optimizing/block_builder.h
index 7d0f56d..e68b95c 100644
--- a/compiler/optimizing/block_builder.h
+++ b/compiler/optimizing/block_builder.h
@@ -19,6 +19,7 @@
#include "base/scoped_arena_allocator.h"
#include "base/scoped_arena_containers.h"
+#include "code_item_accessors.h"
#include "dex_file.h"
#include "nodes.h"
@@ -28,22 +29,8 @@
public:
HBasicBlockBuilder(HGraph* graph,
const DexFile* const dex_file,
- const DexFile::CodeItem* code_item,
- ScopedArenaAllocator* local_allocator)
- : allocator_(graph->GetAllocator()),
- graph_(graph),
- dex_file_(dex_file),
- code_item_(code_item),
- local_allocator_(local_allocator),
- branch_targets_(code_item != nullptr ? code_item->insns_size_in_code_units_
- : /* fake dex_pc=0 for intrinsic graph */ 1u,
- nullptr,
- local_allocator->Adapter(kArenaAllocGraphBuilder)),
- throwing_blocks_(kDefaultNumberOfThrowingBlocks,
- local_allocator->Adapter(kArenaAllocGraphBuilder)),
- number_of_branches_(0u),
- quicken_index_for_dex_pc_(std::less<uint32_t>(),
- local_allocator->Adapter(kArenaAllocGraphBuilder)) {}
+ const CodeItemDebugInfoAccessor& accessor,
+ ScopedArenaAllocator* local_allocator);
// Creates basic blocks in `graph_` at branch target dex_pc positions of the
// `code_item_`. Blocks are connected but left unpopulated with instructions.
@@ -83,7 +70,7 @@
HGraph* const graph_;
const DexFile* const dex_file_;
- const DexFile::CodeItem* const code_item_; // null for intrinsic graph.
+ CodeItemDataAccessor code_item_accessor_; // null code item for intrinsic graph.
ScopedArenaAllocator* const local_allocator_;
ScopedArenaVector<HBasicBlock*> branch_targets_;
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index d73ef1f..af537dd 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -37,7 +37,7 @@
namespace art {
HGraphBuilder::HGraphBuilder(HGraph* graph,
- const DexFile::CodeItem* code_item,
+ const CodeItemDebugInfoAccessor& accessor,
const DexCompilationUnit* dex_compilation_unit,
const DexCompilationUnit* outer_compilation_unit,
CompilerDriver* driver,
@@ -47,7 +47,7 @@
VariableSizedHandleScope* handles)
: graph_(graph),
dex_file_(&graph->GetDexFile()),
- code_item_(code_item),
+ code_item_accessor_(accessor),
dex_compilation_unit_(dex_compilation_unit),
outer_compilation_unit_(outer_compilation_unit),
compiler_driver_(driver),
@@ -57,6 +57,23 @@
handles_(handles),
return_type_(DataType::FromShorty(dex_compilation_unit_->GetShorty()[0])) {}
+HGraphBuilder::HGraphBuilder(HGraph* graph,
+ const DexCompilationUnit* dex_compilation_unit,
+ const CodeItemDebugInfoAccessor& accessor,
+ VariableSizedHandleScope* handles,
+ DataType::Type return_type)
+ : graph_(graph),
+ dex_file_(&graph->GetDexFile()),
+ code_item_accessor_(accessor),
+ dex_compilation_unit_(dex_compilation_unit),
+ outer_compilation_unit_(nullptr),
+ compiler_driver_(nullptr),
+ code_generator_(nullptr),
+ compilation_stats_(nullptr),
+ interpreter_metadata_(nullptr),
+ handles_(handles),
+ return_type_(return_type) {}
+
bool HGraphBuilder::SkipCompilation(size_t number_of_branches) {
if (compiler_driver_ == nullptr) {
// Note that the compiler driver is null when unit testing.
@@ -69,20 +86,20 @@
return false;
}
- if (compiler_options.IsHugeMethod(code_item_->insns_size_in_code_units_)) {
+ const uint32_t code_units = code_item_accessor_.InsnsSizeInCodeUnits();
+ if (compiler_options.IsHugeMethod(code_units)) {
VLOG(compiler) << "Skip compilation of huge method "
<< dex_file_->PrettyMethod(dex_compilation_unit_->GetDexMethodIndex())
- << ": " << code_item_->insns_size_in_code_units_ << " code units";
+ << ": " << code_units << " code units";
MaybeRecordStat(compilation_stats_, MethodCompilationStat::kNotCompiledHugeMethod);
return true;
}
// If it's large and contains no branches, it's likely to be machine generated initialization.
- if (compiler_options.IsLargeMethod(code_item_->insns_size_in_code_units_)
- && (number_of_branches == 0)) {
+ if (compiler_options.IsLargeMethod(code_units) && (number_of_branches == 0)) {
VLOG(compiler) << "Skip compilation of large method with no branch "
<< dex_file_->PrettyMethod(dex_compilation_unit_->GetDexMethodIndex())
- << ": " << code_item_->insns_size_in_code_units_ << " code units";
+ << ": " << code_units << " code units";
MaybeRecordStat(compilation_stats_, MethodCompilationStat::kNotCompiledLargeMethodNoBranches);
return true;
}
@@ -91,17 +108,17 @@
}
GraphAnalysisResult HGraphBuilder::BuildGraph() {
- DCHECK(code_item_ != nullptr);
+ DCHECK(code_item_accessor_.HasCodeItem());
DCHECK(graph_->GetBlocks().empty());
- graph_->SetNumberOfVRegs(code_item_->registers_size_);
- graph_->SetNumberOfInVRegs(code_item_->ins_size_);
- graph_->SetMaximumNumberOfOutVRegs(code_item_->outs_size_);
- graph_->SetHasTryCatch(code_item_->tries_size_ != 0);
+ graph_->SetNumberOfVRegs(code_item_accessor_.RegistersSize());
+ graph_->SetNumberOfInVRegs(code_item_accessor_.InsSize());
+ graph_->SetMaximumNumberOfOutVRegs(code_item_accessor_.OutsSize());
+ graph_->SetHasTryCatch(code_item_accessor_.TriesSize() != 0);
// Use ScopedArenaAllocator for all local allocations.
ScopedArenaAllocator local_allocator(graph_->GetArenaStack());
- HBasicBlockBuilder block_builder(graph_, dex_file_, code_item_, &local_allocator);
+ HBasicBlockBuilder block_builder(graph_, dex_file_, code_item_accessor_, &local_allocator);
SsaBuilder ssa_builder(graph_,
dex_compilation_unit_->GetClassLoader(),
dex_compilation_unit_->GetDexCache(),
@@ -111,7 +128,7 @@
&block_builder,
&ssa_builder,
dex_file_,
- code_item_,
+ code_item_accessor_,
return_type_,
dex_compilation_unit_,
outer_compilation_unit_,
@@ -150,7 +167,7 @@
}
void HGraphBuilder::BuildIntrinsicGraph(ArtMethod* method) {
- DCHECK(code_item_ == nullptr);
+ DCHECK(!code_item_accessor_.HasCodeItem());
DCHECK(graph_->GetBlocks().empty());
// Determine the number of arguments and associated vregs.
@@ -170,7 +187,10 @@
// Use ScopedArenaAllocator for all local allocations.
ScopedArenaAllocator local_allocator(graph_->GetArenaStack());
- HBasicBlockBuilder block_builder(graph_, dex_file_, /* code_item */ nullptr, &local_allocator);
+ HBasicBlockBuilder block_builder(graph_,
+ dex_file_,
+ CodeItemDebugInfoAccessor(),
+ &local_allocator);
SsaBuilder ssa_builder(graph_,
dex_compilation_unit_->GetClassLoader(),
dex_compilation_unit_->GetDexCache(),
@@ -180,7 +200,7 @@
&block_builder,
&ssa_builder,
dex_file_,
- /* code_item */ nullptr,
+ CodeItemDebugInfoAccessor(),
return_type_,
dex_compilation_unit_,
outer_compilation_unit_,
diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h
index 0bb3a05..c40e0b4 100644
--- a/compiler/optimizing/builder.h
+++ b/compiler/optimizing/builder.h
@@ -18,6 +18,7 @@
#define ART_COMPILER_OPTIMIZING_BUILDER_H_
#include "base/arena_object.h"
+#include "code_item_accessors.h"
#include "dex_file-inl.h"
#include "dex_file.h"
#include "driver/compiler_driver.h"
@@ -33,7 +34,7 @@
class HGraphBuilder : public ValueObject {
public:
HGraphBuilder(HGraph* graph,
- const DexFile::CodeItem* code_item,
+ const CodeItemDebugInfoAccessor& accessor,
const DexCompilationUnit* dex_compilation_unit,
const DexCompilationUnit* outer_compilation_unit,
CompilerDriver* driver,
@@ -45,20 +46,9 @@
// Only for unit testing.
HGraphBuilder(HGraph* graph,
const DexCompilationUnit* dex_compilation_unit,
- const DexFile::CodeItem& code_item,
+ const CodeItemDebugInfoAccessor& accessor,
VariableSizedHandleScope* handles,
- DataType::Type return_type = DataType::Type::kInt32)
- : graph_(graph),
- dex_file_(&graph->GetDexFile()),
- code_item_(&code_item),
- dex_compilation_unit_(dex_compilation_unit),
- outer_compilation_unit_(nullptr),
- compiler_driver_(nullptr),
- code_generator_(nullptr),
- compilation_stats_(nullptr),
- interpreter_metadata_(nullptr),
- handles_(handles),
- return_type_(return_type) {}
+ DataType::Type return_type = DataType::Type::kInt32);
GraphAnalysisResult BuildGraph();
void BuildIntrinsicGraph(ArtMethod* method);
@@ -70,7 +60,7 @@
HGraph* const graph_;
const DexFile* const dex_file_;
- const DexFile::CodeItem* const code_item_; // null for intrinsic graph.
+ const CodeItemDebugInfoAccessor code_item_accessor_; // null for intrinsic graph.
// The compilation unit of the current method being compiled. Note that
// it can be an inlined method.
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 8750910..7a66d80 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -1381,26 +1381,26 @@
bool same_dex_file = IsSameDexFile(*outer_compilation_unit_.GetDexFile(), *method->GetDexFile());
- const DexFile::CodeItem* code_item = method->GetCodeItem();
+ CodeItemDataAccessor accessor(method);
- if (code_item == nullptr) {
+ if (!accessor.HasCodeItem()) {
LOG_FAIL_NO_STAT()
<< "Method " << method->PrettyMethod() << " is not inlined because it is native";
return false;
}
size_t inline_max_code_units = compiler_driver_->GetCompilerOptions().GetInlineMaxCodeUnits();
- if (code_item->insns_size_in_code_units_ > inline_max_code_units) {
+ if (accessor.InsnsSizeInCodeUnits() > inline_max_code_units) {
LOG_FAIL(stats_, MethodCompilationStat::kNotInlinedCodeItem)
<< "Method " << method->PrettyMethod()
<< " is not inlined because its code item is too big: "
- << code_item->insns_size_in_code_units_
+ << accessor.InsnsSizeInCodeUnits()
<< " > "
<< inline_max_code_units;
return false;
}
- if (code_item->tries_size_ != 0) {
+ if (accessor.TriesSize() != 0) {
LOG_FAIL(stats_, MethodCompilationStat::kNotInlinedTryCatch)
<< "Method " << method->PrettyMethod() << " is not inlined because of try block";
return false;
@@ -1660,6 +1660,7 @@
const DexFile::CodeItem* code_item = resolved_method->GetCodeItem();
const DexFile& callee_dex_file = *resolved_method->GetDexFile();
uint32_t method_index = resolved_method->GetDexMethodIndex();
+ CodeItemDebugInfoAccessor code_item_accessor(&callee_dex_file, code_item);
ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker();
Handle<mirror::DexCache> dex_cache = NewHandleIfDifferent(resolved_method->GetDexCache(),
caller_compilation_unit_.GetDexCache(),
@@ -1714,7 +1715,7 @@
}
}
HGraphBuilder builder(callee_graph,
- code_item,
+ code_item_accessor,
&dex_compilation_unit,
&outer_compilation_unit_,
compiler_driver_,
@@ -1967,6 +1968,7 @@
return;
}
+ CodeItemDataAccessor accessor(&callee_graph->GetDexFile(), code_item);
HInliner inliner(callee_graph,
outermost_graph_,
codegen_,
@@ -1975,7 +1977,7 @@
compiler_driver_,
handles_,
inline_stats_,
- total_number_of_dex_registers_ + code_item->registers_size_,
+ total_number_of_dex_registers_ + accessor.RegistersSize(),
total_number_of_instructions_ + number_of_instructions,
this,
depth_ + 1);
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index e36d91f..3f5923f 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -39,6 +39,44 @@
namespace art {
+HInstructionBuilder::HInstructionBuilder(HGraph* graph,
+ HBasicBlockBuilder* block_builder,
+ SsaBuilder* ssa_builder,
+ const DexFile* dex_file,
+ const CodeItemDebugInfoAccessor& accessor,
+ DataType::Type return_type,
+ const DexCompilationUnit* dex_compilation_unit,
+ const DexCompilationUnit* outer_compilation_unit,
+ CompilerDriver* compiler_driver,
+ CodeGenerator* code_generator,
+ const uint8_t* interpreter_metadata,
+ OptimizingCompilerStats* compiler_stats,
+ VariableSizedHandleScope* handles,
+ ScopedArenaAllocator* local_allocator)
+ : allocator_(graph->GetAllocator()),
+ graph_(graph),
+ handles_(handles),
+ dex_file_(dex_file),
+ code_item_accessor_(accessor),
+ return_type_(return_type),
+ block_builder_(block_builder),
+ ssa_builder_(ssa_builder),
+ compiler_driver_(compiler_driver),
+ code_generator_(code_generator),
+ dex_compilation_unit_(dex_compilation_unit),
+ outer_compilation_unit_(outer_compilation_unit),
+ quicken_info_(interpreter_metadata),
+ compilation_stats_(compiler_stats),
+ local_allocator_(local_allocator),
+ locals_for_(local_allocator->Adapter(kArenaAllocGraphBuilder)),
+ current_block_(nullptr),
+ current_locals_(nullptr),
+ latest_result_(nullptr),
+ current_this_parameter_(nullptr),
+ loop_headers_(local_allocator->Adapter(kArenaAllocGraphBuilder)) {
+ loop_headers_.reserve(kDefaultNumberOfLoops);
+}
+
HBasicBlock* HInstructionBuilder::FindBlockStartingAt(uint32_t dex_pc) const {
return block_builder_->GetBlockAt(dex_pc);
}
@@ -273,7 +311,7 @@
}
bool HInstructionBuilder::Build() {
- DCHECK(code_item_ != nullptr);
+ DCHECK(code_item_accessor_.HasCodeItem());
locals_for_.resize(
graph_->GetBlocks().size(),
ScopedArenaVector<HInstruction*>(local_allocator_->Adapter(kArenaAllocGraphBuilder)));
@@ -323,7 +361,7 @@
quicken_index = block_builder_->GetQuickenIndex(block_dex_pc);
}
- for (const DexInstructionPcPair& pair : code_item_->Instructions(block_dex_pc)) {
+ for (const DexInstructionPcPair& pair : code_item_accessor_.InstructionsFrom(block_dex_pc)) {
if (current_block_ == nullptr) {
// The previous instruction ended this block.
break;
@@ -367,7 +405,7 @@
}
void HInstructionBuilder::BuildIntrinsic(ArtMethod* method) {
- DCHECK(code_item_ == nullptr);
+ DCHECK(!code_item_accessor_.HasCodeItem());
DCHECK(method->IsIntrinsic());
locals_for_.resize(
@@ -442,15 +480,16 @@
return false;
}
};
- CodeItemDebugInfoAccessor accessor(dex_file_, code_item_);
ArenaBitVector* locations = ArenaBitVector::Create(local_allocator_,
- accessor.InsnsSizeInCodeUnits(),
+ code_item_accessor_.InsnsSizeInCodeUnits(),
/* expandable */ false,
kArenaAllocGraphBuilder);
locations->ClearAllBits();
- dex_file_->DecodeDebugPositionInfo(accessor.DebugInfoOffset(), Callback::Position, locations);
+ dex_file_->DecodeDebugPositionInfo(code_item_accessor_.DebugInfoOffset(),
+ Callback::Position,
+ locations);
// Instruction-specific tweaks.
- for (const DexInstructionPcPair& inst : accessor) {
+ for (const DexInstructionPcPair& inst : code_item_accessor_) {
switch (inst->Opcode()) {
case Instruction::MOVE_EXCEPTION: {
// Stop in native debugger after the exception has been moved.
@@ -459,7 +498,7 @@
locations->ClearBit(inst.DexPc());
DexInstructionIterator next = std::next(DexInstructionIterator(inst));
DCHECK(next.DexPc() != inst.DexPc());
- if (next != accessor.end()) {
+ if (next != code_item_accessor_.end()) {
locations->SetBit(next.DexPc());
}
break;
@@ -1706,7 +1745,8 @@
int32_t payload_offset = instruction.VRegB_31t() + dex_pc;
const Instruction::ArrayDataPayload* payload =
- reinterpret_cast<const Instruction::ArrayDataPayload*>(code_item_->insns_ + payload_offset);
+ reinterpret_cast<const Instruction::ArrayDataPayload*>(
+ code_item_accessor_.Insns() + payload_offset);
const uint8_t* data = payload->data;
uint32_t element_count = payload->element_count;
diff --git a/compiler/optimizing/instruction_builder.h b/compiler/optimizing/instruction_builder.h
index 0500d40..b4e3051 100644
--- a/compiler/optimizing/instruction_builder.h
+++ b/compiler/optimizing/instruction_builder.h
@@ -19,6 +19,7 @@
#include "base/scoped_arena_allocator.h"
#include "base/scoped_arena_containers.h"
+#include "code_item_accessors.h"
#include "data_type.h"
#include "dex_file.h"
#include "dex_file_types.h"
@@ -50,7 +51,7 @@
HBasicBlockBuilder* block_builder,
SsaBuilder* ssa_builder,
const DexFile* dex_file,
- const DexFile::CodeItem* code_item,
+ const CodeItemDebugInfoAccessor& accessor,
DataType::Type return_type,
const DexCompilationUnit* dex_compilation_unit,
const DexCompilationUnit* outer_compilation_unit,
@@ -59,30 +60,7 @@
const uint8_t* interpreter_metadata,
OptimizingCompilerStats* compiler_stats,
VariableSizedHandleScope* handles,
- ScopedArenaAllocator* local_allocator)
- : allocator_(graph->GetAllocator()),
- graph_(graph),
- handles_(handles),
- dex_file_(dex_file),
- code_item_(code_item),
- return_type_(return_type),
- block_builder_(block_builder),
- ssa_builder_(ssa_builder),
- compiler_driver_(compiler_driver),
- code_generator_(code_generator),
- dex_compilation_unit_(dex_compilation_unit),
- outer_compilation_unit_(outer_compilation_unit),
- quicken_info_(interpreter_metadata),
- compilation_stats_(compiler_stats),
- local_allocator_(local_allocator),
- locals_for_(local_allocator->Adapter(kArenaAllocGraphBuilder)),
- current_block_(nullptr),
- current_locals_(nullptr),
- latest_result_(nullptr),
- current_this_parameter_(nullptr),
- loop_headers_(local_allocator->Adapter(kArenaAllocGraphBuilder)) {
- loop_headers_.reserve(kDefaultNumberOfLoops);
- }
+ ScopedArenaAllocator* local_allocator);
bool Build();
void BuildIntrinsic(ArtMethod* method);
@@ -329,7 +307,7 @@
// The dex file where the method being compiled is, and the bytecode data.
const DexFile* const dex_file_;
- const DexFile::CodeItem* const code_item_; // null for intrinsic graph.
+ const CodeItemDebugInfoAccessor code_item_accessor_; // null for intrinsic graph.
// The return type of the method being compiled.
const DataType::Type return_type_;
diff --git a/compiler/optimizing/optimization.cc b/compiler/optimizing/optimization.cc
index 7149d93..d8ac696 100644
--- a/compiler/optimizing/optimization.cc
+++ b/compiler/optimizing/optimization.cc
@@ -35,6 +35,7 @@
#include "bounds_check_elimination.h"
#include "cha_guard_optimization.h"
+#include "code_item_accessors-inl.h"
#include "code_sinking.h"
#include "constant_folding.h"
#include "constructor_fence_redundancy_elimination.h"
@@ -241,7 +242,8 @@
opt = new (allocator) HDeadCodeElimination(graph, stats, name);
break;
case OptimizationPass::kInliner: {
- size_t number_of_dex_registers = dex_compilation_unit.GetCodeItem()->registers_size_;
+ CodeItemDataAccessor accessor(dex_compilation_unit.GetDexFile(),
+ dex_compilation_unit.GetCodeItem());
opt = new (allocator) HInliner(graph, // outer_graph
graph, // outermost_graph
codegen,
@@ -250,7 +252,7 @@
driver,
handles,
stats,
- number_of_dex_registers,
+ accessor.RegistersSize(),
/* total_number_of_instructions */ 0,
/* parent */ nullptr,
/* depth */ 0,
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 24b1a12..9d04dd8 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -766,11 +766,13 @@
static constexpr size_t kSpaceFilterOptimizingThreshold = 128;
const CompilerOptions& compiler_options = compiler_driver->GetCompilerOptions();
if ((compiler_options.GetCompilerFilter() == CompilerFilter::kSpace)
- && (code_item->insns_size_in_code_units_ > kSpaceFilterOptimizingThreshold)) {
+ && (CodeItemInstructionAccessor(&dex_file, code_item).InsnsSizeInCodeUnits() >
+ kSpaceFilterOptimizingThreshold)) {
MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kNotCompiledSpaceFilter);
return nullptr;
}
+ CodeItemDebugInfoAccessor code_item_accessor(&dex_file, code_item);
HGraph* graph = new (allocator) HGraph(
allocator,
arena_stack,
@@ -814,7 +816,7 @@
VLOG(compiler) << "Building " << pass_observer.GetMethodName();
PassScope scope(HGraphBuilder::kBuilderPassName, &pass_observer);
HGraphBuilder builder(graph,
- code_item,
+ code_item_accessor,
&dex_compilation_unit,
&dex_compilation_unit,
compiler_driver,
@@ -932,7 +934,7 @@
VLOG(compiler) << "Building intrinsic graph " << pass_observer.GetMethodName();
PassScope scope(HGraphBuilder::kBuilderPassName, &pass_observer);
HGraphBuilder builder(graph,
- /* code_item */ nullptr,
+ CodeItemDebugInfoAccessor(), // Null code item.
&dex_compilation_unit,
&dex_compilation_unit,
compiler_driver,
diff --git a/compiler/optimizing/optimizing_unit_test.h b/compiler/optimizing/optimizing_unit_test.h
index 158c252..7d05262 100644
--- a/compiler/optimizing/optimizing_unit_test.h
+++ b/compiler/optimizing/optimizing_unit_test.h
@@ -19,6 +19,7 @@
#include "base/scoped_arena_allocator.h"
#include "builder.h"
+#include "code_item_accessors-inl.h"
#include "common_compiler_test.h"
#include "dex_file.h"
#include "dex_instruction.h"
@@ -145,7 +146,8 @@
/* access_flags */ 0u,
/* verified_method */ nullptr,
handles_->NewHandle<mirror::DexCache>(nullptr));
- HGraphBuilder builder(graph, dex_compilation_unit, *code_item, handles_.get(), return_type);
+ CodeItemDebugInfoAccessor accessor(&graph->GetDexFile(), code_item);
+ HGraphBuilder builder(graph, dex_compilation_unit, accessor, handles_.get(), return_type);
bool graph_built = (builder.BuildGraph() == kAnalysisSuccess);
return graph_built ? graph : nullptr;
}