| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/crankshaft/arm/lithium-codegen-arm.h" | 5 #include "src/crankshaft/arm/lithium-codegen-arm.h" |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/crankshaft/arm/lithium-gap-resolver-arm.h" | 10 #include "src/crankshaft/arm/lithium-gap-resolver-arm.h" |
| (...skipping 4478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4489 } | 4489 } |
| 4490 __ vmov(dbl_scratch.low(), src); | 4490 __ vmov(dbl_scratch.low(), src); |
| 4491 __ vcvt_f64_s32(dbl_scratch, dbl_scratch.low()); | 4491 __ vcvt_f64_s32(dbl_scratch, dbl_scratch.low()); |
| 4492 } else { | 4492 } else { |
| 4493 __ vmov(dbl_scratch.low(), src); | 4493 __ vmov(dbl_scratch.low(), src); |
| 4494 __ vcvt_f64_u32(dbl_scratch, dbl_scratch.low()); | 4494 __ vcvt_f64_u32(dbl_scratch, dbl_scratch.low()); |
| 4495 } | 4495 } |
| 4496 | 4496 |
| 4497 if (FLAG_inline_new) { | 4497 if (FLAG_inline_new) { |
| 4498 __ LoadRoot(tmp3, Heap::kHeapNumberMapRootIndex); | 4498 __ LoadRoot(tmp3, Heap::kHeapNumberMapRootIndex); |
| 4499 __ AllocateHeapNumber(dst, tmp1, tmp2, tmp3, &slow, DONT_TAG_RESULT); | 4499 __ AllocateHeapNumber(dst, tmp1, tmp2, tmp3, &slow); |
| 4500 __ b(&done); | 4500 __ b(&done); |
| 4501 } | 4501 } |
| 4502 | 4502 |
| 4503 // Slow case: Call the runtime system to do the number allocation. | 4503 // Slow case: Call the runtime system to do the number allocation. |
| 4504 __ bind(&slow); | 4504 __ bind(&slow); |
| 4505 { | 4505 { |
| 4506 // TODO(3095996): Put a valid pointer value in the stack slot where the | 4506 // TODO(3095996): Put a valid pointer value in the stack slot where the |
| 4507 // result register is stored, as this register is in the pointer map, but | 4507 // result register is stored, as this register is in the pointer map, but |
| 4508 // contains an integer value. | 4508 // contains an integer value. |
| 4509 __ mov(dst, Operand::Zero()); | 4509 __ mov(dst, Operand::Zero()); |
| 4510 | 4510 |
| 4511 // Preserve the value of all registers. | 4511 // Preserve the value of all registers. |
| 4512 PushSafepointRegistersScope scope(this); | 4512 PushSafepointRegistersScope scope(this); |
| 4513 | 4513 |
| 4514 // NumberTagI and NumberTagD use the context from the frame, rather than | 4514 // NumberTagI and NumberTagD use the context from the frame, rather than |
| 4515 // the environment's HContext or HInlinedContext value. | 4515 // the environment's HContext or HInlinedContext value. |
| 4516 // They only call Runtime::kAllocateHeapNumber. | 4516 // They only call Runtime::kAllocateHeapNumber. |
| 4517 // The corresponding HChange instructions are added in a phase that does | 4517 // The corresponding HChange instructions are added in a phase that does |
| 4518 // not have easy access to the local context. | 4518 // not have easy access to the local context. |
| 4519 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4519 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4520 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 4520 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |
| 4521 RecordSafepointWithRegisters( | 4521 RecordSafepointWithRegisters( |
| 4522 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 4522 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
| 4523 __ sub(r0, r0, Operand(kHeapObjectTag)); | |
| 4524 __ StoreToSafepointRegisterSlot(r0, dst); | 4523 __ StoreToSafepointRegisterSlot(r0, dst); |
| 4525 } | 4524 } |
| 4526 | 4525 |
| 4527 // Done. Put the value in dbl_scratch into the value of the allocated heap | 4526 // Done. Put the value in dbl_scratch into the value of the allocated heap |
| 4528 // number. | 4527 // number. |
| 4529 __ bind(&done); | 4528 __ bind(&done); |
| 4530 __ vstr(dbl_scratch, dst, HeapNumber::kValueOffset); | 4529 __ vstr(dbl_scratch, FieldMemOperand(dst, HeapNumber::kValueOffset)); |
| 4531 __ add(dst, dst, Operand(kHeapObjectTag)); | |
| 4532 } | 4530 } |
| 4533 | 4531 |
| 4534 | 4532 |
| 4535 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { | 4533 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { |
| 4536 class DeferredNumberTagD final : public LDeferredCode { | 4534 class DeferredNumberTagD final : public LDeferredCode { |
| 4537 public: | 4535 public: |
| 4538 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) | 4536 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) |
| 4539 : LDeferredCode(codegen), instr_(instr) { } | 4537 : LDeferredCode(codegen), instr_(instr) { } |
| 4540 void Generate() override { codegen()->DoDeferredNumberTagD(instr_); } | 4538 void Generate() override { codegen()->DoDeferredNumberTagD(instr_); } |
| 4541 LInstruction* instr() override { return instr_; } | 4539 LInstruction* instr() override { return instr_; } |
| 4542 | 4540 |
| 4543 private: | 4541 private: |
| 4544 LNumberTagD* instr_; | 4542 LNumberTagD* instr_; |
| 4545 }; | 4543 }; |
| 4546 | 4544 |
| 4547 DwVfpRegister input_reg = ToDoubleRegister(instr->value()); | 4545 DwVfpRegister input_reg = ToDoubleRegister(instr->value()); |
| 4548 Register scratch = scratch0(); | 4546 Register scratch = scratch0(); |
| 4549 Register reg = ToRegister(instr->result()); | 4547 Register reg = ToRegister(instr->result()); |
| 4550 Register temp1 = ToRegister(instr->temp()); | 4548 Register temp1 = ToRegister(instr->temp()); |
| 4551 Register temp2 = ToRegister(instr->temp2()); | 4549 Register temp2 = ToRegister(instr->temp2()); |
| 4552 | 4550 |
| 4553 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); | 4551 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); |
| 4554 if (FLAG_inline_new) { | 4552 if (FLAG_inline_new) { |
| 4555 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); | 4553 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); |
| 4556 // We want the untagged address first for performance | 4554 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry()); |
| 4557 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), | |
| 4558 DONT_TAG_RESULT); | |
| 4559 } else { | 4555 } else { |
| 4560 __ jmp(deferred->entry()); | 4556 __ jmp(deferred->entry()); |
| 4561 } | 4557 } |
| 4562 __ bind(deferred->exit()); | 4558 __ bind(deferred->exit()); |
| 4563 __ vstr(input_reg, reg, HeapNumber::kValueOffset); | 4559 __ vstr(input_reg, FieldMemOperand(reg, HeapNumber::kValueOffset)); |
| 4564 // Now that we have finished with the object's real address tag it | |
| 4565 __ add(reg, reg, Operand(kHeapObjectTag)); | |
| 4566 } | 4560 } |
| 4567 | 4561 |
| 4568 | 4562 |
| 4569 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { | 4563 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { |
| 4570 // TODO(3095996): Get rid of this. For now, we need to make the | 4564 // TODO(3095996): Get rid of this. For now, we need to make the |
| 4571 // result register contain a valid pointer because it is already | 4565 // result register contain a valid pointer because it is already |
| 4572 // contained in the register pointer map. | 4566 // contained in the register pointer map. |
| 4573 Register reg = ToRegister(instr->result()); | 4567 Register reg = ToRegister(instr->result()); |
| 4574 __ mov(reg, Operand::Zero()); | 4568 __ mov(reg, Operand::Zero()); |
| 4575 | 4569 |
| 4576 PushSafepointRegistersScope scope(this); | 4570 PushSafepointRegistersScope scope(this); |
| 4577 // NumberTagI and NumberTagD use the context from the frame, rather than | 4571 // NumberTagI and NumberTagD use the context from the frame, rather than |
| 4578 // the environment's HContext or HInlinedContext value. | 4572 // the environment's HContext or HInlinedContext value. |
| 4579 // They only call Runtime::kAllocateHeapNumber. | 4573 // They only call Runtime::kAllocateHeapNumber. |
| 4580 // The corresponding HChange instructions are added in a phase that does | 4574 // The corresponding HChange instructions are added in a phase that does |
| 4581 // not have easy access to the local context. | 4575 // not have easy access to the local context. |
| 4582 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4576 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4583 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 4577 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |
| 4584 RecordSafepointWithRegisters( | 4578 RecordSafepointWithRegisters( |
| 4585 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 4579 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
| 4586 __ sub(r0, r0, Operand(kHeapObjectTag)); | |
| 4587 __ StoreToSafepointRegisterSlot(r0, reg); | 4580 __ StoreToSafepointRegisterSlot(r0, reg); |
| 4588 } | 4581 } |
| 4589 | 4582 |
| 4590 | 4583 |
| 4591 void LCodeGen::DoSmiTag(LSmiTag* instr) { | 4584 void LCodeGen::DoSmiTag(LSmiTag* instr) { |
| 4592 HChange* hchange = instr->hydrogen(); | 4585 HChange* hchange = instr->hydrogen(); |
| 4593 Register input = ToRegister(instr->value()); | 4586 Register input = ToRegister(instr->value()); |
| 4594 Register output = ToRegister(instr->result()); | 4587 Register output = ToRegister(instr->result()); |
| 4595 if (hchange->CheckFlag(HValue::kCanOverflow) && | 4588 if (hchange->CheckFlag(HValue::kCanOverflow) && |
| 4596 hchange->value()->CheckFlag(HValue::kUint32)) { | 4589 hchange->value()->CheckFlag(HValue::kUint32)) { |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5100 }; | 5093 }; |
| 5101 | 5094 |
| 5102 DeferredAllocate* deferred = | 5095 DeferredAllocate* deferred = |
| 5103 new(zone()) DeferredAllocate(this, instr); | 5096 new(zone()) DeferredAllocate(this, instr); |
| 5104 | 5097 |
| 5105 Register result = ToRegister(instr->result()); | 5098 Register result = ToRegister(instr->result()); |
| 5106 Register scratch = ToRegister(instr->temp1()); | 5099 Register scratch = ToRegister(instr->temp1()); |
| 5107 Register scratch2 = ToRegister(instr->temp2()); | 5100 Register scratch2 = ToRegister(instr->temp2()); |
| 5108 | 5101 |
| 5109 // Allocate memory for the object. | 5102 // Allocate memory for the object. |
| 5110 AllocationFlags flags = TAG_OBJECT; | 5103 AllocationFlags flags = NO_ALLOCATION_FLAGS; |
| 5111 if (instr->hydrogen()->MustAllocateDoubleAligned()) { | 5104 if (instr->hydrogen()->MustAllocateDoubleAligned()) { |
| 5112 flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); | 5105 flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); |
| 5113 } | 5106 } |
| 5114 if (instr->hydrogen()->IsOldSpaceAllocation()) { | 5107 if (instr->hydrogen()->IsOldSpaceAllocation()) { |
| 5115 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); | 5108 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); |
| 5116 flags = static_cast<AllocationFlags>(flags | PRETENURE); | 5109 flags = static_cast<AllocationFlags>(flags | PRETENURE); |
| 5117 } | 5110 } |
| 5118 | 5111 |
| 5119 if (instr->size()->IsConstantOperand()) { | 5112 if (instr->size()->IsConstantOperand()) { |
| 5120 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); | 5113 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5541 __ ldr(result, FieldMemOperand(scratch, | 5534 __ ldr(result, FieldMemOperand(scratch, |
| 5542 FixedArray::kHeaderSize - kPointerSize)); | 5535 FixedArray::kHeaderSize - kPointerSize)); |
| 5543 __ bind(deferred->exit()); | 5536 __ bind(deferred->exit()); |
| 5544 __ bind(&done); | 5537 __ bind(&done); |
| 5545 } | 5538 } |
| 5546 | 5539 |
| 5547 #undef __ | 5540 #undef __ |
| 5548 | 5541 |
| 5549 } // namespace internal | 5542 } // namespace internal |
| 5550 } // namespace v8 | 5543 } // namespace v8 |
| OLD | NEW |