Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Unified Diff: runtime/vm/instructions_arm.cc

Issue 12518016: Decode ic data and arguments descriptor passed in calls on ARM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/instructions_arm.cc
===================================================================
--- runtime/vm/instructions_arm.cc (revision 19822)
+++ runtime/vm/instructions_arm.cc (working copy)
@@ -14,8 +14,18 @@
CallPattern::CallPattern(uword pc, const Code& code)
: end_(reinterpret_cast<uword*>(pc)),
- pool_index_(DecodePoolIndex()),
- object_pool_(Array::Handle(code.ObjectPool())) { }
+ target_address_pool_index_(-1),
+ args_desc_load_end_(-1),
+ args_desc_pool_index_(-1),
+ ic_data_load_end_(-1),
+ ic_data_pool_index_(-1),
+ object_pool_(Array::Handle(code.ObjectPool())) {
+ ASSERT(Back(1) == 0xe12fff3e); // Last instruction: blx lr
+ Register reg;
+ args_desc_load_end_ =
+ DecodeLoadWordFromPool(1, &reg, &target_address_pool_index_);
+ ASSERT(reg == LR);
+}
uword CallPattern::Back(int n) const {
@@ -24,43 +34,83 @@
}
-int CallPattern::DecodePoolIndex() {
- ASSERT(Back(1) == 0xe12fff3e); // Last instruction: blx lr
- // Decode the second to last instruction.
- uword instr = Back(2);
+// 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 instr = Back(++end);
int offset = 0;
- if ((instr & 0xfffff000) == 0xe59ae000) { // ldr lr, [pp, #+offset]
+ if ((instr & 0xffff0000) == 0xe59a0000) { // ldr reg, [pp, #+offset]
zra 2013/03/11 22:36:08 Would it be too heavyweight here to use the Instr
regis 2013/03/11 23:16:30 I thought of using class Instr and tried, but the
offset = instr & 0xfff;
+ *reg = static_cast<Register>((instr & 0xf000) >> 12);
} else {
- ASSERT((instr & 0xfffff000) == 0xe59ee000); // ldr lr, [lr, #+offset]
+ ASSERT((instr & 0xfff00000) == 0xe5900000); // ldr reg, [reg, #+offset]
offset = instr & 0xfff;
- instr = Back(3);
- if ((instr & 0xfffff000) == 0xe28ae000) { // add lr, pp, shifter_op
+ instr = Back(++end);
+ if ((instr & 0xffff0000) == 0xe28a0000) { // add reg, pp, shifter_op
const int rot = (instr & 0xf00) * 2;
const int imm8 = instr & 0xff;
offset |= (imm8 >> rot) | (imm8 << (32 - rot));
+ *reg = static_cast<Register>((instr & 0xf000) >> 12);
} else {
- ASSERT(instr == 0xe08ae00e); // add lr, pp, lr
- instr = Back(4);
- if ((instr & 0xfff0f000) == 0xe340e000) { // movt lr, offset_hi
+ ASSERT((instr & 0xffff0000) == 0xe08a0000); // add reg, pp, reg
+ instr = Back(++end);
+ if ((instr & 0xfff00000) == 0xe3400000) { // movt reg, offset_hi
offset |= (instr & 0xf0000) << 12;
offset |= (instr & 0xfff) << 16;
- instr = Back(5);
+ instr = Back(++end);
}
- ASSERT((instr & 0xfff0f000) == 0xe300e000); // movw lr, offset_lo
+ ASSERT((instr & 0xfff00000) == 0xe3000000); // movw reg, offset_lo
ASSERT((offset & 0xffff) == 0);
offset |= (instr & 0xf0000) >> 4;
offset |= instr & 0xfff;
+ *reg = static_cast<Register>((instr & 0xf000) >> 12);
}
}
offset += kHeapObjectTag;
ASSERT(Utils::IsAligned(offset, 4));
- return (offset - Array::data_offset())/4;
+ *index = (offset - Array::data_offset())/4;
+ return end;
}
+RawICData* CallPattern::IcData() {
+ if (ic_data_pool_index_ < 0) {
+ Register reg;
+ // Loading of the argument descriptor must be decoded first, if not already.
+ if (args_desc_pool_index_ < 0) {
+ ic_data_load_end_ = DecodeLoadWordFromPool(
+ args_desc_load_end_, &reg, &args_desc_pool_index_);
+ ASSERT(reg == R4);
+ }
+ DecodeLoadWordFromPool(ic_data_load_end_, &reg, &ic_data_pool_index_);
+ ASSERT(reg == R5);
+ }
+ ICData& ic_data = ICData::Handle();
+ ic_data ^= object_pool_.At(ic_data_pool_index_);
+ return ic_data.raw();
+}
+
+
+RawArray* CallPattern::ArgumentsDescriptor() {
+ if (args_desc_pool_index_ < 0) {
+ Register reg;
+ ic_data_load_end_ = DecodeLoadWordFromPool(
+ args_desc_load_end_, &reg, &args_desc_pool_index_);
+ ASSERT(reg == R4);
+ }
+ Array& args_desc = Array::Handle();
+ args_desc ^= object_pool_.At(args_desc_pool_index_);
+ return args_desc.raw();
+}
+
+
uword CallPattern::TargetAddress() const {
- const Object& target_address = Object::Handle(object_pool_.At(pool_index_));
+ ASSERT(target_address_pool_index_ >= 0);
+ const Object& target_address =
+ Object::Handle(object_pool_.At(target_address_pool_index_));
ASSERT(target_address.IsSmi());
// The address is stored in the object array as a RawSmi.
return reinterpret_cast<uword>(target_address.raw());
@@ -71,7 +121,7 @@
ASSERT(Utils::IsAligned(target_address, 4));
// The address is stored in the object array as a RawSmi.
const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(target_address));
- object_pool_.SetAt(pool_index_, smi);
+ object_pool_.SetAt(target_address_pool_index_, smi);
// No need to flush the instruction cache, since the code is not modified.
}

Powered by Google App Engine
This is Rietveld 408576698