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 "src/api.h" | 5 #include "src/api.h" |
6 | 6 |
7 #include <string.h> // For memcpy, strlen. | 7 #include <string.h> // For memcpy, strlen. |
8 #ifdef V8_USE_ADDRESS_SANITIZER | 8 #ifdef V8_USE_ADDRESS_SANITIZER |
9 #include <sanitizer/asan_interface.h> | 9 #include <sanitizer/asan_interface.h> |
10 #endif // V8_USE_ADDRESS_SANITIZER | 10 #endif // V8_USE_ADDRESS_SANITIZER |
11 #include <cmath> // For isnan. | 11 #include <cmath> // For isnan. |
12 #include "include/v8-debug.h" | 12 #include "include/v8-debug.h" |
13 #include "include/v8-profiler.h" | 13 #include "include/v8-profiler.h" |
14 #include "include/v8-testing.h" | 14 #include "include/v8-testing.h" |
15 #include "src/assert-scope.h" | 15 #include "src/assert-scope.h" |
| 16 #include "src/background-parser-thread.h" |
16 #include "src/base/platform/platform.h" | 17 #include "src/base/platform/platform.h" |
17 #include "src/base/platform/time.h" | 18 #include "src/base/platform/time.h" |
18 #include "src/base/utils/random-number-generator.h" | 19 #include "src/base/utils/random-number-generator.h" |
19 #include "src/bootstrapper.h" | 20 #include "src/bootstrapper.h" |
20 #include "src/code-stubs.h" | 21 #include "src/code-stubs.h" |
21 #include "src/compiler.h" | 22 #include "src/compiler.h" |
22 #include "src/conversions-inl.h" | 23 #include "src/conversions-inl.h" |
23 #include "src/counters.h" | 24 #include "src/counters.h" |
24 #include "src/cpu-profiler.h" | 25 #include "src/cpu-profiler.h" |
25 #include "src/debug.h" | 26 #include "src/debug.h" |
(...skipping 1542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1568 : data(data_), length(length_), buffer_policy(buffer_policy_) {} | 1569 : data(data_), length(length_), buffer_policy(buffer_policy_) {} |
1569 | 1570 |
1570 | 1571 |
1571 ScriptCompiler::CachedData::~CachedData() { | 1572 ScriptCompiler::CachedData::~CachedData() { |
1572 if (buffer_policy == BufferOwned) { | 1573 if (buffer_policy == BufferOwned) { |
1573 delete[] data; | 1574 delete[] data; |
1574 } | 1575 } |
1575 } | 1576 } |
1576 | 1577 |
1577 | 1578 |
| 1579 ScriptCompiler::StreamedSource::~StreamedSource() { |
| 1580 delete source_stream; |
| 1581 delete cached_data; |
| 1582 delete info; |
| 1583 } |
| 1584 |
| 1585 |
1578 Local<Script> UnboundScript::BindToCurrentContext() { | 1586 Local<Script> UnboundScript::BindToCurrentContext() { |
1579 i::Handle<i::HeapObject> obj = | 1587 i::Handle<i::HeapObject> obj = |
1580 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this)); | 1588 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this)); |
1581 i::Handle<i::SharedFunctionInfo> | 1589 i::Handle<i::SharedFunctionInfo> |
1582 function_info(i::SharedFunctionInfo::cast(*obj), obj->GetIsolate()); | 1590 function_info(i::SharedFunctionInfo::cast(*obj), obj->GetIsolate()); |
1583 i::Handle<i::JSFunction> function = | 1591 i::Handle<i::JSFunction> function = |
1584 obj->GetIsolate()->factory()->NewFunctionFromSharedFunctionInfo( | 1592 obj->GetIsolate()->factory()->NewFunctionFromSharedFunctionInfo( |
1585 function_info, obj->GetIsolate()->global_context()); | 1593 function_info, obj->GetIsolate()->global_context()); |
1586 return ToApiHandle<Script>(function); | 1594 return ToApiHandle<Script>(function); |
1587 } | 1595 } |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1768 script_data->data(), script_data->length(), CachedData::BufferOwned); | 1776 script_data->data(), script_data->length(), CachedData::BufferOwned); |
1769 script_data->ReleaseDataOwnership(); | 1777 script_data->ReleaseDataOwnership(); |
1770 } | 1778 } |
1771 delete script_data; | 1779 delete script_data; |
1772 } | 1780 } |
1773 i::Handle<i::SharedFunctionInfo> result(raw_result, isolate); | 1781 i::Handle<i::SharedFunctionInfo> result(raw_result, isolate); |
1774 return ToApiHandle<UnboundScript>(result); | 1782 return ToApiHandle<UnboundScript>(result); |
1775 } | 1783 } |
1776 | 1784 |
1777 | 1785 |
| 1786 bool ScriptCompiler::StartStreamingScript(Isolate* v8_isolate, |
| 1787 StreamedSource* source, |
| 1788 StreamingCompleteCallback callback, |
| 1789 void* callback_data, |
| 1790 CompileOptions options) { |
| 1791 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); |
| 1792 if (!isolate->global_context().is_null() && |
| 1793 !isolate->global_context()->IsNativeContext()) { |
| 1794 // The context chain is non-trivial, and constructing the corresponding |
| 1795 // non-trivial Scope chain outside the V8 heap is not implemented. Don't |
| 1796 // stream the script. This will only occur if Harmony scoping is enabled and |
| 1797 // a previous script has introduced "let" or "const" variables. TODO(marja): |
| 1798 // Implement externalizing ScopeInfos and constructing non-trivial Scope |
| 1799 // chains independent of the V8 heap so that we can stream also in this |
| 1800 // case. |
| 1801 return false; |
| 1802 } |
| 1803 // At the moment, it's only possible to stream one script per |
| 1804 // time. TODO(marja): get rid of this restriction. Since we need one |
| 1805 // background thread per a script to be streamed, we need to find a trade-off |
| 1806 // between launching new threads and streaming more scripts. |
| 1807 if (isolate->background_parser_thread()->HasTask()) return false; |
| 1808 |
| 1809 source->info = new i::CompilationInfoWithZone(source->source_stream, isolate); |
| 1810 source->info->MarkAsGlobal(); |
| 1811 DCHECK(options == kProduceParserCache || options == kProduceCodeCache || |
| 1812 options == kNoCompileOptions); |
| 1813 bool allow_lazy = !i::Compiler::DebuggerWantsEagerCompilation(source->info); |
| 1814 i::BackgroundParsingTask* task = new i::BackgroundParsingTask( |
| 1815 source, callback, callback_data, allow_lazy, isolate); |
| 1816 if (options == kProduceParserCache || options == kProduceCodeCache) { |
| 1817 source->info->SetCachedData(&(task->script_data_), options); |
| 1818 } |
| 1819 // We don't set the context to the CompilationInfo yet, because the background |
| 1820 // thread cannot do anything with it anyway. We set it just before compilation |
| 1821 // on the foreground thread. |
| 1822 isolate->background_parser_thread()->SetTask(task); |
| 1823 return true; |
| 1824 } |
| 1825 |
| 1826 |
| 1827 Local<Script> ScriptCompiler::Compile(Isolate* v8_isolate, |
| 1828 StreamedSource* source, |
| 1829 Handle<String> full_source_string, |
| 1830 const ScriptOrigin& origin) { |
| 1831 if (source->info->function() == NULL) { |
| 1832 // Parsing has failed. |
| 1833 return Local<Script>(); |
| 1834 } |
| 1835 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); |
| 1836 source->info->ast_value_factory()->Internalize(isolate); |
| 1837 |
| 1838 i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string)); |
| 1839 i::Handle<i::Script> script = isolate->factory()->NewScript(str); |
| 1840 if (!origin.ResourceName().IsEmpty()) { |
| 1841 script->set_name(*Utils::OpenHandle(*(origin.ResourceName()))); |
| 1842 } |
| 1843 if (!origin.ResourceLineOffset().IsEmpty()) { |
| 1844 script->set_line_offset(i::Smi::FromInt( |
| 1845 static_cast<int>(origin.ResourceLineOffset()->Value()))); |
| 1846 } |
| 1847 if (!origin.ResourceColumnOffset().IsEmpty()) { |
| 1848 script->set_column_offset(i::Smi::FromInt( |
| 1849 static_cast<int>(origin.ResourceColumnOffset()->Value()))); |
| 1850 } |
| 1851 if (!origin.ResourceIsSharedCrossOrigin().IsEmpty()) { |
| 1852 script->set_is_shared_cross_origin(origin.ResourceIsSharedCrossOrigin() == |
| 1853 v8::True(v8_isolate)); |
| 1854 } |
| 1855 source->info->set_script(script); |
| 1856 source->info->SetContext(isolate->global_context()); |
| 1857 |
| 1858 ON_BAILOUT(isolate, "v8::ScriptCompiler::Compile()", return Local<Script>()); |
| 1859 LOG_API(isolate, "ScriptCompiler::Compile()"); |
| 1860 ENTER_V8(isolate); |
| 1861 EXCEPTION_PREAMBLE(isolate); |
| 1862 i::Handle<i::SharedFunctionInfo> result = |
| 1863 i::Compiler::CompileStreamedScript(source->info, str->length()); |
| 1864 EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>()); |
| 1865 Local<UnboundScript> generic = ToApiHandle<UnboundScript>(result); |
| 1866 if (generic.IsEmpty()) return Local<Script>(); |
| 1867 return generic->BindToCurrentContext(); |
| 1868 } |
| 1869 |
| 1870 |
1778 Local<Script> ScriptCompiler::Compile( | 1871 Local<Script> ScriptCompiler::Compile( |
1779 Isolate* v8_isolate, | 1872 Isolate* v8_isolate, |
1780 Source* source, | 1873 Source* source, |
1781 CompileOptions options) { | 1874 CompileOptions options) { |
1782 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); | 1875 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); |
1783 ON_BAILOUT(isolate, "v8::ScriptCompiler::Compile()", return Local<Script>()); | 1876 ON_BAILOUT(isolate, "v8::ScriptCompiler::Compile()", return Local<Script>()); |
1784 LOG_API(isolate, "ScriptCompiler::CompiletBound()"); | 1877 LOG_API(isolate, "ScriptCompiler::CompiletBound()"); |
1785 ENTER_V8(isolate); | 1878 ENTER_V8(isolate); |
1786 Local<UnboundScript> generic = CompileUnbound(v8_isolate, source, options); | 1879 Local<UnboundScript> generic = CompileUnbound(v8_isolate, source, options); |
1787 if (generic.IsEmpty()) return Local<Script>(); | 1880 if (generic.IsEmpty()) return Local<Script>(); |
(...skipping 5846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7634 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); | 7727 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); |
7635 Address callback_address = | 7728 Address callback_address = |
7636 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); | 7729 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); |
7637 VMState<EXTERNAL> state(isolate); | 7730 VMState<EXTERNAL> state(isolate); |
7638 ExternalCallbackScope call_scope(isolate, callback_address); | 7731 ExternalCallbackScope call_scope(isolate, callback_address); |
7639 callback(info); | 7732 callback(info); |
7640 } | 7733 } |
7641 | 7734 |
7642 | 7735 |
7643 } } // namespace v8::internal | 7736 } } // namespace v8::internal |
OLD | NEW |