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