LCOV - code coverage report
Current view: top level - src/compiler-dispatcher - unoptimized-compile-job.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 139 176 79.0 %
Date: 2017-10-20 Functions: 17 24 70.8 %

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

Generated by: LCOV version 1.10