• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #ifndef V8_CODEGEN_COMPILER_H_
6 #define V8_CODEGEN_COMPILER_H_
7 
8 #include <forward_list>
9 #include <memory>
10 
11 #include "src/ast/ast-value-factory.h"
12 #include "src/base/platform/elapsed-timer.h"
13 #include "src/base/small-vector.h"
14 #include "src/codegen/bailout-reason.h"
15 #include "src/common/globals.h"
16 #include "src/execution/isolate.h"
17 #include "src/execution/local-isolate.h"
18 #include "src/handles/persistent-handles.h"
19 #include "src/logging/code-events.h"
20 #include "src/objects/contexts.h"
21 #include "src/objects/debug-objects.h"
22 #include "src/parsing/parse-info.h"
23 #include "src/parsing/pending-compilation-error-handler.h"
24 #include "src/snapshot/code-serializer.h"
25 #include "src/utils/allocation.h"
26 #include "src/zone/zone.h"
27 
28 namespace v8 {
29 namespace internal {
30 
31 // Forward declarations.
32 class AlignedCachedData;
33 class BackgroundCompileTask;
34 class IsCompiledScope;
35 class OptimizedCompilationInfo;
36 class ParseInfo;
37 class RuntimeCallStats;
38 class TimedHistogram;
39 class TurbofanCompilationJob;
40 class UnoptimizedCompilationInfo;
41 class UnoptimizedCompilationJob;
42 class UnoptimizedFrame;
43 class WorkerThreadRuntimeCallStats;
44 struct ScriptDetails;
45 struct ScriptStreamingData;
46 
47 namespace maglev {
48 class MaglevCompilationJob;
49 }  // namespace maglev
50 
51 // The V8 compiler API.
52 //
53 // This is the central hub for dispatching to the various compilers within V8.
54 // Logic for which compiler to choose and how to wire compilation results into
55 // the object heap should be kept inside this class.
56 //
57 // General strategy: Scripts are translated into anonymous functions w/o
58 // parameters which then can be executed. If the source code contains other
59 // functions, they might be compiled and allocated as part of the compilation
60 // of the source code or deferred for lazy compilation at a later point.
61 class V8_EXPORT_PRIVATE Compiler : public AllStatic {
62  public:
63   enum ClearExceptionFlag { KEEP_EXCEPTION, CLEAR_EXCEPTION };
64 
65   // ===========================================================================
66   // The following family of methods ensures a given function is compiled. The
67   // general contract is that failures will be reported by returning {false},
68   // whereas successful compilation ensures the {is_compiled} predicate on the
69   // given function holds (except for live-edit, which compiles the world).
70 
71   static bool Compile(Isolate* isolate, Handle<SharedFunctionInfo> shared,
72                       ClearExceptionFlag flag,
73                       IsCompiledScope* is_compiled_scope,
74                       CreateSourcePositions create_source_positions_flag =
75                           CreateSourcePositions::kNo);
76   static bool Compile(Isolate* isolate, Handle<JSFunction> function,
77                       ClearExceptionFlag flag,
78                       IsCompiledScope* is_compiled_scope);
79   static MaybeHandle<SharedFunctionInfo> CompileToplevel(
80       ParseInfo* parse_info, Handle<Script> script, Isolate* isolate,
81       IsCompiledScope* is_compiled_scope);
82 
83   static bool CompileSharedWithBaseline(Isolate* isolate,
84                                         Handle<SharedFunctionInfo> shared,
85                                         ClearExceptionFlag flag,
86                                         IsCompiledScope* is_compiled_scope);
87   static bool CompileBaseline(Isolate* isolate, Handle<JSFunction> function,
88                               ClearExceptionFlag flag,
89                               IsCompiledScope* is_compiled_scope);
90 
91   static bool CompileMaglev(Isolate* isolate, Handle<JSFunction> function,
92                             ConcurrencyMode mode,
93                             IsCompiledScope* is_compiled_scope);
94 
95   static void CompileOptimized(Isolate* isolate, Handle<JSFunction> function,
96                                ConcurrencyMode mode, CodeKind code_kind);
97 
98   // Generate and return optimized code for OSR. The empty handle is returned
99   // either on failure, or after spawning a concurrent OSR task (in which case
100   // a future OSR request will pick up the resulting code object).
101   V8_WARN_UNUSED_RESULT static MaybeHandle<CodeT> CompileOptimizedOSR(
102       Isolate* isolate, Handle<JSFunction> function, BytecodeOffset osr_offset,
103       UnoptimizedFrame* frame, ConcurrencyMode mode);
104 
105   V8_WARN_UNUSED_RESULT static MaybeHandle<SharedFunctionInfo>
106   CompileForLiveEdit(ParseInfo* parse_info, Handle<Script> script,
107                      Isolate* isolate);
108 
109   // Collect source positions for a function that has already been compiled to
110   // bytecode, but for which source positions were not collected (e.g. because
111   // they were not immediately needed).
112   static bool CollectSourcePositions(Isolate* isolate,
113                                      Handle<SharedFunctionInfo> shared);
114 
115   // Finalize and install code from previously run background compile task.
116   static bool FinalizeBackgroundCompileTask(BackgroundCompileTask* task,
117                                             Isolate* isolate,
118                                             ClearExceptionFlag flag);
119 
120   // Dispose a job without finalization.
121   static void DisposeTurbofanCompilationJob(TurbofanCompilationJob* job,
122                                             bool restore_function_code);
123 
124   // Finalize and install Turbofan code from a previously run job.
125   static bool FinalizeTurbofanCompilationJob(TurbofanCompilationJob* job,
126                                              Isolate* isolate);
127 
128   // Finalize and install Maglev code from a previously run job.
129   static bool FinalizeMaglevCompilationJob(maglev::MaglevCompilationJob* job,
130                                            Isolate* isolate);
131 
132   // Give the compiler a chance to perform low-latency initialization tasks of
133   // the given {function} on its instantiation. Note that only the runtime will
134   // offer this chance, optimized closure instantiation will not call this.
135   static void PostInstantiation(Handle<JSFunction> function);
136 
137   // ===========================================================================
138   // The following family of methods instantiates new functions for scripts or
139   // function literals. The decision whether those functions will be compiled,
140   // is left to the discretion of the compiler.
141   //
142   // Please note this interface returns shared function infos.  This means you
143   // need to call Factory::NewFunctionFromSharedFunctionInfo before you have a
144   // real function with a context.
145 
146   // Create a (bound) function for a String source within a context for eval.
147   V8_WARN_UNUSED_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval(
148       Handle<String> source, Handle<SharedFunctionInfo> outer_info,
149       Handle<Context> context, LanguageMode language_mode,
150       ParseRestriction restriction, int parameters_end_pos,
151       int eval_scope_position, int eval_position,
152       ParsingWhileDebugging parsing_while_debugging =
153           ParsingWhileDebugging::kNo);
154 
155   // Create a function that results from wrapping |source| in a function,
156   // with |arguments| being a list of parameters for that function.
157   V8_WARN_UNUSED_RESULT static MaybeHandle<JSFunction> GetWrappedFunction(
158       Handle<String> source, Handle<FixedArray> arguments,
159       Handle<Context> context, const ScriptDetails& script_details,
160       AlignedCachedData* cached_data,
161       v8::ScriptCompiler::CompileOptions compile_options,
162       v8::ScriptCompiler::NoCacheReason no_cache_reason);
163 
164   // Create a (bound) function for a String source within a context for eval.
165   V8_WARN_UNUSED_RESULT static MaybeHandle<JSFunction> GetFunctionFromString(
166       Handle<Context> context, Handle<i::Object> source,
167       ParseRestriction restriction, int parameters_end_pos, bool is_code_like);
168 
169   // Decompose GetFunctionFromString into two functions, to allow callers to
170   // deal seperately with a case of object not handled by the embedder.
171   V8_WARN_UNUSED_RESULT static std::pair<MaybeHandle<String>, bool>
172   ValidateDynamicCompilationSource(Isolate* isolate, Handle<Context> context,
173                                    Handle<i::Object> source_object,
174                                    bool is_code_like = false);
175   V8_WARN_UNUSED_RESULT static MaybeHandle<JSFunction>
176   GetFunctionFromValidatedString(Handle<Context> context,
177                                  MaybeHandle<String> source,
178                                  ParseRestriction restriction,
179                                  int parameters_end_pos);
180 
181   // Create a shared function info object for a String source.
182   static MaybeHandle<SharedFunctionInfo> GetSharedFunctionInfoForScript(
183       Isolate* isolate, Handle<String> source,
184       const ScriptDetails& script_details,
185       ScriptCompiler::CompileOptions compile_options,
186       ScriptCompiler::NoCacheReason no_cache_reason,
187       NativesFlag is_natives_code);
188 
189   // Create a shared function info object for a String source.
190   static MaybeHandle<SharedFunctionInfo>
191   GetSharedFunctionInfoForScriptWithExtension(
192       Isolate* isolate, Handle<String> source,
193       const ScriptDetails& script_details, v8::Extension* extension,
194       ScriptCompiler::CompileOptions compile_options,
195       NativesFlag is_natives_code);
196 
197   // Create a shared function info object for a String source and serialized
198   // cached data. The cached data may be rejected, in which case this function
199   // will set cached_data->rejected() to true.
200   static MaybeHandle<SharedFunctionInfo>
201   GetSharedFunctionInfoForScriptWithCachedData(
202       Isolate* isolate, Handle<String> source,
203       const ScriptDetails& script_details, AlignedCachedData* cached_data,
204       ScriptCompiler::CompileOptions compile_options,
205       ScriptCompiler::NoCacheReason no_cache_reason,
206       NativesFlag is_natives_code);
207 
208   // Create a shared function info object for a String source and a task that
209   // has deserialized cached data on a background thread. The cached data from
210   // the task may be rejected, in which case this function will set
211   // deserialize_task->rejected() to true.
212   static MaybeHandle<SharedFunctionInfo>
213   GetSharedFunctionInfoForScriptWithDeserializeTask(
214       Isolate* isolate, Handle<String> source,
215       const ScriptDetails& script_details,
216       BackgroundDeserializeTask* deserialize_task,
217       ScriptCompiler::CompileOptions compile_options,
218       ScriptCompiler::NoCacheReason no_cache_reason,
219       NativesFlag is_natives_code);
220 
221   // Create a shared function info object for a Script source that has already
222   // been parsed and possibly compiled on a background thread while being loaded
223   // from a streamed source. On return, the data held by |streaming_data| will
224   // have been released, however the object itself isn't freed and is still
225   // owned by the caller.
226   static MaybeHandle<SharedFunctionInfo> GetSharedFunctionInfoForStreamedScript(
227       Isolate* isolate, Handle<String> source,
228       const ScriptDetails& script_details, ScriptStreamingData* streaming_data);
229 
230   static Handle<SharedFunctionInfo> GetSharedFunctionInfoForWebSnapshot(
231       Isolate* isolate, Handle<String> source, MaybeHandle<Object> script_name);
232 
233   // Create a shared function info object for the given function literal
234   // node (the code may be lazily compiled).
235   template <typename IsolateT>
236   static Handle<SharedFunctionInfo> GetSharedFunctionInfo(FunctionLiteral* node,
237                                                           Handle<Script> script,
238                                                           IsolateT* isolate);
239 };
240 
241 // A base class for compilation jobs intended to run concurrent to the main
242 // thread. The current state of the job can be checked using {state()}.
243 class V8_EXPORT_PRIVATE CompilationJob {
244  public:
245   enum Status { SUCCEEDED, FAILED, RETRY_ON_MAIN_THREAD };
246   enum class State {
247     kReadyToPrepare,
248     kReadyToExecute,
249     kReadyToFinalize,
250     kSucceeded,
251     kFailed,
252   };
253 
CompilationJob(State initial_state)254   explicit CompilationJob(State initial_state) : state_(initial_state) {
255     timer_.Start();
256   }
257   virtual ~CompilationJob() = default;
258 
state()259   State state() const { return state_; }
260 
261  protected:
ElapsedTime()262   V8_WARN_UNUSED_RESULT base::TimeDelta ElapsedTime() const {
263     return timer_.Elapsed();
264   }
265 
UpdateState(Status status,State next_state)266   V8_WARN_UNUSED_RESULT Status UpdateState(Status status, State next_state) {
267     switch (status) {
268       case SUCCEEDED:
269         state_ = next_state;
270         break;
271       case FAILED:
272         state_ = State::kFailed;
273         break;
274       case RETRY_ON_MAIN_THREAD:
275         // Don't change the state, we'll re-try on the main thread.
276         break;
277     }
278     return status;
279   }
280 
281  private:
282   State state_;
283   base::ElapsedTimer timer_;
284 };
285 
286 // A base class for unoptimized compilation jobs.
287 //
288 // The job is split into two phases which are called in sequence on
289 // different threads and with different limitations:
290 //  1) ExecuteJob:   Runs concurrently. No heap allocation or handle derefs.
291 //  2) FinalizeJob:  Runs on main thread. No dependency changes.
292 //
293 // Either of phases can either fail or succeed.
294 class UnoptimizedCompilationJob : public CompilationJob {
295  public:
UnoptimizedCompilationJob(uintptr_t stack_limit,ParseInfo * parse_info,UnoptimizedCompilationInfo * compilation_info)296   UnoptimizedCompilationJob(uintptr_t stack_limit, ParseInfo* parse_info,
297                             UnoptimizedCompilationInfo* compilation_info)
298       : CompilationJob(State::kReadyToExecute),
299         stack_limit_(stack_limit),
300         parse_info_(parse_info),
301         compilation_info_(compilation_info) {}
302 
303   // Executes the compile job. Can be called on a background thread.
304   V8_WARN_UNUSED_RESULT Status ExecuteJob();
305 
306   // Finalizes the compile job. Must be called on the main thread.
307   V8_WARN_UNUSED_RESULT Status
308   FinalizeJob(Handle<SharedFunctionInfo> shared_info, Isolate* isolate);
309 
310   // Finalizes the compile job. Can be called on a background thread, and might
311   // return RETRY_ON_MAIN_THREAD if the finalization can't be run on the
312   // background thread, and should instead be retried on the foreground thread.
313   V8_WARN_UNUSED_RESULT Status
314   FinalizeJob(Handle<SharedFunctionInfo> shared_info, LocalIsolate* isolate);
315 
316   void RecordCompilationStats(Isolate* isolate) const;
317   void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag,
318                                  Handle<SharedFunctionInfo> shared,
319                                  Isolate* isolate) const;
320 
parse_info()321   ParseInfo* parse_info() const {
322     DCHECK_NOT_NULL(parse_info_);
323     return parse_info_;
324   }
compilation_info()325   UnoptimizedCompilationInfo* compilation_info() const {
326     return compilation_info_;
327   }
328 
stack_limit()329   uintptr_t stack_limit() const { return stack_limit_; }
330 
time_taken_to_execute()331   base::TimeDelta time_taken_to_execute() const {
332     return time_taken_to_execute_;
333   }
time_taken_to_finalize()334   base::TimeDelta time_taken_to_finalize() const {
335     return time_taken_to_finalize_;
336   }
337 
ClearParseInfo()338   void ClearParseInfo() { parse_info_ = nullptr; }
339 
340  protected:
341   // Overridden by the actual implementation.
342   virtual Status ExecuteJobImpl() = 0;
343   virtual Status FinalizeJobImpl(Handle<SharedFunctionInfo> shared_info,
344                                  Isolate* isolate) = 0;
345   virtual Status FinalizeJobImpl(Handle<SharedFunctionInfo> shared_info,
346                                  LocalIsolate* isolate) = 0;
347 
348  private:
349   uintptr_t stack_limit_;
350   ParseInfo* parse_info_;
351   UnoptimizedCompilationInfo* compilation_info_;
352   base::TimeDelta time_taken_to_execute_;
353   base::TimeDelta time_taken_to_finalize_;
354 };
355 
356 // A base class for optimized compilation jobs.
357 //
358 // The job is split into three phases which are called in sequence on
359 // different threads and with different limitations:
360 //  1) PrepareJob:   Runs on main thread. No major limitations.
361 //  2) ExecuteJob:   Runs concurrently. No heap allocation or handle derefs.
362 //  3) FinalizeJob:  Runs on main thread. No dependency changes.
363 //
364 // Each of the three phases can either fail or succeed.
365 class OptimizedCompilationJob : public CompilationJob {
366  public:
OptimizedCompilationJob(const char * compiler_name,State initial_state)367   OptimizedCompilationJob(const char* compiler_name, State initial_state)
368       : CompilationJob(initial_state), compiler_name_(compiler_name) {}
369 
370   // Prepare the compile job. Must be called on the main thread.
371   V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT Status PrepareJob(Isolate* isolate);
372 
373   // Executes the compile job. Can be called on a background thread.
374   V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT Status
375   ExecuteJob(RuntimeCallStats* stats, LocalIsolate* local_isolate = nullptr);
376 
377   // Finalizes the compile job. Must be called on the main thread.
378   V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT Status FinalizeJob(Isolate* isolate);
379 
compiler_name()380   const char* compiler_name() const { return compiler_name_; }
381 
382  protected:
383   // Overridden by the actual implementation.
384   virtual Status PrepareJobImpl(Isolate* isolate) = 0;
385   virtual Status ExecuteJobImpl(RuntimeCallStats* stats,
386                                 LocalIsolate* local_heap) = 0;
387   virtual Status FinalizeJobImpl(Isolate* isolate) = 0;
388 
389   base::TimeDelta time_taken_to_prepare_;
390   base::TimeDelta time_taken_to_execute_;
391   base::TimeDelta time_taken_to_finalize_;
392 
393  private:
394   const char* const compiler_name_;
395 };
396 
397 // Thin wrapper to split off Turbofan-specific parts.
398 class TurbofanCompilationJob : public OptimizedCompilationJob {
399  public:
TurbofanCompilationJob(OptimizedCompilationInfo * compilation_info,State initial_state)400   TurbofanCompilationJob(OptimizedCompilationInfo* compilation_info,
401                          State initial_state)
402       : OptimizedCompilationJob("Turbofan", initial_state),
403         compilation_info_(compilation_info) {}
404 
compilation_info()405   OptimizedCompilationInfo* compilation_info() const {
406     return compilation_info_;
407   }
408 
409   // Report a transient failure, try again next time. Should only be called on
410   // optimization compilation jobs.
411   Status RetryOptimization(BailoutReason reason);
412 
413   // Report a persistent failure, disable future optimization on the function.
414   // Should only be called on optimization compilation jobs.
415   Status AbortOptimization(BailoutReason reason);
416 
417   void RecordCompilationStats(ConcurrencyMode mode, Isolate* isolate) const;
418   void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag,
419                                  Isolate* isolate) const;
420 
421  private:
422   OptimizedCompilationInfo* const compilation_info_;
423 };
424 
425 class FinalizeUnoptimizedCompilationData {
426  public:
FinalizeUnoptimizedCompilationData(Isolate * isolate,Handle<SharedFunctionInfo> function_handle,MaybeHandle<CoverageInfo> coverage_info,base::TimeDelta time_taken_to_execute,base::TimeDelta time_taken_to_finalize)427   FinalizeUnoptimizedCompilationData(Isolate* isolate,
428                                      Handle<SharedFunctionInfo> function_handle,
429                                      MaybeHandle<CoverageInfo> coverage_info,
430                                      base::TimeDelta time_taken_to_execute,
431                                      base::TimeDelta time_taken_to_finalize)
432       : time_taken_to_execute_(time_taken_to_execute),
433         time_taken_to_finalize_(time_taken_to_finalize),
434         function_handle_(function_handle),
435         coverage_info_(coverage_info) {}
436 
437   FinalizeUnoptimizedCompilationData(LocalIsolate* isolate,
438                                      Handle<SharedFunctionInfo> function_handle,
439                                      MaybeHandle<CoverageInfo> coverage_info,
440                                      base::TimeDelta time_taken_to_execute,
441                                      base::TimeDelta time_taken_to_finalize);
442 
function_handle()443   Handle<SharedFunctionInfo> function_handle() const {
444     return function_handle_;
445   }
446 
coverage_info()447   MaybeHandle<CoverageInfo> coverage_info() const { return coverage_info_; }
448 
time_taken_to_execute()449   base::TimeDelta time_taken_to_execute() const {
450     return time_taken_to_execute_;
451   }
time_taken_to_finalize()452   base::TimeDelta time_taken_to_finalize() const {
453     return time_taken_to_finalize_;
454   }
455 
456  private:
457   base::TimeDelta time_taken_to_execute_;
458   base::TimeDelta time_taken_to_finalize_;
459   Handle<SharedFunctionInfo> function_handle_;
460   MaybeHandle<CoverageInfo> coverage_info_;
461 };
462 
463 using FinalizeUnoptimizedCompilationDataList =
464     std::vector<FinalizeUnoptimizedCompilationData>;
465 
466 class DeferredFinalizationJobData {
467  public:
DeferredFinalizationJobData(Isolate * isolate,Handle<SharedFunctionInfo> function_handle,std::unique_ptr<UnoptimizedCompilationJob> job)468   DeferredFinalizationJobData(Isolate* isolate,
469                               Handle<SharedFunctionInfo> function_handle,
470                               std::unique_ptr<UnoptimizedCompilationJob> job) {
471     UNREACHABLE();
472   }
473   DeferredFinalizationJobData(LocalIsolate* isolate,
474                               Handle<SharedFunctionInfo> function_handle,
475                               std::unique_ptr<UnoptimizedCompilationJob> job);
476 
function_handle()477   Handle<SharedFunctionInfo> function_handle() const {
478     return function_handle_;
479   }
480 
job()481   UnoptimizedCompilationJob* job() const { return job_.get(); }
482 
483  private:
484   Handle<SharedFunctionInfo> function_handle_;
485   std::unique_ptr<UnoptimizedCompilationJob> job_;
486 };
487 
488 // A wrapper around a OptimizedCompilationInfo that detaches the Handles from
489 // the underlying PersistentHandlesScope and stores them in info_ on
490 // destruction.
491 class V8_NODISCARD CompilationHandleScope final {
492  public:
CompilationHandleScope(Isolate * isolate,OptimizedCompilationInfo * info)493   explicit CompilationHandleScope(Isolate* isolate,
494                                   OptimizedCompilationInfo* info)
495       : persistent_(isolate), info_(info) {}
496   V8_EXPORT_PRIVATE ~CompilationHandleScope();
497 
498  private:
499   PersistentHandlesScope persistent_;
500   OptimizedCompilationInfo* info_;
501 };
502 
503 using DeferredFinalizationJobDataList =
504     std::vector<DeferredFinalizationJobData>;
505 
506 class V8_EXPORT_PRIVATE BackgroundCompileTask {
507  public:
508   // Creates a new task that when run will parse and compile the streamed
509   // script associated with |data| and can be finalized with FinalizeScript.
510   // Note: does not take ownership of |data|.
511   BackgroundCompileTask(ScriptStreamingData* data, Isolate* isolate,
512                         v8::ScriptType type);
513   BackgroundCompileTask(const BackgroundCompileTask&) = delete;
514   BackgroundCompileTask& operator=(const BackgroundCompileTask&) = delete;
515   ~BackgroundCompileTask();
516 
517   // Creates a new task that when run will parse and compile the top-level
518   // |shared_info| and can be finalized with FinalizeFunction in
519   // Compiler::FinalizeBackgroundCompileTask.
520   BackgroundCompileTask(
521       Isolate* isolate, Handle<SharedFunctionInfo> shared_info,
522       std::unique_ptr<Utf16CharacterStream> character_stream,
523       WorkerThreadRuntimeCallStats* worker_thread_runtime_stats,
524       TimedHistogram* timer, int max_stack_size);
525 
526   void Run();
527   void RunOnMainThread(Isolate* isolate);
528   void Run(LocalIsolate* isolate,
529            ReusableUnoptimizedCompileState* reusable_state);
530 
531   MaybeHandle<SharedFunctionInfo> FinalizeScript(
532       Isolate* isolate, Handle<String> source,
533       const ScriptDetails& script_details);
534 
535   bool FinalizeFunction(Isolate* isolate, Compiler::ClearExceptionFlag flag);
536 
537   void AbortFunction();
538 
flags()539   UnoptimizedCompileFlags flags() const { return flags_; }
540 
541  private:
542   void ReportStatistics(Isolate* isolate);
543 
544   void ClearFunctionJobPointer();
545 
546   // Data needed for parsing and compilation. These need to be initialized
547   // before the compilation starts.
548   Isolate* isolate_for_local_isolate_;
549   UnoptimizedCompileFlags flags_;
550   UnoptimizedCompileState compile_state_;
551   std::unique_ptr<Utf16CharacterStream> character_stream_;
552   int stack_size_;
553   WorkerThreadRuntimeCallStats* worker_thread_runtime_call_stats_;
554   TimedHistogram* timer_;
555 
556   // Data needed for merging onto the main thread after background finalization.
557   std::unique_ptr<PersistentHandles> persistent_handles_;
558   MaybeHandle<SharedFunctionInfo> outer_function_sfi_;
559   Handle<Script> script_;
560   IsCompiledScope is_compiled_scope_;
561   FinalizeUnoptimizedCompilationDataList finalize_unoptimized_compilation_data_;
562   DeferredFinalizationJobDataList jobs_to_retry_finalization_on_main_thread_;
563   base::SmallVector<v8::Isolate::UseCounterFeature, 8> use_counts_;
564   int total_preparse_skipped_ = 0;
565 
566   // Single function data for top-level function compilation.
567   MaybeHandle<SharedFunctionInfo> input_shared_info_;
568   int start_position_;
569   int end_position_;
570   int function_literal_id_;
571 };
572 
573 // Contains all data which needs to be transmitted between threads for
574 // background parsing and compiling and finalizing it on the main thread.
575 struct ScriptStreamingData {
576   ScriptStreamingData(
577       std::unique_ptr<ScriptCompiler::ExternalSourceStream> source_stream,
578       ScriptCompiler::StreamedSource::Encoding encoding);
579   ScriptStreamingData(const ScriptStreamingData&) = delete;
580   ScriptStreamingData& operator=(const ScriptStreamingData&) = delete;
581   ~ScriptStreamingData();
582 
583   void Release();
584 
585   // Internal implementation of v8::ScriptCompiler::StreamedSource.
586   std::unique_ptr<ScriptCompiler::ExternalSourceStream> source_stream;
587   ScriptCompiler::StreamedSource::Encoding encoding;
588 
589   // Task that performs background parsing and compilation.
590   std::unique_ptr<BackgroundCompileTask> task;
591 };
592 
593 class V8_EXPORT_PRIVATE BackgroundDeserializeTask {
594  public:
595   BackgroundDeserializeTask(Isolate* isolate,
596                             std::unique_ptr<ScriptCompiler::CachedData> data);
597 
598   void Run();
599 
600   MaybeHandle<SharedFunctionInfo> Finish(Isolate* isolate,
601                                          Handle<String> source,
602                                          ScriptOriginOptions origin_options);
603 
rejected()604   bool rejected() const { return cached_data_.rejected(); }
605 
606  private:
607   Isolate* isolate_for_local_isolate_;
608   AlignedCachedData cached_data_;
609   CodeSerializer::OffThreadDeserializeData off_thread_data_;
610 };
611 
612 }  // namespace internal
613 }  // namespace v8
614 
615 #endif  // V8_CODEGEN_COMPILER_H_
616