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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
138 | 138 |
139 private: | 139 private: |
140 friend class Shell; | 140 friend class Shell; |
141 friend class RealmScope; | 141 friend class RealmScope; |
142 Isolate* isolate_; | 142 Isolate* isolate_; |
143 int realm_count_; | 143 int realm_count_; |
144 int realm_current_; | 144 int realm_current_; |
145 int realm_switch_; | 145 int realm_switch_; |
146 Persistent<Context>* realms_; | 146 Persistent<Context>* realms_; |
147 Persistent<Value> realm_shared_; | 147 Persistent<Value> realm_shared_; |
148 ArrayBuffer::Allocator* array_buffer_allocator_; | |
148 | 149 |
149 int RealmIndexOrThrow(const v8::FunctionCallbackInfo<v8::Value>& args, | 150 int RealmIndexOrThrow(const v8::FunctionCallbackInfo<v8::Value>& args, |
150 int arg_offset); | 151 int arg_offset); |
151 int RealmFind(Handle<Context> context); | 152 int RealmFind(Handle<Context> context); |
152 }; | 153 }; |
153 | 154 |
154 | 155 |
155 LineEditor *LineEditor::current_ = NULL; | 156 LineEditor *LineEditor::current_ = NULL; |
156 | 157 |
157 | 158 |
(...skipping 26 matching lines...) Expand all Loading... | |
184 | 185 |
185 #ifndef V8_SHARED | 186 #ifndef V8_SHARED |
186 CounterMap* Shell::counter_map_; | 187 CounterMap* Shell::counter_map_; |
187 base::OS::MemoryMappedFile* Shell::counters_file_ = NULL; | 188 base::OS::MemoryMappedFile* Shell::counters_file_ = NULL; |
188 CounterCollection Shell::local_counters_; | 189 CounterCollection Shell::local_counters_; |
189 CounterCollection* Shell::counters_ = &local_counters_; | 190 CounterCollection* Shell::counters_ = &local_counters_; |
190 base::Mutex Shell::context_mutex_; | 191 base::Mutex Shell::context_mutex_; |
191 const base::TimeTicks Shell::kInitialTicks = | 192 const base::TimeTicks Shell::kInitialTicks = |
192 base::TimeTicks::HighResolutionNow(); | 193 base::TimeTicks::HighResolutionNow(); |
193 Persistent<Context> Shell::utility_context_; | 194 Persistent<Context> Shell::utility_context_; |
195 Worker Shell::worker_; | |
196 i::List<v8::SharedArrayBuffer::Contents> Shell::externalized_shared_contents_; | |
194 #endif // !V8_SHARED | 197 #endif // !V8_SHARED |
195 | 198 |
196 Persistent<Context> Shell::evaluation_context_; | 199 Persistent<Context> Shell::evaluation_context_; |
197 ShellOptions Shell::options; | 200 ShellOptions Shell::options; |
198 const char* Shell::kPrompt = "d8> "; | 201 const char* Shell::kPrompt = "d8> "; |
199 | 202 |
200 #ifndef V8_SHARED | 203 #ifndef V8_SHARED |
201 bool CounterMap::Match(void* key1, void* key2) { | 204 bool CounterMap::Match(void* key1, void* key2) { |
202 const char* name1 = reinterpret_cast<const char*>(key1); | 205 const char* name1 = reinterpret_cast<const char*>(key1); |
203 const char* name2 = reinterpret_cast<const char*>(key2); | 206 const char* name2 = reinterpret_cast<const char*>(key2); |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
654 String::NewFromUtf8(args.GetIsolate(), *file), | 657 String::NewFromUtf8(args.GetIsolate(), *file), |
655 false, | 658 false, |
656 true)) { | 659 true)) { |
657 Throw(args.GetIsolate(), "Error executing file"); | 660 Throw(args.GetIsolate(), "Error executing file"); |
658 return; | 661 return; |
659 } | 662 } |
660 } | 663 } |
661 } | 664 } |
662 | 665 |
663 | 666 |
667 #ifndef V8_SHARED | |
668 void Shell::WorkerNew(const v8::FunctionCallbackInfo<v8::Value>& args) { | |
669 Isolate* isolate = args.GetIsolate(); | |
670 HandleScope handle_scope(isolate); | |
671 if (args.Length() < 1 || !args[0]->IsFunction()) { | |
672 Throw(args.GetIsolate(), "1st argument must be function"); | |
673 return; | |
674 } | |
675 if (args.Length() >= 2 && !args[1]->IsSharedArrayBuffer()) { | |
676 Throw(args.GetIsolate(), "2nd argument must be SharedArrayBuffer"); | |
677 return; | |
678 } | |
679 | |
680 String::Utf8Value function_string(args[0]->ToString()); | |
681 v8::SharedArrayBuffer::Contents contents; | |
682 if (args.Length() >= 2) { | |
683 Handle<SharedArrayBuffer> sab = Handle<SharedArrayBuffer>::Cast(args[1]); | |
684 contents = sab->Externalize(); | |
685 externalized_shared_contents_.Add(contents); | |
686 } | |
687 worker_.StartExecuteInThread(isolate, *function_string, contents); | |
688 } | |
689 | |
690 | |
691 void Shell::WorkerJoin(const v8::FunctionCallbackInfo<v8::Value>& args) { | |
692 Isolate* isolate = args.GetIsolate(); | |
693 HandleScope handle_scope(isolate); | |
694 Handle<Value> result = worker_.WaitForThread(isolate); | |
695 args.GetReturnValue().Set(result); | |
696 } | |
697 #endif // !V8_SHARED | |
698 | |
699 | |
664 void Shell::Quit(const v8::FunctionCallbackInfo<v8::Value>& args) { | 700 void Shell::Quit(const v8::FunctionCallbackInfo<v8::Value>& args) { |
665 int exit_code = args[0]->Int32Value(); | 701 int exit_code = args[0]->Int32Value(); |
666 OnExit(args.GetIsolate()); | 702 OnExit(args.GetIsolate()); |
667 exit(exit_code); | 703 exit(exit_code); |
668 } | 704 } |
669 | 705 |
670 | 706 |
671 void Shell::Version(const v8::FunctionCallbackInfo<v8::Value>& args) { | 707 void Shell::Version(const v8::FunctionCallbackInfo<v8::Value>& args) { |
672 args.GetReturnValue().Set( | 708 args.GetReturnValue().Set( |
673 String::NewFromUtf8(args.GetIsolate(), V8::GetVersion())); | 709 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"), | 1021 realm_template->SetAccessor(String::NewFromUtf8(isolate, "shared"), |
986 RealmSharedGet, RealmSharedSet); | 1022 RealmSharedGet, RealmSharedSet); |
987 global_template->Set(String::NewFromUtf8(isolate, "Realm"), realm_template); | 1023 global_template->Set(String::NewFromUtf8(isolate, "Realm"), realm_template); |
988 | 1024 |
989 #ifndef V8_SHARED | 1025 #ifndef V8_SHARED |
990 Handle<ObjectTemplate> performance_template = ObjectTemplate::New(isolate); | 1026 Handle<ObjectTemplate> performance_template = ObjectTemplate::New(isolate); |
991 performance_template->Set(String::NewFromUtf8(isolate, "now"), | 1027 performance_template->Set(String::NewFromUtf8(isolate, "now"), |
992 FunctionTemplate::New(isolate, PerformanceNow)); | 1028 FunctionTemplate::New(isolate, PerformanceNow)); |
993 global_template->Set(String::NewFromUtf8(isolate, "performance"), | 1029 global_template->Set(String::NewFromUtf8(isolate, "performance"), |
994 performance_template); | 1030 performance_template); |
1031 | |
1032 Handle<ObjectTemplate> worker_template = ObjectTemplate::New(isolate); | |
1033 worker_template->Set(String::NewFromUtf8(isolate, "new"), | |
1034 FunctionTemplate::New(isolate, WorkerNew)); | |
1035 worker_template->Set(String::NewFromUtf8(isolate, "join"), | |
1036 FunctionTemplate::New(isolate, WorkerJoin)); | |
1037 global_template->Set(String::NewFromUtf8(isolate, "Worker"), worker_template); | |
995 #endif // !V8_SHARED | 1038 #endif // !V8_SHARED |
996 | 1039 |
997 Handle<ObjectTemplate> os_templ = ObjectTemplate::New(isolate); | 1040 Handle<ObjectTemplate> os_templ = ObjectTemplate::New(isolate); |
998 AddOSMethods(isolate, os_templ); | 1041 AddOSMethods(isolate, os_templ); |
999 global_template->Set(String::NewFromUtf8(isolate, "os"), os_templ); | 1042 global_template->Set(String::NewFromUtf8(isolate, "os"), os_templ); |
1000 | 1043 |
1001 return global_template; | 1044 return global_template; |
1002 } | 1045 } |
1003 | 1046 |
1004 | 1047 |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1362 | 1405 |
1363 | 1406 |
1364 void SourceGroup::WaitForThread() { | 1407 void SourceGroup::WaitForThread() { |
1365 if (thread_ == NULL) return; | 1408 if (thread_ == NULL) return; |
1366 if (Shell::options.last_run) { | 1409 if (Shell::options.last_run) { |
1367 thread_->Join(); | 1410 thread_->Join(); |
1368 } else { | 1411 } else { |
1369 done_semaphore_.Wait(); | 1412 done_semaphore_.Wait(); |
1370 } | 1413 } |
1371 } | 1414 } |
1415 | |
1416 | |
1417 Worker::Worker() : thread_(NULL), script_(NULL), result_json_(NULL) {} | |
1418 | |
1419 | |
1420 Worker::~Worker() { Cleanup(); } | |
1421 | |
1422 | |
1423 void Worker::StartExecuteInThread( | |
1424 Isolate* isolate, const char* function_string, | |
1425 const v8::SharedArrayBuffer::Contents& contents) { | |
1426 if (thread_) { | |
1427 Throw(isolate, "Only one worker allowed"); | |
1428 return; | |
1429 } | |
1430 | |
1431 static const char format[] = "JSON.stringify((%s).call(this, sab));"; | |
binji
2015/06/15 19:11:48
Better way to do this?
| |
1432 size_t len = strlen(function_string) + sizeof(format); | |
1433 | |
1434 script_ = new char[len + 1]; | |
1435 snprintf(script_, len, format, function_string); | |
1436 script_[len] = 0; | |
1437 | |
1438 contents_ = contents; | |
1439 | |
1440 thread_ = new WorkerThread(this); | |
1441 thread_->Start(); | |
1442 } | |
1443 | |
1444 | |
1445 Handle<Value> Worker::WaitForThread(Isolate* isolate) { | |
1446 EscapableHandleScope handle_scope(isolate); | |
1447 Handle<Value> result; | |
1448 | |
1449 if (thread_ == NULL) return result; | |
1450 thread_->Join(); | |
1451 | |
1452 if (result_json_) { | |
1453 Local<String> result_json = String::NewFromUtf8(isolate, result_json_); | |
1454 MaybeLocal<Value> maybe_result = JSON::Parse(isolate, result_json); | |
1455 if (!maybe_result.IsEmpty()) { | |
1456 result = maybe_result.ToLocalChecked(); | |
1457 } | |
1458 } | |
1459 | |
1460 Cleanup(); | |
1461 return handle_scope.Escape(Local<Value>::Cast(result)); | |
1462 } | |
1463 | |
1464 | |
1465 void Worker::ExecuteInThread() { | |
binji
2015/06/15 19:11:48
A lot of this function is copy/paste from other pl
| |
1466 ShellArrayBufferAllocator allocator; | |
1467 Isolate::CreateParams create_params; | |
1468 create_params.array_buffer_allocator = &allocator; | |
1469 Isolate* isolate = Isolate::New(create_params); | |
1470 { | |
1471 Isolate::Scope iscope(isolate); | |
1472 { | |
1473 HandleScope scope(isolate); | |
1474 PerIsolateData data(isolate); | |
1475 Local<Context> context = Shell::CreateEvaluationContext(isolate); | |
1476 { | |
1477 Context::Scope cscope(context); | |
1478 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); | |
1479 | |
1480 Handle<String> sab_name = String::NewFromUtf8(isolate, "sab"); | |
1481 if (contents_.Data()) { | |
1482 Handle<v8::SharedArrayBuffer> sab = v8::SharedArrayBuffer::New( | |
1483 isolate, contents_.Data(), contents_.ByteLength()); | |
1484 context->Global()->Set(sab_name, sab); | |
1485 } else { | |
1486 context->Global()->Set(sab_name, v8::Undefined(isolate)); | |
1487 } | |
1488 | |
1489 Handle<String> file_name = String::NewFromUtf8(isolate, "unnamed"); | |
1490 Handle<String> source = String::NewFromUtf8(isolate, script_); | |
1491 | |
1492 TryCatch try_catch(isolate); | |
1493 Handle<Script> script = | |
1494 Shell::CompileString(isolate, source, file_name, | |
1495 Shell::options.compile_options, Shell::SCRIPT); | |
1496 result_json_ = NULL; | |
1497 if (script.IsEmpty()) { | |
1498 // Print errors that happened during compilation. | |
1499 // TODO(binji): support debugger? | |
1500 Shell::ReportException(isolate, &try_catch); | |
1501 } else { | |
1502 Handle<Value> result = script->Run(); | |
1503 if (result->IsString()) { | |
1504 Handle<String> str_result = Handle<String>::Cast(result); | |
1505 v8::String::Utf8Value str(str_result); | |
1506 result_json_ = new char[str.length() + 1]; | |
1507 memcpy(result_json_, *str, str.length() + 1); | |
1508 } | |
1509 } | |
1510 } | |
1511 } | |
1512 } | |
1513 Shell::CollectGarbage(isolate); | |
1514 isolate->Dispose(); | |
1515 } | |
1516 | |
1517 | |
1518 void Worker::Cleanup() { | |
1519 delete thread_; | |
1520 thread_ = NULL; | |
1521 delete[] script_; | |
1522 script_ = NULL; | |
1523 delete[] result_json_; | |
1524 result_json_ = NULL; | |
1525 } | |
1372 #endif // !V8_SHARED | 1526 #endif // !V8_SHARED |
1373 | 1527 |
1374 | 1528 |
1375 void SetFlagsFromString(const char* flags) { | 1529 void SetFlagsFromString(const char* flags) { |
1376 v8::V8::SetFlagsFromString(flags, static_cast<int>(strlen(flags))); | 1530 v8::V8::SetFlagsFromString(flags, static_cast<int>(strlen(flags))); |
1377 } | 1531 } |
1378 | 1532 |
1379 | 1533 |
1380 bool Shell::SetOptions(int argc, char* argv[]) { | 1534 bool Shell::SetOptions(int argc, char* argv[]) { |
1381 bool logfile_per_isolate = false; | 1535 bool logfile_per_isolate = false; |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1536 Context::Scope cscope(context); | 1690 Context::Scope cscope(context); |
1537 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); | 1691 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
1538 options.isolate_sources[0].Execute(isolate); | 1692 options.isolate_sources[0].Execute(isolate); |
1539 } | 1693 } |
1540 } | 1694 } |
1541 CollectGarbage(isolate); | 1695 CollectGarbage(isolate); |
1542 #ifndef V8_SHARED | 1696 #ifndef V8_SHARED |
1543 for (int i = 1; i < options.num_isolates; ++i) { | 1697 for (int i = 1; i < options.num_isolates; ++i) { |
1544 options.isolate_sources[i].WaitForThread(); | 1698 options.isolate_sources[i].WaitForThread(); |
1545 } | 1699 } |
1700 CleanupWorker(isolate); | |
1546 #endif // !V8_SHARED | 1701 #endif // !V8_SHARED |
1547 return 0; | 1702 return 0; |
1548 } | 1703 } |
1549 | 1704 |
1550 | 1705 |
1551 void Shell::CollectGarbage(Isolate* isolate) { | 1706 void Shell::CollectGarbage(Isolate* isolate) { |
1552 if (options.send_idle_notification) { | 1707 if (options.send_idle_notification) { |
1553 const double kLongIdlePauseInSeconds = 1.0; | 1708 const double kLongIdlePauseInSeconds = 1.0; |
1554 isolate->ContextDisposedNotification(); | 1709 isolate->ContextDisposedNotification(); |
1555 isolate->IdleNotificationDeadline( | 1710 isolate->IdleNotificationDeadline( |
1556 g_platform->MonotonicallyIncreasingTime() + kLongIdlePauseInSeconds); | 1711 g_platform->MonotonicallyIncreasingTime() + kLongIdlePauseInSeconds); |
1557 } | 1712 } |
1558 if (options.invoke_weak_callbacks) { | 1713 if (options.invoke_weak_callbacks) { |
1559 // By sending a low memory notifications, we will try hard to collect all | 1714 // 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 | 1715 // garbage and will therefore also invoke all weak callbacks of actually |
1561 // unreachable persistent handles. | 1716 // unreachable persistent handles. |
1562 isolate->LowMemoryNotification(); | 1717 isolate->LowMemoryNotification(); |
1563 } | 1718 } |
1564 } | 1719 } |
1565 | 1720 |
1566 | 1721 |
1567 #ifndef V8_SHARED | 1722 #ifndef V8_SHARED |
1723 void Shell::CleanupWorker(Isolate* isolate) { | |
1724 { | |
1725 HandleScope scope(isolate); | |
1726 worker_.WaitForThread(isolate); | |
1727 } | |
1728 PerIsolateData* data = PerIsolateData::Get(isolate); | |
1729 | |
1730 for (int i = 0; i < externalized_shared_contents_.length(); ++i) { | |
1731 const v8::SharedArrayBuffer::Contents& contents = | |
1732 externalized_shared_contents_[i]; | |
1733 data->array_buffer_allocator_->Free(contents.Data(), contents.ByteLength()); | |
1734 } | |
1735 externalized_shared_contents_.Clear(); | |
1736 } | |
1737 | |
1738 | |
1568 static void DumpHeapConstants(i::Isolate* isolate) { | 1739 static void DumpHeapConstants(i::Isolate* isolate) { |
1569 i::Heap* heap = isolate->heap(); | 1740 i::Heap* heap = isolate->heap(); |
1570 | 1741 |
1571 // Dump the INSTANCE_TYPES table to the console. | 1742 // Dump the INSTANCE_TYPES table to the console. |
1572 printf("# List of known V8 instance types.\n"); | 1743 printf("# List of known V8 instance types.\n"); |
1573 #define DUMP_TYPE(T) printf(" %d: \"%s\",\n", i::T, #T); | 1744 #define DUMP_TYPE(T) printf(" %d: \"%s\",\n", i::T, #T); |
1574 printf("INSTANCE_TYPES = {\n"); | 1745 printf("INSTANCE_TYPES = {\n"); |
1575 INSTANCE_TYPE_LIST(DUMP_TYPE) | 1746 INSTANCE_TYPE_LIST(DUMP_TYPE) |
1576 printf("}\n"); | 1747 printf("}\n"); |
1577 #undef DUMP_TYPE | 1748 #undef DUMP_TYPE |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1677 create_params.create_histogram_callback = CreateHistogram; | 1848 create_params.create_histogram_callback = CreateHistogram; |
1678 create_params.add_histogram_sample_callback = AddHistogramSample; | 1849 create_params.add_histogram_sample_callback = AddHistogramSample; |
1679 } | 1850 } |
1680 #endif | 1851 #endif |
1681 Isolate* isolate = Isolate::New(create_params); | 1852 Isolate* isolate = Isolate::New(create_params); |
1682 DumbLineEditor dumb_line_editor(isolate); | 1853 DumbLineEditor dumb_line_editor(isolate); |
1683 { | 1854 { |
1684 Isolate::Scope scope(isolate); | 1855 Isolate::Scope scope(isolate); |
1685 Initialize(isolate); | 1856 Initialize(isolate); |
1686 PerIsolateData data(isolate); | 1857 PerIsolateData data(isolate); |
1858 data.array_buffer_allocator_ = create_params.array_buffer_allocator; | |
1687 InitializeDebugger(isolate); | 1859 InitializeDebugger(isolate); |
1688 | 1860 |
1689 #ifndef V8_SHARED | 1861 #ifndef V8_SHARED |
1690 if (options.dump_heap_constants) { | 1862 if (options.dump_heap_constants) { |
1691 DumpHeapConstants(reinterpret_cast<i::Isolate*>(isolate)); | 1863 DumpHeapConstants(reinterpret_cast<i::Isolate*>(isolate)); |
1692 return 0; | 1864 return 0; |
1693 } | 1865 } |
1694 #endif | 1866 #endif |
1695 | 1867 |
1696 if (options.stress_opt || options.stress_deopt) { | 1868 if (options.stress_opt || options.stress_deopt) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1755 } | 1927 } |
1756 | 1928 |
1757 } // namespace v8 | 1929 } // namespace v8 |
1758 | 1930 |
1759 | 1931 |
1760 #ifndef GOOGLE3 | 1932 #ifndef GOOGLE3 |
1761 int main(int argc, char* argv[]) { | 1933 int main(int argc, char* argv[]) { |
1762 return v8::Shell::Main(argc, argv); | 1934 return v8::Shell::Main(argc, argv); |
1763 } | 1935 } |
1764 #endif | 1936 #endif |
OLD | NEW |