| 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 #include <errno.h> | 5 #include <errno.h> |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 #include <sys/stat.h> | 8 #include <sys/stat.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 base::OS::MemoryMappedFile* Shell::counters_file_ = NULL; | 394 base::OS::MemoryMappedFile* Shell::counters_file_ = NULL; |
| 395 CounterCollection Shell::local_counters_; | 395 CounterCollection Shell::local_counters_; |
| 396 CounterCollection* Shell::counters_ = &local_counters_; | 396 CounterCollection* Shell::counters_ = &local_counters_; |
| 397 base::LazyMutex Shell::context_mutex_; | 397 base::LazyMutex Shell::context_mutex_; |
| 398 const base::TimeTicks Shell::kInitialTicks = | 398 const base::TimeTicks Shell::kInitialTicks = |
| 399 base::TimeTicks::HighResolutionNow(); | 399 base::TimeTicks::HighResolutionNow(); |
| 400 Global<Function> Shell::stringify_function_; | 400 Global<Function> Shell::stringify_function_; |
| 401 base::LazyMutex Shell::workers_mutex_; | 401 base::LazyMutex Shell::workers_mutex_; |
| 402 bool Shell::allow_new_workers_ = true; | 402 bool Shell::allow_new_workers_ = true; |
| 403 i::List<Worker*> Shell::workers_; | 403 i::List<Worker*> Shell::workers_; |
| 404 std::unordered_set<SharedArrayBuffer::Contents, | 404 std::vector<ExternalizedContents> Shell::externalized_contents_; |
| 405 Shell::SharedArrayBufferContentsHash, | |
| 406 Shell::SharedArrayBufferContentsIsEqual> | |
| 407 Shell::externalized_shared_contents_; | |
| 408 | 405 |
| 409 Global<Context> Shell::evaluation_context_; | 406 Global<Context> Shell::evaluation_context_; |
| 410 ArrayBuffer::Allocator* Shell::array_buffer_allocator; | 407 ArrayBuffer::Allocator* Shell::array_buffer_allocator; |
| 411 ShellOptions Shell::options; | 408 ShellOptions Shell::options; |
| 412 base::OnceType Shell::quit_once_ = V8_ONCE_INIT; | 409 base::OnceType Shell::quit_once_ = V8_ONCE_INIT; |
| 413 | 410 |
| 414 bool CounterMap::Match(void* key1, void* key2) { | 411 bool CounterMap::Match(void* key1, void* key2) { |
| 415 const char* name1 = reinterpret_cast<const char*>(key1); | 412 const char* name1 = reinterpret_cast<const char*>(key1); |
| 416 const char* name2 = reinterpret_cast<const char*>(key2); | 413 const char* name2 = reinterpret_cast<const char*>(key2); |
| 417 return strcmp(name1, name2) == 0; | 414 return strcmp(name1, name2) == 0; |
| (...skipping 1690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2108 if (thread_ == NULL) return; | 2105 if (thread_ == NULL) return; |
| 2109 done_semaphore_.Wait(); | 2106 done_semaphore_.Wait(); |
| 2110 } | 2107 } |
| 2111 | 2108 |
| 2112 | 2109 |
| 2113 void SourceGroup::JoinThread() { | 2110 void SourceGroup::JoinThread() { |
| 2114 if (thread_ == NULL) return; | 2111 if (thread_ == NULL) return; |
| 2115 thread_->Join(); | 2112 thread_->Join(); |
| 2116 } | 2113 } |
| 2117 | 2114 |
| 2118 SerializationData::~SerializationData() { | 2115 ExternalizedContents::~ExternalizedContents() { |
| 2119 // Any ArrayBuffer::Contents are owned by this SerializationData object if | 2116 Shell::array_buffer_allocator->Free(data_, size_); |
| 2120 // ownership hasn't been transferred out. | |
| 2121 // SharedArrayBuffer::Contents may be used by multiple threads, so must be | |
| 2122 // cleaned up by the main thread in Shell::CleanupWorkers(). | |
| 2123 for (const auto& contents : array_buffer_contents_) { | |
| 2124 if (contents.Data()) { | |
| 2125 Shell::array_buffer_allocator->Free(contents.Data(), | |
| 2126 contents.ByteLength()); | |
| 2127 } | |
| 2128 } | |
| 2129 } | |
| 2130 | |
| 2131 void SerializationData::ClearTransferredArrayBuffers() { | |
| 2132 array_buffer_contents_.clear(); | |
| 2133 } | 2117 } |
| 2134 | 2118 |
| 2135 void SerializationDataQueue::Enqueue(std::unique_ptr<SerializationData> data) { | 2119 void SerializationDataQueue::Enqueue(std::unique_ptr<SerializationData> data) { |
| 2136 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 2120 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
| 2137 data_.push_back(std::move(data)); | 2121 data_.push_back(std::move(data)); |
| 2138 } | 2122 } |
| 2139 | 2123 |
| 2140 bool SerializationDataQueue::Dequeue( | 2124 bool SerializationDataQueue::Dequeue( |
| 2141 std::unique_ptr<SerializationData>* out_data) { | 2125 std::unique_ptr<SerializationData>* out_data) { |
| 2142 out_data->reset(); | 2126 out_data->reset(); |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2588 } | 2572 } |
| 2589 return Just(true); | 2573 return Just(true); |
| 2590 } else if (transfer->IsUndefined()) { | 2574 } else if (transfer->IsUndefined()) { |
| 2591 return Just(true); | 2575 return Just(true); |
| 2592 } else { | 2576 } else { |
| 2593 Throw(isolate_, "Transfer list must be an Array or undefined"); | 2577 Throw(isolate_, "Transfer list must be an Array or undefined"); |
| 2594 return Nothing<bool>(); | 2578 return Nothing<bool>(); |
| 2595 } | 2579 } |
| 2596 } | 2580 } |
| 2597 | 2581 |
| 2582 template <typename T> |
| 2583 typename T::Contents MaybeExternalize(Local<T> array_buffer) { |
| 2584 if (array_buffer->IsExternal()) { |
| 2585 return array_buffer->GetContents(); |
| 2586 } else { |
| 2587 typename T::Contents contents = array_buffer->Externalize(); |
| 2588 data_->externalized_contents_.emplace_back(contents); |
| 2589 return contents; |
| 2590 } |
| 2591 } |
| 2592 |
| 2598 Maybe<bool> FinalizeTransfer() { | 2593 Maybe<bool> FinalizeTransfer() { |
| 2599 for (const auto& global_array_buffer : array_buffers_) { | 2594 for (const auto& global_array_buffer : array_buffers_) { |
| 2600 Local<ArrayBuffer> array_buffer = | 2595 Local<ArrayBuffer> array_buffer = |
| 2601 Local<ArrayBuffer>::New(isolate_, global_array_buffer); | 2596 Local<ArrayBuffer>::New(isolate_, global_array_buffer); |
| 2602 if (!array_buffer->IsNeuterable()) { | 2597 if (!array_buffer->IsNeuterable()) { |
| 2603 Throw(isolate_, "ArrayBuffer could not be transferred"); | 2598 Throw(isolate_, "ArrayBuffer could not be transferred"); |
| 2604 return Nothing<bool>(); | 2599 return Nothing<bool>(); |
| 2605 } | 2600 } |
| 2606 | 2601 |
| 2607 if (!array_buffer->IsExternal()) { | 2602 ArrayBuffer::Contents contents = MaybeExternalize(array_buffer); |
| 2608 array_buffer->Externalize(); | |
| 2609 } | |
| 2610 ArrayBuffer::Contents contents = array_buffer->GetContents(); | |
| 2611 array_buffer->Neuter(); | 2603 array_buffer->Neuter(); |
| 2612 data_->array_buffer_contents_.push_back(contents); | 2604 data_->array_buffer_contents_.push_back(contents); |
| 2613 } | 2605 } |
| 2614 | 2606 |
| 2615 for (const auto& global_shared_array_buffer : shared_array_buffers_) { | 2607 for (const auto& global_shared_array_buffer : shared_array_buffers_) { |
| 2616 Local<SharedArrayBuffer> shared_array_buffer = | 2608 Local<SharedArrayBuffer> shared_array_buffer = |
| 2617 Local<SharedArrayBuffer>::New(isolate_, global_shared_array_buffer); | 2609 Local<SharedArrayBuffer>::New(isolate_, global_shared_array_buffer); |
| 2618 if (!shared_array_buffer->IsExternal()) { | |
| 2619 shared_array_buffer->Externalize(); | |
| 2620 } | |
| 2621 data_->shared_array_buffer_contents_.push_back( | 2610 data_->shared_array_buffer_contents_.push_back( |
| 2622 shared_array_buffer->GetContents()); | 2611 MaybeExternalize(shared_array_buffer)); |
| 2623 } | 2612 } |
| 2624 | 2613 |
| 2625 return Just(true); | 2614 return Just(true); |
| 2626 } | 2615 } |
| 2627 | 2616 |
| 2628 Isolate* isolate_; | 2617 Isolate* isolate_; |
| 2629 ValueSerializer serializer_; | 2618 ValueSerializer serializer_; |
| 2630 std::unique_ptr<SerializationData> data_; | 2619 std::unique_ptr<SerializationData> data_; |
| 2631 std::vector<Global<ArrayBuffer>> array_buffers_; | 2620 std::vector<Global<ArrayBuffer>> array_buffers_; |
| 2632 std::vector<Global<SharedArrayBuffer>> shared_array_buffers_; | 2621 std::vector<Global<SharedArrayBuffer>> shared_array_buffers_; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2656 deserializer_.TransferArrayBuffer(index++, array_buffer); | 2645 deserializer_.TransferArrayBuffer(index++, array_buffer); |
| 2657 } | 2646 } |
| 2658 | 2647 |
| 2659 index = 0; | 2648 index = 0; |
| 2660 for (const auto& contents : data_->shared_array_buffer_contents()) { | 2649 for (const auto& contents : data_->shared_array_buffer_contents()) { |
| 2661 Local<SharedArrayBuffer> shared_array_buffer = SharedArrayBuffer::New( | 2650 Local<SharedArrayBuffer> shared_array_buffer = SharedArrayBuffer::New( |
| 2662 isolate_, contents.Data(), contents.ByteLength()); | 2651 isolate_, contents.Data(), contents.ByteLength()); |
| 2663 deserializer_.TransferSharedArrayBuffer(index++, shared_array_buffer); | 2652 deserializer_.TransferSharedArrayBuffer(index++, shared_array_buffer); |
| 2664 } | 2653 } |
| 2665 | 2654 |
| 2666 MaybeLocal<Value> result = deserializer_.ReadValue(context); | 2655 return deserializer_.ReadValue(context); |
| 2667 if (!result.IsEmpty()) { | |
| 2668 data_->ClearTransferredArrayBuffers(); | |
| 2669 } | |
| 2670 return result; | |
| 2671 } | 2656 } |
| 2672 | 2657 |
| 2673 private: | 2658 private: |
| 2674 Isolate* isolate_; | 2659 Isolate* isolate_; |
| 2675 ValueDeserializer deserializer_; | 2660 ValueDeserializer deserializer_; |
| 2676 std::unique_ptr<SerializationData> data_; | 2661 std::unique_ptr<SerializationData> data_; |
| 2677 | 2662 |
| 2678 DISALLOW_COPY_AND_ASSIGN(Deserializer); | 2663 DISALLOW_COPY_AND_ASSIGN(Deserializer); |
| 2679 }; | 2664 }; |
| 2680 | 2665 |
| 2681 std::unique_ptr<SerializationData> Shell::SerializeValue( | 2666 std::unique_ptr<SerializationData> Shell::SerializeValue( |
| 2682 Isolate* isolate, Local<Value> value, Local<Value> transfer) { | 2667 Isolate* isolate, Local<Value> value, Local<Value> transfer) { |
| 2683 bool ok; | 2668 bool ok; |
| 2684 Local<Context> context = isolate->GetCurrentContext(); | 2669 Local<Context> context = isolate->GetCurrentContext(); |
| 2685 Serializer serializer(isolate); | 2670 Serializer serializer(isolate); |
| 2686 if (serializer.WriteValue(context, value, transfer).To(&ok)) { | 2671 if (serializer.WriteValue(context, value, transfer).To(&ok)) { |
| 2687 std::unique_ptr<SerializationData> data = serializer.Release(); | 2672 std::unique_ptr<SerializationData> data = serializer.Release(); |
| 2688 base::LockGuard<base::Mutex> lock_guard(workers_mutex_.Pointer()); | 2673 base::LockGuard<base::Mutex> lock_guard(workers_mutex_.Pointer()); |
| 2689 for (const auto& contents : data->shared_array_buffer_contents()) { | 2674 data->AppendExternalizedContentsTo(&externalized_contents_); |
| 2690 externalized_shared_contents_.insert(contents); | |
| 2691 } | |
| 2692 return data; | 2675 return data; |
| 2693 } | 2676 } |
| 2694 return nullptr; | 2677 return nullptr; |
| 2695 } | 2678 } |
| 2696 | 2679 |
| 2697 MaybeLocal<Value> Shell::DeserializeValue( | 2680 MaybeLocal<Value> Shell::DeserializeValue( |
| 2698 Isolate* isolate, std::unique_ptr<SerializationData> data) { | 2681 Isolate* isolate, std::unique_ptr<SerializationData> data) { |
| 2699 Local<Value> value; | 2682 Local<Value> value; |
| 2700 Local<Context> context = isolate->GetCurrentContext(); | 2683 Local<Context> context = isolate->GetCurrentContext(); |
| 2701 Deserializer deserializer(isolate, std::move(data)); | 2684 Deserializer deserializer(isolate, std::move(data)); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2717 | 2700 |
| 2718 for (int i = 0; i < workers_copy.length(); ++i) { | 2701 for (int i = 0; i < workers_copy.length(); ++i) { |
| 2719 Worker* worker = workers_copy[i]; | 2702 Worker* worker = workers_copy[i]; |
| 2720 worker->WaitForThread(); | 2703 worker->WaitForThread(); |
| 2721 delete worker; | 2704 delete worker; |
| 2722 } | 2705 } |
| 2723 | 2706 |
| 2724 // Now that all workers are terminated, we can re-enable Worker creation. | 2707 // Now that all workers are terminated, we can re-enable Worker creation. |
| 2725 base::LockGuard<base::Mutex> lock_guard(workers_mutex_.Pointer()); | 2708 base::LockGuard<base::Mutex> lock_guard(workers_mutex_.Pointer()); |
| 2726 allow_new_workers_ = true; | 2709 allow_new_workers_ = true; |
| 2727 | 2710 externalized_contents_.clear(); |
| 2728 for (const auto& contents : externalized_shared_contents_) { | |
| 2729 Shell::array_buffer_allocator->Free(contents.Data(), contents.ByteLength()); | |
| 2730 } | |
| 2731 externalized_shared_contents_.clear(); | |
| 2732 } | 2711 } |
| 2733 | 2712 |
| 2734 | 2713 |
| 2735 static void DumpHeapConstants(i::Isolate* isolate) { | 2714 static void DumpHeapConstants(i::Isolate* isolate) { |
| 2736 i::Heap* heap = isolate->heap(); | 2715 i::Heap* heap = isolate->heap(); |
| 2737 | 2716 |
| 2738 // Dump the INSTANCE_TYPES table to the console. | 2717 // Dump the INSTANCE_TYPES table to the console. |
| 2739 printf("# List of known V8 instance types.\n"); | 2718 printf("# List of known V8 instance types.\n"); |
| 2740 #define DUMP_TYPE(T) printf(" %d: \"%s\",\n", i::T, #T); | 2719 #define DUMP_TYPE(T) printf(" %d: \"%s\",\n", i::T, #T); |
| 2741 printf("INSTANCE_TYPES = {\n"); | 2720 printf("INSTANCE_TYPES = {\n"); |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2949 } | 2928 } |
| 2950 | 2929 |
| 2951 } // namespace v8 | 2930 } // namespace v8 |
| 2952 | 2931 |
| 2953 | 2932 |
| 2954 #ifndef GOOGLE3 | 2933 #ifndef GOOGLE3 |
| 2955 int main(int argc, char* argv[]) { | 2934 int main(int argc, char* argv[]) { |
| 2956 return v8::Shell::Main(argc, argv); | 2935 return v8::Shell::Main(argc, argv); |
| 2957 } | 2936 } |
| 2958 #endif | 2937 #endif |
| OLD | NEW |