OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 // Declares a Simulator for MIPS instructions if we are not generating a native | 5 // Declares a Simulator for MIPS instructions if we are not generating a native |
6 // MIPS binary. This Simulator allows us to run and debug MIPS code generation | 6 // MIPS binary. This Simulator allows us to run and debug MIPS code generation |
7 // on regular desktop machines. | 7 // on regular desktop machines. |
8 // Dart calls into generated code by "calling" the InvokeDartCode stub, | 8 // Dart calls into generated code by "calling" the InvokeDartCode stub, |
9 // which will start execution in the Simulator or forwards to the real entry | 9 // which will start execution in the Simulator or forwards to the real entry |
10 // on a MIPS HW platform. | 10 // on a MIPS HW platform. |
11 | 11 |
12 #ifndef VM_SIMULATOR_MIPS_H_ | 12 #ifndef VM_SIMULATOR_MIPS_H_ |
13 #define VM_SIMULATOR_MIPS_H_ | 13 #define VM_SIMULATOR_MIPS_H_ |
14 | 14 |
15 #ifndef VM_SIMULATOR_H_ | 15 #ifndef VM_SIMULATOR_H_ |
16 #error Do not include simulator_mips.h directly; use simulator.h. | 16 #error Do not include simulator_mips.h directly; use simulator.h. |
17 #endif | 17 #endif |
18 | 18 |
19 #include "vm/constants_mips.h" | 19 #include "vm/constants_mips.h" |
20 #include "vm/object.h" | |
21 | 20 |
22 namespace dart { | 21 namespace dart { |
23 | 22 |
24 class Isolate; | 23 class Isolate; |
| 24 class Mutex; |
| 25 class RawObject; |
25 class SimulatorSetjmpBuffer; | 26 class SimulatorSetjmpBuffer; |
26 | 27 |
27 class Simulator { | 28 class Simulator { |
28 public: | 29 public: |
29 static const uword kSimulatorStackUnderflowSize = 64; | 30 static const uword kSimulatorStackUnderflowSize = 64; |
30 | 31 |
31 Simulator(); | 32 Simulator(); |
32 ~Simulator(); | 33 ~Simulator(); |
33 | 34 |
34 // The currently executing Simulator instance, which is associated to the | 35 // The currently executing Simulator instance, which is associated to the |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 // result on return. When fp_return is true the return value is the D0 | 104 // result on return. When fp_return is true the return value is the D0 |
104 // floating point register. Otherwise, the return value is V1:V0. | 105 // floating point register. Otherwise, the return value is V1:V0. |
105 int64_t Call(int32_t entry, | 106 int64_t Call(int32_t entry, |
106 int32_t parameter0, | 107 int32_t parameter0, |
107 int32_t parameter1, | 108 int32_t parameter1, |
108 int32_t parameter2, | 109 int32_t parameter2, |
109 int32_t parameter3, | 110 int32_t parameter3, |
110 bool fp_return = false, | 111 bool fp_return = false, |
111 bool fp_args = false); | 112 bool fp_args = false); |
112 | 113 |
| 114 // Implementation of atomic compare and exchange in the same synchronization |
| 115 // domain as other synchronization primitive instructions (e.g. ldrex, strex). |
| 116 static uword CompareExchange(uword* address, |
| 117 uword compare_value, |
| 118 uword new_value); |
| 119 |
113 // Runtime and native call support. | 120 // Runtime and native call support. |
114 enum CallKind { | 121 enum CallKind { |
115 kRuntimeCall, | 122 kRuntimeCall, |
116 kLeafRuntimeCall, | 123 kLeafRuntimeCall, |
117 kLeafFloatRuntimeCall, | 124 kLeafFloatRuntimeCall, |
118 kBootstrapNativeCall, | 125 kBootstrapNativeCall, |
119 kNativeCall | 126 kNativeCall |
120 }; | 127 }; |
121 static uword RedirectExternalReference(uword function, | 128 static uword RedirectExternalReference(uword function, |
122 CallKind call_kind, | 129 CallKind call_kind, |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 inline uint16_t ReadHU(uword addr, Instr *instr); | 190 inline uint16_t ReadHU(uword addr, Instr *instr); |
184 inline intptr_t ReadW(uword addr, Instr* instr); | 191 inline intptr_t ReadW(uword addr, Instr* instr); |
185 | 192 |
186 inline void WriteB(uword addr, uint8_t value); | 193 inline void WriteB(uword addr, uint8_t value); |
187 inline void WriteH(uword addr, uint16_t value, Instr* isntr); | 194 inline void WriteH(uword addr, uint16_t value, Instr* isntr); |
188 inline void WriteW(uword addr, intptr_t value, Instr* instr); | 195 inline void WriteW(uword addr, intptr_t value, Instr* instr); |
189 | 196 |
190 inline double ReadD(uword addr, Instr* instr); | 197 inline double ReadD(uword addr, Instr* instr); |
191 inline void WriteD(uword addr, double value, Instr* instr); | 198 inline void WriteD(uword addr, double value, Instr* instr); |
192 | 199 |
| 200 // In Dart, there is at most one thread per isolate. |
| 201 // We keep track of 16 exclusive access address tags across all isolates. |
| 202 // Since we cannot simulate a native context switch, which clears |
| 203 // the exclusive access state of the local monitor, we associate the isolate |
| 204 // requesting exclusive access to the address tag. |
| 205 // Multiple isolates requesting exclusive access (using the LL instruction) |
| 206 // to the same address will result in multiple address tags being created for |
| 207 // the same address, one per isolate. |
| 208 // At any given time, each isolate is associated to at most one address tag. |
| 209 static Mutex* exclusive_access_lock_; |
| 210 static const int kNumAddressTags = 16; |
| 211 static struct AddressTag { |
| 212 Isolate* isolate; |
| 213 uword addr; |
| 214 } exclusive_access_state_[kNumAddressTags]; |
| 215 static int next_address_tag_; |
| 216 |
| 217 // Synchronization primitives support. |
| 218 void ClearExclusive(); |
| 219 intptr_t ReadExclusiveW(uword addr, Instr* instr); |
| 220 intptr_t WriteExclusiveW(uword addr, intptr_t value, Instr* instr); |
| 221 |
| 222 // Set access to given address to 'exclusive state' for current isolate. |
| 223 static void SetExclusiveAccess(uword addr); |
| 224 |
| 225 // Returns true if the current isolate has exclusive access to given address, |
| 226 // returns false otherwise. In either case, set access to given address to |
| 227 // 'open state' for all isolates. |
| 228 // If given addr is NULL, set access to 'open state' for current |
| 229 // isolate (CLREX). |
| 230 static bool HasExclusiveAccessAndOpen(uword addr); |
| 231 |
193 void DoBranch(Instr* instr, bool taken, bool likely); | 232 void DoBranch(Instr* instr, bool taken, bool likely); |
194 void DoBreak(Instr *instr); | 233 void DoBreak(Instr *instr); |
195 | 234 |
196 void DecodeSpecial(Instr* instr); | 235 void DecodeSpecial(Instr* instr); |
197 void DecodeSpecial2(Instr* instr); | 236 void DecodeSpecial2(Instr* instr); |
198 void DecodeRegImm(Instr* instr); | 237 void DecodeRegImm(Instr* instr); |
199 void DecodeCop1(Instr* instr); | 238 void DecodeCop1(Instr* instr); |
200 void InstructionDecode(Instr* instr); | 239 void InstructionDecode(Instr* instr); |
201 | 240 |
202 void Execute(); | 241 void Execute(); |
203 void ExecuteDelaySlot(); | 242 void ExecuteDelaySlot(); |
204 | 243 |
205 // Longjmp support for exceptions. | 244 // Longjmp support for exceptions. |
206 SimulatorSetjmpBuffer* last_setjmp_buffer() { | 245 SimulatorSetjmpBuffer* last_setjmp_buffer() { |
207 return last_setjmp_buffer_; | 246 return last_setjmp_buffer_; |
208 } | 247 } |
209 void set_last_setjmp_buffer(SimulatorSetjmpBuffer* buffer) { | 248 void set_last_setjmp_buffer(SimulatorSetjmpBuffer* buffer) { |
210 last_setjmp_buffer_ = buffer; | 249 last_setjmp_buffer_ = buffer; |
211 } | 250 } |
212 | 251 |
213 friend class SimulatorDebugger; | 252 friend class SimulatorDebugger; |
214 friend class SimulatorSetjmpBuffer; | 253 friend class SimulatorSetjmpBuffer; |
215 DISALLOW_COPY_AND_ASSIGN(Simulator); | 254 DISALLOW_COPY_AND_ASSIGN(Simulator); |
216 }; | 255 }; |
217 | 256 |
218 } // namespace dart | 257 } // namespace dart |
219 | 258 |
220 #endif // VM_SIMULATOR_MIPS_H_ | 259 #endif // VM_SIMULATOR_MIPS_H_ |
OLD | NEW |