summaryrefslogtreecommitdiff
path: root/deps/v8/src/full-codegen.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/full-codegen.h')
-rw-r--r--deps/v8/src/full-codegen.h126
1 files changed, 109 insertions, 17 deletions
diff --git a/deps/v8/src/full-codegen.h b/deps/v8/src/full-codegen.h
index 97a56bd90..8d9fe2d33 100644
--- a/deps/v8/src/full-codegen.h
+++ b/deps/v8/src/full-codegen.h
@@ -31,6 +31,8 @@
#include "v8.h"
#include "ast.h"
+#include "code-stubs.h"
+#include "codegen.h"
#include "compiler.h"
namespace v8 {
@@ -66,17 +68,39 @@ class BreakableStatementChecker: public AstVisitor {
class FullCodeGenerator: public AstVisitor {
public:
+ enum State {
+ NO_REGISTERS,
+ TOS_REG
+ };
+
explicit FullCodeGenerator(MacroAssembler* masm)
: masm_(masm),
info_(NULL),
nesting_stack_(NULL),
loop_depth_(0),
- context_(NULL) {
+ context_(NULL),
+ bailout_entries_(0),
+ stack_checks_(2), // There's always at least one.
+ forward_bailout_stack_(NULL),
+ forward_bailout_pending_(NULL) {
}
static bool MakeCode(CompilationInfo* info);
void Generate(CompilationInfo* info);
+ void PopulateDeoptimizationData(Handle<Code> code);
+
+ class StateField : public BitField<State, 0, 8> { };
+ class PcField : public BitField<unsigned, 8, 32-8> { };
+
+ static const char* State2String(State state) {
+ switch (state) {
+ case NO_REGISTERS: return "NO_REGISTERS";
+ case TOS_REG: return "TOS_REG";
+ }
+ UNREACHABLE();
+ return NULL;
+ }
private:
class Breakable;
@@ -229,6 +253,24 @@ class FullCodeGenerator: public AstVisitor {
DISALLOW_COPY_AND_ASSIGN(ForIn);
};
+ // The forward bailout stack keeps track of the expressions that can
+ // bail out to just before the control flow is split in a child
+ // node. The stack elements are linked together through the parent
+ // link when visiting expressions in test contexts after requesting
+ // bailout in child forwarding.
+ class ForwardBailoutStack BASE_EMBEDDED {
+ public:
+ ForwardBailoutStack(Expression* expr, ForwardBailoutStack* parent)
+ : expr_(expr), parent_(parent) { }
+
+ Expression* expr() const { return expr_; }
+ ForwardBailoutStack* parent() const { return parent_; }
+
+ private:
+ Expression* const expr_;
+ ForwardBailoutStack* const parent_;
+ };
+
enum ConstantOperand {
kNoConstants,
kLeftConstant,
@@ -274,19 +316,23 @@ class FullCodeGenerator: public AstVisitor {
// register.
MemOperand EmitSlotSearch(Slot* slot, Register scratch);
+ // Forward the bailout responsibility for the given expression to
+ // the next child visited (which must be in a test context).
+ void ForwardBailoutToChild(Expression* expr);
+
void VisitForEffect(Expression* expr) {
EffectContext context(this);
- Visit(expr);
+ HandleInNonTestContext(expr, NO_REGISTERS);
}
void VisitForAccumulatorValue(Expression* expr) {
AccumulatorValueContext context(this);
- Visit(expr);
+ HandleInNonTestContext(expr, TOS_REG);
}
void VisitForStackValue(Expression* expr) {
StackValueContext context(this);
- Visit(expr);
+ HandleInNonTestContext(expr, NO_REGISTERS);
}
void VisitForControl(Expression* expr,
@@ -294,9 +340,15 @@ class FullCodeGenerator: public AstVisitor {
Label* if_false,
Label* fall_through) {
TestContext context(this, if_true, if_false, fall_through);
- Visit(expr);
+ VisitInTestContext(expr);
+ // Forwarding bailouts to children is a one shot operation. It
+ // should have been processed at this point.
+ ASSERT(forward_bailout_pending_ == NULL);
}
+ void HandleInNonTestContext(Expression* expr, State state);
+ void VisitInTestContext(Expression* expr);
+
void VisitDeclarations(ZoneList<Declaration*>* declarations);
void DeclareGlobals(Handle<FixedArray> pairs);
@@ -310,12 +362,39 @@ class FullCodeGenerator: public AstVisitor {
Label* if_false,
Label* fall_through);
+ // Bailout support.
+ void PrepareForBailout(AstNode* node, State state);
+ void PrepareForBailoutForId(int id, State state);
+
+ // Record a call's return site offset, used to rebuild the frame if the
+ // called function was inlined at the site.
+ void RecordJSReturnSite(Call* call);
+
+ // Prepare for bailout before a test (or compare) and branch. If
+ // should_normalize, then the following comparison will not handle the
+ // canonical JS true value so we will insert a (dead) test against true at
+ // the actual bailout target from the optimized code. If not
+ // should_normalize, the true and false labels are ignored.
+ void PrepareForBailoutBeforeSplit(State state,
+ bool should_normalize,
+ Label* if_true,
+ Label* if_false);
+
// Platform-specific code for a variable, constant, or function
// declaration. Functions have an initial value.
void EmitDeclaration(Variable* variable,
Variable::Mode mode,
FunctionLiteral* function);
+ // Platform-specific code for checking the stack limit at the back edge of
+ // a loop.
+ void EmitStackCheck(IterationStatement* stmt);
+ // Record the OSR AST id corresponding to a stack check in the code.
+ void RecordStackCheck(int osr_ast_id);
+ // Emit a table of stack check ids and pcs into the code stream. Return
+ // the offset of the start of the table.
+ unsigned EmitStackCheckTable();
+
// Platform-specific return sequence
void EmitReturnSequence();
@@ -423,9 +502,7 @@ class FullCodeGenerator: public AstVisitor {
void SetStatementPosition(Statement* stmt);
void SetExpressionPosition(Expression* expr, int pos);
void SetStatementPosition(int pos);
- void SetSourcePosition(
- int pos,
- PositionRecordingType recording_type = NORMAL_POSITION);
+ void SetSourcePosition(int pos);
// Non-local control flow support.
void EnterFinallyBlock();
@@ -473,14 +550,13 @@ class FullCodeGenerator: public AstVisitor {
void VisitForTypeofValue(Expression* expr);
- MacroAssembler* masm_;
- CompilationInfo* info_;
+ struct BailoutEntry {
+ unsigned id;
+ unsigned pc_and_state;
+ };
- Label return_label_;
- NestedStatement* nesting_stack_;
- int loop_depth_;
- class ExpressionContext {
+ class ExpressionContext BASE_EMBEDDED {
public:
explicit ExpressionContext(FullCodeGenerator* codegen)
: masm_(codegen->masm()), old_(codegen->context()), codegen_(codegen) {
@@ -506,7 +582,8 @@ class FullCodeGenerator: public AstVisitor {
// Emit code to convert pure control flow to a pair of unbound labels into
// the result expected according to this expression context. The
- // implementation may decide to bind either of the labels.
+ // implementation will bind both labels unless it's a TestContext, which
+ // won't bind them at this point.
virtual void Plug(Label* materialize_true,
Label* materialize_false) const = 0;
@@ -528,12 +605,14 @@ class FullCodeGenerator: public AstVisitor {
Label** if_false,
Label** fall_through) const = 0;
+ virtual void HandleExpression(Expression* expr) const = 0;
+
// Returns true if we are evaluating only for side effects (ie if the result
- // will be discarded.
+ // will be discarded).
virtual bool IsEffect() const { return false; }
// Returns true if we are branching on the value rather than materializing
- // it.
+ // it. Only used for asserts.
virtual bool IsTest() const { return false; }
protected:
@@ -567,6 +646,7 @@ class FullCodeGenerator: public AstVisitor {
Label** if_true,
Label** if_false,
Label** fall_through) const;
+ virtual void HandleExpression(Expression* expr) const;
};
class StackValueContext : public ExpressionContext {
@@ -590,6 +670,7 @@ class FullCodeGenerator: public AstVisitor {
Label** if_true,
Label** if_false,
Label** fall_through) const;
+ virtual void HandleExpression(Expression* expr) const;
};
class TestContext : public ExpressionContext {
@@ -628,6 +709,7 @@ class FullCodeGenerator: public AstVisitor {
Label** if_true,
Label** if_false,
Label** fall_through) const;
+ virtual void HandleExpression(Expression* expr) const;
virtual bool IsTest() const { return true; }
private:
@@ -657,10 +739,20 @@ class FullCodeGenerator: public AstVisitor {
Label** if_true,
Label** if_false,
Label** fall_through) const;
+ virtual void HandleExpression(Expression* expr) const;
virtual bool IsEffect() const { return true; }
};
+ MacroAssembler* masm_;
+ CompilationInfo* info_;
+ Label return_label_;
+ NestedStatement* nesting_stack_;
+ int loop_depth_;
const ExpressionContext* context_;
+ ZoneList<BailoutEntry> bailout_entries_;
+ ZoneList<BailoutEntry> stack_checks_;
+ ForwardBailoutStack* forward_bailout_stack_;
+ ForwardBailoutStack* forward_bailout_pending_;
friend class NestedStatement;