| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #ifndef V8_ARM64_SIMULATOR_ARM64_H_ | 5 #ifndef V8_ARM64_SIMULATOR_ARM64_H_ |
| 6 #define V8_ARM64_SIMULATOR_ARM64_H_ | 6 #define V8_ARM64_SIMULATOR_ARM64_H_ |
| 7 | 7 |
| 8 #include <stdarg.h> | 8 #include <stdarg.h> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 858 static const char* vreg_names[]; | 858 static const char* vreg_names[]; |
| 859 | 859 |
| 860 // Debugger input. | 860 // Debugger input. |
| 861 void set_last_debugger_input(char* input) { | 861 void set_last_debugger_input(char* input) { |
| 862 DeleteArray(last_debugger_input_); | 862 DeleteArray(last_debugger_input_); |
| 863 last_debugger_input_ = input; | 863 last_debugger_input_ = input; |
| 864 } | 864 } |
| 865 char* last_debugger_input() { return last_debugger_input_; } | 865 char* last_debugger_input() { return last_debugger_input_; } |
| 866 char* last_debugger_input_; | 866 char* last_debugger_input_; |
| 867 | 867 |
| 868 // Synchronization primitives. See ARM DDI 0487A.a, B2.10. Pair types not | |
| 869 // implemented. | |
| 870 enum class MonitorAccess { | |
| 871 Open, | |
| 872 Exclusive, | |
| 873 }; | |
| 874 | |
| 875 enum class TransactionSize { | |
| 876 None = 0, | |
| 877 Byte = 1, | |
| 878 HalfWord = 2, | |
| 879 Word = 4, | |
| 880 }; | |
| 881 | |
| 882 TransactionSize get_transaction_size(unsigned size); | |
| 883 | |
| 884 // The least-significant bits of the address are ignored. The number of bits | |
| 885 // is implementation-defined, between 3 and 11. See ARM DDI 0487A.a, B2.10.3. | |
| 886 static const uintptr_t kExclusiveTaggedAddrMask = ~((1 << 11) - 1); | |
| 887 | |
| 888 class LocalMonitor { | |
| 889 public: | |
| 890 LocalMonitor(); | |
| 891 | |
| 892 // These functions manage the state machine for the local monitor, but do | |
| 893 // not actually perform loads and stores. NotifyStoreExcl only returns | |
| 894 // true if the exclusive store is allowed; the global monitor will still | |
| 895 // have to be checked to see whether the memory should be updated. | |
| 896 void NotifyLoad(uintptr_t addr); | |
| 897 void NotifyLoadExcl(uintptr_t addr, TransactionSize size); | |
| 898 void NotifyStore(uintptr_t addr); | |
| 899 bool NotifyStoreExcl(uintptr_t addr, TransactionSize size); | |
| 900 | |
| 901 private: | |
| 902 void Clear(); | |
| 903 | |
| 904 MonitorAccess access_state_; | |
| 905 uintptr_t tagged_addr_; | |
| 906 TransactionSize size_; | |
| 907 }; | |
| 908 | |
| 909 class GlobalMonitor { | |
| 910 public: | |
| 911 GlobalMonitor(); | |
| 912 | |
| 913 class Processor { | |
| 914 public: | |
| 915 Processor(); | |
| 916 | |
| 917 private: | |
| 918 friend class GlobalMonitor; | |
| 919 // These functions manage the state machine for the global monitor, but do | |
| 920 // not actually perform loads and stores. | |
| 921 void Clear_Locked(); | |
| 922 void NotifyLoadExcl_Locked(uintptr_t addr); | |
| 923 void NotifyStore_Locked(uintptr_t addr, bool is_requesting_processor); | |
| 924 bool NotifyStoreExcl_Locked(uintptr_t addr, bool is_requesting_processor); | |
| 925 | |
| 926 MonitorAccess access_state_; | |
| 927 uintptr_t tagged_addr_; | |
| 928 Processor* next_; | |
| 929 Processor* prev_; | |
| 930 // A stxr can fail due to background cache evictions. Rather than | |
| 931 // simulating this, we'll just occasionally introduce cases where an | |
| 932 // exclusive store fails. This will happen once after every | |
| 933 // kMaxFailureCounter exclusive stores. | |
| 934 static const int kMaxFailureCounter = 5; | |
| 935 int failure_counter_; | |
| 936 }; | |
| 937 | |
| 938 // Exposed so it can be accessed by Simulator::{Read,Write}Ex*. | |
| 939 base::Mutex mutex; | |
| 940 | |
| 941 void NotifyLoadExcl_Locked(uintptr_t addr, Processor* processor); | |
| 942 void NotifyStore_Locked(uintptr_t addr, Processor* processor); | |
| 943 bool NotifyStoreExcl_Locked(uintptr_t addr, Processor* processor); | |
| 944 | |
| 945 // Called when the simulator is destroyed. | |
| 946 void RemoveProcessor(Processor* processor); | |
| 947 | |
| 948 private: | |
| 949 bool IsProcessorInLinkedList_Locked(Processor* processor) const; | |
| 950 void PrependProcessor_Locked(Processor* processor); | |
| 951 | |
| 952 Processor* head_; | |
| 953 }; | |
| 954 | |
| 955 LocalMonitor local_monitor_; | |
| 956 GlobalMonitor::Processor global_monitor_processor_; | |
| 957 static base::LazyInstance<GlobalMonitor>::type global_monitor_; | |
| 958 | |
| 959 private: | 868 private: |
| 960 void Init(FILE* stream); | 869 void Init(FILE* stream); |
| 961 | 870 |
| 962 int log_parameters_; | 871 int log_parameters_; |
| 963 Isolate* isolate_; | 872 Isolate* isolate_; |
| 964 }; | 873 }; |
| 965 | 874 |
| 966 | 875 |
| 967 // When running with the simulator transition into simulated execution at this | 876 // When running with the simulator transition into simulated execution at this |
| 968 // point. | 877 // point. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 997 Simulator::current(isolate)->PopAddress(); | 906 Simulator::current(isolate)->PopAddress(); |
| 998 } | 907 } |
| 999 }; | 908 }; |
| 1000 | 909 |
| 1001 #endif // !defined(USE_SIMULATOR) | 910 #endif // !defined(USE_SIMULATOR) |
| 1002 | 911 |
| 1003 } // namespace internal | 912 } // namespace internal |
| 1004 } // namespace v8 | 913 } // namespace v8 |
| 1005 | 914 |
| 1006 #endif // V8_ARM64_SIMULATOR_ARM64_H_ | 915 #endif // V8_ARM64_SIMULATOR_ARM64_H_ |
| OLD | NEW |