summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/Dataflow.cc10
-rw-r--r--src/compiler/codegen/MethodCodegenDriver.cc6
-rw-r--r--src/compiler/codegen/arm/Thumb2/Gen.cc7
-rw-r--r--src/compiler_llvm/compilation_unit.cc1
-rw-r--r--src/disassembler_arm.cc263
-rw-r--r--src/exception_test.cc5
-rw-r--r--src/logging.cc5
-rw-r--r--src/oat/runtime/context.cc3
-rw-r--r--src/object_utils.h14
-rw-r--r--src/thread.cc4
10 files changed, 188 insertions, 130 deletions
diff --git a/src/compiler/Dataflow.cc b/src/compiler/Dataflow.cc
index 5f632c061d..bea5ef07d9 100644
--- a/src/compiler/Dataflow.cc
+++ b/src/compiler/Dataflow.cc
@@ -1869,19 +1869,19 @@ bool basicBlockOpt(CompilationUnit* cUnit, BasicBlock* bb)
ccode = kCondEq;
break;
case Instruction::IF_NEZ:
- // ccode = kCondNe;
+ ccode = kCondNe;
break;
case Instruction::IF_LTZ:
- // ccode = kCondLt;
+ ccode = kCondLt;
break;
case Instruction::IF_GEZ:
- // ccode = kCondGe;
+ ccode = kCondGe;
break;
case Instruction::IF_GTZ:
- // ccode = kCondGt;
+ ccode = kCondGt;
break;
case Instruction::IF_LEZ:
- // ccode = kCondLe;
+ ccode = kCondLe;
break;
default:
break;
diff --git a/src/compiler/codegen/MethodCodegenDriver.cc b/src/compiler/codegen/MethodCodegenDriver.cc
index 1dc11dac70..fb9bdc9227 100644
--- a/src/compiler/codegen/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/MethodCodegenDriver.cc
@@ -737,9 +737,6 @@ bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
const char* extendedMIROpNames[kMirOpLast - kMirOpFirst] = {
"kMirOpPhi",
- "kMirOpNullNRangeUpCheck",
- "kMirOpNullNRangeDownCheck",
- "kMirOpLowerBound",
"kMirOpCopy",
"kMirFusedCmplFloat",
"kMirFusedCmpgFloat",
@@ -747,6 +744,9 @@ const char* extendedMIROpNames[kMirOpLast - kMirOpFirst] = {
"kMirFusedCmpgDouble",
"kMirFusedCmpLong",
"kMirNop",
+ "kMirOpNullNRangeUpCheck",
+ "kMirOpNullNRangeDownCheck",
+ "kMirOpLowerBound",
};
/* Extended MIR instructions like PHI */
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index ea02ca99ac..f48540329e 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -658,12 +658,12 @@ void genFusedLongCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
{
LIR* labelList = (LIR*)cUnit->blockLabelList;
LIR* taken = &labelList[bb->taken->id];
+ LIR* notTaken = &labelList[bb->fallThrough->id];
RegLocation rlSrc1 = oatGetSrcWide(cUnit, mir, 0, 1);
RegLocation rlSrc2 = oatGetSrcWide(cUnit, mir, 2, 3);
rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
ConditionCode ccode = static_cast<ConditionCode>(mir->dalvikInsn.arg[0]);
- LIR* notTaken = rawLIR(cUnit, mir->offset, kPseudoTargetLabel);
opRegReg(cUnit, kOpCmp, rlSrc1.highReg, rlSrc2.highReg);
switch(ccode) {
case kCondEq:
@@ -675,25 +675,28 @@ void genFusedLongCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
case kCondLt:
opCondBranch(cUnit, kCondLt, taken);
opCondBranch(cUnit, kCondGt, notTaken);
+ ccode = kCondCc;
break;
case kCondLe:
opCondBranch(cUnit, kCondLt, taken);
opCondBranch(cUnit, kCondGt, notTaken);
+ ccode = kCondLs;
break;
case kCondGt:
opCondBranch(cUnit, kCondGt, taken);
opCondBranch(cUnit, kCondLt, notTaken);
+ ccode = kCondHi;
break;
case kCondGe:
opCondBranch(cUnit, kCondGt, taken);
opCondBranch(cUnit, kCondLt, notTaken);
+ ccode = kCondCs;
break;
default:
LOG(FATAL) << "Unexpected ccode: " << (int)ccode;
}
opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
opCondBranch(cUnit, ccode, taken);
- oatAppendLIR(cUnit, notTaken);
}
/*
diff --git a/src/compiler_llvm/compilation_unit.cc b/src/compiler_llvm/compilation_unit.cc
index 3b4defd99f..ae87395000 100644
--- a/src/compiler_llvm/compilation_unit.cc
+++ b/src/compiler_llvm/compilation_unit.cc
@@ -139,6 +139,7 @@ bool CompilationUnit::Materialize() {
target_options.NoFramePointerElim = true;
target_options.NoFramePointerElimNonLeaf = true;
target_options.UseSoftFloat = false;
+ target_options.EnableFastISel = true;
// Create the llvm::TargetMachine
llvm::TargetMachine* target_machine =
diff --git a/src/disassembler_arm.cc b/src/disassembler_arm.cc
index 8716a71bff..aa7a39b957 100644
--- a/src/disassembler_arm.cc
+++ b/src/disassembler_arm.cc
@@ -256,130 +256,166 @@ size_t DisassemblerArm::DumpThumb32(std::ostream& os, const uint8_t* instr_ptr)
case 0:
break;
case 1:
- switch (op2) {
- case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0A: case 0x0B:
- case 0x10: case 0x11: case 0x12: case 0x13: case 0x18: case 0x19: case 0x1A: case 0x1B: {
- // |111|11|10|00|0|00|0000|1111110000000000|
- // |5 3|21|09|87|6|54|3 0|5 0 5 0|
- // |---|--|--|--|-|--|----|----------------|
- // |332|22|22|22|2|22|1111|1111110000000000|
- // |1 9|87|65|43|2|10|9 6|5 0 5 0|
- // |---|--|--|--|-|--|----|----------------|
- // |111|01|00|op|0|WL| Rn | |
- // |111|01| op2 | | |
- // STM - 111 01 00-01-0-W0 nnnn rrrrrrrrrrrrrrrr
- // LDM - 111 01 00-01-0-W1 nnnn rrrrrrrrrrrrrrrr
- // PUSH- 111 01 00-01-0-10 1101 0M0rrrrrrrrrrrrr
- // POP - 111 01 00-01-0-11 1101 PM0rrrrrrrrrrrrr
- uint32_t op = (instr >> 23) & 3;
- uint32_t W = (instr >> 21) & 1;
- uint32_t L = (instr >> 20) & 1;
- ArmRegister Rn(instr, 16);
- if (op == 1 || op == 2) {
- if (op == 1) {
- if (L == 0) {
- opcode << "stm";
+ if ((op2 & 0x64) == 0) { // 00x x0xx
+ // |111|11|10|00|0|00|0000|1111110000000000|
+ // |5 3|21|09|87|6|54|3 0|5 0 5 0|
+ // |---|--|--|--|-|--|----|----------------|
+ // |332|22|22|22|2|22|1111|1111110000000000|
+ // |1 9|87|65|43|2|10|9 6|5 0 5 0|
+ // |---|--|--|--|-|--|----|----------------|
+ // |111|01|00|op|0|WL| Rn | |
+ // |111|01| op2 | | |
+ // STM - 111 01 00-01-0-W0 nnnn rrrrrrrrrrrrrrrr
+ // LDM - 111 01 00-01-0-W1 nnnn rrrrrrrrrrrrrrrr
+ // PUSH- 111 01 00-01-0-10 1101 0M0rrrrrrrrrrrrr
+ // POP - 111 01 00-01-0-11 1101 PM0rrrrrrrrrrrrr
+ uint32_t op = (instr >> 23) & 3;
+ uint32_t W = (instr >> 21) & 1;
+ uint32_t L = (instr >> 20) & 1;
+ ArmRegister Rn(instr, 16);
+ if (op == 1 || op == 2) {
+ if (op == 1) {
+ if (L == 0) {
+ opcode << "stm";
+ args << Rn << (W == 0 ? "" : "!") << ", ";
+ } else {
+ if (Rn.r != 13) {
+ opcode << "ldm";
args << Rn << (W == 0 ? "" : "!") << ", ";
} else {
- if (Rn.r != 13) {
- opcode << "ldm";
- args << Rn << (W == 0 ? "" : "!") << ", ";
- } else {
- opcode << "pop";
- }
+ opcode << "pop";
}
- } else {
- if (L == 0) {
- if (Rn.r != 13) {
- opcode << "stmdb";
- args << Rn << (W == 0 ? "" : "!") << ", ";
- } else {
- opcode << "push";
- }
- } else {
- opcode << "ldmdb";
+ }
+ } else {
+ if (L == 0) {
+ if (Rn.r != 13) {
+ opcode << "stmdb";
args << Rn << (W == 0 ? "" : "!") << ", ";
+ } else {
+ opcode << "push";
}
+ } else {
+ opcode << "ldmdb";
+ args << Rn << (W == 0 ? "" : "!") << ", ";
}
- args << RegisterList(instr);
}
- break;
+ args << RegisterList(instr);
+ }
+ } else if ((op2 & 0x60) == 0x20) { // 01x xxxx
+ // Data-processing (shifted register)
+ // |111|1110|0000|0|0000|1111|1100|0000|0000|
+ // |5 3|2109|8765|4|3 0|5 |10 8|7 5 |3 0|
+ // |---|----|----|-|----|----|----|----|----|
+ // |332|2222|2222|2|1111|1111|1100|0000|0000|
+ // |1 9|8765|4321|0|9 6|5 |10 8|7 5 |3 0|
+ // |---|----|----|-|----|----|----|----|----|
+ // |111|0101| op3|S| Rn | | Rd | | Rm |
+ uint32_t op3 = (instr >> 21) & 0xF;
+ uint32_t S = (instr >> 20) & 1;
+ uint32_t Rn = (instr >> 16) & 0xF;
+ ArmRegister Rd(instr, 8);
+ ArmRegister Rm(instr, 0);
+ switch (op3) {
+ case 0x0:
+ if (Rn != 0xF) {
+ opcode << "and";
+ } else {
+ opcode << "tst";
+ S = 0; // don't print 's'
+ }
+ break;
+ case 0x1: opcode << "bic"; break;
+ case 0x2:
+ if (Rn != 0xF) {
+ opcode << "orr";
+ } else {
+ opcode << "mov";
+ }
+ break;
+ case 0x3:
+ if (Rn != 0xF) {
+ opcode << "orn";
+ } else {
+ opcode << "mvn";
+ }
+ break;
+ case 0x4:
+ if (Rn != 0xF) {
+ opcode << "eor";
+ } else {
+ opcode << "teq";
+ S = 0; // don't print 's'
+ }
+ break;
+ case 0x6: opcode << "pkh"; break;
+ case 0x8:
+ if (Rn != 0xF) {
+ opcode << "add";
+ } else {
+ opcode << "cmn";
+ S = 0; // don't print 's'
+ }
+ break;
+ case 0xA: opcode << "adc"; break;
+ case 0xB: opcode << "sbc"; break;
}
- case 0x20: case 0x21: case 0x22: case 0x23: // 01xxxxx
- case 0x24: case 0x25: case 0x26: case 0x27:
- case 0x28: case 0x29: case 0x2A: case 0x2B:
- case 0x2C: case 0x2D: case 0x2E: case 0x2F:
- case 0x30: case 0x31: case 0x32: case 0x33:
- case 0x34: case 0x35: case 0x36: case 0x37:
- case 0x38: case 0x39: case 0x3A: case 0x3B:
- case 0x3C: case 0x3D: case 0x3E: case 0x3F: {
- // Data-processing (shifted register)
- // |111|1110|0000|0|0000|1111|1100|0000|0000|
- // |5 3|2109|8765|4|3 0|5 |10 8|7 5 |3 0|
- // |---|----|----|-|----|----|----|----|----|
- // |332|2222|2222|2|1111|1111|1100|0000|0000|
- // |1 9|8765|4321|0|9 6|5 |10 8|7 5 |3 0|
- // |---|----|----|-|----|----|----|----|----|
- // |111|0101| op3|S| Rn | | Rd | | Rm |
- uint32_t op3 = (instr >> 21) & 0xF;
- uint32_t S = (instr >> 20) & 1;
- uint32_t Rn = (instr >> 16) & 0xF;
- ArmRegister Rd(instr, 8);
- ArmRegister Rm(instr, 0);
- switch (op3) {
- case 0x0:
- if (Rn != 0xF) {
- opcode << "and";
- } else {
- opcode << "tst";
- S = 0; // don't print 's'
- }
- break;
- case 0x1: opcode << "bic"; break;
- case 0x2:
- if (Rn != 0xF) {
- opcode << "orr";
- } else {
- opcode << "mov";
- }
- break;
- case 0x3:
- if (Rn != 0xF) {
- opcode << "orn";
- } else {
- opcode << "mvn";
- }
- break;
- case 0x4:
- if (Rn != 0xF) {
- opcode << "eor";
- } else {
- opcode << "teq";
- S = 0; // don't print 's'
- }
- break;
- case 0x6: opcode << "pkh"; break;
- case 0x8:
- if (Rn != 0xF) {
- opcode << "add";
- } else {
- opcode << "cmn";
- S = 0; // don't print 's'
- }
- break;
- case 0xA: opcode << "adc"; break;
- case 0xB: opcode << "sbc"; break;
- }
- if (S == 1) {
- opcode << "s";
+ if (S == 1) {
+ opcode << "s";
+ }
+ opcode << ".w";
+ args << Rd << ", " << Rm;
+ } else if ((op2 & 0x40) == 0x40) { // 1xx xxxx
+ // Co-processor instructions
+ // |111|1|11|000000|0000|1111|1100|000|0 |0000|
+ // |5 3|2|10|987654|3 0|54 2|10 8|7 5|4 | 0|
+ // |---|-|--|------|----|----|----|---|---|----|
+ // |332|2|22|222222|1111|1111|1100|000|0 |0000|
+ // |1 9|8|76|543210|9 6|54 2|10 8|7 5|4 | 0|
+ // |---|-|--|------|----|----|----|---|---|----|
+ // |111| |11| op3 | Rn | |copr| |op4| |
+ uint32_t op3 = (instr >> 20) & 0x3F;
+ uint32_t coproc = (instr >> 8) & 0xF;
+ uint32_t op4 = (instr >> 4) & 0x1;
+ if ((op3 & 0x30) == 0x20 && op4 == 0) { // 10 xxxx ... 0
+ if ((coproc & 0xE) == 0xA) {
+ // VFP data-processing instructions
+ // |111|1|1100|0000|0000|1111|110|0|00 |0|0|0000|
+ // |5 3|2|1098|7654|3 0|54 2|10 |8|76 |5|4|3 0|
+ // |---|-|----|----|----|----|---|-|----|-|-|----|
+ // |332|2|2222|2222|1111|1111|110|0|00 |0|0|0000|
+ // |1 9|8|7654|3210|9 6|54 2|109|8|76 |5|4|3 0|
+ // |---|-|----|----|----|----|---|-|----|-|-|----|
+ // |111|T|1110|opc1|opc2| |101| |opc3| | | |
+ // 111 0 1110|1111 0100 1110 101 0 01 1 0 1001 - eef4ea69
+ uint32_t opc1 = (instr >> 20) & 0xF;
+ uint32_t opc2 = (instr >> 16) & 0xF;
+ //uint32_t opc3 = (instr >> 6) & 0x3;
+ if ((opc1 & 0xB) == 0xB) { // 1x11
+ // Other VFP data-processing instructions.
+ switch (opc2) {
+ case 0x4: case 0x5: { // Vector compare
+ // 1110 11101 D 11 0100 dddd 101 sE1M0 mmmm
+ uint32_t D = (instr >> 22) & 0x1;
+ uint32_t Vd = (instr >> 12) & 0xF;
+ uint32_t sz = (instr >> 8) & 1;
+ uint32_t E = (instr >> 7) & 1;
+ uint32_t M = (instr >> 5) & 1;
+ uint32_t Vm = instr & 0xF;
+ bool dp_operation = sz == 1;
+ opcode << (E == 0 ? "vcmp" : "vcmpe");
+ opcode << (dp_operation ? ".f64" : ".f32");
+ if (dp_operation) {
+ args << "f" << ((D << 4) | Vd) << ", " << "f" << ((M << 4) | Vm);
+ } else {
+ args << "f" << ((Vd << 1) | D) << ", " << "f" << ((Vm << 1) | M);
+ }
+ break;
+ }
+ }
+ }
}
- opcode << ".w";
- args << Rd << ", " << Rm;
- break;
}
- default:
- break;
}
break;
case 2:
@@ -393,7 +429,6 @@ size_t DisassemblerArm::DumpThumb32(std::ostream& os, const uint8_t* instr_ptr)
// |---|--|--|----|-|----|-|---|----|--------|
// |111|10|i0| op3|S| Rn |0|iii| Rd |iiiiiiii|
// 111 10 x0 xxxx x xxxx opxxx xxxx xxxxxxxx
- // 111 10 00 0110 0 0000 1 000 0000 10101101 - f0c080ad
uint32_t i = (instr >> 26) & 1;
uint32_t op3 = (instr >> 21) & 0xF;
uint32_t S = (instr >> 20) & 1;
diff --git a/src/exception_test.cc b/src/exception_test.cc
index e52992c70d..c83557dae1 100644
--- a/src/exception_test.cc
+++ b/src/exception_test.cc
@@ -146,14 +146,15 @@ TEST_F(ExceptionTest, StackTraceElement) {
fake_stack.push_back(0);
fake_stack.push_back(0);
fake_stack.push_back(reinterpret_cast<uintptr_t>(method_g_));
- fake_stack.push_back(37);
+ // LLVM compiler will do this in the MethodCompiler
+ fake_stack.push_back(dex_->GetLineNumFromPC(method_g_, 3));
fake_stack.push_back(0);
// Create/push fake 20-byte shadow frame for method f
fake_stack.push_back(0);
fake_stack.push_back(0);
fake_stack.push_back(reinterpret_cast<uintptr_t>(method_f_));
- fake_stack.push_back(22);
+ fake_stack.push_back(dex_->GetLineNumFromPC(method_f_, 3));
fake_stack.push_back(0);
Thread* thread = Thread::Current();
diff --git a/src/logging.cc b/src/logging.cc
index f962e41ccc..4aacd3b7fc 100644
--- a/src/logging.cc
+++ b/src/logging.cc
@@ -74,6 +74,11 @@ void HexDump::Dump(std::ostream& os) const {
return;
}
+ if (address_ == NULL) {
+ os << "00000000:";
+ return;
+ }
+
static const char gHexDigit[] = "0123456789abcdef";
const unsigned char* addr = reinterpret_cast<const unsigned char*>(address_);
char out[76]; /* exact fit */
diff --git a/src/oat/runtime/context.cc b/src/oat/runtime/context.cc
index 998e762f2c..30733775ed 100644
--- a/src/oat/runtime/context.cc
+++ b/src/oat/runtime/context.cc
@@ -16,8 +16,11 @@
#include "context.h"
+#if defined(__arm__)
#include "arm/context_arm.h"
+#else
#include "x86/context_x86.h"
+#endif
namespace art {
diff --git a/src/object_utils.h b/src/object_utils.h
index 249fffb303..99768de070 100644
--- a/src/object_utils.h
+++ b/src/object_utils.h
@@ -67,11 +67,15 @@ class ClassHelper {
dex_cache_(NULL),
dex_file_(NULL),
interface_type_list_(NULL),
- klass_(c) {
+ klass_(NULL) {
+ if (c != NULL) {
+ ChangeClass(c);
+ }
}
void ChangeClass(const Class* new_c) {
- CHECK(new_c != NULL);
+ CHECK(new_c != NULL) << "klass_=" << klass_ << " " << HexDump(klass_, sizeof(Class), true);
+ CHECK(new_c->IsClass()) << "klass_=" << klass_ << " " << HexDump(klass_, sizeof(Class), true);
if (dex_cache_ != NULL) {
DexCache* new_c_dex_cache = new_c->GetDexCache();
if (new_c_dex_cache != dex_cache_) {
@@ -87,6 +91,7 @@ class ClassHelper {
// The returned const char* is only guaranteed to be valid for the lifetime of the ClassHelper.
// If you need it longer, copy it into a std::string.
const char* GetDescriptor() {
+ CHECK(klass_ != NULL);
if (UNLIKELY(klass_->IsArrayClass())) {
return GetArrayDescriptor();
} else if (UNLIKELY(klass_->IsPrimitive())) {
@@ -104,6 +109,7 @@ class ClassHelper {
const char* GetArrayDescriptor() {
std::string result("[");
const Class* saved_klass = klass_;
+ CHECK(saved_klass != NULL);
ChangeClass(klass_->GetComponentType());
result += GetDescriptor();
ChangeClass(saved_klass);
@@ -121,6 +127,7 @@ class ClassHelper {
}
uint32_t NumInterfaces() {
+ DCHECK(klass_ != NULL);
if (klass_->IsPrimitive()) {
return 0;
} else if (klass_->IsArrayClass()) {
@@ -138,12 +145,14 @@ class ClassHelper {
}
uint16_t GetInterfaceTypeIdx(uint32_t idx) {
+ DCHECK(klass_ != NULL);
DCHECK(!klass_->IsPrimitive());
DCHECK(!klass_->IsArrayClass());
return GetInterfaceTypeList()->GetTypeItem(idx).type_idx_;
}
Class* GetInterface(uint32_t idx) {
+ DCHECK(klass_ != NULL);
DCHECK(!klass_->IsPrimitive());
if (klass_->IsArrayClass()) {
if (idx == 0) {
@@ -203,6 +212,7 @@ class ClassHelper {
DexCache* GetDexCache() {
DexCache* result = dex_cache_;
if (result == NULL) {
+ DCHECK(klass_ != NULL);
result = klass_->GetDexCache();
dex_cache_ = result;
}
diff --git a/src/thread.cc b/src/thread.cc
index fa78365673..c4934b091f 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -1740,11 +1740,11 @@ void Thread::CheckSafeToLockOrUnlock(MutexRank rank, bool is_locking) {
bad_mutexes_held = true;
}
}
- CHECK(!bad_mutexes_held);
+ CHECK(!bad_mutexes_held) << rank;
}
++held_mutexes_[rank];
} else {
- CHECK_GT(held_mutexes_[rank], 0U);
+ CHECK_GT(held_mutexes_[rank], 0U) << rank;
--held_mutexes_[rank];
}
}