Revert "Revert "Load the array class in the compiler for allocations.""
This reverts commit fee255039e30c1c3dfc70c426c3d176221c3cdf9.
Change-Id: I02b45f9a659d872feeb35df40b42c1be9878413a
diff --git a/compiler/optimizing/bounds_check_elimination.cc b/compiler/optimizing/bounds_check_elimination.cc
index 7dc094b..2ee4db9 100644
--- a/compiler/optimizing/bounds_check_elimination.cc
+++ b/compiler/optimizing/bounds_check_elimination.cc
@@ -153,21 +153,6 @@
return instruction_ == bound.instruction_ && constant_ == bound.constant_;
}
- /*
- * Hunt "under the hood" of array lengths (leading to array references),
- * null checks (also leading to array references), and new arrays
- * (leading to the actual length). This makes it more likely related
- * instructions become actually comparable.
- */
- static HInstruction* HuntForDeclaration(HInstruction* instruction) {
- while (instruction->IsArrayLength() ||
- instruction->IsNullCheck() ||
- instruction->IsNewArray()) {
- instruction = instruction->InputAt(0);
- }
- return instruction;
- }
-
static bool Equal(HInstruction* instruction1, HInstruction* instruction2) {
if (instruction1 == instruction2) {
return true;
@@ -1136,7 +1121,7 @@
}
void VisitNewArray(HNewArray* new_array) OVERRIDE {
- HInstruction* len = new_array->InputAt(0);
+ HInstruction* len = new_array->GetLength();
if (!len->IsIntConstant()) {
HInstruction *left;
int32_t right_const;
@@ -1324,7 +1309,7 @@
InductionVarRange::Value v2;
bool needs_finite_test = false;
HInstruction* index = context->InputAt(0);
- HInstruction* hint = ValueBound::HuntForDeclaration(context->InputAt(1));
+ HInstruction* hint = HuntForDeclaration(context->InputAt(1));
if (induction_range_.GetInductionRange(context, index, hint, &v1, &v2, &needs_finite_test)) {
if (v1.is_known && (v1.a_constant == 0 || v1.a_constant == 1) &&
v2.is_known && (v2.a_constant == 0 || v2.a_constant == 1)) {
diff --git a/compiler/optimizing/bounds_check_elimination_test.cc b/compiler/optimizing/bounds_check_elimination_test.cc
index dfa1504..5d58207 100644
--- a/compiler/optimizing/bounds_check_elimination_test.cc
+++ b/compiler/optimizing/bounds_check_elimination_test.cc
@@ -596,13 +596,11 @@
HBasicBlock* block = new (allocator) HBasicBlock(graph);
graph->AddBlock(block);
entry->AddSuccessor(block);
+ // We pass a bogus constant for the class to avoid mocking one.
HInstruction* new_array = new (allocator) HNewArray(
constant_10,
- graph->GetCurrentMethod(),
- 0,
- dex::TypeIndex(static_cast<uint16_t>(Primitive::kPrimInt)),
- graph->GetDexFile(),
- kQuickAllocArray);
+ constant_10,
+ 0);
block->AddInstruction(new_array);
block->AddInstruction(new (allocator) HGoto());
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 07b1746..9c9c604 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -3984,19 +3984,16 @@
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kCallOnMainOnly);
InvokeRuntimeCallingConvention calling_convention;
- locations->AddTemp(Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
locations->SetOut(Location::RegisterLocation(R0));
- locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(1)));
- locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(2)));
+ locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
+ locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(1)));
}
void InstructionCodeGeneratorARM::VisitNewArray(HNewArray* instruction) {
- InvokeRuntimeCallingConvention calling_convention;
- __ LoadImmediate(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex().index_);
// Note: if heap poisoning is enabled, the entry point takes cares
// of poisoning the reference.
- codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
- CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>();
+ codegen_->InvokeRuntime(kQuickAllocArrayResolved, instruction, instruction->GetDexPc());
+ CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>();
}
void LocationsBuilderARM::VisitParameterValue(HParameterValue* instruction) {
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index b094e54..68d0b86 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -4747,22 +4747,16 @@
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kCallOnMainOnly);
InvokeRuntimeCallingConvention calling_convention;
- locations->AddTemp(LocationFrom(calling_convention.GetRegisterAt(0)));
locations->SetOut(LocationFrom(x0));
- locations->SetInAt(0, LocationFrom(calling_convention.GetRegisterAt(1)));
- locations->SetInAt(1, LocationFrom(calling_convention.GetRegisterAt(2)));
+ locations->SetInAt(0, LocationFrom(calling_convention.GetRegisterAt(0)));
+ locations->SetInAt(1, LocationFrom(calling_convention.GetRegisterAt(1)));
}
void InstructionCodeGeneratorARM64::VisitNewArray(HNewArray* instruction) {
- LocationSummary* locations = instruction->GetLocations();
- InvokeRuntimeCallingConvention calling_convention;
- Register type_index = RegisterFrom(locations->GetTemp(0), Primitive::kPrimInt);
- DCHECK(type_index.Is(w0));
- __ Mov(type_index, instruction->GetTypeIndex().index_);
// Note: if heap poisoning is enabled, the entry point takes cares
// of poisoning the reference.
- codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
- CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>();
+ codegen_->InvokeRuntime(kQuickAllocArrayResolved, instruction, instruction->GetDexPc());
+ CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>();
}
void LocationsBuilderARM64::VisitNewInstance(HNewInstance* instruction) {
diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc
index ecabc58..592ee5a 100644
--- a/compiler/optimizing/code_generator_arm_vixl.cc
+++ b/compiler/optimizing/code_generator_arm_vixl.cc
@@ -3997,19 +3997,16 @@
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kCallOnMainOnly);
InvokeRuntimeCallingConventionARMVIXL calling_convention;
- locations->AddTemp(LocationFrom(calling_convention.GetRegisterAt(0)));
locations->SetOut(LocationFrom(r0));
locations->SetInAt(0, LocationFrom(calling_convention.GetRegisterAt(1)));
locations->SetInAt(1, LocationFrom(calling_convention.GetRegisterAt(2)));
}
void InstructionCodeGeneratorARMVIXL::VisitNewArray(HNewArray* instruction) {
- InvokeRuntimeCallingConventionARMVIXL calling_convention;
- __ Mov(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex().index_);
// Note: if heap poisoning is enabled, the entry point takes cares
// of poisoning the reference.
- codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
- CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>();
+ codegen_->InvokeRuntime(kQuickAllocArrayResolved, instruction, instruction->GetDexPc());
+ CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>();
}
void LocationsBuilderARMVIXL::VisitParameterValue(HParameterValue* instruction) {
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc
index 24234e1..a038382 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -5897,21 +5897,14 @@
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kCallOnMainOnly);
InvokeRuntimeCallingConvention calling_convention;
- locations->AddTemp(Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
- locations->AddTemp(Location::RegisterLocation(calling_convention.GetRegisterAt(2)));
locations->SetOut(calling_convention.GetReturnLocation(Primitive::kPrimNot));
- locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(1)));
+ locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
+ locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(1)));
}
void InstructionCodeGeneratorMIPS::VisitNewArray(HNewArray* instruction) {
- InvokeRuntimeCallingConvention calling_convention;
- Register current_method_register = calling_convention.GetRegisterAt(2);
- __ Lw(current_method_register, SP, kCurrentMethodStackOffset);
- // Move an uint16_t value to a register.
- __ LoadConst32(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex().index_);
- codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
- CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck,
- void*, uint32_t, int32_t, ArtMethod*>();
+ codegen_->InvokeRuntime(kQuickAllocArrayResolved, instruction, instruction->GetDexPc());
+ CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>();
}
void LocationsBuilderMIPS::VisitNewInstance(HNewInstance* instruction) {
diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc
index fc8fb7a..446dea6 100644
--- a/compiler/optimizing/code_generator_mips64.cc
+++ b/compiler/optimizing/code_generator_mips64.cc
@@ -3841,19 +3841,14 @@
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kCallOnMainOnly);
InvokeRuntimeCallingConvention calling_convention;
- locations->AddTemp(Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
locations->SetOut(calling_convention.GetReturnLocation(Primitive::kPrimNot));
- locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(1)));
- locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(2)));
+ locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
+ locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(1)));
}
void InstructionCodeGeneratorMIPS64::VisitNewArray(HNewArray* instruction) {
- LocationSummary* locations = instruction->GetLocations();
- // Move an uint16_t value to a register.
- __ LoadConst32(locations->GetTemp(0).AsRegister<GpuRegister>(),
- instruction->GetTypeIndex().index_);
- codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
- CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>();
+ codegen_->InvokeRuntime(kQuickAllocArrayResolved, instruction, instruction->GetDexPc());
+ CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>();
}
void LocationsBuilderMIPS64::VisitNewInstance(HNewInstance* instruction) {
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index cc727d2..853c91f 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -4192,18 +4192,15 @@
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kCallOnMainOnly);
locations->SetOut(Location::RegisterLocation(EAX));
InvokeRuntimeCallingConvention calling_convention;
- locations->AddTemp(Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
- locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(1)));
- locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(2)));
+ locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
+ locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(1)));
}
void InstructionCodeGeneratorX86::VisitNewArray(HNewArray* instruction) {
- InvokeRuntimeCallingConvention calling_convention;
- __ movl(calling_convention.GetRegisterAt(0), Immediate(instruction->GetTypeIndex().index_));
// Note: if heap poisoning is enabled, the entry point takes cares
// of poisoning the reference.
- codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
- CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>();
+ codegen_->InvokeRuntime(kQuickAllocArrayResolved, instruction, instruction->GetDexPc());
+ CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>();
DCHECK(!codegen_->IsLeafMethod());
}
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 9adedab..74c71cc 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -4088,21 +4088,16 @@
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kCallOnMainOnly);
InvokeRuntimeCallingConvention calling_convention;
- locations->AddTemp(Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
locations->SetOut(Location::RegisterLocation(RAX));
- locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(1)));
- locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(2)));
+ locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
+ locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(1)));
}
void InstructionCodeGeneratorX86_64::VisitNewArray(HNewArray* instruction) {
- InvokeRuntimeCallingConvention calling_convention;
- codegen_->Load64BitValue(CpuRegister(calling_convention.GetRegisterAt(0)),
- instruction->GetTypeIndex().index_);
// Note: if heap poisoning is enabled, the entry point takes cares
// of poisoning the reference.
- codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
- CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>();
-
+ codegen_->InvokeRuntime(kQuickAllocArrayResolved, instruction, instruction->GetDexPc());
+ CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>();
DCHECK(!codegen_->IsLeafMethod());
}
diff --git a/compiler/optimizing/induction_var_range.cc b/compiler/optimizing/induction_var_range.cc
index 6d8ae75..3973985 100644
--- a/compiler/optimizing/induction_var_range.cc
+++ b/compiler/optimizing/induction_var_range.cc
@@ -114,12 +114,7 @@
}
} else {
*suitable = instruction;
- while (instruction->IsArrayLength() ||
- instruction->IsNullCheck() ||
- instruction->IsNewArray()) {
- instruction = instruction->InputAt(0);
- }
- return instruction == hint;
+ return HuntForDeclaration(instruction) == hint;
}
return false;
}
@@ -629,7 +624,7 @@
if (chase_hint_ == nullptr) {
return is_min ? Value(0) : Value(std::numeric_limits<int32_t>::max());
} else if (instruction->InputAt(0)->IsNewArray()) {
- return GetFetch(instruction->InputAt(0)->InputAt(0), trip, in_body, is_min);
+ return GetFetch(instruction->InputAt(0)->AsNewArray()->GetLength(), trip, in_body, is_min);
}
} else if (instruction->IsTypeConversion()) {
// Since analysis is 32-bit (or narrower), chase beyond widening along the path.
diff --git a/compiler/optimizing/induction_var_range_test.cc b/compiler/optimizing/induction_var_range_test.cc
index aa3e1aa..d81817f 100644
--- a/compiler/optimizing/induction_var_range_test.cc
+++ b/compiler/optimizing/induction_var_range_test.cc
@@ -697,13 +697,8 @@
}
TEST_F(InductionVarRangeTest, ArrayLengthAndHints) {
- HInstruction* new_array = new (&allocator_)
- HNewArray(x_,
- graph_->GetCurrentMethod(),
- 0,
- dex::TypeIndex(Primitive::kPrimInt),
- graph_->GetDexFile(),
- kQuickAllocArray);
+ // We pass a bogus constant for the class to avoid mocking one.
+ HInstruction* new_array = new (&allocator_) HNewArray(x_, x_, 0);
entry_block_->AddInstruction(new_array);
HInstruction* array_length = new (&allocator_) HArrayLength(new_array, 0);
entry_block_->AddInstruction(array_length);
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 78a4251..5d40f75 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -1429,15 +1429,6 @@
return false;
}
- if (current->IsNewArray() &&
- (current->AsNewArray()->GetEntrypoint() == kQuickAllocArrayWithAccessCheck)) {
- VLOG(compiler) << "Method " << callee_dex_file.PrettyMethod(method_index)
- << " could not be inlined because it is using an entrypoint"
- << " with access checks";
- // Allocation entrypoint does not handle inlined frames.
- return false;
- }
-
if (current->IsUnresolvedStaticFieldGet() ||
current->IsUnresolvedInstanceFieldGet() ||
current->IsUnresolvedStaticFieldSet() ||
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index 8ed0e7f..ef8d74d 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -1498,16 +1498,8 @@
uint32_t* args,
uint32_t register_index) {
HInstruction* length = graph_->GetIntConstant(number_of_vreg_arguments, dex_pc);
- bool finalizable;
- QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index, &finalizable)
- ? kQuickAllocArrayWithAccessCheck
- : kQuickAllocArray;
- HInstruction* object = new (arena_) HNewArray(length,
- graph_->GetCurrentMethod(),
- dex_pc,
- type_index,
- *dex_compilation_unit_->GetDexFile(),
- entrypoint);
+ HLoadClass* cls = BuildLoadClass(type_index, dex_pc, /* check_access */ true);
+ HInstruction* object = new (arena_) HNewArray(cls, length, dex_pc);
AppendInstruction(object);
const char* descriptor = dex_file_->StringByTypeIdx(type_index);
@@ -1644,9 +1636,13 @@
const DexCompilationUnit* compilation_unit =
outer ? outer_compilation_unit_ : dex_compilation_unit_;
const DexFile& dex_file = *compilation_unit->GetDexFile();
- Handle<mirror::DexCache> dex_cache = compilation_unit->GetDexCache();
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
+ soa.Decode<mirror::ClassLoader>(dex_compilation_unit_->GetClassLoader())));
+ Handle<mirror::Class> klass = handles_->NewHandle(compiler_driver_->ResolveClass(
+ soa, compilation_unit->GetDexCache(), class_loader, type_index, compilation_unit));
+
bool is_accessible = false;
- Handle<mirror::Class> klass = handles_->NewHandle(dex_cache->GetResolvedType(type_index));
if (!check_access) {
is_accessible = true;
} else if (klass.Get() != nullptr) {
@@ -2503,16 +2499,8 @@
case Instruction::NEW_ARRAY: {
dex::TypeIndex type_index(instruction.VRegC_22c());
HInstruction* length = LoadLocal(instruction.VRegB_22c(), Primitive::kPrimInt);
- bool finalizable;
- QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index, &finalizable)
- ? kQuickAllocArrayWithAccessCheck
- : kQuickAllocArray;
- AppendInstruction(new (arena_) HNewArray(length,
- graph_->GetCurrentMethod(),
- dex_pc,
- type_index,
- *dex_compilation_unit_->GetDexFile(),
- entrypoint));
+ HLoadClass* cls = BuildLoadClass(type_index, dex_pc, /* check_access */ true);
+ AppendInstruction(new (arena_) HNewArray(cls, length, dex_pc));
UpdateLocal(instruction.VRegA_22c(), current_block_->GetLastInstruction());
break;
}
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 911bfb9..35f59cb 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -777,7 +777,7 @@
// If the array is a NewArray with constant size, replace the array length
// with the constant instruction. This helps the bounds check elimination phase.
if (input->IsNewArray()) {
- input = input->InputAt(0);
+ input = input->AsNewArray()->GetLength();
if (input->IsIntConstant()) {
instruction->ReplaceWith(input);
}
@@ -1774,7 +1774,7 @@
}
if (potential_array->IsNewArray()) {
- return potential_array->InputAt(0) == potential_length;
+ return potential_array->AsNewArray()->GetLength() == potential_length;
}
return false;
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 53b0fdd..a2980dc 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -3801,6 +3801,15 @@
entrypoint_ = entrypoint;
}
+ HLoadClass* GetLoadClass() const {
+ HInstruction* input = InputAt(0);
+ if (input->IsClinitCheck()) {
+ input = input->InputAt(0);
+ }
+ DCHECK(input->IsLoadClass());
+ return input->AsLoadClass();
+ }
+
bool IsStringAlloc() const;
DECLARE_INSTRUCTION(NewInstance);
@@ -4355,23 +4364,12 @@
class HNewArray FINAL : public HExpression<2> {
public:
- HNewArray(HInstruction* length,
- HCurrentMethod* current_method,
- uint32_t dex_pc,
- dex::TypeIndex type_index,
- const DexFile& dex_file,
- QuickEntrypointEnum entrypoint)
- : HExpression(Primitive::kPrimNot, SideEffects::CanTriggerGC(), dex_pc),
- type_index_(type_index),
- dex_file_(dex_file),
- entrypoint_(entrypoint) {
- SetRawInputAt(0, length);
- SetRawInputAt(1, current_method);
+ HNewArray(HInstruction* cls, HInstruction* length, uint32_t dex_pc)
+ : HExpression(Primitive::kPrimNot, SideEffects::CanTriggerGC(), dex_pc) {
+ SetRawInputAt(0, cls);
+ SetRawInputAt(1, length);
}
- dex::TypeIndex GetTypeIndex() const { return type_index_; }
- const DexFile& GetDexFile() const { return dex_file_; }
-
// Calls runtime so needs an environment.
bool NeedsEnvironment() const OVERRIDE { return true; }
@@ -4380,15 +4378,18 @@
bool CanBeNull() const OVERRIDE { return false; }
- QuickEntrypointEnum GetEntrypoint() const { return entrypoint_; }
+ HLoadClass* GetLoadClass() const {
+ DCHECK(InputAt(0)->IsLoadClass());
+ return InputAt(0)->AsLoadClass();
+ }
+
+ HInstruction* GetLength() const {
+ return InputAt(1);
+ }
DECLARE_INSTRUCTION(NewArray);
private:
- const dex::TypeIndex type_index_;
- const DexFile& dex_file_;
- const QuickEntrypointEnum entrypoint_;
-
DISALLOW_COPY_AND_ASSIGN(HNewArray);
};
@@ -5891,7 +5892,10 @@
bool CanThrow() const OVERRIDE { return true; }
- HLoadClass* GetLoadClass() const { return InputAt(0)->AsLoadClass(); }
+ HLoadClass* GetLoadClass() const {
+ DCHECK(InputAt(0)->IsLoadClass());
+ return InputAt(0)->AsLoadClass();
+ }
DECLARE_INSTRUCTION(ClinitCheck);
@@ -6757,6 +6761,23 @@
std::copy_backward(blocks->begin() + after + 1u, blocks->begin() + old_size, blocks->end());
}
+/*
+ * Hunt "under the hood" of array lengths (leading to array references),
+ * null checks (also leading to array references), and new arrays
+ * (leading to the actual length). This makes it more likely related
+ * instructions become actually comparable.
+ */
+inline HInstruction* HuntForDeclaration(HInstruction* instruction) {
+ while (instruction->IsArrayLength() ||
+ instruction->IsNullCheck() ||
+ instruction->IsNewArray()) {
+ instruction = instruction->IsNewArray()
+ ? instruction->AsNewArray()->GetLength()
+ : instruction->InputAt(0);
+ }
+ return instruction;
+}
+
} // namespace art
#endif // ART_COMPILER_OPTIMIZING_NODES_H_
diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc
index 8854a2b..b02f250 100644
--- a/compiler/optimizing/reference_type_propagation.cc
+++ b/compiler/optimizing/reference_type_propagation.cc
@@ -548,11 +548,13 @@
}
void ReferenceTypePropagation::RTPVisitor::VisitNewInstance(HNewInstance* instr) {
- UpdateReferenceTypeInfo(instr, instr->GetTypeIndex(), instr->GetDexFile(), /* is_exact */ true);
+ ScopedObjectAccess soa(Thread::Current());
+ SetClassAsTypeInfo(instr, instr->GetLoadClass()->GetClass().Get(), /* is_exact */ true);
}
void ReferenceTypePropagation::RTPVisitor::VisitNewArray(HNewArray* instr) {
- UpdateReferenceTypeInfo(instr, instr->GetTypeIndex(), instr->GetDexFile(), /* is_exact */ true);
+ ScopedObjectAccess soa(Thread::Current());
+ SetClassAsTypeInfo(instr, instr->GetLoadClass()->GetClass().Get(), /* is_exact */ true);
}
static mirror::Class* GetClassFromDexCache(Thread* self,
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index ed24a07..436d331 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -1645,7 +1645,7 @@
// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_region_tlab, RegionTLAB)
// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_region_tlab, RegionTLAB)
GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_region_tlab, RegionTLAB)
-// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_region_tlab, RegionTLAB) implemented in asm
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_region_tlab, RegionTLAB)
// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_region_tlab, RegionTLAB)
GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_region_tlab, RegionTLAB)
GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_BYTES(_region_tlab, RegionTLAB)
@@ -1735,13 +1735,6 @@
// The common fast path code for art_quick_alloc_array_region_tlab.
-.macro ALLOC_ARRAY_TLAB_FAST_PATH slowPathLabel, xClass, wClass, xCount, wCount, xTemp0, wTemp0, xTemp1, wTemp1, xTemp2, wTemp2
- // Check null class
- cbz \wClass, \slowPathLabel
- ALLOC_ARRAY_TLAB_FAST_PATH_RESOLVED \slowPathLabel, \xClass, \wClass, \xCount, \wCount, \xTemp0, \wTemp0, \xTemp1, \wTemp1, \xTemp2, \wTemp2
-.endm
-
-// The common fast path code for art_quick_alloc_array_region_tlab.
.macro ALLOC_ARRAY_TLAB_FAST_PATH_RESOLVED slowPathLabel, xClass, wClass, xCount, wCount, xTemp0, wTemp0, xTemp1, wTemp1, xTemp2, wTemp2
// Array classes are never finalizable or uninitialized, no need to check.
ldr \wTemp0, [\xClass, #MIRROR_CLASS_COMPONENT_TYPE_OFFSET] // Load component type
@@ -1878,64 +1871,31 @@
// TODO: We could use this macro for the normal tlab allocator too.
// The common code for art_quick_alloc_array_*region_tlab
-.macro GENERATE_ALLOC_ARRAY_REGION_TLAB name, entrypoint, fast_path, is_resolved
+.macro GENERATE_ALLOC_ARRAY_REGION_TLAB name, entrypoint, fast_path
ENTRY \name
// Fast path array allocation for region tlab allocation.
- // x0: uint32_t type_idx
+ // x0: mirror::Class* type
// x1: int32_t component_count
- // x2: ArtMethod* method
- // x3-x7: free.
+ // x2-x7: free.
#if !defined(USE_READ_BARRIER)
mvn x0, xzr // Read barrier must be enabled here.
ret // Return -1.
#endif
-.if \is_resolved
mov x3, x0
- // If already resolved, class is stored in x0
-.else
- ldr x3, [x2, #ART_METHOD_DEX_CACHE_TYPES_OFFSET_64] // Load dex cache resolved types array
- // Load the class (x2)
- ldr w3, [x3, x0, lsl #COMPRESSED_REFERENCE_SIZE_SHIFT]
-.endif
- // Most common case: GC is not marking.
- ldr w4, [xSELF, #THREAD_IS_GC_MARKING_OFFSET]
- cbnz x4, .Lmarking\name
-.Ldo_allocation\name:
\fast_path .Lslow_path\name, x3, w3, x1, w1, x4, w4, x5, w5, x6, w6
-.Lmarking\name:
- // GC is marking, check the lock word of the class for the mark bit.
- // If the class is null, go slow path. The check is required to read the lock word.
- cbz w3, .Lslow_path\name
- // Class is not null, check mark bit in lock word.
- ldr w4, [x3, #MIRROR_OBJECT_LOCK_WORD_OFFSET]
- // If the bit is not zero, do the allocation.
- tbnz w4, #LOCK_WORD_MARK_BIT_SHIFT, .Ldo_allocation\name
- // The read barrier slow path. Mark
- // the class.
- stp x0, x1, [sp, #-32]! // Save registers (x0, x1, x2, lr).
- stp x2, xLR, [sp, #16]
- mov x0, x3 // Pass the class as the first param.
- bl artReadBarrierMark
- mov x3, x0 // Get the (marked) class back.
- ldp x2, xLR, [sp, #16]
- ldp x0, x1, [sp], #32 // Restore registers.
- b .Ldo_allocation\name
.Lslow_path\name:
- // x0: uint32_t type_idx / mirror::Class* klass (if resolved)
+ // x0: mirror::Class* klass
// x1: int32_t component_count
- // x2: ArtMethod* method
- // x3: Thread* self
+ // x2: Thread* self
SETUP_SAVE_REFS_ONLY_FRAME // save callee saves in case of GC
- mov x3, xSELF // pass Thread::Current
+ mov x2, xSELF // pass Thread::Current
bl \entrypoint
RESTORE_SAVE_REFS_ONLY_FRAME
RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
END \name
.endm
-GENERATE_ALLOC_ARRAY_REGION_TLAB art_quick_alloc_array_region_tlab, artAllocArrayFromCodeRegionTLAB, ALLOC_ARRAY_TLAB_FAST_PATH, 0
-// TODO: art_quick_alloc_array_resolved_region_tlab seems to not get called. Investigate compiler.
-GENERATE_ALLOC_ARRAY_REGION_TLAB art_quick_alloc_array_resolved_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, ALLOC_ARRAY_TLAB_FAST_PATH_RESOLVED, 1
+GENERATE_ALLOC_ARRAY_REGION_TLAB art_quick_alloc_array_resolved_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, ALLOC_ARRAY_TLAB_FAST_PATH_RESOLVED
/*
* Called by managed code when the thread has been asked to suspend.
diff --git a/runtime/arch/quick_alloc_entrypoints.S b/runtime/arch/quick_alloc_entrypoints.S
index 3959cbe..cd6424a 100644
--- a/runtime/arch/quick_alloc_entrypoints.S
+++ b/runtime/arch/quick_alloc_entrypoints.S
@@ -25,7 +25,7 @@
// Called by managed code to allocate an array.
THREE_ARG_DOWNCALL art_quick_alloc_array\c_suffix, artAllocArrayFromCode\cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
// Called by managed code to allocate an array of a resolve class.
-THREE_ARG_DOWNCALL art_quick_alloc_array_resolved\c_suffix, artAllocArrayFromCodeResolved\cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
+TWO_ARG_DOWNCALL art_quick_alloc_array_resolved\c_suffix, artAllocArrayFromCodeResolved\cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
// Called by managed code to allocate an array when the caller doesn't know whether it has access
// to the created type.
THREE_ARG_DOWNCALL art_quick_alloc_array_with_access_check\c_suffix, artAllocArrayFromCodeWithAccessCheck\cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
@@ -64,7 +64,7 @@
#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(c_suffix, cxx_suffix) \
THREE_ARG_DOWNCALL art_quick_alloc_array ## c_suffix, artAllocArrayFromCode ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(c_suffix, cxx_suffix) \
- THREE_ARG_DOWNCALL art_quick_alloc_array_resolved ## c_suffix, artAllocArrayFromCodeResolved ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
+ TWO_ARG_DOWNCALL art_quick_alloc_array_resolved ## c_suffix, artAllocArrayFromCodeResolved ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(c_suffix, cxx_suffix) \
THREE_ARG_DOWNCALL art_quick_alloc_array_with_access_check ## c_suffix, artAllocArrayFromCodeWithAccessCheck ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_BYTES(c_suffix, cxx_suffix) \
diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
index 550a5e8..f5509bd 100644
--- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S
+++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
@@ -986,7 +986,7 @@
// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_region_tlab, RegionTLAB)
// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_region_tlab, RegionTLAB)
GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_region_tlab, RegionTLAB)
-// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_region_tlab, RegionTLAB)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_region_tlab, RegionTLAB)
// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_region_tlab, RegionTLAB)
GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_region_tlab, RegionTLAB)
GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_BYTES(_region_tlab, RegionTLAB)
@@ -997,6 +997,7 @@
// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab, TLAB)
GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab, TLAB)
// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab, TLAB)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_tlab, TLAB)
GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_tlab, TLAB)
GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_BYTES(_tlab, TLAB)
GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_CHARS(_tlab, TLAB)
@@ -1115,12 +1116,11 @@
END_MACRO
// The fast path code for art_quick_alloc_array_region_tlab.
-// Inputs: RDI: uint32_t type_idx, RSI: int32_t component_count, RDX: ArtMethod* method
-// Temps: RCX: the class, r8, r9
+// Inputs: RDI: the class, RSI: int32_t component_count
+// Free temps: RCX, RDX, R8, R9
// Output: RAX: return value.
MACRO1(ALLOC_ARRAY_TLAB_FAST_PATH_RESOLVED, slowPathLabel)
- movq %rcx, %r8 // Save class for later
- movl MIRROR_CLASS_COMPONENT_TYPE_OFFSET(%rcx), %ecx // Load component type.
+ movl MIRROR_CLASS_COMPONENT_TYPE_OFFSET(%rdi), %ecx // Load component type.
UNPOISON_HEAP_REF ecx
movl MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET(%rcx), %ecx // Load primitive type.
shrq LITERAL(PRIMITIVE_TYPE_SIZE_SHIFT_SHIFT), %rcx // Get component size shift.
@@ -1147,8 +1147,8 @@
// Store the class pointer in the
// header.
// No fence needed for x86.
- POISON_HEAP_REF r8d
- movl %r8d, MIRROR_OBJECT_CLASS_OFFSET(%rax)
+ POISON_HEAP_REF edi
+ movl %edi, MIRROR_OBJECT_CLASS_OFFSET(%rax)
movl %esi, MIRROR_ARRAY_LENGTH_OFFSET(%rax)
ret // Fast path succeeded.
END_MACRO
@@ -1169,8 +1169,8 @@
MACRO1(ALLOC_ARRAY_TLAB_SLOW_PATH, cxx_name)
SETUP_SAVE_REFS_ONLY_FRAME // save ref containing registers for GC
// Outgoing argument set up
- movq %gs:THREAD_SELF_OFFSET, %rcx // pass Thread::Current()
- call CALLVAR(cxx_name) // cxx_name(arg0, arg1, arg2, Thread*)
+ movq %gs:THREAD_SELF_OFFSET, %rdx // pass Thread::Current()
+ call CALLVAR(cxx_name) // cxx_name(arg0, arg1, Thread*)
RESTORE_SAVE_REFS_ONLY_FRAME // restore frame up to return address
RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER // return or deliver exception
END_MACRO
@@ -1195,73 +1195,21 @@
ALLOC_OBJECT_TLAB_SLOW_PATH artAllocObjectFromCodeInitializedTLAB
END_FUNCTION art_quick_alloc_object_initialized_tlab
-// A hand-written override for GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_tlab, TLAB).
-DEFINE_FUNCTION art_quick_alloc_array_tlab
- // RDI: uint32_t type_idx, RSI: int32_t component_count, RDX: ArtMethod*
- // RCX: klass, R8, R9: free. RAX: return val.
- movq ART_METHOD_DEX_CACHE_TYPES_OFFSET_64(%rdx), %rcx // Load dex cache resolved types array
- movl 0(%rcx, %rdi, COMPRESSED_REFERENCE_SIZE), %ecx // Load the class
- testl %ecx, %ecx
- jz .Lart_quick_alloc_array_tlab_slow_path
- ALLOC_ARRAY_TLAB_FAST_PATH_RESOLVED .Lart_quick_alloc_array_tlab_slow_path
-.Lart_quick_alloc_array_tlab_slow_path:
- ALLOC_ARRAY_TLAB_SLOW_PATH artAllocArrayFromCodeTLAB
-END_FUNCTION art_quick_alloc_array_tlab
-
// A hand-written override for GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab, TLAB).
DEFINE_FUNCTION art_quick_alloc_array_resolved_tlab
- // RDI: mirror::Class* klass, RSI: int32_t component_count, RDX: ArtMethod*
- // RCX: mirror::Class* klass, R8, R9: free. RAX: return val.
- movq %rdi, %rcx
- // Already resolved, no null check.
+ // RDI: mirror::Class* klass, RSI: int32_t component_count
+ // RDX, RCX, R8, R9: free. RAX: return val.
ALLOC_ARRAY_TLAB_FAST_PATH_RESOLVED .Lart_quick_alloc_array_resolved_tlab_slow_path
.Lart_quick_alloc_array_resolved_tlab_slow_path:
ALLOC_ARRAY_TLAB_SLOW_PATH artAllocArrayFromCodeResolvedTLAB
END_FUNCTION art_quick_alloc_array_resolved_tlab
-// A hand-written override for GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_region_tlab, RegionTLAB).
-DEFINE_FUNCTION art_quick_alloc_array_region_tlab
- // Fast path region tlab allocation.
- // RDI: uint32_t type_idx, RSI: int32_t component_count, RDX: ArtMethod*
- // RCX: klass, R8, R9: free. RAX: return val.
- ASSERT_USE_READ_BARRIER
- movq ART_METHOD_DEX_CACHE_TYPES_OFFSET_64(%rdx), %rcx // Load dex cache resolved types array
- movl 0(%rcx, %rdi, COMPRESSED_REFERENCE_SIZE), %ecx // Load the class
- // Null check so that we can load the lock word.
- testl %ecx, %ecx
- jz .Lart_quick_alloc_array_region_tlab_slow_path
- // Since we have allocation entrypoint switching, we know the GC is marking.
- // Check the mark bit, if it is 0, do the read barrier mark.
- testl LITERAL(LOCK_WORD_MARK_BIT_MASK_SHIFTED), MIRROR_OBJECT_LOCK_WORD_OFFSET(%ecx)
- jz .Lart_quick_alloc_array_region_tlab_class_load_read_barrier_slow_path
-.Lart_quick_alloc_array_region_tlab_class_load_read_barrier_slow_path_exit:
- ALLOC_ARRAY_TLAB_FAST_PATH_RESOLVED .Lart_quick_alloc_array_region_tlab_slow_path
-.Lart_quick_alloc_array_region_tlab_class_load_read_barrier_slow_path:
- // The read barrier slow path. Mark the class.
- PUSH rdi
- PUSH rsi
- PUSH rdx
- // Outgoing argument set up
- movq %rcx, %rdi // Pass the class as the first param.
- call SYMBOL(artReadBarrierMark) // cxx_name(mirror::Object* obj)
- movq %rax, %rcx
- POP rdx
- POP rsi
- POP rdi
- jmp .Lart_quick_alloc_array_region_tlab_class_load_read_barrier_slow_path_exit
-.Lart_quick_alloc_array_region_tlab_slow_path:
- ALLOC_ARRAY_TLAB_SLOW_PATH artAllocArrayFromCodeRegionTLAB
-END_FUNCTION art_quick_alloc_array_region_tlab
-
// A hand-written override for GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_region_tlab, RegionTLAB).
DEFINE_FUNCTION art_quick_alloc_array_resolved_region_tlab
// Fast path region tlab allocation.
- // RDI: mirror::Class* klass, RSI: int32_t component_count, RDX: ArtMethod*
- // RCX: mirror::Class* klass, R8, R9: free. RAX: return val.
+ // RDI: mirror::Class* klass, RSI: int32_t component_count
+ // RCX, RDX, R8, R9: free. RAX: return val.
ASSERT_USE_READ_BARRIER
- movq %rdi, %rcx
- // Caller is responsible for read barrier.
- // Already resolved, no null check.
ALLOC_ARRAY_TLAB_FAST_PATH_RESOLVED .Lart_quick_alloc_array_resolved_region_tlab_slow_path
.Lart_quick_alloc_array_resolved_region_tlab_slow_path:
ALLOC_ARRAY_TLAB_SLOW_PATH artAllocArrayFromCodeResolvedRegionTLAB
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index 87046bc..ac0ce36 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -293,11 +293,10 @@
klass->GetComponentSizeShift(), allocator_type);
}
-template <bool kAccessCheck, bool kInstrumented>
+template <bool kInstrumented>
ALWAYS_INLINE
inline mirror::Array* AllocArrayFromCodeResolved(mirror::Class* klass,
int32_t component_count,
- ArtMethod* method,
Thread* self,
gc::AllocatorType allocator_type) {
DCHECK(klass != nullptr);
@@ -305,13 +304,6 @@
ThrowNegativeArraySizeException(component_count);
return nullptr; // Failure
}
- if (kAccessCheck) {
- mirror::Class* referrer = method->GetDeclaringClass();
- if (UNLIKELY(!referrer->CanAccess(klass))) {
- ThrowIllegalAccessErrorClass(referrer, klass);
- return nullptr; // Failure
- }
- }
// No need to retry a slow-path allocation as the above code won't cause a GC or thread
// suspension.
return mirror::Array::Alloc<kInstrumented>(self, klass, component_count,
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index b427c07..6a04f20 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -93,10 +93,9 @@
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Roles::uninterruptible_);
-template <bool kAccessCheck, bool kInstrumented>
+template <bool kInstrumented>
ALWAYS_INLINE inline mirror::Array* AllocArrayFromCodeResolved(mirror::Class* klass,
int32_t component_count,
- ArtMethod* method,
Thread* self,
gc::AllocatorType allocator_type)
REQUIRES_SHARED(Locks::mutator_lock_)
diff --git a/runtime/entrypoints/quick/quick_alloc_entrypoints.cc b/runtime/entrypoints/quick/quick_alloc_entrypoints.cc
index 23a99a0..3fa5fbf 100644
--- a/runtime/entrypoints/quick/quick_alloc_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_alloc_entrypoints.cc
@@ -93,11 +93,11 @@
allocator_type); \
} \
extern "C" mirror::Array* artAllocArrayFromCodeResolved##suffix##suffix2( \
- mirror::Class* klass, int32_t component_count, ArtMethod* method, Thread* self) \
+ mirror::Class* klass, int32_t component_count, Thread* self) \
REQUIRES_SHARED(Locks::mutator_lock_) { \
ScopedQuickEntrypointChecks sqec(self); \
- return AllocArrayFromCodeResolved<false, instrumented_bool>(klass, component_count, method, self, \
- allocator_type); \
+ return AllocArrayFromCodeResolved<instrumented_bool>(klass, component_count, self, \
+ allocator_type); \
} \
extern "C" mirror::Array* artAllocArrayFromCodeWithAccessCheck##suffix##suffix2( \
uint32_t type_idx, int32_t component_count, ArtMethod* method, Thread* self) \
@@ -149,7 +149,7 @@
#define GENERATE_ENTRYPOINTS(suffix) \
extern "C" void* art_quick_alloc_array##suffix(uint32_t, int32_t, ArtMethod* ref); \
-extern "C" void* art_quick_alloc_array_resolved##suffix(mirror::Class* klass, int32_t, ArtMethod* ref); \
+extern "C" void* art_quick_alloc_array_resolved##suffix(mirror::Class* klass, int32_t); \
extern "C" void* art_quick_alloc_array_with_access_check##suffix(uint32_t, int32_t, ArtMethod* ref); \
extern "C" void* art_quick_alloc_object_resolved##suffix(mirror::Class* klass); \
extern "C" void* art_quick_alloc_object_initialized##suffix(mirror::Class* klass); \
@@ -160,7 +160,7 @@
extern "C" void* art_quick_alloc_string_from_chars##suffix(int32_t, int32_t, void*); \
extern "C" void* art_quick_alloc_string_from_string##suffix(void*); \
extern "C" void* art_quick_alloc_array##suffix##_instrumented(uint32_t, int32_t, ArtMethod* ref); \
-extern "C" void* art_quick_alloc_array_resolved##suffix##_instrumented(mirror::Class* klass, int32_t, ArtMethod* ref); \
+extern "C" void* art_quick_alloc_array_resolved##suffix##_instrumented(mirror::Class* klass, int32_t); \
extern "C" void* art_quick_alloc_array_with_access_check##suffix##_instrumented(uint32_t, int32_t, ArtMethod* ref); \
extern "C" void* art_quick_alloc_object##suffix##_instrumented(uint32_t type_idx, ArtMethod* ref); \
extern "C" void* art_quick_alloc_object_resolved##suffix##_instrumented(mirror::Class* klass); \
diff --git a/runtime/entrypoints/quick/quick_entrypoints_list.h b/runtime/entrypoints/quick/quick_entrypoints_list.h
index 0e75e94..b44f29b 100644
--- a/runtime/entrypoints/quick/quick_entrypoints_list.h
+++ b/runtime/entrypoints/quick/quick_entrypoints_list.h
@@ -21,7 +21,7 @@
#define QUICK_ENTRYPOINT_LIST(V) \
V(AllocArray, void*, uint32_t, int32_t, ArtMethod*) \
- V(AllocArrayResolved, void*, mirror::Class*, int32_t, ArtMethod*) \
+ V(AllocArrayResolved, void*, mirror::Class*, int32_t) \
V(AllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*) \
V(AllocObjectResolved, void*, mirror::Class*) \
V(AllocObjectInitialized, void*, mirror::Class*) \
diff --git a/runtime/generated/asm_support_gen.h b/runtime/generated/asm_support_gen.h
index bebcd71..9e7f52b 100644
--- a/runtime/generated/asm_support_gen.h
+++ b/runtime/generated/asm_support_gen.h
@@ -60,10 +60,6 @@
DEFINE_CHECK_EQ(static_cast<int32_t>(ART_METHOD_DEX_CACHE_METHODS_OFFSET_32), (static_cast<int32_t>(art::ArtMethod:: DexCacheResolvedMethodsOffset(art::PointerSize::k32).Int32Value())))
#define ART_METHOD_DEX_CACHE_METHODS_OFFSET_64 24
DEFINE_CHECK_EQ(static_cast<int32_t>(ART_METHOD_DEX_CACHE_METHODS_OFFSET_64), (static_cast<int32_t>(art::ArtMethod:: DexCacheResolvedMethodsOffset(art::PointerSize::k64).Int32Value())))
-#define ART_METHOD_DEX_CACHE_TYPES_OFFSET_32 24
-DEFINE_CHECK_EQ(static_cast<int32_t>(ART_METHOD_DEX_CACHE_TYPES_OFFSET_32), (static_cast<int32_t>(art::ArtMethod:: DexCacheResolvedTypesOffset(art::PointerSize::k32).Int32Value())))
-#define ART_METHOD_DEX_CACHE_TYPES_OFFSET_64 32
-DEFINE_CHECK_EQ(static_cast<int32_t>(ART_METHOD_DEX_CACHE_TYPES_OFFSET_64), (static_cast<int32_t>(art::ArtMethod:: DexCacheResolvedTypesOffset(art::PointerSize::k64).Int32Value())))
#define ART_METHOD_JNI_OFFSET_32 28
DEFINE_CHECK_EQ(static_cast<int32_t>(ART_METHOD_JNI_OFFSET_32), (static_cast<int32_t>(art::ArtMethod:: EntryPointFromJniOffset(art::PointerSize::k32).Int32Value())))
#define ART_METHOD_JNI_OFFSET_64 40
diff --git a/runtime/oat.h b/runtime/oat.h
index f9396ae..88fa232 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -32,7 +32,7 @@
class PACKED(4) OatHeader {
public:
static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' };
- static constexpr uint8_t kOatVersion[] = { '0', '9', '9', '\0' }; // Remove old entrypoints
+ static constexpr uint8_t kOatVersion[] = { '1', '0', '0', '\0' }; // AllocArrayResolved change
static constexpr const char* kImageLocationKey = "image-location";
static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline";
diff --git a/test/559-checker-rtp-ifnotnull/src/Main.java b/test/559-checker-rtp-ifnotnull/src/Main.java
index 2dc5666..1e15654 100644
--- a/test/559-checker-rtp-ifnotnull/src/Main.java
+++ b/test/559-checker-rtp-ifnotnull/src/Main.java
@@ -18,7 +18,6 @@
public class Main {
/// CHECK-START: void Main.boundTypeForIfNotNull() builder (after)
- /// CHECK-DAG: <<Method:(i|j)\d+>> CurrentMethod
/// CHECK-DAG: <<Null:l\d+>> NullConstant
/// CHECK-DAG: <<Cst5:i\d+>> IntConstant 5
/// CHECK-DAG: <<Cst10:i\d+>> IntConstant 10
@@ -28,10 +27,12 @@
/// CHECK-DAG: <<LoopPhi>> Phi [<<Null>>,<<MergePhi:l\d+>>] klass:int[]
/// CHECK-DAG: <<BoundType:l\d+>> BoundType [<<LoopPhi>>] klass:int[] can_be_null:false
- /// CHECK-DAG: <<NewArray10:l\d+>> NewArray [<<Cst10>>,<<Method>>] klass:int[]
+ /// CHECK-DAG: <<LoadClass1:l\d+>> LoadClass
+ /// CHECK-DAG: <<LoadClass2:l\d+>> LoadClass
+ /// CHECK-DAG: <<NewArray10:l\d+>> NewArray [<<LoadClass2>>,<<Cst10>>] klass:int[]
/// CHECK-DAG: <<NotNullPhi:l\d+>> Phi [<<BoundType>>,<<NewArray10>>] klass:int[]
- /// CHECK-DAG: <<NewArray5:l\d+>> NewArray [<<Cst5>>,<<Method>>] klass:int[]
+ /// CHECK-DAG: <<NewArray5:l\d+>> NewArray [<<LoadClass1>>,<<Cst5>>] klass:int[]
/// CHECK-DAG: <<MergePhi>> Phi [<<NewArray5>>,<<NotNullPhi>>] klass:int[]
public static void boundTypeForIfNotNull() {
diff --git a/test/572-checker-array-get-regression/src/Main.java b/test/572-checker-array-get-regression/src/Main.java
index 89b97ed..03a8448 100644
--- a/test/572-checker-array-get-regression/src/Main.java
+++ b/test/572-checker-array-get-regression/src/Main.java
@@ -21,10 +21,10 @@
}
/// CHECK-START: java.lang.Integer Main.test() builder (after)
- /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod
/// CHECK-DAG: <<Const2P19:i\d+>> IntConstant 524288
/// CHECK-DAG: <<ConstM1:i\d+>> IntConstant -1
- /// CHECK-DAG: <<Array:l\d+>> NewArray [<<Const2P19>>,<<Method>>]
+ /// CHECK-DAG: <<LoadClass:l\d+>> LoadClass
+ /// CHECK-DAG: <<Array:l\d+>> NewArray [<<LoadClass>>,<<Const2P19>>]
/// CHECK-DAG: <<Length1:i\d+>> ArrayLength [<<Array>>]
/// CHECK-DAG: <<Index:i\d+>> Add [<<Length1>>,<<ConstM1>>]
/// CHECK-DAG: <<Length2:i\d+>> ArrayLength [<<Array>>]
@@ -34,10 +34,10 @@
/// CHECK-START: java.lang.Integer Main.test() register (before)
- /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod
/// CHECK-DAG: <<Const2P19:i\d+>> IntConstant 524288
/// CHECK-DAG: <<Const2P19M1:i\d+>> IntConstant 524287
- /// CHECK-DAG: <<Array:l\d+>> NewArray [<<Const2P19>>,<<Method>>]
+ /// CHECK-DAG: <<LoadClass:l\d+>> LoadClass
+ /// CHECK-DAG: <<Array:l\d+>> NewArray [<<LoadClass>>,<<Const2P19>>]
/// CHECK-DAG: <<LastElement:l\d+>> ArrayGet [<<Array>>,<<Const2P19M1>>]
/// CHECK-DAG: Return [<<LastElement>>]
diff --git a/tools/cpp-define-generator/offset_dexcache.def b/tools/cpp-define-generator/offset_dexcache.def
index abb5e1e..43f9434 100644
--- a/tools/cpp-define-generator/offset_dexcache.def
+++ b/tools/cpp-define-generator/offset_dexcache.def
@@ -34,7 +34,6 @@
// New macro suffix Method Name (of the Offset method)
DEFINE_ART_METHOD_OFFSET_SIZED(DEX_CACHE_METHODS, DexCacheResolvedMethods)
-DEFINE_ART_METHOD_OFFSET_SIZED(DEX_CACHE_TYPES, DexCacheResolvedTypes)
DEFINE_ART_METHOD_OFFSET_SIZED(JNI, EntryPointFromJni)
DEFINE_ART_METHOD_OFFSET_SIZED(QUICK_CODE, EntryPointFromQuickCompiledCode)
DEFINE_ART_METHOD_OFFSET(DECLARING_CLASS, DeclaringClass)