compilation-info.h 10.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILATION_INFO_H_
#define V8_COMPILATION_INFO_H_

#include <memory>

#include "src/compilation-dependencies.h"
#include "src/frames.h"
12
#include "src/globals.h"
13 14 15 16 17 18 19 20 21
#include "src/handles.h"
#include "src/objects.h"
#include "src/source-position-table.h"
#include "src/utils.h"
#include "src/vector.h"

namespace v8 {
namespace internal {

22
class CoverageInfo;
23 24 25 26
class DeclarationScope;
class DeferredHandles;
class FunctionLiteral;
class Isolate;
27
class JavaScriptFrame;
28
class ParseInfo;
29
class SourceRangeMap;
30 31 32 33
class Zone;

// CompilationInfo encapsulates some information known at compile time.  It
// is constructed based on the resources available at compile-time.
34
class V8_EXPORT_PRIVATE CompilationInfo final {
35 36 37 38
 public:
  // Various configuration flags for a compilation, as well as some properties
  // of the compiled code produced by a compilation.
  enum Flag {
39 40 41 42 43 44 45 46 47 48 49
    kIsEval = 1 << 0,
    kIsNative = 1 << 1,
    kSerializing = 1 << 2,
    kAccessorInliningEnabled = 1 << 3,
    kFunctionContextSpecializing = 1 << 4,
    kInliningEnabled = 1 << 5,
    kDisableFutureOptimization = 1 << 6,
    kSplittingEnabled = 1 << 7,
    kSourcePositionsEnabled = 1 << 8,
    kBailoutOnUninitialized = 1 << 9,
    kLoopPeelingEnabled = 1 << 10,
50 51
  };

52 53
  // Construct a compilation info for unoptimized compilation.
  CompilationInfo(Zone* zone, Isolate* isolate, ParseInfo* parse_info,
54
                  FunctionLiteral* literal);
55
  // Construct a compilation info for optimized compilation.
56
  CompilationInfo(Zone* zone, Isolate* isolate,
57
                  Handle<SharedFunctionInfo> shared,
58
                  Handle<JSFunction> closure);
59
  // Construct a compilation info for stub compilation (or testing).
60
  CompilationInfo(Vector<const char> debug_name, Isolate* isolate, Zone* zone,
61
                  Code::Kind code_kind);
62 63
  ~CompilationInfo();

64 65 66 67 68 69
  FunctionLiteral* literal() const { return literal_; }
  void set_literal(FunctionLiteral* literal) {
    DCHECK_NOT_NULL(literal);
    literal_ = literal;
  }

70
  bool has_source_range_map() const { return source_range_map_ != nullptr; }
71 72 73 74
  SourceRangeMap* source_range_map() const { return source_range_map_; }
  void set_source_range_map(SourceRangeMap* source_range_map) {
    source_range_map_ = source_range_map;
  }
75 76 77 78 79

  DeclarationScope* scope() const;

  Isolate* isolate() const { return isolate_; }
  Zone* zone() { return zone_; }
80
  bool is_osr() const { return !osr_offset_.IsNone(); }
81 82 83 84 85
  Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
  void set_shared_info(Handle<SharedFunctionInfo> shared_info) {
    shared_info_ = shared_info;
  }
  bool has_shared_info() const { return !shared_info().is_null(); }
86 87
  Handle<JSFunction> closure() const { return closure_; }
  Handle<Code> code() const { return code_; }
88
  Code::Kind code_kind() const { return code_kind_; }
89
  BailoutId osr_offset() const { return osr_offset_; }
90 91 92 93 94 95 96 97 98 99 100 101 102
  JavaScriptFrame* osr_frame() const { return osr_frame_; }
  int num_parameters() const;
  int num_parameters_including_this() const;
  bool is_this_defined() const;

  void set_parameter_count(int parameter_count) {
    DCHECK(IsStub());
    parameter_count_ = parameter_count;
  }

  bool has_bytecode_array() const { return !bytecode_array_.is_null(); }
  Handle<BytecodeArray> bytecode_array() const { return bytecode_array_; }

103 104 105
  bool has_asm_wasm_data() const { return !asm_wasm_data_.is_null(); }
  Handle<FixedArray> asm_wasm_data() const { return asm_wasm_data_; }

106
  // Flags used by unoptimized compilation.
107

108 109
  void MarkAsSerializing() { SetFlag(kSerializing); }
  bool will_serialize() const { return GetFlag(kSerializing); }
110

111 112
  void MarkAsEval() { SetFlag(kIsEval); }
  bool is_eval() const { return GetFlag(kIsEval); }
113

114 115
  void MarkAsNative() { SetFlag(kIsNative); }
  bool is_native() const { return GetFlag(kIsNative); }
116

117
  // Flags used by optimized compilation.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146

