Index: runtime/vm/instructions_mips.cc |
diff --git a/runtime/vm/instructions_mips.cc b/runtime/vm/instructions_mips.cc |
index 7215ec08f6f89f9bbd71ea60aba8693ebceaf4c8..ae6fbf24ed50dd8f7310b485cec7b9cccee75fd9 100644 |
--- a/runtime/vm/instructions_mips.cc |
+++ b/runtime/vm/instructions_mips.cc |
@@ -13,82 +13,88 @@ |
namespace dart { |
CallPattern::CallPattern(uword pc, const Code& code) |
- : end_(reinterpret_cast<uword*>(pc)), |
+ : object_pool_(Array::Handle(code.ObjectPool())), |
+ end_(pc), |
+ args_desc_load_end_(0), |
+ ic_data_load_end_(0), |
target_address_pool_index_(-1), |
- args_desc_load_end_(-1), |
args_desc_(Array::Handle()), |
- ic_data_load_end_(-1), |
- ic_data_(ICData::Handle()), |
- object_pool_(Array::Handle(code.ObjectPool())) { |
+ ic_data_(ICData::Handle()) { |
ASSERT(code.ContainsInstructionAt(pc)); |
- ASSERT(Back(2) == 0x0020f809); // Last instruction: jalr RA, TMP(=R1) |
+ // Last instruction: jalr RA, TMP(=R1). |
+ ASSERT(*(reinterpret_cast<uword*>(end_) - 2) == 0x0020f809); |
Register reg; |
- // First end is 0 so that we begin from the delay slot of the jalr. |
+ // The end of the pattern is the instruction after the delay slot of the jalr. |
ic_data_load_end_ = |
- DecodeLoadWordFromPool(2, ®, &target_address_pool_index_); |
+ InstructionPattern::DecodeLoadWordFromPool(end_ - (2 * Instr::kInstrSize), |
+ ®, |
+ &target_address_pool_index_); |
ASSERT(reg == TMP); |
} |
-uword CallPattern::Back(int n) const { |
- ASSERT(n > 0); |
- return *(end_ - n); |
-} |
- |
- |
-// Decodes a load sequence ending at end. Returns the register being loaded and |
-// the loaded object. |
-// Returns the location of the load sequence, counting the number of |
-// instructions back from the end of the call pattern. |
-int CallPattern::DecodeLoadObject(int end, Register* reg, Object* obj) { |
- ASSERT(end > 0); |
- uword i = Back(end + 1); |
- Instr* instr = Instr::At(reinterpret_cast<uword>(&i)); |
+// 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 |
+// and the loaded object in the output parameters 'reg' and 'obj' |
+// respectively. |
+uword InstructionPattern::DecodeLoadObject(uword end, |
+ const Array& object_pool, |
+ Register* reg, |
+ Object* obj) { |
+ uword start = 0; |
+ Instr* instr = Instr::At(end - Instr::kInstrSize); |
if (instr->OpcodeField() == LW) { |
- int index = 0; |
- end = DecodeLoadWordFromPool(end, reg, &index); |
- *obj = object_pool_.At(index); |
+ intptr_t index = 0; |
+ start = DecodeLoadWordFromPool(end, reg, &index); |
+ *obj = object_pool.At(index); |
} else { |
- int value = 0; |
- end = DecodeLoadWordImmediate(end, reg, &value); |
+ intptr_t value = 0; |
+ start = DecodeLoadWordImmediate(end, reg, &value); |
*obj = reinterpret_cast<RawObject*>(value); |
} |
- return end; |
+ return start; |
} |
-// Decodes a load sequence ending at end. Returns the register being loaded and |
-// the loaded immediate value. |
-// Returns the location of the load sequence, counting the number of |
-// instructions back from the end of the call pattern. |
-int CallPattern::DecodeLoadWordImmediate(int end, Register* reg, int* value) { |
- ASSERT(end > 0); |
- int imm = 0; |
- uword i = Back(++end); |
- Instr* instr = Instr::At(reinterpret_cast<uword>(&i)); |
+// 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 |
+// and the loaded immediate value in the output parameters 'reg' and 'value' |
+// respectively. |
+uword InstructionPattern::DecodeLoadWordImmediate(uword end, |
+ Register* reg, |
+ intptr_t* value) { |
+ // The pattern is a fixed size, but match backwards for uniformity with |
+ // DecodeLoadWordFromPool. |
+ uword start = end - Instr::kInstrSize; |
+ Instr* instr = Instr::At(start); |
+ intptr_t imm = 0; |
ASSERT(instr->OpcodeField() == ORI); |
imm = instr->UImmField(); |
*reg = instr->RtField(); |
- i = Back(++end); |
- instr = Instr::At(reinterpret_cast<uword>(&i)); |
+ start -= Instr::kInstrSize; |
+ instr = Instr::At(start); |
ASSERT(instr->OpcodeField() == LUI); |
ASSERT(instr->RtField() == *reg); |
imm |= (instr->UImmField() << 16); |
*value = imm; |
- return end; |
+ return start; |
} |
-// Decodes a load sequence ending at end. Returns the register being loaded and |
-// the index in the pool being read from. |
-// Returns the location of the load sequence, counting the number of |
-// instructions back from the end of the call pattern. |
-int CallPattern::DecodeLoadWordFromPool(int end, Register* reg, int* index) { |
- ASSERT(end > 0); |
- uword i = Back(++end); |
- Instr* instr = Instr::At(reinterpret_cast<uword>(&i)); |
- int offset = 0; |
+// 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 |
+// and the index in the pool being read from in the output parameters 'reg' |
+// and 'index' respectively. |
+uword InstructionPattern::DecodeLoadWordFromPool(uword end, |
+ Register* reg, |
+ intptr_t* index) { |
+ uword start = end - Instr::kInstrSize; |
+ Instr* instr = Instr::At(start); |
+ intptr_t offset = 0; |
if ((instr->OpcodeField() == LW) && (instr->RsField() == PP)) { |
offset = instr->SImmField(); |
*reg = instr->RtField(); |
@@ -97,16 +103,16 @@ int CallPattern::DecodeLoadWordFromPool(int end, Register* reg, int* index) { |
offset = instr->SImmField(); |
*reg = instr->RtField(); |
- i = Back(++end); |
- instr = Instr::At(reinterpret_cast<uword>(&i)); |
+ start -= Instr::kInstrSize; |
+ instr = Instr::At(start); |
ASSERT(instr->OpcodeField() == SPECIAL); |
ASSERT(instr->FunctionField() == ADDU); |
ASSERT(instr->RdField() == *reg); |
ASSERT(instr->RsField() == *reg); |
ASSERT(instr->RtField() == PP); |
- i = Back(++end); |
- instr = Instr::At(reinterpret_cast<uword>(&i)); |
+ start -= Instr::kInstrSize; |
+ instr = Instr::At(start); |
ASSERT(instr->OpcodeField() == LUI); |
ASSERT(instr->RtField() == *reg); |
// Offset is signed, so add the upper 16 bits. |
@@ -114,15 +120,19 @@ int CallPattern::DecodeLoadWordFromPool(int end, Register* reg, int* index) { |
} |
offset += kHeapObjectTag; |
ASSERT(Utils::IsAligned(offset, 4)); |
- *index = (offset - Array::data_offset())/4; |
- return end; |
+ *index = (offset - Array::data_offset()) / 4; |
+ return start; |
} |
RawICData* CallPattern::IcData() { |
if (ic_data_.IsNull()) { |
Register reg; |
- args_desc_load_end_ = DecodeLoadObject(ic_data_load_end_, ®, &ic_data_); |
+ args_desc_load_end_ = |
+ InstructionPattern::DecodeLoadObject(ic_data_load_end_, |
+ object_pool_, |
+ ®, |
+ &ic_data_); |
ASSERT(reg == S5); |
} |
return ic_data_.raw(); |
@@ -133,7 +143,10 @@ RawArray* CallPattern::ClosureArgumentsDescriptor() { |
if (args_desc_.IsNull()) { |
IcData(); // Loading of the ic_data must be decoded first, if not already. |
Register reg; |
- DecodeLoadObject(args_desc_load_end_, ®, &args_desc_); |
+ InstructionPattern::DecodeLoadObject(args_desc_load_end_, |
+ object_pool_, |
+ ®, |
+ &args_desc_); |
ASSERT(reg == S4); |
} |
return args_desc_.raw(); |
@@ -217,4 +230,3 @@ void JumpPattern::SetTargetAddress(uword target_address) const { |
} // namespace dart |
#endif // defined TARGET_ARCH_MIPS |
- |