# HG changeset patch # User Josef Eisl # Date 1415211515 -3600 # Node ID 79268cfc256a96c1331adb86f9d813349f234961 # Parent 0826409daa24e586cb5661e18bc2cb95ea997ea5 StackSlot is no longer a VirtualStackSlot (rename ForwardingFrameMapBuilder to DelayedFrameMapBuilder). diff -r 0826409daa24 -r 79268cfc256a graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackSlot.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackSlot.java Wed Nov 05 17:30:22 2014 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackSlot.java Wed Nov 05 19:18:35 2014 +0100 @@ -28,7 +28,7 @@ * Represents a compiler spill slot or an outgoing stack-based argument in a method's frame or an * incoming stack-based argument in a method's {@linkplain #isInCallerFrame() caller's frame}. */ -public final class StackSlot extends VirtualStackSlot { +public final class StackSlot extends StackSlotValue { private static final long serialVersionUID = -7725071921307318433L; diff -r 0826409daa24 -r 79268cfc256a graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Wed Nov 05 17:30:22 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Wed Nov 05 19:18:35 2014 +0100 @@ -386,7 +386,7 @@ @Override public FrameMapBuilder newFrameMapBuilder(RegisterConfig registerConfig) { - return new ForwardingFrameMapBuilder(this::newFrameMap, getCodeCache(), registerConfig); + return new DelayedFrameMapBuilder(this::newFrameMap, getCodeCache(), registerConfig); } /** diff -r 0826409daa24 -r 79268cfc256a graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java Wed Nov 05 17:30:22 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java Wed Nov 05 19:18:35 2014 +0100 @@ -157,7 +157,7 @@ @Override public FrameMapBuilder newFrameMapBuilder(RegisterConfig registerConfig) { - return new ForwardingFrameMapBuilder(this::newFrameMap, getCodeCache(), registerConfig); + return new DelayedFrameMapBuilder(this::newFrameMap, getCodeCache(), registerConfig); } @Override diff -r 0826409daa24 -r 79268cfc256a graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Wed Nov 05 17:30:22 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Wed Nov 05 19:18:35 2014 +0100 @@ -73,7 +73,7 @@ @Override public FrameMapBuilder newFrameMapBuilder(RegisterConfig registerConfig) { - return new ForwardingFrameMapBuilder(this::newFrameMap, getCodeCache(), registerConfig); + return new DelayedFrameMapBuilder(this::newFrameMap, getCodeCache(), registerConfig); } @Override diff -r 0826409daa24 -r 79268cfc256a graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMapBuilder.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMapBuilder.java Wed Nov 05 17:30:22 2014 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMapBuilder.java Wed Nov 05 19:18:35 2014 +0100 @@ -24,11 +24,15 @@ import static com.oracle.graal.api.code.ValueUtil.*; +import java.util.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.lir.*; -public class AMD64FrameMapBuilder extends ForwardingFrameMapBuilder { +public class AMD64FrameMapBuilder extends DelayedFrameMapBuilder { + + private TrackedVirtualStackSlot rbpSpillSlot; public AMD64FrameMapBuilder(FrameMapFactory factory, CodeCacheProvider codeCache, RegisterConfig registerConfig) { super(factory, codeCache, registerConfig); @@ -39,9 +43,27 @@ * runtime for walking/inspecting frames of such methods. */ public VirtualStackSlot allocateRBPSpillSlot() { - VirtualStackSlot reservedSlot = allocateSpillSlot(LIRKind.value(Kind.Long)); - assert asStackSlot(reservedSlot).getRawOffset() == -16 : asStackSlot(reservedSlot).getRawOffset(); - return reservedSlot; + rbpSpillSlot = (TrackedVirtualStackSlot) allocateSpillSlot(LIRKind.value(Kind.Long)); + return rbpSpillSlot; } + @Override + public void freeSpillSlot(VirtualStackSlot slot) { + assert slot != null; + if (slot.equals(rbpSpillSlot)) { + rbpSpillSlot = null; + } else { + super.freeSpillSlot(slot); + } + } + + @Override + protected void mapStackSlots(FrameMap frameMap, HashMap mapping) { + if (rbpSpillSlot != null) { + StackSlot reservedSlot = rbpSpillSlot.transform(frameMap); + assert asStackSlot(reservedSlot).getRawOffset() == -16 : asStackSlot(reservedSlot).getRawOffset(); + mapping.put(rbpSpillSlot, reservedSlot); + } + super.mapStackSlots(frameMap, mapping); + } } diff -r 0826409daa24 -r 79268cfc256a graal/com.oracle.graal.lir/src/com/oracle/graal/lir/DelayedFrameMapBuilder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/DelayedFrameMapBuilder.java Wed Nov 05 19:18:35 2014 +0100 @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir; + +import java.util.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.lir.gen.*; + +/** + * A FrameMapBuilder that records allocation. + */ +public class DelayedFrameMapBuilder implements FrameMapBuilder { + + @FunctionalInterface + public interface FrameMapFactory { + FrameMap newFrameMap(FrameMapBuilder frameMapBuilder); + } + + private final RegisterConfig registerConfig; + private final CodeCacheProvider codeCache; + private final FrameMapFactory factory; + private final List stackSlots; + private final List calls; + + public DelayedFrameMapBuilder(FrameMapFactory factory, CodeCacheProvider codeCache, RegisterConfig registerConfig) { + this.registerConfig = registerConfig == null ? codeCache.getRegisterConfig() : registerConfig; + this.codeCache = codeCache; + this.factory = factory; + this.stackSlots = new ArrayList<>(); + this.calls = new ArrayList<>(); + } + + private Set freedSlots; + + public VirtualStackSlot allocateSpillSlot(LIRKind kind) { + if (freedSlots != null) { + for (Iterator iter = freedSlots.iterator(); iter.hasNext();) { + VirtualStackSlot s = iter.next(); + if (s.getLIRKind().equals(kind)) { + iter.remove(); + if (freedSlots.isEmpty()) { + freedSlots = null; + } + return s; + } + } + } + SimpleVirtualStackSlot slot = new SimpleVirtualStackSlot(kind); + stackSlots.add(slot); + return slot; + } + + public abstract class TrackedVirtualStackSlot extends VirtualStackSlot { + /** + * + */ + private static final long serialVersionUID = 408446797222290182L; + + public TrackedVirtualStackSlot(LIRKind lirKind) { + super(lirKind); + } + + public abstract StackSlot transform(FrameMap frameMap); + } + + private class SimpleVirtualStackSlot extends TrackedVirtualStackSlot { + + private static final long serialVersionUID = 7654295701165421750L; + + public SimpleVirtualStackSlot(LIRKind lirKind) { + super(lirKind); + } + + @Override + public StackSlot transform(FrameMap frameMap) { + int size = frameMap.spillSlotSize(getLIRKind()); + frameMap.spillSize = NumUtil.roundUp(frameMap.spillSize + size, size); + return frameMap.allocateNewSpillSlot(getLIRKind(), 0); + } + + } + + private class VirtualStackSlotRange extends TrackedVirtualStackSlot { + + private static final long serialVersionUID = 5152592950118317121L; + private final BitSet objects; + private final int slots; + + public VirtualStackSlotRange(int slots, BitSet objects) { + super(LIRKind.reference(Kind.Object)); + this.slots = slots; + this.objects = (BitSet) objects.clone(); + } + + @Override + public StackSlot transform(FrameMap frameMap) { + frameMap.spillSize += (slots * frameMap.getTarget().wordSize); + + if (!objects.isEmpty()) { + assert objects.length() <= slots; + StackSlot result = null; + for (int slotIndex = 0; slotIndex < slots; slotIndex++) { + StackSlot objectSlot = null; + if (objects.get(slotIndex)) { + objectSlot = frameMap.allocateNewSpillSlot(LIRKind.reference(Kind.Object), slotIndex * frameMap.getTarget().wordSize); + frameMap.addObjectStackSlot(objectSlot); + } + if (slotIndex == 0) { + if (objectSlot != null) { + result = objectSlot; + } else { + result = frameMap.allocateNewSpillSlot(LIRKind.value(frameMap.getTarget().wordKind), 0); + } + } + } + assert result != null; + return result; + + } else { + return frameMap.allocateNewSpillSlot(LIRKind.value(frameMap.getTarget().wordKind), 0); + } + } + + } + + public VirtualStackSlot allocateStackSlots(int slots, BitSet objects, List outObjectStackSlots) { + if (slots == 0) { + return null; + } + if (outObjectStackSlots != null) { + throw GraalInternalError.unimplemented(); + } + VirtualStackSlotRange slot = new VirtualStackSlotRange(slots, objects); + stackSlots.add(slot); + return slot; + } + + public RegisterConfig getRegisterConfig() { + return registerConfig; + } + + public CodeCacheProvider getCodeCache() { + return codeCache; + } + + public void freeSpillSlot(VirtualStackSlot slot) { + if (freedSlots == null) { + freedSlots = new HashSet<>(); + } + freedSlots.add(slot); + } + + public void callsMethod(CallingConvention cc) { + calls.add(cc); + } + + public FrameMap buildFrameMap(LIRGenerationResult res) { + FrameMap frameMap = factory.newFrameMap(this); + HashMap mapping = new HashMap<>(); + // fill + mapStackSlots(frameMap, mapping); + for (CallingConvention cc : calls) { + frameMap.callsMethod(cc); + } + // end fill + if (freedSlots != null) { + // If the freed slots cover the complete spill area (except for the return + // address slot), then the spill size is reset to its initial value. + // Without this, frameNeedsAllocating() would never return true. + int total = 0; + for (VirtualStackSlot s : freedSlots) { + total += frameMap.getTarget().getSizeInBytes(s.getKind()); + } + if (total == frameMap.spillSize - frameMap.initialSpillSize) { + // reset spill area size + frameMap.spillSize = frameMap.initialSpillSize; + } + freedSlots = null; + } + frameMap.finish(); + return frameMap; + } + + protected void mapStackSlots(FrameMap frameMap, HashMap mapping) { + for (TrackedVirtualStackSlot virtualSlot : stackSlots) { + StackSlot slot = virtualSlot.transform(frameMap); + mapping.put(virtualSlot, slot); + } + } + +} diff -r 0826409daa24 -r 79268cfc256a graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ForwardingFrameMapBuilder.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ForwardingFrameMapBuilder.java Wed Nov 05 17:30:22 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.lir; - -import java.util.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.asm.*; -import com.oracle.graal.lir.gen.*; - -/** - * A simple forwarder to {@link FrameMap}. - */ -public class ForwardingFrameMapBuilder implements FrameMapBuilder { - - @FunctionalInterface - public interface FrameMapFactory { - FrameMap newFrameMap(FrameMapBuilder frameMapBuilder); - } - - private final FrameMap frameMap; - private final RegisterConfig registerConfig; - private final CodeCacheProvider codeCache; - - public ForwardingFrameMapBuilder(FrameMapFactory factory, CodeCacheProvider codeCache, RegisterConfig registerConfig) { - this.registerConfig = registerConfig == null ? codeCache.getRegisterConfig() : registerConfig; - this.codeCache = codeCache; - // all members must be set up before calling FrameMapFactory#newFrameMap - this.frameMap = factory.newFrameMap(this); - } - - private Set freedSlots; - - public VirtualStackSlot allocateSpillSlot(LIRKind kind) { - if (freedSlots != null) { - for (Iterator iter = freedSlots.iterator(); iter.hasNext();) { - VirtualStackSlot s = iter.next(); - if (s.getLIRKind().equals(kind)) { - iter.remove(); - if (freedSlots.isEmpty()) { - freedSlots = null; - } - return s; - } - } - } - int size = frameMap.spillSlotSize(kind); - frameMap.spillSize = NumUtil.roundUp(frameMap.spillSize + size, size); - return frameMap.allocateNewSpillSlot(kind, 0); - } - - public VirtualStackSlot allocateStackSlots(int slots, BitSet objects, List outObjectStackSlots) { - if (slots == 0) { - return null; - } - frameMap.spillSize += (slots * frameMap.getTarget().wordSize); - - if (!objects.isEmpty()) { - assert objects.length() <= slots; - StackSlot result = null; - for (int slotIndex = 0; slotIndex < slots; slotIndex++) { - StackSlot objectSlot = null; - if (objects.get(slotIndex)) { - objectSlot = frameMap.allocateNewSpillSlot(LIRKind.reference(Kind.Object), slotIndex * frameMap.getTarget().wordSize); - frameMap.addObjectStackSlot(objectSlot); - if (outObjectStackSlots != null) { - outObjectStackSlots.add(objectSlot); - } - } - if (slotIndex == 0) { - if (objectSlot != null) { - result = objectSlot; - } else { - result = frameMap.allocateNewSpillSlot(LIRKind.value(frameMap.getTarget().wordKind), 0); - } - } - } - assert result != null; - return result; - - } else { - return frameMap.allocateNewSpillSlot(LIRKind.value(frameMap.getTarget().wordKind), 0); - } - } - - public RegisterConfig getRegisterConfig() { - return registerConfig; - } - - public CodeCacheProvider getCodeCache() { - return codeCache; - } - - public void freeSpillSlot(VirtualStackSlot slot) { - if (freedSlots == null) { - freedSlots = new HashSet<>(); - } - freedSlots.add(slot); - } - - public void callsMethod(CallingConvention cc) { - frameMap.callsMethod(cc); - } - - public FrameMap buildFrameMap(LIRGenerationResult res) { - if (freedSlots != null) { - // If the freed slots cover the complete spill area (except for the return - // address slot), then the spill size is reset to its initial value. - // Without this, frameNeedsAllocating() would never return true. - int total = 0; - for (VirtualStackSlot s : freedSlots) { - total += frameMap.getTarget().getSizeInBytes(s.getKind()); - } - if (total == frameMap.spillSize - frameMap.initialSpillSize) { - // reset spill area size - frameMap.spillSize = frameMap.initialSpillSize; - } - freedSlots = null; - } - frameMap.finish(); - return frameMap; - } - -}