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