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

Side by Side Diff: runtime/vm/simulator_mips.cc

Issue 677193002: - Use the simulator to do atomic operations that could also (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/simulator_mips.h ('k') | runtime/vm/vm_sources.gypi » ('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 (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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> 5 #include <setjmp.h>
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_MIPS) 9 #if defined(TARGET_ARCH_MIPS)
10 10
11 // Only build the simulator if not compiling for real MIPS hardware. 11 // Only build the simulator if not compiling for real MIPS hardware.
12 #if !defined(HOST_ARCH_MIPS) 12 #if !defined(HOST_ARCH_MIPS)
13 13
14 #include "vm/simulator.h" 14 #include "vm/simulator.h"
15 15
16 #include "vm/assembler.h" 16 #include "vm/assembler.h"
17 #include "vm/constants_mips.h" 17 #include "vm/constants_mips.h"
18 #include "vm/disassembler.h" 18 #include "vm/disassembler.h"
19 #include "vm/lockers.h"
19 #include "vm/native_arguments.h" 20 #include "vm/native_arguments.h"
20 #include "vm/thread.h" 21 #include "vm/thread.h"
21 22
22 namespace dart { 23 namespace dart {
23 24
24 DEFINE_FLAG(bool, trace_sim, false, "Trace simulator execution."); 25 DEFINE_FLAG(bool, trace_sim, false, "Trace simulator execution.");
25 DEFINE_FLAG(int, stop_sim_at, 0, "Address to stop simulator at."); 26 DEFINE_FLAG(int, stop_sim_at, 0, "Address to stop simulator at.");
26 27
27 28
28 // This macro provides a platform independent use of sscanf. The reason for 29 // This macro provides a platform independent use of sscanf. The reason for
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 // Copy the newly read line into the result. 552 // Copy the newly read line into the result.
552 memmove(result + offset, line_buf, len); 553 memmove(result + offset, line_buf, len);
553 offset += len; 554 offset += len;
554 } 555 }
555 ASSERT(result != NULL); 556 ASSERT(result != NULL);
556 result[offset] = '\0'; 557 result[offset] = '\0';
557 return result; 558 return result;
558 } 559 }
559 560
560 561
562 // Synchronization primitives support.
563 Mutex* Simulator::exclusive_access_lock_ = NULL;
564 Simulator::AddressTag Simulator::exclusive_access_state_[kNumAddressTags] =
565 {{NULL, 0}};
566 int Simulator::next_address_tag_ = 0;
567
568
561 void Simulator::InitOnce() { 569 void Simulator::InitOnce() {
570 // Setup exclusive access state lock.
571 exclusive_access_lock_ = new Mutex();
562 } 572 }
563 573
564 574
565 Simulator::Simulator() { 575 Simulator::Simulator() {
566 // Setup simulator support first. Some of this information is needed to 576 // Setup simulator support first. Some of this information is needed to
567 // setup the architecture state. 577 // setup the architecture state.
568 // We allocate the stack here, the size is computed as the sum of 578 // We allocate the stack here, the size is computed as the sum of
569 // the size specified by the user and the buffer space needed for 579 // the size specified by the user and the buffer space needed for
570 // handling stack overflow exceptions. To be safe in potential 580 // handling stack overflow exceptions. To be safe in potential
571 // stack underflows we also add some underflow buffer space. 581 // stack underflows we also add some underflow buffer space.
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 void Simulator::WriteD(uword addr, double value, Instr* instr) { 946 void Simulator::WriteD(uword addr, double value, Instr* instr) {
937 if ((addr & 7) == 0) { 947 if ((addr & 7) == 0) {
938 double* ptr = reinterpret_cast<double*>(addr); 948 double* ptr = reinterpret_cast<double*>(addr);
939 *ptr = value; 949 *ptr = value;
940 return; 950 return;
941 } 951 }
942 UnalignedAccess("double-precision floating point write", addr, instr); 952 UnalignedAccess("double-precision floating point write", addr, instr);
943 } 953 }
944 954
945 955
956 // Synchronization primitives support.
957 void Simulator::SetExclusiveAccess(uword addr) {
958 Isolate* isolate = Isolate::Current();
959 ASSERT(isolate != NULL);
960 ASSERT(exclusive_access_lock_->Owner() == isolate);
961 int i = 0;
962 // Find an entry for this isolate in the exclusive access state.
963 while ((i < kNumAddressTags) &&
964 (exclusive_access_state_[i].isolate != isolate)) {
965 i++;
966 }
967 // Round-robin replacement of previously used entries.
968 if (i == kNumAddressTags) {
969 i = next_address_tag_;
970 if (++next_address_tag_ == kNumAddressTags) {
971 next_address_tag_ = 0;
972 }
973 exclusive_access_state_[i].isolate = isolate;
974 }
975 // Remember the address being reserved.
976 exclusive_access_state_[i].addr = addr;
977 }
978
979
980 bool Simulator::HasExclusiveAccessAndOpen(uword addr) {
981 Isolate* isolate = Isolate::Current();
982 ASSERT(isolate != NULL);
983 ASSERT(addr != 0);
984 ASSERT(exclusive_access_lock_->Owner() == isolate);
985 bool result = false;
986 for (int i = 0; i < kNumAddressTags; i++) {
987 if (exclusive_access_state_[i].isolate == isolate) {
988 // Check whether the current isolates address reservation matches.
989 if (exclusive_access_state_[i].addr == addr) {
990 result = true;
991 }
992 exclusive_access_state_[i].addr = 0;
993 } else if (exclusive_access_state_[i].addr == addr) {
994 // Other isolates with matching address lose their reservations.
995 exclusive_access_state_[i].addr = 0;
996 }
997 }
998 return result;
999 }
1000
1001
1002 void Simulator::ClearExclusive() {
1003 MutexLocker ml(exclusive_access_lock_);
1004 // Remove the reservation for this isolate.
1005 SetExclusiveAccess(NULL);
1006 }
1007
1008
1009 intptr_t Simulator::ReadExclusiveW(uword addr, Instr* instr) {
1010 MutexLocker ml(exclusive_access_lock_);
1011 SetExclusiveAccess(addr);
1012 return ReadW(addr, instr);
1013 }
1014
1015
1016 intptr_t Simulator::WriteExclusiveW(uword addr, intptr_t value, Instr* instr) {
1017 MutexLocker ml(exclusive_access_lock_);
1018 bool write_allowed = HasExclusiveAccessAndOpen(addr);
1019 if (write_allowed) {
1020 WriteW(addr, value, instr);
1021 return 0; // Success.
1022 }
1023 return 1; // Failure.
1024 }
1025
1026
1027 uword Simulator::CompareExchange(uword* address,
1028 uword compare_value,
1029 uword new_value) {
1030 MutexLocker ml(exclusive_access_lock_);
1031 // We do not get a reservation as it would be guaranteed to be found when
1032 // writing below. No other isolate is able to make a reservation while we
1033 // hold the lock.
1034 uword value = *address;
1035 if (value == compare_value) {
1036 *address = new_value;
1037 // Same effect on exclusive access state as a successful SC.
1038 HasExclusiveAccessAndOpen(reinterpret_cast<uword>(address));
1039 } else {
1040 // Same effect on exclusive access state as an LL.
1041 SetExclusiveAccess(reinterpret_cast<uword>(address));
1042 }
1043 return value;
1044 }
1045
1046
946 bool Simulator::OverflowFrom(int32_t alu_out, 1047 bool Simulator::OverflowFrom(int32_t alu_out,
947 int32_t left, int32_t right, bool addition) { 1048 int32_t left, int32_t right, bool addition) {
948 bool overflow; 1049 bool overflow;
949 if (addition) { 1050 if (addition) {
950 // Operands have the same sign. 1051 // Operands have the same sign.
951 overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0)) 1052 overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0))
952 // And operands and result have different sign. 1053 // And operands and result have different sign.
953 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); 1054 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
954 } else { 1055 } else {
955 // Operands have different signs. 1056 // Operands have different signs.
(...skipping 1292 matching lines...) Expand 10 before | Expand all | Expand 10 after
2248 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); 2349 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception));
2249 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); 2350 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace));
2250 buf->Longjmp(); 2351 buf->Longjmp();
2251 } 2352 }
2252 2353
2253 } // namespace dart 2354 } // namespace dart
2254 2355
2255 #endif // !defined(HOST_ARCH_MIPS) 2356 #endif // !defined(HOST_ARCH_MIPS)
2256 2357
2257 #endif // defined TARGET_ARCH_MIPS 2358 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/simulator_mips.h ('k') | runtime/vm/vm_sources.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698