Always log the value when an alignment check fails.
And move checking that the alignment is a power of two to compile-time.
Change-Id: I551f364af05912958ed2d4d095b1ce35b6abaf6e
diff --git a/src/assembler_arm.cc b/src/assembler_arm.cc
index e1976d7..ac39f2e 100644
--- a/src/assembler_arm.cc
+++ b/src/assembler_arm.cc
@@ -1091,7 +1091,7 @@
int32_t ArmAssembler::EncodeBranchOffset(int offset, int32_t inst) {
// The offset is off by 8 due to the way the ARM CPUs read PC.
offset -= 8;
- CHECK(IsAligned(offset, 4));
+ CHECK_ALIGNED(offset, 4);
CHECK(IsInt(CountOneBits(kBranchOffsetMask), offset));
// Properly preserve only the bits supported in the instruction.
@@ -1423,7 +1423,7 @@
void ArmAssembler::BuildFrame(size_t frame_size, ManagedRegister method_reg,
const std::vector<ManagedRegister>& callee_save_regs) {
- CHECK(IsAligned(frame_size, kStackAlignment));
+ CHECK_ALIGNED(frame_size, kStackAlignment);
CHECK_EQ(R0, method_reg.AsArm().AsCoreRegister());
// Push callee saves and link register
@@ -1447,7 +1447,7 @@
void ArmAssembler::RemoveFrame(size_t frame_size,
const std::vector<ManagedRegister>& callee_save_regs) {
- CHECK(IsAligned(frame_size, kStackAlignment));
+ CHECK_ALIGNED(frame_size, kStackAlignment);
// Compute callee saves to pop and PC
RegList pop_list = 1 << PC;
size_t pop_values = 1;
diff --git a/src/assembler_arm.h b/src/assembler_arm.h
index e1d43e4..bd5ed0b 100644
--- a/src/assembler_arm.h
+++ b/src/assembler_arm.h
@@ -179,7 +179,7 @@
const uint32_t offset_mask = (1 << 12) - 1;
uint32_t offset = encoding_ & offset_mask;
CHECK(IsAbsoluteUint(10, offset)); // In the range -1020 to +1020.
- CHECK(IsAligned(offset, 2)); // Multiple of 4.
+ CHECK_ALIGNED(offset, 2); // Multiple of 4.
int mode = encoding_ & ((8|4|1) << 21);
CHECK((mode == Offset) || (mode == NegOffset));
uint32_t vencoding = (encoding_ & (0xf << kRnShift)) | (offset >> 2);
diff --git a/src/assembler_x86.cc b/src/assembler_x86.cc
index c7b2bb5..f3b3c11 100644
--- a/src/assembler_x86.cc
+++ b/src/assembler_x86.cc
@@ -1379,7 +1379,7 @@
void X86Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg,
const std::vector<ManagedRegister>& spill_regs) {
- CHECK(IsAligned(frame_size, kStackAlignment));
+ CHECK_ALIGNED(frame_size, kStackAlignment);
CHECK_EQ(0u, spill_regs.size()); // no spilled regs on x86
// return address then method on stack
addl(ESP, Immediate(-frame_size + kPointerSize /*method*/ +
@@ -1389,19 +1389,19 @@
void X86Assembler::RemoveFrame(size_t frame_size,
const std::vector<ManagedRegister>& spill_regs) {
- CHECK(IsAligned(frame_size, kStackAlignment));
+ CHECK_ALIGNED(frame_size, kStackAlignment);
CHECK_EQ(0u, spill_regs.size()); // no spilled regs on x86
addl(ESP, Immediate(frame_size - kPointerSize));
ret();
}
void X86Assembler::IncreaseFrameSize(size_t adjust) {
- CHECK(IsAligned(adjust, kStackAlignment));
+ CHECK_ALIGNED(adjust, kStackAlignment);
addl(ESP, Immediate(-adjust));
}
void X86Assembler::DecreaseFrameSize(size_t adjust) {
- CHECK(IsAligned(adjust, kStackAlignment));
+ CHECK_ALIGNED(adjust, kStackAlignment);
addl(ESP, Immediate(adjust));
}
diff --git a/src/class_linker.cc b/src/class_linker.cc
index bd23b2d..eda60ca 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -2387,7 +2387,7 @@
// Now we want to pack all of the double-wide fields together. If
// we're not aligned, though, we want to shuffle one 32-bit field
// into place. If we can't find one, we'll have to pad it.
- if (current_field != num_fields && !IsAligned(field_offset.Uint32Value(), 8)) {
+ if (current_field != num_fields && !IsAligned<8>(field_offset.Uint32Value())) {
for (size_t i = 0; i < grouped_and_sorted_fields.size(); i++) {
Field* field = grouped_and_sorted_fields[i];
const Class* type = field->GetTypeDuringLinking();
@@ -2408,7 +2408,7 @@
// Alignment is good, shuffle any double-wide fields forward, and
// finish assigning field offsets to all fields.
- DCHECK(current_field == num_fields || IsAligned(field_offset.Uint32Value(), 8));
+ DCHECK(current_field == num_fields || IsAligned<8>(field_offset.Uint32Value()));
while (!grouped_and_sorted_fields.empty()) {
Field* field = grouped_and_sorted_fields.front();
grouped_and_sorted_fields.pop_front();
diff --git a/src/heap.cc b/src/heap.cc
index 9bed951..d7c9584 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -171,7 +171,7 @@
bool Heap::IsHeapAddress(const Object* obj) {
// Note: we deliberately don't take the lock here, and mustn't test anything that would
// require taking the lock.
- if (!IsAligned(obj, kObjectAlignment)) {
+ if (!IsAligned<kObjectAlignment>(obj)) {
return false;
}
// TODO
@@ -191,7 +191,7 @@
void Heap::VerifyObjectLocked(const Object* obj) {
lock_->AssertHeld();
if (obj != NULL) {
- if (!IsAligned(obj, kObjectAlignment)) {
+ if (!IsAligned<kObjectAlignment>(obj)) {
LOG(FATAL) << "Object isn't aligned: " << obj;
} else if (!live_bitmap_->Test(obj)) {
// TODO: we don't hold a lock here as it is assumed the live bit map
@@ -205,7 +205,7 @@
const Class* c = *reinterpret_cast<Class* const *>(raw_addr);
if (c == NULL) {
LOG(FATAL) << "Null class" << " in object: " << obj;
- } else if (!IsAligned(c, kObjectAlignment)) {
+ } else if (!IsAligned<kObjectAlignment>(c)) {
LOG(FATAL) << "Class isn't aligned: " << c << " in object: " << obj;
} else if (!live_bitmap_->Test(c)) {
LOG(FATAL) << "Class of object is dead: " << c << " in object: " << obj;
@@ -291,7 +291,7 @@
CHECK(live_bitmap_ != NULL);
byte* current = space->GetBase() + RoundUp(sizeof(ImageHeader), kObjectAlignment);
while (current < space->GetLimit()) {
- DCHECK(IsAligned(current, kObjectAlignment));
+ DCHECK_ALIGNED(current, kObjectAlignment);
const Object* obj = reinterpret_cast<const Object*>(current);
live_bitmap_->Set(obj);
current += RoundUp(obj->SizeOf(), kObjectAlignment);
diff --git a/src/indirect_reference_table.cc b/src/indirect_reference_table.cc
index 4283b83..716c214 100644
--- a/src/indirect_reference_table.cc
+++ b/src/indirect_reference_table.cc
@@ -86,7 +86,7 @@
DCHECK(obj != NULL);
// TODO: stronger sanity check on the object (such as in heap)
- DCHECK(IsAligned(reinterpret_cast<intptr_t>(obj), 8)) << reinterpret_cast<const void*>(obj);
+ DCHECK_ALIGNED(reinterpret_cast<intptr_t>(obj), 8);
DCHECK(table_ != NULL);
DCHECK_LE(alloc_entries_, max_entries_);
DCHECK_GE(segment_state_.parts.numHoles, prevState.parts.numHoles);
diff --git a/src/oat.cc b/src/oat.cc
index 8bf8299..14040f3 100644
--- a/src/oat.cc
+++ b/src/oat.cc
@@ -51,13 +51,13 @@
uint32_t OatHeader::GetExecutableOffset() const {
DCHECK(IsValid());
- DCHECK(IsAligned(executable_offset_, kPageSize));
+ DCHECK_ALIGNED(executable_offset_, kPageSize);
CHECK_GT(executable_offset_, sizeof(OatHeader));
return executable_offset_;
}
void OatHeader::SetExecutableOffset(uint32_t executable_offset) {
- DCHECK(IsAligned(executable_offset, kPageSize));
+ DCHECK_ALIGNED(executable_offset, kPageSize);
CHECK_GT(executable_offset, sizeof(OatHeader));
DCHECK(IsValid());
DCHECK_EQ(executable_offset_, 0U);
diff --git a/src/oat_writer.cc b/src/oat_writer.cc
index 99c9361..931dbc1 100644
--- a/src/oat_writer.cc
+++ b/src/oat_writer.cc
@@ -180,7 +180,7 @@
if (compiled_method != NULL) {
offset = compiled_method->AlignCode(offset);
- DCHECK(IsAligned(offset, kArmAlignment)) << std::hex << offset;
+ DCHECK_ALIGNED(offset, kArmAlignment);
const std::vector<uint8_t>& code = compiled_method->GetCode();
size_t code_size = code.size() * sizeof(code[0]);
uint32_t thumb_offset = compiled_method->CodeDelta();
@@ -224,7 +224,7 @@
const CompiledInvokeStub* compiled_invoke_stub = compiler_->GetCompiledInvokeStub(method);
if (compiled_invoke_stub != NULL) {
offset = CompiledMethod::AlignCode(offset, compiler_->GetInstructionSet());
- DCHECK(IsAligned(offset, kArmAlignment)) << std::hex << offset;
+ DCHECK_ALIGNED(offset, kArmAlignment);
const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
size_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]);
invoke_stub_offset = (invoke_stub_size == 0) ? 0 : offset;
@@ -403,7 +403,7 @@
code_offset += aligned_code_delta;
DCHECK_CODE_OFFSET();
}
- DCHECK(IsAligned(code_offset, kArmAlignment)) << std::hex << code_offset;
+ DCHECK_ALIGNED(code_offset, kArmAlignment);
const std::vector<uint8_t>& code = compiled_method->GetCode();
size_t code_size = code.size() * sizeof(code[0]);
DCHECK((code_size == 0 && method->GetOatCodeOffset() == 0)
@@ -480,7 +480,7 @@
code_offset += aligned_code_delta;
DCHECK_CODE_OFFSET();
}
- DCHECK(IsAligned(code_offset, kArmAlignment)) << std::hex << code_offset;
+ DCHECK_ALIGNED(code_offset, kArmAlignment);
const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
size_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]);
DCHECK((invoke_stub_size == 0 && method->GetOatInvokeStubOffset() == 0)
diff --git a/src/object.h b/src/object.h
index 8f6f75d..a93733c 100644
--- a/src/object.h
+++ b/src/object.h
@@ -2173,43 +2173,36 @@
DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
Class* type = GetTypeDuringLinking();
if (type != NULL && (type->IsPrimitiveDouble() || type->IsPrimitiveLong())) {
- DCHECK(IsAligned(num_bytes.Uint32Value(), 8));
+ DCHECK_ALIGNED(num_bytes.Uint32Value(), 8);
}
- SetField32(OFFSET_OF_OBJECT_MEMBER(Field, offset_),
- num_bytes.Uint32Value(), false);
+ SetField32(OFFSET_OF_OBJECT_MEMBER(Field, offset_), num_bytes.Uint32Value(), false);
}
inline Class* Field::GetDeclaringClass() const {
- Class* result = GetFieldObject<Class*>(
- OFFSET_OF_OBJECT_MEMBER(Field, declaring_class_), false);
+ Class* result = GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Field, declaring_class_), false);
DCHECK(result != NULL);
DCHECK(result->IsLoaded() || result->IsErroneous());
return result;
}
inline void Field::SetDeclaringClass(Class *new_declaring_class) {
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Field, declaring_class_),
- new_declaring_class, false);
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Field, declaring_class_), new_declaring_class, false);
}
inline Class* Method::GetDeclaringClass() const {
- Class* result =
- GetFieldObject<Class*>(
- OFFSET_OF_OBJECT_MEMBER(Method, declaring_class_), false);
+ Class* result = GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Method, declaring_class_), false);
DCHECK(result != NULL);
DCHECK(result->IsIdxLoaded() || result->IsErroneous());
return result;
}
inline void Method::SetDeclaringClass(Class *new_declaring_class) {
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Method, declaring_class_),
- new_declaring_class, false);
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Method, declaring_class_), new_declaring_class, false);
}
inline uint32_t Method::GetReturnTypeIdx() const {
DCHECK(GetDeclaringClass()->IsResolved() || GetDeclaringClass()->IsErroneous());
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Method, java_return_type_idx_),
- false);
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Method, java_return_type_idx_), false);
}
inline bool Method::IsReturnAReference() const {
diff --git a/src/utils.h b/src/utils.h
index 35b350b..dd597e9 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -25,17 +25,23 @@
return (x & (x - 1)) == 0;
}
-template<typename T>
-static inline bool IsAligned(T x, int n) {
- CHECK(IsPowerOfTwo(n));
+template<int n, typename T>
+static inline bool IsAligned(T x) {
+ COMPILE_ASSERT((n & (n - 1)) == 0, n_not_power_of_two);
return (x & (n - 1)) == 0;
}
-template<typename T>
-static inline bool IsAligned(T* x, int n) {
- return IsAligned(reinterpret_cast<uintptr_t>(x), n);
+template<int n, typename T>
+static inline bool IsAligned(T* x) {
+ return IsAligned<n>(reinterpret_cast<uintptr_t>(x));
}
+#define CHECK_ALIGNED(value, alignment) \
+ CHECK(::art::IsAligned<alignment>(value)) << reinterpret_cast<void*>(value)
+
+#define DCHECK_ALIGNED(value, alignment) \
+ DCHECK(::art::IsAligned<alignment>(value)) << reinterpret_cast<void*>(value)
+
// Check whether an N-bit two's-complement representation can hold value.
static inline bool IsInt(int N, word value) {
CHECK_LT(0, N);