| OLD | NEW |
| 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 |
| 11 #include <errno.h> | 11 #include <errno.h> |
| 12 #include <stdlib.h> | 12 #include <stdlib.h> |
| 13 #include <string.h> | 13 #include <string.h> |
| 14 #include <sys/stat.h> | 14 #include <sys/stat.h> |
| 15 | 15 |
| 16 #ifdef V8_SHARED | 16 #ifdef V8_SHARED |
| 17 #include <assert.h> | 17 #include <assert.h> |
| 18 #endif // V8_SHARED | 18 #endif // V8_SHARED |
| 19 | 19 |
| 20 #ifndef V8_SHARED | 20 #ifndef V8_SHARED |
| 21 #include <algorithm> | 21 #include <algorithm> |
| 22 #include <vector> |
| 22 #endif // !V8_SHARED | 23 #endif // !V8_SHARED |
| 23 | 24 |
| 24 #ifdef V8_SHARED | 25 #ifdef V8_SHARED |
| 25 #include "include/v8-testing.h" | 26 #include "include/v8-testing.h" |
| 26 #endif // V8_SHARED | 27 #endif // V8_SHARED |
| 27 | 28 |
| 28 #if !defined(V8_SHARED) && defined(ENABLE_GDB_JIT_INTERFACE) | 29 #if !defined(V8_SHARED) && defined(ENABLE_GDB_JIT_INTERFACE) |
| 29 #include "src/gdb-jit.h" | 30 #include "src/gdb-jit.h" |
| 30 #endif | 31 #endif |
| 31 | 32 |
| (...skipping 1573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1605 | 1606 |
| 1606 | 1607 |
| 1607 void SerializationDataQueue::Enqueue(SerializationData* data) { | 1608 void SerializationDataQueue::Enqueue(SerializationData* data) { |
| 1608 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 1609 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
| 1609 data_.Add(data); | 1610 data_.Add(data); |
| 1610 } | 1611 } |
| 1611 | 1612 |
| 1612 | 1613 |
| 1613 bool SerializationDataQueue::Dequeue(SerializationData** data) { | 1614 bool SerializationDataQueue::Dequeue(SerializationData** data) { |
| 1614 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 1615 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
| 1616 *data = NULL; |
| 1615 if (data_.is_empty()) return false; | 1617 if (data_.is_empty()) return false; |
| 1616 *data = data_.Remove(0); | 1618 *data = data_.Remove(0); |
| 1617 return true; | 1619 return true; |
| 1618 } | 1620 } |
| 1619 | 1621 |
| 1620 | 1622 |
| 1621 bool SerializationDataQueue::IsEmpty() { | 1623 bool SerializationDataQueue::IsEmpty() { |
| 1622 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 1624 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
| 1623 return data_.is_empty(); | 1625 return data_.is_empty(); |
| 1624 } | 1626 } |
| 1625 | 1627 |
| 1626 | 1628 |
| 1627 void SerializationDataQueue::Clear() { | 1629 void SerializationDataQueue::Clear() { |
| 1628 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 1630 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
| 1629 for (int i = 0; i < data_.length(); ++i) { | 1631 for (int i = 0; i < data_.length(); ++i) { |
| 1630 delete data_[i]; | 1632 delete data_[i]; |
| 1631 } | 1633 } |
| 1632 data_.Clear(); | 1634 data_.Clear(); |
| 1633 } | 1635 } |
| 1634 | 1636 |
| 1635 | 1637 |
| 1636 Worker::Worker() | 1638 Worker::Worker() |
| 1637 : in_semaphore_(0), | 1639 : in_semaphore_(0), |
| 1638 out_semaphore_(0), | 1640 out_semaphore_(0), |
| 1639 thread_(NULL), | 1641 thread_(NULL), |
| 1640 script_(NULL), | 1642 script_(NULL), |
| 1641 state_(IDLE) {} | 1643 state_(IDLE), |
| 1644 join_called_(false) {} |
| 1642 | 1645 |
| 1643 | 1646 |
| 1644 Worker::~Worker() { Cleanup(); } | 1647 Worker::~Worker() { Cleanup(); } |
| 1645 | 1648 |
| 1646 | 1649 |
| 1647 void Worker::StartExecuteInThread(Isolate* isolate, const char* script) { | 1650 void Worker::StartExecuteInThread(Isolate* isolate, const char* script) { |
| 1648 if (base::NoBarrier_CompareAndSwap(&state_, IDLE, RUNNING) == IDLE) { | 1651 if (base::NoBarrier_CompareAndSwap(&state_, IDLE, RUNNING) == IDLE) { |
| 1649 script_ = i::StrDup(script); | 1652 script_ = i::StrDup(script); |
| 1650 thread_ = new WorkerThread(this); | 1653 thread_ = new WorkerThread(this); |
| 1651 thread_->Start(); | 1654 thread_->Start(); |
| 1652 } else { | 1655 } else { |
| 1653 // Somehow the Worker was started twice. | 1656 // Somehow the Worker was started twice. |
| 1654 UNREACHABLE(); | 1657 UNREACHABLE(); |
| 1655 } | 1658 } |
| 1656 } | 1659 } |
| 1657 | 1660 |
| 1658 | 1661 |
| 1659 void Worker::PostMessage(SerializationData* data) { | 1662 void Worker::PostMessage(SerializationData* data) { |
| 1660 in_queue_.Enqueue(data); | 1663 in_queue_.Enqueue(data); |
| 1661 in_semaphore_.Signal(); | 1664 in_semaphore_.Signal(); |
| 1662 } | 1665 } |
| 1663 | 1666 |
| 1664 | 1667 |
| 1665 SerializationData* Worker::GetMessage() { | 1668 SerializationData* Worker::GetMessage() { |
| 1666 SerializationData* data = NULL; | 1669 SerializationData* data = NULL; |
| 1667 while (!out_queue_.Dequeue(&data)) { | 1670 while (!out_queue_.Dequeue(&data)) { |
| 1671 // If the worker is no longer running, and there are no messages in the |
| 1672 // queue, don't expect any more messages from it. |
| 1668 if (base::NoBarrier_Load(&state_) != RUNNING) break; | 1673 if (base::NoBarrier_Load(&state_) != RUNNING) break; |
| 1669 out_semaphore_.Wait(); | 1674 out_semaphore_.Wait(); |
| 1670 } | 1675 } |
| 1671 | 1676 |
| 1672 return data; | 1677 return data; |
| 1673 } | 1678 } |
| 1674 | 1679 |
| 1675 | 1680 |
| 1676 void Worker::Terminate() { | 1681 void Worker::Terminate() { |
| 1677 if (base::NoBarrier_CompareAndSwap(&state_, RUNNING, TERMINATED) == RUNNING) { | 1682 if (base::NoBarrier_CompareAndSwap(&state_, RUNNING, TERMINATED) == RUNNING) { |
| 1678 // Post NULL to wake the Worker thread message loop. | 1683 // Post NULL to wake the Worker thread message loop, and tell it to stop |
| 1684 // running. |
| 1679 PostMessage(NULL); | 1685 PostMessage(NULL); |
| 1680 thread_->Join(); | |
| 1681 } | 1686 } |
| 1682 } | 1687 } |
| 1683 | 1688 |
| 1689 |
| 1690 void Worker::WaitForThread() { |
| 1691 Terminate(); |
| 1692 |
| 1693 if (base::NoBarrier_CompareAndSwap(&join_called_, false, true) == false) { |
| 1694 thread_->Join(); |
| 1695 } else { |
| 1696 // Tried to call join twice. |
| 1697 UNREACHABLE(); |
| 1698 } |
| 1699 } |
| 1700 |
| 1684 | 1701 |
| 1685 void Worker::ExecuteInThread() { | 1702 void Worker::ExecuteInThread() { |
| 1686 Isolate::CreateParams create_params; | 1703 Isolate::CreateParams create_params; |
| 1687 create_params.array_buffer_allocator = Shell::array_buffer_allocator; | 1704 create_params.array_buffer_allocator = Shell::array_buffer_allocator; |
| 1688 Isolate* isolate = Isolate::New(create_params); | 1705 Isolate* isolate = Isolate::New(create_params); |
| 1689 { | 1706 { |
| 1690 Isolate::Scope iscope(isolate); | 1707 Isolate::Scope iscope(isolate); |
| 1691 { | 1708 { |
| 1692 HandleScope scope(isolate); | 1709 HandleScope scope(isolate); |
| 1693 PerIsolateData data(isolate); | 1710 PerIsolateData data(isolate); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1711 // First run the script | 1728 // First run the script |
| 1712 Handle<String> file_name = String::NewFromUtf8(isolate, "unnamed"); | 1729 Handle<String> file_name = String::NewFromUtf8(isolate, "unnamed"); |
| 1713 Handle<String> source = String::NewFromUtf8(isolate, script_); | 1730 Handle<String> source = String::NewFromUtf8(isolate, script_); |
| 1714 if (Shell::ExecuteString(isolate, source, file_name, false, true)) { | 1731 if (Shell::ExecuteString(isolate, source, file_name, false, true)) { |
| 1715 // Get the message handler | 1732 // Get the message handler |
| 1716 Handle<Value> onmessage = | 1733 Handle<Value> onmessage = |
| 1717 global->Get(String::NewFromUtf8(isolate, "onmessage")); | 1734 global->Get(String::NewFromUtf8(isolate, "onmessage")); |
| 1718 if (onmessage->IsFunction()) { | 1735 if (onmessage->IsFunction()) { |
| 1719 Handle<Function> onmessage_fun = Handle<Function>::Cast(onmessage); | 1736 Handle<Function> onmessage_fun = Handle<Function>::Cast(onmessage); |
| 1720 // Now wait for messages | 1737 // Now wait for messages |
| 1721 bool done = false; | 1738 while (true) { |
| 1722 while (!done) { | |
| 1723 in_semaphore_.Wait(); | 1739 in_semaphore_.Wait(); |
| 1724 SerializationData* data; | 1740 SerializationData* data; |
| 1725 if (!in_queue_.Dequeue(&data)) continue; | 1741 if (!in_queue_.Dequeue(&data)) continue; |
| 1726 if (data == NULL) { | 1742 if (data == NULL) { |
| 1727 done = true; | |
| 1728 break; | 1743 break; |
| 1729 } | 1744 } |
| 1730 int offset = 0; | 1745 int offset = 0; |
| 1731 Local<Value> data_value; | 1746 Local<Value> data_value; |
| 1732 if (Shell::DeserializeValue(isolate, *data, &offset) | 1747 if (Shell::DeserializeValue(isolate, *data, &offset) |
| 1733 .ToLocal(&data_value)) { | 1748 .ToLocal(&data_value)) { |
| 1734 Handle<Value> argv[] = {data_value}; | 1749 Handle<Value> argv[] = {data_value}; |
| 1735 (void)onmessage_fun->Call(context, global, 1, argv); | 1750 (void)onmessage_fun->Call(context, global, 1, argv); |
| 1736 } | 1751 } |
| 1737 delete data; | 1752 delete data; |
| 1738 } | 1753 } |
| 1739 } | 1754 } |
| 1740 } | 1755 } |
| 1741 } | 1756 } |
| 1742 } | 1757 } |
| 1743 Shell::CollectGarbage(isolate); | 1758 Shell::CollectGarbage(isolate); |
| 1744 } | 1759 } |
| 1745 isolate->Dispose(); | 1760 isolate->Dispose(); |
| 1746 | 1761 |
| 1747 if (base::NoBarrier_CompareAndSwap(&state_, RUNNING, TERMINATED) == RUNNING) { | 1762 // Post NULL to wake the thread waiting on GetMessage() if there is one. |
| 1748 // Post NULL to wake the thread waiting on GetMessage() if there is one. | 1763 out_queue_.Enqueue(NULL); |
| 1749 out_queue_.Enqueue(NULL); | 1764 out_semaphore_.Signal(); |
| 1750 out_semaphore_.Signal(); | |
| 1751 } | |
| 1752 } | 1765 } |
| 1753 | 1766 |
| 1754 | 1767 |
| 1755 void Worker::Cleanup() { | 1768 void Worker::Cleanup() { |
| 1756 delete thread_; | 1769 delete thread_; |
| 1757 thread_ = NULL; | 1770 thread_ = NULL; |
| 1758 delete[] script_; | 1771 delete[] script_; |
| 1759 script_ = NULL; | 1772 script_ = NULL; |
| 1760 in_queue_.Clear(); | 1773 in_queue_.Clear(); |
| 1761 out_queue_.Clear(); | 1774 out_queue_.Clear(); |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2139 result = True(isolate); | 2152 result = True(isolate); |
| 2140 break; | 2153 break; |
| 2141 case kSerializationTagFalse: | 2154 case kSerializationTagFalse: |
| 2142 result = False(isolate); | 2155 result = False(isolate); |
| 2143 break; | 2156 break; |
| 2144 case kSerializationTagNumber: | 2157 case kSerializationTagNumber: |
| 2145 result = Number::New(isolate, data.Read<double>(offset)); | 2158 result = Number::New(isolate, data.Read<double>(offset)); |
| 2146 break; | 2159 break; |
| 2147 case kSerializationTagString: { | 2160 case kSerializationTagString: { |
| 2148 int length = data.Read<int>(offset); | 2161 int length = data.Read<int>(offset); |
| 2149 static char s_buffer[128]; | 2162 CHECK(length >= 0); |
| 2150 char* p = s_buffer; | 2163 std::vector<char> buffer(length + 1); // + 1 so it is never empty. |
| 2151 bool allocated = false; | 2164 data.ReadMemory(&buffer[0], length, offset); |
| 2152 if (length > static_cast<int>(sizeof(s_buffer))) { | 2165 MaybeLocal<String> str = String::NewFromUtf8( |
| 2153 p = new char[length]; | 2166 isolate, &buffer[0], String::kNormalString, length); |
| 2154 allocated = true; | |
| 2155 } | |
| 2156 data.ReadMemory(p, length, offset); | |
| 2157 MaybeLocal<String> str = | |
| 2158 String::NewFromUtf8(isolate, p, String::kNormalString, length); | |
| 2159 if (!str.IsEmpty()) result = str.ToLocalChecked(); | 2167 if (!str.IsEmpty()) result = str.ToLocalChecked(); |
| 2160 if (allocated) delete[] p; | |
| 2161 break; | 2168 break; |
| 2162 } | 2169 } |
| 2163 case kSerializationTagArray: { | 2170 case kSerializationTagArray: { |
| 2164 uint32_t length = data.Read<uint32_t>(offset); | 2171 uint32_t length = data.Read<uint32_t>(offset); |
| 2165 Handle<Array> array = Array::New(isolate, length); | 2172 Handle<Array> array = Array::New(isolate, length); |
| 2166 for (uint32_t i = 0; i < length; ++i) { | 2173 for (uint32_t i = 0; i < length; ++i) { |
| 2167 Local<Value> element_value; | 2174 Local<Value> element_value; |
| 2168 CHECK(DeserializeValue(isolate, data, offset).ToLocal(&element_value)); | 2175 CHECK(DeserializeValue(isolate, data, offset).ToLocal(&element_value)); |
| 2169 array->Set(i, element_value); | 2176 array->Set(i, element_value); |
| 2170 } | 2177 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2222 i::List<Worker*> workers_copy; | 2229 i::List<Worker*> workers_copy; |
| 2223 { | 2230 { |
| 2224 base::LockGuard<base::Mutex> lock_guard(&workers_mutex_); | 2231 base::LockGuard<base::Mutex> lock_guard(&workers_mutex_); |
| 2225 allow_new_workers_ = false; | 2232 allow_new_workers_ = false; |
| 2226 workers_copy.AddAll(workers_); | 2233 workers_copy.AddAll(workers_); |
| 2227 workers_.Clear(); | 2234 workers_.Clear(); |
| 2228 } | 2235 } |
| 2229 | 2236 |
| 2230 for (int i = 0; i < workers_copy.length(); ++i) { | 2237 for (int i = 0; i < workers_copy.length(); ++i) { |
| 2231 Worker* worker = workers_copy[i]; | 2238 Worker* worker = workers_copy[i]; |
| 2232 worker->Terminate(); | 2239 worker->WaitForThread(); |
| 2233 delete worker; | 2240 delete worker; |
| 2234 } | 2241 } |
| 2235 | 2242 |
| 2236 // Now that all workers are terminated, we can re-enable Worker creation. | 2243 // Now that all workers are terminated, we can re-enable Worker creation. |
| 2237 { | 2244 { |
| 2238 base::LockGuard<base::Mutex> lock_guard(&workers_mutex_); | 2245 base::LockGuard<base::Mutex> lock_guard(&workers_mutex_); |
| 2239 allow_new_workers_ = true; | 2246 allow_new_workers_ = true; |
| 2240 } | 2247 } |
| 2241 | 2248 |
| 2242 for (int i = 0; i < externalized_shared_contents_.length(); ++i) { | 2249 for (int i = 0; i < externalized_shared_contents_.length(); ++i) { |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2439 } | 2446 } |
| 2440 | 2447 |
| 2441 } // namespace v8 | 2448 } // namespace v8 |
| 2442 | 2449 |
| 2443 | 2450 |
| 2444 #ifndef GOOGLE3 | 2451 #ifndef GOOGLE3 |
| 2445 int main(int argc, char* argv[]) { | 2452 int main(int argc, char* argv[]) { |
| 2446 return v8::Shell::Main(argc, argv); | 2453 return v8::Shell::Main(argc, argv); |
| 2447 } | 2454 } |
| 2448 #endif | 2455 #endif |
| OLD | NEW |