Index: runtime/vm/instructions_arm.cc |
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc |
index de74bd5ed29840218bf220b2d6751deb595eff54..36281df0b8e8b60050d658647d0001ac79c213fe 100644 |
--- a/runtime/vm/instructions_arm.cc |
+++ b/runtime/vm/instructions_arm.cc |
@@ -169,6 +169,18 @@ uword InstructionPattern::DecodeLoadWordImmediate(uword end, |
} |
+static bool IsLoadWithOffset(int32_t instr, Register base, |
+ intptr_t* offset, Register* dst) { |
+ if ((instr & 0xffff0000) == (0xe5900000 | (base << 16))) { |
+ // ldr reg, [base, #+offset] |
+ *offset = instr & 0xfff; |
+ *dst = static_cast<Register>((instr & 0xf000) >> 12); |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+ |
// Decodes a load sequence ending at 'end' (the last instruction of the load |
// sequence is the instruction before the one at end). Returns a pointer to |
// the first instruction in the sequence. Returns the register being loaded |
@@ -180,10 +192,8 @@ uword InstructionPattern::DecodeLoadWordFromPool(uword end, |
uword start = end - Instr::kInstrSize; |
int32_t instr = Instr::At(start)->InstructionBits(); |
intptr_t offset = 0; |
- if ((instr & 0xffff0000) == (0xe5950000 | (PP << 16))) { |
- // ldr reg, [pp, #+offset] |
- offset = instr & 0xfff; |
- *reg = static_cast<Register>((instr & 0xf000) >> 12); |
+ if (IsLoadWithOffset(instr, PP, &offset, reg)) { |
+ // ldr reg, [PP, #+offset] |
} else { |
ASSERT((instr & 0xfff00000) == 0xe5900000); // ldr reg, [reg, #+offset] |
offset = instr & 0xfff; |
@@ -206,6 +216,30 @@ uword InstructionPattern::DecodeLoadWordFromPool(uword end, |
} |
+bool DecodeLoadObjectFromPoolOrThread(uword pc, |
+ const Code& code, |
+ Object* obj) { |
+ ASSERT(code.ContainsInstructionAt(pc)); |
+ |
+ int32_t instr = Instr::At(pc)->InstructionBits(); |
+ intptr_t offset; |
+ Register dst; |
+ if (IsLoadWithOffset(instr, PP, &offset, &dst)) { |
+ intptr_t index = ObjectPool::IndexFromOffset(offset); |
+ const ObjectPool& pool = ObjectPool::Handle(code.object_pool()); |
+ if (pool.InfoAt(index) == ObjectPool::kTaggedObject) { |
+ *obj = pool.ObjectAt(index); |
+ return true; |
+ } |
+ } else if (IsLoadWithOffset(instr, THR, &offset, &dst)) { |
+ return Thread::ObjectAtOffset(offset, obj); |
+ } |
+ // TODO(rmacnak): Sequence for loads beyond 12 bits. |
+ |
+ return false; |
+} |
+ |
+ |
RawICData* CallPattern::IcData() { |
if (ic_data_.IsNull()) { |
Register reg; |