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 28 matching lines...) Expand all Loading... |
39 #ifndef V8_SHARED | 39 #ifndef V8_SHARED |
40 #include "src/api.h" | 40 #include "src/api.h" |
41 #include "src/base/cpu.h" | 41 #include "src/base/cpu.h" |
42 #include "src/base/logging.h" | 42 #include "src/base/logging.h" |
43 #include "src/base/platform/platform.h" | 43 #include "src/base/platform/platform.h" |
44 #include "src/base/sys-info.h" | 44 #include "src/base/sys-info.h" |
45 #include "src/basic-block-profiler.h" | 45 #include "src/basic-block-profiler.h" |
46 #include "src/d8-debug.h" | 46 #include "src/d8-debug.h" |
47 #include "src/debug.h" | 47 #include "src/debug.h" |
48 #include "src/snapshot/natives.h" | 48 #include "src/snapshot/natives.h" |
| 49 #include "src/utils.h" |
49 #include "src/v8.h" | 50 #include "src/v8.h" |
50 #endif // !V8_SHARED | 51 #endif // !V8_SHARED |
51 | 52 |
52 #ifdef V8_USE_EXTERNAL_STARTUP_DATA | 53 #ifdef V8_USE_EXTERNAL_STARTUP_DATA |
53 #include "src/startup-data-util.h" | 54 #include "src/startup-data-util.h" |
54 #endif // V8_USE_EXTERNAL_STARTUP_DATA | 55 #endif // V8_USE_EXTERNAL_STARTUP_DATA |
55 | 56 |
56 #if !defined(_WIN32) && !defined(_WIN64) | 57 #if !defined(_WIN32) && !defined(_WIN64) |
57 #include <unistd.h> // NOLINT | 58 #include <unistd.h> // NOLINT |
58 #else | 59 #else |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 } | 98 } |
98 void* AllocateUninitialized(size_t length) override { | 99 void* AllocateUninitialized(size_t length) override { |
99 return length > 10 * MB ? malloc(1) : malloc(length); | 100 return length > 10 * MB ? malloc(1) : malloc(length); |
100 } | 101 } |
101 void Free(void* p, size_t) override { free(p); } | 102 void Free(void* p, size_t) override { free(p); } |
102 }; | 103 }; |
103 | 104 |
104 | 105 |
105 v8::Platform* g_platform = NULL; | 106 v8::Platform* g_platform = NULL; |
106 | 107 |
| 108 |
| 109 #ifndef V8_SHARED |
| 110 bool FindInObjectList(Handle<Object> object, const Shell::ObjectList& list) { |
| 111 for (int i = 0; i < list.length(); ++i) { |
| 112 if (list[i]->StrictEquals(object)) { |
| 113 return true; |
| 114 } |
| 115 } |
| 116 return false; |
| 117 } |
| 118 #endif // !V8_SHARED |
| 119 |
| 120 |
107 } // namespace | 121 } // namespace |
108 | 122 |
109 | 123 |
110 static Handle<Value> Throw(Isolate* isolate, const char* message) { | 124 static Handle<Value> Throw(Isolate* isolate, const char* message) { |
111 return isolate->ThrowException(String::NewFromUtf8(isolate, message)); | 125 return isolate->ThrowException(String::NewFromUtf8(isolate, message)); |
112 } | 126 } |
113 | 127 |
114 | 128 |
115 | 129 |
116 class PerIsolateData { | 130 class PerIsolateData { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 | 198 |
185 #ifndef V8_SHARED | 199 #ifndef V8_SHARED |
186 CounterMap* Shell::counter_map_; | 200 CounterMap* Shell::counter_map_; |
187 base::OS::MemoryMappedFile* Shell::counters_file_ = NULL; | 201 base::OS::MemoryMappedFile* Shell::counters_file_ = NULL; |
188 CounterCollection Shell::local_counters_; | 202 CounterCollection Shell::local_counters_; |
189 CounterCollection* Shell::counters_ = &local_counters_; | 203 CounterCollection* Shell::counters_ = &local_counters_; |
190 base::Mutex Shell::context_mutex_; | 204 base::Mutex Shell::context_mutex_; |
191 const base::TimeTicks Shell::kInitialTicks = | 205 const base::TimeTicks Shell::kInitialTicks = |
192 base::TimeTicks::HighResolutionNow(); | 206 base::TimeTicks::HighResolutionNow(); |
193 Persistent<Context> Shell::utility_context_; | 207 Persistent<Context> Shell::utility_context_; |
| 208 i::List<Worker*> Shell::workers_; |
| 209 i::List<SharedArrayBuffer::Contents> Shell::externalized_shared_contents_; |
194 #endif // !V8_SHARED | 210 #endif // !V8_SHARED |
195 | 211 |
196 Persistent<Context> Shell::evaluation_context_; | 212 Persistent<Context> Shell::evaluation_context_; |
| 213 ArrayBuffer::Allocator* Shell::array_buffer_allocator; |
197 ShellOptions Shell::options; | 214 ShellOptions Shell::options; |
198 const char* Shell::kPrompt = "d8> "; | 215 const char* Shell::kPrompt = "d8> "; |
199 | 216 |
200 #ifndef V8_SHARED | 217 #ifndef V8_SHARED |
201 bool CounterMap::Match(void* key1, void* key2) { | 218 bool CounterMap::Match(void* key1, void* key2) { |
202 const char* name1 = reinterpret_cast<const char*>(key1); | 219 const char* name1 = reinterpret_cast<const char*>(key1); |
203 const char* name2 = reinterpret_cast<const char*>(key2); | 220 const char* name2 = reinterpret_cast<const char*>(key2); |
204 return strcmp(name1, name2) == 0; | 221 return strcmp(name1, name2) == 0; |
205 } | 222 } |
206 #endif // !V8_SHARED | 223 #endif // !V8_SHARED |
(...skipping 12 matching lines...) Expand all Loading... |
219 uint16_t* source_buffer = new uint16_t[source_length]; | 236 uint16_t* source_buffer = new uint16_t[source_length]; |
220 source->Write(source_buffer, 0, source_length); | 237 source->Write(source_buffer, 0, source_length); |
221 int name_length = 0; | 238 int name_length = 0; |
222 uint16_t* name_buffer = NULL; | 239 uint16_t* name_buffer = NULL; |
223 if (name->IsString()) { | 240 if (name->IsString()) { |
224 Local<String> name_string = Local<String>::Cast(name); | 241 Local<String> name_string = Local<String>::Cast(name); |
225 name_length = name_string->Length(); | 242 name_length = name_string->Length(); |
226 name_buffer = new uint16_t[name_length]; | 243 name_buffer = new uint16_t[name_length]; |
227 name_string->Write(name_buffer, 0, name_length); | 244 name_string->Write(name_buffer, 0, name_length); |
228 } | 245 } |
229 ShellArrayBufferAllocator allocator; | |
230 Isolate::CreateParams create_params; | 246 Isolate::CreateParams create_params; |
231 create_params.array_buffer_allocator = &allocator; | 247 create_params.array_buffer_allocator = Shell::array_buffer_allocator; |
232 Isolate* temp_isolate = Isolate::New(create_params); | 248 Isolate* temp_isolate = Isolate::New(create_params); |
233 ScriptCompiler::CachedData* result = NULL; | 249 ScriptCompiler::CachedData* result = NULL; |
234 { | 250 { |
235 Isolate::Scope isolate_scope(temp_isolate); | 251 Isolate::Scope isolate_scope(temp_isolate); |
236 HandleScope handle_scope(temp_isolate); | 252 HandleScope handle_scope(temp_isolate); |
237 Context::Scope context_scope(Context::New(temp_isolate)); | 253 Context::Scope context_scope(Context::New(temp_isolate)); |
238 Local<String> source_copy = v8::String::NewFromTwoByte( | 254 Local<String> source_copy = v8::String::NewFromTwoByte( |
239 temp_isolate, source_buffer, v8::String::kNormalString, source_length); | 255 temp_isolate, source_buffer, v8::String::kNormalString, source_length); |
240 Local<Value> name_copy; | 256 Local<Value> name_copy; |
241 if (name_buffer) { | 257 if (name_buffer) { |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 String::NewFromUtf8(args.GetIsolate(), *file), | 670 String::NewFromUtf8(args.GetIsolate(), *file), |
655 false, | 671 false, |
656 true)) { | 672 true)) { |
657 Throw(args.GetIsolate(), "Error executing file"); | 673 Throw(args.GetIsolate(), "Error executing file"); |
658 return; | 674 return; |
659 } | 675 } |
660 } | 676 } |
661 } | 677 } |
662 | 678 |
663 | 679 |
| 680 #ifndef V8_SHARED |
| 681 void Shell::WorkerNew(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 682 Isolate* isolate = args.GetIsolate(); |
| 683 HandleScope handle_scope(isolate); |
| 684 if (args.Length() < 1 || !args[0]->IsFunction()) { |
| 685 Throw(args.GetIsolate(), "1st argument must be function"); |
| 686 return; |
| 687 } |
| 688 |
| 689 Worker* worker = new Worker; |
| 690 args.This()->SetInternalField(0, External::New(isolate, worker)); |
| 691 workers_.Add(worker); |
| 692 |
| 693 String::Utf8Value function_string(args[0]->ToString()); |
| 694 worker->StartExecuteInThread(isolate, *function_string); |
| 695 } |
| 696 |
| 697 |
| 698 void Shell::WorkerPostMessage(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 699 Isolate* isolate = args.GetIsolate(); |
| 700 HandleScope handle_scope(isolate); |
| 701 Local<Context> context = isolate->GetCurrentContext(); |
| 702 |
| 703 if (args.Length() < 1) { |
| 704 Throw(isolate, "Invalid argument"); |
| 705 return; |
| 706 } |
| 707 |
| 708 Local<Value> this_value = args.This()->GetInternalField(0); |
| 709 if (!this_value->IsExternal()) { |
| 710 Throw(isolate, "this is not a Worker"); |
| 711 return; |
| 712 } |
| 713 |
| 714 Worker* worker = |
| 715 static_cast<Worker*>(Local<External>::Cast(this_value)->Value()); |
| 716 |
| 717 Handle<Value> message = args[0]; |
| 718 ObjectList to_transfer; |
| 719 if (args.Length() >= 2) { |
| 720 if (!args[1]->IsArray()) { |
| 721 Throw(isolate, "Transfer list must be an Array"); |
| 722 return; |
| 723 } |
| 724 |
| 725 Handle<Array> transfer = Handle<Array>::Cast(args[1]); |
| 726 uint32_t length = transfer->Length(); |
| 727 for (uint32_t i = 0; i < length; ++i) { |
| 728 Handle<Value> element; |
| 729 if (transfer->Get(context, i).ToLocal(&element)) { |
| 730 if (!element->IsArrayBuffer() && !element->IsSharedArrayBuffer()) { |
| 731 Throw(isolate, |
| 732 "Transfer array elements must be an ArrayBuffer or " |
| 733 "SharedArrayBuffer."); |
| 734 break; |
| 735 } |
| 736 |
| 737 to_transfer.Add(Handle<Object>::Cast(element)); |
| 738 } |
| 739 } |
| 740 } |
| 741 |
| 742 ObjectList seen_objects; |
| 743 SerializationData* data = new SerializationData; |
| 744 if (SerializeValue(isolate, message, to_transfer, &seen_objects, data)) { |
| 745 worker->PostMessage(data); |
| 746 } else { |
| 747 delete data; |
| 748 } |
| 749 } |
| 750 |
| 751 |
| 752 void Shell::WorkerGetMessage(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 753 Isolate* isolate = args.GetIsolate(); |
| 754 HandleScope handle_scope(isolate); |
| 755 |
| 756 Local<Value> this_value = args.This()->GetInternalField(0); |
| 757 if (!this_value->IsExternal()) { |
| 758 Throw(isolate, "this is not a Worker"); |
| 759 return; |
| 760 } |
| 761 |
| 762 Worker* worker = |
| 763 static_cast<Worker*>(Local<External>::Cast(this_value)->Value()); |
| 764 |
| 765 SerializationData* data = worker->GetMessage(); |
| 766 if (data) { |
| 767 int offset = 0; |
| 768 Local<Value> data_value; |
| 769 if (Shell::DeserializeValue(isolate, *data, &offset).ToLocal(&data_value)) { |
| 770 args.GetReturnValue().Set(data_value); |
| 771 } |
| 772 delete data; |
| 773 } |
| 774 } |
| 775 |
| 776 |
| 777 void Shell::WorkerTerminate(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 778 Isolate* isolate = args.GetIsolate(); |
| 779 HandleScope handle_scope(isolate); |
| 780 Local<Value> this_value = args.This()->GetInternalField(0); |
| 781 if (!this_value->IsExternal()) { |
| 782 Throw(isolate, "this is not a Worker"); |
| 783 return; |
| 784 } |
| 785 |
| 786 Worker* worker = |
| 787 static_cast<Worker*>(Local<External>::Cast(this_value)->Value()); |
| 788 worker->Terminate(); |
| 789 workers_.RemoveElement(worker); |
| 790 delete worker; |
| 791 } |
| 792 #endif // !V8_SHARED |
| 793 |
| 794 |
664 void Shell::Quit(const v8::FunctionCallbackInfo<v8::Value>& args) { | 795 void Shell::Quit(const v8::FunctionCallbackInfo<v8::Value>& args) { |
665 int exit_code = args[0]->Int32Value(); | 796 int exit_code = args[0]->Int32Value(); |
666 OnExit(args.GetIsolate()); | 797 OnExit(args.GetIsolate()); |
667 exit(exit_code); | 798 exit(exit_code); |
668 } | 799 } |
669 | 800 |
670 | 801 |
671 void Shell::Version(const v8::FunctionCallbackInfo<v8::Value>& args) { | 802 void Shell::Version(const v8::FunctionCallbackInfo<v8::Value>& args) { |
672 args.GetReturnValue().Set( | 803 args.GetReturnValue().Set( |
673 String::NewFromUtf8(args.GetIsolate(), V8::GetVersion())); | 804 String::NewFromUtf8(args.GetIsolate(), V8::GetVersion())); |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 realm_template->SetAccessor(String::NewFromUtf8(isolate, "shared"), | 1116 realm_template->SetAccessor(String::NewFromUtf8(isolate, "shared"), |
986 RealmSharedGet, RealmSharedSet); | 1117 RealmSharedGet, RealmSharedSet); |
987 global_template->Set(String::NewFromUtf8(isolate, "Realm"), realm_template); | 1118 global_template->Set(String::NewFromUtf8(isolate, "Realm"), realm_template); |
988 | 1119 |
989 #ifndef V8_SHARED | 1120 #ifndef V8_SHARED |
990 Handle<ObjectTemplate> performance_template = ObjectTemplate::New(isolate); | 1121 Handle<ObjectTemplate> performance_template = ObjectTemplate::New(isolate); |
991 performance_template->Set(String::NewFromUtf8(isolate, "now"), | 1122 performance_template->Set(String::NewFromUtf8(isolate, "now"), |
992 FunctionTemplate::New(isolate, PerformanceNow)); | 1123 FunctionTemplate::New(isolate, PerformanceNow)); |
993 global_template->Set(String::NewFromUtf8(isolate, "performance"), | 1124 global_template->Set(String::NewFromUtf8(isolate, "performance"), |
994 performance_template); | 1125 performance_template); |
| 1126 |
| 1127 Handle<FunctionTemplate> worker_fun_template = |
| 1128 FunctionTemplate::New(isolate, WorkerNew); |
| 1129 worker_fun_template->PrototypeTemplate()->Set( |
| 1130 String::NewFromUtf8(isolate, "terminate"), |
| 1131 FunctionTemplate::New(isolate, WorkerTerminate)); |
| 1132 worker_fun_template->PrototypeTemplate()->Set( |
| 1133 String::NewFromUtf8(isolate, "postMessage"), |
| 1134 FunctionTemplate::New(isolate, WorkerPostMessage)); |
| 1135 worker_fun_template->PrototypeTemplate()->Set( |
| 1136 String::NewFromUtf8(isolate, "getMessage"), |
| 1137 FunctionTemplate::New(isolate, WorkerGetMessage)); |
| 1138 worker_fun_template->InstanceTemplate()->SetInternalFieldCount(1); |
| 1139 global_template->Set(String::NewFromUtf8(isolate, "Worker"), |
| 1140 worker_fun_template); |
995 #endif // !V8_SHARED | 1141 #endif // !V8_SHARED |
996 | 1142 |
997 Handle<ObjectTemplate> os_templ = ObjectTemplate::New(isolate); | 1143 Handle<ObjectTemplate> os_templ = ObjectTemplate::New(isolate); |
998 AddOSMethods(isolate, os_templ); | 1144 AddOSMethods(isolate, os_templ); |
999 global_template->Set(String::NewFromUtf8(isolate, "os"), os_templ); | 1145 global_template->Set(String::NewFromUtf8(isolate, "os"), os_templ); |
1000 | 1146 |
1001 return global_template; | 1147 return global_template; |
1002 } | 1148 } |
1003 | 1149 |
1004 | 1150 |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1318 base::Thread::Options SourceGroup::GetThreadOptions() { | 1464 base::Thread::Options SourceGroup::GetThreadOptions() { |
1319 // On some systems (OSX 10.6) the stack size default is 0.5Mb or less | 1465 // On some systems (OSX 10.6) the stack size default is 0.5Mb or less |
1320 // which is not enough to parse the big literal expressions used in tests. | 1466 // which is not enough to parse the big literal expressions used in tests. |
1321 // The stack size should be at least StackGuard::kLimitSize + some | 1467 // The stack size should be at least StackGuard::kLimitSize + some |
1322 // OS-specific padding for thread startup code. 2Mbytes seems to be enough. | 1468 // OS-specific padding for thread startup code. 2Mbytes seems to be enough. |
1323 return base::Thread::Options("IsolateThread", 2 * MB); | 1469 return base::Thread::Options("IsolateThread", 2 * MB); |
1324 } | 1470 } |
1325 | 1471 |
1326 | 1472 |
1327 void SourceGroup::ExecuteInThread() { | 1473 void SourceGroup::ExecuteInThread() { |
1328 ShellArrayBufferAllocator allocator; | |
1329 Isolate::CreateParams create_params; | 1474 Isolate::CreateParams create_params; |
1330 create_params.array_buffer_allocator = &allocator; | 1475 create_params.array_buffer_allocator = Shell::array_buffer_allocator; |
1331 Isolate* isolate = Isolate::New(create_params); | 1476 Isolate* isolate = Isolate::New(create_params); |
1332 do { | 1477 do { |
1333 next_semaphore_.Wait(); | 1478 next_semaphore_.Wait(); |
1334 { | 1479 { |
1335 Isolate::Scope iscope(isolate); | 1480 Isolate::Scope iscope(isolate); |
1336 { | 1481 { |
1337 HandleScope scope(isolate); | 1482 HandleScope scope(isolate); |
1338 PerIsolateData data(isolate); | 1483 PerIsolateData data(isolate); |
1339 Local<Context> context = Shell::CreateEvaluationContext(isolate); | 1484 Local<Context> context = Shell::CreateEvaluationContext(isolate); |
1340 { | 1485 { |
(...skipping 21 matching lines...) Expand all Loading... |
1362 | 1507 |
1363 | 1508 |
1364 void SourceGroup::WaitForThread() { | 1509 void SourceGroup::WaitForThread() { |
1365 if (thread_ == NULL) return; | 1510 if (thread_ == NULL) return; |
1366 if (Shell::options.last_run) { | 1511 if (Shell::options.last_run) { |
1367 thread_->Join(); | 1512 thread_->Join(); |
1368 } else { | 1513 } else { |
1369 done_semaphore_.Wait(); | 1514 done_semaphore_.Wait(); |
1370 } | 1515 } |
1371 } | 1516 } |
| 1517 |
| 1518 |
| 1519 SerializationData::~SerializationData() { |
| 1520 // Any ArrayBuffer::Contents are owned by this SerializationData object. |
| 1521 // SharedArrayBuffer::Contents may be used by other threads, so must be |
| 1522 // cleaned up by the main thread in Shell::CleanupWorkers(). |
| 1523 for (int i = 0; i < array_buffer_contents.length(); ++i) { |
| 1524 ArrayBuffer::Contents& contents = array_buffer_contents[i]; |
| 1525 Shell::array_buffer_allocator->Free(contents.Data(), contents.ByteLength()); |
| 1526 } |
| 1527 } |
| 1528 |
| 1529 |
| 1530 void SerializationData::WriteTag(SerializationTag tag) { data.Add(tag); } |
| 1531 |
| 1532 |
| 1533 void SerializationData::WriteMemory(const void* p, int length) { |
| 1534 i::Vector<uint8_t> block = data.AddBlock(0, length); |
| 1535 memcpy(&block[0], p, length); |
| 1536 } |
| 1537 |
| 1538 |
| 1539 void SerializationData::WriteArrayBufferContents( |
| 1540 const ArrayBuffer::Contents& contents) { |
| 1541 array_buffer_contents.Add(contents); |
| 1542 WriteTag(kSerializationTagTransferredArrayBuffer); |
| 1543 int index = array_buffer_contents.length() - 1; |
| 1544 Write(index); |
| 1545 } |
| 1546 |
| 1547 |
| 1548 void SerializationData::WriteSharedArrayBufferContents( |
| 1549 const SharedArrayBuffer::Contents& contents) { |
| 1550 shared_array_buffer_contents.Add(contents); |
| 1551 WriteTag(kSerializationTagTransferredSharedArrayBuffer); |
| 1552 int index = shared_array_buffer_contents.length() - 1; |
| 1553 Write(index); |
| 1554 } |
| 1555 |
| 1556 |
| 1557 SerializationTag SerializationData::ReadTag(int* offset) const { |
| 1558 return static_cast<SerializationTag>(Read<uint8_t>(offset)); |
| 1559 } |
| 1560 |
| 1561 |
| 1562 void SerializationData::ReadMemory(void* p, int length, int* offset) const { |
| 1563 memcpy(p, &data[*offset], length); |
| 1564 (*offset) += length; |
| 1565 } |
| 1566 |
| 1567 |
| 1568 void SerializationData::ReadArrayBufferContents(ArrayBuffer::Contents* contents, |
| 1569 int* offset) const { |
| 1570 int index = Read<int>(offset); |
| 1571 DCHECK(index < array_buffer_contents.length()); |
| 1572 *contents = array_buffer_contents[index]; |
| 1573 } |
| 1574 |
| 1575 |
| 1576 void SerializationData::ReadSharedArrayBufferContents( |
| 1577 SharedArrayBuffer::Contents* contents, int* offset) const { |
| 1578 int index = Read<int>(offset); |
| 1579 DCHECK(index < shared_array_buffer_contents.length()); |
| 1580 *contents = shared_array_buffer_contents[index]; |
| 1581 } |
| 1582 |
| 1583 |
| 1584 void SerializationDataQueue::Enqueue(SerializationData* data) { |
| 1585 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
| 1586 data_.Add(data); |
| 1587 } |
| 1588 |
| 1589 |
| 1590 bool SerializationDataQueue::Dequeue(SerializationData** data) { |
| 1591 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
| 1592 if (data_.is_empty()) return false; |
| 1593 *data = data_.Remove(0); |
| 1594 return true; |
| 1595 } |
| 1596 |
| 1597 |
| 1598 bool SerializationDataQueue::IsEmpty() { |
| 1599 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
| 1600 return data_.is_empty(); |
| 1601 } |
| 1602 |
| 1603 |
| 1604 void SerializationDataQueue::Clear() { |
| 1605 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
| 1606 for (int i = 0; i < data_.length(); ++i) { |
| 1607 delete data_[i]; |
| 1608 } |
| 1609 data_.Clear(); |
| 1610 } |
| 1611 |
| 1612 |
| 1613 Worker::Worker() |
| 1614 : in_semaphore_(0), out_semaphore_(0), thread_(NULL), script_(NULL) {} |
| 1615 |
| 1616 |
| 1617 Worker::~Worker() { Cleanup(); } |
| 1618 |
| 1619 |
| 1620 void Worker::StartExecuteInThread(Isolate* isolate, |
| 1621 const char* function_string) { |
| 1622 if (thread_) { |
| 1623 Throw(isolate, "Only one worker allowed"); |
| 1624 return; |
| 1625 } |
| 1626 |
| 1627 static const char format[] = "(%s).call(this);"; |
| 1628 size_t len = strlen(function_string) + sizeof(format); |
| 1629 |
| 1630 script_ = new char[len + 1]; |
| 1631 i::Vector<char> vec(script_, static_cast<int>(len + 1)); |
| 1632 i::SNPrintF(vec, format, function_string); |
| 1633 |
| 1634 thread_ = new WorkerThread(this); |
| 1635 thread_->Start(); |
| 1636 } |
| 1637 |
| 1638 |
| 1639 void Worker::PostMessage(SerializationData* data) { |
| 1640 in_queue_.Enqueue(data); |
| 1641 in_semaphore_.Signal(); |
| 1642 } |
| 1643 |
| 1644 |
| 1645 SerializationData* Worker::GetMessage() { |
| 1646 SerializationData* data; |
| 1647 while (!out_queue_.Dequeue(&data)) { |
| 1648 out_semaphore_.Wait(); |
| 1649 } |
| 1650 |
| 1651 return data; |
| 1652 } |
| 1653 |
| 1654 |
| 1655 void Worker::Terminate() { |
| 1656 if (thread_ == NULL) return; |
| 1657 PostMessage(NULL); |
| 1658 thread_->Join(); |
| 1659 Cleanup(); |
| 1660 } |
| 1661 |
| 1662 |
| 1663 void Worker::ExecuteInThread() { |
| 1664 Isolate::CreateParams create_params; |
| 1665 create_params.array_buffer_allocator = Shell::array_buffer_allocator; |
| 1666 Isolate* isolate = Isolate::New(create_params); |
| 1667 { |
| 1668 Isolate::Scope iscope(isolate); |
| 1669 { |
| 1670 HandleScope scope(isolate); |
| 1671 PerIsolateData data(isolate); |
| 1672 Local<Context> context = Shell::CreateEvaluationContext(isolate); |
| 1673 { |
| 1674 Context::Scope cscope(context); |
| 1675 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
| 1676 |
| 1677 Handle<Object> global = context->Global(); |
| 1678 Handle<Value> this_value = External::New(isolate, this); |
| 1679 Handle<FunctionTemplate> postmessage_fun_template = |
| 1680 FunctionTemplate::New(isolate, PostMessageOut, this_value); |
| 1681 |
| 1682 Handle<Function> postmessage_fun; |
| 1683 if (postmessage_fun_template->GetFunction(context) |
| 1684 .ToLocal(&postmessage_fun)) { |
| 1685 global->Set(String::NewFromUtf8(isolate, "postMessage"), |
| 1686 postmessage_fun); |
| 1687 } |
| 1688 |
| 1689 // First run the script |
| 1690 Handle<String> file_name = String::NewFromUtf8(isolate, "unnamed"); |
| 1691 Handle<String> source = String::NewFromUtf8(isolate, script_); |
| 1692 Shell::ExecuteString(isolate, source, file_name, false, true); |
| 1693 |
| 1694 // Get the message handler |
| 1695 Handle<Value> onmessage = |
| 1696 global->Get(String::NewFromUtf8(isolate, "onmessage")); |
| 1697 if (onmessage->IsFunction()) { |
| 1698 Handle<Function> onmessage_fun = Handle<Function>::Cast(onmessage); |
| 1699 // Now wait for messages |
| 1700 bool done = false; |
| 1701 while (!done) { |
| 1702 in_semaphore_.Wait(); |
| 1703 SerializationData* data; |
| 1704 if (!in_queue_.Dequeue(&data)) continue; |
| 1705 if (data == NULL) { |
| 1706 done = true; |
| 1707 break; |
| 1708 } |
| 1709 int offset = 0; |
| 1710 Local<Value> data_value; |
| 1711 if (Shell::DeserializeValue(isolate, *data, &offset) |
| 1712 .ToLocal(&data_value)) { |
| 1713 Handle<Value> argv[] = {data_value}; |
| 1714 (void)onmessage_fun->Call(context, global, 1, argv); |
| 1715 } |
| 1716 delete data; |
| 1717 } |
| 1718 } |
| 1719 } |
| 1720 } |
| 1721 } |
| 1722 Shell::CollectGarbage(isolate); |
| 1723 isolate->Dispose(); |
| 1724 } |
| 1725 |
| 1726 |
| 1727 void Worker::Cleanup() { |
| 1728 delete thread_; |
| 1729 thread_ = NULL; |
| 1730 delete[] script_; |
| 1731 script_ = NULL; |
| 1732 in_queue_.Clear(); |
| 1733 out_queue_.Clear(); |
| 1734 } |
| 1735 |
| 1736 |
| 1737 void Worker::PostMessageOut(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 1738 Isolate* isolate = args.GetIsolate(); |
| 1739 HandleScope handle_scope(isolate); |
| 1740 |
| 1741 if (args.Length() < 1) { |
| 1742 Throw(isolate, "Invalid argument"); |
| 1743 return; |
| 1744 } |
| 1745 |
| 1746 Handle<Value> message = args[0]; |
| 1747 |
| 1748 // TODO(binji): Allow transferring from worker to main thread? |
| 1749 Shell::ObjectList to_transfer; |
| 1750 |
| 1751 Shell::ObjectList seen_objects; |
| 1752 SerializationData* data = new SerializationData; |
| 1753 if (Shell::SerializeValue(isolate, message, to_transfer, &seen_objects, |
| 1754 data)) { |
| 1755 DCHECK(args.Data()->IsExternal()); |
| 1756 Handle<External> this_value = Handle<External>::Cast(args.Data()); |
| 1757 Worker* worker = static_cast<Worker*>(this_value->Value()); |
| 1758 worker->out_queue_.Enqueue(data); |
| 1759 worker->out_semaphore_.Signal(); |
| 1760 } else { |
| 1761 delete data; |
| 1762 } |
| 1763 } |
1372 #endif // !V8_SHARED | 1764 #endif // !V8_SHARED |
1373 | 1765 |
1374 | 1766 |
1375 void SetFlagsFromString(const char* flags) { | 1767 void SetFlagsFromString(const char* flags) { |
1376 v8::V8::SetFlagsFromString(flags, static_cast<int>(strlen(flags))); | 1768 v8::V8::SetFlagsFromString(flags, static_cast<int>(strlen(flags))); |
1377 } | 1769 } |
1378 | 1770 |
1379 | 1771 |
1380 bool Shell::SetOptions(int argc, char* argv[]) { | 1772 bool Shell::SetOptions(int argc, char* argv[]) { |
1381 bool logfile_per_isolate = false; | 1773 bool logfile_per_isolate = false; |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1536 Context::Scope cscope(context); | 1928 Context::Scope cscope(context); |
1537 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); | 1929 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
1538 options.isolate_sources[0].Execute(isolate); | 1930 options.isolate_sources[0].Execute(isolate); |
1539 } | 1931 } |
1540 } | 1932 } |
1541 CollectGarbage(isolate); | 1933 CollectGarbage(isolate); |
1542 #ifndef V8_SHARED | 1934 #ifndef V8_SHARED |
1543 for (int i = 1; i < options.num_isolates; ++i) { | 1935 for (int i = 1; i < options.num_isolates; ++i) { |
1544 options.isolate_sources[i].WaitForThread(); | 1936 options.isolate_sources[i].WaitForThread(); |
1545 } | 1937 } |
| 1938 CleanupWorkers(); |
1546 #endif // !V8_SHARED | 1939 #endif // !V8_SHARED |
1547 return 0; | 1940 return 0; |
1548 } | 1941 } |
1549 | 1942 |
1550 | 1943 |
1551 void Shell::CollectGarbage(Isolate* isolate) { | 1944 void Shell::CollectGarbage(Isolate* isolate) { |
1552 if (options.send_idle_notification) { | 1945 if (options.send_idle_notification) { |
1553 const double kLongIdlePauseInSeconds = 1.0; | 1946 const double kLongIdlePauseInSeconds = 1.0; |
1554 isolate->ContextDisposedNotification(); | 1947 isolate->ContextDisposedNotification(); |
1555 isolate->IdleNotificationDeadline( | 1948 isolate->IdleNotificationDeadline( |
1556 g_platform->MonotonicallyIncreasingTime() + kLongIdlePauseInSeconds); | 1949 g_platform->MonotonicallyIncreasingTime() + kLongIdlePauseInSeconds); |
1557 } | 1950 } |
1558 if (options.invoke_weak_callbacks) { | 1951 if (options.invoke_weak_callbacks) { |
1559 // By sending a low memory notifications, we will try hard to collect all | 1952 // By sending a low memory notifications, we will try hard to collect all |
1560 // garbage and will therefore also invoke all weak callbacks of actually | 1953 // garbage and will therefore also invoke all weak callbacks of actually |
1561 // unreachable persistent handles. | 1954 // unreachable persistent handles. |
1562 isolate->LowMemoryNotification(); | 1955 isolate->LowMemoryNotification(); |
1563 } | 1956 } |
1564 } | 1957 } |
1565 | 1958 |
1566 | 1959 |
1567 #ifndef V8_SHARED | 1960 #ifndef V8_SHARED |
| 1961 bool Shell::SerializeValue(Isolate* isolate, Handle<Value> value, |
| 1962 const ObjectList& to_transfer, |
| 1963 ObjectList* seen_objects, |
| 1964 SerializationData* out_data) { |
| 1965 DCHECK(out_data); |
| 1966 HandleScope scope(isolate); |
| 1967 Local<Context> context = isolate->GetCurrentContext(); |
| 1968 |
| 1969 if (value->IsUndefined()) { |
| 1970 out_data->WriteTag(kSerializationTagUndefined); |
| 1971 } else if (value->IsNull()) { |
| 1972 out_data->WriteTag(kSerializationTagNull); |
| 1973 } else if (value->IsTrue()) { |
| 1974 out_data->WriteTag(kSerializationTagTrue); |
| 1975 } else if (value->IsFalse()) { |
| 1976 out_data->WriteTag(kSerializationTagFalse); |
| 1977 } else if (value->IsNumber()) { |
| 1978 Handle<Number> num = Handle<Number>::Cast(value); |
| 1979 double value = num->Value(); |
| 1980 out_data->WriteTag(kSerializationTagNumber); |
| 1981 out_data->Write(value); |
| 1982 } else if (value->IsString()) { |
| 1983 v8::String::Utf8Value str(value); |
| 1984 out_data->WriteTag(kSerializationTagString); |
| 1985 out_data->Write(str.length()); |
| 1986 out_data->WriteMemory(*str, str.length()); |
| 1987 } else if (value->IsArray()) { |
| 1988 Handle<Array> array = Handle<Array>::Cast(value); |
| 1989 if (FindInObjectList(array, *seen_objects)) { |
| 1990 Throw(isolate, "Duplicated arrays not supported"); |
| 1991 return false; |
| 1992 } |
| 1993 seen_objects->Add(array); |
| 1994 out_data->WriteTag(kSerializationTagArray); |
| 1995 uint32_t length = array->Length(); |
| 1996 out_data->Write(length); |
| 1997 for (uint32_t i = 0; i < length; ++i) { |
| 1998 Local<Value> element_value; |
| 1999 if (array->Get(context, i).ToLocal(&element_value)) { |
| 2000 if (!SerializeValue(isolate, element_value, to_transfer, seen_objects, |
| 2001 out_data)) |
| 2002 return false; |
| 2003 } |
| 2004 } |
| 2005 } else if (value->IsArrayBuffer()) { |
| 2006 Handle<ArrayBuffer> array_buffer = Handle<ArrayBuffer>::Cast(value); |
| 2007 if (FindInObjectList(array_buffer, *seen_objects)) { |
| 2008 Throw(isolate, "Duplicated array buffers not supported"); |
| 2009 return false; |
| 2010 } |
| 2011 seen_objects->Add(array_buffer); |
| 2012 if (FindInObjectList(array_buffer, to_transfer)) { |
| 2013 // Transfer ArrayBuffer |
| 2014 if (!array_buffer->IsNeuterable()) { |
| 2015 Throw(isolate, "Attempting to transfer an un-neuterable ArrayBuffer"); |
| 2016 return false; |
| 2017 } |
| 2018 |
| 2019 ArrayBuffer::Contents contents = array_buffer->Externalize(); |
| 2020 array_buffer->Neuter(); |
| 2021 out_data->WriteArrayBufferContents(contents); |
| 2022 } else { |
| 2023 ArrayBuffer::Contents contents = array_buffer->GetContents(); |
| 2024 // Clone ArrayBuffer |
| 2025 if (contents.ByteLength() > i::kMaxUInt32) { |
| 2026 Throw(isolate, "ArrayBuffer is too big to clone"); |
| 2027 return false; |
| 2028 } |
| 2029 |
| 2030 int byte_length = static_cast<int>(contents.ByteLength()); |
| 2031 out_data->WriteTag(kSerializationTagArrayBuffer); |
| 2032 out_data->Write(byte_length); |
| 2033 out_data->WriteMemory(contents.Data(), |
| 2034 static_cast<int>(contents.ByteLength())); |
| 2035 } |
| 2036 } else if (value->IsSharedArrayBuffer()) { |
| 2037 Handle<SharedArrayBuffer> sab = Handle<SharedArrayBuffer>::Cast(value); |
| 2038 if (FindInObjectList(sab, *seen_objects)) { |
| 2039 Throw(isolate, "Duplicated shared array buffers not supported"); |
| 2040 return false; |
| 2041 } |
| 2042 seen_objects->Add(sab); |
| 2043 if (!FindInObjectList(sab, to_transfer)) { |
| 2044 Throw(isolate, "SharedArrayBuffer must be transferred"); |
| 2045 return false; |
| 2046 } |
| 2047 |
| 2048 SharedArrayBuffer::Contents contents = sab->Externalize(); |
| 2049 out_data->WriteSharedArrayBufferContents(contents); |
| 2050 externalized_shared_contents_.Add(contents); |
| 2051 } else if (value->IsObject()) { |
| 2052 Handle<Object> object = Handle<Object>::Cast(value); |
| 2053 if (FindInObjectList(object, *seen_objects)) { |
| 2054 Throw(isolate, "Duplicated objects not supported"); |
| 2055 return false; |
| 2056 } |
| 2057 seen_objects->Add(object); |
| 2058 Local<Array> property_names; |
| 2059 if (!object->GetOwnPropertyNames(context).ToLocal(&property_names)) { |
| 2060 Throw(isolate, "Unable to get property names"); |
| 2061 return false; |
| 2062 } |
| 2063 |
| 2064 uint32_t length = property_names->Length(); |
| 2065 out_data->WriteTag(kSerializationTagObject); |
| 2066 out_data->Write(length); |
| 2067 for (uint32_t i = 0; i < length; ++i) { |
| 2068 Handle<Value> name; |
| 2069 Handle<Value> property_value; |
| 2070 if (property_names->Get(context, i).ToLocal(&name) && |
| 2071 object->Get(context, name).ToLocal(&property_value)) { |
| 2072 if (!SerializeValue(isolate, name, to_transfer, seen_objects, out_data)) |
| 2073 return false; |
| 2074 if (!SerializeValue(isolate, property_value, to_transfer, seen_objects, |
| 2075 out_data)) |
| 2076 return false; |
| 2077 } |
| 2078 } |
| 2079 } else { |
| 2080 Throw(isolate, "Don't know how to serialize object"); |
| 2081 return false; |
| 2082 } |
| 2083 |
| 2084 return true; |
| 2085 } |
| 2086 |
| 2087 |
| 2088 MaybeLocal<Value> Shell::DeserializeValue(Isolate* isolate, |
| 2089 const SerializationData& data, |
| 2090 int* offset) { |
| 2091 DCHECK(offset); |
| 2092 EscapableHandleScope scope(isolate); |
| 2093 // This function should not use utility_context_ because it is running on a |
| 2094 // different thread. |
| 2095 Local<Value> result; |
| 2096 SerializationTag tag = data.ReadTag(offset); |
| 2097 |
| 2098 switch (tag) { |
| 2099 case kSerializationTagUndefined: |
| 2100 result = Undefined(isolate); |
| 2101 break; |
| 2102 case kSerializationTagNull: |
| 2103 result = Null(isolate); |
| 2104 break; |
| 2105 case kSerializationTagTrue: |
| 2106 result = True(isolate); |
| 2107 break; |
| 2108 case kSerializationTagFalse: |
| 2109 result = False(isolate); |
| 2110 break; |
| 2111 case kSerializationTagNumber: |
| 2112 result = Number::New(isolate, data.Read<double>(offset)); |
| 2113 break; |
| 2114 case kSerializationTagString: { |
| 2115 int length = data.Read<int>(offset); |
| 2116 static char s_buffer[128]; |
| 2117 char* p = s_buffer; |
| 2118 bool allocated = false; |
| 2119 if (length > static_cast<int>(sizeof(s_buffer))) { |
| 2120 p = new char[length]; |
| 2121 allocated = true; |
| 2122 } |
| 2123 data.ReadMemory(p, length, offset); |
| 2124 MaybeLocal<String> str = |
| 2125 String::NewFromUtf8(isolate, p, String::kNormalString, length); |
| 2126 if (!str.IsEmpty()) result = str.ToLocalChecked(); |
| 2127 if (allocated) delete[] p; |
| 2128 break; |
| 2129 } |
| 2130 case kSerializationTagArray: { |
| 2131 uint32_t length = data.Read<uint32_t>(offset); |
| 2132 Handle<Array> array = Array::New(isolate, length); |
| 2133 for (uint32_t i = 0; i < length; ++i) { |
| 2134 Local<Value> element_value; |
| 2135 CHECK(DeserializeValue(isolate, data, offset).ToLocal(&element_value)); |
| 2136 array->Set(i, element_value); |
| 2137 } |
| 2138 result = array; |
| 2139 break; |
| 2140 } |
| 2141 case kSerializationTagObject: { |
| 2142 int length = data.Read<int>(offset); |
| 2143 Handle<Object> object = Object::New(isolate); |
| 2144 for (int i = 0; i < length; ++i) { |
| 2145 Local<Value> property_name; |
| 2146 CHECK(DeserializeValue(isolate, data, offset).ToLocal(&property_name)); |
| 2147 DCHECK(property_name->IsString()); |
| 2148 Local<Value> property_value; |
| 2149 CHECK(DeserializeValue(isolate, data, offset).ToLocal(&property_value)); |
| 2150 object->Set(property_name, property_value); |
| 2151 } |
| 2152 result = object; |
| 2153 break; |
| 2154 } |
| 2155 case kSerializationTagArrayBuffer: { |
| 2156 int byte_length = data.Read<int>(offset); |
| 2157 Handle<ArrayBuffer> array_buffer = ArrayBuffer::New(isolate, byte_length); |
| 2158 ArrayBuffer::Contents contents = array_buffer->GetContents(); |
| 2159 DCHECK(static_cast<size_t>(byte_length) == contents.ByteLength()); |
| 2160 data.ReadMemory(contents.Data(), byte_length, offset); |
| 2161 result = array_buffer; |
| 2162 break; |
| 2163 } |
| 2164 case kSerializationTagTransferredArrayBuffer: { |
| 2165 ArrayBuffer::Contents contents; |
| 2166 data.ReadArrayBufferContents(&contents, offset); |
| 2167 result = |
| 2168 ArrayBuffer::New(isolate, contents.Data(), contents.ByteLength()); |
| 2169 break; |
| 2170 } |
| 2171 case kSerializationTagTransferredSharedArrayBuffer: { |
| 2172 SharedArrayBuffer::Contents contents; |
| 2173 data.ReadSharedArrayBufferContents(&contents, offset); |
| 2174 result = SharedArrayBuffer::New(isolate, contents.Data(), |
| 2175 contents.ByteLength()); |
| 2176 break; |
| 2177 } |
| 2178 default: |
| 2179 UNREACHABLE(); |
| 2180 } |
| 2181 |
| 2182 return scope.Escape(result); |
| 2183 } |
| 2184 |
| 2185 |
| 2186 void Shell::CleanupWorkers() { |
| 2187 for (int i = 0; i < workers_.length(); ++i) { |
| 2188 Worker* worker = workers_[i]; |
| 2189 worker->Terminate(); |
| 2190 delete worker; |
| 2191 } |
| 2192 workers_.Clear(); |
| 2193 |
| 2194 for (int i = 0; i < externalized_shared_contents_.length(); ++i) { |
| 2195 const SharedArrayBuffer::Contents& contents = |
| 2196 externalized_shared_contents_[i]; |
| 2197 Shell::array_buffer_allocator->Free(contents.Data(), contents.ByteLength()); |
| 2198 } |
| 2199 externalized_shared_contents_.Clear(); |
| 2200 } |
| 2201 |
| 2202 |
1568 static void DumpHeapConstants(i::Isolate* isolate) { | 2203 static void DumpHeapConstants(i::Isolate* isolate) { |
1569 i::Heap* heap = isolate->heap(); | 2204 i::Heap* heap = isolate->heap(); |
1570 | 2205 |
1571 // Dump the INSTANCE_TYPES table to the console. | 2206 // Dump the INSTANCE_TYPES table to the console. |
1572 printf("# List of known V8 instance types.\n"); | 2207 printf("# List of known V8 instance types.\n"); |
1573 #define DUMP_TYPE(T) printf(" %d: \"%s\",\n", i::T, #T); | 2208 #define DUMP_TYPE(T) printf(" %d: \"%s\",\n", i::T, #T); |
1574 printf("INSTANCE_TYPES = {\n"); | 2209 printf("INSTANCE_TYPES = {\n"); |
1575 INSTANCE_TYPE_LIST(DUMP_TYPE) | 2210 INSTANCE_TYPE_LIST(DUMP_TYPE) |
1576 printf("}\n"); | 2211 printf("}\n"); |
1577 #undef DUMP_TYPE | 2212 #undef DUMP_TYPE |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1644 v8::V8::Initialize(); | 2279 v8::V8::Initialize(); |
1645 #ifdef V8_USE_EXTERNAL_STARTUP_DATA | 2280 #ifdef V8_USE_EXTERNAL_STARTUP_DATA |
1646 v8::StartupDataHandler startup_data(argv[0], options.natives_blob, | 2281 v8::StartupDataHandler startup_data(argv[0], options.natives_blob, |
1647 options.snapshot_blob); | 2282 options.snapshot_blob); |
1648 #endif | 2283 #endif |
1649 SetFlagsFromString("--trace-hydrogen-file=hydrogen.cfg"); | 2284 SetFlagsFromString("--trace-hydrogen-file=hydrogen.cfg"); |
1650 SetFlagsFromString("--trace-turbo-cfg-file=turbo.cfg"); | 2285 SetFlagsFromString("--trace-turbo-cfg-file=turbo.cfg"); |
1651 SetFlagsFromString("--redirect-code-traces-to=code.asm"); | 2286 SetFlagsFromString("--redirect-code-traces-to=code.asm"); |
1652 int result = 0; | 2287 int result = 0; |
1653 Isolate::CreateParams create_params; | 2288 Isolate::CreateParams create_params; |
1654 ShellArrayBufferAllocator array_buffer_allocator; | 2289 ShellArrayBufferAllocator shell_array_buffer_allocator; |
1655 MockArrayBufferAllocator mock_arraybuffer_allocator; | 2290 MockArrayBufferAllocator mock_arraybuffer_allocator; |
1656 if (options.mock_arraybuffer_allocator) { | 2291 if (options.mock_arraybuffer_allocator) { |
1657 create_params.array_buffer_allocator = &mock_arraybuffer_allocator; | 2292 Shell::array_buffer_allocator = &mock_arraybuffer_allocator; |
1658 } else { | 2293 } else { |
1659 create_params.array_buffer_allocator = &array_buffer_allocator; | 2294 Shell::array_buffer_allocator = &shell_array_buffer_allocator; |
1660 } | 2295 } |
| 2296 create_params.array_buffer_allocator = Shell::array_buffer_allocator; |
1661 #if !defined(V8_SHARED) && defined(ENABLE_GDB_JIT_INTERFACE) | 2297 #if !defined(V8_SHARED) && defined(ENABLE_GDB_JIT_INTERFACE) |
1662 if (i::FLAG_gdbjit) { | 2298 if (i::FLAG_gdbjit) { |
1663 create_params.code_event_handler = i::GDBJITInterface::EventHandler; | 2299 create_params.code_event_handler = i::GDBJITInterface::EventHandler; |
1664 } | 2300 } |
1665 #endif | 2301 #endif |
1666 #ifdef ENABLE_VTUNE_JIT_INTERFACE | 2302 #ifdef ENABLE_VTUNE_JIT_INTERFACE |
1667 create_params.code_event_handler = vTune::GetVtuneCodeEventHandler(); | 2303 create_params.code_event_handler = vTune::GetVtuneCodeEventHandler(); |
1668 #endif | 2304 #endif |
1669 #ifndef V8_SHARED | 2305 #ifndef V8_SHARED |
1670 create_params.constraints.ConfigureDefaults( | 2306 create_params.constraints.ConfigureDefaults( |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1755 } | 2391 } |
1756 | 2392 |
1757 } // namespace v8 | 2393 } // namespace v8 |
1758 | 2394 |
1759 | 2395 |
1760 #ifndef GOOGLE3 | 2396 #ifndef GOOGLE3 |
1761 int main(int argc, char* argv[]) { | 2397 int main(int argc, char* argv[]) { |
1762 return v8::Shell::Main(argc, argv); | 2398 return v8::Shell::Main(argc, argv); |
1763 } | 2399 } |
1764 #endif | 2400 #endif |
OLD | NEW |