Home | History | Annotate | Download | only in src
      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/optimized-compilation-info.h"
      6 
      7 #include "src/api.h"
      8 #include "src/debug/debug.h"
      9 #include "src/isolate.h"
     10 #include "src/objects-inl.h"
     11 #include "src/objects/shared-function-info.h"
     12 #include "src/source-position.h"
     13 
     14 namespace v8 {
     15 namespace internal {
     16 
     17 OptimizedCompilationInfo::OptimizedCompilationInfo(
     18     Zone* zone, Isolate* isolate, Handle<SharedFunctionInfo> shared,
     19     Handle<JSFunction> closure)
     20     : OptimizedCompilationInfo({}, AbstractCode::OPTIMIZED_FUNCTION, zone) {
     21   shared_info_ = shared;
     22   closure_ = closure;
     23   optimization_id_ = isolate->NextOptimizationId();
     24 
     25   SetFlag(kCalledWithCodeStartRegister);
     26   if (FLAG_function_context_specialization) MarkAsFunctionContextSpecializing();
     27   if (FLAG_turbo_splitting) MarkAsSplittingEnabled();
     28   SetFlag(kSwitchJumpTableEnabled);
     29   if (FLAG_untrusted_code_mitigations) MarkAsPoisoningRegisterArguments();
     30 
     31   // TODO(yangguo): Disable this in case of debugging for crbug.com/826613
     32   if (FLAG_analyze_environment_liveness) {
     33     MarkAsAnalyzeEnvironmentLiveness();
     34   }
     35 
     36   // Collect source positions for optimized code when profiling or if debugger
     37   // is active, to be able to get more precise source positions at the price of
     38   // more memory consumption.
     39   if (isolate->NeedsDetailedOptimizedCodeLineInfo()) {
     40     MarkAsSourcePositionsEnabled();
     41   }
     42 
     43   SetTracingFlags(shared->PassesFilter(FLAG_trace_turbo_filter));
     44 }
     45 
     46 OptimizedCompilationInfo::OptimizedCompilationInfo(
     47     Vector<const char> debug_name, Zone* zone, Code::Kind code_kind)
     48     : OptimizedCompilationInfo(
     49           debug_name, static_cast<AbstractCode::Kind>(code_kind), zone) {
     50   if (code_kind == Code::BYTECODE_HANDLER) {
     51     SetFlag(OptimizedCompilationInfo::kCalledWithCodeStartRegister);
     52   }
     53 #if ENABLE_GDB_JIT_INTERFACE
     54 #if DEBUG
     55   if (code_kind == Code::BUILTIN || code_kind == Code::STUB) {
     56     MarkAsSourcePositionsEnabled();
     57   }
     58 #endif
     59 #endif
     60   SetTracingFlags(
     61       PassesFilter(debug_name, CStrVector(FLAG_trace_turbo_filter)));
     62   // Embedded builtins don't support embedded absolute code addresses, so we
     63   // cannot use jump tables.
     64   if (code_kind != Code::BUILTIN) {
     65     SetFlag(kSwitchJumpTableEnabled);
     66   }
     67 }
     68 
     69 OptimizedCompilationInfo::OptimizedCompilationInfo(
     70     Vector<const char> debug_name, AbstractCode::Kind code_kind, Zone* zone)
     71     : flags_(FLAG_untrusted_code_mitigations ? kUntrustedCodeMitigations : 0),
     72       code_kind_(code_kind),
     73       stub_key_(0),
     74       builtin_index_(Builtins::kNoBuiltinId),
     75       osr_offset_(BailoutId::None()),
     76       zone_(zone),
     77       deferred_handles_(nullptr),
     78       bailout_reason_(BailoutReason::kNoReason),
     79       optimization_id_(-1),
     80       debug_name_(debug_name) {}
     81 
     82 OptimizedCompilationInfo::~OptimizedCompilationInfo() {
     83   if (GetFlag(kDisableFutureOptimization) && has_shared_info()) {
     84     shared_info()->DisableOptimization(bailout_reason());
     85   }
     86 }
     87 
     88 void OptimizedCompilationInfo::set_deferred_handles(
     89     std::shared_ptr<DeferredHandles> deferred_handles) {
     90   DCHECK_NULL(deferred_handles_);
     91   deferred_handles_.swap(deferred_handles);
     92 }
     93 
     94 void OptimizedCompilationInfo::set_deferred_handles(
     95     DeferredHandles* deferred_handles) {
     96   DCHECK_NULL(deferred_handles_);
     97   deferred_handles_.reset(deferred_handles);
     98 }
     99 
    100 void OptimizedCompilationInfo::ReopenHandlesInNewHandleScope(Isolate* isolate) {
    101   if (!shared_info_.is_null()) {
    102     shared_info_ = Handle<SharedFunctionInfo>(*shared_info_, isolate);
    103   }
    104   if (!closure_.is_null()) {
    105     closure_ = Handle<JSFunction>(*closure_, isolate);
    106   }
    107 }
    108 
    109 std::unique_ptr<char[]> OptimizedCompilationInfo::GetDebugName() const {
    110   if (!shared_info().is_null()) {
    111     return shared_info()->DebugName()->ToCString();
    112   }
    113   Vector<const char> name_vec = debug_name_;
    114   if (name_vec.is_empty()) name_vec = ArrayVector("unknown");
    115   std::unique_ptr<char[]> name(new char[name_vec.length() + 1]);
    116   memcpy(name.get(), name_vec.start(), name_vec.length());
    117   name[name_vec.length()] = '\0';
    118   return name;
    119 }
    120 
    121 StackFrame::Type OptimizedCompilationInfo::GetOutputStackFrameType() const {
    122   switch (code_kind()) {
    123     case Code::STUB:
    124     case Code::BYTECODE_HANDLER:
    125     case Code::BUILTIN:
    126       return StackFrame::STUB;
    127     case Code::WASM_FUNCTION:
    128       return StackFrame::WASM_COMPILED;
    129     case Code::JS_TO_WASM_FUNCTION:
    130       return StackFrame::JS_TO_WASM;
    131     case Code::WASM_TO_JS_FUNCTION:
    132       return StackFrame::WASM_TO_JS;
    133     case Code::WASM_INTERPRETER_ENTRY:
    134       return StackFrame::WASM_INTERPRETER_ENTRY;
    135     default:
    136       UNIMPLEMENTED();
    137       return StackFrame::NONE;
    138   }
    139 }
    140 
    141 bool OptimizedCompilationInfo::has_context() const {
    142   return !closure().is_null();
    143 }
    144 
    145 Context* OptimizedCompilationInfo::context() const {
    146   return has_context() ? closure()->context() : nullptr;
    147 }
    148 
    149 bool OptimizedCompilationInfo::has_native_context() const {
    150   return !closure().is_null() && (closure()->native_context() != nullptr);
    151 }
    152 
    153 Context* OptimizedCompilationInfo::native_context() const {
    154   return has_native_context() ? closure()->native_context() : nullptr;
    155 }
    156 
    157 bool OptimizedCompilationInfo::has_global_object() const {
    158   return has_native_context();
    159 }
    160 
    161 JSGlobalObject* OptimizedCompilationInfo::global_object() const {
    162   return has_global_object() ? native_context()->global_object() : nullptr;
    163 }
    164 
    165 int OptimizedCompilationInfo::AddInlinedFunction(
    166     Handle<SharedFunctionInfo> inlined_function, SourcePosition pos) {
    167   int id = static_cast<int>(inlined_functions_.size());
    168   inlined_functions_.push_back(InlinedFunctionHolder(inlined_function, pos));
    169   return id;
    170 }
    171 
    172 void OptimizedCompilationInfo::SetTracingFlags(bool passes_filter) {
    173   if (!passes_filter) return;
    174   if (FLAG_trace_turbo) SetFlag(kTraceTurboJson);
    175   if (FLAG_trace_turbo_graph) SetFlag(kTraceTurboGraph);
    176   if (FLAG_trace_turbo_scheduled) SetFlag(kTraceTurboScheduled);
    177 }
    178 
    179 }  // namespace internal
    180 }  // namespace v8
    181