Line data Source code
1 : // Copyright 2016 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/parsing/parse-info.h"
6 :
7 : #include "src/ast/ast-source-ranges.h"
8 : #include "src/ast/ast-value-factory.h"
9 : #include "src/ast/ast.h"
10 : #include "src/base/template-utils.h"
11 : #include "src/compiler-dispatcher/compiler-dispatcher.h"
12 : #include "src/counters.h"
13 : #include "src/heap/heap-inl.h"
14 : #include "src/objects-inl.h"
15 : #include "src/objects/scope-info.h"
16 : #include "src/zone/zone.h"
17 :
18 : namespace v8 {
19 : namespace internal {
20 :
21 2441127 : ParseInfo::ParseInfo(AccountingAllocator* zone_allocator)
22 : : zone_(base::make_unique<Zone>(zone_allocator, ZONE_NAME)),
23 : flags_(0),
24 : extension_(nullptr),
25 : script_scope_(nullptr),
26 : stack_limit_(0),
27 : hash_seed_(0),
28 : function_kind_(FunctionKind::kNormalFunction),
29 : script_id_(-1),
30 : start_position_(0),
31 : end_position_(0),
32 : parameters_end_pos_(kNoSourcePosition),
33 : function_literal_id_(FunctionLiteral::kIdTypeInvalid),
34 : max_function_literal_id_(FunctionLiteral::kIdTypeInvalid),
35 : character_stream_(nullptr),
36 : ast_value_factory_(nullptr),
37 : ast_string_constants_(nullptr),
38 : function_name_(nullptr),
39 : runtime_call_stats_(nullptr),
40 : source_range_map_(nullptr),
41 7323385 : literal_(nullptr) {}
42 :
43 9764302 : ParseInfo::ParseInfo(Isolate* isolate, AccountingAllocator* zone_allocator)
44 2441045 : : ParseInfo(zone_allocator) {
45 2441058 : set_hash_seed(isolate->heap()->HashSeed());
46 2441053 : set_stack_limit(isolate->stack_guard()->real_climit());
47 2441053 : set_runtime_call_stats(isolate->counters()->runtime_call_stats());
48 : set_logger(isolate->logger());
49 : set_ast_string_constants(isolate->ast_string_constants());
50 2441053 : if (isolate->is_block_code_coverage()) set_block_coverage_enabled();
51 2441053 : if (isolate->is_collecting_type_profile()) set_collect_type_profile();
52 2441053 : if (isolate->compiler_dispatcher()->IsEnabled()) {
53 98 : parallel_tasks_.reset(new ParallelTasks(isolate->compiler_dispatcher()));
54 : }
55 2441050 : set_might_always_opt(FLAG_always_opt || FLAG_prepare_always_opt);
56 2441050 : set_allow_lazy_compile(FLAG_lazy);
57 2441050 : set_allow_natives_syntax(FLAG_allow_natives_syntax);
58 2441050 : set_allow_harmony_public_fields(FLAG_harmony_public_fields);
59 2441050 : set_allow_harmony_static_fields(FLAG_harmony_static_fields);
60 2441050 : set_allow_harmony_dynamic_import(FLAG_harmony_dynamic_import);
61 2441050 : set_allow_harmony_import_meta(FLAG_harmony_import_meta);
62 2441050 : set_allow_harmony_numeric_separator(FLAG_harmony_numeric_separator);
63 2441050 : set_allow_harmony_private_fields(FLAG_harmony_private_fields);
64 2441050 : set_allow_harmony_private_methods(FLAG_harmony_private_methods);
65 2441050 : }
66 :
67 2248942 : ParseInfo::ParseInfo(Isolate* isolate)
68 1124471 : : ParseInfo(isolate, isolate->allocator()) {
69 1124470 : script_id_ = isolate->heap()->NextScriptId();
70 1124471 : LOG(isolate, ScriptEvent(Logger::ScriptEventType::kReserveId, script_id_));
71 1124471 : }
72 :
73 : template <typename T>
74 719549 : void ParseInfo::SetFunctionInfo(T function) {
75 1438615 : set_is_named_expression(function->is_named_expression());
76 1438690 : set_language_mode(function->language_mode());
77 80 : set_function_kind(function->kind());
78 1438625 : set_declaration(function->is_declaration());
79 1438625 : set_requires_instance_members_initializer(
80 : function->requires_instance_members_initializer());
81 1438626 : set_toplevel(function->is_toplevel());
82 : set_is_iife(function->is_iife());
83 1438630 : set_wrapped_as_function(function->is_wrapped());
84 719395 : }
85 :
86 719302 : ParseInfo::ParseInfo(Isolate* isolate, Handle<SharedFunctionInfo> shared)
87 719302 : : ParseInfo(isolate, isolate->allocator()) {
88 : // Do not support re-parsing top-level function of a wrapped script.
89 : // TODO(yangguo): consider whether we need a top-level function in a
90 : // wrapped script at all.
91 : DCHECK_IMPLIES(is_toplevel(), !Script::cast(shared->script())->is_wrapped());
92 :
93 : set_allow_lazy_parsing(true);
94 1438607 : set_asm_wasm_broken(shared->is_asm_wasm_broken());
95 :
96 1438605 : set_start_position(shared->StartPosition());
97 1438615 : set_end_position(shared->EndPosition());
98 719310 : function_literal_id_ = shared->FunctionLiteralId(isolate);
99 719314 : SetFunctionInfo(shared);
100 :
101 1438623 : Handle<Script> script(Script::cast(shared->script()), isolate);
102 719308 : set_script(script);
103 :
104 719316 : if (shared->HasOuterScopeInfo()) {
105 883732 : set_outer_scope_info(handle(shared->GetOuterScopeInfo(), isolate));
106 : }
107 :
108 : // CollectTypeProfile uses its own feedback slots. If we have existing
109 : // FeedbackMetadata, we can only collect type profile if the feedback vector
110 : // has the appropriate slots.
111 : set_collect_type_profile(
112 719449 : isolate->is_collecting_type_profile() &&
113 719449 : (shared->HasFeedbackMetadata()
114 719309 : ? shared->feedback_metadata()->HasTypeProfileSlot()
115 1438618 : : script->IsUserJavaScript()));
116 719309 : }
117 :
118 597275 : ParseInfo::ParseInfo(Isolate* isolate, Handle<Script> script)
119 597275 : : ParseInfo(isolate, isolate->allocator()) {
120 597275 : SetScriptForToplevelCompile(isolate, script);
121 597275 : set_collect_type_profile(isolate->is_collecting_type_profile() &&
122 597275 : script->IsUserJavaScript());
123 597275 : }
124 :
125 : // static
126 80 : std::unique_ptr<ParseInfo> ParseInfo::FromParent(
127 240 : const ParseInfo* outer_parse_info, AccountingAllocator* zone_allocator,
128 80 : const FunctionLiteral* literal, const AstRawString* function_name) {
129 : std::unique_ptr<ParseInfo> result =
130 80 : base::make_unique<ParseInfo>(zone_allocator);
131 :
132 : // Replicate shared state of the outer_parse_info.
133 80 : result->flags_ = outer_parse_info->flags_;
134 80 : result->script_id_ = outer_parse_info->script_id_;
135 : result->set_logger(outer_parse_info->logger());
136 : result->set_ast_string_constants(outer_parse_info->ast_string_constants());
137 : result->set_hash_seed(outer_parse_info->hash_seed());
138 :
139 : DCHECK_EQ(outer_parse_info->parameters_end_pos(), kNoSourcePosition);
140 : DCHECK_NULL(outer_parse_info->extension());
141 : DCHECK(outer_parse_info->maybe_outer_scope_info().is_null());
142 :
143 : // Clone the function_name AstRawString into the ParseInfo's own
144 : // AstValueFactory.
145 : const AstRawString* cloned_function_name =
146 : result->GetOrCreateAstValueFactory()->CloneFromOtherFactory(
147 80 : function_name);
148 :
149 : // Setup function specific details.
150 : DCHECK(!literal->is_toplevel());
151 : result->set_function_name(cloned_function_name);
152 80 : result->set_start_position(literal->start_position());
153 80 : result->set_end_position(literal->end_position());
154 : result->set_function_literal_id(literal->function_literal_id());
155 80 : result->SetFunctionInfo(literal);
156 :
157 80 : return result;
158 : }
159 :
160 : ParseInfo::~ParseInfo() = default;
161 :
162 150 : DeclarationScope* ParseInfo::scope() const { return literal()->scope(); }
163 :
164 1111565 : Handle<Script> ParseInfo::CreateScript(Isolate* isolate, Handle<String> source,
165 : ScriptOriginOptions origin_options,
166 : NativesFlag natives) {
167 : // Create a script object describing the script to be compiled.
168 : Handle<Script> script;
169 1111565 : if (script_id_ == -1) {
170 0 : script = isolate->factory()->NewScript(source);
171 : } else {
172 1111565 : script = isolate->factory()->NewScriptWithId(source, script_id_);
173 : }
174 1111568 : if (isolate->NeedsSourcePositionsForProfiling()) {
175 26239 : Script::InitLineEnds(script);
176 : }
177 1111568 : switch (natives) {
178 : case NATIVES_CODE:
179 : script->set_type(Script::TYPE_NATIVE);
180 0 : break;
181 : case EXTENSION_CODE:
182 : script->set_type(Script::TYPE_EXTENSION);
183 3344 : break;
184 : case INSPECTOR_CODE:
185 : script->set_type(Script::TYPE_INSPECTOR);
186 261 : break;
187 : case NOT_NATIVES_CODE:
188 : break;
189 : }
190 1111568 : script->set_origin_options(origin_options);
191 :
192 1111567 : SetScriptForToplevelCompile(isolate, script);
193 1111570 : return script;
194 : }
195 :
196 4882204 : AstValueFactory* ParseInfo::GetOrCreateAstValueFactory() {
197 2441137 : if (!ast_value_factory_.get()) {
198 : ast_value_factory_.reset(
199 2441067 : new AstValueFactory(zone(), ast_string_constants(), hash_seed()));
200 : }
201 2441172 : return ast_value_factory();
202 : }
203 :
204 815 : void ParseInfo::AllocateSourceRangeMap() {
205 : DCHECK(block_coverage_enabled());
206 : set_source_range_map(new (zone()) SourceRangeMap(zone()));
207 815 : }
208 :
209 8049073 : void ParseInfo::ResetCharacterStream() { character_stream_.reset(); }
210 :
211 2441080 : void ParseInfo::set_character_stream(
212 : std::unique_ptr<Utf16CharacterStream> character_stream) {
213 : DCHECK_NULL(character_stream_);
214 : character_stream_.swap(character_stream);
215 2441080 : }
216 :
217 1708842 : void ParseInfo::SetScriptForToplevelCompile(Isolate* isolate,
218 : Handle<Script> script) {
219 1708842 : set_script(script);
220 : set_allow_lazy_parsing();
221 : set_toplevel();
222 1708858 : set_collect_type_profile(isolate->is_collecting_type_profile() &&
223 1708858 : script->IsUserJavaScript());
224 3417690 : set_wrapped_as_function(script->is_wrapped());
225 1708845 : }
226 :
227 2428210 : void ParseInfo::set_script(Handle<Script> script) {
228 2428210 : script_ = script;
229 : DCHECK(script_id_ == -1 || script_id_ == script->id());
230 2428215 : script_id_ = script->id();
231 :
232 : set_native(script->type() == Script::TYPE_NATIVE);
233 4856451 : set_eval(script->compilation_type() == Script::COMPILATION_TYPE_EVAL);
234 4856456 : set_module(script->origin_options().IsModule());
235 : DCHECK(!(is_eval() && is_module()));
236 :
237 2429044 : if (block_coverage_enabled() && script->IsUserJavaScript()) {
238 815 : AllocateSourceRangeMap();
239 : }
240 2428229 : }
241 :
242 55 : void ParseInfo::ParallelTasks::Enqueue(ParseInfo* outer_parse_info,
243 : const AstRawString* function_name,
244 : FunctionLiteral* literal) {
245 : base::Optional<CompilerDispatcher::JobId> job_id =
246 55 : dispatcher_->Enqueue(outer_parse_info, function_name, literal);
247 55 : if (job_id) {
248 110 : enqueued_jobs_.emplace_front(std::make_pair(literal, *job_id));
249 : }
250 55 : }
251 :
252 : } // namespace internal
253 183867 : } // namespace v8
|