Index: src/hydrogen.h |
diff --git a/src/hydrogen.h b/src/hydrogen.h |
index 797b444078d5e838157c77e207a956a4b3d056db..895b9849c97d36c16bb6ecdbd6c93f1eb951eb2c 100644 |
--- a/src/hydrogen.h |
+++ b/src/hydrogen.h |
@@ -69,6 +69,11 @@ class HBasicBlock: public ZoneObject { |
void set_last(HInstruction* instr) { last_ = instr; } |
HControlInstruction* end() const { return end_; } |
HLoopInformation* loop_information() const { return loop_information_; } |
+ HLoopInformation* current_loop() const { |
+ return IsLoopHeader() ? loop_information() |
+ : (parent_loop_header() != NULL |
+ ? parent_loop_header()->loop_information() : NULL); |
+ } |
const ZoneList<HBasicBlock*>* predecessors() const { return &predecessors_; } |
bool HasPredecessor() const { return predecessors_.length() > 0; } |
const ZoneList<HBasicBlock*>* dominated_blocks() const { |
@@ -137,17 +142,15 @@ class HBasicBlock: public ZoneObject { |
} |
int PredecessorIndexOf(HBasicBlock* predecessor) const; |
- void AddSimulate(BailoutId ast_id, |
- RemovableSimulate removable = FIXED_SIMULATE) { |
- AddInstruction(CreateSimulate(ast_id, removable)); |
+ HSimulate* AddSimulate(BailoutId ast_id, |
+ RemovableSimulate removable = FIXED_SIMULATE) { |
+ HSimulate* instr = CreateSimulate(ast_id, removable); |
+ AddInstruction(instr); |
+ return instr; |
} |
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); |
@@ -182,11 +185,12 @@ class HBasicBlock: public ZoneObject { |
#endif |
private: |
+ friend class HGraphBuilder; |
+ |
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_; |
@@ -272,6 +276,20 @@ class HLoopInformation: public ZoneObject { |
stack_check_ = stack_check; |
} |
+ bool IsNestedInThisLoop(HLoopInformation* other) { |
+ while (other != NULL) { |
+ if (other == this) { |
+ return true; |
+ } |
+ other = other->parent_loop(); |
+ } |
+ return false; |
+ } |
+ HLoopInformation* parent_loop() { |
+ HBasicBlock* parent_header = loop_header()->parent_loop_header(); |
+ return parent_header != NULL ? parent_header->loop_information() : NULL; |
+ } |
+ |
private: |
void AddBlock(HBasicBlock* block); |
@@ -283,6 +301,7 @@ class HLoopInformation: public ZoneObject { |
class BoundsCheckTable; |
+class InductionVariableBlocksTable; |
class HGraph: public ZoneObject { |
public: |
explicit HGraph(CompilationInfo* info); |
@@ -449,6 +468,7 @@ class HGraph: public ZoneObject { |
void CheckForBackEdge(HBasicBlock* block, HBasicBlock* successor); |
void SetupInformativeDefinitionsInBlock(HBasicBlock* block); |
void SetupInformativeDefinitionsRecursively(HBasicBlock* block); |
+ void EliminateRedundantBoundsChecksUsingInductionVariables(); |
Isolate* isolate_; |
int next_block_id_; |
@@ -1023,11 +1043,6 @@ class HGraphBuilder { |
new(zone()) I(p1, p2, p3, p4, p5, p6, p7, p8))); |
} |
- void AddSimulate(BailoutId id, |
- RemovableSimulate removable = FIXED_SIMULATE); |
- |
- HReturn* AddReturn(HValue* value); |
- |
void IncrementInNoSideEffectsScope() { |
no_side_effects_scope_count_++; |
} |
@@ -1044,6 +1059,7 @@ class HGraphBuilder { |
HValue* BuildCheckHeapObject(HValue* object); |
HValue* BuildCheckMap(HValue* obj, Handle<Map> map); |
+ HValue* BuildWrapReceiver(HValue* object, HValue* function); |
// Building common constructs |
HValue* BuildCheckForCapacityGrow(HValue* object, |
@@ -1078,8 +1094,7 @@ class HGraphBuilder { |
HLoadNamedField* AddLoad( |
HValue *object, |
HObjectAccess access, |
- HValue *typecheck = NULL, |
- Representation representation = Representation::Tagged()); |
+ HValue *typecheck = NULL); |
HLoadNamedField* BuildLoadNamedField( |
HValue* object, |
@@ -1104,26 +1119,19 @@ class HGraphBuilder { |
LoadKeyedHoleMode load_mode, |
KeyedAccessStoreMode store_mode); |
- HStoreNamedField* AddStore( |
- HValue *object, |
- HObjectAccess access, |
- HValue *val, |
- Representation representation = Representation::Tagged()); |
- |
+ HLoadNamedField* BuildLoadNamedField(HValue* object, HObjectAccess access); |
+ HStoreNamedField* AddStore(HValue *object, HObjectAccess access, HValue *val); |
HStoreNamedField* AddStoreMapConstant(HValue *object, Handle<Map>); |
- |
HLoadNamedField* AddLoadElements(HValue *object, HValue *typecheck = NULL); |
- |
HLoadNamedField* AddLoadFixedArrayLength(HValue *object); |
HValue* AddLoadJSBuiltin(Builtins::JavaScript builtin, HValue* context); |
- enum SoftDeoptimizeMode { |
- MUST_EMIT_SOFT_DEOPT, |
- CAN_OMIT_SOFT_DEOPT |
- }; |
+ HValue* TruncateToNumber(HValue* value, Handle<Type>* expected); |
+ |
+ void PushAndAdd(HInstruction* instr); |
- void AddSoftDeoptimize(SoftDeoptimizeMode mode = CAN_OMIT_SOFT_DEOPT); |
+ void FinishExitWithHardDeoptimization(HBasicBlock* continuation); |
class IfBuilder { |
public: |
@@ -1228,7 +1236,6 @@ class HGraphBuilder { |
void ElseDeopt() { |
Else(); |
Deopt(); |
- End(); |
} |
void Return(HValue* value); |
@@ -1241,6 +1248,8 @@ class HGraphBuilder { |
HGraphBuilder* builder_; |
int position_; |
bool finished_ : 1; |
+ bool deopt_then_ : 1; |
+ bool deopt_else_ : 1; |
bool did_then_ : 1; |
bool did_else_ : 1; |
bool did_and_ : 1; |
@@ -1373,6 +1382,7 @@ class HGraphBuilder { |
HInnerAllocatedObject* BuildJSArrayHeader(HValue* array, |
HValue* array_map, |
AllocationSiteMode mode, |
+ ElementsKind elements_kind, |
HValue* allocation_site_payload, |
HValue* length_field); |
@@ -1422,12 +1432,68 @@ class HGraphBuilder { |
private: |
HGraphBuilder(); |
+ |
+ void PadEnvironmentForContinuation(HBasicBlock* from, |
+ HBasicBlock* continuation); |
+ |
CompilationInfo* info_; |
HGraph* graph_; |
HBasicBlock* current_block_; |
int no_side_effects_scope_count_; |
}; |
+ |
+template<> |
+inline HDeoptimize* HGraphBuilder::Add(Deoptimizer::BailoutType type) { |
+ if (type == Deoptimizer::SOFT) { |
+ isolate()->counters()->soft_deopts_requested()->Increment(); |
+ if (FLAG_always_opt) return NULL; |
+ } |
+ if (current_block()->IsDeoptimizing()) return NULL; |
+ HDeoptimize* instr = new(zone()) HDeoptimize(type); |
+ AddInstruction(instr); |
+ if (type == Deoptimizer::SOFT) { |
+ isolate()->counters()->soft_deopts_inserted()->Increment(); |
+ graph()->set_has_soft_deoptimize(true); |
+ } |
+ current_block()->MarkAsDeoptimizing(); |
+ return instr; |
+} |
+ |
+ |
+template<> |
+inline HSimulate* HGraphBuilder::Add(BailoutId id, |
+ RemovableSimulate removable) { |
+ HSimulate* instr = current_block()->CreateSimulate(id, removable); |
+ AddInstruction(instr); |
+ return instr; |
+} |
+ |
+ |
+template<> |
+inline HSimulate* HGraphBuilder::Add(BailoutId id) { |
+ return Add<HSimulate>(id, FIXED_SIMULATE); |
+} |
+ |
+ |
+template<> |
+inline HReturn* HGraphBuilder::Add(HValue* value) { |
+ HValue* context = environment()->LookupContext(); |
+ int num_parameters = graph()->info()->num_parameters(); |
+ HValue* params = Add<HConstant>(num_parameters); |
+ HReturn* return_instruction = new(graph()->zone()) |
+ HReturn(value, context, params); |
+ current_block()->FinishExit(return_instruction); |
+ return return_instruction; |
+} |
+ |
+ |
+template<> |
+inline HReturn* HGraphBuilder::Add(HConstant* p1) { |
+ return Add<HReturn>(static_cast<HValue*>(p1)); |
+} |
+ |
+ |
class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor { |
public: |
// A class encapsulating (lazily-allocated) break and continue blocks for |
@@ -1666,8 +1732,6 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor { |
// Visit a list of expressions from left to right, each in a value context. |
void VisitExpressions(ZoneList<Expression*>* exprs); |
- 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); |
@@ -2021,10 +2085,14 @@ class HTracer: public Malloced { |
public: |
explicit HTracer(int isolate_id) |
: trace_(&string_allocator_), indent_(0) { |
- OS::SNPrintF(filename_, |
- "hydrogen-%d-%d.cfg", |
- OS::GetCurrentProcessId(), |
- isolate_id); |
+ if (FLAG_trace_hydrogen_file == NULL) { |
+ OS::SNPrintF(filename_, |
+ "hydrogen-%d-%d.cfg", |
+ OS::GetCurrentProcessId(), |
+ isolate_id); |
+ } else { |
+ OS::StrNCpy(filename_, FLAG_trace_hydrogen_file, filename_.length()); |
+ } |
WriteChars(filename_.start(), "", 0, false); |
} |