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 |
868 private: | 959 private: |
869 void Init(FILE* stream); | 960 void Init(FILE* stream); |
870 | 961 |
871 int log_parameters_; | 962 int log_parameters_; |
872 Isolate* isolate_; | 963 Isolate* isolate_; |
873 }; | 964 }; |
874 | 965 |
875 | 966 |
876 // When running with the simulator transition into simulated execution at this | 967 // When running with the simulator transition into simulated execution at this |
877 // point. | 968 // point. |
(...skipping 28 matching lines...) Expand all Loading... |
906 Simulator::current(isolate)->PopAddress(); | 997 Simulator::current(isolate)->PopAddress(); |
907 } | 998 } |
908 }; | 999 }; |
909 | 1000 |
910 #endif // !defined(USE_SIMULATOR) | 1001 #endif // !defined(USE_SIMULATOR) |
911 | 1002 |
912 } // namespace internal | 1003 } // namespace internal |
913 } // namespace v8 | 1004 } // namespace v8 |
914 | 1005 |
915 #endif // V8_ARM64_SIMULATOR_ARM64_H_ | 1006 #endif // V8_ARM64_SIMULATOR_ARM64_H_ |
OLD | NEW |