diff -r 13588c901957 -r 9cf78a70fa4f src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java Thu Oct 17 20:27:44 2019 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java Thu Oct 17 20:53:35 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -38,6 +38,7 @@ import static org.graalvm.compiler.lir.LIRValueUtil.asConstant; import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue; +import java.util.EnumSet; import java.util.function.Function; import org.graalvm.compiler.asm.Label; @@ -48,6 +49,7 @@ import org.graalvm.compiler.core.aarch64.AArch64LIRGenerator; import org.graalvm.compiler.core.aarch64.AArch64LIRKindTool; import org.graalvm.compiler.core.common.CompressEncoding; +import org.graalvm.compiler.core.common.GraalOptions; import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.calc.Condition; import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor; @@ -68,7 +70,7 @@ import org.graalvm.compiler.lir.LIRFrameState; import org.graalvm.compiler.lir.LIRInstruction; import org.graalvm.compiler.lir.LabelRef; -import org.graalvm.compiler.lir.StandardOp.SaveRegistersOp; +import org.graalvm.compiler.lir.StandardOp.ZapRegistersOp; import org.graalvm.compiler.lir.SwitchStrategy; import org.graalvm.compiler.lir.Variable; import org.graalvm.compiler.lir.VirtualStackSlot; @@ -167,10 +169,9 @@ /** * @param savedRegisters the registers saved by this operation which may be subject to pruning * @param savedRegisterLocations the slots to which the registers are saved - * @param supportsRemove determines if registers can be pruned */ - protected AArch64SaveRegistersOp emitSaveRegisters(Register[] savedRegisters, AllocatableValue[] savedRegisterLocations, boolean supportsRemove) { - AArch64SaveRegistersOp save = new AArch64SaveRegistersOp(savedRegisters, savedRegisterLocations, supportsRemove); + protected AArch64SaveRegistersOp emitSaveRegisters(Register[] savedRegisters, AllocatableValue[] savedRegisterLocations) { + AArch64SaveRegistersOp save = new AArch64SaveRegistersOp(savedRegisters, savedRegisterLocations); append(save); return save; } @@ -182,7 +183,7 @@ PlatformKind kind = target().arch.getLargestStorableKind(register.getRegisterCategory()); if (kind.getVectorLength() > 1) { // we don't use vector registers, so there is no need to save them - kind = AArch64Kind.QWORD; + kind = AArch64Kind.DOUBLE; } return getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(kind)); } @@ -190,15 +191,14 @@ /** * Adds a node to the graph that saves all allocatable registers to the stack. * - * @param supportsRemove determines if registers can be pruned * @return the register save node */ - private AArch64SaveRegistersOp emitSaveAllRegisters(Register[] savedRegisters, boolean supportsRemove) { + private AArch64SaveRegistersOp emitSaveAllRegisters(Register[] savedRegisters) { AllocatableValue[] savedRegisterLocations = new AllocatableValue[savedRegisters.length]; for (int i = 0; i < savedRegisters.length; i++) { savedRegisterLocations[i] = allocateSaveRegisterLocation(savedRegisters[i]); } - return emitSaveRegisters(savedRegisters, savedRegisterLocations, supportsRemove); + return emitSaveRegisters(savedRegisters, savedRegisterLocations); } protected void emitRestoreRegisters(AArch64SaveRegistersOp save) { @@ -347,11 +347,9 @@ AArch64SaveRegistersOp save = null; Stub stub = getStub(); - if (destroysRegisters) { - if (stub != null && stub.preservesRegisters()) { - Register[] savedRegisters = getRegisterConfig().getAllocatableRegisters().toArray(); - save = emitSaveAllRegisters(savedRegisters, true); - } + if (destroysRegisters && stub != null && stub.shouldSaveRegistersAroundCalls()) { + Register[] savedRegisters = getRegisterConfig().getAllocatableRegisters().toArray(); + save = emitSaveAllRegisters(savedRegisters); } Variable result; @@ -379,19 +377,15 @@ result = super.emitForeignCall(hotspotLinkage, debugInfo, args); } - if (destroysRegisters) { - if (stub != null) { - if (stub.preservesRegisters()) { - HotSpotLIRGenerationResult generationResult = getResult(); - LIRFrameState key = currentRuntimeCallInfo; - if (key == null) { - key = LIRFrameState.NO_STATE; - } - assert !generationResult.getCalleeSaveInfo().containsKey(key); - generationResult.getCalleeSaveInfo().put(key, save); - emitRestoreRegisters(save); - } + if (save != null) { + HotSpotLIRGenerationResult generationResult = getResult(); + LIRFrameState key = currentRuntimeCallInfo; + if (key == null) { + key = LIRFrameState.NO_STATE; } + assert !generationResult.getCalleeSaveInfo().containsKey(key); + generationResult.getCalleeSaveInfo().put(key, save); + emitRestoreRegisters(save); } return result; @@ -539,7 +533,7 @@ } @Override - public SaveRegistersOp createZapRegisters(Register[] zappedRegisters, JavaConstant[] zapValues) { + public ZapRegistersOp createZapRegisters(Register[] zappedRegisters, JavaConstant[] zapValues) { throw GraalError.unimplemented(); } @@ -547,4 +541,27 @@ public LIRInstruction createZapArgumentSpace(StackSlot[] zappedStack, JavaConstant[] zapValues) { throw GraalError.unimplemented(); } + + @Override + public void emitZeroMemory(Value address, Value length, boolean isAligned) { + int dczidValue = config.psrInfoDczidValue; + EnumSet flags = ((AArch64) target().arch).getFlags(); + + // ARMv8-A architecture reference manual D12.2.35 Data Cache Zero ID register says: + // * BS, bits [3:0] indicate log2 of the DC ZVA block size in (4-byte) words. + // * DZP, bit [4] of indicates whether use of DC ZVA instruction is prohibited. + int zvaLength = 4 << (dczidValue & 0xF); + boolean isDcZvaProhibited = ((dczidValue & 0x10) != 0); + + // Use DC ZVA if it's not prohibited and AArch64 HotSpot flag UseBlockZeroing is on. + boolean useDcZva = !isDcZvaProhibited && flags.contains(AArch64.Flag.UseBlockZeroing); + + // Set zva length negative (unknown at compile-time) for AOT compilation, since the value + // could be different on different AArch64 CPU implementations. + if (GraalOptions.ImmutableCode.getValue(getResult().getLIR().getOptions())) { + useDcZva = false; + } + + emitZeroMemory(address, length, isAligned, useDcZva, zvaLength); + } }