Index: runtime/vm/instructions_arm64.cc |
diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc |
index 83de46e38bc535ffdca02fc102a8606cdea65f9f..59da8d5ff247b14e4eacf41721ad77c8b764d7f3 100644 |
--- a/runtime/vm/instructions_arm64.cc |
+++ b/runtime/vm/instructions_arm64.cc |
@@ -32,6 +32,51 @@ CallPattern::CallPattern(uword pc, const Code& code) |
} |
+NativeCallPattern::NativeCallPattern(uword pc, const Code& code) |
+ : object_pool_(ObjectPool::Handle(code.GetObjectPool())), |
+ end_(pc), |
+ native_function_pool_index_(-1), |
+ target_address_pool_index_(-1) { |
+ ASSERT(code.ContainsInstructionAt(pc)); |
+ // Last instruction: blr ip0. |
+ ASSERT(*(reinterpret_cast<uint32_t*>(end_) - 1) == 0xd63f0200); |
+ |
+ Register reg; |
+ uword native_function_load_end = |
+ InstructionPattern::DecodeLoadWordFromPool(end_ - Instr::kInstrSize, |
+ ®, |
+ &target_address_pool_index_); |
+ ASSERT(reg == IP0); |
+ InstructionPattern::DecodeLoadWordFromPool(native_function_load_end, |
+ ®, |
+ &native_function_pool_index_); |
+ ASSERT(reg == R5); |
+} |
+ |
+ |
+uword NativeCallPattern::target() const { |
+ return object_pool_.RawValueAt(target_address_pool_index_); |
+} |
+ |
+ |
+void NativeCallPattern::set_target(uword target_address) const { |
+ object_pool_.SetRawValueAt(target_address_pool_index_, target_address); |
+ // No need to flush the instruction cache, since the code is not modified. |
+} |
+ |
+ |
+NativeFunction NativeCallPattern::native_function() const { |
+ return reinterpret_cast<NativeFunction>( |
+ object_pool_.RawValueAt(native_function_pool_index_)); |
+} |
+ |
+ |
+void NativeCallPattern::set_native_function(NativeFunction func) const { |
+ object_pool_.SetRawValueAt(native_function_pool_index_, |
+ reinterpret_cast<uword>(func)); |
+} |
+ |
+ |
intptr_t InstructionPattern::OffsetFromPPIndex(intptr_t index) { |
return Array::element_offset(index); |
} |