Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(434)

Unified Diff: src/hydrogen.h

Issue 6697023: Merge 6800:7180 from the bleeding edge branch to the experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/heap-profiler.cc ('k') | src/hydrogen.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen.h
===================================================================
--- src/hydrogen.h (revision 7180)
+++ src/hydrogen.h (working copy)
@@ -117,6 +117,7 @@
void SetJoinId(int id);
void Finish(HControlInstruction* last);
+ void FinishExit(HControlInstruction* instruction);
void Goto(HBasicBlock* block, bool include_stack_check = false);
int PredecessorIndexOf(HBasicBlock* predecessor) const;
@@ -191,113 +192,13 @@
};
-class HSubgraph: public ZoneObject {
+class HGraph: public ZoneObject {
public:
- explicit HSubgraph(HGraph* graph)
- : graph_(graph),
- entry_block_(NULL),
- exit_block_(NULL),
- break_continue_info_(4) {
- }
-
- HGraph* graph() const { return graph_; }
- HEnvironment* environment() const {
- ASSERT(HasExit());
- return exit_block_->last_environment();
- }
-
- bool HasExit() const { return exit_block_ != NULL; }
-
- void PreProcessOsrEntry(IterationStatement* statement);
-
- void AppendOptional(HSubgraph* graph,
- bool on_true_branch,
- HValue* boolean_value);
- void AppendJoin(HSubgraph* then_graph, HSubgraph* else_graph, AstNode* node);
- void AppendWhile(HSubgraph* condition,
- HSubgraph* body,
- IterationStatement* statement,
- HSubgraph* continue_subgraph,
- HSubgraph* exit);
- void AppendDoWhile(HSubgraph* body,
- IterationStatement* statement,
- HSubgraph* go_back,
- HSubgraph* exit);
- void AppendEndless(HSubgraph* body, IterationStatement* statement);
- void Append(HSubgraph* next, BreakableStatement* statement);
- void ResolveContinue(IterationStatement* statement);
- HBasicBlock* BundleBreak(BreakableStatement* statement);
- HBasicBlock* BundleContinue(IterationStatement* statement);
- HBasicBlock* BundleBreakContinue(BreakableStatement* statement,
- bool is_continue,
- int join_id);
- HBasicBlock* JoinBlocks(HBasicBlock* a, HBasicBlock* b, int id);
-
- void FinishExit(HControlInstruction* instruction);
- void FinishBreakContinue(BreakableStatement* target, bool is_continue);
- void Initialize(HBasicBlock* block) {
- ASSERT(entry_block_ == NULL);
- entry_block_ = block;
- exit_block_ = block;
- }
- HBasicBlock* entry_block() const { return entry_block_; }
- HBasicBlock* exit_block() const { return exit_block_; }
- void set_exit_block(HBasicBlock* block) {
- exit_block_ = block;
- }
-
- void ConnectExitTo(HBasicBlock* other, bool include_stack_check = false) {
- if (HasExit()) {
- exit_block()->Goto(other, include_stack_check);
- }
- }
-
- void AddBreakContinueInfo(HSubgraph* other) {
- break_continue_info_.AddAll(other->break_continue_info_);
- }
-
- protected:
- class BreakContinueInfo: public ZoneObject {
- public:
- BreakContinueInfo(BreakableStatement* target, HBasicBlock* block,
- bool is_continue)
- : target_(target), block_(block), continue_(is_continue) {}
- BreakableStatement* target() const { return target_; }
- HBasicBlock* block() const { return block_; }
- bool is_continue() const { return continue_; }
- bool IsResolved() const { return block_ == NULL; }
- void Resolve() { block_ = NULL; }
-
- private:
- BreakableStatement* target_;
- HBasicBlock* block_;
- bool continue_;
- };
-
- const ZoneList<BreakContinueInfo*>* break_continue_info() const {
- return &break_continue_info_;
- }
-
- HGraph* graph_; // The graph this is a subgraph of.
- HBasicBlock* entry_block_;
- HBasicBlock* exit_block_;
-
- private:
- ZoneList<BreakContinueInfo*> break_continue_info_;
-};
-
-
-class HGraph: public HSubgraph {
- public:
explicit HGraph(CompilationInfo* info);
- CompilationInfo* info() const { return info_; }
-
- bool AllowCodeMotion() const;
-
const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
const ZoneList<HPhi*>* phi_list() const { return phi_list_; }
- Handle<String> debug_name() const { return info_->function()->debug_name(); }
+ HBasicBlock* entry_block() const { return entry_block_; }
HEnvironment* start_environment() const { return start_environment_; }
void InitializeInferredTypes();
@@ -306,6 +207,7 @@
void ComputeMinusZeroChecks();
bool ProcessArgumentsObject();
void EliminateRedundantPhis();
+ void EliminateUnreachablePhis();
void Canonicalize();
void OrderBlocks();
void AssignDominators();
@@ -314,7 +216,7 @@
// which are not supported by the optimizing compiler.
bool CollectPhis();
- Handle<Code> Compile();
+ Handle<Code> Compile(CompilationInfo* info);
void set_undefined_constant(HConstant* constant) {
undefined_constant_.set(constant);
@@ -335,9 +237,6 @@
arguments_object_.set(object);
}
- // True iff. we are compiling for OSR and the statement is the entry.
- bool HasOsrEntryAt(IterationStatement* statement);
-
int GetMaximumValueID() const { return values_.length(); }
int GetNextBlockID() { return next_block_id_++; }
int GetNextValueID(HValue* value) {
@@ -369,15 +268,16 @@
void PropagateMinusZeroChecks(HValue* value, BitVector* visited);
void InsertRepresentationChangeForUse(HValue* value,
HValue* use,
- Representation to,
- bool truncating);
- void InsertRepresentationChanges(HValue* current);
+ Representation to);
+ void InsertRepresentationChangesForValue(HValue* current,
+ ZoneList<HValue*>* value_list,
+ ZoneList<Representation>* rep_list);
void InferTypes(ZoneList<HValue*>* worklist);
void InitializeInferredTypes(int from_inclusive, int to_inclusive);
void CheckForBackEdge(HBasicBlock* block, HBasicBlock* successor);
int next_block_id_;
- CompilationInfo* info_;
+ HBasicBlock* entry_block_;
HEnvironment* start_environment_;
ZoneList<HBasicBlock*> blocks_;
ZoneList<HValue*> values_;
@@ -389,8 +289,6 @@
SetOncePointer<HConstant> constant_false_;
SetOncePointer<HArgumentsObject> arguments_object_;
- friend class HSubgraph;
-
DISALLOW_COPY_AND_ASSIGN(HGraph);
};
@@ -481,7 +379,7 @@
void ClearHistory() {
pop_count_ = 0;
push_count_ = 0;
- assigned_variables_.Clear();
+ assigned_variables_.Rewind(0);
}
void SetValueAt(int index, HValue* value) {
@@ -528,6 +426,8 @@
class HGraphBuilder;
+// This class is not BASE_EMBEDDED because our inlining implementation uses
+// new and delete.
class AstContext {
public:
bool IsEffect() const { return kind_ == Expression::kEffect; }
@@ -619,26 +519,122 @@
};
+class FunctionState BASE_EMBEDDED {
+ public:
+ FunctionState(HGraphBuilder* owner,
+ CompilationInfo* info,
+ TypeFeedbackOracle* oracle);
+ ~FunctionState();
+
+ CompilationInfo* compilation_info() { return compilation_info_; }
+ TypeFeedbackOracle* oracle() { return oracle_; }
+ AstContext* call_context() { return call_context_; }
+ HBasicBlock* function_return() { return function_return_; }
+ TestContext* test_context() { return test_context_; }
+ void ClearInlinedTestContext() {
+ delete test_context_;
+ test_context_ = NULL;
+ }
+
+ private:
+ HGraphBuilder* owner_;
+
+ CompilationInfo* compilation_info_;
+ TypeFeedbackOracle* oracle_;
+
+ // During function inlining, expression context of the call being
+ // inlined. NULL when not inlining.
+ AstContext* call_context_;
+
+ // When inlining in an effect of value context, this is the return block.
+ // It is NULL otherwise. When inlining in a test context, there are a
+ // pair of return blocks in the context. When not inlining, there is no
+ // local return point.
+ HBasicBlock* function_return_;
+
+ // When inlining a call in a test context, a context containing a pair of
+ // return blocks. NULL in all other cases.
+ TestContext* test_context_;
+
+ FunctionState* outer_;
+};
+
+
class HGraphBuilder: public AstVisitor {
public:
- explicit HGraphBuilder(TypeFeedbackOracle* oracle)
- : oracle_(oracle),
+ enum BreakType { BREAK, CONTINUE };
+
+ // A class encapsulating (lazily-allocated) break and continue blocks for
+ // a breakable statement. Separated from BreakAndContinueScope so that it
+ // can have a separate lifetime.
+ class BreakAndContinueInfo BASE_EMBEDDED {
+ public:
+ explicit BreakAndContinueInfo(BreakableStatement* target)
+ : target_(target), break_block_(NULL), continue_block_(NULL) {
+ }
+
+ BreakableStatement* target() { return target_; }
+ HBasicBlock* break_block() { return break_block_; }
+ void set_break_block(HBasicBlock* block) { break_block_ = block; }
+ HBasicBlock* continue_block() { return continue_block_; }
+ void set_continue_block(HBasicBlock* block) { continue_block_ = block; }
+
+ private:
+ BreakableStatement* target_;
+ HBasicBlock* break_block_;
+ HBasicBlock* continue_block_;
+ };
+
+ // A helper class to maintain a stack of current BreakAndContinueInfo
+ // structures mirroring BreakableStatement nesting.
+ class BreakAndContinueScope BASE_EMBEDDED {
+ public:
+ BreakAndContinueScope(BreakAndContinueInfo* info, HGraphBuilder* owner)
+ : info_(info), owner_(owner), next_(owner->break_scope()) {
+ owner->set_break_scope(this);
+ }
+
+ ~BreakAndContinueScope() { owner_->set_break_scope(next_); }
+
+ BreakAndContinueInfo* info() { return info_; }
+ HGraphBuilder* owner() { return owner_; }
+ BreakAndContinueScope* next() { return next_; }
+
+ // Search the break stack for a break or continue target.
+ HBasicBlock* Get(BreakableStatement* stmt, BreakType type);
+
+ private:
+ BreakAndContinueInfo* info_;
+ HGraphBuilder* owner_;
+ BreakAndContinueScope* next_;
+ };
+
+ HGraphBuilder(CompilationInfo* info, TypeFeedbackOracle* oracle)
+ : function_state_(NULL),
+ initial_function_state_(this, info, oracle),
+ ast_context_(NULL),
+ break_scope_(NULL),
graph_(NULL),
- current_subgraph_(NULL),
- peeled_statement_(NULL),
- ast_context_(NULL),
- call_context_(NULL),
- function_return_(NULL),
- inlined_count_(0) { }
+ current_block_(NULL),
+ inlined_count_(0) {
+ // 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.
+ function_state_= &initial_function_state_;
+ }
- HGraph* CreateGraph(CompilationInfo* info);
+ HGraph* CreateGraph();
// Simple accessors.
HGraph* graph() const { return graph_; }
- HSubgraph* subgraph() const { return current_subgraph_; }
+ BreakAndContinueScope* break_scope() const { return break_scope_; }
+ void set_break_scope(BreakAndContinueScope* head) { break_scope_ = head; }
- HEnvironment* environment() const { return subgraph()->environment(); }
- HBasicBlock* CurrentBlock() const { return subgraph()->exit_block(); }
+ HBasicBlock* current_block() const { return current_block_; }
+ void set_current_block(HBasicBlock* block) { current_block_ = block; }
+ HEnvironment* environment() const {
+ return current_block()->last_environment();
+ }
// Adding instructions.
HInstruction* AddInstruction(HInstruction* instr);
@@ -650,8 +646,7 @@
private:
// Type of a member function that generates inline code for a native function.
- typedef void (HGraphBuilder::*InlineFunctionGenerator)(int argument_count,
- int ast_id);
+ typedef void (HGraphBuilder::*InlineFunctionGenerator)(CallRuntime* call);
// Forward declarations for inner scope classes.
class SubgraphScope;
@@ -667,15 +662,34 @@
static const int kMaxSourceSize = 600;
// Simple accessors.
- TypeFeedbackOracle* oracle() const { return oracle_; }
+ FunctionState* function_state() const { return function_state_; }
+ void set_function_state(FunctionState* state) { function_state_ = state; }
+
AstContext* ast_context() const { return ast_context_; }
void set_ast_context(AstContext* context) { ast_context_ = context; }
- AstContext* call_context() const { return call_context_; }
- HBasicBlock* function_return() const { return function_return_; }
+ // Accessors forwarded to the function state.
+ CompilationInfo* info() const {
+ return function_state()->compilation_info();
+ }
+ TypeFeedbackOracle* oracle() const { return function_state()->oracle(); }
+
+ AstContext* call_context() const {
+ return function_state()->call_context();
+ }
+ HBasicBlock* function_return() const {
+ return function_state()->function_return();
+ }
+ TestContext* inlined_test_context() const {
+ return function_state()->test_context();
+ }
+ void ClearInlinedTestContext() {
+ function_state()->ClearInlinedTestContext();
+ }
+
// Generators for inline runtime functions.
#define INLINE_FUNCTION_GENERATOR_DECLARATION(Name, argc, ressize) \
- void Generate##Name(int argument_count, int ast_id);
+ void Generate##Name(CallRuntime* call);
INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION)
INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION)
@@ -683,15 +697,31 @@
void Bailout(const char* reason);
- void AppendPeeledWhile(IterationStatement* stmt,
- HSubgraph* cond_graph,
- HSubgraph* body_graph,
- HSubgraph* exit_graph);
+ void PreProcessOsrEntry(IterationStatement* statement);
+ // True iff. we are compiling for OSR and the statement is the entry.
+ bool HasOsrEntryAt(IterationStatement* statement);
- void AddToSubgraph(HSubgraph* graph, ZoneList<Statement*>* stmts);
- void AddToSubgraph(HSubgraph* graph, Statement* stmt);
- void AddToSubgraph(HSubgraph* graph, Expression* expr);
+ HBasicBlock* CreateJoin(HBasicBlock* first,
+ HBasicBlock* second,
+ int join_id);
+ // Create a back edge in the flow graph. body_exit is the predecessor
+ // block and loop_entry is the successor block. loop_successor is the
+ // block where control flow exits the loop normally (e.g., via failure of
+ // the condition) and break_block is the block where control flow breaks
+ // from the loop. All blocks except loop_entry can be NULL. The return
+ // value is the new successor block which is the join of loop_successor
+ // and break_block, or NULL.
+ HBasicBlock* CreateLoop(IterationStatement* statement,
+ HBasicBlock* loop_entry,
+ HBasicBlock* body_exit,
+ HBasicBlock* loop_successor,
+ HBasicBlock* break_block);
+
+ HBasicBlock* JoinContinue(IterationStatement* statement,
+ HBasicBlock* exit_block,
+ HBasicBlock* continue_block);
+
HValue* Top() const { return environment()->Top(); }
void Drop(int n) { environment()->Drop(n); }
void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); }
@@ -702,17 +732,21 @@
HBasicBlock* true_block,
HBasicBlock* false_block);
- // Visit an argument subexpression.
+ // Visit an argument subexpression and emit a push to the outgoing
+ // arguments.
void VisitArgument(Expression* expr);
void VisitArgumentList(ZoneList<Expression*>* arguments);
+ // Visit a list of expressions from left to right, each in a value context.
+ void VisitExpressions(ZoneList<Expression*>* exprs);
+
void AddPhi(HPhi* phi);
void PushAndAdd(HInstruction* instr);
// Remove the arguments from the bailout environment and emit instructions
// to push them as outgoing parameters.
- void PreProcessCall(HCall* call);
+ template <int V> HInstruction* PreProcessCall(HCall<V>* call);
void AssumeRepresentation(HValue* value, Representation r);
static Representation ToRepresentation(TypeInfo info);
@@ -724,16 +758,8 @@
AST_NODE_LIST(DECLARE_VISIT)
#undef DECLARE_VISIT
- bool ShouldPeel(HSubgraph* cond, HSubgraph* body);
-
HBasicBlock* CreateBasicBlock(HEnvironment* env);
- HSubgraph* CreateEmptySubgraph();
- HSubgraph* CreateGotoSubgraph(HEnvironment* env);
- HSubgraph* CreateBranchSubgraph(HEnvironment* env);
- HSubgraph* CreateLoopHeaderSubgraph(HEnvironment* env);
- HSubgraph* CreateInlinedSubgraph(HEnvironment* outer,
- Handle<JSFunction> target,
- FunctionLiteral* function);
+ HBasicBlock* CreateLoopHeaderBlock();
// Helpers for flow graph construction.
void LookupGlobalPropertyCell(Variable* var,
@@ -747,8 +773,12 @@
HValue* receiver,
Handle<Map> receiver_map,
CheckType check_type);
- void TraceInline(Handle<JSFunction> target, bool result);
+ // If --trace-inlining, print a line of the inlining trace. Inlining
+ // succeeded if the reason string is NULL and failed if there is a
+ // non-NULL reason string.
+ void TraceInline(Handle<JSFunction> target, const char* failure_reason);
+
void HandleGlobalVariableAssignment(Variable* var,
HValue* value,
int position,
@@ -816,9 +846,10 @@
HValue* val,
Expression* expr);
- HCompare* BuildSwitchCompare(HSubgraph* subgraph,
- HValue* switch_value,
- CaseClause* clause);
+ HInstruction* BuildStoreKeyedPixelArrayElement(HValue* object,
+ HValue* key,
+ HValue* val,
+ Expression* expr);
HValue* BuildContextChainWalk(Variable* var);
@@ -828,31 +859,25 @@
bool smi_and_map_check);
- HBasicBlock* BuildTypeSwitch(HValue* receiver,
- ZoneMapList* maps,
- ZoneList<HSubgraph*>* body_graphs,
- HSubgraph* default_graph,
- int join_id);
+ // The translation state of the currently-being-translated function.
+ FunctionState* function_state_;
- TypeFeedbackOracle* oracle_;
- HGraph* graph_;
- HSubgraph* current_subgraph_;
- IterationStatement* peeled_statement_;
+ // The base of the function state stack.
+ FunctionState initial_function_state_;
+
// Expression context of the currently visited subexpression. NULL when
// visiting statements.
AstContext* ast_context_;
- // During function inlining, expression context of the call being
- // inlined. NULL when not inlining.
- AstContext* call_context_;
+ // A stack of breakable statements entered.
+ BreakAndContinueScope* break_scope_;
- // When inlining a call in an effect or value context, the return
- // block. NULL otherwise. When inlining a call in a test context, there
- // are a pair of target blocks in the call context.
- HBasicBlock* function_return_;
+ HGraph* graph_;
+ HBasicBlock* current_block_;
int inlined_count_;
+ friend class FunctionState; // Pushes and pops the state stack.
friend class AstContext; // Pushes and pops the AST context stack.
DISALLOW_COPY_AND_ASSIGN(HGraphBuilder);
@@ -914,6 +939,7 @@
class HStatistics: public Malloced {
public:
+ void Initialize(CompilationInfo* info);
void Print();
void SaveTiming(const char* name, int64_t ticks, unsigned size);
static HStatistics* Instance() {
@@ -932,7 +958,8 @@
sizes_(5),
total_(0),
total_size_(0),
- full_code_gen_(0) { }
+ full_code_gen_(0),
+ source_size_(0) { }
List<int64_t> timing_;
List<const char*> names_;
@@ -940,6 +967,7 @@
int64_t total_;
unsigned total_size_;
int64_t full_code_gen_;
+ double source_size_;
};
« no previous file with comments | « src/heap-profiler.cc ('k') | src/hydrogen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698