Index: runtime/vm/instructions_mips.cc |
diff --git a/runtime/vm/instructions_mips.cc b/runtime/vm/instructions_mips.cc |
index 60568eb891364c94ca93421375a51a0891107846..fc758cde39f208736c355243283fa17e6adab254 100644 |
--- a/runtime/vm/instructions_mips.cc |
+++ b/runtime/vm/instructions_mips.cc |
@@ -145,6 +145,51 @@ void CallPattern::SetTargetAddress(uword target_address) const { |
} |
+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: jalr RA, T9(=R25). |
+ ASSERT(*(reinterpret_cast<uword*>(end_) - 2) == 0x0320f809); |
+ |
+ Register reg; |
+ uword native_function_load_end = |
+ InstructionPattern::DecodeLoadWordFromPool(end_ - 2 * Instr::kInstrSize, |
+ ®, |
+ &target_address_pool_index_); |
+ ASSERT(reg == T9); |
+ InstructionPattern::DecodeLoadWordFromPool(native_function_load_end, |
+ ®, |
+ &native_function_pool_index_); |
+ ASSERT(reg == T5); |
+} |
+ |
+ |
+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)); |
+} |
+ |
+ |
void CallPattern::InsertAt(uword pc, uword target_address) { |
Instr* lui = Instr::At(pc + (0 * Instr::kInstrSize)); |
Instr* ori = Instr::At(pc + (1 * Instr::kInstrSize)); |