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