• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
OptimizedCompilationInfo(Zone * zone,Isolate * isolate,Handle<SharedFunctionInfo> shared,Handle<JSFunction> closure)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 
OptimizedCompilationInfo(Vector<const char> debug_name,Zone * zone,Code::Kind code_kind)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 
OptimizedCompilationInfo(Vector<const char> debug_name,AbstractCode::Kind code_kind,Zone * zone)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 
~OptimizedCompilationInfo()82 OptimizedCompilationInfo::~OptimizedCompilationInfo() {
83   if (GetFlag(kDisableFutureOptimization) && has_shared_info()) {
84     shared_info()->DisableOptimization(bailout_reason());
85   }
86 }
87 
set_deferred_handles(std::shared_ptr<DeferredHandles> deferred_handles)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 
set_deferred_handles(DeferredHandles * deferred_handles)94 void OptimizedCompilationInfo::set_deferred_handles(
95     DeferredHandles* deferred_handles) {
96   DCHECK_NULL(deferred_handles_);
97   deferred_handles_.reset(deferred_handles);
98 }
99 
ReopenHandlesInNewHandleScope(Isolate * isolate)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 
GetDebugName() const109 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 
GetOutputStackFrameType() const121 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 
has_context() const141 bool OptimizedCompilationInfo::has_context() const {
142   return !closure().is_null();
143 }
144 
context() const145 Context* OptimizedCompilationInfo::context() const {
146   return has_context() ? closure()->context() : nullptr;
147 }
148 
has_native_context() const149 bool OptimizedCompilationInfo::has_native_context() const {
150   return !closure().is_null() && (closure()->native_context() != nullptr);
151 }
152 
native_context() const153 Context* OptimizedCompilationInfo::native_context() const {
154   return has_native_context() ? closure()->native_context() : nullptr;
155 }
156 
has_global_object() const157 bool OptimizedCompilationInfo::has_global_object() const {
158   return has_native_context();
159 }
160 
global_object() const161 JSGlobalObject* OptimizedCompilationInfo::global_object() const {
162   return has_global_object() ? native_context()->global_object() : nullptr;
163 }
164 
AddInlinedFunction(Handle<SharedFunctionInfo> inlined_function,SourcePosition pos)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 
SetTracingFlags(bool passes_filter)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