summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/v8/src/hydrogen.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/v8/src/hydrogen.h')
-rw-r--r--src/3rdparty/v8/src/hydrogen.h1703
1 files changed, 0 insertions, 1703 deletions
diff --git a/src/3rdparty/v8/src/hydrogen.h b/src/3rdparty/v8/src/hydrogen.h
deleted file mode 100644
index a9829a0..0000000
--- a/src/3rdparty/v8/src/hydrogen.h
+++ /dev/null
@@ -1,1703 +0,0 @@
-// Copyright 2012 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_H_
-#define V8_HYDROGEN_H_
-
-#include "v8.h"
-
-#include "allocation.h"
-#include "ast.h"
-#include "compiler.h"
-#include "hydrogen-instructions.h"
-#include "type-info.h"
-#include "zone.h"
-
-namespace v8 {
-namespace internal {
-
-// Forward declarations.
-class BitVector;
-class FunctionState;
-class HEnvironment;
-class HGraph;
-class HLoopInformation;
-class HTracer;
-class LAllocator;
-class LChunk;
-class LiveRange;
-
-
-class HBasicBlock: public ZoneObject {
- public:
- explicit HBasicBlock(HGraph* graph);
- virtual ~HBasicBlock() { }
-
- // Simple accessors.
- int block_id() const { return block_id_; }
- void set_block_id(int id) { block_id_ = id; }
- HGraph* graph() const { return graph_; }
- const ZoneList<HPhi*>* phis() const { return &phis_; }
- HInstruction* first() const { return first_; }
- HInstruction* last() const { return last_; }
- void set_last(HInstruction* instr) { last_ = instr; }
- HInstruction* GetLastInstruction();
- HControlInstruction* end() const { return end_; }
- HLoopInformation* loop_information() const { return loop_information_; }
- const ZoneList<HBasicBlock*>* predecessors() const { return &predecessors_; }
- bool HasPredecessor() const { return predecessors_.length() > 0; }
- const ZoneList<HBasicBlock*>* dominated_blocks() const {
- return &dominated_blocks_;
- }
- const ZoneList<int>* deleted_phis() const {
- return &deleted_phis_;
- }
- void RecordDeletedPhi(int merge_index) {
- deleted_phis_.Add(merge_index, zone());
- }
- HBasicBlock* dominator() const { return dominator_; }
- HEnvironment* last_environment() const { return last_environment_; }
- int argument_count() const { return argument_count_; }
- void set_argument_count(int count) { argument_count_ = count; }
- int first_instruction_index() const { return first_instruction_index_; }
- void set_first_instruction_index(int index) {
- first_instruction_index_ = index;
- }
- int last_instruction_index() const { return last_instruction_index_; }
- void set_last_instruction_index(int index) {
- last_instruction_index_ = index;
- }
- bool is_osr_entry() { return is_osr_entry_; }
- void set_osr_entry() { is_osr_entry_ = true; }
-
- void AttachLoopInformation();
- void DetachLoopInformation();
- bool IsLoopHeader() const { return loop_information() != NULL; }
- bool IsStartBlock() const { return block_id() == 0; }
- void PostProcessLoopHeader(IterationStatement* stmt);
-
- bool IsFinished() const { return end_ != NULL; }
- void AddPhi(HPhi* phi);
- void RemovePhi(HPhi* phi);
- void AddInstruction(HInstruction* instr);
- bool Dominates(HBasicBlock* other) const;
- int LoopNestingDepth() const;
-
- void SetInitialEnvironment(HEnvironment* env);
- void ClearEnvironment() { last_environment_ = NULL; }
- bool HasEnvironment() const { return last_environment_ != NULL; }
- void UpdateEnvironment(HEnvironment* env) { last_environment_ = env; }
- HBasicBlock* parent_loop_header() const { return parent_loop_header_; }
-
- void set_parent_loop_header(HBasicBlock* block) {
- ASSERT(parent_loop_header_ == NULL);
- parent_loop_header_ = block;
- }
-
- bool HasParentLoopHeader() const { return parent_loop_header_ != NULL; }
-
- void SetJoinId(BailoutId ast_id);
-
- void Finish(HControlInstruction* last);
- void FinishExit(HControlInstruction* instruction);
- void Goto(HBasicBlock* block, FunctionState* state = NULL);
-
- int PredecessorIndexOf(HBasicBlock* predecessor) const;
- void AddSimulate(BailoutId ast_id,
- RemovableSimulate removable = FIXED_SIMULATE) {
- AddInstruction(CreateSimulate(ast_id, removable));
- }
- void AssignCommonDominator(HBasicBlock* other);
- void AssignLoopSuccessorDominators();
-
- void FinishExitWithDeoptimization(HDeoptimize::UseEnvironment has_uses) {
- FinishExit(CreateDeoptimize(has_uses));
- }
-
- // Add the inlined function exit sequence, adding an HLeaveInlined
- // instruction and updating the bailout environment.
- void AddLeaveInlined(HValue* return_value, FunctionState* state);
-
- // If a target block is tagged as an inline function return, all
- // predecessors should contain the inlined exit sequence:
- //
- // LeaveInlined
- // Simulate (caller's environment)
- // Goto (target block)
- bool IsInlineReturnTarget() const { return is_inline_return_target_; }
- void MarkAsInlineReturnTarget() { is_inline_return_target_ = true; }
-
- bool IsDeoptimizing() const { return is_deoptimizing_; }
- void MarkAsDeoptimizing() { is_deoptimizing_ = true; }
-
- bool IsLoopSuccessorDominator() const {
- return dominates_loop_successors_;
- }
- void MarkAsLoopSuccessorDominator() {
- dominates_loop_successors_ = true;
- }
-
- inline Zone* zone() const;
-
-#ifdef DEBUG
- void Verify();
-#endif
-
- private:
- void RegisterPredecessor(HBasicBlock* pred);
- void AddDominatedBlock(HBasicBlock* block);
-
- HSimulate* CreateSimulate(BailoutId ast_id, RemovableSimulate removable);
- HDeoptimize* CreateDeoptimize(HDeoptimize::UseEnvironment has_uses);
-
- int block_id_;
- HGraph* graph_;
- ZoneList<HPhi*> phis_;
- HInstruction* first_;
- HInstruction* last_;
- HControlInstruction* end_;
- HLoopInformation* loop_information_;
- ZoneList<HBasicBlock*> predecessors_;
- HBasicBlock* dominator_;
- ZoneList<HBasicBlock*> dominated_blocks_;
- HEnvironment* last_environment_;
- // Outgoing parameter count at block exit, set during lithium translation.
- int argument_count_;
- // Instruction indices into the lithium code stream.
- int first_instruction_index_;
- int last_instruction_index_;
- ZoneList<int> deleted_phis_;
- HBasicBlock* parent_loop_header_;
- bool is_inline_return_target_;
- bool is_deoptimizing_;
- bool dominates_loop_successors_;
- bool is_osr_entry_;
-};
-
-
-class HPredecessorIterator BASE_EMBEDDED {
- public:
- explicit HPredecessorIterator(HBasicBlock* block)
- : predecessor_list_(block->predecessors()), current_(0) { }
-
- bool Done() { return current_ >= predecessor_list_->length(); }
- HBasicBlock* Current() { return predecessor_list_->at(current_); }
- void Advance() { current_++; }
-
- private:
- const ZoneList<HBasicBlock*>* predecessor_list_;
- int current_;
-};
-
-
-class HLoopInformation: public ZoneObject {
- public:
- HLoopInformation(HBasicBlock* loop_header, Zone* zone)
- : back_edges_(4, zone),
- loop_header_(loop_header),
- blocks_(8, zone),
- stack_check_(NULL) {
- blocks_.Add(loop_header, zone);
- }
- virtual ~HLoopInformation() {}
-
- const ZoneList<HBasicBlock*>* back_edges() const { return &back_edges_; }
- const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
- HBasicBlock* loop_header() const { return loop_header_; }
- HBasicBlock* GetLastBackEdge() const;
- void RegisterBackEdge(HBasicBlock* block);
-
- HStackCheck* stack_check() const { return stack_check_; }
- void set_stack_check(HStackCheck* stack_check) {
- stack_check_ = stack_check;
- }
-
- private:
- void AddBlock(HBasicBlock* block);
-
- ZoneList<HBasicBlock*> back_edges_;
- HBasicBlock* loop_header_;
- ZoneList<HBasicBlock*> blocks_;
- HStackCheck* stack_check_;
-};
-
-class BoundsCheckTable;
-class HGraph: public ZoneObject {
- public:
- explicit HGraph(CompilationInfo* info);
-
- Isolate* isolate() const { return isolate_; }
- Zone* zone() const { return zone_; }
- CompilationInfo* info() const { return info_; }
-
- const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
- const ZoneList<HPhi*>* phi_list() const { return phi_list_; }
- HBasicBlock* entry_block() const { return entry_block_; }
- HEnvironment* start_environment() const { return start_environment_; }
-
- void InitializeInferredTypes();
- void InsertTypeConversions();
- void MergeRemovableSimulates();
- void InsertRepresentationChanges();
- void MarkDeoptimizeOnUndefined();
- void ComputeMinusZeroChecks();
- void ComputeSafeUint32Operations();
- void GlobalValueNumbering();
- bool ProcessArgumentsObject();
- void EliminateRedundantPhis();
- void EliminateUnreachablePhis();
- void Canonicalize();
- void OrderBlocks();
- void AssignDominators();
- void SetupInformativeDefinitions();
- void EliminateRedundantBoundsChecks();
- void DehoistSimpleArrayIndexComputations();
- void DeadCodeElimination();
- void RestoreActualValues();
- void PropagateDeoptimizingMark();
- void EliminateUnusedInstructions();
-
- // Returns false if there are phi-uses of the arguments-object
- // which are not supported by the optimizing compiler.
- bool CheckArgumentsPhiUses();
-
- // Returns false if there are phi-uses of an uninitialized const
- // which are not supported by the optimizing compiler.
- bool CheckConstPhiUses();
-
- void CollectPhis();
-
- void set_undefined_constant(HConstant* constant) {
- undefined_constant_.set(constant);
- }
- HConstant* GetConstantUndefined() const { return undefined_constant_.get(); }
- HConstant* GetConstant0();
- HConstant* GetConstant1();
- HConstant* GetConstantMinus1();
- HConstant* GetConstantTrue();
- HConstant* GetConstantFalse();
- HConstant* GetConstantHole();
-
- HBasicBlock* CreateBasicBlock();
- HArgumentsObject* GetArgumentsObject() const {
- return arguments_object_.get();
- }
-
- void SetArgumentsObject(HArgumentsObject* object) {
- arguments_object_.set(object);
- }
-
- int GetMaximumValueID() const { return values_.length(); }
- int GetNextBlockID() { return next_block_id_++; }
- int GetNextValueID(HValue* value) {
- values_.Add(value, zone());
- return values_.length() - 1;
- }
- HValue* LookupValue(int id) const {
- if (id >= 0 && id < values_.length()) return values_[id];
- return NULL;
- }
-
- bool Optimize(SmartArrayPointer<char>* bailout_reason);
-
-#ifdef DEBUG
- void Verify(bool do_full_verify) const;
-#endif
-
- bool has_osr_loop_entry() {
- return osr_loop_entry_.is_set();
- }
-
- HBasicBlock* osr_loop_entry() {
- return osr_loop_entry_.get();
- }
-
- 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);
- }
-
- int update_type_change_checksum(int delta) {
- type_change_checksum_ += delta;
- return type_change_checksum_;
- }
-
- bool use_optimistic_licm() {
- return use_optimistic_licm_;
- }
-
- void set_use_optimistic_licm(bool value) {
- use_optimistic_licm_ = value;
- }
-
- bool has_soft_deoptimize() {
- return has_soft_deoptimize_;
- }
-
- void set_has_soft_deoptimize(bool value) {
- has_soft_deoptimize_ = value;
- }
-
- void MarkRecursive() {
- is_recursive_ = true;
- }
-
- bool is_recursive() const {
- return is_recursive_;
- }
-
- void RecordUint32Instruction(HInstruction* instr) {
- if (uint32_instructions_ == NULL) {
- uint32_instructions_ = new(zone()) ZoneList<HInstruction*>(4, zone());
- }
- uint32_instructions_->Add(instr, zone());
- }
-
- private:
- HConstant* GetConstant(SetOncePointer<HConstant>* pointer,
- Handle<Object> value);
- HConstant* GetConstantInt32(SetOncePointer<HConstant>* pointer,
- int32_t integer_value);
-
- void MarkAsDeoptimizingRecursively(HBasicBlock* block);
- void NullifyUnreachableInstructions();
- void InsertTypeConversions(HInstruction* instr);
- void PropagateMinusZeroChecks(HValue* value, BitVector* visited);
- void RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi);
- void InsertRepresentationChangeForUse(HValue* value,
- HValue* use_value,
- int use_index,
- Representation to);
- void InsertRepresentationChangesForValue(HValue* value);
- void InferTypes(ZoneList<HValue*>* worklist);
- void InitializeInferredTypes(int from_inclusive, int to_inclusive);
- void CheckForBackEdge(HBasicBlock* block, HBasicBlock* successor);
- void SetupInformativeDefinitionsInBlock(HBasicBlock* block);
- void SetupInformativeDefinitionsRecursively(HBasicBlock* block);
- void EliminateRedundantBoundsChecks(HBasicBlock* bb, BoundsCheckTable* table);
-
- Isolate* isolate_;
- int next_block_id_;
- HBasicBlock* entry_block_;
- HEnvironment* start_environment_;
- ZoneList<HBasicBlock*> blocks_;
- ZoneList<HValue*> values_;
- ZoneList<HPhi*>* phi_list_;
- ZoneList<HInstruction*>* uint32_instructions_;
- SetOncePointer<HConstant> undefined_constant_;
- SetOncePointer<HConstant> constant_0_;
- SetOncePointer<HConstant> constant_1_;
- SetOncePointer<HConstant> constant_minus1_;
- SetOncePointer<HConstant> constant_true_;
- SetOncePointer<HConstant> constant_false_;
- SetOncePointer<HConstant> constant_hole_;
- SetOncePointer<HArgumentsObject> arguments_object_;
-
- SetOncePointer<HBasicBlock> osr_loop_entry_;
- SetOncePointer<ZoneList<HUnknownOSRValue*> > osr_values_;
-
- CompilationInfo* info_;
- Zone* zone_;
-
- bool is_recursive_;
- bool use_optimistic_licm_;
- bool has_soft_deoptimize_;
- int type_change_checksum_;
-
- DISALLOW_COPY_AND_ASSIGN(HGraph);
-};
-
-
-Zone* HBasicBlock::zone() const { return graph_->zone(); }
-
-
-// Type of stack frame an environment might refer to.
-enum FrameType {
- JS_FUNCTION,
- JS_CONSTRUCT,
- JS_GETTER,
- JS_SETTER,
- ARGUMENTS_ADAPTOR,
- STUB
-};
-
-
-class HEnvironment: public ZoneObject {
- public:
- HEnvironment(HEnvironment* outer,
- Scope* scope,
- Handle<JSFunction> closure,
- Zone* zone);
-
- HEnvironment(Zone* zone, int parameter_count);
-
- HEnvironment* arguments_environment() {
- return outer()->frame_type() == ARGUMENTS_ADAPTOR ? outer() : this;
- }
-
- // Simple accessors.
- Handle<JSFunction> closure() const { return closure_; }
- const ZoneList<HValue*>* values() const { return &values_; }
- const GrowableBitVector* assigned_variables() const {
- return &assigned_variables_;
- }
- FrameType frame_type() const { return frame_type_; }
- int parameter_count() const { return parameter_count_; }
- int specials_count() const { return specials_count_; }
- int local_count() const { return local_count_; }
- HEnvironment* outer() const { return outer_; }
- int pop_count() const { return pop_count_; }
- int push_count() const { return push_count_; }
-
- BailoutId ast_id() const { return ast_id_; }
- void set_ast_id(BailoutId id) { ast_id_ = id; }
-
- HEnterInlined* entry() const { return entry_; }
- void set_entry(HEnterInlined* entry) { entry_ = entry; }
-
- int length() const { return values_.length(); }
- bool is_special_index(int i) const {
- return i >= parameter_count() && i < parameter_count() + specials_count();
- }
-
- int first_expression_index() const {
- return parameter_count() + specials_count() + local_count();
- }
-
- void Bind(Variable* variable, HValue* value) {
- Bind(IndexFor(variable), value);
- }
-
- void Bind(int index, HValue* value);
-
- void BindContext(HValue* value) {
- Bind(parameter_count(), value);
- }
-
- HValue* Lookup(Variable* variable) const {
- return Lookup(IndexFor(variable));
- }
-
- HValue* Lookup(int index) const {
- HValue* result = values_[index];
- ASSERT(result != NULL);
- return result;
- }
-
- HValue* LookupContext() const {
- // Return first special.
- return Lookup(parameter_count());
- }
-
- void Push(HValue* value) {
- ASSERT(value != NULL);
- ++push_count_;
- values_.Add(value, zone());
- }
-
- HValue* Pop() {
- ASSERT(!ExpressionStackIsEmpty());
- if (push_count_ > 0) {
- --push_count_;
- } else {
- ++pop_count_;
- }
- return values_.RemoveLast();
- }
-
- void Drop(int count);
-
- HValue* Top() const { return ExpressionStackAt(0); }
-
- bool ExpressionStackIsEmpty() const;
-
- HValue* ExpressionStackAt(int index_from_top) const {
- int index = length() - index_from_top - 1;
- ASSERT(HasExpressionAt(index));
- return values_[index];
- }
-
- void SetExpressionStackAt(int index_from_top, HValue* value);
-
- HEnvironment* Copy() const;
- HEnvironment* CopyWithoutHistory() const;
- HEnvironment* CopyAsLoopHeader(HBasicBlock* block) const;
-
- // Create an "inlined version" of this environment, where the original
- // environment is the outer environment but the top expression stack
- // elements are moved to an inner environment as parameters.
- HEnvironment* CopyForInlining(Handle<JSFunction> target,
- int arguments,
- FunctionLiteral* function,
- HConstant* undefined,
- InliningKind inlining_kind,
- bool undefined_receiver) const;
-
- static bool UseUndefinedReceiver(Handle<JSFunction> closure,
- FunctionLiteral* function,
- CallKind call_kind,
- InliningKind inlining_kind) {
- return (closure->shared()->native() || !function->is_classic_mode()) &&
- call_kind == CALL_AS_FUNCTION && inlining_kind != CONSTRUCT_CALL_RETURN;
- }
-
- HEnvironment* DiscardInlined(bool drop_extra) {
- HEnvironment* outer = outer_;
- while (outer->frame_type() != JS_FUNCTION) outer = outer->outer_;
- if (drop_extra) outer->Drop(1);
- return outer;
- }
-
- void AddIncomingEdge(HBasicBlock* block, HEnvironment* other);
-
- void ClearHistory() {
- pop_count_ = 0;
- push_count_ = 0;
- assigned_variables_.Clear();
- }
-
- void SetValueAt(int index, HValue* value) {
- ASSERT(index < length());
- values_[index] = value;
- }
-
- void PrintTo(StringStream* stream);
- void PrintToStd();
-
- Zone* zone() const { return zone_; }
-
- private:
- HEnvironment(const HEnvironment* other, Zone* zone);
-
- HEnvironment(HEnvironment* outer,
- Handle<JSFunction> closure,
- FrameType frame_type,
- int arguments,
- Zone* zone);
-
- // Create an artificial stub environment (e.g. for argument adaptor or
- // constructor stub).
- HEnvironment* CreateStubEnvironment(HEnvironment* outer,
- Handle<JSFunction> target,
- FrameType frame_type,
- int arguments) const;
-
- // True if index is included in the expression stack part of the environment.
- bool HasExpressionAt(int index) const;
-
- void Initialize(int parameter_count, int local_count, int stack_height);
- void Initialize(const HEnvironment* other);
-
- // Map a variable to an environment index. Parameter indices are shifted
- // by 1 (receiver is parameter index -1 but environment index 0).
- // Stack-allocated local indices are shifted by the number of parameters.
- int IndexFor(Variable* variable) const {
- ASSERT(variable->IsStackAllocated());
- int shift = variable->IsParameter()
- ? 1
- : parameter_count_ + specials_count_;
- return variable->index() + shift;
- }
-
- Handle<JSFunction> closure_;
- // Value array [parameters] [specials] [locals] [temporaries].
- ZoneList<HValue*> values_;
- GrowableBitVector assigned_variables_;
- FrameType frame_type_;
- int parameter_count_;
- int specials_count_;
- int local_count_;
- HEnvironment* outer_;
- HEnterInlined* entry_;
- int pop_count_;
- int push_count_;
- BailoutId ast_id_;
- Zone* zone_;
-};
-
-
-class HInferRepresentation BASE_EMBEDDED {
- public:
- explicit HInferRepresentation(HGraph* graph)
- : graph_(graph),
- worklist_(8, graph->zone()),
- in_worklist_(graph->GetMaximumValueID(), graph->zone()) { }
-
- void Analyze();
- void AddToWorklist(HValue* current);
-
- private:
- Zone* zone() const { return graph_->zone(); }
-
- HGraph* graph_;
- ZoneList<HValue*> worklist_;
- BitVector in_worklist_;
-};
-
-
-class HOptimizedGraphBuilder;
-
-enum ArgumentsAllowedFlag {
- ARGUMENTS_NOT_ALLOWED,
- ARGUMENTS_ALLOWED
-};
-
-// This class is not BASE_EMBEDDED because our inlining implementation uses
-// new and delete.
-class AstContext {
- public:
- bool IsEffect() const { return kind_ == Expression::kEffect; }
- bool IsValue() const { return kind_ == Expression::kValue; }
- bool IsTest() const { return kind_ == Expression::kTest; }
-
- // 'Fill' this context with a hydrogen value. The value is assumed to
- // have already been inserted in the instruction stream (or not need to
- // be, e.g., HPhi). Call this function in tail position in the Visit
- // functions for expressions.
- virtual void ReturnValue(HValue* value) = 0;
-
- // Add a hydrogen instruction to the instruction stream (recording an
- // environment simulation if necessary) and then fill this context with
- // the instruction as value.
- virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id) = 0;
-
- // Finishes the current basic block and materialize a boolean for
- // value context, nothing for effect, generate a branch for test context.
- // Call this function in tail position in the Visit functions for
- // expressions.
- virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id) = 0;
-
- void set_for_typeof(bool for_typeof) { for_typeof_ = for_typeof; }
- bool is_for_typeof() { return for_typeof_; }
-
- protected:
- AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind);
- virtual ~AstContext();
-
- HOptimizedGraphBuilder* owner() const { return owner_; }
-
- inline Zone* zone() const;
-
- // We want to be able to assert, in a context-specific way, that the stack
- // height makes sense when the context is filled.
-#ifdef DEBUG
- int original_length_;
-#endif
-
- private:
- HOptimizedGraphBuilder* owner_;
- Expression::Context kind_;
- AstContext* outer_;
- bool for_typeof_;
-};
-
-
-class EffectContext: public AstContext {
- public:
- explicit EffectContext(HOptimizedGraphBuilder* owner)
- : AstContext(owner, Expression::kEffect) {
- }
- virtual ~EffectContext();
-
- virtual void ReturnValue(HValue* value);
- virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id);
- virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id);
-};
-
-
-class ValueContext: public AstContext {
- public:
- ValueContext(HOptimizedGraphBuilder* owner, ArgumentsAllowedFlag flag)
- : AstContext(owner, Expression::kValue), flag_(flag) {
- }
- virtual ~ValueContext();
-
- virtual void ReturnValue(HValue* value);
- virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id);
- virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id);
-
- bool arguments_allowed() { return flag_ == ARGUMENTS_ALLOWED; }
-
- private:
- ArgumentsAllowedFlag flag_;
-};
-
-
-class TestContext: public AstContext {
- public:
- TestContext(HOptimizedGraphBuilder* owner,
- Expression* condition,
- TypeFeedbackOracle* oracle,
- HBasicBlock* if_true,
- HBasicBlock* if_false)
- : AstContext(owner, Expression::kTest),
- condition_(condition),
- oracle_(oracle),
- if_true_(if_true),
- if_false_(if_false) {
- }
-
- virtual void ReturnValue(HValue* value);
- virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id);
- virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id);
-
- static TestContext* cast(AstContext* context) {
- ASSERT(context->IsTest());
- return reinterpret_cast<TestContext*>(context);
- }
-
- Expression* condition() const { return condition_; }
- TypeFeedbackOracle* oracle() const { return oracle_; }
- HBasicBlock* if_true() const { return if_true_; }
- HBasicBlock* if_false() const { return if_false_; }
-
- private:
- // Build the shared core part of the translation unpacking a value into
- // control flow.
- void BuildBranch(HValue* value);
-
- Expression* condition_;
- TypeFeedbackOracle* oracle_;
- HBasicBlock* if_true_;
- HBasicBlock* if_false_;
-};
-
-
-class FunctionState {
- public:
- FunctionState(HOptimizedGraphBuilder* owner,
- CompilationInfo* info,
- TypeFeedbackOracle* oracle,
- InliningKind inlining_kind);
- ~FunctionState();
-
- CompilationInfo* compilation_info() { return compilation_info_; }
- TypeFeedbackOracle* oracle() { return oracle_; }
- AstContext* call_context() { return call_context_; }
- InliningKind inlining_kind() const { return inlining_kind_; }
- HBasicBlock* function_return() { return function_return_; }
- TestContext* test_context() { return test_context_; }
- void ClearInlinedTestContext() {
- delete test_context_;
- test_context_ = NULL;
- }
-
- FunctionState* outer() { return outer_; }
-
- HEnterInlined* entry() { return entry_; }
- void set_entry(HEnterInlined* entry) { entry_ = entry; }
-
- HArgumentsElements* arguments_elements() { return arguments_elements_; }
- void set_arguments_elements(HArgumentsElements* arguments_elements) {
- arguments_elements_ = arguments_elements;
- }
-
- bool arguments_pushed() { return arguments_elements() != NULL; }
-
- private:
- HOptimizedGraphBuilder* owner_;
-
- CompilationInfo* compilation_info_;
- TypeFeedbackOracle* oracle_;
-
- // During function inlining, expression context of the call being
- // inlined. NULL when not inlining.
- AstContext* call_context_;
-
- // The kind of call which is currently being inlined.
- InliningKind inlining_kind_;
-
- // When inlining in an effect or 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_;
-
- // When inlining HEnterInlined instruction corresponding to the function
- // entry.
- HEnterInlined* entry_;
-
- HArgumentsElements* arguments_elements_;
-
- FunctionState* outer_;
-};
-
-
-class HGraphBuilder {
- public:
- explicit HGraphBuilder(CompilationInfo* info)
- : info_(info), graph_(NULL), current_block_(NULL) {}
- virtual ~HGraphBuilder() {}
-
- HBasicBlock* current_block() const { return current_block_; }
- void set_current_block(HBasicBlock* block) { current_block_ = block; }
- HEnvironment* environment() const {
- return current_block()->last_environment();
- }
- Zone* zone() const { return info_->zone(); }
- HGraph* graph() { return graph_; }
-
- HGraph* CreateGraph();
-
- // Adding instructions.
- HInstruction* AddInstruction(HInstruction* instr);
- void AddSimulate(BailoutId id,
- RemovableSimulate removable = FIXED_SIMULATE);
- HBoundsCheck* AddBoundsCheck(
- HValue* index,
- HValue* length,
- BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY,
- Representation r = Representation::None());
-
- protected:
- virtual bool BuildGraph() = 0;
-
- HBasicBlock* CreateBasicBlock(HEnvironment* env);
- HBasicBlock* CreateLoopHeaderBlock();
-
- // Building common constructs
- HInstruction* BuildExternalArrayElementAccess(
- HValue* external_elements,
- HValue* checked_key,
- HValue* val,
- HValue* dependency,
- ElementsKind elements_kind,
- bool is_store);
-
- HInstruction* BuildFastElementAccess(
- HValue* elements,
- HValue* checked_key,
- HValue* val,
- HValue* dependency,
- ElementsKind elements_kind,
- bool is_store);
-
- HInstruction* BuildUncheckedMonomorphicElementAccess(
- HValue* object,
- HValue* key,
- HValue* val,
- HCheckMaps* mapcheck,
- bool is_js_array,
- ElementsKind elements_kind,
- bool is_store,
- Representation checked_index_representation = Representation::None());
-
- HInstruction* BuildStoreMap(HValue* object, HValue* map, BailoutId id);
- HInstruction* BuildStoreMap(HValue* object, Handle<Map> map, BailoutId id);
-
- class CheckBuilder {
- public:
- CheckBuilder(HGraphBuilder* builder, BailoutId id);
- ~CheckBuilder() {
- if (!finished_) End();
- }
-
- void CheckNotUndefined(HValue* value);
- void CheckIntegerEq(HValue* left, HValue* right);
- void End();
-
- private:
- Zone* zone() { return builder_->zone(); }
-
- HGraphBuilder* builder_;
- bool finished_;
- HBasicBlock* failure_block_;
- HBasicBlock* merge_block_;
- BailoutId id_;
- };
-
- class IfBuilder {
- public:
- IfBuilder(HGraphBuilder* builder, BailoutId id);
- ~IfBuilder() {
- if (!finished_) End();
- }
-
- HInstruction* BeginTrue(
- HValue* left,
- HValue* right,
- Token::Value token,
- Representation input_representation = Representation::Integer32());
- void BeginFalse();
- void End();
-
- private:
- Zone* zone() { return builder_->zone(); }
-
- HGraphBuilder* builder_;
- bool finished_;
- HBasicBlock* first_true_block_;
- HBasicBlock* last_true_block_;
- HBasicBlock* first_false_block_;
- HBasicBlock* merge_block_;
- BailoutId id_;
- };
-
- class LoopBuilder {
- public:
- enum Direction {
- kPreIncrement,
- kPostIncrement,
- kPreDecrement,
- kPostDecrement
- };
-
- LoopBuilder(HGraphBuilder* builder,
- HValue* context,
- Direction direction,
- BailoutId id);
- ~LoopBuilder() {
- ASSERT(finished_);
- }
-
- HValue* BeginBody(
- HValue* initial,
- HValue* terminating,
- Token::Value token,
- Representation input_representation = Representation::Integer32());
- void EndBody();
-
- private:
- Zone* zone() { return builder_->zone(); }
-
- HGraphBuilder* builder_;
- HValue* context_;
- HInstruction* increment_;
- HPhi* phi_;
- HBasicBlock* header_block_;
- HBasicBlock* body_block_;
- HBasicBlock* exit_block_;
- Direction direction_;
- BailoutId id_;
- bool finished_;
- };
-
- HValue* BuildAllocateElements(HContext* context,
- ElementsKind kind,
- HValue* capacity);
-
- void BuildCopyElements(HContext* context,
- HValue* from_elements,
- ElementsKind from_elements_kind,
- HValue* to_elements,
- ElementsKind to_elements_kind,
- HValue* length);
-
- private:
- HGraphBuilder();
- CompilationInfo* info_;
- HGraph* graph_;
- HBasicBlock* current_block_;
-};
-
-
-class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor {
- public:
- enum BreakType { BREAK, CONTINUE };
- enum SwitchType { UNKNOWN_SWITCH, SMI_SWITCH, STRING_SWITCH };
-
- // 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,
- int drop_extra = 0)
- : target_(target),
- break_block_(NULL),
- continue_block_(NULL),
- drop_extra_(drop_extra) {
- }
-
- 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; }
- int drop_extra() { return drop_extra_; }
-
- private:
- BreakableStatement* target_;
- HBasicBlock* break_block_;
- HBasicBlock* continue_block_;
- int drop_extra_;
- };
-
- // A helper class to maintain a stack of current BreakAndContinueInfo
- // structures mirroring BreakableStatement nesting.
- class BreakAndContinueScope BASE_EMBEDDED {
- public:
- BreakAndContinueScope(BreakAndContinueInfo* info,
- HOptimizedGraphBuilder* owner)
- : info_(info), owner_(owner), next_(owner->break_scope()) {
- owner->set_break_scope(this);
- }
-
- ~BreakAndContinueScope() { owner_->set_break_scope(next_); }
-
- BreakAndContinueInfo* info() { return info_; }
- HOptimizedGraphBuilder* owner() { return owner_; }
- BreakAndContinueScope* next() { return next_; }
-
- // Search the break stack for a break or continue target.
- HBasicBlock* Get(BreakableStatement* stmt, BreakType type, int* drop_extra);
-
- private:
- BreakAndContinueInfo* info_;
- HOptimizedGraphBuilder* owner_;
- BreakAndContinueScope* next_;
- };
-
- HOptimizedGraphBuilder(CompilationInfo* info, TypeFeedbackOracle* oracle);
-
- virtual bool BuildGraph();
-
- // Simple accessors.
- BreakAndContinueScope* break_scope() const { return break_scope_; }
- void set_break_scope(BreakAndContinueScope* head) { break_scope_ = head; }
-
- bool inline_bailout() { return inline_bailout_; }
-
- void AddSoftDeoptimize();
-
- // Bailout environment manipulation.
- void Push(HValue* value) { environment()->Push(value); }
- HValue* Pop() { return environment()->Pop(); }
-
- void Bailout(const char* reason);
-
- HBasicBlock* CreateJoin(HBasicBlock* first,
- HBasicBlock* second,
- BailoutId join_id);
-
- TypeFeedbackOracle* oracle() const { return function_state()->oracle(); }
-
- FunctionState* function_state() const { return function_state_; }
-
- void VisitDeclarations(ZoneList<Declaration*>* declarations);
-
- void* operator new(size_t size, Zone* zone) {
- return zone->New(static_cast<int>(size));
- }
- void operator delete(void* pointer, Zone* zone) { }
- void operator delete(void* pointer) { }
-
- DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
-
- private:
- // Type of a member function that generates inline code for a native function.
- typedef void (HOptimizedGraphBuilder::*InlineFunctionGenerator)
- (CallRuntime* call);
-
- // Forward declarations for inner scope classes.
- class SubgraphScope;
-
- static const InlineFunctionGenerator kInlineFunctionGenerators[];
-
- static const int kMaxCallPolymorphism = 4;
- static const int kMaxLoadPolymorphism = 4;
- static const int kMaxStorePolymorphism = 4;
-
- // Even in the 'unlimited' case we have to have some limit in order not to
- // overflow the stack.
- static const int kUnlimitedMaxInlinedSourceSize = 100000;
- static const int kUnlimitedMaxInlinedNodes = 10000;
- static const int kUnlimitedMaxInlinedNodesCumulative = 10000;
-
- // Simple accessors.
- 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; }
-
- // Accessors forwarded to the function state.
- CompilationInfo* info() const {
- return function_state()->compilation_info();
- }
- 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();
- }
- StrictModeFlag function_strict_mode_flag() {
- return function_state()->compilation_info()->is_classic_mode()
- ? kNonStrictMode : kStrictMode;
- }
-
- // Generators for inline runtime functions.
-#define INLINE_FUNCTION_GENERATOR_DECLARATION(Name, argc, ressize) \
- void Generate##Name(CallRuntime* call);
-
- INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION)
- INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION)
-#undef INLINE_FUNCTION_GENERATOR_DECLARATION
-
- void VisitDelete(UnaryOperation* expr);
- void VisitVoid(UnaryOperation* expr);
- void VisitTypeof(UnaryOperation* expr);
- void VisitAdd(UnaryOperation* expr);
- void VisitSub(UnaryOperation* expr);
- void VisitBitNot(UnaryOperation* expr);
- void VisitNot(UnaryOperation* expr);
-
- void VisitComma(BinaryOperation* expr);
- void VisitLogicalExpression(BinaryOperation* expr);
- 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);
-
- // 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); }
-
- // The value of the arguments object is allowed in some but not most value
- // contexts. (It's allowed in all effect contexts and disallowed in all
- // test contexts.)
- void VisitForValue(Expression* expr,
- ArgumentsAllowedFlag flag = ARGUMENTS_NOT_ALLOWED);
- void VisitForTypeOf(Expression* expr);
- void VisitForEffect(Expression* expr);
- void VisitForControl(Expression* expr,
- HBasicBlock* true_block,
- HBasicBlock* false_block);
-
- // 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.
- template <class Instruction> HInstruction* PreProcessCall(Instruction* call);
-
- static Representation ToRepresentation(TypeInfo info);
-
- void SetUpScope(Scope* scope);
- virtual void VisitStatements(ZoneList<Statement*>* statements);
-
-#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
- AST_NODE_LIST(DECLARE_VISIT)
-#undef DECLARE_VISIT
-
- // Helpers for flow graph construction.
- enum GlobalPropertyAccess {
- kUseCell,
- kUseGeneric
- };
- GlobalPropertyAccess LookupGlobalProperty(Variable* var,
- LookupResult* lookup,
- bool is_store);
-
- void EnsureArgumentsArePushedForAccess();
- bool TryArgumentsAccess(Property* expr);
-
- // Try to optimize fun.apply(receiver, arguments) pattern.
- bool TryCallApply(Call* expr);
-
- int InliningAstSize(Handle<JSFunction> target);
- bool TryInline(CallKind call_kind,
- Handle<JSFunction> target,
- int arguments_count,
- HValue* implicit_return_value,
- BailoutId ast_id,
- BailoutId return_id,
- InliningKind inlining_kind);
-
- bool TryInlineCall(Call* expr, bool drop_extra = false);
- bool TryInlineConstruct(CallNew* expr, HValue* implicit_return_value);
- bool TryInlineGetter(Handle<JSFunction> getter, Property* prop);
- bool TryInlineSetter(Handle<JSFunction> setter,
- Assignment* assignment,
- HValue* implicit_return_value);
- bool TryInlineApply(Handle<JSFunction> function,
- Call* expr,
- int arguments_count);
- bool TryInlineBuiltinMethodCall(Call* expr,
- HValue* receiver,
- Handle<Map> receiver_map,
- CheckType check_type);
- bool TryInlineBuiltinFunctionCall(Call* expr, bool drop_extra);
-
- // 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,
- Handle<JSFunction> caller,
- const char* failure_reason);
-
- void HandleGlobalVariableAssignment(Variable* var,
- HValue* value,
- int position,
- BailoutId ast_id);
-
- void HandlePropertyAssignment(Assignment* expr);
- void HandleCompoundAssignment(Assignment* expr);
- void HandlePolymorphicLoadNamedField(Property* expr,
- HValue* object,
- SmallMapList* types,
- Handle<String> name);
- void HandlePolymorphicStoreNamedField(Assignment* expr,
- HValue* object,
- HValue* value,
- SmallMapList* types,
- Handle<String> name);
- void HandlePolymorphicCallNamed(Call* expr,
- HValue* receiver,
- SmallMapList* types,
- Handle<String> name);
- void HandleLiteralCompareTypeof(CompareOperation* expr,
- HTypeof* typeof_expr,
- Handle<String> check);
- void HandleLiteralCompareNil(CompareOperation* expr,
- HValue* value,
- NilValue nil);
-
- HInstruction* BuildStringCharCodeAt(HValue* context,
- HValue* string,
- HValue* index);
- HInstruction* BuildBinaryOperation(BinaryOperation* expr,
- HValue* left,
- HValue* right);
- HInstruction* BuildIncrement(bool returns_original_input,
- CountOperation* expr);
- HInstruction* BuildLoadKeyedGeneric(HValue* object,
- HValue* key);
-
- HInstruction* TryBuildConsolidatedElementLoad(HValue* object,
- HValue* key,
- HValue* val,
- SmallMapList* maps);
-
- HInstruction* BuildMonomorphicElementAccess(HValue* object,
- HValue* key,
- HValue* val,
- HValue* dependency,
- Handle<Map> map,
- bool is_store);
-
- HValue* HandlePolymorphicElementAccess(HValue* object,
- HValue* key,
- HValue* val,
- Expression* prop,
- BailoutId ast_id,
- int position,
- bool is_store,
- bool* has_side_effects);
-
- HValue* HandleKeyedElementAccess(HValue* obj,
- HValue* key,
- HValue* val,
- Expression* expr,
- BailoutId ast_id,
- int position,
- bool is_store,
- bool* has_side_effects);
-
- HLoadNamedField* BuildLoadNamedField(HValue* object,
- Handle<Map> map,
- LookupResult* result);
- HInstruction* BuildLoadNamedGeneric(HValue* object,
- Handle<String> name,
- Property* expr);
- HInstruction* BuildCallGetter(HValue* object,
- Handle<Map> map,
- Handle<JSFunction> getter,
- Handle<JSObject> holder);
- HInstruction* BuildLoadNamedMonomorphic(HValue* object,
- Handle<String> name,
- Property* expr,
- Handle<Map> map);
-
- void AddCheckMapsWithTransitions(HValue* object,
- Handle<Map> map);
-
- HInstruction* BuildStoreNamedField(HValue* object,
- Handle<String> name,
- HValue* value,
- Handle<Map> map,
- LookupResult* lookup);
- HInstruction* BuildStoreNamedGeneric(HValue* object,
- Handle<String> name,
- HValue* value);
- HInstruction* BuildCallSetter(HValue* object,
- HValue* value,
- Handle<Map> map,
- Handle<JSFunction> setter,
- Handle<JSObject> holder);
- HInstruction* BuildStoreNamedMonomorphic(HValue* object,
- Handle<String> name,
- HValue* value,
- Handle<Map> map);
- HInstruction* BuildStoreKeyedGeneric(HValue* object,
- HValue* key,
- HValue* value);
-
- HValue* BuildContextChainWalk(Variable* var);
-
- HInstruction* BuildThisFunction();
-
- void AddCheckPrototypeMaps(Handle<JSObject> holder,
- Handle<Map> receiver_map);
-
- void AddCheckConstantFunction(Handle<JSObject> holder,
- HValue* receiver,
- Handle<Map> receiver_map);
-
- bool MatchRotateRight(HValue* left,
- HValue* right,
- HValue** operand,
- HValue** shift_amount);
-
- // The translation state of the currently-being-translated function.
- FunctionState* function_state_;
-
- // 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_;
-
- // A stack of breakable statements entered.
- BreakAndContinueScope* break_scope_;
-
- int inlined_count_;
- ZoneList<Handle<Object> > globals_;
-
- bool inline_bailout_;
-
- friend class FunctionState; // Pushes and pops the state stack.
- friend class AstContext; // Pushes and pops the AST context stack.
- friend class KeyedLoadFastElementStub;
-
- DISALLOW_COPY_AND_ASSIGN(HOptimizedGraphBuilder);
-};
-
-
-Zone* AstContext::zone() const { return owner_->zone(); }
-
-
-class HValueMap: public ZoneObject {
- public:
- explicit HValueMap(Zone* zone)
- : array_size_(0),
- lists_size_(0),
- count_(0),
- present_flags_(0),
- array_(NULL),
- lists_(NULL),
- free_list_head_(kNil) {
- ResizeLists(kInitialSize, zone);
- Resize(kInitialSize, zone);
- }
-
- void Kill(GVNFlagSet flags);
-
- void Add(HValue* value, Zone* zone) {
- present_flags_.Add(value->gvn_flags());
- Insert(value, zone);
- }
-
- HValue* Lookup(HValue* value) const;
-
- HValueMap* Copy(Zone* zone) const {
- return new(zone) HValueMap(zone, this);
- }
-
- bool IsEmpty() const { return count_ == 0; }
-
- private:
- // A linked list of HValue* values. Stored in arrays.
- struct HValueMapListElement {
- HValue* value;
- int next; // Index in the array of the next list element.
- };
- static const int kNil = -1; // The end of a linked list
-
- // Must be a power of 2.
- static const int kInitialSize = 16;
-
- HValueMap(Zone* zone, const HValueMap* other);
-
- void Resize(int new_size, Zone* zone);
- void ResizeLists(int new_size, Zone* zone);
- void Insert(HValue* value, Zone* zone);
- uint32_t Bound(uint32_t value) const { return value & (array_size_ - 1); }
-
- int array_size_;
- int lists_size_;
- int count_; // The number of values stored in the HValueMap.
- GVNFlagSet present_flags_; // All flags that are in any value in the
- // HValueMap.
- HValueMapListElement* array_; // Primary store - contains the first value
- // with a given hash. Colliding elements are stored in linked lists.
- HValueMapListElement* lists_; // The linked lists containing hash collisions.
- int free_list_head_; // Unused elements in lists_ are on the free list.
-};
-
-
-class HSideEffectMap BASE_EMBEDDED {
- public:
- HSideEffectMap();
- explicit HSideEffectMap(HSideEffectMap* other);
- HSideEffectMap& operator= (const HSideEffectMap& other);
-
- void Kill(GVNFlagSet flags);
-
- void Store(GVNFlagSet flags, HInstruction* instr);
-
- bool IsEmpty() const { return count_ == 0; }
-
- inline HInstruction* operator[](int i) const {
- ASSERT(0 <= i);
- ASSERT(i < kNumberOfTrackedSideEffects);
- return data_[i];
- }
- inline HInstruction* at(int i) const { return operator[](i); }
-
- private:
- int count_;
- HInstruction* data_[kNumberOfTrackedSideEffects];
-};
-
-
-class HStatistics: public Malloced {
- public:
- void Initialize(CompilationInfo* info);
- void Print();
- void SaveTiming(const char* name, int64_t ticks, unsigned size);
- static HStatistics* Instance() {
- static SetOncePointer<HStatistics> instance;
- if (!instance.is_set()) {
- instance.set(new HStatistics());
- }
- return instance.get();
- }
-
- void IncrementSubtotals(int64_t create_graph,
- int64_t optimize_graph,
- int64_t generate_code) {
- create_graph_ += create_graph;
- optimize_graph_ += optimize_graph;
- generate_code_ += generate_code;
- }
-
- private:
- HStatistics()
- : timing_(5),
- names_(5),
- sizes_(5),
- create_graph_(0),
- optimize_graph_(0),
- generate_code_(0),
- total_size_(0),
- full_code_gen_(0),
- source_size_(0) { }
-
- List<int64_t> timing_;
- List<const char*> names_;
- List<unsigned> sizes_;
- int64_t create_graph_;
- int64_t optimize_graph_;
- int64_t generate_code_;
- unsigned total_size_;
- int64_t full_code_gen_;
- double source_size_;
-};
-
-
-class HPhase BASE_EMBEDDED {
- public:
- static const char* const kFullCodeGen;
-
- explicit HPhase(const char* name) { Begin(name, NULL, NULL, NULL); }
- HPhase(const char* name, HGraph* graph) {
- Begin(name, graph, NULL, NULL);
- }
- HPhase(const char* name, LChunk* chunk) {
- Begin(name, NULL, chunk, NULL);
- }
- HPhase(const char* name, LAllocator* allocator) {
- Begin(name, NULL, NULL, allocator);
- }
-
- ~HPhase() {
- End();
- }
-
- private:
- void Begin(const char* name,
- HGraph* graph,
- LChunk* chunk,
- LAllocator* allocator);
- void End() const;
-
- int64_t start_;
- const char* name_;
- HGraph* graph_;
- LChunk* chunk_;
- LAllocator* allocator_;
- unsigned start_allocation_size_;
-};
-
-
-class HTracer: public Malloced {
- public:
- void TraceCompilation(CompilationInfo* info);
- void TraceHydrogen(const char* name, HGraph* graph);
- void TraceLithium(const char* name, LChunk* chunk);
- void TraceLiveRanges(const char* name, LAllocator* allocator);
-
- static HTracer* Instance() {
- static SetOncePointer<HTracer> instance;
- if (!instance.is_set()) {
- instance.set(new HTracer("hydrogen.cfg"));
- }
- return instance.get();
- }
-
- private:
- class Tag BASE_EMBEDDED {
- public:
- Tag(HTracer* tracer, const char* name) {
- name_ = name;
- tracer_ = tracer;
- tracer->PrintIndent();
- tracer->trace_.Add("begin_%s\n", name);
- tracer->indent_++;
- }
-
- ~Tag() {
- tracer_->indent_--;
- tracer_->PrintIndent();
- tracer_->trace_.Add("end_%s\n", name_);
- ASSERT(tracer_->indent_ >= 0);
- tracer_->FlushToFile();
- }
-
- private:
- HTracer* tracer_;
- const char* name_;
- };
-
- explicit HTracer(const char* filename)
- : filename_(filename), trace_(&string_allocator_), indent_(0) {
- WriteChars(filename, "", 0, false);
- }
-
- void TraceLiveRange(LiveRange* range, const char* type, Zone* zone);
- void Trace(const char* name, HGraph* graph, LChunk* chunk);
- void FlushToFile();
-
- void PrintEmptyProperty(const char* name) {
- PrintIndent();
- trace_.Add("%s\n", name);
- }
-
- void PrintStringProperty(const char* name, const char* value) {
- PrintIndent();
- trace_.Add("%s \"%s\"\n", name, value);
- }
-
- void PrintLongProperty(const char* name, int64_t value) {
- PrintIndent();
- trace_.Add("%s %d000\n", name, static_cast<int>(value / 1000));
- }
-
- void PrintBlockProperty(const char* name, int block_id) {
- PrintIndent();
- trace_.Add("%s \"B%d\"\n", name, block_id);
- }
-
- void PrintIntProperty(const char* name, int value) {
- PrintIndent();
- trace_.Add("%s %d\n", name, value);
- }
-
- void PrintIndent() {
- for (int i = 0; i < indent_; i++) {
- trace_.Add(" ");
- }
- }
-
- const char* filename_;
- HeapStringAllocator string_allocator_;
- StringStream trace_;
- int indent_;
-};
-
-
-} } // namespace v8::internal
-
-#endif // V8_HYDROGEN_H_