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 dependencies()->Rollback(); | 90 RollbackDependencies(); |
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), | |
147 bailout_reason_(kNoReason), | 146 bailout_reason_(kNoReason), |
148 prologue_offset_(Code::kPrologueOffsetNotSet), | 147 prologue_offset_(Code::kPrologueOffsetNotSet), |
149 no_frame_ranges_(isolate->cpu_profiler()->is_profiling() | 148 no_frame_ranges_(isolate->cpu_profiler()->is_profiling() |
150 ? new List<OffsetRange>(2) | 149 ? new List<OffsetRange>(2) |
151 : nullptr), | 150 : nullptr), |
152 track_positions_(FLAG_hydrogen_track_positions || | 151 track_positions_(FLAG_hydrogen_track_positions || |
153 isolate->cpu_profiler()->is_profiling()), | 152 isolate->cpu_profiler()->is_profiling()), |
154 opt_count_(has_shared_info() ? shared_info()->opt_count() : 0), | 153 opt_count_(has_shared_info() ? shared_info()->opt_count() : 0), |
155 parameter_count_(0), | 154 parameter_count_(0), |
156 optimization_id_(-1), | 155 optimization_id_(-1), |
157 osr_expr_stack_height_(0) {} | 156 aborted_due_to_dependency_change_(false), |
| 157 osr_expr_stack_height_(0) { |
| 158 std::fill_n(dependencies_, DependentCode::kGroupCount, nullptr); |
| 159 } |
158 | 160 |
159 | 161 |
160 CompilationInfo::~CompilationInfo() { | 162 CompilationInfo::~CompilationInfo() { |
161 DisableFutureOptimization(); | 163 DisableFutureOptimization(); |
162 delete deferred_handles_; | 164 delete deferred_handles_; |
163 delete no_frame_ranges_; | 165 delete no_frame_ranges_; |
164 #ifdef DEBUG | 166 #ifdef DEBUG |
165 // Check that no dependent maps have been added or added dependent maps have | 167 // Check that no dependent maps have been added or added dependent maps have |
166 // been rolled back or committed. | 168 // been rolled back or committed. |
167 DCHECK(dependencies()->IsEmpty()); | 169 for (int i = 0; i < DependentCode::kGroupCount; i++) { |
| 170 DCHECK(!dependencies_[i]); |
| 171 } |
168 #endif // DEBUG | 172 #endif // DEBUG |
169 } | 173 } |
170 | 174 |
171 | 175 |
| 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 |
172 int CompilationInfo::num_parameters() const { | 223 int CompilationInfo::num_parameters() const { |
173 return has_scope() ? scope()->num_parameters() : parameter_count_; | 224 return has_scope() ? scope()->num_parameters() : parameter_count_; |
174 } | 225 } |
175 | 226 |
176 | 227 |
177 int CompilationInfo::num_heap_slots() const { | 228 int CompilationInfo::num_heap_slots() const { |
178 return has_scope() ? scope()->num_heap_slots() : 0; | 229 return has_scope() ? scope()->num_heap_slots() : 0; |
179 } | 230 } |
180 | 231 |
181 | 232 |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 | 486 |
436 Timer t(this, &time_taken_to_create_graph_); | 487 Timer t(this, &time_taken_to_create_graph_); |
437 graph_ = graph_builder_->CreateGraph(); | 488 graph_ = graph_builder_->CreateGraph(); |
438 | 489 |
439 if (isolate()->has_pending_exception()) { | 490 if (isolate()->has_pending_exception()) { |
440 return SetLastStatus(FAILED); | 491 return SetLastStatus(FAILED); |
441 } | 492 } |
442 | 493 |
443 if (graph_ == NULL) return SetLastStatus(BAILED_OUT); | 494 if (graph_ == NULL) return SetLastStatus(BAILED_OUT); |
444 | 495 |
445 if (info()->dependencies()->HasAborted()) { | 496 if (info()->HasAbortedDueToDependencyChange()) { |
446 // Dependency has changed during graph creation. Let's try again later. | 497 // Dependency has changed during graph creation. Let's try again later. |
447 return RetryOptimization(kBailedOutDueToDependencyChange); | 498 return RetryOptimization(kBailedOutDueToDependencyChange); |
448 } | 499 } |
449 | 500 |
450 return SetLastStatus(SUCCEEDED); | 501 return SetLastStatus(SUCCEEDED); |
451 } | 502 } |
452 | 503 |
453 | 504 |
454 OptimizedCompileJob::Status OptimizedCompileJob::OptimizeGraph() { | 505 OptimizedCompileJob::Status OptimizedCompileJob::OptimizeGraph() { |
455 DisallowHeapAllocation no_allocation; | 506 DisallowHeapAllocation no_allocation; |
(...skipping 27 matching lines...) Expand all Loading... |
483 // TODO(turbofan): Currently everything is done in the first phase. | 534 // TODO(turbofan): Currently everything is done in the first phase. |
484 if (!info()->code().is_null()) { | 535 if (!info()->code().is_null()) { |
485 if (FLAG_turbo_deoptimization) { | 536 if (FLAG_turbo_deoptimization) { |
486 info()->parse_info()->context()->native_context()->AddOptimizedCode( | 537 info()->parse_info()->context()->native_context()->AddOptimizedCode( |
487 *info()->code()); | 538 *info()->code()); |
488 } | 539 } |
489 RecordOptimizationStats(); | 540 RecordOptimizationStats(); |
490 return last_status(); | 541 return last_status(); |
491 } | 542 } |
492 | 543 |
493 DCHECK(!info()->dependencies()->HasAborted()); | 544 DCHECK(!info()->HasAbortedDueToDependencyChange()); |
494 DisallowCodeDependencyChange no_dependency_change; | 545 DisallowCodeDependencyChange no_dependency_change; |
495 DisallowJavascriptExecution no_js(isolate()); | 546 DisallowJavascriptExecution no_js(isolate()); |
496 { // Scope for timer. | 547 { // Scope for timer. |
497 Timer timer(this, &time_taken_to_codegen_); | 548 Timer timer(this, &time_taken_to_codegen_); |
498 DCHECK(chunk_ != NULL); | 549 DCHECK(chunk_ != NULL); |
499 DCHECK(graph_ != NULL); | 550 DCHECK(graph_ != NULL); |
500 // Deferred handles reference objects that were accessible during | 551 // Deferred handles reference objects that were accessible during |
501 // graph creation. To make sure that we don't encounter inconsistencies | 552 // graph creation. To make sure that we don't encounter inconsistencies |
502 // between graph creation and code generation, we disallow accessing | 553 // between graph creation and code generation, we disallow accessing |
503 // objects through deferred handles during the latter, with exceptions. | 554 // objects through deferred handles during the latter, with exceptions. |
(...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1464 | 1515 |
1465 // 1) Optimization on the concurrent thread may have failed. | 1516 // 1) Optimization on the concurrent thread may have failed. |
1466 // 2) The function may have already been optimized by OSR. Simply continue. | 1517 // 2) The function may have already been optimized by OSR. Simply continue. |
1467 // Except when OSR already disabled optimization for some reason. | 1518 // Except when OSR already disabled optimization for some reason. |
1468 // 3) The code may have already been invalidated due to dependency change. | 1519 // 3) The code may have already been invalidated due to dependency change. |
1469 // 4) Debugger may have been activated. | 1520 // 4) Debugger may have been activated. |
1470 // 5) Code generation may have failed. | 1521 // 5) Code generation may have failed. |
1471 if (job->last_status() == OptimizedCompileJob::SUCCEEDED) { | 1522 if (job->last_status() == OptimizedCompileJob::SUCCEEDED) { |
1472 if (shared->optimization_disabled()) { | 1523 if (shared->optimization_disabled()) { |
1473 job->RetryOptimization(kOptimizationDisabled); | 1524 job->RetryOptimization(kOptimizationDisabled); |
1474 } else if (info->dependencies()->HasAborted()) { | 1525 } else if (info->HasAbortedDueToDependencyChange()) { |
1475 job->RetryOptimization(kBailedOutDueToDependencyChange); | 1526 job->RetryOptimization(kBailedOutDueToDependencyChange); |
1476 } else if (isolate->debug()->has_break_points()) { | 1527 } else if (isolate->debug()->has_break_points()) { |
1477 job->RetryOptimization(kDebuggerHasBreakPoints); | 1528 job->RetryOptimization(kDebuggerHasBreakPoints); |
1478 } else if (job->GenerateCode() == OptimizedCompileJob::SUCCEEDED) { | 1529 } else if (job->GenerateCode() == OptimizedCompileJob::SUCCEEDED) { |
1479 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info.get(), shared); | 1530 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info.get(), shared); |
1480 if (info->shared_info()->SearchOptimizedCodeMap( | 1531 if (info->shared_info()->SearchOptimizedCodeMap( |
1481 info->context()->native_context(), info->osr_ast_id()) == -1) { | 1532 info->context()->native_context(), info->osr_ast_id()) == -1) { |
1482 InsertCodeIntoOptimizedCodeMap(info.get()); | 1533 InsertCodeIntoOptimizedCodeMap(info.get()); |
1483 } | 1534 } |
1484 if (FLAG_trace_opt) { | 1535 if (FLAG_trace_opt) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1540 } | 1591 } |
1541 | 1592 |
1542 | 1593 |
1543 #if DEBUG | 1594 #if DEBUG |
1544 void CompilationInfo::PrintAstForTesting() { | 1595 void CompilationInfo::PrintAstForTesting() { |
1545 PrintF("--- Source from AST ---\n%s\n", | 1596 PrintF("--- Source from AST ---\n%s\n", |
1546 PrettyPrinter(isolate(), zone()).PrintProgram(function())); | 1597 PrettyPrinter(isolate(), zone()).PrintProgram(function())); |
1547 } | 1598 } |
1548 #endif | 1599 #endif |
1549 } } // namespace v8::internal | 1600 } } // namespace v8::internal |
OLD | NEW |