Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1511)

Side by Side Diff: src/compiler.cc

Issue 2284313003: Separate CompilationInfo into its own file. (Closed)
Patch Set: fix Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler.h ('k') | src/compiler-dispatcher/compiler-dispatcher-job.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler.h" 5 #include "src/compiler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <memory> 8 #include <memory>
9 9
10 #include "src/asmjs/asm-js.h" 10 #include "src/asmjs/asm-js.h"
(...skipping 22 matching lines...) Expand all
33 #include "src/parsing/rewriter.h" 33 #include "src/parsing/rewriter.h"
34 #include "src/parsing/scanner-character-streams.h" 34 #include "src/parsing/scanner-character-streams.h"
35 #include "src/runtime-profiler.h" 35 #include "src/runtime-profiler.h"
36 #include "src/snapshot/code-serializer.h" 36 #include "src/snapshot/code-serializer.h"
37 #include "src/vm-state-inl.h" 37 #include "src/vm-state-inl.h"
38 38
39 namespace v8 { 39 namespace v8 {
40 namespace internal { 40 namespace internal {
41 41
42 42
43 #define PARSE_INFO_GETTER(type, name) \
44 type CompilationInfo::name() const { \
45 CHECK(parse_info()); \
46 return parse_info()->name(); \
47 }
48
49
50 #define PARSE_INFO_GETTER_WITH_DEFAULT(type, name, def) \
51 type CompilationInfo::name() const { \
52 return parse_info() ? parse_info()->name() : def; \
53 }
54
55
56 PARSE_INFO_GETTER(Handle<Script>, script)
57 PARSE_INFO_GETTER(FunctionLiteral*, literal)
58 PARSE_INFO_GETTER_WITH_DEFAULT(DeclarationScope*, scope, nullptr)
59 PARSE_INFO_GETTER_WITH_DEFAULT(Handle<Context>, context,
60 Handle<Context>::null())
61 PARSE_INFO_GETTER(Handle<SharedFunctionInfo>, shared_info)
62
63 #undef PARSE_INFO_GETTER
64 #undef PARSE_INFO_GETTER_WITH_DEFAULT
65 43
66 // A wrapper around a CompilationInfo that detaches the Handles from 44 // A wrapper around a CompilationInfo that detaches the Handles from
67 // the underlying DeferredHandleScope and stores them in info_ on 45 // the underlying DeferredHandleScope and stores them in info_ on
68 // destruction. 46 // destruction.
69 class CompilationHandleScope final { 47 class CompilationHandleScope final {
70 public: 48 public:
71 explicit CompilationHandleScope(CompilationInfo* info) 49 explicit CompilationHandleScope(CompilationInfo* info)
72 : deferred_(info->isolate()), info_(info) {} 50 : deferred_(info->isolate()), info_(info) {}
73 ~CompilationHandleScope() { info_->set_deferred_handles(deferred_.Detach()); } 51 ~CompilationHandleScope() { info_->set_deferred_handles(deferred_.Detach()); }
74 52
75 private: 53 private:
76 DeferredHandleScope deferred_; 54 DeferredHandleScope deferred_;
77 CompilationInfo* info_; 55 CompilationInfo* info_;
78 }; 56 };
79 57
80 // Helper that times a scoped region and records the elapsed time. 58 // Helper that times a scoped region and records the elapsed time.
81 struct ScopedTimer { 59 struct ScopedTimer {
82 explicit ScopedTimer(base::TimeDelta* location) : location_(location) { 60 explicit ScopedTimer(base::TimeDelta* location) : location_(location) {
83 DCHECK(location_ != NULL); 61 DCHECK(location_ != NULL);
84 timer_.Start(); 62 timer_.Start();
85 } 63 }
86 64
87 ~ScopedTimer() { *location_ += timer_.Elapsed(); } 65 ~ScopedTimer() { *location_ += timer_.Elapsed(); }
88 66
89 base::ElapsedTimer timer_; 67 base::ElapsedTimer timer_;
90 base::TimeDelta* location_; 68 base::TimeDelta* location_;
91 }; 69 };
92 70
93 // ---------------------------------------------------------------------------- 71 // ----------------------------------------------------------------------------
94 // Implementation of CompilationInfo
95
96 bool CompilationInfo::has_shared_info() const {
97 return parse_info_ && !parse_info_->shared_info().is_null();
98 }
99
100 CompilationInfo::CompilationInfo(ParseInfo* parse_info,
101 Handle<JSFunction> closure)
102 : CompilationInfo(parse_info, {}, Code::ComputeFlags(Code::FUNCTION), BASE,
103 parse_info->isolate(), parse_info->zone()) {
104 closure_ = closure;
105
106 // Compiling for the snapshot typically results in different code than
107 // compiling later on. This means that code recompiled with deoptimization
108 // support won't be "equivalent" (as defined by SharedFunctionInfo::
109 // EnableDeoptimizationSupport), so it will replace the old code and all
110 // its type feedback. To avoid this, always compile functions in the snapshot
111 // with deoptimization support.
112 if (isolate_->serializer_enabled()) EnableDeoptimizationSupport();
113
114 if (FLAG_function_context_specialization) MarkAsFunctionContextSpecializing();
115 if (FLAG_turbo_inlining) MarkAsInliningEnabled();
116 if (FLAG_turbo_source_positions) MarkAsSourcePositionsEnabled();
117 if (FLAG_turbo_splitting) MarkAsSplittingEnabled();
118 }
119
120 CompilationInfo::CompilationInfo(Vector<const char> debug_name,
121 Isolate* isolate, Zone* zone,
122 Code::Flags code_flags)
123 : CompilationInfo(nullptr, debug_name, code_flags, STUB, isolate, zone) {}
124
125 CompilationInfo::CompilationInfo(ParseInfo* parse_info,
126 Vector<const char> debug_name,
127 Code::Flags code_flags, Mode mode,
128 Isolate* isolate, Zone* zone)
129 : parse_info_(parse_info),
130 isolate_(isolate),
131 flags_(0),
132 code_flags_(code_flags),
133 mode_(mode),
134 osr_ast_id_(BailoutId::None()),
135 zone_(zone),
136 deferred_handles_(nullptr),
137 dependencies_(isolate, zone),
138 bailout_reason_(kNoReason),
139 prologue_offset_(Code::kPrologueOffsetNotSet),
140 track_positions_(FLAG_hydrogen_track_positions ||
141 isolate->is_profiling()),
142 parameter_count_(0),
143 optimization_id_(-1),
144 osr_expr_stack_height_(0),
145 debug_name_(debug_name) {}
146
147 CompilationInfo::~CompilationInfo() {
148 if (GetFlag(kDisableFutureOptimization) && has_shared_info()) {
149 shared_info()->DisableOptimization(bailout_reason());
150 }
151 dependencies()->Rollback();
152 delete deferred_handles_;
153 }
154
155
156 int CompilationInfo::num_parameters() const {
157 return !IsStub() ? scope()->num_parameters() : parameter_count_;
158 }
159
160
161 int CompilationInfo::num_parameters_including_this() const {
162 return num_parameters() + (is_this_defined() ? 1 : 0);
163 }
164
165
166 bool CompilationInfo::is_this_defined() const { return !IsStub(); }
167
168
169 // Primitive functions are unlikely to be picked up by the stack-walking
170 // profiler, so they trigger their own optimization when they're called
171 // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time.
172 bool CompilationInfo::ShouldSelfOptimize() {
173 return FLAG_crankshaft &&
174 !(literal()->flags() & AstProperties::kDontSelfOptimize) &&
175 !literal()->dont_optimize() &&
176 literal()->scope()->AllowsLazyCompilation() &&
177 !shared_info()->optimization_disabled();
178 }
179
180 void CompilationInfo::ReopenHandlesInNewHandleScope() {
181 closure_ = Handle<JSFunction>(*closure_);
182 }
183
184 bool CompilationInfo::has_simple_parameters() {
185 return scope()->has_simple_parameters();
186 }
187
188 std::unique_ptr<char[]> CompilationInfo::GetDebugName() const {
189 if (parse_info() && parse_info()->literal()) {
190 AllowHandleDereference allow_deref;
191 return parse_info()->literal()->debug_name()->ToCString();
192 }
193 if (parse_info() && !parse_info()->shared_info().is_null()) {
194 return parse_info()->shared_info()->DebugName()->ToCString();
195 }
196 Vector<const char> name_vec = debug_name_;
197 if (name_vec.is_empty()) name_vec = ArrayVector("unknown");
198 std::unique_ptr<char[]> name(new char[name_vec.length() + 1]);
199 memcpy(name.get(), name_vec.start(), name_vec.length());
200 name[name_vec.length()] = '\0';
201 return name;
202 }
203
204 StackFrame::Type CompilationInfo::GetOutputStackFrameType() const {
205 switch (output_code_kind()) {
206 case Code::STUB:
207 case Code::BYTECODE_HANDLER:
208 case Code::HANDLER:
209 case Code::BUILTIN:
210 #define CASE_KIND(kind) case Code::kind:
211 IC_KIND_LIST(CASE_KIND)
212 #undef CASE_KIND
213 return StackFrame::STUB;
214 case Code::WASM_FUNCTION:
215 return StackFrame::WASM;
216 case Code::JS_TO_WASM_FUNCTION:
217 return StackFrame::JS_TO_WASM;
218 case Code::WASM_TO_JS_FUNCTION:
219 return StackFrame::WASM_TO_JS;
220 default:
221 UNIMPLEMENTED();
222 return StackFrame::NONE;
223 }
224 }
225
226 int CompilationInfo::GetDeclareGlobalsFlags() const {
227 DCHECK(DeclareGlobalsLanguageMode::is_valid(parse_info()->language_mode()));
228 return DeclareGlobalsEvalFlag::encode(parse_info()->is_eval()) |
229 DeclareGlobalsNativeFlag::encode(parse_info()->is_native()) |
230 DeclareGlobalsLanguageMode::encode(parse_info()->language_mode());
231 }
232
233 SourcePositionTableBuilder::RecordingMode
234 CompilationInfo::SourcePositionRecordingMode() const {
235 return parse_info() && parse_info()->is_native()
236 ? SourcePositionTableBuilder::OMIT_SOURCE_POSITIONS
237 : SourcePositionTableBuilder::RECORD_SOURCE_POSITIONS;
238 }
239
240 bool CompilationInfo::ExpectsJSReceiverAsReceiver() {
241 return is_sloppy(parse_info()->language_mode()) && !parse_info()->is_native();
242 }
243
244 bool CompilationInfo::has_native_context() const {
245 return !closure().is_null() && (closure()->native_context() != nullptr);
246 }
247
248 Context* CompilationInfo::native_context() const {
249 return has_native_context() ? closure()->native_context() : nullptr;
250 }
251
252 bool CompilationInfo::has_global_object() const { return has_native_context(); }
253
254 JSGlobalObject* CompilationInfo::global_object() const {
255 return has_global_object() ? native_context()->global_object() : nullptr;
256 }
257
258 void CompilationInfo::AddInlinedFunction(
259 Handle<SharedFunctionInfo> inlined_function) {
260 inlined_functions_.push_back(InlinedFunctionHolder(
261 inlined_function, handle(inlined_function->code())));
262 }
263
264 Code::Kind CompilationInfo::output_code_kind() const {
265 return Code::ExtractKindFromFlags(code_flags_);
266 }
267
268 // ----------------------------------------------------------------------------
269 // Implementation of CompilationJob 72 // Implementation of CompilationJob
270 73
271 CompilationJob::Status CompilationJob::PrepareJob() { 74 CompilationJob::Status CompilationJob::PrepareJob() {
272 DCHECK(ThreadId::Current().Equals(info()->isolate()->thread_id())); 75 DCHECK(ThreadId::Current().Equals(info()->isolate()->thread_id()));
273 DisallowJavascriptExecution no_js(isolate()); 76 DisallowJavascriptExecution no_js(isolate());
274 77
275 if (FLAG_trace_opt && info()->IsOptimizing()) { 78 if (FLAG_trace_opt && info()->IsOptimizing()) {
276 OFStream os(stdout); 79 OFStream os(stdout);
277 os << "[compiling method " << Brief(*info()->closure()) << " using " 80 os << "[compiling method " << Brief(*info()->closure()) << " using "
278 << compiler_name_; 81 << compiler_name_;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 DisallowCodeDependencyChange no_dependency_change; 114 DisallowCodeDependencyChange no_dependency_change;
312 DisallowJavascriptExecution no_js(isolate()); 115 DisallowJavascriptExecution no_js(isolate());
313 DCHECK(!info()->dependencies()->HasAborted()); 116 DCHECK(!info()->dependencies()->HasAborted());
314 117
315 // Delegate to the underlying implementation. 118 // Delegate to the underlying implementation.
316 DCHECK(state() == State::kReadyToFinalize); 119 DCHECK(state() == State::kReadyToFinalize);
317 ScopedTimer t(&time_taken_to_finalize_); 120 ScopedTimer t(&time_taken_to_finalize_);
318 return UpdateState(FinalizeJobImpl(), State::kSucceeded); 121 return UpdateState(FinalizeJobImpl(), State::kSucceeded);
319 } 122 }
320 123
124 CompilationJob::Status CompilationJob::RetryOptimization(BailoutReason reason) {
125 DCHECK(info_->IsOptimizing());
126 info_->RetryOptimization(reason);
127 state_ = State::kFailed;
128 return FAILED;
129 }
130
131 CompilationJob::Status CompilationJob::AbortOptimization(BailoutReason reason) {
132 DCHECK(info_->IsOptimizing());
133 info_->AbortOptimization(reason);
134 state_ = State::kFailed;
135 return FAILED;
136 }
137
321 void CompilationJob::RecordUnoptimizedCompilationStats() const { 138 void CompilationJob::RecordUnoptimizedCompilationStats() const {
322 int code_size; 139 int code_size;
323 if (info()->has_bytecode_array()) { 140 if (info()->has_bytecode_array()) {
324 code_size = info()->bytecode_array()->SizeIncludingMetadata(); 141 code_size = info()->bytecode_array()->SizeIncludingMetadata();
325 } else { 142 } else {
326 code_size = info()->code()->SizeIncludingMetadata(); 143 code_size = info()->code()->SizeIncludingMetadata();
327 } 144 }
328 145
329 Counters* counters = isolate()->counters(); 146 Counters* counters = isolate()->counters();
330 // TODO(4280): Rename counters from "baseline" to "unoptimized" eventually. 147 // TODO(4280): Rename counters from "baseline" to "unoptimized" eventually.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 PrintF("Compiled: %d functions with %d byte source size in %fms.\n", 179 PrintF("Compiled: %d functions with %d byte source size in %fms.\n",
363 compiled_functions, code_size, compilation_time); 180 compiled_functions, code_size, compilation_time);
364 } 181 }
365 if (FLAG_hydrogen_stats) { 182 if (FLAG_hydrogen_stats) {
366 isolate()->GetHStatistics()->IncrementSubtotals(time_taken_to_prepare_, 183 isolate()->GetHStatistics()->IncrementSubtotals(time_taken_to_prepare_,
367 time_taken_to_execute_, 184 time_taken_to_execute_,
368 time_taken_to_finalize_); 185 time_taken_to_finalize_);
369 } 186 }
370 } 187 }
371 188
189 Isolate* CompilationJob::isolate() const { return info()->isolate(); }
190
372 namespace { 191 namespace {
373 192
374 void AddWeakObjectToCodeDependency(Isolate* isolate, Handle<HeapObject> object, 193 void AddWeakObjectToCodeDependency(Isolate* isolate, Handle<HeapObject> object,
375 Handle<Code> code) { 194 Handle<Code> code) {
376 Handle<WeakCell> cell = Code::WeakCellFor(code); 195 Handle<WeakCell> cell = Code::WeakCellFor(code);
377 Heap* heap = isolate->heap(); 196 Heap* heap = isolate->heap();
378 if (heap->InNewSpace(*object)) { 197 if (heap->InNewSpace(*object)) {
379 heap->AddWeakNewSpaceObjectToCodeDependency(object, cell); 198 heap->AddWeakNewSpaceObjectToCodeDependency(object, cell);
380 } else { 199 } else {
381 Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(object)); 200 Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(object));
(...skipping 1693 matching lines...) Expand 10 before | Expand all | Expand 10 after
2075 DCHECK(shared->is_compiled()); 1894 DCHECK(shared->is_compiled());
2076 function->set_literals(cached.literals); 1895 function->set_literals(cached.literals);
2077 } else if (shared->is_compiled()) { 1896 } else if (shared->is_compiled()) {
2078 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. 1897 // TODO(mvstanton): pass pretenure flag to EnsureLiterals.
2079 JSFunction::EnsureLiterals(function); 1898 JSFunction::EnsureLiterals(function);
2080 } 1899 }
2081 } 1900 }
2082 1901
2083 } // namespace internal 1902 } // namespace internal
2084 } // namespace v8 1903 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler.h ('k') | src/compiler-dispatcher/compiler-dispatcher-job.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698