LCOV - code coverage report
Current view: top level - src - compilation-info.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 93 97 95.9 %
Date: 2017-04-26 Functions: 32 34 94.1 %

          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/compilation-info.h"
       6             : 
       7             : #include "src/api.h"
       8             : #include "src/ast/ast.h"
       9             : #include "src/ast/scopes.h"
      10             : #include "src/debug/debug.h"
      11             : #include "src/isolate.h"
      12             : #include "src/objects-inl.h"
      13             : #include "src/parsing/parse-info.h"
      14             : #include "src/source-position.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : 
      19             : #define PARSE_INFO_GETTER(type, name)  \
      20             :   type CompilationInfo::name() const { \
      21             :     CHECK(parse_info());               \
      22             :     return parse_info()->name();       \
      23             :   }
      24             : 
      25             : #define PARSE_INFO_GETTER_WITH_DEFAULT(type, name, def) \
      26             :   type CompilationInfo::name() const {                  \
      27             :     return parse_info() ? parse_info()->name() : def;   \
      28             :   }
      29             : 
      30     9177226 : PARSE_INFO_GETTER(Handle<Script>, script)
      31    28790475 : PARSE_INFO_GETTER(FunctionLiteral*, literal)
      32    33789211 : PARSE_INFO_GETTER_WITH_DEFAULT(DeclarationScope*, scope, nullptr)
      33    34477865 : PARSE_INFO_GETTER(Handle<SharedFunctionInfo>, shared_info)
      34             : 
      35             : #undef PARSE_INFO_GETTER
      36             : #undef PARSE_INFO_GETTER_WITH_DEFAULT
      37             : 
      38    21444783 : bool CompilationInfo::is_debug() const {
      39    42889566 :   return parse_info() ? parse_info()->is_debug() : false;
      40             : }
      41             : 
      42       10197 : void CompilationInfo::set_is_debug() {
      43       10197 :   CHECK(parse_info());
      44             :   parse_info()->set_is_debug();
      45       10197 : }
      46             : 
      47       35638 : void CompilationInfo::PrepareForSerializing() {
      48       35638 :   if (parse_info()) parse_info()->set_will_serialize();
      49             :   SetFlag(kSerializing);
      50       35638 : }
      51             : 
      52      469578 : bool CompilationInfo::has_shared_info() const {
      53      518386 :   return parse_info_ && !parse_info_->shared_info().is_null();
      54             : }
      55             : 
      56     4290909 : CompilationInfo::CompilationInfo(Zone* zone, ParseInfo* parse_info,
      57             :                                  Isolate* isolate, Handle<JSFunction> closure)
      58             :     : CompilationInfo(parse_info, {}, Code::ComputeFlags(Code::FUNCTION), BASE,
      59             :                       isolate, zone) {
      60     4290909 :   closure_ = closure;
      61             : 
      62             :   // Compiling for the snapshot typically results in different code than
      63             :   // compiling later on. This means that code recompiled with deoptimization
      64             :   // support won't be "equivalent" (as defined by SharedFunctionInfo::
      65             :   // EnableDeoptimizationSupport), so it will replace the old code and all
      66             :   // its type feedback. To avoid this, always compile functions in the snapshot
      67             :   // with deoptimization support.
      68     4290909 :   if (isolate_->serializer_enabled()) EnableDeoptimizationSupport();
      69             : 
      70     4290909 :   if (FLAG_function_context_specialization) MarkAsFunctionContextSpecializing();
      71     4290909 :   if (FLAG_turbo_splitting) MarkAsSplittingEnabled();
      72             : 
      73             :   // Collect source positions for optimized code when profiling or if debugger
      74             :   // is active, to be able to get more precise source positions at the price of
      75             :   // more memory consumption.
      76     4290909 :   if (isolate_->NeedsSourcePositionsForProfiling()) {
      77             :     MarkAsSourcePositionsEnabled();
      78             :   }
      79     4290912 : }
      80             : 
      81      544509 : CompilationInfo::CompilationInfo(Vector<const char> debug_name,
      82             :                                  Isolate* isolate, Zone* zone,
      83             :                                  Code::Flags code_flags)
      84      544509 :     : CompilationInfo(nullptr, debug_name, code_flags, STUB, isolate, zone) {}
      85             : 
      86           0 : CompilationInfo::CompilationInfo(ParseInfo* parse_info,
      87             :                                  Vector<const char> debug_name,
      88             :                                  Code::Flags code_flags, Mode mode,
      89             :                                  Isolate* isolate, Zone* zone)
      90             :     : parse_info_(parse_info),
      91             :       isolate_(isolate),
      92             :       flags_(0),
      93             :       code_flags_(code_flags),
      94             :       mode_(mode),
      95             :       osr_ast_id_(BailoutId::None()),
      96             :       zone_(zone),
      97             :       deferred_handles_(nullptr),
      98             :       dependencies_(isolate, zone),
      99             :       bailout_reason_(kNoReason),
     100             :       prologue_offset_(Code::kPrologueOffsetNotSet),
     101             :       parameter_count_(0),
     102             :       optimization_id_(-1),
     103             :       osr_expr_stack_height_(-1),
     104    24177090 :       debug_name_(debug_name) {}
     105             : 
     106     4884205 : CompilationInfo::~CompilationInfo() {
     107     4884205 :   if (GetFlag(kDisableFutureOptimization) && has_shared_info()) {
     108       97616 :     shared_info()->DisableOptimization(bailout_reason());
     109             :   }
     110     4835397 :   dependencies()->Rollback();
     111     4835394 : }
     112             : 
     113     2840138 : int CompilationInfo::num_parameters() const {
     114     2840138 :   return !IsStub() ? scope()->num_parameters() : parameter_count_;
     115             : }
     116             : 
     117     2082464 : int CompilationInfo::num_parameters_including_this() const {
     118     4164936 :   return num_parameters() + (is_this_defined() ? 1 : 0);
     119             : }
     120             : 
     121     2084979 : bool CompilationInfo::is_this_defined() const { return !IsStub(); }
     122             : 
     123             : // Primitive functions are unlikely to be picked up by the stack-walking
     124             : // profiler, so they trigger their own optimization when they're called
     125             : // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time.
     126     1080961 : bool CompilationInfo::ShouldSelfOptimize() {
     127     2160606 :   return FLAG_opt && FLAG_crankshaft &&
     128     2079704 :          !(literal()->flags() & AstProperties::kDontSelfOptimize) &&
     129      999999 :          !literal()->dont_optimize() &&
     130     3080956 :          literal()->scope()->AllowsLazyCompilation() &&
     131     2080955 :          !shared_info()->optimization_disabled();
     132             : }
     133             : 
     134           5 : void CompilationInfo::set_deferred_handles(
     135             :     std::shared_ptr<DeferredHandles> deferred_handles) {
     136             :   DCHECK(deferred_handles_.get() == nullptr);
     137             :   deferred_handles_.swap(deferred_handles);
     138           5 : }
     139             : 
     140      148195 : void CompilationInfo::set_deferred_handles(DeferredHandles* deferred_handles) {
     141             :   DCHECK(deferred_handles_.get() == nullptr);
     142      148195 :   deferred_handles_.reset(deferred_handles);
     143      148195 : }
     144             : 
     145      752949 : void CompilationInfo::ReopenHandlesInNewHandleScope() {
     146      752949 :   if (!closure_.is_null()) {
     147      752951 :     closure_ = Handle<JSFunction>(*closure_);
     148             :   }
     149      752951 : }
     150             : 
     151       68237 : bool CompilationInfo::has_simple_parameters() {
     152       68237 :   return scope()->has_simple_parameters();
     153             : }
     154             : 
     155      943816 : std::unique_ptr<char[]> CompilationInfo::GetDebugName() const {
     156      943816 :   if (parse_info() && parse_info()->literal()) {
     157             :     AllowHandleDereference allow_deref;
     158         882 :     return parse_info()->literal()->debug_name()->ToCString();
     159             :   }
     160      943375 :   if (parse_info() && !parse_info()->shared_info().is_null()) {
     161      422787 :     return parse_info()->shared_info()->DebugName()->ToCString();
     162             :   }
     163      520588 :   Vector<const char> name_vec = debug_name_;
     164      520588 :   if (name_vec.is_empty()) name_vec = ArrayVector("unknown");
     165      520588 :   std::unique_ptr<char[]> name(new char[name_vec.length() + 1]);
     166      520581 :   memcpy(name.get(), name_vec.start(), name_vec.length());
     167      520581 :   name[name_vec.length()] = '\0';
     168             :   return name;
     169             : }
     170             : 
     171      193389 : StackFrame::Type CompilationInfo::GetOutputStackFrameType() const {
     172      193389 :   switch (output_code_kind()) {
     173             :     case Code::STUB:
     174             :     case Code::BYTECODE_HANDLER:
     175             :     case Code::HANDLER:
     176             :     case Code::BUILTIN:
     177             : #define CASE_KIND(kind) case Code::kind:
     178             :       IC_KIND_LIST(CASE_KIND)
     179             : #undef CASE_KIND
     180             :       return StackFrame::STUB;
     181             :     case Code::WASM_FUNCTION:
     182       52539 :       return StackFrame::WASM_COMPILED;
     183             :     case Code::JS_TO_WASM_FUNCTION:
     184           0 :       return StackFrame::JS_TO_WASM;
     185             :     case Code::WASM_TO_JS_FUNCTION:
     186       37883 :       return StackFrame::WASM_TO_JS;
     187             :     case Code::WASM_INTERPRETER_ENTRY:
     188        1369 :       return StackFrame::WASM_INTERPRETER_ENTRY;
     189             :     default:
     190           0 :       UNIMPLEMENTED();
     191             :       return StackFrame::NONE;
     192             :   }
     193             : }
     194             : 
     195      129059 : int CompilationInfo::GetDeclareGlobalsFlags() const {
     196             :   DCHECK(DeclareGlobalsLanguageMode::is_valid(parse_info()->language_mode()));
     197      129059 :   return DeclareGlobalsEvalFlag::encode(parse_info()->is_eval()) |
     198      129059 :          DeclareGlobalsNativeFlag::encode(parse_info()->is_native()) |
     199      129059 :          DeclareGlobalsLanguageMode::encode(parse_info()->language_mode());
     200             : }
     201             : 
     202             : SourcePositionTableBuilder::RecordingMode
     203     4349548 : CompilationInfo::SourcePositionRecordingMode() const {
     204             :   return parse_info() && parse_info()->is_native()
     205             :              ? SourcePositionTableBuilder::OMIT_SOURCE_POSITIONS
     206     8154989 :              : SourcePositionTableBuilder::RECORD_SOURCE_POSITIONS;
     207             : }
     208             : 
     209         123 : bool CompilationInfo::ExpectsJSReceiverAsReceiver() {
     210         246 :   return is_sloppy(parse_info()->language_mode()) && !parse_info()->is_native();
     211             : }
     212             : 
     213           0 : bool CompilationInfo::has_context() const { return !closure().is_null(); }
     214             : 
     215     1253330 : Context* CompilationInfo::context() const {
     216     2506660 :   return has_context() ? closure()->context() : nullptr;
     217             : }
     218             : 
     219     2694725 : bool CompilationInfo::has_native_context() const {
     220     5389451 :   return !closure().is_null() && (closure()->native_context() != nullptr);
     221             : }
     222             : 
     223     1957169 : Context* CompilationInfo::native_context() const {
     224     3914339 :   return has_native_context() ? closure()->native_context() : nullptr;
     225             : }
     226             : 
     227      737556 : bool CompilationInfo::has_global_object() const { return has_native_context(); }
     228             : 
     229      371554 : JSGlobalObject* CompilationInfo::global_object() const {
     230      371554 :   return has_global_object() ? native_context()->global_object() : nullptr;
     231             : }
     232             : 
     233     1604504 : void CompilationInfo::SetOptimizing() {
     234             :   DCHECK(has_shared_info());
     235             :   SetMode(OPTIMIZE);
     236      802252 :   optimization_id_ = isolate()->NextOptimizationId();
     237     1604504 :   code_flags_ = Code::KindField::update(code_flags_, Code::OPTIMIZED_FUNCTION);
     238      802252 : }
     239             : 
     240      145428 : int CompilationInfo::AddInlinedFunction(
     241             :     Handle<SharedFunctionInfo> inlined_function, SourcePosition pos) {
     242      290856 :   int id = static_cast<int>(inlined_functions_.size());
     243             :   inlined_functions_.push_back(InlinedFunctionHolder(
     244      290856 :       inlined_function, handle(inlined_function->code()), pos));
     245      145428 :   return id;
     246             : }
     247             : 
     248          26 : Code::Kind CompilationInfo::output_code_kind() const {
     249      193441 :   return Code::ExtractKindFromFlags(code_flags_);
     250             : }
     251             : 
     252             : }  // namespace internal
     253             : }  // namespace v8

Generated by: LCOV version 1.10