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 |