OLD | NEW |
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 | 8 |
9 #include "src/ast-numbering.h" | 9 #include "src/ast-numbering.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 class CompilationInfoWithZone : public CompilationInfo { | 80 class CompilationInfoWithZone : public CompilationInfo { |
81 public: | 81 public: |
82 explicit CompilationInfoWithZone(Handle<JSFunction> function) | 82 explicit CompilationInfoWithZone(Handle<JSFunction> function) |
83 : CompilationInfo(new ParseInfo(&zone_, function)) {} | 83 : CompilationInfo(new ParseInfo(&zone_, function)) {} |
84 | 84 |
85 // Virtual destructor because a CompilationInfoWithZone has to exit the | 85 // Virtual destructor because a CompilationInfoWithZone has to exit the |
86 // zone scope and get rid of dependent maps even when the destructor is | 86 // zone scope and get rid of dependent maps even when the destructor is |
87 // called when cast as a CompilationInfo. | 87 // called when cast as a CompilationInfo. |
88 virtual ~CompilationInfoWithZone() { | 88 virtual ~CompilationInfoWithZone() { |
89 DisableFutureOptimization(); | 89 DisableFutureOptimization(); |
90 RollbackDependencies(); | 90 dependencies()->Rollback(); |
91 delete parse_info_; | 91 delete parse_info_; |
92 parse_info_ = nullptr; | 92 parse_info_ = nullptr; |
93 } | 93 } |
94 | 94 |
95 private: | 95 private: |
96 Zone zone_; | 96 Zone zone_; |
97 }; | 97 }; |
98 | 98 |
99 | 99 |
100 bool CompilationInfo::has_shared_info() const { | 100 bool CompilationInfo::has_shared_info() const { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 CompilationInfo::CompilationInfo(ParseInfo* parse_info, CodeStub* code_stub, | 136 CompilationInfo::CompilationInfo(ParseInfo* parse_info, CodeStub* code_stub, |
137 Mode mode, Isolate* isolate, Zone* zone) | 137 Mode mode, Isolate* isolate, Zone* zone) |
138 : parse_info_(parse_info), | 138 : parse_info_(parse_info), |
139 isolate_(isolate), | 139 isolate_(isolate), |
140 flags_(0), | 140 flags_(0), |
141 code_stub_(code_stub), | 141 code_stub_(code_stub), |
142 mode_(mode), | 142 mode_(mode), |
143 osr_ast_id_(BailoutId::None()), | 143 osr_ast_id_(BailoutId::None()), |
144 zone_(zone), | 144 zone_(zone), |
145 deferred_handles_(nullptr), | 145 deferred_handles_(nullptr), |
| 146 dependencies_(isolate, zone), |
146 bailout_reason_(kNoReason), | 147 bailout_reason_(kNoReason), |
147 prologue_offset_(Code::kPrologueOffsetNotSet), | 148 prologue_offset_(Code::kPrologueOffsetNotSet), |
148 no_frame_ranges_(isolate->cpu_profiler()->is_profiling() | 149 no_frame_ranges_(isolate->cpu_profiler()->is_profiling() |
149 ? new List<OffsetRange>(2) | 150 ? new List<OffsetRange>(2) |
150 : nullptr), | 151 : nullptr), |
151 track_positions_(FLAG_hydrogen_track_positions || | 152 track_positions_(FLAG_hydrogen_track_positions || |
152 isolate->cpu_profiler()->is_profiling()), | 153 isolate->cpu_profiler()->is_profiling()), |
153 opt_count_(has_shared_info() ? shared_info()->opt_count() : 0), | 154 opt_count_(has_shared_info() ? shared_info()->opt_count() : 0), |
154 parameter_count_(0), | 155 parameter_count_(0), |
155 optimization_id_(-1), | 156 optimization_id_(-1), |
156 aborted_due_to_dependency_change_(false), | 157 osr_expr_stack_height_(0) {} |
157 osr_expr_stack_height_(0) { | |
158 std::fill_n(dependencies_, DependentCode::kGroupCount, nullptr); | |
159 } | |
160 | 158 |
161 | 159 |
162 CompilationInfo::~CompilationInfo() { | 160 CompilationInfo::~CompilationInfo() { |
163 DisableFutureOptimization(); | 161 DisableFutureOptimization(); |
164 delete deferred_handles_; | 162 delete deferred_handles_; |
165 delete no_frame_ranges_; | 163 delete no_frame_ranges_; |
166 #ifdef DEBUG | 164 #ifdef DEBUG |
167 // Check that no dependent maps have been added or added dependent maps have | 165 // Check that no dependent maps have been added or added dependent maps have |
168 // been rolled back or committed. | 166 // been rolled back or committed. |
169 for (int i = 0; i < DependentCode::kGroupCount; i++) { | 167 DCHECK(dependencies()->IsEmpty()); |
170 DCHECK(!dependencies_[i]); | |
171 } | |
172 #endif // DEBUG | 168 #endif // DEBUG |
173 } | 169 } |
174 | 170 |
175 | 171 |
176 void CompilationInfo::CommitDependencies(Handle<Code> code) { | |
177 bool has_dependencies = false; | |
178 for (int i = 0; i < DependentCode::kGroupCount; i++) { | |
179 has_dependencies |= | |
180 dependencies_[i] != NULL && dependencies_[i]->length() > 0; | |
181 } | |
182 // Avoid creating a weak cell for code with no dependencies. | |
183 if (!has_dependencies) return; | |
184 | |
185 AllowDeferredHandleDereference get_object_wrapper; | |
186 WeakCell* cell = *Code::WeakCellFor(code); | |
187 for (int i = 0; i < DependentCode::kGroupCount; i++) { | |
188 ZoneList<Handle<HeapObject> >* group_objects = dependencies_[i]; | |
189 if (group_objects == NULL) continue; | |
190 DCHECK(!object_wrapper_.is_null()); | |
191 for (int j = 0; j < group_objects->length(); j++) { | |
192 DependentCode::DependencyGroup group = | |
193 static_cast<DependentCode::DependencyGroup>(i); | |
194 Foreign* info = *object_wrapper(); | |
195 DependentCode* dependent_code = | |
196 DependentCode::ForObject(group_objects->at(j), group); | |
197 dependent_code->UpdateToFinishedCode(group, info, cell); | |
198 } | |
199 dependencies_[i] = NULL; // Zone-allocated, no need to delete. | |
200 } | |
201 } | |
202 | |
203 | |
204 void CompilationInfo::RollbackDependencies() { | |
205 AllowDeferredHandleDereference get_object_wrapper; | |
206 // Unregister from all dependent maps if not yet committed. | |
207 for (int i = 0; i < DependentCode::kGroupCount; i++) { | |
208 ZoneList<Handle<HeapObject> >* group_objects = dependencies_[i]; | |
209 if (group_objects == NULL) continue; | |
210 for (int j = 0; j < group_objects->length(); j++) { | |
211 DependentCode::DependencyGroup group = | |
212 static_cast<DependentCode::DependencyGroup>(i); | |
213 Foreign* info = *object_wrapper(); | |
214 DependentCode* dependent_code = | |
215 DependentCode::ForObject(group_objects->at(j), group); | |
216 dependent_code->RemoveCompilationInfo(group, info); | |
217 } | |
218 dependencies_[i] = NULL; // Zone-allocated, no need to delete. | |
219 } | |
220 } | |
221 | |
222 | |
223 int CompilationInfo::num_parameters() const { | 172 int CompilationInfo::num_parameters() const { |
224 return has_scope() ? scope()->num_parameters() : parameter_count_; | 173 return has_scope() ? scope()->num_parameters() : parameter_count_; |
225 } | 174 } |
226 | 175 |
227 | 176 |
228 int CompilationInfo::num_heap_slots() const { | 177 int CompilationInfo::num_heap_slots() const { |
229 return has_scope() ? scope()->num_heap_slots() : 0; | 178 return has_scope() ? scope()->num_heap_slots() : 0; |
230 } | 179 } |
231 | 180 |
232 | 181 |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 | 435 |
487 Timer t(this, &time_taken_to_create_graph_); | 436 Timer t(this, &time_taken_to_create_graph_); |
488 graph_ = graph_builder_->CreateGraph(); | 437 graph_ = graph_builder_->CreateGraph(); |
489 | 438 |
490 if (isolate()->has_pending_exception()) { | 439 if (isolate()->has_pending_exception()) { |
491 return SetLastStatus(FAILED); | 440 return SetLastStatus(FAILED); |
492 } | 441 } |
493 | 442 |
494 if (graph_ == NULL) return SetLastStatus(BAILED_OUT); | 443 if (graph_ == NULL) return SetLastStatus(BAILED_OUT); |
495 | 444 |
496 if (info()->HasAbortedDueToDependencyChange()) { | 445 if (info()->dependencies()->HasAborted()) { |
497 // Dependency has changed during graph creation. Let's try again later. | 446 // Dependency has changed during graph creation. Let's try again later. |
498 return RetryOptimization(kBailedOutDueToDependencyChange); | 447 return RetryOptimization(kBailedOutDueToDependencyChange); |
499 } | 448 } |
500 | 449 |
501 return SetLastStatus(SUCCEEDED); | 450 return SetLastStatus(SUCCEEDED); |
502 } | 451 } |
503 | 452 |
504 | 453 |
505 OptimizedCompileJob::Status OptimizedCompileJob::OptimizeGraph() { | 454 OptimizedCompileJob::Status OptimizedCompileJob::OptimizeGraph() { |
506 DisallowHeapAllocation no_allocation; | 455 DisallowHeapAllocation no_allocation; |
(...skipping 27 matching lines...) Expand all Loading... |
534 // TODO(turbofan): Currently everything is done in the first phase. | 483 // TODO(turbofan): Currently everything is done in the first phase. |
535 if (!info()->code().is_null()) { | 484 if (!info()->code().is_null()) { |
536 if (FLAG_turbo_deoptimization) { | 485 if (FLAG_turbo_deoptimization) { |
537 info()->parse_info()->context()->native_context()->AddOptimizedCode( | 486 info()->parse_info()->context()->native_context()->AddOptimizedCode( |
538 *info()->code()); | 487 *info()->code()); |
539 } | 488 } |
540 RecordOptimizationStats(); | 489 RecordOptimizationStats(); |
541 return last_status(); | 490 return last_status(); |
542 } | 491 } |
543 | 492 |
544 DCHECK(!info()->HasAbortedDueToDependencyChange()); | 493 DCHECK(!info()->dependencies()->HasAborted()); |
545 DisallowCodeDependencyChange no_dependency_change; | 494 DisallowCodeDependencyChange no_dependency_change; |
546 DisallowJavascriptExecution no_js(isolate()); | 495 DisallowJavascriptExecution no_js(isolate()); |
547 { // Scope for timer. | 496 { // Scope for timer. |
548 Timer timer(this, &time_taken_to_codegen_); | 497 Timer timer(this, &time_taken_to_codegen_); |
549 DCHECK(chunk_ != NULL); | 498 DCHECK(chunk_ != NULL); |
550 DCHECK(graph_ != NULL); | 499 DCHECK(graph_ != NULL); |
551 // Deferred handles reference objects that were accessible during | 500 // Deferred handles reference objects that were accessible during |
552 // graph creation. To make sure that we don't encounter inconsistencies | 501 // graph creation. To make sure that we don't encounter inconsistencies |
553 // between graph creation and code generation, we disallow accessing | 502 // between graph creation and code generation, we disallow accessing |
554 // objects through deferred handles during the latter, with exceptions. | 503 // objects through deferred handles during the latter, with exceptions. |
(...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1515 | 1464 |
1516 // 1) Optimization on the concurrent thread may have failed. | 1465 // 1) Optimization on the concurrent thread may have failed. |
1517 // 2) The function may have already been optimized by OSR. Simply continue. | 1466 // 2) The function may have already been optimized by OSR. Simply continue. |
1518 // Except when OSR already disabled optimization for some reason. | 1467 // Except when OSR already disabled optimization for some reason. |
1519 // 3) The code may have already been invalidated due to dependency change. | 1468 // 3) The code may have already been invalidated due to dependency change. |
1520 // 4) Debugger may have been activated. | 1469 // 4) Debugger may have been activated. |
1521 // 5) Code generation may have failed. | 1470 // 5) Code generation may have failed. |
1522 if (job->last_status() == OptimizedCompileJob::SUCCEEDED) { | 1471 if (job->last_status() == OptimizedCompileJob::SUCCEEDED) { |
1523 if (shared->optimization_disabled()) { | 1472 if (shared->optimization_disabled()) { |
1524 job->RetryOptimization(kOptimizationDisabled); | 1473 job->RetryOptimization(kOptimizationDisabled); |
1525 } else if (info->HasAbortedDueToDependencyChange()) { | 1474 } else if (info->dependencies()->HasAborted()) { |
1526 job->RetryOptimization(kBailedOutDueToDependencyChange); | 1475 job->RetryOptimization(kBailedOutDueToDependencyChange); |
1527 } else if (isolate->debug()->has_break_points()) { | 1476 } else if (isolate->debug()->has_break_points()) { |
1528 job->RetryOptimization(kDebuggerHasBreakPoints); | 1477 job->RetryOptimization(kDebuggerHasBreakPoints); |
1529 } else if (job->GenerateCode() == OptimizedCompileJob::SUCCEEDED) { | 1478 } else if (job->GenerateCode() == OptimizedCompileJob::SUCCEEDED) { |
1530 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info.get(), shared); | 1479 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info.get(), shared); |
1531 if (info->shared_info()->SearchOptimizedCodeMap( | 1480 if (info->shared_info()->SearchOptimizedCodeMap( |
1532 info->context()->native_context(), info->osr_ast_id()) == -1) { | 1481 info->context()->native_context(), info->osr_ast_id()) == -1) { |
1533 InsertCodeIntoOptimizedCodeMap(info.get()); | 1482 InsertCodeIntoOptimizedCodeMap(info.get()); |
1534 } | 1483 } |
1535 if (FLAG_trace_opt) { | 1484 if (FLAG_trace_opt) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1591 } | 1540 } |
1592 | 1541 |
1593 | 1542 |
1594 #if DEBUG | 1543 #if DEBUG |
1595 void CompilationInfo::PrintAstForTesting() { | 1544 void CompilationInfo::PrintAstForTesting() { |
1596 PrintF("--- Source from AST ---\n%s\n", | 1545 PrintF("--- Source from AST ---\n%s\n", |
1597 PrettyPrinter(isolate(), zone()).PrintProgram(function())); | 1546 PrettyPrinter(isolate(), zone()).PrintProgram(function())); |
1598 } | 1547 } |
1599 #endif | 1548 #endif |
1600 } } // namespace v8::internal | 1549 } } // namespace v8::internal |
OLD | NEW |