| 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 |
| (...skipping 1519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1530 if (thread_ == NULL) return; | 1530 if (thread_ == NULL) return; |
| 1531 if (Shell::options.last_run) { | 1531 if (Shell::options.last_run) { |
| 1532 thread_->Join(); | 1532 thread_->Join(); |
| 1533 } else { | 1533 } else { |
| 1534 done_semaphore_.Wait(); | 1534 done_semaphore_.Wait(); |
| 1535 } | 1535 } |
| 1536 } | 1536 } |
| 1537 | 1537 |
| 1538 | 1538 |
| 1539 SerializationData::~SerializationData() { | 1539 SerializationData::~SerializationData() { |
| 1540 // Any ArrayBuffer::Contents are owned by this SerializationData object. | 1540 // Any ArrayBuffer::Contents are owned by this SerializationData object if |
| 1541 // SharedArrayBuffer::Contents may be used by other threads, so must be | 1541 // ownership hasn't been transferred out via ReadArrayBufferContents. |
| 1542 // SharedArrayBuffer::Contents may be used by multiple threads, so must be |
| 1542 // cleaned up by the main thread in Shell::CleanupWorkers(). | 1543 // cleaned up by the main thread in Shell::CleanupWorkers(). |
| 1543 for (int i = 0; i < array_buffer_contents.length(); ++i) { | 1544 for (int i = 0; i < array_buffer_contents_.length(); ++i) { |
| 1544 ArrayBuffer::Contents& contents = array_buffer_contents[i]; | 1545 ArrayBuffer::Contents& contents = array_buffer_contents_[i]; |
| 1545 Shell::array_buffer_allocator->Free(contents.Data(), contents.ByteLength()); | 1546 if (contents.Data()) { |
| 1547 Shell::array_buffer_allocator->Free(contents.Data(), |
| 1548 contents.ByteLength()); |
| 1549 } |
| 1546 } | 1550 } |
| 1547 } | 1551 } |
| 1548 | 1552 |
| 1549 | 1553 |
| 1550 void SerializationData::WriteTag(SerializationTag tag) { data.Add(tag); } | 1554 void SerializationData::WriteTag(SerializationTag tag) { data_.Add(tag); } |
| 1551 | 1555 |
| 1552 | 1556 |
| 1553 void SerializationData::WriteMemory(const void* p, int length) { | 1557 void SerializationData::WriteMemory(const void* p, int length) { |
| 1554 if (length > 0) { | 1558 if (length > 0) { |
| 1555 i::Vector<uint8_t> block = data.AddBlock(0, length); | 1559 i::Vector<uint8_t> block = data_.AddBlock(0, length); |
| 1556 memcpy(&block[0], p, length); | 1560 memcpy(&block[0], p, length); |
| 1557 } | 1561 } |
| 1558 } | 1562 } |
| 1559 | 1563 |
| 1560 | 1564 |
| 1561 void SerializationData::WriteArrayBufferContents( | 1565 void SerializationData::WriteArrayBufferContents( |
| 1562 const ArrayBuffer::Contents& contents) { | 1566 const ArrayBuffer::Contents& contents) { |
| 1563 array_buffer_contents.Add(contents); | 1567 array_buffer_contents_.Add(contents); |
| 1564 WriteTag(kSerializationTagTransferredArrayBuffer); | 1568 WriteTag(kSerializationTagTransferredArrayBuffer); |
| 1565 int index = array_buffer_contents.length() - 1; | 1569 int index = array_buffer_contents_.length() - 1; |
| 1566 Write(index); | 1570 Write(index); |
| 1567 } | 1571 } |
| 1568 | 1572 |
| 1569 | 1573 |
| 1570 void SerializationData::WriteSharedArrayBufferContents( | 1574 void SerializationData::WriteSharedArrayBufferContents( |
| 1571 const SharedArrayBuffer::Contents& contents) { | 1575 const SharedArrayBuffer::Contents& contents) { |
| 1572 shared_array_buffer_contents.Add(contents); | 1576 shared_array_buffer_contents_.Add(contents); |
| 1573 WriteTag(kSerializationTagTransferredSharedArrayBuffer); | 1577 WriteTag(kSerializationTagTransferredSharedArrayBuffer); |
| 1574 int index = shared_array_buffer_contents.length() - 1; | 1578 int index = shared_array_buffer_contents_.length() - 1; |
| 1575 Write(index); | 1579 Write(index); |
| 1576 } | 1580 } |
| 1577 | 1581 |
| 1578 | 1582 |
| 1579 SerializationTag SerializationData::ReadTag(int* offset) const { | 1583 SerializationTag SerializationData::ReadTag(int* offset) const { |
| 1580 return static_cast<SerializationTag>(Read<uint8_t>(offset)); | 1584 return static_cast<SerializationTag>(Read<uint8_t>(offset)); |
| 1581 } | 1585 } |
| 1582 | 1586 |
| 1583 | 1587 |
| 1584 void SerializationData::ReadMemory(void* p, int length, int* offset) const { | 1588 void SerializationData::ReadMemory(void* p, int length, int* offset) const { |
| 1585 if (length > 0) { | 1589 if (length > 0) { |
| 1586 memcpy(p, &data[*offset], length); | 1590 memcpy(p, &data_[*offset], length); |
| 1587 (*offset) += length; | 1591 (*offset) += length; |
| 1588 } | 1592 } |
| 1589 } | 1593 } |
| 1590 | 1594 |
| 1591 | 1595 |
| 1592 void SerializationData::ReadArrayBufferContents(ArrayBuffer::Contents* contents, | 1596 void SerializationData::ReadArrayBufferContents(ArrayBuffer::Contents* contents, |
| 1593 int* offset) const { | 1597 int* offset) const { |
| 1594 int index = Read<int>(offset); | 1598 int index = Read<int>(offset); |
| 1595 DCHECK(index < array_buffer_contents.length()); | 1599 DCHECK(index < array_buffer_contents_.length()); |
| 1596 *contents = array_buffer_contents[index]; | 1600 *contents = array_buffer_contents_[index]; |
| 1601 // Ownership of this ArrayBuffer::Contents is passed to the caller. Neuter |
| 1602 // our copy so it won't be double-free'd when this SerializationData is |
| 1603 // destroyed. |
| 1604 array_buffer_contents_[index] = ArrayBuffer::Contents(); |
| 1597 } | 1605 } |
| 1598 | 1606 |
| 1599 | 1607 |
| 1600 void SerializationData::ReadSharedArrayBufferContents( | 1608 void SerializationData::ReadSharedArrayBufferContents( |
| 1601 SharedArrayBuffer::Contents* contents, int* offset) const { | 1609 SharedArrayBuffer::Contents* contents, int* offset) const { |
| 1602 int index = Read<int>(offset); | 1610 int index = Read<int>(offset); |
| 1603 DCHECK(index < shared_array_buffer_contents.length()); | 1611 DCHECK(index < shared_array_buffer_contents_.length()); |
| 1604 *contents = shared_array_buffer_contents[index]; | 1612 *contents = shared_array_buffer_contents_[index]; |
| 1605 } | 1613 } |
| 1606 | 1614 |
| 1607 | 1615 |
| 1608 void SerializationDataQueue::Enqueue(SerializationData* data) { | 1616 void SerializationDataQueue::Enqueue(SerializationData* data) { |
| 1609 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 1617 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
| 1610 data_.Add(data); | 1618 data_.Add(data); |
| 1611 } | 1619 } |
| 1612 | 1620 |
| 1613 | 1621 |
| 1614 bool SerializationDataQueue::Dequeue(SerializationData** data) { | 1622 bool SerializationDataQueue::Dequeue(SerializationData** data) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1637 | 1645 |
| 1638 Worker::Worker() | 1646 Worker::Worker() |
| 1639 : in_semaphore_(0), | 1647 : in_semaphore_(0), |
| 1640 out_semaphore_(0), | 1648 out_semaphore_(0), |
| 1641 thread_(NULL), | 1649 thread_(NULL), |
| 1642 script_(NULL), | 1650 script_(NULL), |
| 1643 state_(IDLE), | 1651 state_(IDLE), |
| 1644 join_called_(false) {} | 1652 join_called_(false) {} |
| 1645 | 1653 |
| 1646 | 1654 |
| 1647 Worker::~Worker() { Cleanup(); } | 1655 Worker::~Worker() { |
| 1656 delete thread_; |
| 1657 thread_ = NULL; |
| 1658 delete[] script_; |
| 1659 script_ = NULL; |
| 1660 in_queue_.Clear(); |
| 1661 out_queue_.Clear(); |
| 1662 } |
| 1648 | 1663 |
| 1649 | 1664 |
| 1650 void Worker::StartExecuteInThread(Isolate* isolate, const char* script) { | 1665 void Worker::StartExecuteInThread(Isolate* isolate, const char* script) { |
| 1651 if (base::NoBarrier_CompareAndSwap(&state_, IDLE, RUNNING) == IDLE) { | 1666 if (base::NoBarrier_CompareAndSwap(&state_, IDLE, RUNNING) == IDLE) { |
| 1652 script_ = i::StrDup(script); | 1667 script_ = i::StrDup(script); |
| 1653 thread_ = new WorkerThread(this); | 1668 thread_ = new WorkerThread(this); |
| 1654 thread_->Start(); | 1669 thread_->Start(); |
| 1655 } else { | 1670 } else { |
| 1656 // Somehow the Worker was started twice. | 1671 // Somehow the Worker was started twice. |
| 1657 UNREACHABLE(); | 1672 UNREACHABLE(); |
| 1658 } | 1673 } |
| 1659 } | 1674 } |
| 1660 | 1675 |
| 1661 | 1676 |
| 1662 void Worker::PostMessage(SerializationData* data) { | 1677 void Worker::PostMessage(SerializationData* data) { |
| 1663 in_queue_.Enqueue(data); | 1678 in_queue_.Enqueue(data); |
| 1664 in_semaphore_.Signal(); | 1679 in_semaphore_.Signal(); |
| 1665 } | 1680 } |
| 1666 | 1681 |
| 1667 | 1682 |
| 1668 SerializationData* Worker::GetMessage() { | 1683 SerializationData* Worker::GetMessage() { |
| 1669 SerializationData* data = NULL; | 1684 SerializationData* data = NULL; |
| 1670 while (!out_queue_.Dequeue(&data)) { | 1685 while (!out_queue_.Dequeue(&data)) { |
| 1671 // If the worker is no longer running, and there are no messages in the | 1686 // If the worker is no longer running, and there are no messages in the |
| 1672 // queue, don't expect any more messages from it. | 1687 // queue, don't expect any more messages from it. |
| 1673 if (base::NoBarrier_Load(&state_) != RUNNING) break; | 1688 if (base::NoBarrier_Load(&state_) != RUNNING) break; |
| 1674 out_semaphore_.Wait(); | 1689 out_semaphore_.Wait(); |
| 1675 } | 1690 } |
| 1676 | |
| 1677 return data; | 1691 return data; |
| 1678 } | 1692 } |
| 1679 | 1693 |
| 1680 | 1694 |
| 1681 void Worker::Terminate() { | 1695 void Worker::Terminate() { |
| 1682 if (base::NoBarrier_CompareAndSwap(&state_, RUNNING, TERMINATED) == RUNNING) { | 1696 if (base::NoBarrier_CompareAndSwap(&state_, RUNNING, TERMINATED) == RUNNING) { |
| 1683 // Post NULL to wake the Worker thread message loop, and tell it to stop | 1697 // Post NULL to wake the Worker thread message loop, and tell it to stop |
| 1684 // running. | 1698 // running. |
| 1685 PostMessage(NULL); | 1699 PostMessage(NULL); |
| 1686 } | 1700 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1758 Shell::CollectGarbage(isolate); | 1772 Shell::CollectGarbage(isolate); |
| 1759 } | 1773 } |
| 1760 isolate->Dispose(); | 1774 isolate->Dispose(); |
| 1761 | 1775 |
| 1762 // Post NULL to wake the thread waiting on GetMessage() if there is one. | 1776 // Post NULL to wake the thread waiting on GetMessage() if there is one. |
| 1763 out_queue_.Enqueue(NULL); | 1777 out_queue_.Enqueue(NULL); |
| 1764 out_semaphore_.Signal(); | 1778 out_semaphore_.Signal(); |
| 1765 } | 1779 } |
| 1766 | 1780 |
| 1767 | 1781 |
| 1768 void Worker::Cleanup() { | |
| 1769 delete thread_; | |
| 1770 thread_ = NULL; | |
| 1771 delete[] script_; | |
| 1772 script_ = NULL; | |
| 1773 in_queue_.Clear(); | |
| 1774 out_queue_.Clear(); | |
| 1775 } | |
| 1776 | |
| 1777 | |
| 1778 void Worker::PostMessageOut(const v8::FunctionCallbackInfo<v8::Value>& args) { | 1782 void Worker::PostMessageOut(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 1779 Isolate* isolate = args.GetIsolate(); | 1783 Isolate* isolate = args.GetIsolate(); |
| 1780 HandleScope handle_scope(isolate); | 1784 HandleScope handle_scope(isolate); |
| 1781 | 1785 |
| 1782 if (args.Length() < 1) { | 1786 if (args.Length() < 1) { |
| 1783 Throw(isolate, "Invalid argument"); | 1787 Throw(isolate, "Invalid argument"); |
| 1784 return; | 1788 return; |
| 1785 } | 1789 } |
| 1786 | 1790 |
| 1787 Handle<Value> message = args[0]; | 1791 Handle<Value> message = args[0]; |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2052 return false; | 2056 return false; |
| 2053 } | 2057 } |
| 2054 seen_objects->Add(array_buffer); | 2058 seen_objects->Add(array_buffer); |
| 2055 if (FindInObjectList(array_buffer, to_transfer)) { | 2059 if (FindInObjectList(array_buffer, to_transfer)) { |
| 2056 // Transfer ArrayBuffer | 2060 // Transfer ArrayBuffer |
| 2057 if (!array_buffer->IsNeuterable()) { | 2061 if (!array_buffer->IsNeuterable()) { |
| 2058 Throw(isolate, "Attempting to transfer an un-neuterable ArrayBuffer"); | 2062 Throw(isolate, "Attempting to transfer an un-neuterable ArrayBuffer"); |
| 2059 return false; | 2063 return false; |
| 2060 } | 2064 } |
| 2061 | 2065 |
| 2062 ArrayBuffer::Contents contents = array_buffer->Externalize(); | 2066 ArrayBuffer::Contents contents = array_buffer->IsExternal() |
| 2067 ? array_buffer->GetContents() |
| 2068 : array_buffer->Externalize(); |
| 2063 array_buffer->Neuter(); | 2069 array_buffer->Neuter(); |
| 2064 out_data->WriteArrayBufferContents(contents); | 2070 out_data->WriteArrayBufferContents(contents); |
| 2065 } else { | 2071 } else { |
| 2066 ArrayBuffer::Contents contents = array_buffer->GetContents(); | 2072 ArrayBuffer::Contents contents = array_buffer->GetContents(); |
| 2067 // Clone ArrayBuffer | 2073 // Clone ArrayBuffer |
| 2068 if (contents.ByteLength() > i::kMaxUInt32) { | 2074 if (contents.ByteLength() > i::kMaxUInt32) { |
| 2069 Throw(isolate, "ArrayBuffer is too big to clone"); | 2075 Throw(isolate, "ArrayBuffer is too big to clone"); |
| 2070 return false; | 2076 return false; |
| 2071 } | 2077 } |
| 2072 | 2078 |
| 2073 int byte_length = static_cast<int>(contents.ByteLength()); | 2079 int byte_length = static_cast<int>(contents.ByteLength()); |
| 2074 out_data->WriteTag(kSerializationTagArrayBuffer); | 2080 out_data->WriteTag(kSerializationTagArrayBuffer); |
| 2075 out_data->Write(byte_length); | 2081 out_data->Write(byte_length); |
| 2076 out_data->WriteMemory(contents.Data(), | 2082 out_data->WriteMemory(contents.Data(), |
| 2077 static_cast<int>(contents.ByteLength())); | 2083 static_cast<int>(contents.ByteLength())); |
| 2078 } | 2084 } |
| 2079 } else if (value->IsSharedArrayBuffer()) { | 2085 } else if (value->IsSharedArrayBuffer()) { |
| 2080 Handle<SharedArrayBuffer> sab = Handle<SharedArrayBuffer>::Cast(value); | 2086 Handle<SharedArrayBuffer> sab = Handle<SharedArrayBuffer>::Cast(value); |
| 2081 if (FindInObjectList(sab, *seen_objects)) { | 2087 if (FindInObjectList(sab, *seen_objects)) { |
| 2082 Throw(isolate, "Duplicated shared array buffers not supported"); | 2088 Throw(isolate, "Duplicated shared array buffers not supported"); |
| 2083 return false; | 2089 return false; |
| 2084 } | 2090 } |
| 2085 seen_objects->Add(sab); | 2091 seen_objects->Add(sab); |
| 2086 if (!FindInObjectList(sab, to_transfer)) { | 2092 if (!FindInObjectList(sab, to_transfer)) { |
| 2087 Throw(isolate, "SharedArrayBuffer must be transferred"); | 2093 Throw(isolate, "SharedArrayBuffer must be transferred"); |
| 2088 return false; | 2094 return false; |
| 2089 } | 2095 } |
| 2090 | 2096 |
| 2091 SharedArrayBuffer::Contents contents = sab->Externalize(); | 2097 SharedArrayBuffer::Contents contents; |
| 2098 if (sab->IsExternal()) { |
| 2099 contents = sab->GetContents(); |
| 2100 } else { |
| 2101 contents = sab->Externalize(); |
| 2102 externalized_shared_contents_.Add(contents); |
| 2103 } |
| 2092 out_data->WriteSharedArrayBufferContents(contents); | 2104 out_data->WriteSharedArrayBufferContents(contents); |
| 2093 externalized_shared_contents_.Add(contents); | |
| 2094 } else if (value->IsObject()) { | 2105 } else if (value->IsObject()) { |
| 2095 Handle<Object> object = Handle<Object>::Cast(value); | 2106 Handle<Object> object = Handle<Object>::Cast(value); |
| 2096 if (FindInObjectList(object, *seen_objects)) { | 2107 if (FindInObjectList(object, *seen_objects)) { |
| 2097 Throw(isolate, "Duplicated objects not supported"); | 2108 Throw(isolate, "Duplicated objects not supported"); |
| 2098 return false; | 2109 return false; |
| 2099 } | 2110 } |
| 2100 seen_objects->Add(object); | 2111 seen_objects->Add(object); |
| 2101 Local<Array> property_names; | 2112 Local<Array> property_names; |
| 2102 if (!object->GetOwnPropertyNames(context).ToLocal(&property_names)) { | 2113 if (!object->GetOwnPropertyNames(context).ToLocal(&property_names)) { |
| 2103 Throw(isolate, "Unable to get property names"); | 2114 Throw(isolate, "Unable to get property names"); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2196 Handle<ArrayBuffer> array_buffer = ArrayBuffer::New(isolate, byte_length); | 2207 Handle<ArrayBuffer> array_buffer = ArrayBuffer::New(isolate, byte_length); |
| 2197 ArrayBuffer::Contents contents = array_buffer->GetContents(); | 2208 ArrayBuffer::Contents contents = array_buffer->GetContents(); |
| 2198 DCHECK(static_cast<size_t>(byte_length) == contents.ByteLength()); | 2209 DCHECK(static_cast<size_t>(byte_length) == contents.ByteLength()); |
| 2199 data.ReadMemory(contents.Data(), byte_length, offset); | 2210 data.ReadMemory(contents.Data(), byte_length, offset); |
| 2200 result = array_buffer; | 2211 result = array_buffer; |
| 2201 break; | 2212 break; |
| 2202 } | 2213 } |
| 2203 case kSerializationTagTransferredArrayBuffer: { | 2214 case kSerializationTagTransferredArrayBuffer: { |
| 2204 ArrayBuffer::Contents contents; | 2215 ArrayBuffer::Contents contents; |
| 2205 data.ReadArrayBufferContents(&contents, offset); | 2216 data.ReadArrayBufferContents(&contents, offset); |
| 2206 result = | 2217 result = ArrayBuffer::New(isolate, contents.Data(), contents.ByteLength(), |
| 2207 ArrayBuffer::New(isolate, contents.Data(), contents.ByteLength()); | 2218 ArrayBufferCreationMode::kInternalized); |
| 2208 break; | 2219 break; |
| 2209 } | 2220 } |
| 2210 case kSerializationTagTransferredSharedArrayBuffer: { | 2221 case kSerializationTagTransferredSharedArrayBuffer: { |
| 2211 SharedArrayBuffer::Contents contents; | 2222 SharedArrayBuffer::Contents contents; |
| 2212 data.ReadSharedArrayBufferContents(&contents, offset); | 2223 data.ReadSharedArrayBufferContents(&contents, offset); |
| 2213 result = SharedArrayBuffer::New(isolate, contents.Data(), | 2224 result = SharedArrayBuffer::New(isolate, contents.Data(), |
| 2214 contents.ByteLength()); | 2225 contents.ByteLength()); |
| 2215 break; | 2226 break; |
| 2216 } | 2227 } |
| 2217 default: | 2228 default: |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2446 } | 2457 } |
| 2447 | 2458 |
| 2448 } // namespace v8 | 2459 } // namespace v8 |
| 2449 | 2460 |
| 2450 | 2461 |
| 2451 #ifndef GOOGLE3 | 2462 #ifndef GOOGLE3 |
| 2452 int main(int argc, char* argv[]) { | 2463 int main(int argc, char* argv[]) { |
| 2453 return v8::Shell::Main(argc, argv); | 2464 return v8::Shell::Main(argc, argv); |
| 2454 } | 2465 } |
| 2455 #endif | 2466 #endif |
| OLD | NEW |