LCOV - code coverage report
Current view: top level - src/compiler-dispatcher - compiler-dispatcher-job.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 154 198 77.8 %
Date: 2017-04-26 Functions: 16 23 69.6 %

          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/compiler-dispatcher/compiler-dispatcher-job.h"
       6             : 
       7             : #include "src/assert-scope.h"
       8             : #include "src/compilation-info.h"
       9             : #include "src/compiler-dispatcher/compiler-dispatcher-tracer.h"
      10             : #include "src/compiler.h"
      11             : #include "src/flags.h"
      12             : #include "src/global-handles.h"
      13             : #include "src/isolate.h"
      14             : #include "src/objects-inl.h"
      15             : #include "src/parsing/parse-info.h"
      16             : #include "src/parsing/parser.h"
      17             : #include "src/parsing/scanner-character-streams.h"
      18             : #include "src/unicode-cache.h"
      19             : #include "src/utils.h"
      20             : 
      21             : namespace v8 {
      22             : namespace internal {
      23             : 
      24             : namespace {
      25             : 
      26             : class OneByteWrapper : public v8::String::ExternalOneByteStringResource {
      27             :  public:
      28          24 :   OneByteWrapper(const void* data, int length) : data_(data), length_(length) {}
      29          48 :   ~OneByteWrapper() override = default;
      30             : 
      31          48 :   const char* data() const override {
      32          48 :     return reinterpret_cast<const char*>(data_);
      33             :   }
      34             : 
      35          24 :   size_t length() const override { return static_cast<size_t>(length_); }
      36             : 
      37             :  private:
      38             :   const void* data_;
      39             :   int length_;
      40             : 
      41             :   DISALLOW_COPY_AND_ASSIGN(OneByteWrapper);
      42             : };
      43             : 
      44             : class TwoByteWrapper : public v8::String::ExternalStringResource {
      45             :  public:
      46           0 :   TwoByteWrapper(const void* data, int length) : data_(data), length_(length) {}
      47           0 :   ~TwoByteWrapper() override = default;
      48             : 
      49           0 :   const uint16_t* data() const override {
      50           0 :     return reinterpret_cast<const uint16_t*>(data_);
      51             :   }
      52             : 
      53           0 :   size_t length() const override { return static_cast<size_t>(length_); }
      54             : 
      55             :  private:
      56             :   const void* data_;
      57             :   int length_;
      58             : 
      59             :   DISALLOW_COPY_AND_ASSIGN(TwoByteWrapper);
      60             : };
      61             : 
      62             : }  // namespace
      63             : 
      64           3 : CompilerDispatcherJob::CompilerDispatcherJob(
      65             :     CompilerDispatcherTracer* tracer, size_t max_stack_size,
      66             :     Handle<String> source, int start_position, int end_position,
      67             :     LanguageMode language_mode, int function_literal_id, bool native,
      68             :     bool module, bool is_named_expression, uint32_t hash_seed,
      69             :     AccountingAllocator* zone_allocator, int compiler_hints,
      70             :     const AstStringConstants* ast_string_constants,
      71             :     CompileJobFinishCallback* finish_callback)
      72             :     : status_(CompileJobStatus::kReadyToParse),
      73             :       isolate_(nullptr),
      74             :       tracer_(tracer),
      75             :       max_stack_size_(max_stack_size),
      76             :       finish_callback_(finish_callback),
      77           6 :       trace_compiler_dispatcher_jobs_(FLAG_trace_compiler_dispatcher_jobs) {
      78           3 :   parse_info_.reset(new ParseInfo(zone_allocator));
      79             :   DCHECK(source->IsExternalTwoByteString() ||
      80             :          source->IsExternalOneByteString());
      81             :   character_stream_.reset(
      82           3 :       ScannerStream::For(source, start_position, end_position));
      83             :   parse_info_->set_character_stream(character_stream_.get());
      84             :   parse_info_->set_hash_seed(hash_seed);
      85             :   parse_info_->set_compiler_hints(compiler_hints);
      86             :   parse_info_->set_start_position(start_position);
      87             :   parse_info_->set_end_position(end_position);
      88           3 :   unicode_cache_.reset(new UnicodeCache());
      89             :   parse_info_->set_unicode_cache(unicode_cache_.get());
      90             :   parse_info_->set_language_mode(language_mode);
      91             :   parse_info_->set_function_literal_id(function_literal_id);
      92             :   parse_info_->set_ast_string_constants(ast_string_constants);
      93             : 
      94             :   parse_info_->set_native(native);
      95             :   parse_info_->set_module(module);
      96             :   parse_info_->set_is_named_expression(is_named_expression);
      97             : 
      98           3 :   parser_.reset(new Parser(parse_info_.get()));
      99           3 :   parser_->DeserializeScopeChain(parse_info_.get(), MaybeHandle<ScopeInfo>());
     100             : 
     101           3 :   if (trace_compiler_dispatcher_jobs_) {
     102           0 :     PrintF("CompilerDispatcherJob[%p] created for ", static_cast<void*>(this));
     103           0 :     ShortPrint();
     104           0 :     PrintF(" in ready to parse state.\n");
     105             :   }
     106           3 : }
     107             : 
     108          68 : CompilerDispatcherJob::CompilerDispatcherJob(Isolate* isolate,
     109             :                                              CompilerDispatcherTracer* tracer,
     110             :                                              Handle<SharedFunctionInfo> shared,
     111             :                                              size_t max_stack_size)
     112             :     : status_(CompileJobStatus::kInitial),
     113             :       isolate_(isolate),
     114             :       tracer_(tracer),
     115          68 :       context_(isolate_->global_handles()->Create(isolate->context())),
     116          34 :       shared_(isolate_->global_handles()->Create(*shared)),
     117             :       max_stack_size_(max_stack_size),
     118         136 :       trace_compiler_dispatcher_jobs_(FLAG_trace_compiler_dispatcher_jobs) {
     119             :   DCHECK(!shared_->is_toplevel());
     120          34 :   HandleScope scope(isolate_);
     121             :   Handle<Script> script(Script::cast(shared_->script()), isolate_);
     122          34 :   Handle<String> source(String::cast(script->source()), isolate_);
     123          34 :   if (trace_compiler_dispatcher_jobs_) {
     124           0 :     PrintF("CompilerDispatcherJob[%p] created for ", static_cast<void*>(this));
     125           0 :     ShortPrint();
     126           0 :     PrintF(" in initial state.\n");
     127             :   }
     128          34 : }
     129             : 
     130           5 : CompilerDispatcherJob::CompilerDispatcherJob(
     131           5 :     Isolate* isolate, CompilerDispatcherTracer* tracer, Handle<Script> script,
     132             :     Handle<SharedFunctionInfo> shared, FunctionLiteral* literal,
     133             :     std::shared_ptr<Zone> parse_zone,
     134             :     std::shared_ptr<DeferredHandles> parse_handles,
     135             :     std::shared_ptr<DeferredHandles> compile_handles, size_t max_stack_size)
     136             :     : status_(CompileJobStatus::kAnalyzed),
     137             :       isolate_(isolate),
     138             :       tracer_(tracer),
     139          10 :       context_(isolate_->global_handles()->Create(isolate->context())),
     140           5 :       shared_(isolate_->global_handles()->Create(*shared)),
     141             :       max_stack_size_(max_stack_size),
     142           5 :       parse_info_(new ParseInfo(shared_)),
     143             :       parse_zone_(parse_zone),
     144             :       compile_info_(new CompilationInfo(parse_info_->zone(), parse_info_.get(),
     145           5 :                                         isolate_, Handle<JSFunction>::null())),
     146          35 :       trace_compiler_dispatcher_jobs_(FLAG_trace_compiler_dispatcher_jobs) {
     147             :   parse_info_->set_literal(literal);
     148             :   parse_info_->set_script(script);
     149          10 :   parse_info_->set_deferred_handles(parse_handles);
     150          10 :   compile_info_->set_deferred_handles(compile_handles);
     151             : 
     152           5 :   if (trace_compiler_dispatcher_jobs_) {
     153           0 :     PrintF("CompilerDispatcherJob[%p] created for ", static_cast<void*>(this));
     154           0 :     ShortPrint();
     155           0 :     PrintF(" in Analyzed state.\n");
     156             :   }
     157           5 : }
     158             : 
     159          42 : CompilerDispatcherJob::~CompilerDispatcherJob() {
     160             :   DCHECK(status_ == CompileJobStatus::kInitial ||
     161             :          (status_ == CompileJobStatus::kReadyToParse && finish_callback_) ||
     162             :          status_ == CompileJobStatus::kDone);
     163          42 :   if (!shared_.is_null()) {
     164             :     DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
     165          39 :     i::GlobalHandles::Destroy(Handle<Object>::cast(shared_).location());
     166             :   }
     167          42 :   if (!context_.is_null()) {
     168             :     DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
     169          39 :     i::GlobalHandles::Destroy(Handle<Object>::cast(context_).location());
     170             :   }
     171          42 : }
     172             : 
     173           0 : bool CompilerDispatcherJob::IsAssociatedWith(
     174             :     Handle<SharedFunctionInfo> shared) const {
     175           0 :   return *shared_ == *shared;
     176             : }
     177             : 
     178          28 : void CompilerDispatcherJob::PrepareToParseOnMainThread() {
     179             :   DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
     180             :   DCHECK(status() == CompileJobStatus::kInitial);
     181         112 :   COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kPrepareToParse);
     182          28 :   if (trace_compiler_dispatcher_jobs_) {
     183             :     PrintF("CompilerDispatcherJob[%p]: Preparing to parse\n",
     184           0 :            static_cast<void*>(this));
     185             :   }
     186          80 :   HandleScope scope(isolate_);
     187          28 :   unicode_cache_.reset(new UnicodeCache());
     188          28 :   Handle<Script> script(Script::cast(shared_->script()), isolate_);
     189             :   DCHECK(script->type() != Script::TYPE_NATIVE);
     190             : 
     191          28 :   Handle<String> source(String::cast(script->source()), isolate_);
     192          56 :   parse_info_.reset(new ParseInfo(isolate_->allocator()));
     193          56 :   if (source->IsExternalTwoByteString() || source->IsExternalOneByteString()) {
     194             :     character_stream_.reset(ScannerStream::For(
     195           4 :         source, shared_->start_position(), shared_->end_position()));
     196             :   } else {
     197          24 :     source = String::Flatten(source);
     198             :     const void* data;
     199             :     int offset = 0;
     200             :     int length = source->length();
     201             : 
     202             :     // Objects in lo_space don't move, so we can just read the contents from
     203             :     // any thread.
     204          24 :     if (isolate_->heap()->lo_space()->Contains(*source)) {
     205             :       // We need to globalize the handle to the flattened string here, in
     206             :       // case it's not referenced from anywhere else.
     207           0 :       source_ = isolate_->global_handles()->Create(*source);
     208             :       DisallowHeapAllocation no_allocation;
     209           0 :       String::FlatContent content = source->GetFlatContent();
     210             :       DCHECK(content.IsFlat());
     211             :       data =
     212           0 :           content.IsOneByte()
     213             :               ? reinterpret_cast<const void*>(content.ToOneByteVector().start())
     214           0 :               : reinterpret_cast<const void*>(content.ToUC16Vector().start());
     215             :     } else {
     216             :       // Otherwise, create a copy of the part of the string we'll parse in the
     217             :       // zone.
     218          24 :       length = (shared_->end_position() - shared_->start_position());
     219             :       offset = shared_->start_position();
     220             : 
     221          24 :       int byte_len = length * (source->IsOneByteRepresentation() ? 1 : 2);
     222          48 :       data = parse_info_->zone()->New(byte_len);
     223             : 
     224             :       DisallowHeapAllocation no_allocation;
     225          24 :       String::FlatContent content = source->GetFlatContent();
     226             :       DCHECK(content.IsFlat());
     227          24 :       if (content.IsOneByte()) {
     228             :         MemCopy(const_cast<void*>(data),
     229             :                 &content.ToOneByteVector().at(shared_->start_position()),
     230             :                 byte_len);
     231             :       } else {
     232             :         MemCopy(const_cast<void*>(data),
     233             :                 &content.ToUC16Vector().at(shared_->start_position()),
     234             :                 byte_len);
     235             :       }
     236             :     }
     237             :     Handle<String> wrapper;
     238          24 :     if (source->IsOneByteRepresentation()) {
     239             :       ExternalOneByteString::Resource* resource =
     240          24 :           new OneByteWrapper(data, length);
     241             :       source_wrapper_.reset(resource);
     242             :       wrapper = isolate_->factory()
     243             :                     ->NewExternalStringFromOneByte(resource)
     244          48 :                     .ToHandleChecked();
     245             :     } else {
     246             :       ExternalTwoByteString::Resource* resource =
     247           0 :           new TwoByteWrapper(data, length);
     248             :       source_wrapper_.reset(resource);
     249             :       wrapper = isolate_->factory()
     250             :                     ->NewExternalStringFromTwoByte(resource)
     251           0 :                     .ToHandleChecked();
     252             :     }
     253          48 :     wrapper_ = isolate_->global_handles()->Create(*wrapper);
     254             : 
     255             :     character_stream_.reset(
     256             :         ScannerStream::For(wrapper_, shared_->start_position() - offset,
     257          48 :                            shared_->end_position() - offset));
     258             :   }
     259          56 :   parse_info_->InitFromIsolate(isolate_);
     260             :   parse_info_->set_character_stream(character_stream_.get());
     261          28 :   parse_info_->set_hash_seed(isolate_->heap()->HashSeed());
     262             :   parse_info_->set_is_named_expression(shared_->is_named_expression());
     263             :   parse_info_->set_compiler_hints(shared_->compiler_hints());
     264             :   parse_info_->set_start_position(shared_->start_position());
     265             :   parse_info_->set_end_position(shared_->end_position());
     266             :   parse_info_->set_unicode_cache(unicode_cache_.get());
     267             :   parse_info_->set_language_mode(shared_->language_mode());
     268             :   parse_info_->set_function_literal_id(shared_->function_literal_id());
     269             : 
     270          28 :   parser_.reset(new Parser(parse_info_.get()));
     271             :   MaybeHandle<ScopeInfo> outer_scope_info;
     272          82 :   if (!shared_->outer_scope_info()->IsTheHole(isolate_) &&
     273             :       ScopeInfo::cast(shared_->outer_scope_info())->length() > 0) {
     274             :     outer_scope_info = handle(ScopeInfo::cast(shared_->outer_scope_info()));
     275             :   }
     276          56 :   parser_->DeserializeScopeChain(parse_info_.get(), outer_scope_info);
     277             : 
     278             :   Handle<String> name(String::cast(shared_->name()));
     279             :   parse_info_->set_function_name(
     280          28 :       parse_info_->ast_value_factory()->GetString(name));
     281          56 :   status_ = CompileJobStatus::kReadyToParse;
     282          28 : }
     283             : 
     284          28 : void CompilerDispatcherJob::Parse() {
     285             :   DCHECK(status() == CompileJobStatus::kReadyToParse);
     286         112 :   COMPILER_DISPATCHER_TRACE_SCOPE_WITH_NUM(
     287             :       tracer_, kParse,
     288             :       parse_info_->end_position() - parse_info_->start_position());
     289          28 :   if (trace_compiler_dispatcher_jobs_) {
     290           0 :     PrintF("CompilerDispatcherJob[%p]: Parsing\n", static_cast<void*>(this));
     291             :   }
     292             : 
     293             :   DisallowHeapAllocation no_allocation;
     294             :   DisallowHandleAllocation no_handles;
     295             :   DisallowHandleDereference no_deref;
     296             : 
     297          28 :   uintptr_t stack_limit = GetCurrentStackPosition() - max_stack_size_ * KB;
     298             : 
     299             :   parser_->set_stack_limit(stack_limit);
     300          28 :   parser_->ParseOnBackground(parse_info_.get());
     301             : 
     302          28 :   if (finish_callback_) {
     303           3 :     finish_callback_->ParseFinished(std::move(parse_info_));
     304           1 :     status_ = CompileJobStatus::kDone;
     305             :   } else {
     306          27 :     status_ = CompileJobStatus::kParsed;
     307          28 :   }
     308          28 : }
     309             : 
     310          27 : bool CompilerDispatcherJob::FinalizeParsingOnMainThread() {
     311             :   DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
     312             :   DCHECK(status() == CompileJobStatus::kParsed);
     313         108 :   COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kFinalizeParsing);
     314          27 :   if (trace_compiler_dispatcher_jobs_) {
     315             :     PrintF("CompilerDispatcherJob[%p]: Finalizing parsing\n",
     316           0 :            static_cast<void*>(this));
     317             :   }
     318             : 
     319          27 :   if (!source_.is_null()) {
     320           0 :     i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location());
     321           0 :     source_ = Handle<String>::null();
     322             :   }
     323          27 :   if (!wrapper_.is_null()) {
     324          23 :     i::GlobalHandles::Destroy(Handle<Object>::cast(wrapper_).location());
     325          23 :     wrapper_ = Handle<String>::null();
     326             :   }
     327             : 
     328          27 :   Handle<Script> script(Script::cast(shared_->script()), isolate_);
     329             :   parse_info_->set_script(script);
     330          27 :   if (parse_info_->literal() == nullptr) {
     331           2 :     parser_->ReportErrors(isolate_, script);
     332           1 :     status_ = CompileJobStatus::kFailed;
     333             :   } else {
     334          26 :     status_ = CompileJobStatus::kReadyToAnalyze;
     335             :   }
     336          54 :   parser_->UpdateStatistics(isolate_, script);
     337             : 
     338          54 :   DeferredHandleScope scope(isolate_);
     339             :   {
     340          27 :     parse_info_->ReopenHandlesInNewHandleScope();
     341             : 
     342          79 :     if (!shared_->outer_scope_info()->IsTheHole(isolate_) &&
     343             :         ScopeInfo::cast(shared_->outer_scope_info())->length() > 0) {
     344             :       Handle<ScopeInfo> outer_scope_info(
     345             :           handle(ScopeInfo::cast(shared_->outer_scope_info())));
     346             :       parse_info_->set_outer_scope_info(outer_scope_info);
     347             :     }
     348             :     parse_info_->set_shared_info(shared_);
     349             : 
     350             :     // Internalize ast values on the main thread.
     351          54 :     parse_info_->ast_value_factory()->Internalize(isolate_);
     352          54 :     parser_->HandleSourceURLComments(isolate_, script);
     353             : 
     354             :     parse_info_->set_character_stream(nullptr);
     355             :     parse_info_->set_unicode_cache(nullptr);
     356             :     parser_.reset();
     357             :     unicode_cache_.reset();
     358             :     character_stream_.reset();
     359             :   }
     360          54 :   parse_info_->set_deferred_handles(scope.Detach());
     361             : 
     362          54 :   return status_ != CompileJobStatus::kFailed;
     363             : }
     364             : 
     365          26 : bool CompilerDispatcherJob::AnalyzeOnMainThread() {
     366             :   DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
     367             :   DCHECK(status() == CompileJobStatus::kReadyToAnalyze);
     368         104 :   COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kAnalyze);
     369          26 :   if (trace_compiler_dispatcher_jobs_) {
     370           0 :     PrintF("CompilerDispatcherJob[%p]: Analyzing\n", static_cast<void*>(this));
     371             :   }
     372             : 
     373             :   compile_info_.reset(new CompilationInfo(parse_info_->zone(),
     374             :                                           parse_info_.get(), isolate_,
     375          52 :                                           Handle<JSFunction>::null()));
     376             : 
     377          52 :   DeferredHandleScope scope(isolate_);
     378             :   {
     379          26 :     if (Compiler::Analyze(compile_info_.get())) {
     380          25 :       status_ = CompileJobStatus::kAnalyzed;
     381             :     } else {
     382           1 :       status_ = CompileJobStatus::kFailed;
     383           1 :       if (!isolate_->has_pending_exception()) isolate_->StackOverflow();
     384             :     }
     385             :   }
     386          52 :   compile_info_->set_deferred_handles(scope.Detach());
     387             : 
     388          52 :   return status_ != CompileJobStatus::kFailed;
     389             : }
     390             : 
     391          29 : bool CompilerDispatcherJob::PrepareToCompileOnMainThread() {
     392             :   DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
     393             :   DCHECK(status() == CompileJobStatus::kAnalyzed);
     394         116 :   COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kPrepareToCompile);
     395             : 
     396             :   compile_job_.reset(
     397          29 :       Compiler::PrepareUnoptimizedCompilationJob(compile_info_.get()));
     398          29 :   if (!compile_job_.get()) {
     399           0 :     if (!isolate_->has_pending_exception()) isolate_->StackOverflow();
     400           0 :     status_ = CompileJobStatus::kFailed;
     401           0 :     return false;
     402             :   }
     403             : 
     404          29 :   CHECK(compile_job_->can_execute_on_background_thread());
     405          29 :   status_ = CompileJobStatus::kReadyToCompile;
     406          58 :   return true;
     407             : }
     408             : 
     409          25 : void CompilerDispatcherJob::Compile() {
     410             :   DCHECK(status() == CompileJobStatus::kReadyToCompile);
     411         125 :   COMPILER_DISPATCHER_TRACE_SCOPE_WITH_NUM(
     412             :       tracer_, kCompile, parse_info_->literal()->ast_node_count());
     413          25 :   if (trace_compiler_dispatcher_jobs_) {
     414           0 :     PrintF("CompilerDispatcherJob[%p]: Compiling\n", static_cast<void*>(this));
     415             :   }
     416             : 
     417             :   // Disallowing of handle dereference and heap access dealt with in
     418             :   // CompilationJob::ExecuteJob.
     419             : 
     420          25 :   uintptr_t stack_limit = GetCurrentStackPosition() - max_stack_size_ * KB;
     421             :   compile_job_->set_stack_limit(stack_limit);
     422             : 
     423          25 :   CompilationJob::Status status = compile_job_->ExecuteJob();
     424             :   USE(status);
     425             : 
     426             :   // Always transition to kCompiled - errors will be reported by
     427             :   // FinalizeCompilingOnMainThread.
     428          50 :   status_ = CompileJobStatus::kCompiled;
     429          25 : }
     430             : 
     431          24 : bool CompilerDispatcherJob::FinalizeCompilingOnMainThread() {
     432             :   DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
     433             :   DCHECK(status() == CompileJobStatus::kCompiled);
     434          96 :   COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kFinalizeCompiling);
     435          24 :   if (trace_compiler_dispatcher_jobs_) {
     436             :     PrintF("CompilerDispatcherJob[%p]: Finalizing compiling\n",
     437           0 :            static_cast<void*>(this));
     438             :   }
     439             : 
     440             :   {
     441          24 :     HandleScope scope(isolate_);
     442          45 :     if (compile_job_->state() == CompilationJob::State::kFailed ||
     443          21 :         !Compiler::FinalizeCompilationJob(compile_job_.release())) {
     444           3 :       if (!isolate_->has_pending_exception()) isolate_->StackOverflow();
     445           3 :       status_ = CompileJobStatus::kFailed;
     446             :       return false;
     447             :     }
     448             :   }
     449             : 
     450             :   compile_job_.reset();
     451             :   compile_info_.reset();
     452             :   parse_zone_.reset();
     453             :   parse_info_.reset();
     454             : 
     455          21 :   status_ = CompileJobStatus::kDone;
     456          45 :   return true;
     457             : }
     458             : 
     459          40 : void CompilerDispatcherJob::ResetOnMainThread() {
     460          40 :   if (trace_compiler_dispatcher_jobs_) {
     461           0 :     PrintF("CompilerDispatcherJob[%p]: Resetting\n", static_cast<void*>(this));
     462             :   }
     463             : 
     464             :   compile_job_.reset();
     465             :   compile_info_.reset();
     466             :   parse_zone_.reset();
     467             :   parser_.reset();
     468             :   unicode_cache_.reset();
     469             :   character_stream_.reset();
     470             :   parse_info_.reset();
     471          40 :   finish_callback_ = nullptr;
     472             : 
     473          40 :   if (!source_.is_null()) {
     474             :     DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
     475           0 :     i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location());
     476           0 :     source_ = Handle<String>::null();
     477             :   }
     478          40 :   if (!wrapper_.is_null()) {
     479             :     DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
     480           1 :     i::GlobalHandles::Destroy(Handle<Object>::cast(wrapper_).location());
     481           1 :     wrapper_ = Handle<String>::null();
     482             :   }
     483             : 
     484          40 :   status_ = CompileJobStatus::kInitial;
     485          40 : }
     486             : 
     487          96 : double CompilerDispatcherJob::EstimateRuntimeOfNextStepInMs() const {
     488          96 :   switch (status_) {
     489             :     case CompileJobStatus::kInitial:
     490          12 :       return tracer_->EstimatePrepareToParseInMs();
     491             : 
     492             :     case CompileJobStatus::kReadyToParse:
     493          24 :       return tracer_->EstimateParseInMs(parse_info_->end_position() -
     494          24 :                                         parse_info_->start_position());
     495             : 
     496             :     case CompileJobStatus::kParsed:
     497          12 :       return tracer_->EstimateFinalizeParsingInMs();
     498             : 
     499             :     case CompileJobStatus::kReadyToAnalyze:
     500          12 :       return tracer_->EstimateAnalyzeInMs();
     501             : 
     502             :     case CompileJobStatus::kAnalyzed:
     503          14 :       return tracer_->EstimatePrepareToCompileInMs();
     504             : 
     505             :     case CompileJobStatus::kReadyToCompile:
     506             :       return tracer_->EstimateCompileInMs(
     507          28 :           parse_info_->literal()->ast_node_count());
     508             : 
     509             :     case CompileJobStatus::kCompiled:
     510          10 :       return tracer_->EstimateFinalizeCompilingInMs();
     511             : 
     512             :     case CompileJobStatus::kFailed:
     513             :     case CompileJobStatus::kDone:
     514             :       return 0.0;
     515             :   }
     516             : 
     517           0 :   UNREACHABLE();
     518             :   return 0.0;
     519             : }
     520             : 
     521           0 : void CompilerDispatcherJob::ShortPrint() {
     522           0 :   if (isolate_) {
     523             :     DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
     524             :     DCHECK(!shared_.is_null());
     525           0 :     shared_->ShortPrint();
     526             :   } else {
     527             :     // TODO(wiktorg) more useful info in those cases
     528           0 :     if (parse_info_) {
     529           0 :       PrintF("function at %d", parse_info_->start_position());
     530             :     } else {
     531           0 :       PrintF("parsed function");
     532             :     }
     533             :   }
     534           0 : }
     535             : 
     536             : }  // namespace internal
     537             : }  // namespace v8

Generated by: LCOV version 1.10