summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/image_writer.cc10
-rw-r--r--compiler/optimizing/code_generator_arm64.cc11
-rw-r--r--compiler/optimizing/code_generator_arm_vixl.cc20
-rw-r--r--compiler/optimizing/common_arm64.h4
-rw-r--r--compiler/optimizing/inliner.cc3
-rw-r--r--compiler/optimizing/intrinsics_arm_vixl.cc26
-rw-r--r--compiler/optimizing/stack_map_stream.cc8
-rw-r--r--compiler/optimizing/stack_map_test.cc27
8 files changed, 83 insertions, 26 deletions
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index 15e4cd8e9c..c72edb18a3 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -2348,6 +2348,16 @@ const uint8_t* ImageWriter::GetQuickCode(ArtMethod* method,
void ImageWriter::CopyAndFixupMethod(ArtMethod* orig,
ArtMethod* copy,
const ImageInfo& image_info) {
+ if (orig->IsAbstract()) {
+ // Ignore the single-implementation info for abstract method.
+ // Do this on orig instead of copy, otherwise there is a crash due to methods
+ // are copied before classes.
+ // TODO: handle fixup of single-implementation method for abstract method.
+ orig->SetHasSingleImplementation(false);
+ orig->SetSingleImplementation(
+ nullptr, Runtime::Current()->GetClassLinker()->GetImagePointerSize());
+ }
+
memcpy(copy, orig, ArtMethod::Size(target_ptr_size_));
copy->SetDeclaringClass(GetImageAddress(orig->GetDeclaringClassUnchecked()));
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index 1e89ba590c..cf824a14e3 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -1533,7 +1533,9 @@ void CodeGeneratorARM64::MoveLocation(Location destination,
HConstant* src_cst = source.GetConstant();
CPURegister temp;
if (src_cst->IsZeroBitPattern()) {
- temp = (src_cst->IsLongConstant() || src_cst->IsDoubleConstant()) ? xzr : wzr;
+ temp = (src_cst->IsLongConstant() || src_cst->IsDoubleConstant())
+ ? Register(xzr)
+ : Register(wzr);
} else {
if (src_cst->IsIntConstant()) {
temp = temps.AcquireW();
@@ -1903,6 +1905,9 @@ void LocationsBuilderARM64::HandleFieldGet(HInstruction* instruction) {
LocationSummary::kNoCall);
if (object_field_get_with_read_barrier && kUseBakerReadBarrier) {
locations->SetCustomSlowPathCallerSaves(RegisterSet::Empty()); // No caller-save registers.
+ // We need a temporary register for the read barrier marking slow
+ // path in CodeGeneratorARM64::GenerateFieldLoadWithBakerReadBarrier.
+ locations->AddTemp(Location::RequiresRegister());
}
locations->SetInAt(0, Location::RequiresRegister());
if (Primitive::IsFloatingPointType(instruction->GetType())) {
@@ -1930,11 +1935,9 @@ void InstructionCodeGeneratorARM64::HandleFieldGet(HInstruction* instruction,
if (field_type == Primitive::kPrimNot && kEmitCompilerReadBarrier && kUseBakerReadBarrier) {
// Object FieldGet with Baker's read barrier case.
- MacroAssembler* masm = GetVIXLAssembler();
- UseScratchRegisterScope temps(masm);
// /* HeapReference<Object> */ out = *(base + offset)
Register base = RegisterFrom(base_loc, Primitive::kPrimNot);
- Register temp = temps.AcquireW();
+ Register temp = WRegisterFrom(locations->GetTemp(0));
// Note that potential implicit null checks are handled in this
// CodeGeneratorARM64::GenerateFieldLoadWithBakerReadBarrier call.
codegen_->GenerateFieldLoadWithBakerReadBarrier(
diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc
index 893e465392..f4d3ec54ee 100644
--- a/compiler/optimizing/code_generator_arm_vixl.cc
+++ b/compiler/optimizing/code_generator_arm_vixl.cc
@@ -7679,15 +7679,21 @@ void InstructionCodeGeneratorARMVIXL::VisitPackedSwitch(HPackedSwitch* switch_in
vixl32::Register jump_offset = temps.Acquire();
// Load jump offset from the table.
- __ Adr(table_base, jump_table->GetTableStartLabel());
- __ Ldr(jump_offset, MemOperand(table_base, key_reg, vixl32::LSL, 2));
+ {
+ const size_t jump_size = switch_instr->GetNumEntries() * sizeof(int32_t);
+ ExactAssemblyScope aas(GetVIXLAssembler(),
+ (vixl32::kMaxInstructionSizeInBytes * 4) + jump_size,
+ CodeBufferCheckScope::kMaximumSize);
+ __ adr(table_base, jump_table->GetTableStartLabel());
+ __ ldr(jump_offset, MemOperand(table_base, key_reg, vixl32::LSL, 2));
- // Jump to target block by branching to table_base(pc related) + offset.
- vixl32::Register target_address = table_base;
- __ Add(target_address, table_base, jump_offset);
- __ Bx(target_address);
+ // Jump to target block by branching to table_base(pc related) + offset.
+ vixl32::Register target_address = table_base;
+ __ add(target_address, table_base, jump_offset);
+ __ bx(target_address);
- jump_table->EmitTable(codegen_);
+ jump_table->EmitTable(codegen_);
+ }
}
}
void LocationsBuilderARMVIXL::VisitArmDexCacheArraysBase(HArmDexCacheArraysBase* base) {
diff --git a/compiler/optimizing/common_arm64.h b/compiler/optimizing/common_arm64.h
index 776a483d43..93ea090583 100644
--- a/compiler/optimizing/common_arm64.h
+++ b/compiler/optimizing/common_arm64.h
@@ -130,8 +130,8 @@ inline vixl::aarch64::CPURegister InputCPURegisterOrZeroRegAt(HInstruction* inst
Primitive::Type input_type = input->GetType();
if (input->IsConstant() && input->AsConstant()->IsZeroBitPattern()) {
return (Primitive::ComponentSize(input_type) >= vixl::aarch64::kXRegSizeInBytes)
- ? vixl::aarch64::xzr
- : vixl::aarch64::wzr;
+ ? vixl::aarch64::Register(vixl::aarch64::xzr)
+ : vixl::aarch64::Register(vixl::aarch64::wzr);
}
return InputCPURegisterAt(instr, index);
}
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 5d40f75618..7772e8f973 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -304,7 +304,8 @@ ArtMethod* HInliner::TryCHADevirtualization(ArtMethod* resolved_method) {
// We do not support HDeoptimize in OSR methods.
return nullptr;
}
- return resolved_method->GetSingleImplementation();
+ PointerSize pointer_size = caller_compilation_unit_.GetClassLinker()->GetImagePointerSize();
+ return resolved_method->GetSingleImplementation(pointer_size);
}
bool HInliner::TryInline(HInvoke* invoke_instruction) {
diff --git a/compiler/optimizing/intrinsics_arm_vixl.cc b/compiler/optimizing/intrinsics_arm_vixl.cc
index 68c2d2e36e..91d9c56d10 100644
--- a/compiler/optimizing/intrinsics_arm_vixl.cc
+++ b/compiler/optimizing/intrinsics_arm_vixl.cc
@@ -2742,14 +2742,36 @@ void IntrinsicCodeGeneratorARMVIXL::VisitReferenceGetReferent(HInvoke* invoke) {
__ Bind(slow_path->GetExitLabel());
}
+void IntrinsicLocationsBuilderARMVIXL::VisitMathCeil(HInvoke* invoke) {
+ if (features_.HasARMv8AInstructions()) {
+ CreateFPToFPLocations(arena_, invoke);
+ }
+}
+
+void IntrinsicCodeGeneratorARMVIXL::VisitMathCeil(HInvoke* invoke) {
+ ArmVIXLAssembler* assembler = GetAssembler();
+ DCHECK(codegen_->GetInstructionSetFeatures().HasARMv8AInstructions());
+ __ Vrintp(F64, F64, OutputDRegister(invoke), InputDRegisterAt(invoke, 0));
+}
+
+void IntrinsicLocationsBuilderARMVIXL::VisitMathFloor(HInvoke* invoke) {
+ if (features_.HasARMv8AInstructions()) {
+ CreateFPToFPLocations(arena_, invoke);
+ }
+}
+
+void IntrinsicCodeGeneratorARMVIXL::VisitMathFloor(HInvoke* invoke) {
+ ArmVIXLAssembler* assembler = GetAssembler();
+ DCHECK(codegen_->GetInstructionSetFeatures().HasARMv8AInstructions());
+ __ Vrintm(F64, F64, OutputDRegister(invoke), InputDRegisterAt(invoke, 0));
+}
+
UNIMPLEMENTED_INTRINSIC(ARMVIXL, MathMinDoubleDouble)
UNIMPLEMENTED_INTRINSIC(ARMVIXL, MathMinFloatFloat)
UNIMPLEMENTED_INTRINSIC(ARMVIXL, MathMaxDoubleDouble)
UNIMPLEMENTED_INTRINSIC(ARMVIXL, MathMaxFloatFloat)
UNIMPLEMENTED_INTRINSIC(ARMVIXL, MathMinLongLong)
UNIMPLEMENTED_INTRINSIC(ARMVIXL, MathMaxLongLong)
-UNIMPLEMENTED_INTRINSIC(ARMVIXL, MathCeil) // Could be done by changing rounding mode, maybe?
-UNIMPLEMENTED_INTRINSIC(ARMVIXL, MathFloor) // Could be done by changing rounding mode, maybe?
UNIMPLEMENTED_INTRINSIC(ARMVIXL, MathRint)
UNIMPLEMENTED_INTRINSIC(ARMVIXL, MathRoundDouble) // Could be done by changing rounding mode, maybe?
UNIMPLEMENTED_INTRINSIC(ARMVIXL, MathRoundFloat) // Could be done by changing rounding mode, maybe?
diff --git a/compiler/optimizing/stack_map_stream.cc b/compiler/optimizing/stack_map_stream.cc
index a9a1e6f592..1b9bd7eb31 100644
--- a/compiler/optimizing/stack_map_stream.cc
+++ b/compiler/optimizing/stack_map_stream.cc
@@ -165,7 +165,7 @@ size_t StackMapStream::PrepareForFillIn() {
inline_info_size_,
register_mask_max_,
stack_mask_number_of_bits);
- stack_maps_size_ = stack_maps_.size() * stack_map_size;
+ stack_maps_size_ = RoundUp(stack_maps_.size() * stack_map_size, kBitsPerByte) / kBitsPerByte;
dex_register_location_catalog_size_ = ComputeDexRegisterLocationCatalogSize();
size_t non_header_size =
@@ -178,7 +178,7 @@ size_t StackMapStream::PrepareForFillIn() {
CodeInfoEncoding code_info_encoding;
code_info_encoding.non_header_size = non_header_size;
code_info_encoding.number_of_stack_maps = stack_maps_.size();
- code_info_encoding.stack_map_size_in_bytes = stack_map_size;
+ code_info_encoding.stack_map_size_in_bits = stack_map_size;
code_info_encoding.stack_map_encoding = stack_map_encoding_;
code_info_encoding.inline_info_encoding = inline_info_encoding_;
code_info_encoding.number_of_location_catalog_entries = location_catalog_entries_.size();
@@ -322,7 +322,7 @@ void StackMapStream::FillIn(MemoryRegion region) {
stack_map.SetDexPc(stack_map_encoding_, entry.dex_pc);
stack_map.SetNativePcCodeOffset(stack_map_encoding_, entry.native_pc_code_offset);
stack_map.SetRegisterMask(stack_map_encoding_, entry.register_mask);
- size_t number_of_stack_mask_bits = stack_map.GetNumberOfStackMaskBits(stack_map_encoding_);
+ size_t number_of_stack_mask_bits = code_info.GetNumberOfStackMaskBits(encoding);
if (entry.sp_mask != nullptr) {
for (size_t bit = 0; bit < number_of_stack_mask_bits; bit++) {
stack_map.SetStackMaskBit(stack_map_encoding_, bit, entry.sp_mask->IsBitSet(bit));
@@ -551,7 +551,7 @@ void StackMapStream::CheckCodeInfo(MemoryRegion region) const {
entry.native_pc_code_offset.Uint32Value(instruction_set_));
DCHECK_EQ(stack_map.GetDexPc(stack_map_encoding), entry.dex_pc);
DCHECK_EQ(stack_map.GetRegisterMask(stack_map_encoding), entry.register_mask);
- size_t num_stack_mask_bits = stack_map.GetNumberOfStackMaskBits(stack_map_encoding);
+ size_t num_stack_mask_bits = code_info.GetNumberOfStackMaskBits(encoding);
if (entry.sp_mask != nullptr) {
DCHECK_GE(num_stack_mask_bits, entry.sp_mask->GetNumberOfBits());
for (size_t b = 0; b < num_stack_mask_bits; b++) {
diff --git a/compiler/optimizing/stack_map_test.cc b/compiler/optimizing/stack_map_test.cc
index f68695bcbc..da4597e385 100644
--- a/compiler/optimizing/stack_map_test.cc
+++ b/compiler/optimizing/stack_map_test.cc
@@ -27,10 +27,10 @@ namespace art {
// Check that the stack mask of given stack map is identical
// to the given bit vector. Returns true if they are same.
static bool CheckStackMask(
+ int number_of_bits,
const StackMap& stack_map,
StackMapEncoding& encoding,
const BitVector& bit_vector) {
- int number_of_bits = stack_map.GetNumberOfStackMaskBits(encoding);
if (bit_vector.GetHighestBitSet() >= number_of_bits) {
return false;
}
@@ -81,7 +81,10 @@ TEST(StackMapTest, Test1) {
ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding.stack_map_encoding, kRuntimeISA));
ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding.stack_map_encoding));
- ASSERT_TRUE(CheckStackMask(stack_map, encoding.stack_map_encoding, sp_mask));
+ ASSERT_TRUE(CheckStackMask(code_info.GetNumberOfStackMaskBits(encoding),
+ stack_map,
+ encoding.stack_map_encoding,
+ sp_mask));
ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
DexRegisterMap dex_register_map =
@@ -196,7 +199,10 @@ TEST(StackMapTest, Test2) {
ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding.stack_map_encoding, kRuntimeISA));
ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding.stack_map_encoding));
- ASSERT_TRUE(CheckStackMask(stack_map, encoding.stack_map_encoding, sp_mask1));
+ ASSERT_TRUE(CheckStackMask(code_info.GetNumberOfStackMaskBits(encoding),
+ stack_map,
+ encoding.stack_map_encoding,
+ sp_mask1));
ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
DexRegisterMap dex_register_map =
@@ -255,7 +261,10 @@ TEST(StackMapTest, Test2) {
ASSERT_EQ(128u, stack_map.GetNativePcOffset(encoding.stack_map_encoding, kRuntimeISA));
ASSERT_EQ(0xFFu, stack_map.GetRegisterMask(encoding.stack_map_encoding));
- ASSERT_TRUE(CheckStackMask(stack_map, encoding.stack_map_encoding, sp_mask2));
+ ASSERT_TRUE(CheckStackMask(code_info.GetNumberOfStackMaskBits(encoding),
+ stack_map,
+ encoding.stack_map_encoding,
+ sp_mask2));
ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
DexRegisterMap dex_register_map =
@@ -309,7 +318,10 @@ TEST(StackMapTest, Test2) {
ASSERT_EQ(192u, stack_map.GetNativePcOffset(encoding.stack_map_encoding, kRuntimeISA));
ASSERT_EQ(0xABu, stack_map.GetRegisterMask(encoding.stack_map_encoding));
- ASSERT_TRUE(CheckStackMask(stack_map, encoding.stack_map_encoding, sp_mask3));
+ ASSERT_TRUE(CheckStackMask(code_info.GetNumberOfStackMaskBits(encoding),
+ stack_map,
+ encoding.stack_map_encoding,
+ sp_mask3));
ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
DexRegisterMap dex_register_map =
@@ -363,7 +375,10 @@ TEST(StackMapTest, Test2) {
ASSERT_EQ(256u, stack_map.GetNativePcOffset(encoding.stack_map_encoding, kRuntimeISA));
ASSERT_EQ(0xCDu, stack_map.GetRegisterMask(encoding.stack_map_encoding));
- ASSERT_TRUE(CheckStackMask(stack_map, encoding.stack_map_encoding, sp_mask4));
+ ASSERT_TRUE(CheckStackMask(code_info.GetNumberOfStackMaskBits(encoding),
+ stack_map,
+ encoding.stack_map_encoding,
+ sp_mask4));
ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
DexRegisterMap dex_register_map =