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

Side by Side Diff: src/d8.cc

Issue 1226143003: d8: Fix some TSAN bugs (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 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
« src/d8.h ('K') | « src/d8.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 5
6 // Defined when linking against shared lib on Windows. 6 // Defined when linking against shared lib on Windows.
7 #if defined(USING_V8_SHARED) && !defined(V8_SHARED) 7 #if defined(USING_V8_SHARED) && !defined(V8_SHARED)
8 #define V8_SHARED 8 #define V8_SHARED
9 #endif 9 #endif
10 10
(...skipping 1591 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 1602
1603 1603
1604 void SerializationDataQueue::Enqueue(SerializationData* data) { 1604 void SerializationDataQueue::Enqueue(SerializationData* data) {
1605 base::LockGuard<base::Mutex> lock_guard(&mutex_); 1605 base::LockGuard<base::Mutex> lock_guard(&mutex_);
1606 data_.Add(data); 1606 data_.Add(data);
1607 } 1607 }
1608 1608
1609 1609
1610 bool SerializationDataQueue::Dequeue(SerializationData** data) { 1610 bool SerializationDataQueue::Dequeue(SerializationData** data) {
1611 base::LockGuard<base::Mutex> lock_guard(&mutex_); 1611 base::LockGuard<base::Mutex> lock_guard(&mutex_);
1612 *data = NULL;
1612 if (data_.is_empty()) return false; 1613 if (data_.is_empty()) return false;
1613 *data = data_.Remove(0); 1614 *data = data_.Remove(0);
1614 return true; 1615 return true;
1615 } 1616 }
1616 1617
1617 1618
1618 bool SerializationDataQueue::IsEmpty() { 1619 bool SerializationDataQueue::IsEmpty() {
1619 base::LockGuard<base::Mutex> lock_guard(&mutex_); 1620 base::LockGuard<base::Mutex> lock_guard(&mutex_);
1620 return data_.is_empty(); 1621 return data_.is_empty();
1621 } 1622 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 1656
1656 void Worker::PostMessage(SerializationData* data) { 1657 void Worker::PostMessage(SerializationData* data) {
1657 in_queue_.Enqueue(data); 1658 in_queue_.Enqueue(data);
1658 in_semaphore_.Signal(); 1659 in_semaphore_.Signal();
1659 } 1660 }
1660 1661
1661 1662
1662 SerializationData* Worker::GetMessage() { 1663 SerializationData* Worker::GetMessage() {
1663 SerializationData* data = NULL; 1664 SerializationData* data = NULL;
1664 while (!out_queue_.Dequeue(&data)) { 1665 while (!out_queue_.Dequeue(&data)) {
1665 if (base::NoBarrier_Load(&state_) != RUNNING) break; 1666 // If the worker is no longer running, and there are no messages in the
1667 // queue, don't expect any more messages from it.
1668 if (base::NoBarrier_Load(&state_) > RUNNING) break;
1666 out_semaphore_.Wait(); 1669 out_semaphore_.Wait();
1667 } 1670 }
1668 1671
1669 return data; 1672 return data;
1670 } 1673 }
1671 1674
1672 1675
1673 void Worker::Terminate() { 1676 void Worker::Terminate() {
1674 if (base::NoBarrier_CompareAndSwap(&state_, RUNNING, TERMINATED) == RUNNING) { 1677 if (base::NoBarrier_CompareAndSwap(&state_, RUNNING, TERMINATING) ==
1678 RUNNING) {
1675 // Post NULL to wake the Worker thread message loop. 1679 // Post NULL to wake the Worker thread message loop.
1676 PostMessage(NULL); 1680 PostMessage(NULL);
1677 thread_->Join();
1678 } 1681 }
1679 } 1682 }
1680 1683
1681 1684
1685 void Worker::WaitForThread() {
1686 Terminate();
1687
1688 State expected_state = TERMINATING;
1689 while (true) {
1690 State actual_state = static_cast<State>(
1691 base::NoBarrier_CompareAndSwap(&state_, expected_state, JOINING));
1692
1693 if (actual_state == expected_state) break;
1694
1695 switch (actual_state) {
1696 case IDLE:
1697 case RUNNING:
1698 // We terminated above, we should never be IDLE or RUNNING.
1699 UNREACHABLE();
1700 return;
1701
1702 case TERMINATING:
1703 case STOPPED:
Jarin 2015/07/10 10:43:17 Why do we want to retry when STOPPED? Actually, I
binji 2015/07/10 17:40:46 You're right, this is too complicated. I refactore
1704 // Try again.
1705 expected_state = actual_state;
1706 break;
1707
1708 case JOINING:
Jarin 2015/07/10 10:43:17 Is not this only called when the shell finishes, s
binji 2015/07/10 17:40:46 True, this was just caution to prevent multiple jo
1709 // Someone else is joining. Bail.
1710 return;
1711
1712 case JOINED:
1713 // Tried to join twice.
1714 UNREACHABLE();
1715 return;
1716 }
1717 }
1718
1719 thread_->Join();
1720 base::NoBarrier_Store(&state_, JOINED);
1721 }
1722
1723
1682 void Worker::ExecuteInThread() { 1724 void Worker::ExecuteInThread() {
1683 Isolate::CreateParams create_params; 1725 Isolate::CreateParams create_params;
1684 create_params.array_buffer_allocator = Shell::array_buffer_allocator; 1726 create_params.array_buffer_allocator = Shell::array_buffer_allocator;
1685 Isolate* isolate = Isolate::New(create_params); 1727 Isolate* isolate = Isolate::New(create_params);
1686 { 1728 {
1687 Isolate::Scope iscope(isolate); 1729 Isolate::Scope iscope(isolate);
1688 { 1730 {
1689 HandleScope scope(isolate); 1731 HandleScope scope(isolate);
1690 PerIsolateData data(isolate); 1732 PerIsolateData data(isolate);
1691 Local<Context> context = Shell::CreateEvaluationContext(isolate); 1733 Local<Context> context = Shell::CreateEvaluationContext(isolate);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1734 delete data; 1776 delete data;
1735 } 1777 }
1736 } 1778 }
1737 } 1779 }
1738 } 1780 }
1739 } 1781 }
1740 Shell::CollectGarbage(isolate); 1782 Shell::CollectGarbage(isolate);
1741 } 1783 }
1742 isolate->Dispose(); 1784 isolate->Dispose();
1743 1785
1744 if (base::NoBarrier_CompareAndSwap(&state_, RUNNING, TERMINATED) == RUNNING) { 1786 base::NoBarrier_Store(&state_, STOPPED);
1745 // Post NULL to wake the thread waiting on GetMessage() if there is one. 1787 // Post NULL to wake the thread waiting on GetMessage() if there is one.
1746 out_queue_.Enqueue(NULL); 1788 out_queue_.Enqueue(NULL);
1747 out_semaphore_.Signal(); 1789 out_semaphore_.Signal();
1748 }
1749 } 1790 }
1750 1791
1751 1792
1752 void Worker::Cleanup() { 1793 void Worker::Cleanup() {
1753 delete thread_; 1794 delete thread_;
1754 thread_ = NULL; 1795 thread_ = NULL;
1755 delete[] script_; 1796 delete[] script_;
1756 script_ = NULL; 1797 script_ = NULL;
1757 in_queue_.Clear(); 1798 in_queue_.Clear();
1758 out_queue_.Clear(); 1799 out_queue_.Clear();
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
2136 result = True(isolate); 2177 result = True(isolate);
2137 break; 2178 break;
2138 case kSerializationTagFalse: 2179 case kSerializationTagFalse:
2139 result = False(isolate); 2180 result = False(isolate);
2140 break; 2181 break;
2141 case kSerializationTagNumber: 2182 case kSerializationTagNumber:
2142 result = Number::New(isolate, data.Read<double>(offset)); 2183 result = Number::New(isolate, data.Read<double>(offset));
2143 break; 2184 break;
2144 case kSerializationTagString: { 2185 case kSerializationTagString: {
2145 int length = data.Read<int>(offset); 2186 int length = data.Read<int>(offset);
2146 static char s_buffer[128]; 2187 char* p = new char[length];
binji 2015/07/09 00:13:12 I'm pretty ashamed of this one... :-|
Jarin 2015/07/10 10:43:17 How about using std::vector<char> here, instead of
binji 2015/07/10 17:40:46 Done (though I was not sure that std containers we
2147 char* p = s_buffer;
2148 bool allocated = false;
2149 if (length > static_cast<int>(sizeof(s_buffer))) {
2150 p = new char[length];
2151 allocated = true;
2152 }
2153 data.ReadMemory(p, length, offset); 2188 data.ReadMemory(p, length, offset);
2154 MaybeLocal<String> str = 2189 MaybeLocal<String> str =
2155 String::NewFromUtf8(isolate, p, String::kNormalString, length); 2190 String::NewFromUtf8(isolate, p, String::kNormalString, length);
2156 if (!str.IsEmpty()) result = str.ToLocalChecked(); 2191 if (!str.IsEmpty()) result = str.ToLocalChecked();
2157 if (allocated) delete[] p; 2192 delete[] p;
2158 break; 2193 break;
2159 } 2194 }
2160 case kSerializationTagArray: { 2195 case kSerializationTagArray: {
2161 uint32_t length = data.Read<uint32_t>(offset); 2196 uint32_t length = data.Read<uint32_t>(offset);
2162 Handle<Array> array = Array::New(isolate, length); 2197 Handle<Array> array = Array::New(isolate, length);
2163 for (uint32_t i = 0; i < length; ++i) { 2198 for (uint32_t i = 0; i < length; ++i) {
2164 Local<Value> element_value; 2199 Local<Value> element_value;
2165 CHECK(DeserializeValue(isolate, data, offset).ToLocal(&element_value)); 2200 CHECK(DeserializeValue(isolate, data, offset).ToLocal(&element_value));
2166 array->Set(i, element_value); 2201 array->Set(i, element_value);
2167 } 2202 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2219 i::List<Worker*> workers_copy; 2254 i::List<Worker*> workers_copy;
2220 { 2255 {
2221 base::LockGuard<base::Mutex> lock_guard(&workers_mutex_); 2256 base::LockGuard<base::Mutex> lock_guard(&workers_mutex_);
2222 allow_new_workers_ = false; 2257 allow_new_workers_ = false;
2223 workers_copy.AddAll(workers_); 2258 workers_copy.AddAll(workers_);
2224 workers_.Clear(); 2259 workers_.Clear();
2225 } 2260 }
2226 2261
2227 for (int i = 0; i < workers_copy.length(); ++i) { 2262 for (int i = 0; i < workers_copy.length(); ++i) {
2228 Worker* worker = workers_copy[i]; 2263 Worker* worker = workers_copy[i];
2229 worker->Terminate(); 2264 worker->WaitForThread();
2230 delete worker; 2265 delete worker;
2231 } 2266 }
2232 2267
2233 // Now that all workers are terminated, we can re-enable Worker creation. 2268 // Now that all workers are terminated, we can re-enable Worker creation.
Jarin 2015/07/10 10:43:17 I know this has not be introduced by this CL, but
2234 { 2269 {
2235 base::LockGuard<base::Mutex> lock_guard(&workers_mutex_); 2270 base::LockGuard<base::Mutex> lock_guard(&workers_mutex_);
2236 allow_new_workers_ = true; 2271 allow_new_workers_ = true;
2237 } 2272 }
2238 2273
2239 for (int i = 0; i < externalized_shared_contents_.length(); ++i) { 2274 for (int i = 0; i < externalized_shared_contents_.length(); ++i) {
2240 const SharedArrayBuffer::Contents& contents = 2275 const SharedArrayBuffer::Contents& contents =
2241 externalized_shared_contents_[i]; 2276 externalized_shared_contents_[i];
2242 Shell::array_buffer_allocator->Free(contents.Data(), contents.ByteLength()); 2277 Shell::array_buffer_allocator->Free(contents.Data(), contents.ByteLength());
2243 } 2278 }
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
2436 } 2471 }
2437 2472
2438 } // namespace v8 2473 } // namespace v8
2439 2474
2440 2475
2441 #ifndef GOOGLE3 2476 #ifndef GOOGLE3
2442 int main(int argc, char* argv[]) { 2477 int main(int argc, char* argv[]) {
2443 return v8::Shell::Main(argc, argv); 2478 return v8::Shell::Main(argc, argv);
2444 } 2479 }
2445 #endif 2480 #endif
OLDNEW
« src/d8.h ('K') | « src/d8.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698