1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-osr.h" 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen.h" 862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// True iff. we are compiling for OSR and the statement is the entry. 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOsrBuilder::HasOsrEntryAt(IterationStatement* statement) { 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return statement->OsrEntryId() == builder_->current_info()->osr_ast_id(); 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HOsrBuilder::BuildOsrLoopEntry(IterationStatement* statement) { 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(HasOsrEntryAt(statement)); 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone = builder_->zone(); 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HGraph* graph = builder_->graph(); 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // only one OSR point per compile is allowed. 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(graph->osr() == NULL); 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // remember this builder as the one OSR builder in the graph. 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph->set_osr(this); 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* non_osr_entry = graph->CreateBasicBlock(); 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr_entry_ = graph->CreateBasicBlock(); 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* true_value = graph->GetConstantTrue(); 34c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HBranch* test = builder_->New<HBranch>(true_value, ToBooleanHint::kNone, 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch non_osr_entry, osr_entry_); 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->FinishCurrentBlock(test); 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_predecessor = graph->CreateBasicBlock(); 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->Goto(non_osr_entry, loop_predecessor); 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->set_current_block(osr_entry_); 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr_entry_->set_osr_entry(); 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId osr_entry_id = statement->OsrEntryId(); 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment *environment = builder_->environment(); 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int first_expression_index = environment->first_expression_index(); 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length = environment->length(); 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr_values_ = new(zone) ZoneList<HUnknownOSRValue*>(length, zone); 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < first_expression_index; ++i) { 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HUnknownOSRValue* osr_value 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch = builder_->Add<HUnknownOSRValue>(environment, i); 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment->Bind(i, osr_value); 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr_values_->Add(osr_value, zone); 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (first_expression_index != length) { 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment->Drop(length - first_expression_index); 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = first_expression_index; i < length; ++i) { 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HUnknownOSRValue* osr_value 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch = builder_->Add<HUnknownOSRValue>(environment, i); 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment->Push(osr_value); 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr_values_->Add(osr_value, zone); 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unoptimized_frame_slots_ = 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment->local_count() + environment->push_count(); 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Keep a copy of the old environment, since the OSR values need it 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to figure out where exactly they are located in the unoptimized frame. 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment = environment->Copy(); 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->current_block()->UpdateEnvironment(environment); 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->Add<HSimulate>(osr_entry_id); 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->Add<HOsrEntry>(osr_entry_id); 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HContext* context = builder_->Add<HContext>(); 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment->BindContext(context); 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->Goto(loop_predecessor); 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_predecessor->SetJoinId(statement->EntryId()); 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->set_current_block(loop_predecessor); 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create the final loop entry 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr_loop_entry_ = builder_->BuildLoopEntry(); 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return osr_loop_entry_; 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOsrBuilder::FinishGraph() { 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // do nothing for now. 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOsrBuilder::FinishOsrValues() { 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ZoneList<HPhi*>* phis = osr_loop_entry_->phis(); 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int j = 0; j < phis->length(); j++) { 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhi* phi = phis->at(j); 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (phi->HasMergedIndex()) { 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr_values_->at(phi->merged_index())->set_incoming_value(phi); 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 106