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/codegen/optimized-compilation-info.h" 6 7#include "src/api/api.h" 8#include "src/base/platform/wrappers.h" 9#include "src/codegen/source-position.h" 10#include "src/debug/debug.h" 11#include "src/execution/isolate.h" 12#include "src/objects/objects-inl.h" 13#include "src/objects/shared-function-info.h" 14#include "src/tracing/trace-event.h" 15#include "src/tracing/traced-value.h" 16 17#if V8_ENABLE_WEBASSEMBLY 18#include "src/wasm/function-compiler.h" 19#endif // V8_ENABLE_WEBASSEMBLY 20 21namespace v8 { 22namespace internal { 23 24OptimizedCompilationInfo::OptimizedCompilationInfo( 25 Zone* zone, Isolate* isolate, Handle<SharedFunctionInfo> shared, 26 Handle<JSFunction> closure, CodeKind code_kind, BytecodeOffset osr_offset, 27 JavaScriptFrame* osr_frame) 28 : code_kind_(code_kind), 29 osr_offset_(osr_offset), 30 osr_frame_(osr_frame), 31 zone_(zone), 32 optimization_id_(isolate->NextOptimizationId()) { 33 DCHECK_EQ(*shared, closure->shared()); 34 DCHECK(shared->is_compiled()); 35 DCHECK_IMPLIES(is_osr(), IsOptimizing()); 36 bytecode_array_ = handle(shared->GetBytecodeArray(isolate), isolate); 37 shared_info_ = shared; 38 closure_ = closure; 39 40 // Collect source positions for optimized code when profiling or if debugger 41 // is active, to be able to get more precise source positions at the price of 42 // more memory consumption. 43 if (isolate->NeedsDetailedOptimizedCodeLineInfo()) { 44 set_source_positions(); 45 } 46 47 SetTracingFlags(shared->PassesFilter(FLAG_trace_turbo_filter)); 48 ConfigureFlags(); 49 50 if (isolate->node_observer()) { 51 SetNodeObserver(isolate->node_observer()); 52 } 53} 54 55OptimizedCompilationInfo::OptimizedCompilationInfo( 56 base::Vector<const char> debug_name, Zone* zone, CodeKind code_kind) 57 : code_kind_(code_kind), 58 zone_(zone), 59 optimization_id_(kNoOptimizationId), 60 debug_name_(debug_name) { 61 SetTracingFlags( 62 PassesFilter(debug_name, base::CStrVector(FLAG_trace_turbo_filter))); 63 ConfigureFlags(); 64} 65 66void OptimizedCompilationInfo::ConfigureFlags() { 67 if (FLAG_turbo_inline_js_wasm_calls) set_inline_js_wasm_calls(); 68 69 switch (code_kind_) { 70 case CodeKind::TURBOFAN: 71 set_called_with_code_start_register(); 72 set_switch_jump_table(); 73 if (FLAG_analyze_environment_liveness) { 74 set_analyze_environment_liveness(); 75 } 76 if (FLAG_turbo_splitting) set_splitting(); 77 break; 78 case CodeKind::BYTECODE_HANDLER: 79 set_called_with_code_start_register(); 80 if (FLAG_turbo_splitting) set_splitting(); 81 break; 82 case CodeKind::BUILTIN: 83 case CodeKind::FOR_TESTING: 84 if (FLAG_turbo_splitting) set_splitting(); 85#if ENABLE_GDB_JIT_INTERFACE && DEBUG 86 set_source_positions(); 87#endif // ENABLE_GDB_JIT_INTERFACE && DEBUG 88 break; 89 case CodeKind::WASM_FUNCTION: 90 case CodeKind::WASM_TO_CAPI_FUNCTION: 91 set_switch_jump_table(); 92 break; 93 case CodeKind::C_WASM_ENTRY: 94 case CodeKind::JS_TO_JS_FUNCTION: 95 case CodeKind::JS_TO_WASM_FUNCTION: 96 case CodeKind::WASM_TO_JS_FUNCTION: 97 break; 98 case CodeKind::BASELINE: 99 case CodeKind::MAGLEV: 100 case CodeKind::INTERPRETED_FUNCTION: 101 case CodeKind::REGEXP: 102 UNREACHABLE(); 103 } 104} 105 106OptimizedCompilationInfo::~OptimizedCompilationInfo() { 107 if (disable_future_optimization() && has_shared_info()) { 108 shared_info()->DisableOptimization(bailout_reason()); 109 } 110} 111 112void OptimizedCompilationInfo::ReopenHandlesInNewHandleScope(Isolate* isolate) { 113 if (!shared_info_.is_null()) { 114 shared_info_ = Handle<SharedFunctionInfo>(*shared_info_, isolate); 115 } 116 if (!bytecode_array_.is_null()) { 117 bytecode_array_ = Handle<BytecodeArray>(*bytecode_array_, isolate); 118 } 119 if (!closure_.is_null()) { 120 closure_ = Handle<JSFunction>(*closure_, isolate); 121 } 122 DCHECK(code_.is_null()); 123} 124 125void OptimizedCompilationInfo::AbortOptimization(BailoutReason reason) { 126 DCHECK_NE(reason, BailoutReason::kNoReason); 127 if (bailout_reason_ == BailoutReason::kNoReason) { 128 bailout_reason_ = reason; 129 } 130 set_disable_future_optimization(); 131} 132 133void OptimizedCompilationInfo::RetryOptimization(BailoutReason reason) { 134 DCHECK_NE(reason, BailoutReason::kNoReason); 135 if (disable_future_optimization()) return; 136 bailout_reason_ = reason; 137} 138 139std::unique_ptr<char[]> OptimizedCompilationInfo::GetDebugName() const { 140 if (!shared_info().is_null()) { 141 return shared_info()->DebugNameCStr(); 142 } 143 base::Vector<const char> name_vec = debug_name_; 144 if (name_vec.empty()) name_vec = base::ArrayVector("unknown"); 145 std::unique_ptr<char[]> name(new char[name_vec.length() + 1]); 146 memcpy(name.get(), name_vec.begin(), name_vec.length()); 147 name[name_vec.length()] = '\0'; 148 return name; 149} 150 151StackFrame::Type OptimizedCompilationInfo::GetOutputStackFrameType() const { 152 switch (code_kind()) { 153 case CodeKind::FOR_TESTING: 154 case CodeKind::BYTECODE_HANDLER: 155 case CodeKind::BUILTIN: 156 return StackFrame::STUB; 157#if V8_ENABLE_WEBASSEMBLY 158 case CodeKind::WASM_FUNCTION: 159 return StackFrame::WASM; 160 case CodeKind::WASM_TO_CAPI_FUNCTION: 161 return StackFrame::WASM_EXIT; 162 case CodeKind::JS_TO_WASM_FUNCTION: 163 return StackFrame::JS_TO_WASM; 164 case CodeKind::WASM_TO_JS_FUNCTION: 165 return StackFrame::WASM_TO_JS; 166 case CodeKind::C_WASM_ENTRY: 167 return StackFrame::C_WASM_ENTRY; 168#endif // V8_ENABLE_WEBASSEMBLY 169 default: 170 UNIMPLEMENTED(); 171 } 172} 173 174void OptimizedCompilationInfo::SetCode(Handle<Code> code) { 175 DCHECK_EQ(code->kind(), code_kind()); 176 code_ = code; 177} 178 179#if V8_ENABLE_WEBASSEMBLY 180void OptimizedCompilationInfo::SetWasmCompilationResult( 181 std::unique_ptr<wasm::WasmCompilationResult> wasm_compilation_result) { 182 wasm_compilation_result_ = std::move(wasm_compilation_result); 183} 184 185std::unique_ptr<wasm::WasmCompilationResult> 186OptimizedCompilationInfo::ReleaseWasmCompilationResult() { 187 return std::move(wasm_compilation_result_); 188} 189#endif // V8_ENABLE_WEBASSEMBLY 190 191bool OptimizedCompilationInfo::has_context() const { 192 return !closure().is_null(); 193} 194 195Context OptimizedCompilationInfo::context() const { 196 DCHECK(has_context()); 197 return closure()->context(); 198} 199 200bool OptimizedCompilationInfo::has_native_context() const { 201 return !closure().is_null() && !closure()->native_context().is_null(); 202} 203 204NativeContext OptimizedCompilationInfo::native_context() const { 205 DCHECK(has_native_context()); 206 return closure()->native_context(); 207} 208 209bool OptimizedCompilationInfo::has_global_object() const { 210 return has_native_context(); 211} 212 213JSGlobalObject OptimizedCompilationInfo::global_object() const { 214 DCHECK(has_global_object()); 215 return native_context().global_object(); 216} 217 218int OptimizedCompilationInfo::AddInlinedFunction( 219 Handle<SharedFunctionInfo> inlined_function, 220 Handle<BytecodeArray> inlined_bytecode, SourcePosition pos) { 221 int id = static_cast<int>(inlined_functions_.size()); 222 inlined_functions_.push_back( 223 InlinedFunctionHolder(inlined_function, inlined_bytecode, pos)); 224 return id; 225} 226 227void OptimizedCompilationInfo::SetTracingFlags(bool passes_filter) { 228 if (!passes_filter) return; 229 if (FLAG_trace_turbo) set_trace_turbo_json(); 230 if (FLAG_trace_turbo_graph) set_trace_turbo_graph(); 231 if (FLAG_trace_turbo_scheduled) set_trace_turbo_scheduled(); 232 if (FLAG_trace_turbo_alloc) set_trace_turbo_allocation(); 233 if (FLAG_trace_heap_broker) set_trace_heap_broker(); 234} 235 236OptimizedCompilationInfo::InlinedFunctionHolder::InlinedFunctionHolder( 237 Handle<SharedFunctionInfo> inlined_shared_info, 238 Handle<BytecodeArray> inlined_bytecode, SourcePosition pos) 239 : shared_info(inlined_shared_info), bytecode_array(inlined_bytecode) { 240 position.position = pos; 241 // initialized when generating the deoptimization literals 242 position.inlined_function_id = DeoptimizationData::kNotInlinedIndex; 243} 244 245} // namespace internal 246} // namespace v8 247