18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// Copyright 2013 the V8 project authors. All rights reserved. 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// Use of this source code is governed by a BSD-style license that can be 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// found in the LICENSE file. 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "src/hydrogen.h" 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "src/hydrogen-osr.h" 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectnamespace v8 { 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectnamespace internal { 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// True iff. we are compiling for OSR and the statement is the entry. 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbool HOsrBuilder::HasOsrEntryAt(IterationStatement* statement) { 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return statement->OsrEntryId() == builder_->current_info()->osr_ast_id(); 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectHBasicBlock* HOsrBuilder::BuildOsrLoopEntry(IterationStatement* statement) { 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DCHECK(HasOsrEntryAt(statement)); 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Zone* zone = builder_->zone(); 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HGraph* graph = builder_->graph(); 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project // only one OSR point per compile is allowed. 2486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner DCHECK(graph->osr() == NULL); 2586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 2686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner // remember this builder as the one OSR builder in the graph. 2786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner graph->set_osr(this); 285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner HBasicBlock* non_osr_entry = graph->CreateBasicBlock(); 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project osr_entry_ = graph->CreateBasicBlock(); 3186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner HValue* true_value = graph->GetConstantTrue(); 3286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner HBranch* test = builder_->New<HBranch>(true_value, ToBooleanStub::Types(), 3386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner non_osr_entry, osr_entry_); 3486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner builder_->FinishCurrentBlock(test); 3586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 3686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner HBasicBlock* loop_predecessor = graph->CreateBasicBlock(); 3786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner builder_->Goto(non_osr_entry, loop_predecessor); 3886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 3986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner builder_->set_current_block(osr_entry_); 4086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner osr_entry_->set_osr_entry(); 4186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner BailoutId osr_entry_id = statement->OsrEntryId(); 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HEnvironment *environment = builder_->environment(); 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int first_expression_index = environment->first_expression_index(); 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int length = environment->length(); 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project osr_values_ = new(zone) ZoneList<HUnknownOSRValue*>(length, zone); 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (int i = 0; i < first_expression_index; ++i) { 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HUnknownOSRValue* osr_value 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project = builder_->Add<HUnknownOSRValue>(environment, i); 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project environment->Bind(i, osr_value); 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project osr_values_->Add(osr_value, zone); 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (first_expression_index != length) { 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project environment->Drop(length - first_expression_index); 5786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner for (int i = first_expression_index; i < length; ++i) { 5886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner HUnknownOSRValue* osr_value 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project = builder_->Add<HUnknownOSRValue>(environment, i); 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project environment->Push(osr_value); 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project osr_values_->Add(osr_value, zone); 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unoptimized_frame_slots_ = 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project environment->local_count() + environment->push_count(); 6786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 6886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner // Keep a copy of the old environment, since the OSR values need it 6986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner // to figure out where exactly they are located in the unoptimized frame. 7086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner environment = environment->Copy(); 7186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner builder_->current_block()->UpdateEnvironment(environment); 7286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 7386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner builder_->Add<HSimulate>(osr_entry_id); 7486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner builder_->Add<HOsrEntry>(osr_entry_id); 7586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner HContext* context = builder_->Add<HContext>(); 7686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner environment->BindContext(context); 7786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner builder_->Goto(loop_predecessor); 7886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner loop_predecessor->SetJoinId(statement->EntryId()); 7986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner builder_->set_current_block(loop_predecessor); 8086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 8186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner // Create the final loop entry 8286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner osr_loop_entry_ = builder_->BuildLoopEntry(); 8386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner return osr_loop_entry_; 8486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 8586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 8686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 8786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnervoid HOsrBuilder::FinishGraph() { 8886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner // do nothing for now. 8986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 9086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 9186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 9286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnervoid HOsrBuilder::FinishOsrValues() { 9386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner const ZoneList<HPhi*>* phis = osr_loop_entry_->phis(); 9486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner for (int j = 0; j < phis->length(); j++) { 9586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner HPhi* phi = phis->at(j); 9686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (phi->HasMergedIndex()) { 9786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner osr_values_->at(phi->merged_index())->set_incoming_value(phi); 9886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 9986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 10086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 10186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 10286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} } // namespace v8::internal 10386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner