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 |