| Index: src/ia32/codegen-ia32.cc
|
| ===================================================================
|
| --- src/ia32/codegen-ia32.cc (revision 2063)
|
| +++ src/ia32/codegen-ia32.cc (working copy)
|
| @@ -318,9 +318,7 @@
|
| 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 @@
|
| // 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 @@
|
| 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 @@
|
| // 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 @@
|
|
|
| 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 @@
|
| 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 @@
|
| 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 @@
|
| };
|
|
|
|
|
| -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 @@
|
| };
|
|
|
|
|
| -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 @@
|
| };
|
|
|
|
|
| +#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 @@
|
| // 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 @@
|
|
|
| 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 @@
|
| 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 @@
|
| } 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 @@
|
| // 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 @@
|
| // 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 @@
|
| // 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 @@
|
| 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 @@
|
|
|
| class DeferredStackCheck: public DeferredCode {
|
| public:
|
| - explicit DeferredStackCheck(CodeGenerator* generator)
|
| - : DeferredCode(generator) {
|
| + explicit DeferredStackCheck() {
|
| set_comment("[ DeferredStackCheck");
|
| }
|
|
|
| @@ -1709,7 +1695,7 @@
|
| 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 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 @@
|
|
|
| class DeferredRegExpLiteral: public DeferredCode {
|
| public:
|
| - DeferredRegExpLiteral(CodeGenerator* generator, RegExpLiteral* node)
|
| - : DeferredCode(generator), node_(node) {
|
| + DeferredRegExpLiteral(RegExpLiteral* node) : node_(node) {
|
| set_comment("[ DeferredRegExpLiteral");
|
| }
|
|
|
| @@ -3593,7 +3578,7 @@
|
| // 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 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 @@
|
| // therefore context dependent.
|
| class DeferredObjectLiteral: public DeferredCode {
|
| public:
|
| - DeferredObjectLiteral(CodeGenerator* generator,
|
| - ObjectLiteral* node)
|
| - : DeferredCode(generator), node_(node) {
|
| + DeferredObjectLiteral(ObjectLiteral* node) : node_(node) {
|
| set_comment("[ DeferredObjectLiteral");
|
| }
|
|
|
| @@ -3670,7 +3653,7 @@
|
| // 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 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 @@
|
| // therefore context dependent.
|
| class DeferredArrayLiteral: public DeferredCode {
|
| public:
|
| - DeferredArrayLiteral(CodeGenerator* generator,
|
| - ArrayLiteral* node)
|
| - : DeferredCode(generator), node_(node) {
|
| + DeferredArrayLiteral(ArrayLiteral* node) : node_(node) {
|
| set_comment("[ DeferredArrayLiteral");
|
| }
|
|
|
| @@ -3808,7 +3789,7 @@
|
| // 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 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 @@
|
|
|
| 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 @@
|
| };
|
|
|
|
|
| +#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 @@
|
| }
|
|
|
|
|
| +#undef __
|
| +#define __ ACCESS_MASM(masm_)
|
| +
|
| +
|
| void CodeGenerator::VisitCountOperation(CountOperation* node) {
|
| Comment cmnt(masm_, "[ CountOperation");
|
|
|
| @@ -4857,8 +4843,7 @@
|
| 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 @@
|
|
|
| class DeferredReferenceGetNamedValue: public DeferredCode {
|
| public:
|
| - DeferredReferenceGetNamedValue(CodeGenerator* cgen, Handle<String> name)
|
| - : DeferredCode(cgen), name_(name) {
|
| + DeferredReferenceGetNamedValue(Handle<String> name) : name_(name) {
|
| set_comment("[ DeferredReferenceGetNamedValue");
|
| }
|
|
|
| @@ -5297,35 +5281,9 @@
|
| };
|
|
|
|
|
| -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) {
|
| + DeferredReferenceGetKeyedValue(bool is_global) : is_global_(is_global) {
|
| set_comment("[ DeferredReferenceGetKeyedValue");
|
| }
|
|
|
| @@ -5339,13 +5297,41 @@
|
| };
|
|
|
|
|
| +#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 +5342,30 @@
|
| 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 +5438,7 @@
|
| // 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 +5503,7 @@
|
| 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 +5731,9 @@
|
| }
|
|
|
|
|
| -#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 <op> right) and
|
| // returns the result in a Result.
|
| // If any fast-case tests fail, it jumps to the slow-case deferred code,
|
| @@ -5761,7 +5747,7 @@
|
| // 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 +5818,8 @@
|
| // 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 +5833,7 @@
|
| // 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 +5864,7 @@
|
| // 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 +5883,12 @@
|
| 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 +5978,7 @@
|
| // 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 +5986,7 @@
|
| __ 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 +6004,8 @@
|
| // 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 +6075,6 @@
|
| }
|
|
|
|
|
| -#undef __
|
| -#define __ ACCESS_MASM(masm)
|
| -
|
| void GenericBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, Label* slow) {
|
| // Perform fast-case smi code for the operation (eax <op> ebx) and
|
| // leave result in register eax.
|
|
|