Chromium Code Reviews| 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 |