compilation-info.cc 6.98 KB
Newer Older
1 2 3 4 5 6 7
// 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.

#include "src/compilation-info.h"

#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 17 18

namespace v8 {
namespace internal {

19 20 21
// TODO(mvstanton): the Code::OPTIMIZED_FUNCTION constant below is
// bogus, it's just that I've eliminated Code::FUNCTION and there isn't
// a "better" value to put in this place.
22
CompilationInfo::CompilationInfo(Zone* zone, ParseInfo* parse_info,
23
                                 FunctionLiteral* literal)
24
    : CompilationInfo({}, Code::OPTIMIZED_FUNCTION, BASE, zone) {
25 26 27 28 29 30 31 32
  // NOTE: The parse_info passed here represents the global information gathered
  // during parsing, but does not represent specific details of the actual
  // function literal being compiled for this CompilationInfo. As such,
  // parse_info->literal() might be different from literal, and only global
  // details of the script being parsed are relevant to this CompilationInfo.
  DCHECK_NOT_NULL(literal);
  literal_ = literal;
  source_range_map_ = parse_info->source_range_map();
33

34 35
  if (parse_info->is_eval()) MarkAsEval();
  if (parse_info->is_native()) MarkAsNative();
36
  if (parse_info->collect_type_profile()) MarkAsCollectTypeProfile();
37 38
}

39 40 41
CompilationInfo::CompilationInfo(Zone* zone, Isolate* isolate,
                                 Handle<SharedFunctionInfo> shared,
                                 Handle<JSFunction> closure)
42
    : CompilationInfo({}, Code::OPTIMIZED_FUNCTION, OPTIMIZE, zone) {
43 44 45
  shared_info_ = shared;
  closure_ = closure;
  optimization_id_ = isolate->NextOptimizationId();
46
  dependencies_.reset(new CompilationDependencies(isolate, zone));
47 48 49

  if (FLAG_function_context_specialization) MarkAsFunctionContextSpecializing();
  if (FLAG_turbo_splitting) MarkAsSplittingEnabled();
50
  if (!FLAG_turbo_disable_switch_jump_table) SetFlag(kSwitchJumpTableEnabled);
51 52 53 54

  // Collect source positions for optimized code when profiling or if debugger
  // is active, to be able to get more precise source positions at the price of
  // more memory consumption.
55
  if (isolate->NeedsSourcePositionsForProfiling()) {
56 57 58 59
    MarkAsSourcePositionsEnabled();
  }
}

60
CompilationInfo::CompilationInfo(Vector<const char> debug_name, Zone* zone,
61
                                 Code::Kind code_kind)
62
    : CompilationInfo(debug_name, code_kind, STUB, zone) {}
63

64
CompilationInfo::CompilationInfo(Vector<const char> debug_name,
65 66
                                 Code::Kind code_kind, Mode mode, Zone* zone)
    : literal_(nullptr),
67
      source_range_map_(nullptr),
68
      flags_(FLAG_untrusted_code_mitigations ? kUntrustedCodeMitigations : 0),
69
      code_kind_(code_kind),
70
      stub_key_(0),
71
      builtin_index_(Builtins::kNoBuiltinId),
72
      mode_(mode),
73
      osr_offset_(BailoutId::None()),
74
      feedback_vector_spec_(zone),
75 76
      zone_(zone),
      deferred_handles_(nullptr),
77
      dependencies_(nullptr),
78
      bailout_reason_(BailoutReason::kNoReason),
79 80 81 82 83 84 85 86
      parameter_count_(0),
      optimization_id_(-1),
      debug_name_(debug_name) {}

CompilationInfo::~CompilationInfo() {
  if (GetFlag(kDisableFutureOptimization) && has_shared_info()) {
    shared_info()->DisableOptimization(bailout_reason());
  }
87 88 89
  if (dependencies()) {
    dependencies()->Rollback();
  }
90 91
}

92 93 94 95 96
DeclarationScope* CompilationInfo::scope() const {
  DCHECK_NOT_NULL(literal_);
  return literal_->scope();
}

97 98 99 100 101 102 103 104 105 106
int CompilationInfo::num_parameters() const {
  return !IsStub() ? scope()->num_parameters() : parameter_count_;
}

int CompilationInfo::num_parameters_including_this() const {
  return num_parameters() + (is_this_defined() ? 1 : 0);
}

bool CompilationInfo::is_this_defined() const { return !IsStub(); }

107 108
void CompilationInfo::set_deferred_handles(
    std::shared_ptr<DeferredHandles> deferred_handles) {
109
  DCHECK_NULL(deferred_handles_);
110 111 112 113
  deferred_handles_.swap(deferred_handles);
}

void CompilationInfo::set_deferred_handles(DeferredHandles* deferred_handles) {
114
  DCHECK_NULL(deferred_handles_);
115 116 117
  deferred_handles_.reset(deferred_handles);
}

118
void CompilationInfo::ReopenHandlesInNewHandleScope() {
119 120 121
  if (!shared_info_.is_null()) {
    shared_info_ = Handle<SharedFunctionInfo>(*shared_info_);
  }
122 123 124
  if (!closure_.is_null()) {
    closure_ = Handle<JSFunction>(*closure_);
  }
125 126 127 128 129 130 131
}

bool CompilationInfo::has_simple_parameters() {
  return scope()->has_simple_parameters();
}

std::unique_ptr<char[]> CompilationInfo::GetDebugName() const {
132
  if (literal()) {
133
    return literal()->GetDebugName();
134
  }
135 136
  if (!shared_info().is_null()) {
    return shared_info()->DebugName()->ToCString();
137 138 139 140 141 142 143 144 145 146
  }
  Vector<const char> name_vec = debug_name_;
  if (name_vec.is_empty()) name_vec = ArrayVector("unknown");
  std::unique_ptr<char[]> name(new char[name_vec.length() + 1]);
  memcpy(name.get(), name_vec.start(), name_vec.length());
  name[name_vec.length()] = '\0';
  return name;
}

StackFrame::Type CompilationInfo::GetOutputStackFrameType() const {
147
  switch (code_kind()) {
148 149 150 151 152
    case Code::STUB:
    case Code::BYTECODE_HANDLER:
    case Code::BUILTIN:
      return StackFrame::STUB;
    case Code::WASM_FUNCTION:
153
      return StackFrame::WASM_COMPILED;
154 155
    case Code::JS_TO_WASM_FUNCTION:
      return StackFrame::JS_TO_WASM;
156 157
    case Code::WASM_TO_WASM_FUNCTION:
      return StackFrame::WASM_TO_WASM;
158 159
    case Code::WASM_TO_JS_FUNCTION:
      return StackFrame::WASM_TO_JS;
160 161
    case Code::WASM_INTERPRETER_ENTRY:
      return StackFrame::WASM_INTERPRETER_ENTRY;
162 163 164 165 166 167 168
    default:
      UNIMPLEMENTED();
      return StackFrame::NONE;
  }
}

int CompilationInfo::GetDeclareGlobalsFlags() const {
169 170
  return DeclareGlobalsEvalFlag::encode(is_eval()) |
         DeclareGlobalsNativeFlag::encode(is_native());
171 172 173 174
}

SourcePositionTableBuilder::RecordingMode
CompilationInfo::SourcePositionRecordingMode() const {
175 176
  return is_native() ? SourcePositionTableBuilder::OMIT_SOURCE_POSITIONS
                     : SourcePositionTableBuilder::RECORD_SOURCE_POSITIONS;
177 178
}

179 180 181 182 183 184
bool CompilationInfo::has_context() const { return !closure().is_null(); }

Context* CompilationInfo::context() const {
  return has_context() ? closure()->context() : nullptr;
}

185 186 187 188 189 190 191 192 193 194 195 196 197 198
bool CompilationInfo::has_native_context() const {
  return !closure().is_null() && (closure()->native_context() != nullptr);
}

Context* CompilationInfo::native_context() const {
  return has_native_context() ? closure()->native_context() : nullptr;
}

bool CompilationInfo::has_global_object() const { return has_native_context(); }

JSGlobalObject* CompilationInfo::global_object() const {
  return has_global_object() ? native_context()->global_object() : nullptr;
}

199 200 201
int CompilationInfo::AddInlinedFunction(
    Handle<SharedFunctionInfo> inlined_function, SourcePosition pos) {
  int id = static_cast<int>(inlined_functions_.size());
202
  inlined_functions_.push_back(InlinedFunctionHolder(inlined_function, pos));
203
  return id;
204 205 206 207
}

}  // namespace internal
}  // namespace v8