Index: runtime/vm/code_patcher_ia32.cc |
diff --git a/runtime/vm/code_patcher_ia32.cc b/runtime/vm/code_patcher_ia32.cc |
index 9cccd56c19639dbc612561ff512f2b1b8cb77ddd..ce36f00d4bdc914b101c59341e3a9681ca971f8c 100644 |
--- a/runtime/vm/code_patcher_ia32.cc |
+++ b/runtime/vm/code_patcher_ia32.cc |
@@ -149,7 +149,7 @@ class StaticCall : public ValueObject { |
}; |
-// The expected pattern of a dart closure call: |
+// The expected pattern of a Dart closure call: |
// mov EDX, arguments_descriptor_array |
// call target_address |
// <- return address |
@@ -259,6 +259,34 @@ intptr_t CodePatcher::InstanceCallSizeInBytes() { |
return InstanceCall::kNumInstructions * InstanceCall::kInstructionSize; |
} |
+ |
+// The expected code pattern of an edge counter in unoptimized code: |
+// b8 imm32 mov EAX, immediate |
+class EdgeCounter : public ValueObject { |
+ public: |
+ EdgeCounter(uword start, const Code& ignored) : start_(start) { |
+ ASSERT(IsValid(start)); |
+ } |
+ |
+ static bool IsValid(uword start) { |
+ return (*reinterpret_cast<uint8_t*>(start) == 0xb8); |
+ } |
+ |
+ RawObject* edge_counter() const { |
+ return *reinterpret_cast<RawObject**>(start_ + 1); |
+ } |
+ |
+ private: |
+ uword start_; |
+}; |
+ |
+ |
+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_IA32 |