Chromium Code Reviews| Index: src/x64/lithium-codegen-x64.cc |
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
| index eb8274bfd89bc46d84ef1f6793ecf7be86cd2879..52627fe9941079c3fe6f5c702aaf46601fc94082 100644 |
| --- a/src/x64/lithium-codegen-x64.cc |
| +++ b/src/x64/lithium-codegen-x64.cc |
| @@ -4548,6 +4548,109 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
| } |
| +void LCodeGen::DoMaybeGrowElements(LMaybeGrowElements* instr) { |
| + class DeferredMaybeGrowElements final : public LDeferredCode { |
| + public: |
| + DeferredMaybeGrowElements(LCodeGen* codegen, LMaybeGrowElements* instr) |
| + : LDeferredCode(codegen), instr_(instr) {} |
| + void Generate() override { codegen()->DoDeferredMaybeGrowElements(instr_); } |
| + LInstruction* instr() override { return instr_; } |
| + |
| + private: |
| + LMaybeGrowElements* instr_; |
| + }; |
| + |
| + Register result = rax; |
| + DeferredMaybeGrowElements* deferred = |
| + new (zone()) DeferredMaybeGrowElements(this, instr); |
| + LOperand* key = instr->key(); |
| + LOperand* current_capacity = instr->current_capacity(); |
| + |
| + DCHECK(instr->hydrogen()->key()->representation().IsInteger32()); |
| + DCHECK(instr->hydrogen()->current_capacity()->representation().IsInteger32()); |
| + DCHECK(key->IsConstantOperand() || key->IsRegister()); |
| + DCHECK(current_capacity->IsConstantOperand() || |
| + current_capacity->IsRegister()); |
| + |
| + if (key->IsConstantOperand() && current_capacity->IsConstantOperand()) { |
| + int32_t constant_key = ToInteger32(LConstantOperand::cast(key)); |
| + int32_t constant_capacity = |
| + ToInteger32(LConstantOperand::cast(current_capacity)); |
| + if (constant_key >= constant_capacity) { |
| + // Deferred case. |
| + __ jmp(deferred->entry()); |
| + } |
| + } else if (key->IsConstantOperand()) { |
| + int32_t constant_key = ToInteger32(LConstantOperand::cast(key)); |
| + __ cmpl(ToRegister(current_capacity), Immediate(constant_key)); |
| + __ j(less_equal, deferred->entry()); |
| + } else if (current_capacity->IsConstantOperand()) { |
| + int32_t constant_capacity = |
| + ToInteger32(LConstantOperand::cast(current_capacity)); |
| + __ cmpl(ToRegister(key), Immediate(constant_capacity)); |
| + __ j(greater_equal, deferred->entry()); |
| + } else { |
| + __ cmpl(ToRegister(key), ToRegister(current_capacity)); |
| + __ j(greater_equal, deferred->entry()); |
| + } |
| + |
| + if (instr->elements()->IsRegister()) { |
| + __ movp(result, ToRegister(instr->elements())); |
| + } else { |
| + __ movp(result, ToOperand(instr->elements())); |
| + } |
| + |
| + __ bind(deferred->exit()); |
| +} |
| + |
| + |
| +void LCodeGen::DoDeferredMaybeGrowElements(LMaybeGrowElements* instr) { |
| + // TODO(3095996): Get rid of this. For now, we need to make the |
| + // result register contain a valid pointer because it is already |
| + // contained in the register pointer map. |
| + Register result = rax; |
| + __ Move(result, Smi::FromInt(0)); |
| + |
| + // We have to call a stub. |
| + { |
| + PushSafepointRegistersScope scope(this); |
| + if (instr->object()->IsConstantOperand()) { |
| + LConstantOperand* constant_object = |
| + LConstantOperand::cast(instr->object()); |
| + if (IsSmiConstant(constant_object)) { |
| + Smi* immediate = ToSmi(constant_object); |
| + __ Move(result, immediate); |
| + } else { |
| + Handle<Object> handle_value = ToHandle(constant_object); |
| + __ Move(result, handle_value); |
| + } |
| + } else if (instr->object()->IsRegister()) { |
| + __ Move(result, ToRegister(instr->object())); |
| + } else { |
| + __ movp(result, ToOperand(instr->object())); |
| + } |
| + |
| + LOperand* key = instr->key(); |
| + if (key->IsConstantOperand()) { |
| + __ Move(rbx, ToSmi(LConstantOperand::cast(key))); |
| + } else { |
| + __ Move(rbx, ToRegister(key)); |
| + __ Integer32ToSmi(rbx, rbx); |
| + } |
| + |
| + GrowArrayElementsStub stub(isolate(), instr->hydrogen()->is_js_array(), |
| + instr->hydrogen()->kind()); |
| + __ CallStub(&stub); |
| + RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0); |
| + __ StoreToSafepointRegisterSlot(result, result); |
| + } |
| + |
| + // Deoptimize if we got a smi back. |
|
Benedikt Meurer
2015/05/12 05:13:04
Please add a comment here to describe why we deopt
mvstanton
2015/05/12 07:59:03
Good idea, done.
|
| + Condition is_smi = __ CheckSmi(result); |
| + DeoptimizeIf(is_smi, instr, Deoptimizer::kSmi); |
| +} |
| + |
| + |
| void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { |
| Register object_reg = ToRegister(instr->object()); |