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 |