# HG changeset patch # User Thomas Wuerthinger # Date 1396719330 -7200 # Node ID a0dbb3628f2a1c2a2e96e713750138f1565bd8ff # Parent 82ff6c8c8f6eb19d02b84cc548ac2e55b1354582 Allow limiting maximum frame size in register configuration and bailout if it exceeds the specified limit. diff -r 82ff6c8c8f6e -r a0dbb3628f2a graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterConfig.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterConfig.java Sat Apr 05 19:11:07 2014 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterConfig.java Sat Apr 05 19:35:30 2014 +0200 @@ -37,13 +37,20 @@ Register getReturnRegister(Kind kind); /** + * Gets the maximum allowed size of the frame. + */ + default int getMaximumFrameSize() { + return Integer.MAX_VALUE; + } + + /** * Gets the register to which {@link Register#Frame} and {@link Register#CallerFrame} are bound. */ Register getFrameRegister(); /** * Gets the calling convention describing how arguments are passed. - * + * * @param type the type of calling convention being requested * @param returnType the return type (can be null for methods returning {@code void}) * @param parameterTypes the types of the arguments of the call @@ -55,7 +62,7 @@ /** * Gets the ordered set of registers that are can be used to pass parameters according to a * given calling convention. - * + * * @param type the type of calling convention * @param kind specifies what kind of registers is being requested * @return the ordered set of registers that may be used to pass parameters in a call conforming @@ -81,7 +88,7 @@ /** * Gets the layout of the callee save area of this register configuration. - * + * * @return {@code null} if there is no callee save area */ CalleeSaveLayout getCalleeSaveLayout(); @@ -89,7 +96,7 @@ /** * Gets a map from register {@linkplain Register#number numbers} to register * {@linkplain RegisterAttributes attributes} for this register configuration. - * + * * @return an array where an element at index i holds the attributes of the register whose * number is i */ @@ -97,7 +104,7 @@ /** * Gets the register corresponding to a runtime-defined role. - * + * * @param id the identifier of a runtime-defined register role * @return the register playing the role specified by {@code id} */ diff -r 82ff6c8c8f6e -r a0dbb3628f2a graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Sat Apr 05 19:11:07 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Sat Apr 05 19:35:30 2014 +0200 @@ -42,6 +42,8 @@ private final Register[] allocatable; + private final int maxFrameSize; + /** * The same as {@link #allocatable}, except if parameter registers are removed with the * {@link GraalOptions#RegisterPressure} option. The caller saved registers always include all @@ -55,6 +57,10 @@ private final RegisterAttributes[] attributesMap; + public int getMaximumFrameSize() { + return maxFrameSize; + } + @Override public Register[] getAllocatableRegisters() { return allocatable.clone(); @@ -136,6 +142,7 @@ public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) { this.architecture = architecture; + this.maxFrameSize = config.maxFrameSize; if (config.windowsOs) { javaGeneralParameterRegisters = new Register[]{rdx, r8, r9, rdi, rsi, rcx}; diff -r 82ff6c8c8f6e -r a0dbb3628f2a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Sat Apr 05 19:11:07 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Sat Apr 05 19:35:30 2014 +0200 @@ -59,6 +59,11 @@ return false; } + /** + * Maximum allowed size of allocated area for a frame. + */ + public final int maxFrameSize = 16 * 1024; + HotSpotVMConfig(CompilerToVM compilerToVm) { /** These fields are set in {@link CompilerToVM#initializeConfiguration}. */ gHotSpotVMStructs = 0; diff -r 82ff6c8c8f6e -r a0dbb3628f2a graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Sat Apr 05 19:11:07 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Sat Apr 05 19:35:30 2014 +0200 @@ -114,7 +114,7 @@ /** * Gets the frame size of the compiled frame, not including the size of the * {@link Architecture#getReturnAddressSize() return address slot}. - * + * * @return The size of the frame (in bytes). */ public int frameSize() { @@ -138,7 +138,7 @@ /** * Gets the total frame size of the compiled frame, including the size of the * {@link Architecture#getReturnAddressSize() return address slot}. - * + * * @return The total size of the frame (in bytes). */ public abstract int totalFrameSize(); @@ -151,7 +151,7 @@ /** * Aligns the given frame size to the stack alignment size and return the aligned size. - * + * * @param size the initial frame size to be aligned * @return the aligned frame size */ @@ -179,11 +179,14 @@ freedSlots = null; } frameSize = currentFrameSize(); + if (frameSize > registerConfig.getMaximumFrameSize()) { + throw new BailoutException(String.format("Frame size (%d) exceeded maximum allowed frame size (%d).", frameSize, registerConfig.getMaximumFrameSize())); + } } /** * Computes the offset of a stack slot relative to the frame register. - * + * * @param slot a stack slot * @return the offset of the stack slot */ @@ -199,7 +202,7 @@ /** * Computes the index of a stack slot relative to slot 0. This is also the bit index of stack * slots in the reference map. - * + * * @param slot a stack slot * @return the index of the stack slot */ @@ -211,7 +214,7 @@ /** * Gets the offset from the stack pointer to the stack area where callee-saved registers are * stored. - * + * * @return The offset to the callee save area (in bytes). */ public abstract int offsetToCalleeSaveArea(); @@ -219,7 +222,7 @@ /** * Informs the frame map that the compiled code calls a particular method, which may need stack * space for outgoing arguments. - * + * * @param cc The calling convention for the called method. */ public void callsMethod(CallingConvention cc) { @@ -228,7 +231,7 @@ /** * Reserves space for stack-based outgoing arguments. - * + * * @param argsSize The amount of space (in bytes) to reserve for stack-based outgoing arguments. */ public void reserveOutgoing(int argsSize) { @@ -241,7 +244,7 @@ * Reserves a new spill slot in the frame of the method being compiled. The returned slot is * aligned on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte * boundary. - * + * * @param kind The kind of the spill slot to be reserved. * @param additionalOffset * @return A spill slot denoting the reserved memory area. @@ -251,7 +254,7 @@ /** * Returns the spill slot size for the given {@link PlatformKind}. The default value is the size * in bytes for the target architecture. - * + * * @param kind the {@link PlatformKind} to be stored in the spill slot. * @return the size in bytes */ @@ -263,7 +266,7 @@ * Reserves a spill slot in the frame of the method being compiled. The returned slot is aligned * on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte boundary, unless * overridden by a subclass. - * + * * @param kind The kind of the spill slot to be reserved. * @return A spill slot denoting the reserved memory area. */ @@ -302,7 +305,7 @@ /** * Reserves a number of contiguous slots in the frame of the method being compiled. If the * requested number of slots is 0, this method returns {@code null}. - * + * * @param slots the number of slots to reserve * @param objects specifies the indexes of the object pointer slots. The caller is responsible * for guaranteeing that each such object pointer slot is initialized before any @@ -359,7 +362,7 @@ * Marks the specified location as a reference in the reference map of the debug information. * The tracked location can be a {@link RegisterValue} or a {@link StackSlot}. Note that a * {@link Constant} is automatically tracked. - * + * * @param location The location to be added to the reference map. * @param refMap A reference map, as created by {@link #initReferenceMap(boolean)}. */