| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/arm64/lithium-codegen-arm64.h" | 5 #include "src/crankshaft/arm64/lithium-codegen-arm64.h" |
| 6 | 6 |
| 7 #include "src/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
| 8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 } else { | 431 } else { |
| 432 UNREACHABLE(); | 432 UNREACHABLE(); |
| 433 } | 433 } |
| 434 } | 434 } |
| 435 | 435 |
| 436 | 436 |
| 437 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, | 437 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, |
| 438 int argc, | 438 int argc, |
| 439 LInstruction* instr, | 439 LInstruction* instr, |
| 440 LOperand* context) { | 440 LOperand* context) { |
| 441 LoadContextFromDeferred(context); | 441 if (context != nullptr) LoadContextFromDeferred(context); |
| 442 __ CallRuntimeSaveDoubles(id); | 442 __ CallRuntimeSaveDoubles(id); |
| 443 RecordSafepointWithRegisters( | 443 RecordSafepointWithRegisters( |
| 444 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt); | 444 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt); |
| 445 } | 445 } |
| 446 | 446 |
| 447 | 447 |
| 448 void LCodeGen::RecordSafepointWithLazyDeopt(LInstruction* instr, | 448 void LCodeGen::RecordSafepointWithLazyDeopt(LInstruction* instr, |
| 449 SafepointMode safepoint_mode) { | 449 SafepointMode safepoint_mode) { |
| 450 if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) { | 450 if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) { |
| 451 RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt); | 451 RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt); |
| (...skipping 996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1448 } | 1448 } |
| 1449 | 1449 |
| 1450 | 1450 |
| 1451 void LCodeGen::DoDeferredAllocate(LAllocate* instr) { | 1451 void LCodeGen::DoDeferredAllocate(LAllocate* instr) { |
| 1452 // TODO(3095996): Get rid of this. For now, we need to make the | 1452 // TODO(3095996): Get rid of this. For now, we need to make the |
| 1453 // result register contain a valid pointer because it is already | 1453 // result register contain a valid pointer because it is already |
| 1454 // contained in the register pointer map. | 1454 // contained in the register pointer map. |
| 1455 __ Mov(ToRegister(instr->result()), Smi::FromInt(0)); | 1455 __ Mov(ToRegister(instr->result()), Smi::FromInt(0)); |
| 1456 | 1456 |
| 1457 PushSafepointRegistersScope scope(this); | 1457 PushSafepointRegistersScope scope(this); |
| 1458 LoadContextFromDeferred(instr->context()); |
| 1458 // We're in a SafepointRegistersScope so we can use any scratch registers. | 1459 // We're in a SafepointRegistersScope so we can use any scratch registers. |
| 1459 Register size = x0; | 1460 Register size = x0; |
| 1460 if (instr->size()->IsConstantOperand()) { | 1461 if (instr->size()->IsConstantOperand()) { |
| 1461 __ Mov(size, ToSmi(LConstantOperand::cast(instr->size()))); | 1462 __ Mov(size, ToSmi(LConstantOperand::cast(instr->size()))); |
| 1462 } else { | 1463 } else { |
| 1463 __ SmiTag(size, ToRegister32(instr->size()).X()); | 1464 __ SmiTag(size, ToRegister32(instr->size()).X()); |
| 1464 } | 1465 } |
| 1465 int flags = AllocateDoubleAlignFlag::encode( | 1466 int flags = AllocateDoubleAlignFlag::encode( |
| 1466 instr->hydrogen()->MustAllocateDoubleAligned()); | 1467 instr->hydrogen()->MustAllocateDoubleAligned()); |
| 1467 if (instr->hydrogen()->IsOldSpaceAllocation()) { | 1468 if (instr->hydrogen()->IsOldSpaceAllocation()) { |
| 1468 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); | 1469 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); |
| 1469 flags = AllocateTargetSpace::update(flags, OLD_SPACE); | 1470 flags = AllocateTargetSpace::update(flags, OLD_SPACE); |
| 1470 } else { | 1471 } else { |
| 1471 flags = AllocateTargetSpace::update(flags, NEW_SPACE); | 1472 flags = AllocateTargetSpace::update(flags, NEW_SPACE); |
| 1472 } | 1473 } |
| 1473 __ Mov(x10, Smi::FromInt(flags)); | 1474 __ Mov(x10, Smi::FromInt(flags)); |
| 1474 __ Push(size, x10); | 1475 __ Push(size, x10); |
| 1475 | 1476 |
| 1476 CallRuntimeFromDeferred( | 1477 CallRuntimeFromDeferred(Runtime::kAllocateInTargetSpace, 2, instr, nullptr); |
| 1477 Runtime::kAllocateInTargetSpace, 2, instr, instr->context()); | |
| 1478 __ StoreToSafepointRegisterSlot(x0, ToRegister(instr->result())); | 1478 __ StoreToSafepointRegisterSlot(x0, ToRegister(instr->result())); |
| 1479 | 1479 |
| 1480 if (instr->hydrogen()->IsAllocationFoldingDominator()) { | 1480 if (instr->hydrogen()->IsAllocationFoldingDominator()) { |
| 1481 AllocationFlags allocation_flags = NO_ALLOCATION_FLAGS; | 1481 AllocationFlags allocation_flags = NO_ALLOCATION_FLAGS; |
| 1482 if (instr->hydrogen()->IsOldSpaceAllocation()) { | 1482 if (instr->hydrogen()->IsOldSpaceAllocation()) { |
| 1483 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); | 1483 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); |
| 1484 allocation_flags = static_cast<AllocationFlags>(flags | PRETENURE); | 1484 allocation_flags = static_cast<AllocationFlags>(flags | PRETENURE); |
| 1485 } | 1485 } |
| 1486 // If the allocation folding dominator allocate triggered a GC, allocation | 1486 // If the allocation folding dominator allocate triggered a GC, allocation |
| 1487 // happend in the runtime. We have to reset the top pointer to virtually | 1487 // happend in the runtime. We have to reset the top pointer to virtually |
| (...skipping 2700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4188 | 4188 |
| 4189 | 4189 |
| 4190 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { | 4190 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { |
| 4191 // TODO(3095996): Get rid of this. For now, we need to make the | 4191 // TODO(3095996): Get rid of this. For now, we need to make the |
| 4192 // result register contain a valid pointer because it is already | 4192 // result register contain a valid pointer because it is already |
| 4193 // contained in the register pointer map. | 4193 // contained in the register pointer map. |
| 4194 Register result = ToRegister(instr->result()); | 4194 Register result = ToRegister(instr->result()); |
| 4195 __ Mov(result, 0); | 4195 __ Mov(result, 0); |
| 4196 | 4196 |
| 4197 PushSafepointRegistersScope scope(this); | 4197 PushSafepointRegistersScope scope(this); |
| 4198 // NumberTagU and NumberTagD use the context from the frame, rather than | 4198 // Reset the context register. |
| 4199 // the environment's HContext or HInlinedContext value. | 4199 if (!result.is(cp)) { |
| 4200 // They only call Runtime::kAllocateHeapNumber. | 4200 __ Mov(cp, 0); |
| 4201 // The corresponding HChange instructions are added in a phase that does | 4201 } |
| 4202 // not have easy access to the local context. | |
| 4203 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
| 4204 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 4202 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |
| 4205 RecordSafepointWithRegisters( | 4203 RecordSafepointWithRegisters( |
| 4206 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 4204 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
| 4207 __ StoreToSafepointRegisterSlot(x0, result); | 4205 __ StoreToSafepointRegisterSlot(x0, result); |
| 4208 } | 4206 } |
| 4209 | 4207 |
| 4210 | 4208 |
| 4211 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { | 4209 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { |
| 4212 class DeferredNumberTagD: public LDeferredCode { | 4210 class DeferredNumberTagD: public LDeferredCode { |
| 4213 public: | 4211 public: |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4253 | 4251 |
| 4254 // Slow case: call the runtime system to do the number allocation. | 4252 // Slow case: call the runtime system to do the number allocation. |
| 4255 __ Bind(&slow); | 4253 __ Bind(&slow); |
| 4256 // TODO(3095996): Put a valid pointer value in the stack slot where the result | 4254 // TODO(3095996): Put a valid pointer value in the stack slot where the result |
| 4257 // register is stored, as this register is in the pointer map, but contains an | 4255 // register is stored, as this register is in the pointer map, but contains an |
| 4258 // integer value. | 4256 // integer value. |
| 4259 __ Mov(dst, 0); | 4257 __ Mov(dst, 0); |
| 4260 { | 4258 { |
| 4261 // Preserve the value of all registers. | 4259 // Preserve the value of all registers. |
| 4262 PushSafepointRegistersScope scope(this); | 4260 PushSafepointRegistersScope scope(this); |
| 4263 | 4261 // Reset the context register. |
| 4264 // NumberTagU and NumberTagD use the context from the frame, rather than | 4262 if (!dst.is(cp)) { |
| 4265 // the environment's HContext or HInlinedContext value. | 4263 __ Mov(cp, 0); |
| 4266 // They only call Runtime::kAllocateHeapNumber. | 4264 } |
| 4267 // The corresponding HChange instructions are added in a phase that does | |
| 4268 // not have easy access to the local context. | |
| 4269 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
| 4270 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 4265 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |
| 4271 RecordSafepointWithRegisters( | 4266 RecordSafepointWithRegisters( |
| 4272 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 4267 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
| 4273 __ StoreToSafepointRegisterSlot(x0, dst); | 4268 __ StoreToSafepointRegisterSlot(x0, dst); |
| 4274 } | 4269 } |
| 4275 | 4270 |
| 4276 // Convert number to floating point and store in the newly allocated heap | 4271 // Convert number to floating point and store in the newly allocated heap |
| 4277 // number. | 4272 // number. |
| 4278 __ Bind(&convert_and_store); | 4273 __ Bind(&convert_and_store); |
| 4279 DoubleRegister dbl_scratch = double_scratch(); | 4274 DoubleRegister dbl_scratch = double_scratch(); |
| (...skipping 1439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5719 // Index is equal to negated out of object property index plus 1. | 5714 // Index is equal to negated out of object property index plus 1. |
| 5720 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5715 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
| 5721 __ Ldr(result, FieldMemOperand(result, | 5716 __ Ldr(result, FieldMemOperand(result, |
| 5722 FixedArray::kHeaderSize - kPointerSize)); | 5717 FixedArray::kHeaderSize - kPointerSize)); |
| 5723 __ Bind(deferred->exit()); | 5718 __ Bind(deferred->exit()); |
| 5724 __ Bind(&done); | 5719 __ Bind(&done); |
| 5725 } | 5720 } |
| 5726 | 5721 |
| 5727 } // namespace internal | 5722 } // namespace internal |
| 5728 } // namespace v8 | 5723 } // namespace v8 |
| OLD | NEW |