Index: src/crankshaft/hydrogen.cc |
diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc |
index e5354e27c5166374c61f6ff2946d3c762179c34f..d16efd0f2512b14ec37a61ee4bbecd48c52d7f01 100644 |
--- a/src/crankshaft/hydrogen.cc |
+++ b/src/crankshaft/hydrogen.cc |
@@ -68,6 +68,153 @@ |
namespace v8 { |
namespace internal { |
+class HOptimizedGraphBuilderWithPositions : public HOptimizedGraphBuilder { |
+ public: |
+ explicit HOptimizedGraphBuilderWithPositions(CompilationInfo* info) |
+ : HOptimizedGraphBuilder(info) {} |
+ |
+#define DEF_VISIT(type) \ |
+ void Visit##type(type* node) override { \ |
+ SourcePosition old_position = SourcePosition::Unknown(); \ |
+ if (node->position() != RelocInfo::kNoPosition) { \ |
+ old_position = source_position(); \ |
+ SetSourcePosition(node->position()); \ |
+ } \ |
+ HOptimizedGraphBuilder::Visit##type(node); \ |
+ if (!old_position.IsUnknown()) { \ |
+ set_source_position(old_position); \ |
+ } \ |
+ } |
+ EXPRESSION_NODE_LIST(DEF_VISIT) |
+#undef DEF_VISIT |
+ |
+#define DEF_VISIT(type) \ |
+ void Visit##type(type* node) override { \ |
+ SourcePosition old_position = SourcePosition::Unknown(); \ |
+ if (node->position() != RelocInfo::kNoPosition) { \ |
+ old_position = source_position(); \ |
+ SetSourcePosition(node->position()); \ |
+ } \ |
+ HOptimizedGraphBuilder::Visit##type(node); \ |
+ if (!old_position.IsUnknown()) { \ |
+ set_source_position(old_position); \ |
+ } \ |
+ } |
+ STATEMENT_NODE_LIST(DEF_VISIT) |
+#undef DEF_VISIT |
+ |
+#define DEF_VISIT(type) \ |
+ void Visit##type(type* node) override { \ |
+ HOptimizedGraphBuilder::Visit##type(node); \ |
+ } |
+ DECLARATION_NODE_LIST(DEF_VISIT) |
+#undef DEF_VISIT |
+}; |
+ |
+HCompilationJob::Status HCompilationJob::CreateGraphImpl() { |
+ bool dont_crankshaft = info()->shared_info()->dont_crankshaft(); |
+ |
+ if (!isolate()->use_crankshaft() || dont_crankshaft) { |
+ // Crankshaft is entirely disabled. |
+ return FAILED; |
+ } |
+ |
+ Scope* scope = info()->scope(); |
+ if (LUnallocated::TooManyParameters(scope->num_parameters())) { |
+ // Crankshaft would require too many Lithium operands. |
+ return AbortOptimization(kTooManyParameters); |
+ } |
+ |
+ if (info()->is_osr() && |
+ LUnallocated::TooManyParametersOrStackSlots(scope->num_parameters(), |
+ scope->num_stack_slots())) { |
+ // Crankshaft would require too many Lithium operands. |
+ return AbortOptimization(kTooManyParametersLocals); |
+ } |
+ |
+ if (FLAG_trace_opt) { |
+ OFStream os(stdout); |
+ os << "[compiling method " << Brief(*info()->closure()) |
+ << " using Crankshaft"; |
+ if (info()->is_osr()) os << " OSR"; |
+ os << "]" << std::endl; |
+ } |
+ |
+ if (FLAG_trace_hydrogen) { |
+ isolate()->GetHTracer()->TraceCompilation(info()); |
+ } |
+ |
+ // Type-check the function. |
+ AstTyper(info()->isolate(), info()->zone(), info()->closure(), |
+ info()->scope(), info()->osr_ast_id(), info()->literal()) |
+ .Run(); |
+ |
+ // Optimization could have been disabled by the parser. Note that this check |
+ // is only needed because the Hydrogen graph builder is missing some bailouts. |
+ if (info()->shared_info()->optimization_disabled()) { |
+ return AbortOptimization( |
+ info()->shared_info()->disable_optimization_reason()); |
+ } |
+ |
+ HOptimizedGraphBuilder* graph_builder = |
+ (info()->is_tracking_positions() || FLAG_trace_ic) |
+ ? new (info()->zone()) HOptimizedGraphBuilderWithPositions(info()) |
+ : new (info()->zone()) HOptimizedGraphBuilder(info()); |
+ |
+ graph_ = graph_builder->CreateGraph(); |
+ |
+ if (isolate()->has_pending_exception()) { |
+ return FAILED; |
+ } |
+ |
+ if (graph_ == NULL) return BAILED_OUT; |
+ |
+ if (info()->dependencies()->HasAborted()) { |
+ // Dependency has changed during graph creation. Let's try again later. |
+ return RetryOptimization(kBailedOutDueToDependencyChange); |
+ } |
+ |
+ return SUCCEEDED; |
+} |
+ |
+HCompilationJob::Status HCompilationJob::OptimizeGraphImpl() { |
+ DCHECK(graph_ != NULL); |
+ BailoutReason bailout_reason = kNoReason; |
+ |
+ if (graph_->Optimize(&bailout_reason)) { |
+ chunk_ = LChunk::NewChunk(graph_); |
+ if (chunk_ != NULL) return SUCCEEDED; |
+ } else if (bailout_reason != kNoReason) { |
+ info()->AbortOptimization(bailout_reason); |
+ } |
+ |
+ return BAILED_OUT; |
+} |
+ |
+HCompilationJob::Status HCompilationJob::GenerateCodeImpl() { |
+ DCHECK(chunk_ != NULL); |
+ DCHECK(graph_ != NULL); |
+ { |
+ // Deferred handles reference objects that were accessible during |
+ // graph creation. To make sure that we don't encounter inconsistencies |
+ // between graph creation and code generation, we disallow accessing |
+ // objects through deferred handles during the latter, with exceptions. |
+ DisallowDeferredHandleDereference no_deferred_handle_deref; |
+ Handle<Code> optimized_code = chunk_->Codegen(); |
+ if (optimized_code.is_null()) { |
+ if (info()->bailout_reason() == kNoReason) { |
+ return AbortOptimization(kCodeGenerationFailed); |
+ } |
+ return BAILED_OUT; |
+ } |
+ RegisterWeakObjectsInOptimizedCode(optimized_code); |
+ info()->SetCode(optimized_code); |
+ } |
+ // Add to the weak list of optimized code objects. |
+ info()->context()->native_context()->AddOptimizedCode(*info()->code()); |
+ return SUCCEEDED; |
+} |
+ |
HBasicBlock::HBasicBlock(HGraph* graph) |
: block_id_(graph->GetNextBlockID()), |
graph_(graph), |