| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include <setjmp.h> // NOLINT | 5 #include <setjmp.h> // NOLINT |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 | 7 |
| 8 #include "vm/globals.h" | 8 #include "vm/globals.h" |
| 9 #if defined(TARGET_ARCH_ARM64) | 9 #if defined(TARGET_ARCH_ARM64) |
| 10 | 10 |
| (...skipping 1146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1157 | 1157 |
| 1158 | 1158 |
| 1159 void Simulator::WriteB(uword addr, uint8_t value) { | 1159 void Simulator::WriteB(uword addr, uint8_t value) { |
| 1160 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); | 1160 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); |
| 1161 *ptr = value; | 1161 *ptr = value; |
| 1162 } | 1162 } |
| 1163 | 1163 |
| 1164 | 1164 |
| 1165 // Synchronization primitives support. | 1165 // Synchronization primitives support. |
| 1166 void Simulator::SetExclusiveAccess(uword addr) { | 1166 void Simulator::SetExclusiveAccess(uword addr) { |
| 1167 Isolate* isolate = Isolate::Current(); | 1167 Thread* thread = Thread::Current(); |
| 1168 ASSERT(isolate != NULL); | 1168 ASSERT(thread != NULL); |
| 1169 DEBUG_ASSERT(exclusive_access_lock_->Owner() == isolate); | 1169 DEBUG_ASSERT(exclusive_access_lock_->IsOwnedByCurrentThread()); |
| 1170 int i = 0; | 1170 int i = 0; |
| 1171 // Find an entry for this isolate in the exclusive access state. | 1171 // Find an entry for this thread in the exclusive access state. |
| 1172 while ((i < kNumAddressTags) && | 1172 while ((i < kNumAddressTags) && |
| 1173 (exclusive_access_state_[i].isolate != isolate)) { | 1173 (exclusive_access_state_[i].thread != thread)) { |
| 1174 i++; | 1174 i++; |
| 1175 } | 1175 } |
| 1176 // Round-robin replacement of previously used entries. | 1176 // Round-robin replacement of previously used entries. |
| 1177 if (i == kNumAddressTags) { | 1177 if (i == kNumAddressTags) { |
| 1178 i = next_address_tag_; | 1178 i = next_address_tag_; |
| 1179 if (++next_address_tag_ == kNumAddressTags) { | 1179 if (++next_address_tag_ == kNumAddressTags) { |
| 1180 next_address_tag_ = 0; | 1180 next_address_tag_ = 0; |
| 1181 } | 1181 } |
| 1182 exclusive_access_state_[i].isolate = isolate; | 1182 exclusive_access_state_[i].thread = thread; |
| 1183 } | 1183 } |
| 1184 // Remember the address being reserved. | 1184 // Remember the address being reserved. |
| 1185 exclusive_access_state_[i].addr = addr; | 1185 exclusive_access_state_[i].addr = addr; |
| 1186 } | 1186 } |
| 1187 | 1187 |
| 1188 | 1188 |
| 1189 bool Simulator::HasExclusiveAccessAndOpen(uword addr) { | 1189 bool Simulator::HasExclusiveAccessAndOpen(uword addr) { |
| 1190 Isolate* isolate = Isolate::Current(); | 1190 Thread* thread = Thread::Current(); |
| 1191 ASSERT(isolate != NULL); | 1191 ASSERT(thread != NULL); |
| 1192 ASSERT(addr != 0); | 1192 ASSERT(addr != 0); |
| 1193 DEBUG_ASSERT(exclusive_access_lock_->Owner() == isolate); | 1193 DEBUG_ASSERT(exclusive_access_lock_->IsOwnedByCurrentThread()); |
| 1194 bool result = false; | 1194 bool result = false; |
| 1195 for (int i = 0; i < kNumAddressTags; i++) { | 1195 for (int i = 0; i < kNumAddressTags; i++) { |
| 1196 if (exclusive_access_state_[i].isolate == isolate) { | 1196 if (exclusive_access_state_[i].thread == thread) { |
| 1197 // Check whether the current isolates address reservation matches. | 1197 // Check whether the current threads address reservation matches. |
| 1198 if (exclusive_access_state_[i].addr == addr) { | 1198 if (exclusive_access_state_[i].addr == addr) { |
| 1199 result = true; | 1199 result = true; |
| 1200 } | 1200 } |
| 1201 exclusive_access_state_[i].addr = 0; | 1201 exclusive_access_state_[i].addr = 0; |
| 1202 } else if (exclusive_access_state_[i].addr == addr) { | 1202 } else if (exclusive_access_state_[i].addr == addr) { |
| 1203 // Other isolates with matching address lose their reservations. | 1203 // Other threads with matching address lose their reservations. |
| 1204 exclusive_access_state_[i].addr = 0; | 1204 exclusive_access_state_[i].addr = 0; |
| 1205 } | 1205 } |
| 1206 } | 1206 } |
| 1207 return result; | 1207 return result; |
| 1208 } | 1208 } |
| 1209 | 1209 |
| 1210 | 1210 |
| 1211 void Simulator::ClearExclusive() { | 1211 void Simulator::ClearExclusive() { |
| 1212 MutexLocker ml(exclusive_access_lock_); | 1212 MutexLocker ml(exclusive_access_lock_); |
| 1213 // Remove the reservation for this isolate. | 1213 // Remove the reservation for this thread. |
| 1214 SetExclusiveAccess(NULL); | 1214 SetExclusiveAccess(NULL); |
| 1215 } | 1215 } |
| 1216 | 1216 |
| 1217 | 1217 |
| 1218 intptr_t Simulator::ReadExclusiveW(uword addr, Instr* instr) { | 1218 intptr_t Simulator::ReadExclusiveW(uword addr, Instr* instr) { |
| 1219 MutexLocker ml(exclusive_access_lock_); | 1219 MutexLocker ml(exclusive_access_lock_); |
| 1220 SetExclusiveAccess(addr); | 1220 SetExclusiveAccess(addr); |
| 1221 return ReadW(addr, instr); | 1221 return ReadW(addr, instr); |
| 1222 } | 1222 } |
| 1223 | 1223 |
| 1224 | 1224 |
| 1225 intptr_t Simulator::WriteExclusiveW(uword addr, intptr_t value, Instr* instr) { | 1225 intptr_t Simulator::WriteExclusiveW(uword addr, intptr_t value, Instr* instr) { |
| 1226 MutexLocker ml(exclusive_access_lock_); | 1226 MutexLocker ml(exclusive_access_lock_); |
| 1227 bool write_allowed = HasExclusiveAccessAndOpen(addr); | 1227 bool write_allowed = HasExclusiveAccessAndOpen(addr); |
| 1228 if (write_allowed) { | 1228 if (write_allowed) { |
| 1229 WriteW(addr, value, instr); | 1229 WriteW(addr, value, instr); |
| 1230 return 0; // Success. | 1230 return 0; // Success. |
| 1231 } | 1231 } |
| 1232 return 1; // Failure. | 1232 return 1; // Failure. |
| 1233 } | 1233 } |
| 1234 | 1234 |
| 1235 | 1235 |
| 1236 uword Simulator::CompareExchange(uword* address, | 1236 uword Simulator::CompareExchange(uword* address, |
| 1237 uword compare_value, | 1237 uword compare_value, |
| 1238 uword new_value) { | 1238 uword new_value) { |
| 1239 MutexLocker ml(exclusive_access_lock_); | 1239 MutexLocker ml(exclusive_access_lock_); |
| 1240 // We do not get a reservation as it would be guaranteed to be found when | 1240 // We do not get a reservation as it would be guaranteed to be found when |
| 1241 // writing below. No other isolate is able to make a reservation while we | 1241 // writing below. No other thread is able to make a reservation while we |
| 1242 // hold the lock. | 1242 // hold the lock. |
| 1243 uword value = *address; | 1243 uword value = *address; |
| 1244 if (value == compare_value) { | 1244 if (value == compare_value) { |
| 1245 *address = new_value; | 1245 *address = new_value; |
| 1246 // Same effect on exclusive access state as a successful STREX. | 1246 // Same effect on exclusive access state as a successful STREX. |
| 1247 HasExclusiveAccessAndOpen(reinterpret_cast<uword>(address)); | 1247 HasExclusiveAccessAndOpen(reinterpret_cast<uword>(address)); |
| 1248 } else { | 1248 } else { |
| 1249 // Same effect on exclusive access state as an LDREX. | 1249 // Same effect on exclusive access state as an LDREX. |
| 1250 SetExclusiveAccess(reinterpret_cast<uword>(address)); | 1250 SetExclusiveAccess(reinterpret_cast<uword>(address)); |
| 1251 } | 1251 } |
| (...skipping 2242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3494 set_register(NULL, kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); | 3494 set_register(NULL, kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); |
| 3495 set_register(NULL, kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); | 3495 set_register(NULL, kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); |
| 3496 buf->Longjmp(); | 3496 buf->Longjmp(); |
| 3497 } | 3497 } |
| 3498 | 3498 |
| 3499 } // namespace dart | 3499 } // namespace dart |
| 3500 | 3500 |
| 3501 #endif // !defined(HOST_ARCH_ARM64) | 3501 #endif // !defined(HOST_ARCH_ARM64) |
| 3502 | 3502 |
| 3503 #endif // defined TARGET_ARCH_ARM64 | 3503 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |