--- /dev/null
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "hydrogen.h"
+#include "hydrogen-osr.h"
+
+namespace v8 {
+namespace internal {
+
+// True iff. we are compiling for OSR and the statement is the entry.
+bool HOsrBuilder::HasOsrEntryAt(IterationStatement* statement) {
+ return statement->OsrEntryId() == builder_->current_info()->osr_ast_id();
+}
+
+
+// Build a new loop header block and set it as the current block.
+HBasicBlock *HOsrBuilder::BuildLoopEntry() {
+ HBasicBlock* loop_entry = builder_->CreateLoopHeaderBlock();
+ builder_->current_block()->Goto(loop_entry);
+ builder_->set_current_block(loop_entry);
+ return loop_entry;
+}
+
+
+HBasicBlock* HOsrBuilder::BuildPossibleOsrLoopEntry(
+ IterationStatement* statement) {
+ // Check if there is an OSR here first.
+ if (!HasOsrEntryAt(statement)) return BuildLoopEntry();
+
+ Zone* zone = builder_->zone();
+ HGraph* graph = builder_->graph();
+
+ // only one OSR point per compile is allowed.
+ ASSERT(graph->osr() == NULL);
+
+ // remember this builder as the one OSR builder in the graph.
+ graph->set_osr(this);
+
+ HBasicBlock* non_osr_entry = graph->CreateBasicBlock();
+ osr_entry_ = graph->CreateBasicBlock();
+ HValue* true_value = graph->GetConstantTrue();
+ HBranch* test = new(zone) HBranch(true_value, non_osr_entry, osr_entry_);
+ builder_->current_block()->Finish(test);
+
+ HBasicBlock* loop_predecessor = graph->CreateBasicBlock();
+ non_osr_entry->Goto(loop_predecessor);
+
+ builder_->set_current_block(osr_entry_);
+ osr_entry_->set_osr_entry();
+ BailoutId osr_entry_id = statement->OsrEntryId();
+
+ HEnvironment *environment = builder_->environment();
+ int first_expression_index = environment->first_expression_index();
+ int length = environment->length();
+ osr_values_ = new(zone) ZoneList<HUnknownOSRValue*>(length, zone);
+
+ for (int i = 0; i < first_expression_index; ++i) {
+ HUnknownOSRValue* osr_value = builder_->Add<HUnknownOSRValue>();
+ environment->Bind(i, osr_value);
+ osr_values_->Add(osr_value, zone);
+ }
+
+ if (first_expression_index != length) {
+ environment->Drop(length - first_expression_index);
+ for (int i = first_expression_index; i < length; ++i) {
+ HUnknownOSRValue* osr_value = builder_->Add<HUnknownOSRValue>();
+ environment->Push(osr_value);
+ osr_values_->Add(osr_value, zone);
+ }
+ }
+
+ builder_->AddSimulate(osr_entry_id);
+ builder_->Add<HOsrEntry>(osr_entry_id);
+ HContext* context = builder_->Add<HContext>();
+ environment->BindContext(context);
+ builder_->current_block()->Goto(loop_predecessor);
+ loop_predecessor->SetJoinId(statement->EntryId());
+ builder_->set_current_block(loop_predecessor);
+
+ // Create the final loop entry
+ osr_loop_entry_ = BuildLoopEntry();
+ return osr_loop_entry_;
+}
+
+
+void HOsrBuilder::FinishGraph() {
+ // do nothing for now.
+}
+
+
+void HOsrBuilder::FinishOsrValues() {
+ const ZoneList<HPhi*>* phis = osr_loop_entry_->phis();
+ for (int j = 0; j < phis->length(); j++) {
+ HPhi* phi = phis->at(j);
+ osr_values_->at(phi->merged_index())->set_incoming_value(phi);
+ }
+}
+
+} } // namespace v8::internal
--- /dev/null
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_HYDROGEN_OSR_H_
+#define V8_HYDROGEN_OSR_H_
+
+#include "hydrogen.h"
+#include "ast.h"
+#include "zone.h"
+
+namespace v8 {
+namespace internal {
+
+// Responsible for building graph parts related to OSR and otherwise
+// setting up the graph to do an OSR compile.
+class HOsrBuilder : public ZoneObject {
+ public:
+ explicit HOsrBuilder(HOptimizedGraphBuilder* builder)
+ : builder_(builder),
+ osr_entry_(NULL),
+ osr_loop_entry_(NULL),
+ osr_values_(NULL) { }
+ // Creates the loop entry block for the given statement, setting up OSR
+ // entries as necessary, and sets the current block to the new block.
+ HBasicBlock* BuildPossibleOsrLoopEntry(IterationStatement* statement);
+
+ // Process the hydrogen graph after it has been completed, performing
+ // any OSR-specific cleanups or changes.
+ void FinishGraph();
+
+ // Process the OSR values and phis after initial graph optimization.
+ void FinishOsrValues();
+
+ private:
+ HBasicBlock* BuildLoopEntry();
+ bool HasOsrEntryAt(IterationStatement* statement);
+
+ HOptimizedGraphBuilder* builder_;
+ HBasicBlock* osr_entry_;
+ HBasicBlock* osr_loop_entry_;
+ ZoneList<HUnknownOSRValue*>* osr_values_;
+};
+
+} } // namespace v8::internal
+
+#endif // V8_HYDROGEN_OSR_H_
#include "hydrogen-escape-analysis.h"
#include "hydrogen-infer-representation.h"
#include "hydrogen-gvn.h"
+#include "hydrogen-osr.h"
#include "hydrogen-uint32-analysis.h"
#include "lithium-allocator.h"
#include "parser.h"
break_scope_(NULL),
inlined_count_(0),
globals_(10, info->zone()),
- inline_bailout_(false) {
+ inline_bailout_(false),
+ osr_(new(info->zone()) HOsrBuilder(this)) {
// This is not initialized in the initializer list because the
// constructor for the initial state relies on function_state_ == NULL
// to know it's the initial state.
values_(16, info->zone()),
phi_list_(NULL),
uint32_instructions_(NULL),
+ osr_(NULL),
info_(info),
zone_(info->zone()),
is_recursive_(false),
!type_info->matches_inlined_type_change_checksum(composite_checksum));
type_info->set_inlined_type_change_checksum(composite_checksum);
+ // Perform any necessary OSR-specific cleanups or changes to the graph.
+ osr_->FinishGraph();
+
return true;
}
}
CollectPhis();
- if (has_osr_loop_entry()) {
- const ZoneList<HPhi*>* phis = osr_loop_entry()->phis();
- for (int j = 0; j < phis->length(); j++) {
- HPhi* phi = phis->at(j);
- osr_values()->at(phi->merged_index())->set_incoming_value(phi);
- }
- }
+ if (has_osr()) osr()->FinishOsrValues();
Run<HInferRepresentationPhase>();
}
-bool HOptimizedGraphBuilder::HasOsrEntryAt(IterationStatement* statement) {
- return statement->OsrEntryId() == current_info()->osr_ast_id();
-}
-
-
-bool HOptimizedGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) {
- if (!HasOsrEntryAt(statement)) return false;
-
- HBasicBlock* non_osr_entry = graph()->CreateBasicBlock();
- HBasicBlock* osr_entry = graph()->CreateBasicBlock();
- HValue* true_value = graph()->GetConstantTrue();
- HBranch* test = new(zone()) HBranch(true_value, non_osr_entry, osr_entry);
- current_block()->Finish(test);
-
- HBasicBlock* loop_predecessor = graph()->CreateBasicBlock();
- non_osr_entry->Goto(loop_predecessor);
-
- set_current_block(osr_entry);
- osr_entry->set_osr_entry();
- BailoutId osr_entry_id = statement->OsrEntryId();
- int first_expression_index = environment()->first_expression_index();
- int length = environment()->length();
- ZoneList<HUnknownOSRValue*>* osr_values =
- new(zone()) ZoneList<HUnknownOSRValue*>(length, zone());
-
- for (int i = 0; i < first_expression_index; ++i) {
- HUnknownOSRValue* osr_value = Add<HUnknownOSRValue>();
- environment()->Bind(i, osr_value);
- osr_values->Add(osr_value, zone());
- }
-
- if (first_expression_index != length) {
- environment()->Drop(length - first_expression_index);
- for (int i = first_expression_index; i < length; ++i) {
- HUnknownOSRValue* osr_value = Add<HUnknownOSRValue>();
- environment()->Push(osr_value);
- osr_values->Add(osr_value, zone());
- }
- }
-
- graph()->set_osr_values(osr_values);
-
- AddSimulate(osr_entry_id);
- Add<HOsrEntry>(osr_entry_id);
- HContext* context = Add<HContext>();
- environment()->BindContext(context);
- current_block()->Goto(loop_predecessor);
- loop_predecessor->SetJoinId(statement->EntryId());
- set_current_block(loop_predecessor);
- return true;
-}
-
-
void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt,
HBasicBlock* loop_entry,
BreakAndContinueInfo* break_info) {
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
ASSERT(current_block() != NULL);
- bool osr_entry = PreProcessOsrEntry(stmt);
- HBasicBlock* loop_entry = CreateLoopHeaderBlock();
- current_block()->Goto(loop_entry);
- set_current_block(loop_entry);
- if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
+ HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt);
BreakAndContinueInfo break_info(stmt);
CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
ASSERT(current_block() != NULL);
- bool osr_entry = PreProcessOsrEntry(stmt);
- HBasicBlock* loop_entry = CreateLoopHeaderBlock();
- current_block()->Goto(loop_entry);
- set_current_block(loop_entry);
- if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
-
+ HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt);
// If the condition is constant true, do not generate a branch.
HBasicBlock* loop_successor = NULL;
CHECK_ALIVE(Visit(stmt->init()));
}
ASSERT(current_block() != NULL);
- bool osr_entry = PreProcessOsrEntry(stmt);
- HBasicBlock* loop_entry = CreateLoopHeaderBlock();
- current_block()->Goto(loop_entry);
- set_current_block(loop_entry);
- if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
+ HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt);
HBasicBlock* loop_successor = NULL;
if (stmt->cond() != NULL) {
HForInCacheArray::cast(array)->set_index_cache(
HForInCacheArray::cast(index_cache));
- bool osr_entry = PreProcessOsrEntry(stmt);
- HBasicBlock* loop_entry = CreateLoopHeaderBlock();
- current_block()->Goto(loop_entry);
- set_current_block(loop_entry);
- if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
+ HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt);
HValue* index = environment()->ExpressionStackAt(0);
HValue* limit = environment()->ExpressionStackAt(1);
class HEnvironment;
class HGraph;
class HLoopInformation;
+class HOsrBuilder;
class HTracer;
class LAllocator;
class LChunk;
void Verify(bool do_full_verify) const;
#endif
- bool has_osr_loop_entry() {
- return osr_loop_entry_.is_set();
+ bool has_osr() {
+ return osr_ != NULL;
}
- HBasicBlock* osr_loop_entry() {
- return osr_loop_entry_.get();
+ void set_osr(HOsrBuilder* osr) {
+ osr_ = osr;
}
- void set_osr_loop_entry(HBasicBlock* entry) {
- osr_loop_entry_.set(entry);
- }
-
- ZoneList<HUnknownOSRValue*>* osr_values() {
- return osr_values_.get();
- }
-
- void set_osr_values(ZoneList<HUnknownOSRValue*>* values) {
- osr_values_.set(values);
+ HOsrBuilder* osr() {
+ return osr_;
}
int update_type_change_checksum(int delta) {
SetOncePointer<HConstant> constant_invalid_context_;
SetOncePointer<HArgumentsObject> arguments_object_;
- SetOncePointer<HBasicBlock> osr_loop_entry_;
- SetOncePointer<ZoneList<HUnknownOSRValue*> > osr_values_;
+ HOsrBuilder* osr_;
CompilationInfo* info_;
Zone* zone_;
int no_side_effects_scope_count_;
};
-
class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor {
public:
// A class encapsulating (lazily-allocated) break and continue blocks for
void VisitArithmeticExpression(BinaryOperation* expr);
bool PreProcessOsrEntry(IterationStatement* statement);
- // True iff. we are compiling for OSR and the statement is the entry.
- bool HasOsrEntryAt(IterationStatement* statement);
void VisitLoopBody(IterationStatement* stmt,
HBasicBlock* loop_entry,
BreakAndContinueInfo* break_info);
bool inline_bailout_;
+ HOsrBuilder* osr_;
+
friend class FunctionState; // Pushes and pops the state stack.
friend class AstContext; // Pushes and pops the AST context stack.
friend class KeyedLoadFastElementStub;
+ friend class HOsrBuilder;
DISALLOW_COPY_AND_ASSIGN(HOptimizedGraphBuilder);
};
'../../src/hydrogen-infer-representation.h',
'../../src/hydrogen-uint32-analysis.cc',
'../../src/hydrogen-uint32-analysis.h',
+ '../../src/hydrogen-osr.cc',
+ '../../src/hydrogen-osr.h',
'../../src/ic-inl.h',
'../../src/ic.cc',
'../../src/ic.h',