  void MarkAsFunctionContextSpecializing() {
    SetFlag(kFunctionContextSpecializing);
  }
  bool is_function_context_specializing() const {
    return GetFlag(kFunctionContextSpecializing);
  }

  void MarkAsAccessorInliningEnabled() { SetFlag(kAccessorInliningEnabled); }
  bool is_accessor_inlining_enabled() const {
    return GetFlag(kAccessorInliningEnabled);
  }

  void MarkAsSourcePositionsEnabled() { SetFlag(kSourcePositionsEnabled); }
  bool is_source_positions_enabled() const {
    return GetFlag(kSourcePositionsEnabled);
  }

  void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); }
  bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); }

  void MarkAsSplittingEnabled() { SetFlag(kSplittingEnabled); }
  bool is_splitting_enabled() const { return GetFlag(kSplittingEnabled); }

  void MarkAsBailoutOnUninitialized() { SetFlag(kBailoutOnUninitialized); }
  bool is_bailout_on_uninitialized() const {
    return GetFlag(kBailoutOnUninitialized);
  }

147 148 149
  void MarkAsLoopPeelingEnabled() { SetFlag(kLoopPeelingEnabled); }
  bool is_loop_peeling_enabled() const { return GetFlag(kLoopPeelingEnabled); }

150
  // Code getters and setters.
151

152 153 154 155 156 157
  void SetCode(Handle<Code> code) { code_ = code; }

  void SetBytecodeArray(Handle<BytecodeArray> bytecode_array) {
    bytecode_array_ = bytecode_array;
  }

158 159
  void SetAsmWasmData(Handle<FixedArray> asm_wasm_data) {
    asm_wasm_data_ = asm_wasm_data;
160 161
  }

162 163 164
  bool has_context() const;
  Context* context() const;

165 166 167 168 169 170 171 172 173
  bool has_native_context() const;
  Context* native_context() const;

  bool has_global_object() const;
  JSGlobalObject* global_object() const;

  // Accessors for the different compilation modes.
  bool IsOptimizing() const { return mode_ == OPTIMIZE; }
  bool IsStub() const { return mode_ == STUB; }
174
  bool IsWasm() const { return code_kind() == Code::WASM_FUNCTION; }
175
  void SetOptimizingForOsr(BailoutId osr_offset, JavaScriptFrame* osr_frame) {
176
    DCHECK(IsOptimizing());
177
    osr_offset_ = osr_offset;
178 179 180
    osr_frame_ = osr_frame;
  }

181 182 183 184
  void set_deferred_handles(std::shared_ptr<DeferredHandles> deferred_handles);
  void set_deferred_handles(DeferredHandles* deferred_handles);
  std::shared_ptr<DeferredHandles> deferred_handles() {
    return deferred_handles_;
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
  }

  void ReopenHandlesInNewHandleScope();

  void AbortOptimization(BailoutReason reason) {
    DCHECK(reason != kNoReason);
    if (bailout_reason_ == kNoReason) bailout_reason_ = reason;
    SetFlag(kDisableFutureOptimization);
  }

  void RetryOptimization(BailoutReason reason) {
    DCHECK(reason != kNoReason);
    if (GetFlag(kDisableFutureOptimization)) return;
    bailout_reason_ = reason;
  }

  BailoutReason bailout_reason() const { return bailout_reason_; }

  CompilationDependencies* dependencies() { return &dependencies_; }

205 206 207 208
  int optimization_id() const {
    DCHECK(IsOptimizing());
    return optimization_id_;
  }
209

210 211 212 213
  int osr_expr_stack_height() {
    DCHECK_GE(osr_expr_stack_height_, 0);
    return osr_expr_stack_height_;
  }
214
  void set_osr_expr_stack_height(int height) {
215
    DCHECK_EQ(osr_expr_stack_height_, -1);
216
    osr_expr_stack_height_ = height;
217
    DCHECK_GE(osr_expr_stack_height_, 0);
218 219 220 221 222 223 224
  }

  bool has_simple_parameters();

  struct InlinedFunctionHolder {
    Handle<SharedFunctionInfo> shared_info;

225 226
    InliningPosition position;

227
    InlinedFunctionHolder(Handle<SharedFunctionInfo> inlined_shared_info,
228
                          SourcePosition pos)
229
        : shared_info(inlined_shared_info) {
230 231
      position.position = pos;
      // initialized when generating the deoptimization literals
232
      position.inlined_function_id = DeoptimizationInputData::kNotInlinedIndex;
233 234 235 236 237
    }

    void RegisterInlinedFunctionId(size_t inlined_function_id) {
      position.inlined_function_id = static_cast<int>(inlined_function_id);
    }
238 239 240
  };

  typedef std::vector<InlinedFunctionHolder> InlinedFunctionList;
241
  InlinedFunctionList& inlined_functions() { return inlined_functions_; }
242

243 244 245
  // Returns the inlining id for source position tracking.
  int AddInlinedFunction(Handle<SharedFunctionInfo> inlined_function,
                         SourcePosition pos);
246 247 248 249 250 251 252 253 254

  std::unique_ptr<char[]> GetDebugName() const;

  StackFrame::Type GetOutputStackFrameType() const;

  int GetDeclareGlobalsFlags() const;

  SourcePositionTableBuilder::RecordingMode SourcePositionRecordingMode() const;

255 256 257 258 259 260
  bool has_coverage_info() const { return !coverage_info_.is_null(); }
  Handle<CoverageInfo> coverage_info() const { return coverage_info_; }
  void set_coverage_info(Handle<CoverageInfo> coverage_info) {
    coverage_info_ = coverage_info;
  }

261 262 263 264 265 266
 private:
  // Compilation mode.
  // BASE is generated by the full codegen, optionally prepared for bailouts.
  // OPTIMIZE is optimized code generated by the Hydrogen-based backend.
  enum Mode { BASE, OPTIMIZE, STUB };

267
  CompilationInfo(Vector<const char> debug_name, Code::Kind code_kind,
268
                  Mode mode, Isolate* isolate, Zone* zone);
269 270 271 272 273 274 275 276 277 278 279

  void SetMode(Mode mode) { mode_ = mode; }

  void SetFlag(Flag flag) { flags_ |= flag; }

  void SetFlag(Flag flag, bool value) {
    flags_ = value ? flags_ | flag : flags_ & ~flag;
  }

  bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; }

280 281 282
  Isolate* isolate_;
  FunctionLiteral* literal_;
  SourceRangeMap* source_range_map_;  // Used when block coverage is enabled.
283

284 285
  unsigned flags_;

286
  Code::Kind code_kind_;
287

288 289
  Handle<SharedFunctionInfo> shared_info_;

290 291 292 293 294 295 296
  Handle<JSFunction> closure_;

  // The compiled code.
  Handle<Code> code_;

  // Compilation mode flag and whether deoptimization is allowed.
  Mode mode_;
297
  BailoutId osr_offset_;
298 299 300 301 302 303

  // Holds the bytecode array generated by the interpreter.
  // TODO(rmcilroy/mstarzinger): Temporary work-around until compiler.cc is
  // refactored to avoid us needing to carry the BytcodeArray around.
  Handle<BytecodeArray> bytecode_array_;

304 305 306
  // Holds the asm_wasm array generated by the asmjs compiler.
  Handle<FixedArray> asm_wasm_data_;

307 308 309 310
  // The zone from which the compilation pipeline working on this
  // CompilationInfo allocates.
  Zone* zone_;

311
  std::shared_ptr<DeferredHandles> deferred_handles_;
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331

  // Dependencies for this compilation, e.g. stable maps.
  CompilationDependencies dependencies_;

  BailoutReason bailout_reason_;

  InlinedFunctionList inlined_functions_;

  // Number of parameters used for compilation of stubs that require arguments.
  int parameter_count_;

  int optimization_id_;

  int osr_expr_stack_height_;

  // The current OSR frame for specialization or {nullptr}.
  JavaScriptFrame* osr_frame_ = nullptr;

  Vector<const char> debug_name_;

332 333 334 335
  // Encapsulates coverage information gathered by the bytecode generator.
  // Needs to be stored on the shared function info once compilation completes.
  Handle<CoverageInfo> coverage_info_;

336 337 338 339 340 341 342
  DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
};

}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILATION_INFO_H_