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 16 matching lines...) Expand all Loading... |
27 #include "src/base/debug/stack_trace.h" | 27 #include "src/base/debug/stack_trace.h" |
28 #include "src/base/logging.h" | 28 #include "src/base/logging.h" |
29 #include "src/base/platform/platform.h" | 29 #include "src/base/platform/platform.h" |
30 #include "src/base/sys-info.h" | 30 #include "src/base/sys-info.h" |
31 #include "src/basic-block-profiler.h" | 31 #include "src/basic-block-profiler.h" |
32 #include "src/interpreter/interpreter.h" | 32 #include "src/interpreter/interpreter.h" |
33 #include "src/snapshot/natives.h" | 33 #include "src/snapshot/natives.h" |
34 #include "src/utils.h" | 34 #include "src/utils.h" |
35 #include "src/v8.h" | 35 #include "src/v8.h" |
36 | 36 |
| 37 #ifdef V8_INSPECTOR_ENABLED |
| 38 #include "include/v8-inspector.h" |
| 39 #endif // V8_INSPECTOR_ENABLED |
| 40 |
37 #if !defined(_WIN32) && !defined(_WIN64) | 41 #if !defined(_WIN32) && !defined(_WIN64) |
38 #include <unistd.h> // NOLINT | 42 #include <unistd.h> // NOLINT |
39 #else | 43 #else |
40 #include <windows.h> // NOLINT | 44 #include <windows.h> // NOLINT |
41 #if defined(_MSC_VER) | 45 #if defined(_MSC_VER) |
42 #include <crtdbg.h> // NOLINT | 46 #include <crtdbg.h> // NOLINT |
43 #endif // defined(_MSC_VER) | 47 #endif // defined(_MSC_VER) |
44 #endif // !defined(_WIN32) && !defined(_WIN64) | 48 #endif // !defined(_WIN32) && !defined(_WIN64) |
45 | 49 |
46 #ifndef DCHECK | 50 #ifndef DCHECK |
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 // Map from normalized module specifier to Module. | 593 // Map from normalized module specifier to Module. |
590 std::unordered_map<std::string, Global<Module>> specifier_to_module_map; | 594 std::unordered_map<std::string, Global<Module>> specifier_to_module_map; |
591 // Map from Module to the directory that Module was loaded from. | 595 // Map from Module to the directory that Module was loaded from. |
592 std::unordered_map<Global<Module>, std::string, ModuleGlobalHash> | 596 std::unordered_map<Global<Module>, std::string, ModuleGlobalHash> |
593 module_to_directory_map; | 597 module_to_directory_map; |
594 }; | 598 }; |
595 | 599 |
596 enum { | 600 enum { |
597 // The debugger reserves the first slot in the Context embedder data. | 601 // The debugger reserves the first slot in the Context embedder data. |
598 kDebugIdIndex = Context::kDebugIdIndex, | 602 kDebugIdIndex = Context::kDebugIdIndex, |
599 kModuleEmbedderDataIndex | 603 kModuleEmbedderDataIndex, |
| 604 kInspectorClientIndex |
600 }; | 605 }; |
601 | 606 |
602 void InitializeModuleEmbedderData(Local<Context> context) { | 607 void InitializeModuleEmbedderData(Local<Context> context) { |
603 context->SetAlignedPointerInEmbedderData( | 608 context->SetAlignedPointerInEmbedderData( |
604 kModuleEmbedderDataIndex, new ModuleEmbedderData(context->GetIsolate())); | 609 kModuleEmbedderDataIndex, new ModuleEmbedderData(context->GetIsolate())); |
605 } | 610 } |
606 | 611 |
607 ModuleEmbedderData* GetModuleDataFromContext(Local<Context> context) { | 612 ModuleEmbedderData* GetModuleDataFromContext(Local<Context> context) { |
608 return static_cast<ModuleEmbedderData*>( | 613 return static_cast<ModuleEmbedderData*>( |
609 context->GetAlignedPointerFromEmbedderData(kModuleEmbedderDataIndex)); | 614 context->GetAlignedPointerFromEmbedderData(kModuleEmbedderDataIndex)); |
(...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1752 while (true) { | 1757 while (true) { |
1753 HandleScope inner_scope(isolate); | 1758 HandleScope inner_scope(isolate); |
1754 printf("d8> "); | 1759 printf("d8> "); |
1755 Local<String> input = Shell::ReadFromStdin(isolate); | 1760 Local<String> input = Shell::ReadFromStdin(isolate); |
1756 if (input.IsEmpty()) break; | 1761 if (input.IsEmpty()) break; |
1757 ExecuteString(isolate, input, name, true, true); | 1762 ExecuteString(isolate, input, name, true, true); |
1758 } | 1763 } |
1759 printf("\n"); | 1764 printf("\n"); |
1760 } | 1765 } |
1761 | 1766 |
| 1767 #ifdef V8_INSPECTOR_ENABLED |
| 1768 class InspectorFrontend final : public v8_inspector::V8Inspector::Channel { |
| 1769 public: |
| 1770 explicit InspectorFrontend(Local<Context> context) { |
| 1771 isolate_ = context->GetIsolate(); |
| 1772 context_.Reset(isolate_, context); |
| 1773 } |
| 1774 virtual ~InspectorFrontend() = default; |
| 1775 |
| 1776 private: |
| 1777 void sendProtocolResponse(int callId, |
| 1778 const v8_inspector::StringView& message) override { |
| 1779 Send(message); |
| 1780 } |
| 1781 void sendProtocolNotification( |
| 1782 const v8_inspector::StringView& message) override { |
| 1783 Send(message); |
| 1784 } |
| 1785 void flushProtocolNotifications() override {} |
| 1786 |
| 1787 void Send(const v8_inspector::StringView& string) { |
| 1788 int length = static_cast<int>(string.length()); |
| 1789 DCHECK(length < v8::String::kMaxLength); |
| 1790 Local<String> message = |
| 1791 (string.is8Bit() |
| 1792 ? v8::String::NewFromOneByte( |
| 1793 isolate_, |
| 1794 reinterpret_cast<const uint8_t*>(string.characters8()), |
| 1795 v8::NewStringType::kNormal, length) |
| 1796 : v8::String::NewFromTwoByte( |
| 1797 isolate_, |
| 1798 reinterpret_cast<const uint16_t*>(string.characters16()), |
| 1799 v8::NewStringType::kNormal, length)) |
| 1800 .ToLocalChecked(); |
| 1801 Local<String> callback_name = |
| 1802 v8::String::NewFromUtf8(isolate_, "receive", v8::NewStringType::kNormal) |
| 1803 .ToLocalChecked(); |
| 1804 Local<Context> context = context_.Get(isolate_); |
| 1805 Local<Value> callback = |
| 1806 context->Global()->Get(context, callback_name).ToLocalChecked(); |
| 1807 if (callback->IsFunction()) { |
| 1808 v8::TryCatch try_catch(isolate_); |
| 1809 Local<Value> args[] = {message}; |
| 1810 if (Local<Function>::Cast(callback) |
| 1811 ->Call(context, Undefined(isolate_), 1, args) |
| 1812 .IsEmpty()) { |
| 1813 try_catch.ReThrow(); |
| 1814 } |
| 1815 } |
| 1816 } |
| 1817 |
| 1818 Isolate* isolate_; |
| 1819 Global<Context> context_; |
| 1820 }; |
| 1821 |
| 1822 class InspectorClient : public v8_inspector::V8InspectorClient { |
| 1823 public: |
| 1824 InspectorClient(Local<Context> context, bool connect) { |
| 1825 if (!connect) return; |
| 1826 isolate_ = context->GetIsolate(); |
| 1827 channel_.reset(new InspectorFrontend(context)); |
| 1828 inspector_ = v8_inspector::V8Inspector::create(isolate_, this); |
| 1829 session_ = |
| 1830 inspector_->connect(1, channel_.get(), v8_inspector::StringView()); |
| 1831 context->SetAlignedPointerInEmbedderData(kInspectorClientIndex, this); |
| 1832 inspector_->contextCreated(v8_inspector::V8ContextInfo( |
| 1833 context, kContextGroupId, v8_inspector::StringView())); |
| 1834 |
| 1835 Local<Value> function = |
| 1836 FunctionTemplate::New(isolate_, SendInspectorMessage) |
| 1837 ->GetFunction(context) |
| 1838 .ToLocalChecked(); |
| 1839 Local<String> function_name = |
| 1840 String::NewFromUtf8(isolate_, "send", NewStringType::kNormal) |
| 1841 .ToLocalChecked(); |
| 1842 CHECK(context->Global()->Set(context, function_name, function).FromJust()); |
| 1843 |
| 1844 context_.Reset(isolate_, context); |
| 1845 } |
| 1846 |
| 1847 private: |
| 1848 static v8_inspector::V8InspectorSession* GetSession(Local<Context> context) { |
| 1849 InspectorClient* inspector_client = static_cast<InspectorClient*>( |
| 1850 context->GetAlignedPointerFromEmbedderData(kInspectorClientIndex)); |
| 1851 return inspector_client->session_.get(); |
| 1852 } |
| 1853 |
| 1854 Local<Context> ensureDefaultContextInGroup(int group_id) override { |
| 1855 DCHECK(isolate_); |
| 1856 DCHECK_EQ(kContextGroupId, group_id); |
| 1857 return context_.Get(isolate_); |
| 1858 } |
| 1859 |
| 1860 static void SendInspectorMessage( |
| 1861 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 1862 Isolate* isolate = args.GetIsolate(); |
| 1863 v8::HandleScope handle_scope(isolate); |
| 1864 Local<Context> context = isolate->GetCurrentContext(); |
| 1865 args.GetReturnValue().Set(Undefined(isolate)); |
| 1866 Local<String> message = args[0]->ToString(context).ToLocalChecked(); |
| 1867 v8_inspector::V8InspectorSession* session = |
| 1868 InspectorClient::GetSession(context); |
| 1869 int length = message->Length(); |
| 1870 std::unique_ptr<uint16_t> buffer(new uint16_t[length]); |
| 1871 message->Write(buffer.get(), 0, length); |
| 1872 v8_inspector::StringView message_view(buffer.get(), length); |
| 1873 session->dispatchProtocolMessage(message_view); |
| 1874 args.GetReturnValue().Set(True(isolate)); |
| 1875 } |
| 1876 |
| 1877 static const int kContextGroupId = 1; |
| 1878 |
| 1879 std::unique_ptr<v8_inspector::V8Inspector> inspector_; |
| 1880 std::unique_ptr<v8_inspector::V8InspectorSession> session_; |
| 1881 std::unique_ptr<v8_inspector::V8Inspector::Channel> channel_; |
| 1882 Global<Context> context_; |
| 1883 Isolate* isolate_; |
| 1884 }; |
| 1885 #else // V8_INSPECTOR_ENABLED |
| 1886 class InspectorClient { |
| 1887 public: |
| 1888 InspectorClient(Local<Context> context, bool connect) { CHECK(!connect); } |
| 1889 }; |
| 1890 #endif // V8_INSPECTOR_ENABLED |
1762 | 1891 |
1763 SourceGroup::~SourceGroup() { | 1892 SourceGroup::~SourceGroup() { |
1764 delete thread_; | 1893 delete thread_; |
1765 thread_ = NULL; | 1894 thread_ = NULL; |
1766 } | 1895 } |
1767 | 1896 |
1768 | 1897 |
1769 void SourceGroup::Execute(Isolate* isolate) { | 1898 void SourceGroup::Execute(Isolate* isolate) { |
1770 bool exception_was_thrown = false; | 1899 bool exception_was_thrown = false; |
1771 for (int i = begin_offset_; i < end_offset_; ++i) { | 1900 for (int i = begin_offset_; i < end_offset_; ++i) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1835 | 1964 |
1836 | 1965 |
1837 base::Thread::Options SourceGroup::GetThreadOptions() { | 1966 base::Thread::Options SourceGroup::GetThreadOptions() { |
1838 // On some systems (OSX 10.6) the stack size default is 0.5Mb or less | 1967 // On some systems (OSX 10.6) the stack size default is 0.5Mb or less |
1839 // which is not enough to parse the big literal expressions used in tests. | 1968 // which is not enough to parse the big literal expressions used in tests. |
1840 // The stack size should be at least StackGuard::kLimitSize + some | 1969 // The stack size should be at least StackGuard::kLimitSize + some |
1841 // OS-specific padding for thread startup code. 2Mbytes seems to be enough. | 1970 // OS-specific padding for thread startup code. 2Mbytes seems to be enough. |
1842 return base::Thread::Options("IsolateThread", 2 * MB); | 1971 return base::Thread::Options("IsolateThread", 2 * MB); |
1843 } | 1972 } |
1844 | 1973 |
1845 | |
1846 void SourceGroup::ExecuteInThread() { | 1974 void SourceGroup::ExecuteInThread() { |
1847 Isolate::CreateParams create_params; | 1975 Isolate::CreateParams create_params; |
1848 create_params.array_buffer_allocator = Shell::array_buffer_allocator; | 1976 create_params.array_buffer_allocator = Shell::array_buffer_allocator; |
1849 Isolate* isolate = Isolate::New(create_params); | 1977 Isolate* isolate = Isolate::New(create_params); |
1850 for (int i = 0; i < Shell::options.stress_runs; ++i) { | 1978 for (int i = 0; i < Shell::options.stress_runs; ++i) { |
1851 next_semaphore_.Wait(); | 1979 next_semaphore_.Wait(); |
1852 { | 1980 { |
1853 Isolate::Scope iscope(isolate); | 1981 Isolate::Scope iscope(isolate); |
1854 { | 1982 { |
1855 HandleScope scope(isolate); | 1983 HandleScope scope(isolate); |
1856 PerIsolateData data(isolate); | 1984 PerIsolateData data(isolate); |
1857 Local<Context> context = Shell::CreateEvaluationContext(isolate); | 1985 Local<Context> context = Shell::CreateEvaluationContext(isolate); |
1858 { | 1986 { |
1859 Context::Scope cscope(context); | 1987 Context::Scope cscope(context); |
| 1988 InspectorClient inspector_client(context, |
| 1989 Shell::options.enable_inspector); |
1860 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); | 1990 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
1861 Execute(isolate); | 1991 Execute(isolate); |
1862 } | 1992 } |
1863 DisposeModuleEmbedderData(context); | 1993 DisposeModuleEmbedderData(context); |
1864 } | 1994 } |
1865 Shell::CollectGarbage(isolate); | 1995 Shell::CollectGarbage(isolate); |
1866 } | 1996 } |
1867 done_semaphore_.Signal(); | 1997 done_semaphore_.Signal(); |
1868 } | 1998 } |
1869 | 1999 |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2245 printf("Unknown option to --cache.\n"); | 2375 printf("Unknown option to --cache.\n"); |
2246 return false; | 2376 return false; |
2247 } | 2377 } |
2248 argv[i] = NULL; | 2378 argv[i] = NULL; |
2249 } else if (strcmp(argv[i], "--enable-tracing") == 0) { | 2379 } else if (strcmp(argv[i], "--enable-tracing") == 0) { |
2250 options.trace_enabled = true; | 2380 options.trace_enabled = true; |
2251 argv[i] = NULL; | 2381 argv[i] = NULL; |
2252 } else if (strncmp(argv[i], "--trace-config=", 15) == 0) { | 2382 } else if (strncmp(argv[i], "--trace-config=", 15) == 0) { |
2253 options.trace_config = argv[i] + 15; | 2383 options.trace_config = argv[i] + 15; |
2254 argv[i] = NULL; | 2384 argv[i] = NULL; |
| 2385 } else if (strcmp(argv[i], "--enable-inspector") == 0) { |
| 2386 options.enable_inspector = true; |
| 2387 argv[i] = NULL; |
2255 } | 2388 } |
2256 } | 2389 } |
2257 | 2390 |
2258 v8::V8::SetFlagsFromCommandLine(&argc, argv, true); | 2391 v8::V8::SetFlagsFromCommandLine(&argc, argv, true); |
2259 | 2392 |
2260 // Set up isolated source groups. | 2393 // Set up isolated source groups. |
2261 options.isolate_sources = new SourceGroup[options.num_isolates]; | 2394 options.isolate_sources = new SourceGroup[options.num_isolates]; |
2262 SourceGroup* current = options.isolate_sources; | 2395 SourceGroup* current = options.isolate_sources; |
2263 current->Begin(argv, 1); | 2396 current->Begin(argv, 1); |
2264 for (int i = 1; i < argc; i++) { | 2397 for (int i = 1; i < argc; i++) { |
(...skipping 29 matching lines...) Expand all Loading... |
2294 } | 2427 } |
2295 { | 2428 { |
2296 HandleScope scope(isolate); | 2429 HandleScope scope(isolate); |
2297 Local<Context> context = CreateEvaluationContext(isolate); | 2430 Local<Context> context = CreateEvaluationContext(isolate); |
2298 if (last_run && options.use_interactive_shell()) { | 2431 if (last_run && options.use_interactive_shell()) { |
2299 // Keep using the same context in the interactive shell. | 2432 // Keep using the same context in the interactive shell. |
2300 evaluation_context_.Reset(isolate, context); | 2433 evaluation_context_.Reset(isolate, context); |
2301 } | 2434 } |
2302 { | 2435 { |
2303 Context::Scope cscope(context); | 2436 Context::Scope cscope(context); |
| 2437 InspectorClient inspector_client(context, options.enable_inspector); |
2304 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); | 2438 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
2305 options.isolate_sources[0].Execute(isolate); | 2439 options.isolate_sources[0].Execute(isolate); |
2306 } | 2440 } |
2307 DisposeModuleEmbedderData(context); | 2441 DisposeModuleEmbedderData(context); |
2308 } | 2442 } |
2309 CollectGarbage(isolate); | 2443 CollectGarbage(isolate); |
2310 for (int i = 1; i < options.num_isolates; ++i) { | 2444 for (int i = 1; i < options.num_isolates; ++i) { |
2311 if (last_run) { | 2445 if (last_run) { |
2312 options.isolate_sources[i].JoinThread(); | 2446 options.isolate_sources[i].JoinThread(); |
2313 } else { | 2447 } else { |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2814 } | 2948 } |
2815 | 2949 |
2816 } // namespace v8 | 2950 } // namespace v8 |
2817 | 2951 |
2818 | 2952 |
2819 #ifndef GOOGLE3 | 2953 #ifndef GOOGLE3 |
2820 int main(int argc, char* argv[]) { | 2954 int main(int argc, char* argv[]) { |
2821 return v8::Shell::Main(argc, argv); | 2955 return v8::Shell::Main(argc, argv); |
2822 } | 2956 } |
2823 #endif | 2957 #endif |
OLD | NEW |