diff options
Diffstat (limited to 'deps/v8/src/full-codegen/full-codegen.h')
-rw-r--r-- | deps/v8/src/full-codegen/full-codegen.h | 136 |
1 files changed, 95 insertions, 41 deletions
diff --git a/deps/v8/src/full-codegen/full-codegen.h b/deps/v8/src/full-codegen/full-codegen.h index 52eddafa1a..6ab02313bb 100644 --- a/deps/v8/src/full-codegen/full-codegen.h +++ b/deps/v8/src/full-codegen/full-codegen.h @@ -42,6 +42,7 @@ class FullCodeGenerator: public AstVisitor { nesting_stack_(NULL), loop_depth_(0), try_catch_depth_(0), + operand_stack_depth_(0), globals_(NULL), context_(NULL), bailout_entries_(info->HasDeoptimizationSupport() @@ -96,9 +97,12 @@ class FullCodeGenerator: public AstVisitor { #error Unsupported target architecture. #endif + static Register result_register(); + private: class Breakable; class Iteration; + class TryFinally; class TestContext; @@ -115,11 +119,13 @@ class FullCodeGenerator: public AstVisitor { codegen_->nesting_stack_ = previous_; } - virtual Breakable* AsBreakable() { return NULL; } - virtual Iteration* AsIteration() { return NULL; } + virtual Breakable* AsBreakable() { return nullptr; } + virtual Iteration* AsIteration() { return nullptr; } + virtual TryFinally* AsTryFinally() { return nullptr; } virtual bool IsContinueTarget(Statement* target) { return false; } virtual bool IsBreakTarget(Statement* target) { return false; } + virtual bool IsTryFinally() { return false; } // Notify the statement that we are exiting it via break, continue, or // return and give it a chance to generate cleanup code. Return the @@ -131,11 +137,6 @@ class FullCodeGenerator: public AstVisitor { return previous_; } - // Like the Exit() method above, but limited to accumulating stack depth. - virtual NestedStatement* AccumulateDepth(int* stack_depth) { - return previous_; - } - protected: MacroAssembler* masm() { return codegen_->masm(); } @@ -211,10 +212,43 @@ class FullCodeGenerator: public AstVisitor { *stack_depth += kElementCount; return previous_; } - NestedStatement* AccumulateDepth(int* stack_depth) override { - *stack_depth += kElementCount; - return previous_; - } + }; + + class DeferredCommands { + public: + enum Command { kReturn, kThrow, kBreak, kContinue }; + typedef int TokenId; + struct DeferredCommand { + Command command; + TokenId token; + Statement* target; + }; + + DeferredCommands(FullCodeGenerator* codegen, Label* finally_entry) + : codegen_(codegen), + commands_(codegen->zone()), + return_token_(TokenDispenserForFinally::kInvalidToken), + throw_token_(TokenDispenserForFinally::kInvalidToken), + finally_entry_(finally_entry) {} + + void EmitCommands(); + + void RecordBreak(Statement* target); + void RecordContinue(Statement* target); + void RecordReturn(); + void RecordThrow(); + void EmitFallThrough(); + + private: + MacroAssembler* masm() { return codegen_->masm(); } + void EmitJumpToFinally(TokenId token); + + FullCodeGenerator* codegen_; + ZoneVector<DeferredCommand> commands_; + TokenDispenserForFinally dispenser_; + TokenId return_token_; + TokenId throw_token_; + Label* finally_entry_; }; // The try block of a try/finally statement. @@ -222,18 +256,18 @@ class FullCodeGenerator: public AstVisitor { public: static const int kElementCount = TryBlockConstant::kElementCount; - TryFinally(FullCodeGenerator* codegen, Label* finally_entry) - : NestedStatement(codegen), finally_entry_(finally_entry) { - } + TryFinally(FullCodeGenerator* codegen, DeferredCommands* commands) + : NestedStatement(codegen), deferred_commands_(commands) {} NestedStatement* Exit(int* stack_depth, int* context_length) override; - NestedStatement* AccumulateDepth(int* stack_depth) override { - *stack_depth += kElementCount; - return previous_; - } + + bool IsTryFinally() override { return true; } + TryFinally* AsTryFinally() override { return this; } + + DeferredCommands* deferred_commands() { return deferred_commands_; } private: - Label* finally_entry_; + DeferredCommands* deferred_commands_; }; // The finally block of a try/finally statement. @@ -247,10 +281,6 @@ class FullCodeGenerator: public AstVisitor { *stack_depth += kElementCount; return previous_; } - NestedStatement* AccumulateDepth(int* stack_depth) override { - *stack_depth += kElementCount; - return previous_; - } }; // The body of a for/in loop. @@ -266,10 +296,6 @@ class FullCodeGenerator: public AstVisitor { *stack_depth += kElementCount; return previous_; } - NestedStatement* AccumulateDepth(int* stack_depth) override { - *stack_depth += kElementCount; - return previous_; - } }; @@ -354,18 +380,21 @@ class FullCodeGenerator: public AstVisitor { MemOperand VarOperand(Variable* var, Register scratch); void VisitForEffect(Expression* expr) { + if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); EffectContext context(this); Visit(expr); PrepareForBailout(expr, NO_REGISTERS); } void VisitForAccumulatorValue(Expression* expr) { + if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); AccumulatorValueContext context(this); Visit(expr); PrepareForBailout(expr, TOS_REG); } void VisitForStackValue(Expression* expr) { + if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); StackValueContext context(this); Visit(expr); PrepareForBailout(expr, NO_REGISTERS); @@ -375,6 +404,7 @@ class FullCodeGenerator: public AstVisitor { Label* if_true, Label* if_false, Label* fall_through) { + if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); TestContext context(this, expr, if_true, if_false, fall_through); Visit(expr); // For test contexts, we prepare for bailout before branching, not at @@ -389,6 +419,34 @@ class FullCodeGenerator: public AstVisitor { void DeclareGlobals(Handle<FixedArray> pairs); int DeclareGlobalsFlags(); + // Push, pop or drop values onto/from the operand stack. + void PushOperand(Register reg); + void PopOperand(Register reg); + void DropOperands(int count); + + // Convenience helpers for pushing onto the operand stack. + void PushOperand(MemOperand operand); + void PushOperand(Handle<Object> handle); + void PushOperand(Smi* smi); + + // Convenience helpers for pushing/popping multiple operands. + void PushOperands(Register reg1, Register reg2); + void PushOperands(Register reg1, Register reg2, Register reg3); + void PushOperands(Register reg1, Register reg2, Register reg3, Register reg4); + void PopOperands(Register reg1, Register reg2); + + // Convenience helper for calling a runtime function that consumes arguments + // from the operand stack (only usable for functions with known arity). + void CallRuntimeWithOperands(Runtime::FunctionId function_id); + + // Static tracking of the operand stack depth. + void OperandStackDepthDecrement(int count); + void OperandStackDepthIncrement(int count); + + // Generate debug code that verifies that our static tracking of the operand + // stack depth is in sync with the actual operand stack during runtime. + void EmitOperandStackDepthCheck(); + // Generate code to create an iterator result object. The "value" property is // set to a value popped from the stack, and "done" is set according to the // argument. The result object is left in the result register. @@ -455,11 +513,13 @@ class FullCodeGenerator: public AstVisitor { // Emit code to pop values from the stack associated with nested statements // like try/catch, try/finally, etc, running the finallies and unwinding the - // handlers as needed. - void EmitUnwindBeforeReturn(); + // handlers as needed. Also emits the return sequence if necessary (i.e., + // if the return is not delayed by a finally block). + void EmitUnwindAndReturn(); // Platform-specific return sequence void EmitReturnSequence(); + void EmitProfilingCounterHandlingForReturnSequence(bool is_tail_call); // Platform-specific code sequences for calls void EmitCall(Call* expr, ConvertReceiverMode = ConvertReceiverMode::kAny); @@ -477,26 +537,18 @@ class FullCodeGenerator: public AstVisitor { F(IsRegExp) \ F(IsJSProxy) \ F(Call) \ - F(ArgumentsLength) \ - F(Arguments) \ F(ValueOf) \ - F(SetValueOf) \ - F(IsDate) \ F(StringCharFromCode) \ F(StringCharAt) \ F(OneByteSeqStringSetChar) \ F(TwoByteSeqStringSetChar) \ - F(ObjectEquals) \ - F(IsFunction) \ F(IsJSReceiver) \ - F(IsSimdValue) \ F(MathPow) \ - F(IsMinusZero) \ F(HasCachedArrayIndex) \ F(GetCachedArrayIndex) \ F(GetSuperConstructor) \ - F(FastOneByteArrayJoin) \ F(GeneratorNext) \ + F(GeneratorReturn) \ F(GeneratorThrow) \ F(DebugBreakInOptimizedCode) \ F(ClassOf) \ @@ -633,7 +685,7 @@ class FullCodeGenerator: public AstVisitor { TypeFeedbackId id = TypeFeedbackId::None()); // Inside typeof reference errors are never thrown. - void CallLoadIC(TypeofMode typeof_mode, LanguageMode language_mode = SLOPPY, + void CallLoadIC(TypeofMode typeof_mode, TypeFeedbackId id = TypeFeedbackId::None()); void CallStoreIC(TypeFeedbackId id = TypeFeedbackId::None()); @@ -669,6 +721,9 @@ class FullCodeGenerator: public AstVisitor { void ExitFinallyBlock(); void ClearPendingMessage(); + void EmitContinue(Statement* target); + void EmitBreak(Statement* target); + // Loop nesting counter. int loop_depth() { return loop_depth_; } void increment_loop_depth() { loop_depth_++; } @@ -693,7 +748,6 @@ class FullCodeGenerator: public AstVisitor { FunctionLiteral* literal() const { return info_->literal(); } Scope* scope() { return scope_; } - static Register result_register(); static Register context_register(); // Set fields in the stack frame. Offsets are the frame pointer relative @@ -945,6 +999,7 @@ class FullCodeGenerator: public AstVisitor { NestedStatement* nesting_stack_; int loop_depth_; int try_catch_depth_; + int operand_stack_depth_; ZoneList<Handle<Object> >* globals_; Handle<FixedArray> modules_; int module_index_; @@ -954,7 +1009,6 @@ class FullCodeGenerator: public AstVisitor { ZoneVector<HandlerTableEntry> handler_table_; int ic_total_count_; Handle<Cell> profiling_counter_; - bool generate_debug_code_; friend class NestedStatement; |