summaryrefslogtreecommitdiff
path: root/compiler/optimizing/builder.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/builder.cc')
-rw-r--r--compiler/optimizing/builder.cc70
1 files changed, 35 insertions, 35 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index ebbfb14190..21540e8ed7 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -375,7 +375,7 @@ void HGraphBuilder::InsertTryBoundaryBlocks(const DexFile::CodeItem& code_item)
// We do not split each edge separately, but rather create one boundary block
// that all predecessors are relinked to. This preserves loop headers (b/23895756).
for (auto entry : try_block_info) {
- HBasicBlock* try_block = graph_->GetBlock(entry.first);
+ HBasicBlock* try_block = graph_->GetBlocks()[entry.first];
for (HBasicBlock* predecessor : try_block->GetPredecessors()) {
if (GetTryItem(predecessor, try_block_info) != entry.second) {
// Found a predecessor not covered by the same TryItem. Insert entering
@@ -392,10 +392,10 @@ void HGraphBuilder::InsertTryBoundaryBlocks(const DexFile::CodeItem& code_item)
// Do a second pass over the try blocks and insert exit TryBoundaries where
// the successor is not in the same TryItem.
for (auto entry : try_block_info) {
- HBasicBlock* try_block = graph_->GetBlock(entry.first);
+ HBasicBlock* try_block = graph_->GetBlocks()[entry.first];
// NOTE: Do not use iterators because SplitEdge would invalidate them.
for (size_t i = 0, e = try_block->GetSuccessors().size(); i < e; ++i) {
- HBasicBlock* successor = try_block->GetSuccessor(i);
+ HBasicBlock* successor = try_block->GetSuccessors()[i];
// If the successor is a try block, all of its predecessors must be
// covered by the same TryItem. Otherwise the previous pass would have
@@ -581,7 +581,6 @@ bool HGraphBuilder::ComputeBranchTargets(const uint16_t* code_ptr,
HBasicBlock* HGraphBuilder::FindBlockStartingAt(int32_t dex_pc) const {
DCHECK_GE(dex_pc, 0);
- DCHECK_LT(static_cast<size_t>(dex_pc), branch_targets_.size());
return branch_targets_[dex_pc];
}
@@ -940,7 +939,8 @@ HClinitCheck* HGraphBuilder::ProcessClinitCheckForInvoke(
storage_index,
*dex_compilation_unit_->GetDexFile(),
is_outer_class,
- dex_pc);
+ dex_pc,
+ /*needs_access_check*/ false);
current_block_->AddInstruction(load_class);
clinit_check = new (arena_) HClinitCheck(load_class, dex_pc);
current_block_->AddInstruction(clinit_check);
@@ -1175,10 +1175,9 @@ void HGraphBuilder::PotentiallySimplifyFakeString(uint16_t original_dex_register
verified_method->GetStringInitPcRegMap();
auto map_it = string_init_map.find(dex_pc);
if (map_it != string_init_map.end()) {
- std::set<uint32_t> reg_set = map_it->second;
- for (auto set_it = reg_set.begin(); set_it != reg_set.end(); ++set_it) {
+ for (uint32_t reg : map_it->second) {
HInstruction* load_local = LoadLocal(original_dex_register, Primitive::kPrimNot, dex_pc);
- UpdateLocal(*set_it, load_local, dex_pc);
+ UpdateLocal(reg, load_local, dex_pc);
}
}
} else {
@@ -1302,7 +1301,13 @@ bool HGraphBuilder::IsOutermostCompilingClass(uint16_t type_index) const {
soa, dex_cache, class_loader, type_index, dex_compilation_unit_)));
Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass()));
- return outer_class.Get() == cls.Get();
+ // GetOutermostCompilingClass returns null when the class is unresolved
+ // (e.g. if it derives from an unresolved class). This is bogus knowing that
+ // we are compiling it.
+ // When this happens we cannot establish a direct relation between the current
+ // class and the outer class, so we return false.
+ // (Note that this is only used for optimizing invokes and field accesses)
+ return (cls.Get() != nullptr) && (outer_class.Get() == cls.Get());
}
void HGraphBuilder::BuildUnresolvedStaticFieldAccess(const Instruction& instruction,
@@ -1384,7 +1389,8 @@ bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction,
storage_index,
*dex_compilation_unit_->GetDexFile(),
is_outer_class,
- dex_pc);
+ dex_pc,
+ /*needs_access_check*/ false);
current_block_->AddInstruction(constant);
HInstruction* cls = constant;
@@ -1615,7 +1621,9 @@ void HGraphBuilder::BuildFillWideArrayData(HInstruction* object,
static TypeCheckKind ComputeTypeCheckKind(Handle<mirror::Class> cls)
SHARED_REQUIRES(Locks::mutator_lock_) {
- if (cls->IsInterface()) {
+ if (cls.Get() == nullptr) {
+ return TypeCheckKind::kUnresolvedCheck;
+ } else if (cls->IsInterface()) {
return TypeCheckKind::kInterfaceCheck;
} else if (cls->IsArrayClass()) {
if (cls->GetComponentType()->IsObjectClass()) {
@@ -1634,11 +1642,20 @@ static TypeCheckKind ComputeTypeCheckKind(Handle<mirror::Class> cls)
}
}
-bool HGraphBuilder::BuildTypeCheck(const Instruction& instruction,
+void HGraphBuilder::BuildTypeCheck(const Instruction& instruction,
uint8_t destination,
uint8_t reference,
uint16_t type_index,
uint32_t dex_pc) {
+ bool type_known_final, type_known_abstract, use_declaring_class;
+ bool can_access = compiler_driver_->CanAccessTypeWithoutChecks(
+ dex_compilation_unit_->GetDexMethodIndex(),
+ *dex_compilation_unit_->GetDexFile(),
+ type_index,
+ &type_known_final,
+ &type_known_abstract,
+ &use_declaring_class);
+
ScopedObjectAccess soa(Thread::Current());
StackHandleScope<2> hs(soa.Self());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(
@@ -1646,22 +1663,14 @@ bool HGraphBuilder::BuildTypeCheck(const Instruction& instruction,
soa.Self(), *dex_compilation_unit_->GetDexFile())));
Handle<mirror::Class> resolved_class(hs.NewHandle(dex_cache->GetResolvedType(type_index)));
- if ((resolved_class.Get() == nullptr) ||
- // TODO: Remove this check once the compiler actually knows which
- // ArtMethod it is compiling.
- (GetCompilingClass() == nullptr) ||
- !GetCompilingClass()->CanAccess(resolved_class.Get())) {
- MaybeRecordStat(MethodCompilationStat::kNotCompiledCantAccesType);
- return false;
- }
-
HInstruction* object = LoadLocal(reference, Primitive::kPrimNot, dex_pc);
HLoadClass* cls = new (arena_) HLoadClass(
graph_->GetCurrentMethod(),
type_index,
*dex_compilation_unit_->GetDexFile(),
IsOutermostCompilingClass(type_index),
- dex_pc);
+ dex_pc,
+ !can_access);
current_block_->AddInstruction(cls);
// The class needs a temporary before being used by the type check.
@@ -1676,7 +1685,6 @@ bool HGraphBuilder::BuildTypeCheck(const Instruction& instruction,
DCHECK_EQ(instruction.Opcode(), Instruction::CHECK_CAST);
current_block_->AddInstruction(new (arena_) HCheckCast(object, cls, check_kind, dex_pc));
}
- return true;
}
bool HGraphBuilder::NeedsAccessCheck(uint32_t type_index) const {
@@ -2791,16 +2799,13 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32
bool can_access = compiler_driver_->CanAccessTypeWithoutChecks(
dex_compilation_unit_->GetDexMethodIndex(), *dex_file_, type_index,
&type_known_final, &type_known_abstract, &dont_use_is_referrers_class);
- if (!can_access) {
- MaybeRecordStat(MethodCompilationStat::kNotCompiledCantAccesType);
- return false;
- }
current_block_->AddInstruction(new (arena_) HLoadClass(
graph_->GetCurrentMethod(),
type_index,
*dex_compilation_unit_->GetDexFile(),
IsOutermostCompilingClass(type_index),
- dex_pc));
+ dex_pc,
+ !can_access));
UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction(), dex_pc);
break;
}
@@ -2827,18 +2832,14 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32
uint8_t destination = instruction.VRegA_22c();
uint8_t reference = instruction.VRegB_22c();
uint16_t type_index = instruction.VRegC_22c();
- if (!BuildTypeCheck(instruction, destination, reference, type_index, dex_pc)) {
- return false;
- }
+ BuildTypeCheck(instruction, destination, reference, type_index, dex_pc);
break;
}
case Instruction::CHECK_CAST: {
uint8_t reference = instruction.VRegA_21c();
uint16_t type_index = instruction.VRegB_21c();
- if (!BuildTypeCheck(instruction, -1, reference, type_index, dex_pc)) {
- return false;
- }
+ BuildTypeCheck(instruction, -1, reference, type_index, dex_pc);
break;
}
@@ -2880,7 +2881,6 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32
} // NOLINT(readability/fn_size)
HLocal* HGraphBuilder::GetLocalAt(uint32_t register_index) const {
- DCHECK_LT(register_index, locals_.size());
return locals_[register_index];
}