summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/arch/arm64/instruction_set_features_arm64.cc16
-rw-r--r--runtime/arch/arm64/instruction_set_features_arm64.h14
-rw-r--r--runtime/gc/accounting/mod_union_table_test.cc2
-rw-r--r--runtime/mirror/array-inl.h21
4 files changed, 32 insertions, 21 deletions
diff --git a/runtime/arch/arm64/instruction_set_features_arm64.cc b/runtime/arch/arm64/instruction_set_features_arm64.cc
index a1270dcde9..f8a9f9d6aa 100644
--- a/runtime/arch/arm64/instruction_set_features_arm64.cc
+++ b/runtime/arch/arm64/instruction_set_features_arm64.cc
@@ -48,19 +48,23 @@ const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromVariant(
return nullptr;
}
}
- return new Arm64InstructionSetFeatures(smp, needs_a53_835769_fix);
+
+ // The variants that need a fix for 843419 are the same that need a fix for 835769.
+ bool needs_a53_843419_fix = needs_a53_835769_fix;
+
+ return new Arm64InstructionSetFeatures(smp, needs_a53_835769_fix, needs_a53_843419_fix);
}
const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromBitmap(uint32_t bitmap) {
bool smp = (bitmap & kSmpBitfield) != 0;
bool is_a53 = (bitmap & kA53Bitfield) != 0;
- return new Arm64InstructionSetFeatures(smp, is_a53);
+ return new Arm64InstructionSetFeatures(smp, is_a53, is_a53);
}
const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromCppDefines() {
const bool smp = true;
const bool is_a53 = true; // Pessimistically assume all ARM64s are A53s.
- return new Arm64InstructionSetFeatures(smp, is_a53);
+ return new Arm64InstructionSetFeatures(smp, is_a53, is_a53);
}
const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromCpuInfo() {
@@ -85,13 +89,13 @@ const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromCpuInfo() {
} else {
LOG(ERROR) << "Failed to open /proc/cpuinfo";
}
- return new Arm64InstructionSetFeatures(smp, is_a53);
+ return new Arm64InstructionSetFeatures(smp, is_a53, is_a53);
}
const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromHwcap() {
bool smp = sysconf(_SC_NPROCESSORS_CONF) > 1;
const bool is_a53 = true; // Pessimistically assume all ARM64s are A53s.
- return new Arm64InstructionSetFeatures(smp, is_a53);
+ return new Arm64InstructionSetFeatures(smp, is_a53, is_a53);
}
const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromAssembly() {
@@ -140,7 +144,7 @@ const InstructionSetFeatures* Arm64InstructionSetFeatures::AddFeaturesFromSplitS
return nullptr;
}
}
- return new Arm64InstructionSetFeatures(smp, is_a53);
+ return new Arm64InstructionSetFeatures(smp, is_a53, is_a53);
}
} // namespace art
diff --git a/runtime/arch/arm64/instruction_set_features_arm64.h b/runtime/arch/arm64/instruction_set_features_arm64.h
index f6bfee7e63..3b3e2c95fe 100644
--- a/runtime/arch/arm64/instruction_set_features_arm64.h
+++ b/runtime/arch/arm64/instruction_set_features_arm64.h
@@ -61,6 +61,11 @@ class Arm64InstructionSetFeatures FINAL : public InstructionSetFeatures {
return fix_cortex_a53_835769_;
}
+ // Generate code addressing Cortex-A53 erratum 843419?
+ bool NeedFixCortexA53_843419() const {
+ return fix_cortex_a53_843419_;
+ }
+
// TODO: Tune this on a per CPU basis. For now, we pessimistically assume
// that all ARM64 CPUs prefer explicit memory barriers over acquire-release.
//
@@ -79,8 +84,12 @@ class Arm64InstructionSetFeatures FINAL : public InstructionSetFeatures {
std::string* error_msg) const OVERRIDE;
private:
- explicit Arm64InstructionSetFeatures(bool smp, bool needs_a53_835769_fix)
- : InstructionSetFeatures(smp), fix_cortex_a53_835769_(needs_a53_835769_fix) {
+ explicit Arm64InstructionSetFeatures(bool smp,
+ bool needs_a53_835769_fix,
+ bool needs_a53_843419_fix)
+ : InstructionSetFeatures(smp),
+ fix_cortex_a53_835769_(needs_a53_835769_fix),
+ fix_cortex_a53_843419_(needs_a53_843419_fix) {
}
// Bitmap positions for encoding features as a bitmap.
@@ -90,6 +99,7 @@ class Arm64InstructionSetFeatures FINAL : public InstructionSetFeatures {
};
const bool fix_cortex_a53_835769_;
+ const bool fix_cortex_a53_843419_;
DISALLOW_COPY_AND_ASSIGN(Arm64InstructionSetFeatures);
};
diff --git a/runtime/gc/accounting/mod_union_table_test.cc b/runtime/gc/accounting/mod_union_table_test.cc
index 77809358e4..94bb3f52cc 100644
--- a/runtime/gc/accounting/mod_union_table_test.cc
+++ b/runtime/gc/accounting/mod_union_table_test.cc
@@ -47,7 +47,7 @@ class ModUnionTableTest : public CommonRuntimeTest {
Thread* self, space::ContinuousMemMapAllocSpace* space, size_t component_count)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
auto* klass = GetObjectArrayClass(self, space);
- const size_t size = ComputeArraySize(self, klass, component_count, 2);
+ const size_t size = mirror::ComputeArraySize(component_count, 2);
size_t bytes_allocated = 0, bytes_tl_bulk_allocated;
auto* obj = down_cast<mirror::ObjectArray<mirror::Object>*>(
space->Alloc(self, size, &bytes_allocated, nullptr, &bytes_tl_bulk_allocated));
diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h
index 048d8ba08f..7f04992c5c 100644
--- a/runtime/mirror/array-inl.h
+++ b/runtime/mirror/array-inl.h
@@ -64,25 +64,20 @@ inline bool Array::CheckIsValidIndex(int32_t index) {
return true;
}
-static inline size_t ComputeArraySize(Thread* self, Class* array_class, int32_t component_count,
- size_t component_size_shift)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(array_class != NULL);
+static inline size_t ComputeArraySize(int32_t component_count, size_t component_size_shift) {
DCHECK_GE(component_count, 0);
- DCHECK(array_class->IsArrayClass());
size_t component_size = 1U << component_size_shift;
size_t header_size = Array::DataOffset(component_size).SizeValue();
size_t data_size = static_cast<size_t>(component_count) << component_size_shift;
size_t size = header_size + data_size;
- // Check for size_t overflow and throw OutOfMemoryError if this was
- // an unreasonable request.
+ // Check for size_t overflow if this was an unreasonable request
+ // but let the caller throw OutOfMemoryError.
#ifdef __LP64__
// 64-bit. No overflow as component_count is 32-bit and the maximum
// component size is 8.
DCHECK_LE((1U << component_size_shift), 8U);
- UNUSED(self);
#else
// 32-bit.
DCHECK_NE(header_size, 0U);
@@ -90,9 +85,6 @@ static inline size_t ComputeArraySize(Thread* self, Class* array_class, int32_t
// The array length limit (exclusive).
const size_t length_limit = (0U - header_size) >> component_size_shift;
if (UNLIKELY(length_limit <= static_cast<size_t>(component_count))) {
- self->ThrowOutOfMemoryError(StringPrintf("%s of length %d would overflow",
- PrettyDescriptor(array_class).c_str(),
- component_count).c_str());
return 0; // failure
}
#endif
@@ -159,15 +151,20 @@ template <bool kIsInstrumented, bool kFillUsable>
inline Array* Array::Alloc(Thread* self, Class* array_class, int32_t component_count,
size_t component_size_shift, gc::AllocatorType allocator_type) {
DCHECK(allocator_type != gc::kAllocatorTypeLOS);
+ DCHECK(array_class != nullptr);
+ DCHECK(array_class->IsArrayClass());
DCHECK_EQ(array_class->GetComponentSizeShift(), component_size_shift);
DCHECK_EQ(array_class->GetComponentSize(), (1U << component_size_shift));
- size_t size = ComputeArraySize(self, array_class, component_count, component_size_shift);
+ size_t size = ComputeArraySize(component_count, component_size_shift);
#ifdef __LP64__
// 64-bit. No size_t overflow.
DCHECK_NE(size, 0U);
#else
// 32-bit.
if (UNLIKELY(size == 0)) {
+ self->ThrowOutOfMemoryError(StringPrintf("%s of length %d would overflow",
+ PrettyDescriptor(array_class).c_str(),
+ component_count).c_str());
return nullptr;
}
#endif