| Index: src/x64/lithium-codegen-x64.cc
|
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
|
| index d2325b821f41a43a6d138924cf6275eec97aeb52..bedafeb94c6f057713bc5d35a19e902ba2c14d59 100644
|
| --- a/src/x64/lithium-codegen-x64.cc
|
| +++ b/src/x64/lithium-codegen-x64.cc
|
| @@ -2560,6 +2560,7 @@ void LCodeGen::DoReturn(LReturn* instr) {
|
| rcx);
|
| } else {
|
| Register reg = ToRegister(instr->parameter_count());
|
| + __ SmiToInteger32(reg, reg);
|
| Register return_addr_reg = reg.is(rcx) ? rbx : rcx;
|
| __ pop(return_addr_reg);
|
| __ shl(reg, Immediate(kPointerSizeLog2));
|
| @@ -2900,16 +2901,26 @@ void LCodeGen::DoLoadExternalArrayPointer(
|
|
|
| void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
|
| Register arguments = ToRegister(instr->arguments());
|
| - Register length = ToRegister(instr->length());
|
| Register result = ToRegister(instr->result());
|
| - // There are two words between the frame pointer and the last argument.
|
| - // Subtracting from length accounts for one of them add one more.
|
| - if (instr->index()->IsRegister()) {
|
| - __ subl(length, ToRegister(instr->index()));
|
| +
|
| + if (instr->length()->IsConstantOperand() &&
|
| + instr->index()->IsConstantOperand()) {
|
| + int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
|
| + int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
|
| + int index = (const_length - const_index) + 1;
|
| + __ movq(result, Operand(arguments, index * kPointerSize));
|
| } else {
|
| - __ subl(length, ToOperand(instr->index()));
|
| + Register length = ToRegister(instr->length());
|
| + // There are two words between the frame pointer and the last argument.
|
| + // Subtracting from length accounts for one of them add one more.
|
| + if (instr->index()->IsRegister()) {
|
| + __ subl(length, ToRegister(instr->index()));
|
| + } else {
|
| + __ subl(length, ToOperand(instr->index()));
|
| + }
|
| + __ movq(result,
|
| + Operand(arguments, length, times_pointer_size, kPointerSize));
|
| }
|
| - __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize));
|
| }
|
|
|
|
|
| @@ -3897,9 +3908,18 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
|
|
| __ Set(rax, instr->arity());
|
| __ Move(rbx, instr->hydrogen()->property_cell());
|
| - Handle<Code> array_construct_code =
|
| - isolate()->builtins()->ArrayConstructCode();
|
| - CallCode(array_construct_code, RelocInfo::CONSTRUCT_CALL, instr);
|
| + Object* cell_value = instr->hydrogen()->property_cell()->value();
|
| + ElementsKind kind = static_cast<ElementsKind>(Smi::cast(cell_value)->value());
|
| + if (instr->arity() == 0) {
|
| + ArrayNoArgumentConstructorStub stub(kind);
|
| + CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
|
| + } else if (instr->arity() == 1) {
|
| + ArraySingleArgumentConstructorStub stub(kind);
|
| + CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
|
| + } else {
|
| + ArrayNArgumentsConstructorStub stub(kind);
|
| + CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
|
| + }
|
| }
|
|
|
|
|
| @@ -3917,7 +3937,6 @@ void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
|
|
|
| void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
|
| Register object = ToRegister(instr->object());
|
| - Register value = ToRegister(instr->value());
|
| int offset = instr->offset();
|
|
|
| if (!instr->transition().is_null()) {
|
| @@ -3944,8 +3963,25 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
|
| SmiCheck check_needed =
|
| type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
|
| if (instr->is_in_object()) {
|
| - __ movq(FieldOperand(object, offset), value);
|
| + if (instr->value()->IsConstantOperand()) {
|
| + LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
|
| + if (IsInteger32Constant(operand_value)) {
|
| + int const_value = ToInteger32(operand_value);
|
| + __ movq(FieldOperand(object, offset), Immediate(const_value));
|
| + } else {
|
| + if (operand_value->IsRegister()) {
|
| + __ movq(FieldOperand(object, offset), ToRegister(operand_value));
|
| + } else {
|
| + Handle<Object> handle_value = ToHandle(operand_value);
|
| + __ Move(FieldOperand(object, offset), handle_value);
|
| + }
|
| + }
|
| + } else {
|
| + __ movq(FieldOperand(object, offset), ToRegister(instr->value()));
|
| + }
|
| +
|
| if (instr->hydrogen()->NeedsWriteBarrier()) {
|
| + Register value = ToRegister(instr->value());
|
| Register temp = ToRegister(instr->temp());
|
| // Update the write barrier for the object for in-object properties.
|
| __ RecordWriteField(object,
|
| @@ -3959,8 +3995,26 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
|
| } else {
|
| Register temp = ToRegister(instr->temp());
|
| __ movq(temp, FieldOperand(object, JSObject::kPropertiesOffset));
|
| - __ movq(FieldOperand(temp, offset), value);
|
| +
|
| + if (instr->value()->IsConstantOperand()) {
|
| + LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
|
| + if (IsInteger32Constant(operand_value)) {
|
| + int const_value = ToInteger32(operand_value);
|
| + __ movq(FieldOperand(temp, offset), Immediate(const_value));
|
| + } else {
|
| + if (operand_value->IsRegister()) {
|
| + __ movq(FieldOperand(temp, offset), ToRegister(operand_value));
|
| + } else {
|
| + Handle<Object> handle_value = ToHandle(operand_value);
|
| + __ Move(FieldOperand(temp, offset), handle_value);
|
| + }
|
| + }
|
| + } else {
|
| + __ movq(FieldOperand(temp, offset), ToRegister(instr->value()));
|
| + }
|
| +
|
| if (instr->hydrogen()->NeedsWriteBarrier()) {
|
| + Register value = ToRegister(instr->value());
|
| // Update the write barrier for the properties array.
|
| // object is used as a scratch register.
|
| __ RecordWriteField(temp,
|
| @@ -4136,7 +4190,6 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
|
|
|
|
|
| void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
|
| - Register value = ToRegister(instr->value());
|
| Register elements = ToRegister(instr->elements());
|
| LOperand* key = instr->key();
|
| if (!key->IsConstantOperand()) {
|
| @@ -4161,8 +4214,22 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
|
| FAST_ELEMENTS,
|
| FixedArray::kHeaderSize - kHeapObjectTag,
|
| instr->additional_index());
|
| + if (instr->value()->IsRegister()) {
|
| + __ movq(operand, ToRegister(instr->value()));
|
| + } else {
|
| + LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
|
| + if (IsInteger32Constant(operand_value)) {
|
| + int const_value = ToInteger32(operand_value);
|
| + __ movq(operand, Immediate(const_value));
|
| + } else {
|
| + Handle<Object> handle_value = ToHandle(operand_value);
|
| + __ Move(operand, handle_value);
|
| + }
|
| + }
|
|
|
| if (instr->hydrogen()->NeedsWriteBarrier()) {
|
| + ASSERT(instr->value()->IsRegister());
|
| + Register value = ToRegister(instr->value());
|
| ASSERT(!instr->key()->IsConstantOperand());
|
| HType type = instr->hydrogen()->value()->type();
|
| SmiCheck check_needed =
|
| @@ -4177,9 +4244,12 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
|
| kSaveFPRegs,
|
| EMIT_REMEMBERED_SET,
|
| check_needed);
|
| - } else {
|
| - __ movq(operand, value);
|
| }
|
| +
|
| + // TODO(mvstanton): we don't need this line, do we?
|
| + // else {
|
| + // __ movq(operand, value);
|
| + // }
|
| }
|
|
|
|
|
|
|