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> |
11 #include <fstream> | 11 #include <fstream> |
12 #include <unordered_map> | 12 #include <unordered_map> |
13 #include <utility> | 13 #include <utility> |
14 #include <vector> | 14 #include <vector> |
15 | 15 |
16 #ifdef ENABLE_VTUNE_JIT_INTERFACE | 16 #ifdef ENABLE_VTUNE_JIT_INTERFACE |
17 #include "src/third_party/vtune/v8-vtune.h" | 17 #include "src/third_party/vtune/v8-vtune.h" |
18 #endif | 18 #endif |
19 | 19 |
20 #include "src/d8.h" | 20 #include "src/d8.h" |
21 #include "src/ostreams.h" | 21 #include "src/ostreams.h" |
22 | 22 |
23 #include "include/libplatform/libplatform.h" | 23 #include "include/libplatform/libplatform.h" |
24 #include "include/libplatform/v8-tracing.h" | 24 #include "include/libplatform/v8-tracing.h" |
25 #include "include/v8-inspector.h" | |
25 #include "src/api.h" | 26 #include "src/api.h" |
26 #include "src/base/cpu.h" | 27 #include "src/base/cpu.h" |
27 #include "src/base/debug/stack_trace.h" | 28 #include "src/base/debug/stack_trace.h" |
28 #include "src/base/logging.h" | 29 #include "src/base/logging.h" |
29 #include "src/base/platform/platform.h" | 30 #include "src/base/platform/platform.h" |
30 #include "src/base/sys-info.h" | 31 #include "src/base/sys-info.h" |
31 #include "src/basic-block-profiler.h" | 32 #include "src/basic-block-profiler.h" |
32 #include "src/interpreter/interpreter.h" | 33 #include "src/interpreter/interpreter.h" |
33 #include "src/snapshot/natives.h" | 34 #include "src/snapshot/natives.h" |
34 #include "src/utils.h" | 35 #include "src/utils.h" |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
589 // Map from normalized module specifier to Module. | 590 // Map from normalized module specifier to Module. |
590 std::unordered_map<std::string, Global<Module>> specifier_to_module_map; | 591 std::unordered_map<std::string, Global<Module>> specifier_to_module_map; |
591 // Map from Module to the directory that Module was loaded from. | 592 // Map from Module to the directory that Module was loaded from. |
592 std::unordered_map<Global<Module>, std::string, ModuleGlobalHash> | 593 std::unordered_map<Global<Module>, std::string, ModuleGlobalHash> |
593 module_to_directory_map; | 594 module_to_directory_map; |
594 }; | 595 }; |
595 | 596 |
596 enum { | 597 enum { |
597 // The debugger reserves the first slot in the Context embedder data. | 598 // The debugger reserves the first slot in the Context embedder data. |
598 kDebugIdIndex = Context::kDebugIdIndex, | 599 kDebugIdIndex = Context::kDebugIdIndex, |
599 kModuleEmbedderDataIndex | 600 kModuleEmbedderDataIndex, |
601 kInspectorClientIndex | |
600 }; | 602 }; |
601 | 603 |
602 void InitializeModuleEmbedderData(Local<Context> context) { | 604 void InitializeModuleEmbedderData(Local<Context> context) { |
603 context->SetAlignedPointerInEmbedderData( | 605 context->SetAlignedPointerInEmbedderData( |
604 kModuleEmbedderDataIndex, new ModuleEmbedderData(context->GetIsolate())); | 606 kModuleEmbedderDataIndex, new ModuleEmbedderData(context->GetIsolate())); |
605 } | 607 } |
606 | 608 |
607 ModuleEmbedderData* GetModuleDataFromContext(Local<Context> context) { | 609 ModuleEmbedderData* GetModuleDataFromContext(Local<Context> context) { |
608 return static_cast<ModuleEmbedderData*>( | 610 return static_cast<ModuleEmbedderData*>( |
609 context->GetAlignedPointerFromEmbedderData(kModuleEmbedderDataIndex)); | 611 context->GetAlignedPointerFromEmbedderData(kModuleEmbedderDataIndex)); |
(...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1752 while (true) { | 1754 while (true) { |
1753 HandleScope inner_scope(isolate); | 1755 HandleScope inner_scope(isolate); |
1754 printf("d8> "); | 1756 printf("d8> "); |
1755 Local<String> input = Shell::ReadFromStdin(isolate); | 1757 Local<String> input = Shell::ReadFromStdin(isolate); |
1756 if (input.IsEmpty()) break; | 1758 if (input.IsEmpty()) break; |
1757 ExecuteString(isolate, input, name, true, true); | 1759 ExecuteString(isolate, input, name, true, true); |
1758 } | 1760 } |
1759 printf("\n"); | 1761 printf("\n"); |
1760 } | 1762 } |
1761 | 1763 |
1764 class InspectorFrontend final : public v8_inspector::V8Inspector::Channel { | |
1765 public: | |
1766 explicit InspectorFrontend(Local<Context> context) { | |
1767 isolate_ = context->GetIsolate(); | |
1768 context_.Reset(isolate_, context); | |
1769 } | |
1770 virtual ~InspectorFrontend() = default; | |
1771 | |
1772 private: | |
1773 void sendProtocolResponse(int callId, | |
1774 const v8_inspector::StringView& message) override { | |
1775 Send(message); | |
1776 } | |
1777 void sendProtocolNotification( | |
1778 const v8_inspector::StringView& message) override { | |
1779 Send(message); | |
1780 } | |
1781 void flushProtocolNotifications() override {} | |
1782 | |
1783 void Send(const v8_inspector::StringView& string) { | |
1784 int length = static_cast<int>(string.length()); | |
1785 DCHECK(length < v8::String::kMaxLength); | |
1786 Local<String> message = | |
1787 (string.is8Bit() | |
1788 ? v8::String::NewFromOneByte( | |
1789 isolate_, | |
1790 reinterpret_cast<const uint8_t*>(string.characters8()), | |
1791 v8::NewStringType::kNormal, length) | |
1792 : v8::String::NewFromTwoByte( | |
1793 isolate_, | |
1794 reinterpret_cast<const uint16_t*>(string.characters16()), | |
1795 v8::NewStringType::kNormal, length)) | |
1796 .ToLocalChecked(); | |
1797 Local<String> callback_name = | |
1798 v8::String::NewFromUtf8(isolate_, "receive", v8::NewStringType::kNormal) | |
1799 .ToLocalChecked(); | |
1800 Local<Context> context = context_.Get(isolate_); | |
1801 Local<Value> callback = | |
1802 context->Global()->Get(context, callback_name).ToLocalChecked(); | |
1803 if (callback->IsFunction()) { | |
1804 v8::TryCatch try_catch(isolate_); | |
1805 Local<Value> args[] = {message}; | |
1806 if (Local<Function>::Cast(callback) | |
1807 ->Call(context, Undefined(isolate_), 1, args) | |
1808 .IsEmpty()) { | |
1809 try_catch.ReThrow(); | |
1810 } | |
1811 } | |
1812 } | |
1813 | |
1814 Isolate* isolate_; | |
1815 Global<Context> context_; | |
1816 }; | |
1817 | |
1818 class InspectorClient : public v8_inspector::V8InspectorClient { | |
1819 public: | |
1820 InspectorClient(Local<Context> context, bool connect) { | |
1821 #ifdef V8_INSPECTOR_ENABLED | |
1822 if (!connect) return; | |
1823 isolate_ = context->GetIsolate(); | |
1824 channel_.reset(new InspectorFrontend(context)); | |
1825 inspector_ = v8_inspector::V8Inspector::create(isolate_, this); | |
1826 session_ = | |
1827 inspector_->connect(1, channel_.get(), v8_inspector::StringView()); | |
1828 context->SetAlignedPointerInEmbedderData(kInspectorClientIndex, this); | |
jgruber
2016/10/19 07:33:03
Just curious - why aren't we using a standard sing
Yang
2016/10/20 07:29:30
d8 can run with --isolate option, in which case we
| |
1829 inspector_->contextCreated( | |
1830 v8_inspector::V8ContextInfo(context, 1, v8_inspector::StringView())); | |
jgruber
2016/10/19 07:33:03
Please add a named constant to replace the 1 for t
Yang
2016/10/20 07:29:30
Done.
| |
1831 | |
1832 Local<Value> function = | |
1833 FunctionTemplate::New(isolate_, SendInspectorMessage) | |
1834 ->GetFunction(context) | |
1835 .ToLocalChecked(); | |
1836 Local<String> function_name = | |
1837 String::NewFromUtf8(isolate_, "send", NewStringType::kNormal) | |
1838 .ToLocalChecked(); | |
1839 CHECK(context->Global()->Set(context, function_name, function).FromJust()); | |
1840 | |
1841 context_.Reset(isolate_, context); | |
1842 #endif // V8_INSPECTOR_ENABLED | |
1843 } | |
1844 | |
1845 static v8_inspector::V8InspectorSession* GetSession(Local<Context> context) { | |
jgruber
2016/10/19 07:33:03
Could this be private?
Yang
2016/10/20 07:29:30
Done.
| |
1846 InspectorClient* inspector_client = static_cast<InspectorClient*>( | |
1847 context->GetAlignedPointerFromEmbedderData(kInspectorClientIndex)); | |
1848 return inspector_client->session_.get(); | |
1849 } | |
1850 | |
1851 Local<Context> ensureDefaultContextInGroup(int groupId) override { | |
1852 CHECK(isolate_); | |
1853 return context_.Get(isolate_); | |
1854 } | |
1855 | |
1856 private: | |
1857 static void SendInspectorMessage( | |
1858 const v8::FunctionCallbackInfo<v8::Value>& args) { | |
1859 Isolate* isolate = args.GetIsolate(); | |
1860 v8::HandleScope handle_scope(isolate); | |
1861 Local<Context> context = isolate->GetCurrentContext(); | |
1862 args.GetReturnValue().Set(Undefined(isolate)); | |
1863 Local<String> message = args[0]->ToString(context).ToLocalChecked(); | |
1864 v8_inspector::V8InspectorSession* session = | |
1865 InspectorClient::GetSession(context); | |
1866 int length = message->Length(); | |
1867 std::unique_ptr<uint16_t> buffer(new uint16_t[length]); | |
1868 message->Write(buffer.get(), 0, length); | |
1869 v8_inspector::StringView message_view(buffer.get(), length); | |
1870 session->dispatchProtocolMessage(message_view); | |
1871 args.GetReturnValue().Set(True(isolate)); | |
1872 } | |
1873 | |
1874 std::unique_ptr<v8_inspector::V8Inspector> inspector_; | |
1875 std::unique_ptr<v8_inspector::V8InspectorSession> session_; | |
1876 std::unique_ptr<v8_inspector::V8Inspector::Channel> channel_; | |
1877 Global<Context> context_; | |
1878 Isolate* isolate_; | |
1879 }; | |
1762 | 1880 |
1763 SourceGroup::~SourceGroup() { | 1881 SourceGroup::~SourceGroup() { |
1764 delete thread_; | 1882 delete thread_; |
1765 thread_ = NULL; | 1883 thread_ = NULL; |
1766 } | 1884 } |
1767 | 1885 |
1768 | 1886 |
1769 void SourceGroup::Execute(Isolate* isolate) { | 1887 void SourceGroup::Execute(Isolate* isolate) { |
1770 bool exception_was_thrown = false; | 1888 bool exception_was_thrown = false; |
1771 for (int i = begin_offset_; i < end_offset_; ++i) { | 1889 for (int i = begin_offset_; i < end_offset_; ++i) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1835 | 1953 |
1836 | 1954 |
1837 base::Thread::Options SourceGroup::GetThreadOptions() { | 1955 base::Thread::Options SourceGroup::GetThreadOptions() { |
1838 // On some systems (OSX 10.6) the stack size default is 0.5Mb or less | 1956 // 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. | 1957 // which is not enough to parse the big literal expressions used in tests. |
1840 // The stack size should be at least StackGuard::kLimitSize + some | 1958 // The stack size should be at least StackGuard::kLimitSize + some |
1841 // OS-specific padding for thread startup code. 2Mbytes seems to be enough. | 1959 // OS-specific padding for thread startup code. 2Mbytes seems to be enough. |
1842 return base::Thread::Options("IsolateThread", 2 * MB); | 1960 return base::Thread::Options("IsolateThread", 2 * MB); |
1843 } | 1961 } |
1844 | 1962 |
1845 | |
1846 void SourceGroup::ExecuteInThread() { | 1963 void SourceGroup::ExecuteInThread() { |
1847 Isolate::CreateParams create_params; | 1964 Isolate::CreateParams create_params; |
1848 create_params.array_buffer_allocator = Shell::array_buffer_allocator; | 1965 create_params.array_buffer_allocator = Shell::array_buffer_allocator; |
1849 Isolate* isolate = Isolate::New(create_params); | 1966 Isolate* isolate = Isolate::New(create_params); |
1850 for (int i = 0; i < Shell::options.stress_runs; ++i) { | 1967 for (int i = 0; i < Shell::options.stress_runs; ++i) { |
1851 next_semaphore_.Wait(); | 1968 next_semaphore_.Wait(); |
1852 { | 1969 { |
1853 Isolate::Scope iscope(isolate); | 1970 Isolate::Scope iscope(isolate); |
1854 { | 1971 { |
1855 HandleScope scope(isolate); | 1972 HandleScope scope(isolate); |
1856 PerIsolateData data(isolate); | 1973 PerIsolateData data(isolate); |
1857 Local<Context> context = Shell::CreateEvaluationContext(isolate); | 1974 Local<Context> context = Shell::CreateEvaluationContext(isolate); |
1858 { | 1975 { |
1859 Context::Scope cscope(context); | 1976 Context::Scope cscope(context); |
1977 InspectorClient inspector_client(context, | |
1978 Shell::options.enable_inspector); | |
1860 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); | 1979 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
1861 Execute(isolate); | 1980 Execute(isolate); |
1862 } | 1981 } |
1863 DisposeModuleEmbedderData(context); | 1982 DisposeModuleEmbedderData(context); |
1864 } | 1983 } |
1865 Shell::CollectGarbage(isolate); | 1984 Shell::CollectGarbage(isolate); |
1866 } | 1985 } |
1867 done_semaphore_.Signal(); | 1986 done_semaphore_.Signal(); |
1868 } | 1987 } |
1869 | 1988 |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2245 printf("Unknown option to --cache.\n"); | 2364 printf("Unknown option to --cache.\n"); |
2246 return false; | 2365 return false; |
2247 } | 2366 } |
2248 argv[i] = NULL; | 2367 argv[i] = NULL; |
2249 } else if (strcmp(argv[i], "--enable-tracing") == 0) { | 2368 } else if (strcmp(argv[i], "--enable-tracing") == 0) { |
2250 options.trace_enabled = true; | 2369 options.trace_enabled = true; |
2251 argv[i] = NULL; | 2370 argv[i] = NULL; |
2252 } else if (strncmp(argv[i], "--trace-config=", 15) == 0) { | 2371 } else if (strncmp(argv[i], "--trace-config=", 15) == 0) { |
2253 options.trace_config = argv[i] + 15; | 2372 options.trace_config = argv[i] + 15; |
2254 argv[i] = NULL; | 2373 argv[i] = NULL; |
2374 } else if (strcmp(argv[i], "--enable-inspector") == 0) { | |
2375 options.enable_inspector = true; | |
2376 argv[i] = NULL; | |
2255 } | 2377 } |
2256 } | 2378 } |
2257 | 2379 |
2258 v8::V8::SetFlagsFromCommandLine(&argc, argv, true); | 2380 v8::V8::SetFlagsFromCommandLine(&argc, argv, true); |
2259 | 2381 |
2260 // Set up isolated source groups. | 2382 // Set up isolated source groups. |
2261 options.isolate_sources = new SourceGroup[options.num_isolates]; | 2383 options.isolate_sources = new SourceGroup[options.num_isolates]; |
2262 SourceGroup* current = options.isolate_sources; | 2384 SourceGroup* current = options.isolate_sources; |
2263 current->Begin(argv, 1); | 2385 current->Begin(argv, 1); |
2264 for (int i = 1; i < argc; i++) { | 2386 for (int i = 1; i < argc; i++) { |
(...skipping 29 matching lines...) Expand all Loading... | |
2294 } | 2416 } |
2295 { | 2417 { |
2296 HandleScope scope(isolate); | 2418 HandleScope scope(isolate); |
2297 Local<Context> context = CreateEvaluationContext(isolate); | 2419 Local<Context> context = CreateEvaluationContext(isolate); |
2298 if (last_run && options.use_interactive_shell()) { | 2420 if (last_run && options.use_interactive_shell()) { |
2299 // Keep using the same context in the interactive shell. | 2421 // Keep using the same context in the interactive shell. |
2300 evaluation_context_.Reset(isolate, context); | 2422 evaluation_context_.Reset(isolate, context); |
2301 } | 2423 } |
2302 { | 2424 { |
2303 Context::Scope cscope(context); | 2425 Context::Scope cscope(context); |
2426 InspectorClient inspector_client(context, options.enable_inspector); | |
2304 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); | 2427 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
2305 options.isolate_sources[0].Execute(isolate); | 2428 options.isolate_sources[0].Execute(isolate); |
2306 } | 2429 } |
2307 DisposeModuleEmbedderData(context); | 2430 DisposeModuleEmbedderData(context); |
2308 } | 2431 } |
2309 CollectGarbage(isolate); | 2432 CollectGarbage(isolate); |
2310 for (int i = 1; i < options.num_isolates; ++i) { | 2433 for (int i = 1; i < options.num_isolates; ++i) { |
2311 if (last_run) { | 2434 if (last_run) { |
2312 options.isolate_sources[i].JoinThread(); | 2435 options.isolate_sources[i].JoinThread(); |
2313 } else { | 2436 } else { |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2814 } | 2937 } |
2815 | 2938 |
2816 } // namespace v8 | 2939 } // namespace v8 |
2817 | 2940 |
2818 | 2941 |
2819 #ifndef GOOGLE3 | 2942 #ifndef GOOGLE3 |
2820 int main(int argc, char* argv[]) { | 2943 int main(int argc, char* argv[]) { |
2821 return v8::Shell::Main(argc, argv); | 2944 return v8::Shell::Main(argc, argv); |
2822 } | 2945 } |
2823 #endif | 2946 #endif |
OLD | NEW |