diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc index c7e32c3c33..fe6d945a28 100644 --- a/src/arm/codegen-arm.cc +++ b/src/arm/codegen-arm.cc @@ -289,9 +289,7 @@ void CodeGenerator::GenCode(FunctionLiteral* fun) { DeleteFrame(); // Process any deferred code using the register allocator. - if (HasStackOverflow()) { - ClearDeferred(); - } else { + if (!HasStackOverflow()) { ProcessDeferred(); } @@ -757,13 +755,11 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op, class DeferredInlineSmiOperation: public DeferredCode { public: - DeferredInlineSmiOperation(CodeGenerator* generator, - Token::Value op, + DeferredInlineSmiOperation(Token::Value op, int value, bool reversed, OverwriteMode overwrite_mode) - : DeferredCode(generator), - op_(op), + : op_(op), value_(value), reversed_(reversed), overwrite_mode_(overwrite_mode) { @@ -780,7 +776,12 @@ class DeferredInlineSmiOperation: public DeferredCode { }; +#undef __ +#define __ ACCESS_MASM(masm) + + void DeferredInlineSmiOperation::Generate() { + MacroAssembler* masm = cgen()->masm(); enter()->Bind(); VirtualFrame::SpilledScope spilled_scope; @@ -841,15 +842,19 @@ void DeferredInlineSmiOperation::Generate() { } GenericBinaryOpStub igostub(op_, overwrite_mode_); - Result arg0 = generator()->allocator()->Allocate(r1); + Result arg0 = cgen()->allocator()->Allocate(r1); ASSERT(arg0.is_valid()); - Result arg1 = generator()->allocator()->Allocate(r0); + Result arg1 = cgen()->allocator()->Allocate(r0); ASSERT(arg1.is_valid()); - generator()->frame()->CallStub(&igostub, &arg0, &arg1); + cgen()->frame()->CallStub(&igostub, &arg0, &arg1); exit_.Jump(); } +#undef __ +#define __ ACCESS_MASM(masm_) + + void CodeGenerator::SmiOperation(Token::Value op, Handle value, bool reversed, @@ -872,7 +877,7 @@ void CodeGenerator::SmiOperation(Token::Value op, switch (op) { case Token::ADD: { DeferredCode* deferred = - new DeferredInlineSmiOperation(this, op, int_value, reversed, mode); + new DeferredInlineSmiOperation(op, int_value, reversed, mode); __ add(r0, r0, Operand(value), SetCC); deferred->enter()->Branch(vs); @@ -884,7 +889,7 @@ void CodeGenerator::SmiOperation(Token::Value op, case Token::SUB: { DeferredCode* deferred = - new DeferredInlineSmiOperation(this, op, int_value, reversed, mode); + new DeferredInlineSmiOperation(op, int_value, reversed, mode); if (!reversed) { __ sub(r0, r0, Operand(value), SetCC); @@ -902,7 +907,7 @@ void CodeGenerator::SmiOperation(Token::Value op, case Token::BIT_XOR: case Token::BIT_AND: { DeferredCode* deferred = - new DeferredInlineSmiOperation(this, op, int_value, reversed, mode); + new DeferredInlineSmiOperation(op, int_value, reversed, mode); __ tst(r0, Operand(kSmiTagMask)); deferred->enter()->Branch(ne); switch (op) { @@ -927,7 +932,7 @@ void CodeGenerator::SmiOperation(Token::Value op, } else { int shift_value = int_value & 0x1f; // least significant 5 bits DeferredCode* deferred = - new DeferredInlineSmiOperation(this, op, shift_value, false, mode); + new DeferredInlineSmiOperation(op, shift_value, false, mode); __ tst(r0, Operand(kSmiTagMask)); deferred->enter()->Branch(ne); __ mov(r2, Operand(r0, ASR, kSmiTagSize)); // remove tags @@ -2654,8 +2659,7 @@ void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) { // therefore context dependent. class DeferredObjectLiteral: public DeferredCode { public: - DeferredObjectLiteral(CodeGenerator* generator, ObjectLiteral* node) - : DeferredCode(generator), node_(node) { + explicit DeferredObjectLiteral(ObjectLiteral* node) : node_(node) { set_comment("[ DeferredObjectLiteral"); } @@ -2666,7 +2670,12 @@ class DeferredObjectLiteral: public DeferredCode { }; +#undef __ +#define __ ACCESS_MASM(masm) + + void DeferredObjectLiteral::Generate() { + MacroAssembler* masm = cgen()->masm(); // Argument is passed in r1. enter()->Bind(); VirtualFrame::SpilledScope spilled_scope; @@ -2674,7 +2683,7 @@ void DeferredObjectLiteral::Generate() { // If the entry is undefined we call the runtime system to compute // the literal. - VirtualFrame* frame = generator()->frame(); + VirtualFrame* frame = cgen()->frame(); // Literal array (0). frame->EmitPush(r1); // Literal index (1). @@ -2691,6 +2700,10 @@ void DeferredObjectLiteral::Generate() { } +#undef __ +#define __ ACCESS_MASM(masm_) + + void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { #ifdef DEBUG int original_height = frame_->height(); @@ -2698,7 +2711,7 @@ void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { VirtualFrame::SpilledScope spilled_scope; Comment cmnt(masm_, "[ ObjectLiteral"); - DeferredObjectLiteral* deferred = new DeferredObjectLiteral(this, node); + DeferredObjectLiteral* deferred = new DeferredObjectLiteral(node); // Retrieve the literal array and check the allocated entry. @@ -2783,8 +2796,7 @@ void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { // therefore context dependent. class DeferredArrayLiteral: public DeferredCode { public: - DeferredArrayLiteral(CodeGenerator* generator, ArrayLiteral* node) - : DeferredCode(generator), node_(node) { + explicit DeferredArrayLiteral(ArrayLiteral* node) : node_(node) { set_comment("[ DeferredArrayLiteral"); } @@ -2795,7 +2807,12 @@ class DeferredArrayLiteral: public DeferredCode { }; +#undef __ +#define __ ACCESS_MASM(masm) + + void DeferredArrayLiteral::Generate() { + MacroAssembler* masm = cgen()->masm(); // Argument is passed in r1. enter()->Bind(); VirtualFrame::SpilledScope spilled_scope; @@ -2803,7 +2820,7 @@ void DeferredArrayLiteral::Generate() { // If the entry is undefined we call the runtime system to computed // the literal. - VirtualFrame* frame = generator()->frame(); + VirtualFrame* frame = cgen()->frame(); // Literal array (0). frame->EmitPush(r1); // Literal index (1). @@ -2820,6 +2837,10 @@ void DeferredArrayLiteral::Generate() { } +#undef __ +#define __ ACCESS_MASM(masm_) + + void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { #ifdef DEBUG int original_height = frame_->height(); @@ -2827,7 +2848,7 @@ void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { VirtualFrame::SpilledScope spilled_scope; Comment cmnt(masm_, "[ ArrayLiteral"); - DeferredArrayLiteral* deferred = new DeferredArrayLiteral(this, node); + DeferredArrayLiteral* deferred = new DeferredArrayLiteral(node); // Retrieve the literal array and check the allocated entry. diff --git a/src/arm/codegen-arm.h b/src/arm/codegen-arm.h index 24033cb004..a8cb777d79 100644 --- a/src/arm/codegen-arm.h +++ b/src/arm/codegen-arm.h @@ -194,8 +194,7 @@ class CodeGenerator: public AstVisitor { // Accessors Scope* scope() const { return scope_; } - // Clearing and generating deferred code. - void ClearDeferred(); + // Generating deferred code. void ProcessDeferred(); bool is_eval() { return is_eval_; } diff --git a/src/codegen-inl.h b/src/codegen-inl.h index f75b302780..12582a9e1d 100644 --- a/src/codegen-inl.h +++ b/src/codegen-inl.h @@ -37,20 +37,20 @@ namespace internal { void DeferredCode::SetEntryFrame(Result* arg) { - ASSERT(generator()->has_valid_frame()); - generator()->frame()->Push(arg); - enter()->set_entry_frame(new VirtualFrame(generator()->frame())); - *arg = generator()->frame()->Pop(); + ASSERT(cgen()->has_valid_frame()); + cgen()->frame()->Push(arg); + enter()->set_entry_frame(new VirtualFrame(cgen()->frame())); + *arg = cgen()->frame()->Pop(); } void DeferredCode::SetEntryFrame(Result* arg0, Result* arg1) { - ASSERT(generator()->has_valid_frame()); - generator()->frame()->Push(arg0); - generator()->frame()->Push(arg1); - enter()->set_entry_frame(new VirtualFrame(generator()->frame())); - *arg1 = generator()->frame()->Pop(); - *arg0 = generator()->frame()->Pop(); + ASSERT(cgen()->has_valid_frame()); + cgen()->frame()->Push(arg0); + cgen()->frame()->Push(arg1); + enter()->set_entry_frame(new VirtualFrame(cgen()->frame())); + *arg1 = cgen()->frame()->Pop(); + *arg0 = cgen()->frame()->Pop(); } diff --git a/src/codegen.cc b/src/codegen.cc index 40a898eae9..3b288d4b30 100644 --- a/src/codegen.cc +++ b/src/codegen.cc @@ -45,32 +45,24 @@ namespace internal { CodeGenerator* CodeGeneratorScope::top_ = NULL; -DeferredCode::DeferredCode(CodeGenerator* generator) - : generator_(generator), - masm_(generator->masm()), - exit_(JumpTarget::BIDIRECTIONAL), - statement_position_(masm_->current_statement_position()), - position_(masm_->current_position()) { - generator->AddDeferred(this); +DeferredCode::DeferredCode() : exit_(JumpTarget::BIDIRECTIONAL) { + MacroAssembler* masm = cgen()->masm(); + statement_position_ = masm->current_statement_position(); + position_ = masm->current_position(); ASSERT(statement_position_ != RelocInfo::kNoPosition); ASSERT(position_ != RelocInfo::kNoPosition); + + cgen()->AddDeferred(this); #ifdef DEBUG comment_ = ""; #endif } -void CodeGenerator::ClearDeferred() { - for (int i = 0; i < deferred_.length(); i++) { - deferred_[i]->Clear(); - } -} - - void CodeGenerator::ProcessDeferred() { while (!deferred_.is_empty()) { DeferredCode* code = deferred_.RemoveLast(); - MacroAssembler* masm = code->masm(); + MacroAssembler* masm = code->cgen()->masm(); // Record position of deferred code stub. masm->RecordStatementPosition(code->statement_position()); if (code->position() != RelocInfo::kNoPosition) { @@ -80,7 +72,6 @@ void CodeGenerator::ProcessDeferred() { Comment cmnt(masm, code->comment()); code->Generate(); ASSERT(code->enter()->is_bound()); - code->Clear(); } } diff --git a/src/codegen.h b/src/codegen.h index 487a7a43ad..9df2b4982d 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -52,7 +52,6 @@ // CodeGenerator // ~CodeGenerator // ProcessDeferred -// ClearDeferred // GenCode // BuildBoilerplate // ComputeCallInitialize @@ -116,33 +115,17 @@ class CodeGeneratorScope BASE_EMBEDDED { }; -// Use lazy compilation; defaults to true. -// NOTE: Do not remove non-lazy compilation until we can properly -// install extensions with lazy compilation enabled. At the -// moment, this doesn't work for the extensions in Google3, -// and we can only run the tests with --nolazy. - - // Deferred code objects are small pieces of code that are compiled // out of line. They are used to defer the compilation of uncommon // paths thereby avoiding expensive jumps around uncommon code parts. class DeferredCode: public ZoneObject { public: - explicit DeferredCode(CodeGenerator* generator); + DeferredCode(); virtual ~DeferredCode() { } virtual void Generate() = 0; - // Unuse the entry and exit targets, deallocating all virtual frames - // held by them. It will be impossible to emit a (correct) jump - // into or out of the deferred code after clearing. - void Clear() { - enter_.Unuse(); - exit_.Unuse(); - } - - MacroAssembler* masm() const { return masm_; } - CodeGenerator* generator() const { return generator_; } + CodeGenerator* cgen() const { return CodeGeneratorScope::Current(); } // Set the virtual frame for entry to the deferred code as a // snapshot of the code generator's current frame (plus additional @@ -169,13 +152,11 @@ class DeferredCode: public ZoneObject { void set_comment(const char* comment) { comment_ = comment; } const char* comment() const { return comment_; } #else - inline void set_comment(const char* comment) { } + void set_comment(const char* comment) { } const char* comment() const { return ""; } #endif protected: - CodeGenerator* const generator_; - MacroAssembler* const masm_; JumpTarget enter_; JumpTarget exit_; diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc index d6dbe6315a..c72c126f01 100644 --- a/src/ia32/codegen-ia32.cc +++ b/src/ia32/codegen-ia32.cc @@ -318,9 +318,7 @@ void CodeGenerator::GenCode(FunctionLiteral* fun) { DeleteFrame(); // Process any deferred code using the register allocator. - if (HasStackOverflow()) { - ClearDeferred(); - } else { + if (!HasStackOverflow()) { HistogramTimerScope deferred_timer(&Counters::deferred_code_generation); JumpTarget::set_compiling_deferred_code(true); ProcessDeferred(); @@ -784,11 +782,10 @@ const char* GenericBinaryOpStub::GetName() { // the GenericBinaryOpStub stub for slow cases. class DeferredInlineBinaryOperation: public DeferredCode { public: - DeferredInlineBinaryOperation(CodeGenerator* generator, - Token::Value op, + DeferredInlineBinaryOperation(Token::Value op, OverwriteMode mode, GenericBinaryFlags flags) - : DeferredCode(generator), stub_(op, mode, flags), op_(op) { + : stub_(op, mode, flags), op_(op) { set_comment("[ DeferredInlineBinaryOperation"); } @@ -807,9 +804,9 @@ void DeferredInlineBinaryOperation::Generate() { Result left; Result right; enter()->Bind(&left, &right); - generator()->frame()->Push(&left); - generator()->frame()->Push(&right); - Result answer = generator()->frame()->CallStub(&stub_, 2); + cgen()->frame()->Push(&left); + cgen()->frame()->Push(&right); + Result answer = cgen()->frame()->CallStub(&stub_, 2); exit_.Jump(&answer); } @@ -1013,8 +1010,7 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, // Implements a binary operation using a deferred code object // and some inline code to operate on smis quickly. DeferredInlineBinaryOperation* deferred = - new DeferredInlineBinaryOperation(this, op, overwrite_mode, - SMI_CODE_INLINED); + new DeferredInlineBinaryOperation(op, overwrite_mode, SMI_CODE_INLINED); // Generate the inline code that handles some smi operations, // and jumps to the deferred code for everything else. Result answer = deferred->GenerateInlineCode(left, right); @@ -1025,12 +1021,10 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, class DeferredInlineSmiOperation: public DeferredCode { public: - DeferredInlineSmiOperation(CodeGenerator* generator, - Token::Value op, + DeferredInlineSmiOperation(Token::Value op, Smi* value, OverwriteMode overwrite_mode) - : DeferredCode(generator), - op_(op), + : op_(op), value_(value), overwrite_mode_(overwrite_mode) { set_comment("[ DeferredInlineSmiOperation"); @@ -1048,22 +1042,20 @@ class DeferredInlineSmiOperation: public DeferredCode { void DeferredInlineSmiOperation::Generate() { Result left; enter()->Bind(&left); - generator()->frame()->Push(&left); - generator()->frame()->Push(value_); + cgen()->frame()->Push(&left); + cgen()->frame()->Push(value_); GenericBinaryOpStub igostub(op_, overwrite_mode_, SMI_CODE_INLINED); - Result answer = generator()->frame()->CallStub(&igostub, 2); + Result answer = cgen()->frame()->CallStub(&igostub, 2); exit_.Jump(&answer); } class DeferredInlineSmiOperationReversed: public DeferredCode { public: - DeferredInlineSmiOperationReversed(CodeGenerator* generator, - Token::Value op, + DeferredInlineSmiOperationReversed(Token::Value op, Smi* value, OverwriteMode overwrite_mode) - : DeferredCode(generator), - op_(op), + : op_(op), value_(value), overwrite_mode_(overwrite_mode) { set_comment("[ DeferredInlineSmiOperationReversed"); @@ -1081,21 +1073,19 @@ class DeferredInlineSmiOperationReversed: public DeferredCode { void DeferredInlineSmiOperationReversed::Generate() { Result right; enter()->Bind(&right); - generator()->frame()->Push(value_); - generator()->frame()->Push(&right); + cgen()->frame()->Push(value_); + cgen()->frame()->Push(&right); GenericBinaryOpStub igostub(op_, overwrite_mode_, SMI_CODE_INLINED); - Result answer = generator()->frame()->CallStub(&igostub, 2); + Result answer = cgen()->frame()->CallStub(&igostub, 2); exit_.Jump(&answer); } class DeferredInlineSmiAdd: public DeferredCode { public: - DeferredInlineSmiAdd(CodeGenerator* generator, - Smi* value, + DeferredInlineSmiAdd(Smi* value, OverwriteMode overwrite_mode) - : DeferredCode(generator), - value_(value), + : value_(value), overwrite_mode_(overwrite_mode) { set_comment("[ DeferredInlineSmiAdd"); } @@ -1108,28 +1098,11 @@ class DeferredInlineSmiAdd: public DeferredCode { }; -void DeferredInlineSmiAdd::Generate() { - // Undo the optimistic add operation and call the shared stub. - Result left; // Initially left + value_. - enter()->Bind(&left); - left.ToRegister(); - generator()->frame()->Spill(left.reg()); - __ sub(Operand(left.reg()), Immediate(value_)); - generator()->frame()->Push(&left); - generator()->frame()->Push(value_); - GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, SMI_CODE_INLINED); - Result answer = generator()->frame()->CallStub(&igostub, 2); - exit_.Jump(&answer); -} - - class DeferredInlineSmiAddReversed: public DeferredCode { public: - DeferredInlineSmiAddReversed(CodeGenerator* generator, - Smi* value, + DeferredInlineSmiAddReversed(Smi* value, OverwriteMode overwrite_mode) - : DeferredCode(generator), - value_(value), + : value_(value), overwrite_mode_(overwrite_mode) { set_comment("[ DeferredInlineSmiAddReversed"); } @@ -1142,28 +1115,11 @@ class DeferredInlineSmiAddReversed: public DeferredCode { }; -void DeferredInlineSmiAddReversed::Generate() { - // Undo the optimistic add operation and call the shared stub. - Result right; // Initially value_ + right. - enter()->Bind(&right); - right.ToRegister(); - generator()->frame()->Spill(right.reg()); - __ sub(Operand(right.reg()), Immediate(value_)); - generator()->frame()->Push(value_); - generator()->frame()->Push(&right); - GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, SMI_CODE_INLINED); - Result answer = generator()->frame()->CallStub(&igostub, 2); - exit_.Jump(&answer); -} - - class DeferredInlineSmiSub: public DeferredCode { public: - DeferredInlineSmiSub(CodeGenerator* generator, - Smi* value, + DeferredInlineSmiSub(Smi* value, OverwriteMode overwrite_mode) - : DeferredCode(generator), - value_(value), + : value_(value), overwrite_mode_(overwrite_mode) { set_comment("[ DeferredInlineSmiSub"); } @@ -1176,28 +1132,64 @@ class DeferredInlineSmiSub: public DeferredCode { }; +#undef __ +#define __ ACCESS_MASM(cgen()->masm()) + + +void DeferredInlineSmiAdd::Generate() { + // Undo the optimistic add operation and call the shared stub. + Result left; // Initially left + value_. + enter()->Bind(&left); + left.ToRegister(); + cgen()->frame()->Spill(left.reg()); + __ sub(Operand(left.reg()), Immediate(value_)); + cgen()->frame()->Push(&left); + cgen()->frame()->Push(value_); + GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, SMI_CODE_INLINED); + Result answer = cgen()->frame()->CallStub(&igostub, 2); + exit_.Jump(&answer); +} + + +void DeferredInlineSmiAddReversed::Generate() { + // Undo the optimistic add operation and call the shared stub. + Result right; // Initially value_ + right. + enter()->Bind(&right); + right.ToRegister(); + cgen()->frame()->Spill(right.reg()); + __ sub(Operand(right.reg()), Immediate(value_)); + cgen()->frame()->Push(value_); + cgen()->frame()->Push(&right); + GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, SMI_CODE_INLINED); + Result answer = cgen()->frame()->CallStub(&igostub, 2); + exit_.Jump(&answer); +} + + void DeferredInlineSmiSub::Generate() { // Undo the optimistic sub operation and call the shared stub. Result left; // Initially left - value_. enter()->Bind(&left); left.ToRegister(); - generator()->frame()->Spill(left.reg()); + cgen()->frame()->Spill(left.reg()); __ add(Operand(left.reg()), Immediate(value_)); - generator()->frame()->Push(&left); - generator()->frame()->Push(value_); + cgen()->frame()->Push(&left); + cgen()->frame()->Push(value_); GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, SMI_CODE_INLINED); - Result answer = generator()->frame()->CallStub(&igostub, 2); + Result answer = cgen()->frame()->CallStub(&igostub, 2); exit_.Jump(&answer); } +#undef __ +#define __ ACCESS_MASM(masm_) + + class DeferredInlineSmiSubReversed: public DeferredCode { public: - DeferredInlineSmiSubReversed(CodeGenerator* generator, - Smi* value, + DeferredInlineSmiSubReversed(Smi* value, OverwriteMode overwrite_mode) - : DeferredCode(generator), - value_(value), + : value_(value), overwrite_mode_(overwrite_mode) { set_comment("[ DeferredInlineSmiSubReversed"); } @@ -1214,10 +1206,10 @@ void DeferredInlineSmiSubReversed::Generate() { // Call the shared stub. Result right; enter()->Bind(&right); - generator()->frame()->Push(value_); - generator()->frame()->Push(&right); + cgen()->frame()->Push(value_); + cgen()->frame()->Push(&right); GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, SMI_CODE_INLINED); - Result answer = generator()->frame()->CallStub(&igostub, 2); + Result answer = cgen()->frame()->CallStub(&igostub, 2); exit_.Jump(&answer); } @@ -1260,10 +1252,9 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, DeferredCode* deferred = NULL; if (reversed) { - deferred = new DeferredInlineSmiAddReversed(this, smi_value, - overwrite_mode); + deferred = new DeferredInlineSmiAddReversed(smi_value, overwrite_mode); } else { - deferred = new DeferredInlineSmiAdd(this, smi_value, overwrite_mode); + deferred = new DeferredInlineSmiAdd(smi_value, overwrite_mode); } deferred->SetEntryFrame(operand); deferred->enter()->Branch(overflow, operand, not_taken); @@ -1280,8 +1271,7 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, if (reversed) { answer = allocator()->Allocate(); ASSERT(answer.is_valid()); - deferred = new DeferredInlineSmiSubReversed(this, smi_value, - overwrite_mode); + deferred = new DeferredInlineSmiSubReversed(smi_value, overwrite_mode); __ Set(answer.reg(), Immediate(value)); // We are in the reversed case so they can't both be Smi constants. ASSERT(operand->is_register()); @@ -1289,7 +1279,7 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, } else { operand->ToRegister(); frame_->Spill(operand->reg()); - deferred = new DeferredInlineSmiSub(this, smi_value, overwrite_mode); + deferred = new DeferredInlineSmiSub(smi_value, overwrite_mode); __ sub(Operand(operand->reg()), Immediate(value)); answer = *operand; } @@ -1313,8 +1303,7 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, // In the slow case, this masking is done inside the runtime call. int shift_value = int_value & 0x1f; DeferredCode* deferred = - new DeferredInlineSmiOperation(this, Token::SAR, smi_value, - overwrite_mode); + new DeferredInlineSmiOperation(op, smi_value, overwrite_mode); operand->ToRegister(); __ test(operand->reg(), Immediate(kSmiTagMask)); deferred->enter()->Branch(not_zero, operand, not_taken); @@ -1339,8 +1328,7 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, // In the slow case, this masking is done inside the runtime call. int shift_value = int_value & 0x1f; DeferredCode* deferred = - new DeferredInlineSmiOperation(this, Token::SHR, smi_value, - overwrite_mode); + new DeferredInlineSmiOperation(op, smi_value, overwrite_mode); operand->ToRegister(); __ test(operand->reg(), Immediate(kSmiTagMask)); deferred->enter()->Branch(not_zero, operand, not_taken); @@ -1374,8 +1362,7 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, // In the slow case, this masking is done inside the runtime call. int shift_value = int_value & 0x1f; DeferredCode* deferred = - new DeferredInlineSmiOperation(this, Token::SHL, smi_value, - overwrite_mode); + new DeferredInlineSmiOperation(op, smi_value, overwrite_mode); operand->ToRegister(); __ test(operand->reg(), Immediate(kSmiTagMask)); deferred->enter()->Branch(not_zero, operand, not_taken); @@ -1408,10 +1395,10 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, case Token::BIT_AND: { DeferredCode* deferred = NULL; if (reversed) { - deferred = new DeferredInlineSmiOperationReversed(this, op, smi_value, + deferred = new DeferredInlineSmiOperationReversed(op, smi_value, overwrite_mode); } else { - deferred = new DeferredInlineSmiOperation(this, op, smi_value, + deferred = new DeferredInlineSmiOperation(op, smi_value, overwrite_mode); } operand->ToRegister(); @@ -1697,8 +1684,7 @@ void CodeGenerator::CallWithArguments(ZoneList* args, class DeferredStackCheck: public DeferredCode { public: - explicit DeferredStackCheck(CodeGenerator* generator) - : DeferredCode(generator) { + explicit DeferredStackCheck() { set_comment("[ DeferredStackCheck"); } @@ -1709,7 +1695,7 @@ class DeferredStackCheck: public DeferredCode { void DeferredStackCheck::Generate() { enter()->Bind(); StackCheckStub stub; - Result ignored = generator()->frame()->CallStub(&stub, 0); + Result ignored = cgen()->frame()->CallStub(&stub, 0); ignored.Unuse(); exit_.Jump(); } @@ -1717,7 +1703,7 @@ void DeferredStackCheck::Generate() { void CodeGenerator::CheckStack() { if (FLAG_check_stack) { - DeferredStackCheck* deferred = new DeferredStackCheck(this); + DeferredStackCheck* deferred = new DeferredStackCheck; ExternalReference stack_guard_limit = ExternalReference::address_of_stack_guard_limit(); __ cmp(esp, Operand::StaticVariable(stack_guard_limit)); @@ -3575,8 +3561,7 @@ bool CodeGenerator::IsUnsafeSmi(Handle value) { class DeferredRegExpLiteral: public DeferredCode { public: - DeferredRegExpLiteral(CodeGenerator* generator, RegExpLiteral* node) - : DeferredCode(generator), node_(node) { + explicit DeferredRegExpLiteral(RegExpLiteral* node) : node_(node) { set_comment("[ DeferredRegExpLiteral"); } @@ -3593,7 +3578,7 @@ void DeferredRegExpLiteral::Generate() { // Since the entry is undefined we call the runtime system to // compute the literal. - VirtualFrame* frame = generator()->frame(); + VirtualFrame* frame = cgen()->frame(); // Literal array (0). frame->Push(&literals); // Literal index (1). @@ -3610,7 +3595,7 @@ void DeferredRegExpLiteral::Generate() { void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) { Comment cmnt(masm_, "[ RegExp Literal"); - DeferredRegExpLiteral* deferred = new DeferredRegExpLiteral(this, node); + DeferredRegExpLiteral* deferred = new DeferredRegExpLiteral(node); // Retrieve the literals array and check the allocated entry. Begin // with a writable copy of the function of this activation in a @@ -3651,9 +3636,7 @@ void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) { // therefore context dependent. class DeferredObjectLiteral: public DeferredCode { public: - DeferredObjectLiteral(CodeGenerator* generator, - ObjectLiteral* node) - : DeferredCode(generator), node_(node) { + explicit DeferredObjectLiteral(ObjectLiteral* node) : node_(node) { set_comment("[ DeferredObjectLiteral"); } @@ -3670,7 +3653,7 @@ void DeferredObjectLiteral::Generate() { // Since the entry is undefined we call the runtime system to // compute the literal. - VirtualFrame* frame = generator()->frame(); + VirtualFrame* frame = cgen()->frame(); // Literal array (0). frame->Push(&literals); // Literal index (1). @@ -3685,7 +3668,7 @@ void DeferredObjectLiteral::Generate() { void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { Comment cmnt(masm_, "[ ObjectLiteral"); - DeferredObjectLiteral* deferred = new DeferredObjectLiteral(this, node); + DeferredObjectLiteral* deferred = new DeferredObjectLiteral(node); // Retrieve the literals array and check the allocated entry. Begin // with a writable copy of the function of this activation in a @@ -3789,9 +3772,7 @@ void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { // therefore context dependent. class DeferredArrayLiteral: public DeferredCode { public: - DeferredArrayLiteral(CodeGenerator* generator, - ArrayLiteral* node) - : DeferredCode(generator), node_(node) { + explicit DeferredArrayLiteral(ArrayLiteral* node) : node_(node) { set_comment("[ DeferredArrayLiteral"); } @@ -3808,7 +3789,7 @@ void DeferredArrayLiteral::Generate() { // Since the entry is undefined we call the runtime system to // compute the literal. - VirtualFrame* frame = generator()->frame(); + VirtualFrame* frame = cgen()->frame(); // Literal array (0). frame->Push(&literals); // Literal index (1). @@ -3823,7 +3804,7 @@ void DeferredArrayLiteral::Generate() { void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { Comment cmnt(masm_, "[ ArrayLiteral"); - DeferredArrayLiteral* deferred = new DeferredArrayLiteral(this, node); + DeferredArrayLiteral* deferred = new DeferredArrayLiteral(node); // Retrieve the literals array and check the allocated entry. Begin // with a writable copy of the function of this activation in a @@ -4778,12 +4759,10 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { class DeferredCountOperation: public DeferredCode { public: - DeferredCountOperation(CodeGenerator* generator, - bool is_postfix, + DeferredCountOperation(bool is_postfix, bool is_increment, int target_size) - : DeferredCode(generator), - is_postfix_(is_postfix), + : is_postfix_(is_postfix), is_increment_(is_increment), target_size_(target_size) { set_comment("[ DeferredCountOperation"); @@ -4798,11 +4777,14 @@ class DeferredCountOperation: public DeferredCode { }; +#undef __ +#define __ ACCESS_MASM(cgen()->masm()) + + void DeferredCountOperation::Generate() { - CodeGenerator* cgen = generator(); Result value; enter()->Bind(&value); - VirtualFrame* frame = cgen->frame(); + VirtualFrame* frame = cgen()->frame(); // Undo the optimistic smi operation. value.ToRegister(); frame->Spill(value.reg()); @@ -4830,6 +4812,10 @@ void DeferredCountOperation::Generate() { } +#undef __ +#define __ ACCESS_MASM(masm_) + + void CodeGenerator::VisitCountOperation(CountOperation* node) { Comment cmnt(masm_, "[ CountOperation"); @@ -4857,8 +4843,7 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) { target.TakeValue(NOT_INSIDE_TYPEOF); DeferredCountOperation* deferred = - new DeferredCountOperation(this, is_postfix, - is_increment, target.size()); + new DeferredCountOperation(is_postfix, is_increment, target.size()); Result value = frame_->Pop(); value.ToRegister(); @@ -5282,8 +5267,7 @@ bool CodeGenerator::HasValidEntryRegisters() { class DeferredReferenceGetNamedValue: public DeferredCode { public: - DeferredReferenceGetNamedValue(CodeGenerator* cgen, Handle name) - : DeferredCode(cgen), name_(name) { + explicit DeferredReferenceGetNamedValue(Handle name) : name_(name) { set_comment("[ DeferredReferenceGetNamedValue"); } @@ -5297,35 +5281,10 @@ class DeferredReferenceGetNamedValue: public DeferredCode { }; -void DeferredReferenceGetNamedValue::Generate() { - CodeGenerator* cgen = generator(); - Result receiver; - enter()->Bind(&receiver); - - cgen->frame()->Push(&receiver); - cgen->frame()->Push(name_); - Result answer = cgen->frame()->CallLoadIC(RelocInfo::CODE_TARGET); - // The call must be followed by a test eax instruction to indicate - // that the inobject property case was inlined. - ASSERT(answer.is_register() && answer.reg().is(eax)); - // Store the delta to the map check instruction here in the test instruction. - // Use masm_-> instead of the double underscore macro since the latter can't - // return a value. - int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site()); - // Here we use masm_-> instead of the double underscore macro because - // this is the instruction that gets patched and coverage code gets in - // the way. - masm_->test(answer.reg(), Immediate(-delta_to_patch_site)); - __ IncrementCounter(&Counters::named_load_inline_miss, 1); - receiver = cgen->frame()->Pop(); - exit_.Jump(&receiver, &answer); -} - - class DeferredReferenceGetKeyedValue: public DeferredCode { public: - DeferredReferenceGetKeyedValue(CodeGenerator* generator, bool is_global) - : DeferredCode(generator), is_global_(is_global) { + explicit DeferredReferenceGetKeyedValue(bool is_global) + : is_global_(is_global) { set_comment("[ DeferredReferenceGetKeyedValue"); } @@ -5339,13 +5298,41 @@ class DeferredReferenceGetKeyedValue: public DeferredCode { }; +#undef __ +#define __ ACCESS_MASM(cgen()->masm()) + + +void DeferredReferenceGetNamedValue::Generate() { + Result receiver; + enter()->Bind(&receiver); + + cgen()->frame()->Push(&receiver); + cgen()->frame()->Push(name_); + Result answer = cgen()->frame()->CallLoadIC(RelocInfo::CODE_TARGET); + // The call must be followed by a test eax instruction to indicate + // that the inobject property case was inlined. + ASSERT(answer.is_register() && answer.reg().is(eax)); + // Store the delta to the map check instruction here in the test + // instruction. Use cgen()->masm()-> instead of the __ macro since + // the latter can't return a value. + int delta_to_patch_site = + cgen()->masm()->SizeOfCodeGeneratedSince(patch_site()); + // Here we use cgen()->masm()-> instead of the __ macro because this + // is the instruction that gets patched and coverage code gets in the + // way. + cgen()->masm()->test(answer.reg(), Immediate(-delta_to_patch_site)); + __ IncrementCounter(&Counters::named_load_inline_miss, 1); + receiver = cgen()->frame()->Pop(); + exit_.Jump(&receiver, &answer); +} + + void DeferredReferenceGetKeyedValue::Generate() { - CodeGenerator* cgen = generator(); Result receiver; Result key; enter()->Bind(&receiver, &key); - cgen->frame()->Push(&receiver); // First IC argument. - cgen->frame()->Push(&key); // Second IC argument. + cgen()->frame()->Push(&receiver); // First IC argument. + cgen()->frame()->Push(&key); // Second IC argument. // Calculate the delta from the IC call instruction to the map check // cmp instruction in the inlined version. This delta is stored in @@ -5356,28 +5343,30 @@ void DeferredReferenceGetKeyedValue::Generate() { RelocInfo::Mode mode = is_global_ ? RelocInfo::CODE_TARGET_CONTEXT : RelocInfo::CODE_TARGET; - Result value = cgen->frame()->CallKeyedLoadIC(mode); + Result value = cgen()->frame()->CallKeyedLoadIC(mode); // The result needs to be specifically the eax register because the // offset to the patch site will be expected in a test eax // instruction. ASSERT(value.is_register() && value.reg().is(eax)); - // The delta from the start of the map-compare instruction to the - // test instruction. We use masm_ directly here instead of the - // double underscore macro because the macro sometimes uses macro - // expansion to turn into something that can't return a value. This - // is encountered when doing generated code coverage tests. - int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site()); - // Here we use masm_-> instead of the double underscore macro because this - // is the instruction that gets patched and coverage code gets in the way. - masm_->test(value.reg(), Immediate(-delta_to_patch_site)); + // The delta from the start of the map-compare instruction to the test + // instruction. We use cgen()->masm() directly here instead of the __ + // macro because the macro sometimes uses macro expansion to turn into + // something that can't return a value. This is encountered when + // doing generated code coverage tests. + int delta_to_patch_site = + cgen()->masm()->SizeOfCodeGeneratedSince(patch_site()); + // Here we use cgen()->masm()-> instead of the __ macro because this + // is the instruction that gets patched and coverage code gets in the + // way. + cgen()->masm()->test(value.reg(), Immediate(-delta_to_patch_site)); __ IncrementCounter(&Counters::keyed_load_inline_miss, 1); // The receiver and key were spilled by the call, so their state as // constants or copies has been changed. Thus, they need to be // "mergable" in the block at the exit label and are therefore // passed as return results here. - key = cgen->frame()->Pop(); - receiver = cgen->frame()->Pop(); + key = cgen()->frame()->Pop(); + receiver = cgen()->frame()->Pop(); exit_.Jump(&receiver, &key, &value); } @@ -5450,7 +5439,7 @@ void Reference::GetValue(TypeofState typeof_state) { // Inline the inobject property case. Comment cmnt(masm, "[ Inlined named property load"); DeferredReferenceGetNamedValue* deferred = - new DeferredReferenceGetNamedValue(cgen_, GetName()); + new DeferredReferenceGetNamedValue(GetName()); Result receiver = cgen_->frame()->Pop(); receiver.ToRegister(); @@ -5515,7 +5504,7 @@ void Reference::GetValue(TypeofState typeof_state) { if (cgen_->loop_nesting() > 0) { Comment cmnt(masm, "[ Inlined array index load"); DeferredReferenceGetKeyedValue* deferred = - new DeferredReferenceGetKeyedValue(cgen_, is_global); + new DeferredReferenceGetKeyedValue(is_global); Result key = cgen_->frame()->Pop(); Result receiver = cgen_->frame()->Pop(); @@ -5743,11 +5732,9 @@ void ToBooleanStub::Generate(MacroAssembler* masm) { } -#undef __ -#define __ ACCESS_MASM(masm_) - Result DeferredInlineBinaryOperation::GenerateInlineCode(Result* left, Result* right) { + MacroAssembler* masm = cgen()->masm(); // Perform fast-case smi code for the operation (left right) and // returns the result in a Result. // If any fast-case tests fail, it jumps to the slow-case deferred code, @@ -5761,7 +5748,7 @@ Result DeferredInlineBinaryOperation::GenerateInlineCode(Result* left, // A newly allocated register answer is used to hold the answer. // The registers containing left and right are not modified in // most cases, so they usually don't need to be spilled in the fast case. - Result answer = generator()->allocator()->Allocate(); + Result answer = cgen()->allocator()->Allocate(); ASSERT(answer.is_valid()); // Perform the smi check. @@ -5832,8 +5819,8 @@ Result DeferredInlineBinaryOperation::GenerateInlineCode(Result* left, // from left and right, and is spilled. // The value in left is copied to answer. - Result reg_eax = generator()->allocator()->Allocate(eax); - Result reg_edx = generator()->allocator()->Allocate(edx); + Result reg_eax = cgen()->allocator()->Allocate(eax); + Result reg_edx = cgen()->allocator()->Allocate(edx); // These allocations may have failed, if one of left, right, or answer // is in register eax or edx. bool left_copied_to_eax = false; // We will make sure this becomes true. @@ -5847,7 +5834,7 @@ Result DeferredInlineBinaryOperation::GenerateInlineCode(Result* left, // We use answer if it is not edx, otherwise we allocate one. if (answer.reg().is(edx)) { reg_edx = answer; - answer = generator()->allocator()->Allocate(); + answer = cgen()->allocator()->Allocate(); ASSERT(answer.is_valid()); } @@ -5878,7 +5865,7 @@ Result DeferredInlineBinaryOperation::GenerateInlineCode(Result* left, // Is answer used? if (answer.reg().is(eax) || answer.reg().is(left->reg()) || answer.reg().is(right->reg())) { - answer = generator()->allocator()->Allocate(); + answer = cgen()->allocator()->Allocate(); ASSERT(answer.is_valid()); // We cannot hit both Allocate() calls. } if (left->reg().is(edx)) { @@ -5897,12 +5884,12 @@ Result DeferredInlineBinaryOperation::GenerateInlineCode(Result* left, ASSERT(!right->reg().is(eax)); answer = reg_eax; // May free answer, if it was never used. - generator()->frame()->Spill(eax); + cgen()->frame()->Spill(eax); if (!left_copied_to_eax) { __ mov(eax, left->reg()); left_copied_to_eax = true; } - generator()->frame()->Spill(edx); + cgen()->frame()->Spill(edx); // Postcondition: // reg_eax, reg_edx are valid, correct, and spilled. @@ -5992,7 +5979,7 @@ Result DeferredInlineBinaryOperation::GenerateInlineCode(Result* left, // spilling left. *left = answer; } else if (left->reg().is(ecx)) { - generator()->frame()->Spill(left->reg()); + cgen()->frame()->Spill(left->reg()); __ mov(left->reg(), right->reg()); *right = *left; *left = answer; // Use copy of left in answer as left. @@ -6000,7 +5987,7 @@ Result DeferredInlineBinaryOperation::GenerateInlineCode(Result* left, __ mov(answer.reg(), right->reg()); *right = answer; } else { - Result reg_ecx = generator()->allocator()->Allocate(ecx); + Result reg_ecx = cgen()->allocator()->Allocate(ecx); ASSERT(reg_ecx.is_valid()); __ mov(ecx, right->reg()); *right = reg_ecx; @@ -6018,8 +6005,8 @@ Result DeferredInlineBinaryOperation::GenerateInlineCode(Result* left, // the same answer. // We are modifying left and right. They must be spilled! - generator()->frame()->Spill(left->reg()); - generator()->frame()->Spill(right->reg()); + cgen()->frame()->Spill(left->reg()); + cgen()->frame()->Spill(right->reg()); // Remove tags from operands (but keep sign). __ sar(left->reg(), kSmiTagSize); @@ -6089,9 +6076,6 @@ Result DeferredInlineBinaryOperation::GenerateInlineCode(Result* left, } -#undef __ -#define __ ACCESS_MASM(masm) - void GenericBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, Label* slow) { // Perform fast-case smi code for the operation (eax ebx) and // leave result in register eax. diff --git a/src/ia32/codegen-ia32.h b/src/ia32/codegen-ia32.h index 5892a4ac64..9b609a1562 100644 --- a/src/ia32/codegen-ia32.h +++ b/src/ia32/codegen-ia32.h @@ -333,8 +333,7 @@ class CodeGenerator: public AstVisitor { // Accessors Scope* scope() const { return scope_; } - // Clearing and generating deferred code. - void ClearDeferred(); + // Generating deferred code. void ProcessDeferred(); bool is_eval() { return is_eval_; } diff --git a/src/x64/codegen-x64.h b/src/x64/codegen-x64.h index 8087d9caf4..5f5daa422b 100644 --- a/src/x64/codegen-x64.h +++ b/src/x64/codegen-x64.h @@ -333,8 +333,7 @@ class CodeGenerator: public AstVisitor { // Accessors Scope* scope() const { return scope_; } - // Clearing and generating deferred code. - void ClearDeferred(); + // Generating deferred code. void ProcessDeferred(); bool is_eval() { return is_eval_; }