| Index: src/x64/lithium-codegen-x64.cc
|
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
|
| index b095119a53643c08010d91a4af50b7dfb5a6d6d8..1e68b87c663c3e38fcc69033016c641fbcf2476d 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.
|
| + Condition is_smi = __ CheckSmi(result);
|
| + DeoptimizeIf(is_smi, instr, Deoptimizer::kSmi);
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
|
| Register object_reg = ToRegister(instr->object());
|
|
|
|
|