| 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 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 | 324 |
| 325 #define DEF_VISIT(type) \ | 325 #define DEF_VISIT(type) \ |
| 326 void Visit##type(type* node) override { \ | 326 void Visit##type(type* node) override { \ |
| 327 HOptimizedGraphBuilder::Visit##type(node); \ | 327 HOptimizedGraphBuilder::Visit##type(node); \ |
| 328 } | 328 } |
| 329 DECLARATION_NODE_LIST(DEF_VISIT) | 329 DECLARATION_NODE_LIST(DEF_VISIT) |
| 330 #undef DEF_VISIT | 330 #undef DEF_VISIT |
| 331 }; | 331 }; |
| 332 | 332 |
| 333 | 333 |
| 334 OptimizedCompileJob::~OptimizedCompileJob() { delete pipeline_; } |
| 335 |
| 336 |
| 334 OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() { | 337 OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() { |
| 335 DCHECK(info()->IsOptimizing()); | 338 DCHECK(info()->IsOptimizing()); |
| 336 DCHECK(!info()->IsCompilingForDebugging()); | 339 DCHECK(!info()->IsCompilingForDebugging()); |
| 337 | 340 |
| 338 // Do not use Crankshaft/TurboFan if we need to be able to set break points. | 341 // Do not use Crankshaft/TurboFan if we need to be able to set break points. |
| 339 if (isolate()->debug()->has_break_points()) { | 342 if (isolate()->debug()->has_break_points()) { |
| 340 return RetryOptimization(kDebuggerHasBreakPoints); | 343 return RetryOptimization(kDebuggerHasBreakPoints); |
| 341 } | 344 } |
| 342 | 345 |
| 343 // Limit the number of times we try to optimize functions. | 346 // Limit the number of times we try to optimize functions. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 } else if (FLAG_turbo_type_feedback) { | 396 } else if (FLAG_turbo_type_feedback) { |
| 394 info()->MarkAsTypeFeedbackEnabled(); | 397 info()->MarkAsTypeFeedbackEnabled(); |
| 395 info()->EnsureFeedbackVector(); | 398 info()->EnsureFeedbackVector(); |
| 396 } | 399 } |
| 397 if (!info()->shared_info()->asm_function() || | 400 if (!info()->shared_info()->asm_function() || |
| 398 FLAG_turbo_asm_deoptimization) { | 401 FLAG_turbo_asm_deoptimization) { |
| 399 info()->MarkAsDeoptimizationEnabled(); | 402 info()->MarkAsDeoptimizationEnabled(); |
| 400 } | 403 } |
| 401 | 404 |
| 402 Timer t(this, &time_taken_to_create_graph_); | 405 Timer t(this, &time_taken_to_create_graph_); |
| 403 compiler::Pipeline pipeline(info()); | 406 pipeline_ = new compiler::Pipeline(info()); |
| 404 pipeline.GenerateCode(); | 407 if (pipeline_->CreateGraph()) { |
| 405 if (!info()->code().is_null()) { | |
| 406 return SetLastStatus(SUCCEEDED); | 408 return SetLastStatus(SUCCEEDED); |
| 407 } | 409 } |
| 410 delete pipeline_; |
| 411 pipeline_ = nullptr; |
| 408 } | 412 } |
| 409 | 413 |
| 410 if (!isolate()->use_crankshaft() || dont_crankshaft) { | 414 if (!isolate()->use_crankshaft() || dont_crankshaft) { |
| 411 // Crankshaft is entirely disabled. | 415 // Crankshaft is entirely disabled. |
| 412 return SetLastStatus(FAILED); | 416 return SetLastStatus(FAILED); |
| 413 } | 417 } |
| 414 | 418 |
| 415 Scope* scope = info()->scope(); | 419 Scope* scope = info()->scope(); |
| 416 if (LUnallocated::TooManyParameters(scope->num_parameters())) { | 420 if (LUnallocated::TooManyParameters(scope->num_parameters())) { |
| 417 // Crankshaft would require too many Lithium operands. | 421 // Crankshaft would require too many Lithium operands. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 } | 479 } |
| 476 | 480 |
| 477 | 481 |
| 478 OptimizedCompileJob::Status OptimizedCompileJob::OptimizeGraph() { | 482 OptimizedCompileJob::Status OptimizedCompileJob::OptimizeGraph() { |
| 479 DisallowHeapAllocation no_allocation; | 483 DisallowHeapAllocation no_allocation; |
| 480 DisallowHandleAllocation no_handles; | 484 DisallowHandleAllocation no_handles; |
| 481 DisallowHandleDereference no_deref; | 485 DisallowHandleDereference no_deref; |
| 482 DisallowCodeDependencyChange no_dependency_change; | 486 DisallowCodeDependencyChange no_dependency_change; |
| 483 | 487 |
| 484 DCHECK(last_status() == SUCCEEDED); | 488 DCHECK(last_status() == SUCCEEDED); |
| 485 // TODO(turbofan): Currently everything is done in the first phase. | 489 Timer t(this, &time_taken_to_optimize_); |
| 486 if (!info()->code().is_null()) { | 490 if (pipeline_) { |
| 487 return last_status(); | 491 if (pipeline_->OptimizeGraph()) return SetLastStatus(SUCCEEDED); |
| 492 return SetLastStatus(BAILED_OUT); |
| 488 } | 493 } |
| 489 | |
| 490 Timer t(this, &time_taken_to_optimize_); | |
| 491 DCHECK(graph_ != NULL); | 494 DCHECK(graph_ != NULL); |
| 492 BailoutReason bailout_reason = kNoReason; | 495 BailoutReason bailout_reason = kNoReason; |
| 493 | 496 |
| 494 if (graph_->Optimize(&bailout_reason)) { | 497 if (graph_->Optimize(&bailout_reason)) { |
| 495 chunk_ = LChunk::NewChunk(graph_); | 498 chunk_ = LChunk::NewChunk(graph_); |
| 496 if (chunk_ != NULL) return SetLastStatus(SUCCEEDED); | 499 if (chunk_ != NULL) return SetLastStatus(SUCCEEDED); |
| 497 } else if (bailout_reason != kNoReason) { | 500 } else if (bailout_reason != kNoReason) { |
| 498 graph_builder_->Bailout(bailout_reason); | 501 graph_builder_->Bailout(bailout_reason); |
| 499 } | 502 } |
| 500 | 503 |
| 501 return SetLastStatus(BAILED_OUT); | 504 return SetLastStatus(BAILED_OUT); |
| 502 } | 505 } |
| 503 | 506 |
| 504 | 507 |
| 505 OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() { | 508 OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() { |
| 506 DCHECK(last_status() == SUCCEEDED); | 509 DCHECK(last_status() == SUCCEEDED); |
| 507 // TODO(turbofan): Currently everything is done in the first phase. | |
| 508 if (!info()->code().is_null()) { | |
| 509 info()->dependencies()->Commit(info()->code()); | |
| 510 if (info()->is_deoptimization_enabled()) { | |
| 511 info()->parse_info()->context()->native_context()->AddOptimizedCode( | |
| 512 *info()->code()); | |
| 513 } | |
| 514 RecordOptimizationStats(); | |
| 515 return last_status(); | |
| 516 } | |
| 517 | |
| 518 DCHECK(!info()->dependencies()->HasAborted()); | 510 DCHECK(!info()->dependencies()->HasAborted()); |
| 519 DisallowCodeDependencyChange no_dependency_change; | 511 DisallowCodeDependencyChange no_dependency_change; |
| 520 DisallowJavascriptExecution no_js(isolate()); | 512 DisallowJavascriptExecution no_js(isolate()); |
| 521 { // Scope for timer. | 513 { // Scope for timer. |
| 522 Timer timer(this, &time_taken_to_codegen_); | 514 Timer timer(this, &time_taken_to_codegen_); |
| 515 if (pipeline_) { |
| 516 Handle<Code> optimized_code = pipeline_->CreateCode(); |
| 517 if (optimized_code.is_null()) return SetLastStatus(BAILED_OUT); |
| 518 DCHECK(optimized_code.is_identical_to(info()->code())); |
| 519 info()->dependencies()->Commit(info()->code()); |
| 520 if (info()->is_deoptimization_enabled()) { |
| 521 info()->parse_info()->context()->native_context()->AddOptimizedCode( |
| 522 *info()->code()); |
| 523 } |
| 524 RecordOptimizationStats(); |
| 525 return SetLastStatus(SUCCEEDED); |
| 526 } |
| 523 DCHECK(chunk_ != NULL); | 527 DCHECK(chunk_ != NULL); |
| 524 DCHECK(graph_ != NULL); | 528 DCHECK(graph_ != NULL); |
| 525 // Deferred handles reference objects that were accessible during | 529 // Deferred handles reference objects that were accessible during |
| 526 // graph creation. To make sure that we don't encounter inconsistencies | 530 // graph creation. To make sure that we don't encounter inconsistencies |
| 527 // between graph creation and code generation, we disallow accessing | 531 // between graph creation and code generation, we disallow accessing |
| 528 // objects through deferred handles during the latter, with exceptions. | 532 // objects through deferred handles during the latter, with exceptions. |
| 529 DisallowDeferredHandleDereference no_deferred_handle_deref; | 533 DisallowDeferredHandleDereference no_deferred_handle_deref; |
| 530 Handle<Code> optimized_code = chunk_->Codegen(); | 534 Handle<Code> optimized_code = chunk_->Codegen(); |
| 531 if (optimized_code.is_null()) { | 535 if (optimized_code.is_null()) { |
| 532 if (info()->bailout_reason() == kNoReason) { | 536 if (info()->bailout_reason() == kNoReason) { |
| (...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1506 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info.get(), shared); | 1510 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info.get(), shared); |
| 1507 if (info->shared_info()->SearchOptimizedCodeMap( | 1511 if (info->shared_info()->SearchOptimizedCodeMap( |
| 1508 info->context()->native_context(), info->osr_ast_id()) == -1) { | 1512 info->context()->native_context(), info->osr_ast_id()) == -1) { |
| 1509 InsertCodeIntoOptimizedCodeMap(info.get()); | 1513 InsertCodeIntoOptimizedCodeMap(info.get()); |
| 1510 } | 1514 } |
| 1511 if (FLAG_trace_opt) { | 1515 if (FLAG_trace_opt) { |
| 1512 PrintF("[completed optimizing "); | 1516 PrintF("[completed optimizing "); |
| 1513 info->closure()->ShortPrint(); | 1517 info->closure()->ShortPrint(); |
| 1514 PrintF("]\n"); | 1518 PrintF("]\n"); |
| 1515 } | 1519 } |
| 1520 // TODO(bmeurer): Improve resource management for OptimizedCompileJob. |
| 1521 job->~OptimizedCompileJob(); |
| 1516 return Handle<Code>(*info->code()); | 1522 return Handle<Code>(*info->code()); |
| 1517 } | 1523 } |
| 1518 } | 1524 } |
| 1519 | 1525 |
| 1520 DCHECK(job->last_status() != OptimizedCompileJob::SUCCEEDED); | 1526 DCHECK(job->last_status() != OptimizedCompileJob::SUCCEEDED); |
| 1521 if (FLAG_trace_opt) { | 1527 if (FLAG_trace_opt) { |
| 1522 PrintF("[aborted optimizing "); | 1528 PrintF("[aborted optimizing "); |
| 1523 info->closure()->ShortPrint(); | 1529 info->closure()->ShortPrint(); |
| 1524 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); | 1530 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); |
| 1525 } | 1531 } |
| 1532 // TODO(bmeurer): Improve resource management for OptimizedCompileJob. |
| 1533 job->~OptimizedCompileJob(); |
| 1526 return Handle<Code>::null(); | 1534 return Handle<Code>::null(); |
| 1527 } | 1535 } |
| 1528 | 1536 |
| 1529 | 1537 |
| 1530 bool Compiler::DebuggerWantsEagerCompilation(Isolate* isolate, | 1538 bool Compiler::DebuggerWantsEagerCompilation(Isolate* isolate, |
| 1531 bool allow_lazy_without_ctx) { | 1539 bool allow_lazy_without_ctx) { |
| 1532 if (LiveEditFunctionTracker::IsActive(isolate)) return true; | 1540 if (LiveEditFunctionTracker::IsActive(isolate)) return true; |
| 1533 Debug* debug = isolate->debug(); | 1541 Debug* debug = isolate->debug(); |
| 1534 bool debugging = debug->is_active() || debug->has_break_points(); | 1542 bool debugging = debug->is_active() || debug->has_break_points(); |
| 1535 return debugging && !allow_lazy_without_ctx; | 1543 return debugging && !allow_lazy_without_ctx; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1568 | 1576 |
| 1569 | 1577 |
| 1570 #if DEBUG | 1578 #if DEBUG |
| 1571 void CompilationInfo::PrintAstForTesting() { | 1579 void CompilationInfo::PrintAstForTesting() { |
| 1572 PrintF("--- Source from AST ---\n%s\n", | 1580 PrintF("--- Source from AST ---\n%s\n", |
| 1573 PrettyPrinter(isolate(), zone()).PrintProgram(function())); | 1581 PrettyPrinter(isolate(), zone()).PrintProgram(function())); |
| 1574 } | 1582 } |
| 1575 #endif | 1583 #endif |
| 1576 } // namespace internal | 1584 } // namespace internal |
| 1577 } // namespace v8 | 1585 } // namespace v8 |
| OLD | NEW |