Chromium Code Reviews| Index: runtime/vm/code_patcher_arm.cc |
| diff --git a/runtime/vm/code_patcher_arm.cc b/runtime/vm/code_patcher_arm.cc |
| index 105d3a1d3747251cde9f0c5f145cd07d189d3cb0..a4cdc8f4e4708d8c22105f64ab0404ce47af18a0 100644 |
| --- a/runtime/vm/code_patcher_arm.cc |
| +++ b/runtime/vm/code_patcher_arm.cc |
| @@ -84,6 +84,51 @@ RawFunction* CodePatcher::GetUnoptimizedStaticCallAt( |
| return ic_data.GetTargetAt(0); |
| } |
| + |
| +// This class pattern matches on a load from the object pool. Loading on |
| +// ARM is complicated because it can take four possible different forms. We |
| +// match backwards from the end of the sequence so we can reuse the code for |
| +// matching object pool loads at calls. |
| +class EdgeCounter : public ValueObject { |
| + public: |
| + EdgeCounter(uword end, const Code& code) |
| + : end_(end - kAdjust), object_pool_(Array::Handle(code.ObjectPool())) { |
| + // An IsValid predicate is complicated and duplicates the code in the |
| + // decoding function. Instead we rely on decoding the pattern which |
| + // will partial validity. |
|
Florian Schneider
2013/09/30 08:55:38
missing verb in this comment?
|
| + } |
| + |
| + RawObject* edge_counter() const { |
| + Register ignored; |
| + intptr_t index; |
| + InstructionPattern::DecodeLoadWordFromPool( |
| + reinterpret_cast<const uword*>(end_), |
| + &ignored, |
| + &index); |
| + ASSERT(ignored == R0); |
| + return object_pool_.At(index); |
| + } |
| + |
| + private: |
| + // The object pool load is followed by the fixed-size edge counter |
| + // incrementing code: |
| + // ldr ip, [r0, #+11] |
| + // adds ip, ip, #2 |
| + // mvnvs ip, #-2147483647 |
| + // str ip, [r0, #+11] |
| + static const intptr_t kAdjust = 4 * Instr::kInstrSize; |
| + |
| + uword end_; |
| + const Array& object_pool_; |
| +}; |
| + |
| + |
| +RawObject* CodePatcher::GetEdgeCounterAt(uword pc, const Code& code) { |
| + ASSERT(code.ContainsInstructionAt(pc)); |
| + EdgeCounter counter(pc, code); |
| + return counter.edge_counter(); |
| +} |
| + |
| } // namespace dart |
| #endif // defined TARGET_ARCH_ARM |