Revert "Revert "Upgrade to 5.0.71.48"" DO NOT MERGE
This reverts commit f2e3994fa5148cc3d9946666f0b0596290192b0e,
and updates the x64 makefile properly so it doesn't break that
build.
FPIIM-449
Change-Id: Ib83e35bfbae6af627451c926a9650ec57c045605
(cherry picked from commit 109988c7ccb6f3fd1a58574fa3dfb88beaef6632)
diff --git a/src/compiler/bytecode-graph-builder.h b/src/compiler/bytecode-graph-builder.h
index 94a278c..2fa5967 100644
--- a/src/compiler/bytecode-graph-builder.h
+++ b/src/compiler/bytecode-graph-builder.h
@@ -23,19 +23,14 @@
JSGraph* jsgraph);
// Creates a graph by visiting bytecodes.
- bool CreateGraph(bool stack_check = true);
-
- Graph* graph() const { return jsgraph_->graph(); }
+ bool CreateGraph();
private:
class Environment;
class FrameStateBeforeAndAfter;
- void CreateGraphBody(bool stack_check);
void VisitBytecodes();
- Node* LoadAccumulator(Node* value);
-
// Get or create the node that represents the outer function closure.
Node* GetFunctionClosure();
@@ -45,13 +40,6 @@
// Get or create the node that represents the incoming new target value.
Node* GetNewTarget();
- // Builder for accessing a (potentially immutable) object field.
- Node* BuildLoadObjectField(Node* object, int offset);
- Node* BuildLoadImmutableObjectField(Node* object, int offset);
-
- // Builder for accessing type feedback vector.
- Node* BuildLoadFeedbackVector();
-
// Builder for loading the a native context field.
Node* BuildLoadNativeContextField(int index);
@@ -111,91 +99,102 @@
Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs,
bool incomplete);
- // Helper to indicate a node exits the function body.
- void UpdateControlDependencyToLeaveFunction(Node* exit);
-
Node** EnsureInputBufferSize(int size);
Node* ProcessCallArguments(const Operator* call_op, Node* callee,
interpreter::Register receiver, size_t arity);
- Node* ProcessCallNewArguments(const Operator* call_new_op,
- interpreter::Register callee,
+ Node* ProcessCallNewArguments(const Operator* call_new_op, Node* callee,
+ Node* new_target,
interpreter::Register first_arg, size_t arity);
Node* ProcessCallRuntimeArguments(const Operator* call_runtime_op,
interpreter::Register first_arg,
size_t arity);
- void BuildCreateLiteral(const Operator* op,
- const interpreter::BytecodeArrayIterator& iterator);
- void BuildCreateRegExpLiteral(
- const interpreter::BytecodeArrayIterator& iterator);
- void BuildCreateArrayLiteral(
- const interpreter::BytecodeArrayIterator& iterator);
- void BuildCreateObjectLiteral(
- const interpreter::BytecodeArrayIterator& iterator);
- void BuildCreateArguments(CreateArgumentsParameters::Type type,
- const interpreter::BytecodeArrayIterator& iterator);
- void BuildLoadGlobal(const interpreter::BytecodeArrayIterator& iterator,
- TypeofMode typeof_mode);
- void BuildStoreGlobal(const interpreter::BytecodeArrayIterator& iterator);
- void BuildNamedLoad(const interpreter::BytecodeArrayIterator& iterator);
- void BuildKeyedLoad(const interpreter::BytecodeArrayIterator& iterator);
- void BuildNamedStore(const interpreter::BytecodeArrayIterator& iterator);
- void BuildKeyedStore(const interpreter::BytecodeArrayIterator& iterator);
- void BuildLdaLookupSlot(TypeofMode typeof_mode,
- const interpreter::BytecodeArrayIterator& iterator);
- void BuildStaLookupSlot(LanguageMode language_mode,
- const interpreter::BytecodeArrayIterator& iterator);
- void BuildCall(const interpreter::BytecodeArrayIterator& iterator);
- void BuildBinaryOp(const Operator* op,
- const interpreter::BytecodeArrayIterator& iterator);
- void BuildCompareOp(const Operator* op,
- const interpreter::BytecodeArrayIterator& iterator);
- void BuildDelete(const interpreter::BytecodeArrayIterator& iterator);
- void BuildCastOperator(const Operator* js_op,
- const interpreter::BytecodeArrayIterator& iterator);
+ void BuildCreateLiteral(const Operator* op);
+ void BuildCreateRegExpLiteral();
+ void BuildCreateArrayLiteral();
+ void BuildCreateObjectLiteral();
+ void BuildCreateArguments(CreateArgumentsType type);
+ void BuildLoadGlobal(TypeofMode typeof_mode);
+ void BuildStoreGlobal(LanguageMode language_mode);
+ void BuildNamedLoad();
+ void BuildKeyedLoad();
+ void BuildNamedStore(LanguageMode language_mode);
+ void BuildKeyedStore(LanguageMode language_mode);
+ void BuildLdaLookupSlot(TypeofMode typeof_mode);
+ void BuildStaLookupSlot(LanguageMode language_mode);
+ void BuildCall(TailCallMode tail_call_mode);
+ void BuildCallJSRuntime();
+ void BuildCallRuntime();
+ void BuildCallRuntimeForPair();
+ void BuildCallConstruct();
+ void BuildThrow();
+ void BuildBinaryOp(const Operator* op);
+ void BuildCompareOp(const Operator* op);
+ void BuildDelete(LanguageMode language_mode);
+ void BuildCastOperator(const Operator* op);
+ void BuildForInPrepare();
+ void BuildForInNext();
// Control flow plumbing.
- void BuildJump(int source_offset, int target_offset);
void BuildJump();
void BuildConditionalJump(Node* condition);
void BuildJumpIfEqual(Node* comperand);
void BuildJumpIfToBooleanEqual(Node* boolean_comperand);
+ void BuildJumpIfNotHole();
- // Constructing merge and loop headers.
- void MergeEnvironmentsOfBackwardBranches(int source_offset,
- int target_offset);
- void MergeEnvironmentsOfForwardBranches(int source_offset);
- void BuildLoopHeaderForBackwardBranches(int source_offset);
+ // Simulates control flow by forward-propagating environments.
+ void MergeIntoSuccessorEnvironment(int target_offset);
+ void BuildLoopHeaderEnvironment(int current_offset);
+ void SwitchToMergeEnvironment(int current_offset);
- // Attaches a frame state to |node| for the entry to the function.
- void PrepareEntryFrameState(Node* node);
+ // Simulates control flow that exits the function body.
+ void MergeControlToLeaveFunction(Node* exit);
+
+ // Simulates entry and exit of exception handlers.
+ void EnterAndExitExceptionHandlers(int current_offset);
// Growth increment for the temporary buffer used to construct input lists to
// new nodes.
static const int kInputBufferSizeIncrement = 64;
+ // The catch prediction from the handler table is reused.
+ typedef HandlerTable::CatchPrediction CatchPrediction;
+
+ // An abstract representation for an exception handler that is being
+ // entered and exited while the graph builder is iterating over the
+ // underlying bytecode. The exception handlers within the bytecode are
+ // well scoped, hence will form a stack during iteration.
+ struct ExceptionHandler {
+ int start_offset_; // Start offset of the handled area in the bytecode.
+ int end_offset_; // End offset of the handled area in the bytecode.
+ int handler_offset_; // Handler entry offset within the bytecode.
+ int context_register_; // Index of register holding handler context.
+ CatchPrediction pred_; // Prediction of whether handler is catching.
+ };
+
// Field accessors
+ Graph* graph() const { return jsgraph_->graph(); }
CommonOperatorBuilder* common() const { return jsgraph_->common(); }
Zone* graph_zone() const { return graph()->zone(); }
- CompilationInfo* info() const { return info_; }
JSGraph* jsgraph() const { return jsgraph_; }
JSOperatorBuilder* javascript() const { return jsgraph_->javascript(); }
Zone* local_zone() const { return local_zone_; }
const Handle<BytecodeArray>& bytecode_array() const {
return bytecode_array_;
}
+ const Handle<HandlerTable>& exception_handler_table() const {
+ return exception_handler_table_;
+ }
+ const Handle<TypeFeedbackVector>& feedback_vector() const {
+ return feedback_vector_;
+ }
const FrameStateFunctionInfo* frame_state_function_info() const {
return frame_state_function_info_;
}
- LanguageMode language_mode() const {
- // TODO(mythria): Don't rely on parse information to get language mode.
- return info()->language_mode();
- }
-
- const interpreter::BytecodeArrayIterator* bytecode_iterator() const {
- return bytecode_iterator_;
+ const interpreter::BytecodeArrayIterator& bytecode_iterator() const {
+ return *bytecode_iterator_;
}
void set_bytecode_iterator(
@@ -211,28 +210,32 @@
branch_analysis_ = branch_analysis;
}
-#define DECLARE_VISIT_BYTECODE(name, ...) \
- void Visit##name(const interpreter::BytecodeArrayIterator& iterator);
+#define DECLARE_VISIT_BYTECODE(name, ...) void Visit##name();
BYTECODE_LIST(DECLARE_VISIT_BYTECODE)
#undef DECLARE_VISIT_BYTECODE
Zone* local_zone_;
- CompilationInfo* info_;
JSGraph* jsgraph_;
Handle<BytecodeArray> bytecode_array_;
+ Handle<HandlerTable> exception_handler_table_;
+ Handle<TypeFeedbackVector> feedback_vector_;
const FrameStateFunctionInfo* frame_state_function_info_;
const interpreter::BytecodeArrayIterator* bytecode_iterator_;
const BytecodeBranchAnalysis* branch_analysis_;
Environment* environment_;
+ // Indicates whether deoptimization support is enabled for this compilation
+ // and whether valid frame states need to be attached to deoptimizing nodes.
+ bool deoptimization_enabled_;
- // Merge environments are snapshots of the environment at a particular
- // bytecode offset to be merged into a later environment.
+ // Merge environments are snapshots of the environment at points where the
+ // control flow merges. This models a forward data flow propagation of all
+ // values from all predecessors of the merge in question.
ZoneMap<int, Environment*> merge_environments_;
- // Loop header environments are environments created for bytecodes
- // where it is known there are back branches, ie a loop header.
- ZoneMap<int, Environment*> loop_header_environments_;
+ // Exception handlers currently entered by the iteration.
+ ZoneStack<ExceptionHandler> exception_handlers_;
+ int current_exception_handler_;
// Temporary storage for building node input lists.
int input_buffer_size_;
@@ -243,100 +246,12 @@
SetOncePointer<Node> function_closure_;
SetOncePointer<Node> new_target_;
- // Optimization to cache loaded feedback vector.
- SetOncePointer<Node> feedback_vector_;
-
// Control nodes that exit the function body.
ZoneVector<Node*> exit_controls_;
DISALLOW_COPY_AND_ASSIGN(BytecodeGraphBuilder);
};
-
-class BytecodeGraphBuilder::Environment : public ZoneObject {
- public:
- Environment(BytecodeGraphBuilder* builder, int register_count,
- int parameter_count, Node* control_dependency, Node* context);
-
- int parameter_count() const { return parameter_count_; }
- int register_count() const { return register_count_; }
-
- Node* LookupAccumulator() const;
- Node* LookupRegister(interpreter::Register the_register) const;
-
- void ExchangeRegisters(interpreter::Register reg0,
- interpreter::Register reg1);
-
- void BindAccumulator(Node* node, FrameStateBeforeAndAfter* states = nullptr);
- void BindRegister(interpreter::Register the_register, Node* node,
- FrameStateBeforeAndAfter* states = nullptr);
- void BindRegistersToProjections(interpreter::Register first_reg, Node* node,
- FrameStateBeforeAndAfter* states = nullptr);
- void RecordAfterState(Node* node, FrameStateBeforeAndAfter* states);
-
- bool IsMarkedAsUnreachable() const;
- void MarkAsUnreachable();
-
- // Effect dependency tracked by this environment.
- Node* GetEffectDependency() { return effect_dependency_; }
- void UpdateEffectDependency(Node* dependency) {
- effect_dependency_ = dependency;
- }
-
- // Preserve a checkpoint of the environment for the IR graph. Any
- // further mutation of the environment will not affect checkpoints.
- Node* Checkpoint(BailoutId bytecode_offset, OutputFrameStateCombine combine);
-
- // Returns true if the state values are up to date with the current
- // environment.
- bool StateValuesAreUpToDate(int output_poke_offset, int output_poke_count);
-
- // Control dependency tracked by this environment.
- Node* GetControlDependency() const { return control_dependency_; }
- void UpdateControlDependency(Node* dependency) {
- control_dependency_ = dependency;
- }
-
- Node* Context() const { return context_; }
- void SetContext(Node* new_context) { context_ = new_context; }
-
- Environment* CopyForConditional() const;
- Environment* CopyForLoop();
- void Merge(Environment* other);
-
- private:
- explicit Environment(const Environment* copy);
- void PrepareForLoop();
- bool StateValuesAreUpToDate(Node** state_values, int offset, int count,
- int output_poke_start, int output_poke_end);
- bool StateValuesRequireUpdate(Node** state_values, int offset, int count);
- void UpdateStateValues(Node** state_values, int offset, int count);
-
- int RegisterToValuesIndex(interpreter::Register the_register) const;
-
- Zone* zone() const { return builder_->local_zone(); }
- Graph* graph() const { return builder_->graph(); }
- CommonOperatorBuilder* common() const { return builder_->common(); }
- BytecodeGraphBuilder* builder() const { return builder_; }
- const NodeVector* values() const { return &values_; }
- NodeVector* values() { return &values_; }
- int register_base() const { return register_base_; }
- int accumulator_base() const { return accumulator_base_; }
-
- BytecodeGraphBuilder* builder_;
- int register_count_;
- int parameter_count_;
- Node* context_;
- Node* control_dependency_;
- Node* effect_dependency_;
- NodeVector values_;
- Node* parameters_state_values_;
- Node* registers_state_values_;
- Node* accumulator_state_values_;
- int register_base_;
- int accumulator_base_;
-};
-
} // namespace compiler
} // namespace internal
} // namespace v8