Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(155)

Side by Side Diff: src/arm64/simulator-arm64.cc

Issue 2720133003: Revert of [Atomics] Implement ldaxr/stlxr instructions in ARM64 simulator (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/arm64/simulator-arm64.h ('k') | test/cctest/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include <stdlib.h> 5 #include <stdlib.h>
6 #include <cmath> 6 #include <cmath>
7 #include <cstdarg> 7 #include <cstdarg>
8 8
9 #if V8_TARGET_ARCH_ARM64 9 #if V8_TARGET_ARCH_ARM64
10 10
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 TEXT_COLOUR clr_flag_value = FLAG_log_colour ? COLOUR(NORMAL) : ""; 48 TEXT_COLOUR clr_flag_value = FLAG_log_colour ? COLOUR(NORMAL) : "";
49 TEXT_COLOUR clr_reg_name = FLAG_log_colour ? COLOUR_BOLD(CYAN) : ""; 49 TEXT_COLOUR clr_reg_name = FLAG_log_colour ? COLOUR_BOLD(CYAN) : "";
50 TEXT_COLOUR clr_reg_value = FLAG_log_colour ? COLOUR(CYAN) : ""; 50 TEXT_COLOUR clr_reg_value = FLAG_log_colour ? COLOUR(CYAN) : "";
51 TEXT_COLOUR clr_fpreg_name = FLAG_log_colour ? COLOUR_BOLD(MAGENTA) : ""; 51 TEXT_COLOUR clr_fpreg_name = FLAG_log_colour ? COLOUR_BOLD(MAGENTA) : "";
52 TEXT_COLOUR clr_fpreg_value = FLAG_log_colour ? COLOUR(MAGENTA) : ""; 52 TEXT_COLOUR clr_fpreg_value = FLAG_log_colour ? COLOUR(MAGENTA) : "";
53 TEXT_COLOUR clr_memory_address = FLAG_log_colour ? COLOUR_BOLD(BLUE) : ""; 53 TEXT_COLOUR clr_memory_address = FLAG_log_colour ? COLOUR_BOLD(BLUE) : "";
54 TEXT_COLOUR clr_debug_number = FLAG_log_colour ? COLOUR_BOLD(YELLOW) : ""; 54 TEXT_COLOUR clr_debug_number = FLAG_log_colour ? COLOUR_BOLD(YELLOW) : "";
55 TEXT_COLOUR clr_debug_message = FLAG_log_colour ? COLOUR(YELLOW) : ""; 55 TEXT_COLOUR clr_debug_message = FLAG_log_colour ? COLOUR(YELLOW) : "";
56 TEXT_COLOUR clr_printf = FLAG_log_colour ? COLOUR(GREEN) : ""; 56 TEXT_COLOUR clr_printf = FLAG_log_colour ? COLOUR(GREEN) : "";
57 57
58 // static
59 base::LazyInstance<Simulator::GlobalMonitor>::type Simulator::global_monitor_ =
60 LAZY_INSTANCE_INITIALIZER;
61 58
62 // This is basically the same as PrintF, with a guard for FLAG_trace_sim. 59 // This is basically the same as PrintF, with a guard for FLAG_trace_sim.
63 void Simulator::TraceSim(const char* format, ...) { 60 void Simulator::TraceSim(const char* format, ...) {
64 if (FLAG_trace_sim) { 61 if (FLAG_trace_sim) {
65 va_list arguments; 62 va_list arguments;
66 va_start(arguments, format); 63 va_start(arguments, format);
67 base::OS::VFPrint(stream_, format, arguments); 64 base::OS::VFPrint(stream_, format, arguments);
68 va_end(arguments); 65 va_end(arguments);
69 } 66 }
70 } 67 }
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 // Returning to address 0 exits the Simulator. 422 // Returning to address 0 exits the Simulator.
426 set_lr(kEndOfSimAddress); 423 set_lr(kEndOfSimAddress);
427 424
428 // Reset debug helpers. 425 // Reset debug helpers.
429 breakpoints_.empty(); 426 breakpoints_.empty();
430 break_on_next_ = false; 427 break_on_next_ = false;
431 } 428 }
432 429
433 430
434 Simulator::~Simulator() { 431 Simulator::~Simulator() {
435 global_monitor_.Pointer()->RemoveProcessor(&global_monitor_processor_);
436 delete[] reinterpret_cast<byte*>(stack_); 432 delete[] reinterpret_cast<byte*>(stack_);
437 if (FLAG_log_instruction_stats) { 433 if (FLAG_log_instruction_stats) {
438 delete instrument_; 434 delete instrument_;
439 } 435 }
440 delete disassembler_decoder_; 436 delete disassembler_decoder_;
441 delete print_disasm_; 437 delete print_disasm_;
442 DeleteArray(last_debugger_input_); 438 DeleteArray(last_debugger_input_);
443 delete decoder_; 439 delete decoder_;
444 } 440 }
445 441
(...skipping 1179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1625 1621
1626 1622
1627 void Simulator::LoadStoreHelper(Instruction* instr, 1623 void Simulator::LoadStoreHelper(Instruction* instr,
1628 int64_t offset, 1624 int64_t offset,
1629 AddrMode addrmode) { 1625 AddrMode addrmode) {
1630 unsigned srcdst = instr->Rt(); 1626 unsigned srcdst = instr->Rt();
1631 unsigned addr_reg = instr->Rn(); 1627 unsigned addr_reg = instr->Rn();
1632 uintptr_t address = LoadStoreAddress(addr_reg, offset, addrmode); 1628 uintptr_t address = LoadStoreAddress(addr_reg, offset, addrmode);
1633 uintptr_t stack = 0; 1629 uintptr_t stack = 0;
1634 1630
1635 base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex);
1636 if (instr->IsLoad()) {
1637 local_monitor_.NotifyLoad(address);
1638 } else {
1639 local_monitor_.NotifyStore(address);
1640 global_monitor_.Pointer()->NotifyStore_Locked(address,
1641 &global_monitor_processor_);
1642 }
1643
1644 // Handle the writeback for stores before the store. On a CPU the writeback 1631 // Handle the writeback for stores before the store. On a CPU the writeback
1645 // and the store are atomic, but when running on the simulator it is possible 1632 // and the store are atomic, but when running on the simulator it is possible
1646 // to be interrupted in between. The simulator is not thread safe and V8 does 1633 // to be interrupted in between. The simulator is not thread safe and V8 does
1647 // not require it to be to run JavaScript therefore the profiler may sample 1634 // not require it to be to run JavaScript therefore the profiler may sample
1648 // the "simulated" CPU in the middle of load/store with writeback. The code 1635 // the "simulated" CPU in the middle of load/store with writeback. The code
1649 // below ensures that push operations are safe even when interrupted: the 1636 // below ensures that push operations are safe even when interrupted: the
1650 // stack pointer will be decremented before adding an element to the stack. 1637 // stack pointer will be decremented before adding an element to the stack.
1651 if (instr->IsStore()) { 1638 if (instr->IsStore()) {
1652 LoadStoreWriteBack(addr_reg, offset, addrmode); 1639 LoadStoreWriteBack(addr_reg, offset, addrmode);
1653 1640
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1736 AddrMode addrmode) { 1723 AddrMode addrmode) {
1737 unsigned rt = instr->Rt(); 1724 unsigned rt = instr->Rt();
1738 unsigned rt2 = instr->Rt2(); 1725 unsigned rt2 = instr->Rt2();
1739 unsigned addr_reg = instr->Rn(); 1726 unsigned addr_reg = instr->Rn();
1740 size_t access_size = 1 << instr->SizeLSPair(); 1727 size_t access_size = 1 << instr->SizeLSPair();
1741 int64_t offset = instr->ImmLSPair() * access_size; 1728 int64_t offset = instr->ImmLSPair() * access_size;
1742 uintptr_t address = LoadStoreAddress(addr_reg, offset, addrmode); 1729 uintptr_t address = LoadStoreAddress(addr_reg, offset, addrmode);
1743 uintptr_t address2 = address + access_size; 1730 uintptr_t address2 = address + access_size;
1744 uintptr_t stack = 0; 1731 uintptr_t stack = 0;
1745 1732
1746 base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex);
1747 if (instr->IsLoad()) {
1748 local_monitor_.NotifyLoad(address);
1749 local_monitor_.NotifyLoad(address2);
1750 } else {
1751 local_monitor_.NotifyStore(address);
1752 local_monitor_.NotifyStore(address2);
1753 global_monitor_.Pointer()->NotifyStore_Locked(address,
1754 &global_monitor_processor_);
1755 global_monitor_.Pointer()->NotifyStore_Locked(address2,
1756 &global_monitor_processor_);
1757 }
1758
1759 // Handle the writeback for stores before the store. On a CPU the writeback 1733 // Handle the writeback for stores before the store. On a CPU the writeback
1760 // and the store are atomic, but when running on the simulator it is possible 1734 // and the store are atomic, but when running on the simulator it is possible
1761 // to be interrupted in between. The simulator is not thread safe and V8 does 1735 // to be interrupted in between. The simulator is not thread safe and V8 does
1762 // not require it to be to run JavaScript therefore the profiler may sample 1736 // not require it to be to run JavaScript therefore the profiler may sample
1763 // the "simulated" CPU in the middle of load/store with writeback. The code 1737 // the "simulated" CPU in the middle of load/store with writeback. The code
1764 // below ensures that push operations are safe even when interrupted: the 1738 // below ensures that push operations are safe even when interrupted: the
1765 // stack pointer will be decremented before adding an element to the stack. 1739 // stack pointer will be decremented before adding an element to the stack.
1766 if (instr->IsStore()) { 1740 if (instr->IsStore()) {
1767 LoadStoreWriteBack(addr_reg, offset, addrmode); 1741 LoadStoreWriteBack(addr_reg, offset, addrmode);
1768 1742
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1872 // Accesses below the stack pointer (but above the platform stack limit) are 1846 // Accesses below the stack pointer (but above the platform stack limit) are
1873 // not allowed in the ABI. 1847 // not allowed in the ABI.
1874 CheckMemoryAccess(address, stack); 1848 CheckMemoryAccess(address, stack);
1875 } 1849 }
1876 1850
1877 1851
1878 void Simulator::VisitLoadLiteral(Instruction* instr) { 1852 void Simulator::VisitLoadLiteral(Instruction* instr) {
1879 uintptr_t address = instr->LiteralAddress(); 1853 uintptr_t address = instr->LiteralAddress();
1880 unsigned rt = instr->Rt(); 1854 unsigned rt = instr->Rt();
1881 1855
1882 base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex);
1883 local_monitor_.NotifyLoad(address);
1884
1885 switch (instr->Mask(LoadLiteralMask)) { 1856 switch (instr->Mask(LoadLiteralMask)) {
1886 // Use _no_log variants to suppress the register trace (LOG_REGS, 1857 // Use _no_log variants to suppress the register trace (LOG_REGS,
1887 // LOG_FP_REGS), then print a more detailed log. 1858 // LOG_FP_REGS), then print a more detailed log.
1888 case LDR_w_lit: 1859 case LDR_w_lit:
1889 set_wreg_no_log(rt, MemoryRead<uint32_t>(address)); 1860 set_wreg_no_log(rt, MemoryRead<uint32_t>(address));
1890 LogRead(address, kWRegSize, rt); 1861 LogRead(address, kWRegSize, rt);
1891 break; 1862 break;
1892 case LDR_x_lit: 1863 case LDR_x_lit:
1893 set_xreg_no_log(rt, MemoryRead<uint64_t>(address)); 1864 set_xreg_no_log(rt, MemoryRead<uint64_t>(address));
1894 LogRead(address, kXRegSize, rt); 1865 LogRead(address, kXRegSize, rt);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1928 void Simulator::LoadStoreWriteBack(unsigned addr_reg, 1899 void Simulator::LoadStoreWriteBack(unsigned addr_reg,
1929 int64_t offset, 1900 int64_t offset,
1930 AddrMode addrmode) { 1901 AddrMode addrmode) {
1931 if ((addrmode == PreIndex) || (addrmode == PostIndex)) { 1902 if ((addrmode == PreIndex) || (addrmode == PostIndex)) {
1932 DCHECK(offset != 0); 1903 DCHECK(offset != 0);
1933 uint64_t address = xreg(addr_reg, Reg31IsStackPointer); 1904 uint64_t address = xreg(addr_reg, Reg31IsStackPointer);
1934 set_reg(addr_reg, address + offset, Reg31IsStackPointer); 1905 set_reg(addr_reg, address + offset, Reg31IsStackPointer);
1935 } 1906 }
1936 } 1907 }
1937 1908
1938 Simulator::TransactionSize Simulator::get_transaction_size(unsigned size) {
1939 switch (size) {
1940 case 0:
1941 return TransactionSize::None;
1942 case 1:
1943 return TransactionSize::Byte;
1944 case 2:
1945 return TransactionSize::HalfWord;
1946 case 4:
1947 return TransactionSize::Word;
1948 default:
1949 UNREACHABLE();
1950 }
1951 return TransactionSize::None;
1952 }
1953
1954 void Simulator::VisitLoadStoreAcquireRelease(Instruction* instr) { 1909 void Simulator::VisitLoadStoreAcquireRelease(Instruction* instr) {
1955 unsigned rs = instr->Rs(); 1910 // TODO(binji)
1956 unsigned rt = instr->Rt();
1957 unsigned rn = instr->Rn();
1958 LoadStoreAcquireReleaseOp op = static_cast<LoadStoreAcquireReleaseOp>(
1959 instr->Mask(LoadStoreAcquireReleaseMask));
1960 int32_t is_acquire_release = instr->LoadStoreXAcquireRelease();
1961 int32_t is_not_exclusive = instr->LoadStoreXNotExclusive();
1962 int32_t is_load = instr->LoadStoreXLoad();
1963 int32_t is_pair = instr->LoadStoreXPair();
1964 DCHECK_NE(is_acquire_release, 0);
1965 DCHECK_EQ(is_not_exclusive, 0); // Non exclusive unimplemented.
1966 DCHECK_EQ(is_pair, 0); // Pair unimplemented.
1967 unsigned access_size = 1 << instr->LoadStoreXSizeLog2();
1968 uintptr_t address = LoadStoreAddress(rn, 0, AddrMode::Offset);
1969 DCHECK(address % access_size == 0);
1970 base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex);
1971 if (is_load != 0) {
1972 local_monitor_.NotifyLoadExcl(address, get_transaction_size(access_size));
1973 global_monitor_.Pointer()->NotifyLoadExcl_Locked(
1974 address, &global_monitor_processor_);
1975 switch (op) {
1976 case LDAXR_b:
1977 set_wreg_no_log(rt, MemoryRead<uint8_t>(address));
1978 break;
1979 case LDAXR_h:
1980 set_wreg_no_log(rt, MemoryRead<uint16_t>(address));
1981 break;
1982 case LDAXR_w:
1983 set_wreg_no_log(rt, MemoryRead<uint32_t>(address));
1984 break;
1985 default:
1986 UNIMPLEMENTED();
1987 }
1988 LogRead(address, access_size, rt);
1989 } else {
1990 if (local_monitor_.NotifyStoreExcl(address,
1991 get_transaction_size(access_size)) &&
1992 global_monitor_.Pointer()->NotifyStoreExcl_Locked(
1993 address, &global_monitor_processor_)) {
1994 switch (op) {
1995 case STLXR_b:
1996 MemoryWrite<uint8_t>(address, wreg(rt));
1997 break;
1998 case STLXR_h:
1999 MemoryWrite<uint16_t>(address, wreg(rt));
2000 break;
2001 case STLXR_w:
2002 MemoryWrite<uint32_t>(address, wreg(rt));
2003 break;
2004 default:
2005 UNIMPLEMENTED();
2006 }
2007 LogWrite(address, access_size, rt);
2008 set_wreg(rs, 0);
2009 } else {
2010 set_wreg(rs, 1);
2011 }
2012 }
2013 } 1911 }
2014 1912
2015 void Simulator::CheckMemoryAccess(uintptr_t address, uintptr_t stack) { 1913 void Simulator::CheckMemoryAccess(uintptr_t address, uintptr_t stack) {
2016 if ((address >= stack_limit_) && (address < stack)) { 1914 if ((address >= stack_limit_) && (address < stack)) {
2017 fprintf(stream_, "ACCESS BELOW STACK POINTER:\n"); 1915 fprintf(stream_, "ACCESS BELOW STACK POINTER:\n");
2018 fprintf(stream_, " sp is here: 0x%016" PRIx64 "\n", 1916 fprintf(stream_, " sp is here: 0x%016" PRIx64 "\n",
2019 static_cast<uint64_t>(stack)); 1917 static_cast<uint64_t>(stack));
2020 fprintf(stream_, " access was here: 0x%016" PRIx64 "\n", 1918 fprintf(stream_, " access was here: 0x%016" PRIx64 "\n",
2021 static_cast<uint64_t>(address)); 1919 static_cast<uint64_t>(address));
2022 fprintf(stream_, " stack limit is here: 0x%016" PRIx64 "\n", 1920 fprintf(stream_, " stack limit is here: 0x%016" PRIx64 "\n",
(...skipping 1949 matching lines...) Expand 10 before | Expand all | Expand 10 after
3972 3870
3973 // The printf parameters are inlined in the code, so skip them. 3871 // The printf parameters are inlined in the code, so skip them.
3974 set_pc(instr->InstructionAtOffset(kPrintfLength)); 3872 set_pc(instr->InstructionAtOffset(kPrintfLength));
3975 3873
3976 // Set LR as if we'd just called a native printf function. 3874 // Set LR as if we'd just called a native printf function.
3977 set_lr(pc()); 3875 set_lr(pc());
3978 3876
3979 delete[] format; 3877 delete[] format;
3980 } 3878 }
3981 3879
3982 Simulator::LocalMonitor::LocalMonitor()
3983 : access_state_(MonitorAccess::Open),
3984 tagged_addr_(0),
3985 size_(TransactionSize::None) {}
3986
3987 void Simulator::LocalMonitor::Clear() {
3988 access_state_ = MonitorAccess::Open;
3989 tagged_addr_ = 0;
3990 size_ = TransactionSize::None;
3991 }
3992
3993 void Simulator::LocalMonitor::NotifyLoad(uintptr_t addr) {
3994 if (access_state_ == MonitorAccess::Exclusive) {
3995 // A non exclusive load could clear the local monitor. As a result, it's
3996 // most strict to unconditionally clear the local monitor on load.
3997 Clear();
3998 }
3999 }
4000
4001 void Simulator::LocalMonitor::NotifyLoadExcl(uintptr_t addr,
4002 TransactionSize size) {
4003 access_state_ = MonitorAccess::Exclusive;
4004 tagged_addr_ = addr;
4005 size_ = size;
4006 }
4007
4008 void Simulator::LocalMonitor::NotifyStore(uintptr_t addr) {
4009 if (access_state_ == MonitorAccess::Exclusive) {
4010 // A non exclusive store could clear the local monitor. As a result, it's
4011 // most strict to unconditionally clear the local monitor on store.
4012 Clear();
4013 }
4014 }
4015
4016 bool Simulator::LocalMonitor::NotifyStoreExcl(uintptr_t addr,
4017 TransactionSize size) {
4018 if (access_state_ == MonitorAccess::Exclusive) {
4019 // It is allowed for a processor to require that the address matches
4020 // exactly (B2.10.1), so this comparison does not mask addr.
4021 if (addr == tagged_addr_ && size_ == size) {
4022 Clear();
4023 return true;
4024 } else {
4025 // It is implementation-defined whether an exclusive store to a
4026 // non-tagged address will update memory. As a result, it's most strict
4027 // to unconditionally clear the local monitor.
4028 Clear();
4029 return false;
4030 }
4031 } else {
4032 DCHECK(access_state_ == MonitorAccess::Open);
4033 return false;
4034 }
4035 }
4036
4037 Simulator::GlobalMonitor::Processor::Processor()
4038 : access_state_(MonitorAccess::Open),
4039 tagged_addr_(0),
4040 next_(nullptr),
4041 prev_(nullptr),
4042 failure_counter_(0) {}
4043
4044 void Simulator::GlobalMonitor::Processor::Clear_Locked() {
4045 access_state_ = MonitorAccess::Open;
4046 tagged_addr_ = 0;
4047 }
4048
4049 void Simulator::GlobalMonitor::Processor::NotifyLoadExcl_Locked(
4050 uintptr_t addr) {
4051 access_state_ = MonitorAccess::Exclusive;
4052 tagged_addr_ = addr;
4053 }
4054
4055 void Simulator::GlobalMonitor::Processor::NotifyStore_Locked(
4056 uintptr_t addr, bool is_requesting_processor) {
4057 if (access_state_ == MonitorAccess::Exclusive) {
4058 // A non exclusive store could clear the global monitor. As a result, it's
4059 // most strict to unconditionally clear global monitors on store.
4060 Clear_Locked();
4061 }
4062 }
4063
4064 bool Simulator::GlobalMonitor::Processor::NotifyStoreExcl_Locked(
4065 uintptr_t addr, bool is_requesting_processor) {
4066 if (access_state_ == MonitorAccess::Exclusive) {
4067 if (is_requesting_processor) {
4068 // It is allowed for a processor to require that the address matches
4069 // exactly (B2.10.2), so this comparison does not mask addr.
4070 if (addr == tagged_addr_) {
4071 Clear_Locked();
4072 // Introduce occasional stxr failures. This is to simulate the
4073 // behavior of hardware, which can randomly fail due to background
4074 // cache evictions.
4075 if (failure_counter_++ >= kMaxFailureCounter) {
4076 failure_counter_ = 0;
4077 return false;
4078 } else {
4079 return true;
4080 }
4081 }
4082 } else if ((addr & kExclusiveTaggedAddrMask) ==
4083 (tagged_addr_ & kExclusiveTaggedAddrMask)) {
4084 // Check the masked addresses when responding to a successful lock by
4085 // another processor so the implementation is more conservative (i.e. the
4086 // granularity of locking is as large as possible.)
4087 Clear_Locked();
4088 return false;
4089 }
4090 }
4091 return false;
4092 }
4093
4094 Simulator::GlobalMonitor::GlobalMonitor() : head_(nullptr) {}
4095
4096 void Simulator::GlobalMonitor::NotifyLoadExcl_Locked(uintptr_t addr,
4097 Processor* processor) {
4098 processor->NotifyLoadExcl_Locked(addr);
4099 PrependProcessor_Locked(processor);
4100 }
4101
4102 void Simulator::GlobalMonitor::NotifyStore_Locked(uintptr_t addr,
4103 Processor* processor) {
4104 // Notify each processor of the store operation.
4105 for (Processor* iter = head_; iter; iter = iter->next_) {
4106 bool is_requesting_processor = iter == processor;
4107 iter->NotifyStore_Locked(addr, is_requesting_processor);
4108 }
4109 }
4110
4111 bool Simulator::GlobalMonitor::NotifyStoreExcl_Locked(uintptr_t addr,
4112 Processor* processor) {
4113 DCHECK(IsProcessorInLinkedList_Locked(processor));
4114 if (processor->NotifyStoreExcl_Locked(addr, true)) {
4115 // Notify the other processors that this StoreExcl succeeded.
4116 for (Processor* iter = head_; iter; iter = iter->next_) {
4117 if (iter != processor) {
4118 iter->NotifyStoreExcl_Locked(addr, false);
4119 }
4120 }
4121 return true;
4122 } else {
4123 return false;
4124 }
4125 }
4126
4127 bool Simulator::GlobalMonitor::IsProcessorInLinkedList_Locked(
4128 Processor* processor) const {
4129 return head_ == processor || processor->next_ || processor->prev_;
4130 }
4131
4132 void Simulator::GlobalMonitor::PrependProcessor_Locked(Processor* processor) {
4133 if (IsProcessorInLinkedList_Locked(processor)) {
4134 return;
4135 }
4136
4137 if (head_) {
4138 head_->prev_ = processor;
4139 }
4140 processor->prev_ = nullptr;
4141 processor->next_ = head_;
4142 head_ = processor;
4143 }
4144
4145 void Simulator::GlobalMonitor::RemoveProcessor(Processor* processor) {
4146 base::LockGuard<base::Mutex> lock_guard(&mutex);
4147 if (!IsProcessorInLinkedList_Locked(processor)) {
4148 return;
4149 }
4150
4151 if (processor->prev_) {
4152 processor->prev_->next_ = processor->next_;
4153 } else {
4154 head_ = processor->next_;
4155 }
4156 if (processor->next_) {
4157 processor->next_->prev_ = processor->prev_;
4158 }
4159 processor->prev_ = nullptr;
4160 processor->next_ = nullptr;
4161 }
4162 3880
4163 #endif // USE_SIMULATOR 3881 #endif // USE_SIMULATOR
4164 3882
4165 } // namespace internal 3883 } // namespace internal
4166 } // namespace v8 3884 } // namespace v8
4167 3885
4168 #endif // V8_TARGET_ARCH_ARM64 3886 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm64/simulator-arm64.h ('k') | test/cctest/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698