Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 | 5 |
| 6 // Declares a Simulator for ARM instructions if we are not generating a native | 6 // Declares a Simulator for ARM instructions if we are not generating a native |
| 7 // ARM binary. This Simulator allows us to run and debug ARM code generation on | 7 // ARM binary. This Simulator allows us to run and debug ARM code generation on |
| 8 // regular desktop machines. | 8 // regular desktop machines. |
| 9 // V8 calls into generated code by "calling" the CALL_GENERATED_CODE macro, | 9 // V8 calls into generated code by "calling" the CALL_GENERATED_CODE macro, |
| 10 // which will start execution in the Simulator or forwards to the real entry | 10 // which will start execution in the Simulator or forwards to the real entry |
| 11 // on a ARM HW platform. | 11 // on a ARM HW platform. |
| 12 | 12 |
| 13 #ifndef V8_ARM_SIMULATOR_ARM_H_ | 13 #ifndef V8_ARM_SIMULATOR_ARM_H_ |
| 14 #define V8_ARM_SIMULATOR_ARM_H_ | 14 #define V8_ARM_SIMULATOR_ARM_H_ |
| 15 | 15 |
| 16 #include "src/allocation.h" | 16 #include "src/allocation.h" |
| 17 #include "src/base/lazy-instance.h" | |
| 18 #include "src/base/platform/mutex.h" | |
| 17 | 19 |
| 18 #if !defined(USE_SIMULATOR) | 20 #if !defined(USE_SIMULATOR) |
| 19 // Running without a simulator on a native arm platform. | 21 // Running without a simulator on a native arm platform. |
| 20 | 22 |
| 21 namespace v8 { | 23 namespace v8 { |
| 22 namespace internal { | 24 namespace internal { |
| 23 | 25 |
| 24 // When running without a simulator we call the entry directly. | 26 // When running without a simulator we call the entry directly. |
| 25 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \ | 27 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \ |
| 26 (entry(p0, p1, p2, p3, p4)) | 28 (entry(p0, p1, p2, p3, p4)) |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 422 | 424 |
| 423 // A stop is enabled, meaning the simulator will stop when meeting the | 425 // A stop is enabled, meaning the simulator will stop when meeting the |
| 424 // instruction, if bit 31 of watched_stops_[code].count is unset. | 426 // instruction, if bit 31 of watched_stops_[code].count is unset. |
| 425 // The value watched_stops_[code].count & ~(1 << 31) indicates how many times | 427 // The value watched_stops_[code].count & ~(1 << 31) indicates how many times |
| 426 // the breakpoint was hit or gone through. | 428 // the breakpoint was hit or gone through. |
| 427 struct StopCountAndDesc { | 429 struct StopCountAndDesc { |
| 428 uint32_t count; | 430 uint32_t count; |
| 429 char* desc; | 431 char* desc; |
| 430 }; | 432 }; |
| 431 StopCountAndDesc watched_stops_[kNumOfWatchedStops]; | 433 StopCountAndDesc watched_stops_[kNumOfWatchedStops]; |
| 434 | |
| 435 // Syncronization primitives. See ARM DDI 0406C.b, A2.9. | |
| 436 class DataMonitor { | |
| 437 public: | |
| 438 DataMonitor(); | |
| 439 | |
| 440 // Read and write exclusive. The writes return the strex status: 0 if the | |
| 441 // write succeeds, and 1 if the write fails. | |
| 442 uint8_t ReadExBU(Simulator* simulator, int32_t addr); | |
| 443 int WriteExB(Simulator* simulator, | |
| 444 int32_t addr, | |
| 445 uint8_t value); | |
| 446 | |
| 447 uint16_t ReadExHU(Simulator* simulator, int32_t addr, Instruction* instr); | |
| 448 int WriteExH(Simulator* simulator, | |
| 449 int32_t addr, | |
| 450 uint16_t value, | |
| 451 Instruction* instr); | |
| 452 | |
| 453 int ReadExW(Simulator* simulator, int32_t addr, Instruction* instr); | |
| 454 int WriteExW(Simulator* simulator, | |
| 455 int32_t addr, | |
| 456 int value, | |
| 457 Instruction* instr); | |
| 458 | |
| 459 private: | |
| 460 // Common code for exclusive loads/stores. WriteExInternal returns true if | |
| 461 // the write will succeed. | |
| 462 void ReadExInternal_Locked(int32_t addr); | |
| 463 bool WriteExInternal_Locked(int32_t addr); | |
| 464 | |
| 465 void RemoveNode_Locked(); | |
| 466 void PrependNode_Locked(); | |
| 467 DataMonitor* FirstNodeWithTaggedAddr_Locked(int32_t addr); | |
| 468 | |
| 469 // The exclusive range of a tagged address has an implementation defined | |
| 470 // size, with a minimum size of the access size, and a maximum size of 128 | |
| 471 // bytes. | |
| 472 static const int32_t kAddrMask = ~7; | |
| 473 | |
| 474 enum class Access { | |
| 475 Open, | |
| 476 Exclusive, | |
| 477 }; | |
| 478 | |
| 479 static base::LazyMutex mutex_; | |
| 480 | |
| 481 Access access_state_; | |
| 482 int32_t tagged_addr_; | |
| 483 | |
| 484 // An Isolate's DataMonitor is only in this linked list if it currently has | |
| 485 // exclusive access for some address range. | |
|
jbramley
2016/05/31 16:58:47
The global monitor remembers a single outstanding
binji
2016/06/01 21:06:40
I was writing this as though each Simulator is one
| |
| 486 static DataMonitor* head_; | |
|
jbramley
2016/05/31 16:58:47
I can't see how the list is allocated. Does this c
binji
2016/06/01 21:06:40
Each DataMonitor is a node in the list, so it is a
| |
| 487 DataMonitor* next_; | |
| 488 DataMonitor* prev_; | |
| 489 }; | |
| 490 | |
| 491 DataMonitor data_monitor_; | |
| 432 }; | 492 }; |
| 433 | 493 |
| 434 | 494 |
| 435 // When running with the simulator transition into simulated execution at this | 495 // When running with the simulator transition into simulated execution at this |
| 436 // point. | 496 // point. |
| 437 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \ | 497 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \ |
| 438 reinterpret_cast<Object*>(Simulator::current(isolate)->Call( \ | 498 reinterpret_cast<Object*>(Simulator::current(isolate)->Call( \ |
| 439 FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4)) | 499 FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4)) |
| 440 | 500 |
| 441 #define CALL_GENERATED_FP_INT(isolate, entry, p0, p1) \ | 501 #define CALL_GENERATED_FP_INT(isolate, entry, p0, p1) \ |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 467 static inline void UnregisterCTryCatch(v8::internal::Isolate* isolate) { | 527 static inline void UnregisterCTryCatch(v8::internal::Isolate* isolate) { |
| 468 Simulator::current(isolate)->PopAddress(); | 528 Simulator::current(isolate)->PopAddress(); |
| 469 } | 529 } |
| 470 }; | 530 }; |
| 471 | 531 |
| 472 } // namespace internal | 532 } // namespace internal |
| 473 } // namespace v8 | 533 } // namespace v8 |
| 474 | 534 |
| 475 #endif // !defined(USE_SIMULATOR) | 535 #endif // !defined(USE_SIMULATOR) |
| 476 #endif // V8_ARM_SIMULATOR_ARM_H_ | 536 #endif // V8_ARM_SIMULATOR_ARM_H_ |
| OLD | NEW |