Improve CHECK_<op> logging.
This patch lets us show the lhs and rhs when a relational check fails. (I show
both, even though that looks silly in cases like CHECK_EQ(rc, 0) where we'll
say "rc=-1, 0=0", because it's helpful in cases like CHECK_LT(i, size()) where
we want "i=4, size=2".)
I had to add a few operator<<s for enums, and fix a bunch of signed/unsigned
mismatches, and put the StringPiece operator<< in the right namespace.
Change-Id: I390f38bd97b3f50e12182f36ff027ca067c48d69
diff --git a/src/assembler.cc b/src/assembler.cc
index d0a8aa4..689e0c8 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -61,7 +61,7 @@
// Verify internal state.
CHECK_EQ(Capacity(), kInitialBufferCapacity);
- CHECK_EQ(Size(), 0);
+ CHECK_EQ(Size(), 0U);
}
diff --git a/src/assembler_arm.cc b/src/assembler_arm.cc
index ce66fb2..3ce5199 100644
--- a/src/assembler_arm.cc
+++ b/src/assembler_arm.cc
@@ -61,6 +61,53 @@
};
+static const char* kRegisterNames[] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
+ "fp", "ip", "sp", "lr", "pc"
+};
+std::ostream& operator<<(std::ostream& os, const Register& rhs) {
+ if (rhs >= R0 && rhs <= PC) {
+ os << kRegisterNames[rhs];
+ } else {
+ os << "Register[" << int(rhs) << "]";
+ }
+ return os;
+}
+
+
+std::ostream& operator<<(std::ostream& os, const SRegister& rhs) {
+ if (rhs >= S0 && rhs < kNumberOfSRegisters) {
+ os << "s" << int(rhs);
+ } else {
+ os << "SRegister[" << int(rhs) << "]";
+ }
+ return os;
+}
+
+
+std::ostream& operator<<(std::ostream& os, const DRegister& rhs) {
+ if (rhs >= D0 && rhs < kNumberOfDRegisters) {
+ os << "d" << int(rhs);
+ } else {
+ os << "DRegister[" << int(rhs) << "]";
+ }
+ return os;
+}
+
+
+static const char* kConditionNames[] = {
+ "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", "LE", "AL",
+};
+std::ostream& operator<<(std::ostream& os, const Condition& rhs) {
+ if (rhs >= EQ && rhs <= AL) {
+ os << kConditionNames[rhs];
+ } else {
+ os << "Condition[" << int(rhs) << "]";
+ }
+ return os;
+}
+
+
void Assembler::Emit(int32_t value) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
buffer_.Emit<int32_t>(value);
@@ -151,7 +198,7 @@
Register rm,
ShifterOperand so) {
CHECK_NE(cond, kNoCondition);
- CHECK_EQ(so.type(), 1);
+ CHECK_EQ(so.type(), 1U);
int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
static_cast<int32_t>(MOV) << kOpcodeShift |
static_cast<int32_t>(rd) << kRdShift |
@@ -168,7 +215,7 @@
Register rm,
ShifterOperand so) {
CHECK_NE(cond, kNoCondition);
- CHECK_EQ(so.type(), 0);
+ CHECK_EQ(so.type(), 0U);
int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
static_cast<int32_t>(MOV) << kOpcodeShift |
static_cast<int32_t>(rd) << kRdShift |
diff --git a/src/assembler_x86.cc b/src/assembler_x86.cc
index ce7f104..0c44c08 100644
--- a/src/assembler_x86.cc
+++ b/src/assembler_x86.cc
@@ -20,6 +20,18 @@
}
};
+static const char* kRegisterNames[] = {
+ "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
+};
+std::ostream& operator<<(std::ostream& os, const Register& rhs) {
+ if (rhs >= EAX && rhs <= EDI) {
+ os << kRegisterNames[rhs];
+ } else {
+ os << "Register[" << int(rhs) << "]";
+ }
+ return os;
+}
+
void Assembler::InitializeMemoryWithBreakpoints(byte* data, size_t length) {
memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length);
diff --git a/src/class_linker.cc b/src/class_linker.cc
index e2ab39a..a205a06 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -1118,10 +1118,10 @@
const InstanceField* field = klass->GetInstanceField(i);
size_t byte_offset = field->GetOffset();
CHECK_GE(byte_offset, CLASS_SMALLEST_OFFSET);
- CHECK_EQ(byte_offset & (CLASS_OFFSET_ALIGNMENT - 1), 0);
+ CHECK_EQ(byte_offset & (CLASS_OFFSET_ALIGNMENT - 1), 0U);
if (CLASS_CAN_ENCODE_OFFSET(byte_offset)) {
uint32_t new_bit = CLASS_BIT_FROM_OFFSET(byte_offset);
- CHECK_NE(new_bit, 0);
+ CHECK_NE(new_bit, 0U);
reference_offsets |= new_bit;
} else {
reference_offsets = CLASS_WALK_SUPER;
diff --git a/src/constants_arm.h b/src/constants_arm.h
index 0849a09..bb693d3 100644
--- a/src/constants_arm.h
+++ b/src/constants_arm.h
@@ -3,6 +3,7 @@
#ifndef ART_SRC_CONSTANTS_ARM_H_
#define ART_SRC_CONSTANTS_ARM_H_
+#include <iosfwd>
#include <stdint.h>
#include "src/casts.h"
#include "src/logging.h"
@@ -54,6 +55,7 @@
kNumberOfCoreRegisters = 16,
kNoRegister = -1,
};
+std::ostream& operator<<(std::ostream& os, const Register& rhs);
enum ScaleFactor {
@@ -101,6 +103,7 @@
kNumberOfSRegisters = 32,
kNoSRegister = -1,
};
+std::ostream& operator<<(std::ostream& os, const SRegister& rhs);
// Values for double-precision floating point registers.
@@ -145,6 +148,7 @@
kNumberOfOverlappingDRegisters = 16,
kNoDRegister = -1,
};
+std::ostream& operator<<(std::ostream& os, const DRegister& rhs);
// Values for the condition field as defined in section A3.2.
@@ -168,6 +172,7 @@
kSpecialCondition = 15, // special condition (refer to section A3.2.1)
kMaxCondition = 16,
};
+std::ostream& operator<<(std::ostream& os, const Condition& rhs);
// Opcodes for Data-processing instructions (instructions with a type 0 and 1)
diff --git a/src/constants_x86.h b/src/constants_x86.h
index 70a79e9..d96e6dc 100644
--- a/src/constants_x86.h
+++ b/src/constants_x86.h
@@ -7,6 +7,8 @@
#include "src/logging.h"
#include "src/macros.h"
+#include <iosfwd>
+
namespace art {
enum Register {
@@ -22,6 +24,7 @@
kFirstByteUnsafeRegister = 4,
kNoRegister = -1 // Signals an illegal register.
};
+std::ostream& operator<<(std::ostream& os, const Register& rhs);
enum ByteRegister {
diff --git a/src/dex_verifier.cc b/src/dex_verifier.cc
index 7840827..53bc305 100644
--- a/src/dex_verifier.cc
+++ b/src/dex_verifier.cc
@@ -2,6 +2,10 @@
#include "src/dex_verifier.h"
+#include <iostream>
+
+#include "logging.h"
+#include "stringpiece.h"
namespace art {
@@ -12,14 +16,14 @@
for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
Method* method = klass->GetDirectMethod(i);
if (!VerifyMethod(method)) {
- LG << "Verifier rejected class " << klass->GetDescriptor();
+ LOG(ERROR) << "Verifier rejected class " << klass->GetDescriptor();
return false;
}
}
for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
Method* method = klass->GetVirtualMethod(i);
if (!VerifyMethod(method)) {
- LG << "Verifier rejected class " << klass->GetDescriptor();
+ LOG(ERROR) << "Verifier rejected class " << klass->GetDescriptor();
return false;
}
}
diff --git a/src/logging.h b/src/logging.h
index 98eb953..0a96504 100644
--- a/src/logging.h
+++ b/src/logging.h
@@ -25,14 +25,23 @@
if (!(x)) \
LogMessage(__FILE__, __LINE__, FATAL, -1).stream() << "Check failed: " #x
-#define CHECK_EQ(x, y) CHECK((x) == (y))
-#define CHECK_NE(x, y) CHECK((x) != (y))
-#define CHECK_LE(x, y) CHECK((x) <= (y))
-#define CHECK_LT(x, y) CHECK((x) < (y))
-#define CHECK_GE(x, y) CHECK((x) >= (y))
-#define CHECK_GT(x, y) CHECK((x) > (y))
-#define CHECK_STREQ(s1, s2) CHECK_STROP(s1, s2, true)
-#define CHECK_STRNE(s1, s2) CHECK_STROP(s1, s2, false)
+#define CHECK_OP(LHS, RHS, OP) \
+ do { \
+ typeof (LHS) _lhs = (LHS); \
+ typeof (RHS) _rhs = (RHS); \
+ if (!(_lhs OP _rhs)) { \
+ LogMessage(__FILE__, __LINE__, FATAL, -1).stream() \
+ << "Check failed: " << #LHS << " " << #OP << " " << #RHS \
+ << " (" #LHS "=" << _lhs << ", " #RHS "=" << _rhs << ")"; \
+ } \
+ } while (false)
+
+#define CHECK_EQ(x, y) CHECK_OP(x, y, ==)
+#define CHECK_NE(x, y) CHECK_OP(x, y, !=)
+#define CHECK_LE(x, y) CHECK_OP(x, y, <=)
+#define CHECK_LT(x, y) CHECK_OP(x, y, <)
+#define CHECK_GE(x, y) CHECK_OP(x, y, >=)
+#define CHECK_GT(x, y) CHECK_OP(x, y, >)
#define CHECK_STROP(s1, s2, sense) \
do { \
@@ -44,6 +53,9 @@
} \
} while (false)
+#define CHECK_STREQ(s1, s2) CHECK_STROP(s1, s2, true)
+#define CHECK_STRNE(s1, s2) CHECK_STROP(s1, s2, false)
+
#ifndef NDEBUG
#define DCHECK(x) CHECK(x)
diff --git a/src/memory_region.cc b/src/memory_region.cc
index a10516f..30d61ed 100644
--- a/src/memory_region.cc
+++ b/src/memory_region.cc
@@ -9,8 +9,8 @@
namespace art {
void MemoryRegion::CopyFrom(size_t offset, const MemoryRegion& from) const {
- CHECK_NE(from.pointer(), NULL);
- CHECK_GT(from.size(), 0);
+ CHECK(from.pointer() != NULL);
+ CHECK_GT(from.size(), 0U);
CHECK_GE(this->size(), from.size());
CHECK_LE(offset, this->size() - from.size());
memmove(reinterpret_cast<void*>(start() + offset),
diff --git a/src/object.cc b/src/object.cc
index d897c52..f5792fc 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -117,5 +117,24 @@
return NULL; // TODO
}
+static const char* kClassStatusNames[] = {
+ "Error",
+ "NotReady",
+ "Idx",
+ "Loaded",
+ "Resolved",
+ "Verifying",
+ "Verified",
+ "Initializing",
+ "Initialized"
+};
+std::ostream& operator<<(std::ostream& os, const Class::Status& rhs) {
+ if (rhs >= Class::kStatusError && rhs <= Class::kStatusInitialized) {
+ os << kClassStatusNames[rhs - 1];
+ } else {
+ os << "Class::Status[" << int(rhs) << "]";
+ }
+ return os;
+}
} // namespace art
diff --git a/src/object.h b/src/object.h
index 3bad627..ac42081 100644
--- a/src/object.h
+++ b/src/object.h
@@ -702,6 +702,7 @@
size_t num_sfields_;
StaticField* sfields_;
};
+std::ostream& operator<<(std::ostream& os, const Class::Status& rhs);
class DataObject : public Object {
public:
diff --git a/src/raw_dex_file.cc b/src/raw_dex_file.cc
index 2aaa5d9..caa159a 100644
--- a/src/raw_dex_file.cc
+++ b/src/raw_dex_file.cc
@@ -146,7 +146,7 @@
}
void RawDexFile::InitIndex() {
- CHECK_EQ(index_.size(), 0);
+ CHECK_EQ(index_.size(), 0U);
for (size_t i = 0; i < NumClassDefs(); ++i) {
const ClassDef& class_def = GetClassDef(i);
const char* descriptor = GetClassDescriptor(class_def);
diff --git a/src/stringpiece.cc b/src/stringpiece.cc
index 27e24d1..4b1ef7b 100644
--- a/src/stringpiece.cc
+++ b/src/stringpiece.cc
@@ -90,9 +90,9 @@
const StringPiece::size_type StringPiece::npos = size_type(-1);
-} // namespace art
-
std::ostream& operator<<(std::ostream& o, const art::StringPiece& piece) {
o.write(piece.data(), piece.size());
return o;
}
+
+} // namespace art
diff --git a/src/stringpiece.h b/src/stringpiece.h
index 3aefa57..6a5c60b 100644
--- a/src/stringpiece.h
+++ b/src/stringpiece.h
@@ -198,9 +198,8 @@
return !(x < y);
}
-} // namespace art
-
-// allow StringPiece to be logged
extern std::ostream& operator<<(std::ostream& o, const art::StringPiece& piece);
+} // namespace art
+
#endif // ART_SRC_STRINGPIECE_H_
diff --git a/src/thread.cc b/src/thread.cc
index a3899c7..60e977f 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -137,7 +137,7 @@
// Make sure that all threads have exited and unregistered when we
// reach this point. This means that all daemon threads had been
// shutdown cleanly.
- CHECK_EQ(list_.size(), 0);
+ CHECK_EQ(list_.size(), 0U);
delete lock_;
lock_ = NULL;
}