Line data Source code
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 : #include "src/tracing/trace-event.h"
14 : #include "src/tracing/traced-value.h"
15 : #include "src/wasm/function-compiler.h"
16 :
17 : namespace v8 {
18 : namespace internal {
19 :
20 483030 : OptimizedCompilationInfo::OptimizedCompilationInfo(
21 : Zone* zone, Isolate* isolate, Handle<SharedFunctionInfo> shared,
22 : Handle<JSFunction> closure)
23 483030 : : OptimizedCompilationInfo(Code::OPTIMIZED_FUNCTION, zone) {
24 : DCHECK(shared->is_compiled());
25 966065 : bytecode_array_ = handle(shared->GetBytecodeArray(), isolate);
26 483033 : shared_info_ = shared;
27 483033 : closure_ = closure;
28 483033 : optimization_id_ = isolate->NextOptimizationId();
29 :
30 : // Collect source positions for optimized code when profiling or if debugger
31 : // is active, to be able to get more precise source positions at the price of
32 : // more memory consumption.
33 483033 : if (isolate->NeedsDetailedOptimizedCodeLineInfo()) {
34 : MarkAsSourcePositionsEnabled();
35 : }
36 :
37 1449100 : SetTracingFlags(shared->PassesFilter(FLAG_trace_turbo_filter));
38 483034 : }
39 :
40 2120534 : OptimizedCompilationInfo::OptimizedCompilationInfo(
41 : Vector<const char> debug_name, Zone* zone, Code::Kind code_kind)
42 2120534 : : OptimizedCompilationInfo(code_kind, zone) {
43 2120573 : debug_name_ = debug_name;
44 :
45 : SetTracingFlags(
46 4241146 : PassesFilter(debug_name, CStrVector(FLAG_trace_turbo_filter)));
47 2120518 : }
48 :
49 2603582 : OptimizedCompilationInfo::OptimizedCompilationInfo(Code::Kind code_kind,
50 : Zone* zone)
51 10414328 : : code_kind_(code_kind), zone_(zone) {
52 2603582 : ConfigureFlags();
53 2603600 : }
54 :
55 2603417 : void OptimizedCompilationInfo::ConfigureFlags() {
56 2603417 : if (FLAG_untrusted_code_mitigations) SetFlag(kUntrustedCodeMitigations);
57 :
58 2603417 : switch (code_kind_) {
59 : case Code::OPTIMIZED_FUNCTION:
60 : SetFlag(kCalledWithCodeStartRegister);
61 : SetFlag(kSwitchJumpTableEnabled);
62 483031 : if (FLAG_function_context_specialization) {
63 : MarkAsFunctionContextSpecializing();
64 : }
65 483031 : if (FLAG_turbo_splitting) {
66 : MarkAsSplittingEnabled();
67 : }
68 483031 : if (FLAG_untrusted_code_mitigations) {
69 : MarkAsPoisoningRegisterArguments();
70 : }
71 483031 : if (FLAG_analyze_environment_liveness) {
72 : // TODO(yangguo): Disable this in case of debugging for crbug.com/826613
73 : MarkAsAnalyzeEnvironmentLiveness();
74 : }
75 : break;
76 : case Code::BYTECODE_HANDLER:
77 : SetFlag(kCalledWithCodeStartRegister);
78 : break;
79 : case Code::BUILTIN:
80 : case Code::STUB:
81 : #if ENABLE_GDB_JIT_INTERFACE && DEBUG
82 : MarkAsSourcePositionsEnabled();
83 : #endif // ENABLE_GDB_JIT_INTERFACE && DEBUG
84 : break;
85 : case Code::WASM_FUNCTION:
86 : SetFlag(kSwitchJumpTableEnabled);
87 : break;
88 : default:
89 : break;
90 : }
91 :
92 2603417 : if (FLAG_turbo_control_flow_aware_allocation) {
93 : MarkAsTurboControlFlowAwareAllocation();
94 : }
95 2603417 : if (FLAG_turbo_preprocess_ranges) {
96 : MarkAsTurboPreprocessRanges();
97 : }
98 2603417 : }
99 :
100 5203269 : OptimizedCompilationInfo::~OptimizedCompilationInfo() {
101 2601669 : if (GetFlag(kDisableFutureOptimization) && has_shared_info()) {
102 19077 : shared_info()->DisableOptimization(bailout_reason());
103 : }
104 2601529 : }
105 :
106 0 : void OptimizedCompilationInfo::set_deferred_handles(
107 : std::shared_ptr<DeferredHandles> deferred_handles) {
108 : DCHECK_NULL(deferred_handles_);
109 : deferred_handles_.swap(deferred_handles);
110 0 : }
111 :
112 6849 : void OptimizedCompilationInfo::set_deferred_handles(
113 : DeferredHandles* deferred_handles) {
114 : DCHECK_NULL(deferred_handles_);
115 6849 : deferred_handles_.reset(deferred_handles);
116 6849 : }
117 :
118 462403 : void OptimizedCompilationInfo::ReopenHandlesInNewHandleScope(Isolate* isolate) {
119 462403 : if (!shared_info_.is_null()) {
120 462403 : shared_info_ = Handle<SharedFunctionInfo>(*shared_info_, isolate);
121 : }
122 462402 : if (!bytecode_array_.is_null()) {
123 462405 : bytecode_array_ = Handle<BytecodeArray>(*bytecode_array_, isolate);
124 : }
125 462402 : if (!closure_.is_null()) {
126 462406 : closure_ = Handle<JSFunction>(*closure_, isolate);
127 : }
128 462403 : }
129 :
130 19077 : void OptimizedCompilationInfo::AbortOptimization(BailoutReason reason) {
131 : DCHECK_NE(reason, BailoutReason::kNoReason);
132 19077 : if (bailout_reason_ == BailoutReason::kNoReason) {
133 38154 : TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
134 : "V8.AbortOptimization", TRACE_EVENT_SCOPE_THREAD,
135 : "reason", GetBailoutReason(reason), "function",
136 : shared_info()->TraceIDRef());
137 19077 : bailout_reason_ = reason;
138 : }
139 : SetFlag(kDisableFutureOptimization);
140 19077 : }
141 :
142 69 : void OptimizedCompilationInfo::RetryOptimization(BailoutReason reason) {
143 : DCHECK_NE(reason, BailoutReason::kNoReason);
144 69 : if (GetFlag(kDisableFutureOptimization)) return;
145 138 : TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
146 : "V8.RetryOptimization", TRACE_EVENT_SCOPE_THREAD,
147 : "reason", GetBailoutReason(reason), "function",
148 : shared_info()->TraceIDRef());
149 69 : bailout_reason_ = reason;
150 : }
151 :
152 2660019 : std::unique_ptr<char[]> OptimizedCompilationInfo::GetDebugName() const {
153 2660019 : if (!shared_info().is_null()) {
154 483010 : return shared_info()->DebugName()->ToCString();
155 : }
156 2177009 : Vector<const char> name_vec = debug_name_;
157 2177009 : if (name_vec.empty()) name_vec = ArrayVector("unknown");
158 2177009 : std::unique_ptr<char[]> name(new char[name_vec.length() + 1]);
159 2177931 : memcpy(name.get(), name_vec.start(), name_vec.length());
160 2177931 : name[name_vec.length()] = '\0';
161 : return name;
162 : }
163 :
164 1102747 : StackFrame::Type OptimizedCompilationInfo::GetOutputStackFrameType() const {
165 1102747 : switch (code_kind()) {
166 : case Code::STUB:
167 : case Code::BYTECODE_HANDLER:
168 : case Code::BUILTIN:
169 : return StackFrame::STUB;
170 : case Code::WASM_FUNCTION:
171 608446 : return StackFrame::WASM_COMPILED;
172 : case Code::JS_TO_WASM_FUNCTION:
173 0 : return StackFrame::JS_TO_WASM;
174 : case Code::WASM_TO_JS_FUNCTION:
175 6858 : return StackFrame::WASM_TO_JS;
176 : case Code::WASM_INTERPRETER_ENTRY:
177 369215 : return StackFrame::WASM_INTERPRETER_ENTRY;
178 : default:
179 0 : UNIMPLEMENTED();
180 : return StackFrame::NONE;
181 : }
182 : }
183 :
184 607256 : void OptimizedCompilationInfo::SetWasmCompilationResult(
185 : std::unique_ptr<wasm::WasmCompilationResult> wasm_compilation_result) {
186 607256 : wasm_compilation_result_ = std::move(wasm_compilation_result);
187 606977 : }
188 :
189 : std::unique_ptr<wasm::WasmCompilationResult>
190 609065 : OptimizedCompilationInfo::ReleaseWasmCompilationResult() {
191 609065 : return std::move(wasm_compilation_result_);
192 : }
193 :
194 0 : bool OptimizedCompilationInfo::has_context() const {
195 0 : return !closure().is_null();
196 : }
197 :
198 437423 : Context OptimizedCompilationInfo::context() const {
199 : DCHECK(has_context());
200 437423 : return closure()->context();
201 : }
202 :
203 0 : bool OptimizedCompilationInfo::has_native_context() const {
204 0 : return !closure().is_null() && !closure()->native_context().is_null();
205 : }
206 :
207 1576001 : Context OptimizedCompilationInfo::native_context() const {
208 : DCHECK(has_native_context());
209 1576002 : return closure()->native_context();
210 : }
211 :
212 0 : bool OptimizedCompilationInfo::has_global_object() const {
213 0 : return has_native_context();
214 : }
215 :
216 0 : JSGlobalObject OptimizedCompilationInfo::global_object() const {
217 : DCHECK(has_global_object());
218 0 : return native_context()->global_object();
219 : }
220 :
221 65818 : int OptimizedCompilationInfo::AddInlinedFunction(
222 : Handle<SharedFunctionInfo> inlined_function,
223 : Handle<BytecodeArray> inlined_bytecode, SourcePosition pos) {
224 65818 : int id = static_cast<int>(inlined_functions_.size());
225 131636 : inlined_functions_.push_back(
226 : InlinedFunctionHolder(inlined_function, inlined_bytecode, pos));
227 65818 : return id;
228 : }
229 :
230 0 : void OptimizedCompilationInfo::SetTracingFlags(bool passes_filter) {
231 2603552 : if (!passes_filter) return;
232 2603542 : if (FLAG_trace_turbo) SetFlag(kTraceTurboJson);
233 2603542 : if (FLAG_trace_turbo_graph) SetFlag(kTraceTurboGraph);
234 2603542 : if (FLAG_trace_turbo_scheduled) SetFlag(kTraceTurboScheduled);
235 : }
236 :
237 0 : OptimizedCompilationInfo::InlinedFunctionHolder::InlinedFunctionHolder(
238 : Handle<SharedFunctionInfo> inlined_shared_info,
239 : Handle<BytecodeArray> inlined_bytecode, SourcePosition pos)
240 65818 : : shared_info(inlined_shared_info), bytecode_array(inlined_bytecode) {
241 : DCHECK_EQ(shared_info->GetBytecodeArray(), *bytecode_array);
242 65818 : position.position = pos;
243 : // initialized when generating the deoptimization literals
244 65818 : position.inlined_function_id = DeoptimizationData::kNotInlinedIndex;
245 0 : }
246 :
247 : std::unique_ptr<v8::tracing::TracedValue>
248 0 : OptimizedCompilationInfo::ToTracedValue() {
249 0 : auto value = v8::tracing::TracedValue::Create();
250 0 : value->SetBoolean("osr", is_osr());
251 0 : value->SetBoolean("functionContextSpecialized",
252 0 : is_function_context_specializing());
253 0 : if (has_shared_info()) {
254 0 : value->SetValue("function", shared_info()->TraceIDRef());
255 : }
256 0 : if (bailout_reason() != BailoutReason::kNoReason) {
257 0 : value->SetString("bailoutReason", GetBailoutReason(bailout_reason()));
258 0 : value->SetBoolean("disableFutureOptimization",
259 0 : is_disable_future_optimization());
260 : } else {
261 0 : value->SetInteger("optimizationId", optimization_id());
262 0 : value->BeginArray("inlinedFunctions");
263 0 : for (auto const& inlined_function : inlined_functions()) {
264 0 : value->BeginDictionary();
265 0 : value->SetValue("function", inlined_function.shared_info->TraceIDRef());
266 : // TODO(bmeurer): Also include the source position from the
267 : // {inlined_function} here as dedicated "sourcePosition" field.
268 0 : value->EndDictionary();
269 : }
270 0 : value->EndArray();
271 : }
272 0 : return value;
273 : }
274 :
275 : } // namespace internal
276 122036 : } // namespace v8
|