LCOV - code coverage report
Current view: top level - src - compilation-info.h (source / functions) Hit Total Coverage
Test: app.info Lines: 41 44 93.2 %
Date: 2017-04-26 Functions: 1 1 100.0 %

          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             : #ifndef V8_COMPILATION_INFO_H_
       6             : #define V8_COMPILATION_INFO_H_
       7             : 
       8             : #include <memory>
       9             : 
      10             : #include "src/compilation-dependencies.h"
      11             : #include "src/frames.h"
      12             : #include "src/globals.h"
      13             : #include "src/handles.h"
      14             : #include "src/objects.h"
      15             : #include "src/source-position-table.h"
      16             : #include "src/utils.h"
      17             : #include "src/vector.h"
      18             : 
      19             : namespace v8 {
      20             : namespace internal {
      21             : 
      22             : class DeclarationScope;
      23             : class DeferredHandles;
      24             : class FunctionLiteral;
      25             : class JavaScriptFrame;
      26             : class ParseInfo;
      27             : class Isolate;
      28             : class Zone;
      29             : 
      30             : // CompilationInfo encapsulates some information known at compile time.  It
      31             : // is constructed based on the resources available at compile-time.
      32             : class V8_EXPORT_PRIVATE CompilationInfo final {
      33             :  public:
      34             :   // Various configuration flags for a compilation, as well as some properties
      35             :   // of the compiled code produced by a compilation.
      36             :   enum Flag {
      37             :     kDeferredCalling = 1 << 0,
      38             :     kNonDeferredCalling = 1 << 1,
      39             :     kSavesCallerDoubles = 1 << 2,
      40             :     kRequiresFrame = 1 << 3,
      41             :     kDeoptimizationSupport = 1 << 4,
      42             :     kAccessorInliningEnabled = 1 << 5,
      43             :     kSerializing = 1 << 6,
      44             :     kFunctionContextSpecializing = 1 << 7,
      45             :     kFrameSpecializing = 1 << 8,
      46             :     kInliningEnabled = 1 << 9,
      47             :     kDisableFutureOptimization = 1 << 10,
      48             :     kSplittingEnabled = 1 << 11,
      49             :     kDeoptimizationEnabled = 1 << 12,
      50             :     kSourcePositionsEnabled = 1 << 13,
      51             :     kBailoutOnUninitialized = 1 << 14,
      52             :     kOptimizeFromBytecode = 1 << 15,
      53             :     kLoopPeelingEnabled = 1 << 16,
      54             :   };
      55             : 
      56             :   CompilationInfo(Zone* zone, ParseInfo* parse_info, Isolate* isolate,
      57             :                   Handle<JSFunction> closure);
      58             :   CompilationInfo(Vector<const char> debug_name, Isolate* isolate, Zone* zone,
      59             :                   Code::Flags code_flags);
      60             :   ~CompilationInfo();
      61             : 
      62             :   ParseInfo* parse_info() const { return parse_info_; }
      63             : 
      64             :   // -----------------------------------------------------------
      65             :   // TODO(titzer): inline and delete accessors of ParseInfo
      66             :   // -----------------------------------------------------------
      67             :   Handle<Script> script() const;
      68             :   FunctionLiteral* literal() const;
      69             :   DeclarationScope* scope() const;
      70             :   Handle<SharedFunctionInfo> shared_info() const;
      71             :   bool has_shared_info() const;
      72             :   // -----------------------------------------------------------
      73             : 
      74             :   Isolate* isolate() const { return isolate_; }
      75             :   Zone* zone() { return zone_; }
      76      395378 :   bool is_osr() const { return !osr_ast_id_.IsNone(); }
      77             :   Handle<JSFunction> closure() const { return closure_; }
      78             :   Handle<Code> code() const { return code_; }
      79             :   Code::Flags code_flags() const { return code_flags_; }
      80             :   BailoutId osr_ast_id() const { return osr_ast_id_; }
      81             :   JavaScriptFrame* osr_frame() const { return osr_frame_; }
      82             :   int num_parameters() const;
      83             :   int num_parameters_including_this() const;
      84             :   bool is_this_defined() const;
      85             : 
      86             :   void set_parameter_count(int parameter_count) {
      87             :     DCHECK(IsStub());
      88       23533 :     parameter_count_ = parameter_count;
      89             :   }
      90             : 
      91             :   bool has_bytecode_array() const { return !bytecode_array_.is_null(); }
      92             :   Handle<BytecodeArray> bytecode_array() const { return bytecode_array_; }
      93             : 
      94             :   bool is_calling() const {
      95             :     return GetFlag(kDeferredCalling) || GetFlag(kNonDeferredCalling);
      96             :   }
      97             : 
      98             :   void MarkAsDeferredCalling() { SetFlag(kDeferredCalling); }
      99             : 
     100        9002 :   bool is_deferred_calling() const { return GetFlag(kDeferredCalling); }
     101             : 
     102             :   void MarkAsNonDeferredCalling() { SetFlag(kNonDeferredCalling); }
     103             : 
     104       59968 :   bool is_non_deferred_calling() const { return GetFlag(kNonDeferredCalling); }
     105             : 
     106             :   void MarkAsSavesCallerDoubles() { SetFlag(kSavesCallerDoubles); }
     107             : 
     108     5151489 :   bool saves_caller_doubles() const { return GetFlag(kSavesCallerDoubles); }
     109             : 
     110             :   void MarkAsRequiresFrame() { SetFlag(kRequiresFrame); }
     111             : 
     112             :   bool requires_frame() const { return GetFlag(kRequiresFrame); }
     113             : 
     114             :   // Compiles marked as debug produce unoptimized code with debug break slots.
     115             :   // Inner functions that cannot be compiled w/o context are compiled eagerly.
     116             :   // Always include deoptimization support to avoid having to recompile again.
     117             :   void MarkAsDebug() {
     118       10197 :     set_is_debug();
     119             :     SetFlag(kDeoptimizationSupport);
     120             :   }
     121             : 
     122             :   bool is_debug() const;
     123             : 
     124             :   void PrepareForSerializing();
     125             : 
     126     5304808 :   bool will_serialize() const { return GetFlag(kSerializing); }
     127             : 
     128             :   void MarkAsFunctionContextSpecializing() {
     129             :     SetFlag(kFunctionContextSpecializing);
     130             :   }
     131             : 
     132     1049719 :   bool is_function_context_specializing() const {
     133             :     return GetFlag(kFunctionContextSpecializing);
     134             :   }
     135             : 
     136             :   void MarkAsFrameSpecializing() { SetFlag(kFrameSpecializing); }
     137             : 
     138      395343 :   bool is_frame_specializing() const { return GetFlag(kFrameSpecializing); }
     139             : 
     140             :   void MarkAsDeoptimizationEnabled() { SetFlag(kDeoptimizationEnabled); }
     141             : 
     142     2959893 :   bool is_deoptimization_enabled() const {
     143             :     return GetFlag(kDeoptimizationEnabled);
     144             :   }
     145             : 
     146             :   void MarkAsAccessorInliningEnabled() { SetFlag(kAccessorInliningEnabled); }
     147             : 
     148      395343 :   bool is_accessor_inlining_enabled() const {
     149             :     return GetFlag(kAccessorInliningEnabled);
     150             :   }
     151             : 
     152             :   void MarkAsSourcePositionsEnabled() { SetFlag(kSourcePositionsEnabled); }
     153             : 
     154    17546148 :   bool is_source_positions_enabled() const {
     155             :     return GetFlag(kSourcePositionsEnabled);
     156             :   }
     157             : 
     158             :   void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); }
     159             : 
     160      395342 :   bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); }
     161             : 
     162             :   void MarkAsSplittingEnabled() { SetFlag(kSplittingEnabled); }
     163             : 
     164      568259 :   bool is_splitting_enabled() const { return GetFlag(kSplittingEnabled); }
     165             : 
     166             :   void MarkAsBailoutOnUninitialized() { SetFlag(kBailoutOnUninitialized); }
     167             : 
     168       38030 :   bool is_bailout_on_uninitialized() const {
     169             :     return GetFlag(kBailoutOnUninitialized);
     170             :   }
     171             : 
     172             :   void MarkAsOptimizeFromBytecode() { SetFlag(kOptimizeFromBytecode); }
     173             : 
     174     2305236 :   bool is_optimizing_from_bytecode() const {
     175             :     return GetFlag(kOptimizeFromBytecode);
     176             :   }
     177             : 
     178             :   void MarkAsLoopPeelingEnabled() { SetFlag(kLoopPeelingEnabled); }
     179             : 
     180      395303 :   bool is_loop_peeling_enabled() const { return GetFlag(kLoopPeelingEnabled); }
     181             : 
     182     2194167 :   bool GeneratePreagedPrologue() const {
     183             :     // Generate a pre-aged prologue if we are optimizing for size, which
     184             :     // will make code flushing more aggressive. Only apply to Code::FUNCTION,
     185             :     // since StaticMarkingVisitor::IsFlushable only flushes proper functions.
     186     2194193 :     return FLAG_optimize_for_size && FLAG_age_code && !is_debug() &&
     187     2194193 :            output_code_kind() == Code::FUNCTION;
     188             :   }
     189             : 
     190     4716470 :   void SetCode(Handle<Code> code) { code_ = code; }
     191             : 
     192             :   void SetBytecodeArray(Handle<BytecodeArray> bytecode_array) {
     193     2077425 :     bytecode_array_ = bytecode_array;
     194             :   }
     195             : 
     196           0 :   bool ShouldTrapOnDeopt() const {
     197      779377 :     return (FLAG_trap_on_deopt && IsOptimizing()) ||
     198           0 :            (FLAG_trap_on_stub_deopt && IsStub());
     199             :   }
     200             : 
     201             :   bool has_context() const;
     202             :   Context* context() const;
     203             : 
     204             :   bool has_native_context() const;
     205             :   Context* native_context() const;
     206             : 
     207             :   bool has_global_object() const;
     208             :   JSGlobalObject* global_object() const;
     209             : 
     210             :   // Accessors for the different compilation modes.
     211             :   bool IsOptimizing() const { return mode_ == OPTIMIZE; }
     212           0 :   bool IsStub() const { return mode_ == STUB; }
     213             :   bool IsWasm() const { return output_code_kind() == Code::WASM_FUNCTION; }
     214             :   void SetOptimizing();
     215             :   void SetOptimizingForOsr(BailoutId osr_ast_id, JavaScriptFrame* osr_frame) {
     216      797360 :     SetOptimizing();
     217      797359 :     osr_ast_id_ = osr_ast_id;
     218      797359 :     osr_frame_ = osr_frame;
     219             :   }
     220             : 
     221             :   // Deoptimization support.
     222    45576796 :   bool HasDeoptimizationSupport() const {
     223             :     return GetFlag(kDeoptimizationSupport);
     224             :   }
     225             :   void EnableDeoptimizationSupport() {
     226             :     DCHECK_EQ(BASE, mode_);
     227             :     SetFlag(kDeoptimizationSupport);
     228             :   }
     229     7421081 :   bool ShouldEnsureSpaceForLazyDeopt() { return !IsStub(); }
     230             : 
     231             :   bool ExpectsJSReceiverAsReceiver();
     232             : 
     233             :   // Determines whether or not to insert a self-optimization header.
     234             :   bool ShouldSelfOptimize();
     235             : 
     236             :   void set_deferred_handles(std::shared_ptr<DeferredHandles> deferred_handles);
     237             :   void set_deferred_handles(DeferredHandles* deferred_handles);
     238             :   std::shared_ptr<DeferredHandles> deferred_handles() {
     239             :     return deferred_handles_;
     240             :   }
     241             : 
     242             :   void ReopenHandlesInNewHandleScope();
     243             : 
     244             :   void AbortOptimization(BailoutReason reason) {
     245             :     DCHECK(reason != kNoReason);
     246       48808 :     if (bailout_reason_ == kNoReason) bailout_reason_ = reason;
     247             :     SetFlag(kDisableFutureOptimization);
     248             :   }
     249             : 
     250         159 :   void RetryOptimization(BailoutReason reason) {
     251             :     DCHECK(reason != kNoReason);
     252         159 :     if (GetFlag(kDisableFutureOptimization)) return;
     253         128 :     bailout_reason_ = reason;
     254             :   }
     255             : 
     256             :   BailoutReason bailout_reason() const { return bailout_reason_; }
     257             : 
     258             :   int prologue_offset() const {
     259             :     DCHECK_NE(Code::kPrologueOffsetNotSet, prologue_offset_);
     260             :     return prologue_offset_;
     261             :   }
     262             : 
     263             :   void set_prologue_offset(int prologue_offset) {
     264             :     DCHECK_EQ(Code::kPrologueOffsetNotSet, prologue_offset_);
     265     2272089 :     prologue_offset_ = prologue_offset;
     266             :   }
     267             : 
     268             :   CompilationDependencies* dependencies() { return &dependencies_; }
     269             : 
     270             :   int optimization_id() const { return optimization_id_; }
     271             : 
     272             :   int osr_expr_stack_height() { return osr_expr_stack_height_; }
     273             :   void set_osr_expr_stack_height(int height) {
     274             :     DCHECK(height >= 0);
     275          68 :     osr_expr_stack_height_ = height;
     276             :   }
     277             : 
     278             :   bool has_simple_parameters();
     279             : 
     280             :   struct InlinedFunctionHolder {
     281             :     Handle<SharedFunctionInfo> shared_info;
     282             : 
     283             :     // Root that holds the unoptimized code of the inlined function alive
     284             :     // (and out of reach of code flushing) until we finish compilation.
     285             :     // Do not remove.
     286             :     Handle<Code> inlined_code_object_root;
     287             : 
     288             :     InliningPosition position;
     289             : 
     290             :     InlinedFunctionHolder(Handle<SharedFunctionInfo> inlined_shared_info,
     291             :                           Handle<Code> inlined_code_object_root,
     292             :                           SourcePosition pos)
     293             :         : shared_info(inlined_shared_info),
     294      145428 :           inlined_code_object_root(inlined_code_object_root) {
     295      145428 :       position.position = pos;
     296             :       // initialized when generating the deoptimization literals
     297      145428 :       position.inlined_function_id = DeoptimizationInputData::kNotInlinedIndex;
     298             :     }
     299             : 
     300             :     void RegisterInlinedFunctionId(size_t inlined_function_id) {
     301      142976 :       position.inlined_function_id = static_cast<int>(inlined_function_id);
     302             :     }
     303             :   };
     304             : 
     305             :   typedef std::vector<InlinedFunctionHolder> InlinedFunctionList;
     306             :   InlinedFunctionList& inlined_functions() { return inlined_functions_; }
     307             : 
     308             :   // Returns the inlining id for source position tracking.
     309             :   int AddInlinedFunction(Handle<SharedFunctionInfo> inlined_function,
     310             :                          SourcePosition pos);
     311             : 
     312             :   std::unique_ptr<char[]> GetDebugName() const;
     313             : 
     314             :   Code::Kind output_code_kind() const;
     315             : 
     316             :   StackFrame::Type GetOutputStackFrameType() const;
     317             : 
     318             :   int GetDeclareGlobalsFlags() const;
     319             : 
     320             :   SourcePositionTableBuilder::RecordingMode SourcePositionRecordingMode() const;
     321             : 
     322             :  private:
     323             :   // Compilation mode.
     324             :   // BASE is generated by the full codegen, optionally prepared for bailouts.
     325             :   // OPTIMIZE is optimized code generated by the Hydrogen-based backend.
     326             :   enum Mode { BASE, OPTIMIZE, STUB };
     327             : 
     328             :   CompilationInfo(ParseInfo* parse_info, Vector<const char> debug_name,
     329             :                   Code::Flags code_flags, Mode mode, Isolate* isolate,
     330             :                   Zone* zone);
     331             : 
     332             :   ParseInfo* parse_info_;
     333             :   Isolate* isolate_;
     334             : 
     335      802252 :   void SetMode(Mode mode) { mode_ = mode; }
     336             : 
     337     9992277 :   void SetFlag(Flag flag) { flags_ |= flag; }
     338             : 
     339             :   void SetFlag(Flag flag, bool value) {
     340             :     flags_ = value ? flags_ | flag : flags_ & ~flag;
     341             :   }
     342             : 
     343    88229724 :   bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; }
     344             : 
     345             :   void set_is_debug();
     346             : 
     347             :   unsigned flags_;
     348             : 
     349             :   Code::Flags code_flags_;
     350             : 
     351             :   Handle<JSFunction> closure_;
     352             : 
     353             :   // The compiled code.
     354             :   Handle<Code> code_;
     355             : 
     356             :   // Compilation mode flag and whether deoptimization is allowed.
     357             :   Mode mode_;
     358             :   BailoutId osr_ast_id_;
     359             : 
     360             :   // Holds the bytecode array generated by the interpreter.
     361             :   // TODO(rmcilroy/mstarzinger): Temporary work-around until compiler.cc is
     362             :   // refactored to avoid us needing to carry the BytcodeArray around.
     363             :   Handle<BytecodeArray> bytecode_array_;
     364             : 
     365             :   // The zone from which the compilation pipeline working on this
     366             :   // CompilationInfo allocates.
     367             :   Zone* zone_;
     368             : 
     369             :   std::shared_ptr<DeferredHandles> deferred_handles_;
     370             : 
     371             :   // Dependencies for this compilation, e.g. stable maps.
     372             :   CompilationDependencies dependencies_;
     373             : 
     374             :   BailoutReason bailout_reason_;
     375             : 
     376             :   int prologue_offset_;
     377             : 
     378             :   InlinedFunctionList inlined_functions_;
     379             : 
     380             :   // Number of parameters used for compilation of stubs that require arguments.
     381             :   int parameter_count_;
     382             : 
     383             :   int optimization_id_;
     384             : 
     385             :   int osr_expr_stack_height_;
     386             : 
     387             :   // The current OSR frame for specialization or {nullptr}.
     388             :   JavaScriptFrame* osr_frame_ = nullptr;
     389             : 
     390             :   Vector<const char> debug_name_;
     391             : 
     392             :   DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
     393             : };
     394             : 
     395             : }  // namespace internal
     396             : }  // namespace v8
     397             : 
     398             : #endif  // V8_COMPILATION_INFO_H_

Generated by: LCOV version 1.10