001/* 002 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.lir.sparc; 024 025import jdk.internal.jvmci.code.*; 026import jdk.internal.jvmci.meta.*; 027import jdk.internal.jvmci.sparc.*; 028 029import com.oracle.graal.asm.*; 030import com.oracle.graal.lir.framemap.*; 031 032/** 033 * SPARC specific frame map. 034 * 035 * This is the format of a SPARC stack frame: 036 * 037 * <pre> 038 * Base Contents 039 * : : ----- 040 * caller | incoming overflow argument n | ^ 041 * frame : ... : | positive 042 * | incoming overflow argument 0 | | offsets 043 * +--------------------------------+ | 044 * | | | 045 * : register save area : | 046 * | | | 047 * ---------+--------------------------------+--------------------------- 048 * | spill slot 0 | | negative ^ ^ 049 * : ... : v offsets | | 050 * | spill slot n | ----- total | 051 * +--------------------------------+ frame | 052 * current | alignment padding | size | 053 * frame +--------------------------------+ ----- | | 054 * | outgoing overflow argument n | ^ | frame 055 * : ... : | positive | size 056 * | outgoing overflow argument 0 | | offsets | | 057 * +--------------------------------+ | | | 058 * | return address | | | | 059 * +--------------------------------+ | | | 060 * | | | | | 061 * : callee save area : | | | 062 * | | | v v 063 * %sp--> +--------------------------------+--------------------------- 064 * 065 * </pre> 066 * 067 * The spill slot area also includes stack allocated memory blocks (ALLOCA blocks). The size of such 068 * a block may be greater than the size of a normal spill slot or the word size. 069 * <p> 070 * A runtime can reserve space at the beginning of the overflow argument area. The calling 071 * convention can specify that the first overflow stack argument is not at offset 0, but at a 072 * specified offset. Use {@link CodeCacheProvider#getMinimumOutgoingSize()} to make sure that 073 * call-free methods also have this space reserved. Then the VM can use the memory at offset 0 074 * relative to the stack pointer. 075 */ 076public final class SPARCFrameMap extends FrameMap { 077 078 public SPARCFrameMap(CodeCacheProvider codeCache, RegisterConfig registerConfig, ReferenceMapBuilderFactory referenceMapFactory) { 079 super(codeCache, registerConfig, referenceMapFactory); 080 // Initial spill size is set to register save area size (SPARC register window) 081 initialSpillSize = 0; 082 spillSize = initialSpillSize; 083 } 084 085 @Override 086 public int totalFrameSize() { 087 return frameSize(); 088 } 089 090 @Override 091 public int currentFrameSize() { 092 return alignFrameSize(calleeSaveAreaSize() + outgoingSize + spillSize); 093 } 094 095 @Override 096 protected int calleeSaveAreaSize() { 097 return SPARC.REGISTER_SAFE_AREA_SIZE; 098 } 099 100 @Override 101 protected int alignFrameSize(int size) { 102 return NumUtil.roundUp(size, getTarget().stackAlignment); 103 } 104 105 @Override 106 public int offsetToCalleeSaveArea() { 107 return 0; 108 } 109 110 @Override 111 protected StackSlot allocateNewSpillSlot(LIRKind kind, int additionalOffset) { 112 return StackSlot.get(kind, -spillSize + additionalOffset, true); 113 } 114 115 /** 116 * In SPARC we have spill slots word aligned. 117 */ 118 @Override 119 public int spillSlotSize(LIRKind kind) { 120 return SPARC.spillSlotSize(getTarget(), kind.getPlatformKind()); 121 } 122 123 @Override 124 public int offsetForStackSlot(StackSlot slot) { 125 // @formatter:off 126 assert (!slot.getRawAddFrameSize() && slot.getRawOffset() < outgoingSize + SPARC.REGISTER_SAFE_AREA_SIZE) || 127 (slot.getRawAddFrameSize() && slot.getRawOffset() < 0 && -slot.getRawOffset() <= spillSize) || 128 (slot.getRawAddFrameSize() && slot.getRawOffset() >= 0) : 129 String.format("RawAddFrameSize: %b RawOffset: 0x%x spillSize: 0x%x outgoingSize: 0x%x", slot.getRawAddFrameSize(), slot.getRawOffset(), spillSize, outgoingSize); 130 // @formatter:on 131 return super.offsetForStackSlot(slot); 132 } 133 134 @Override 135 public boolean frameNeedsAllocating() { 136 return super.frameNeedsAllocating() || spillSize > 0; 137 } 138 139 public StackSlot allocateDeoptimizationRescueSlot() { 140 assert spillSize == initialSpillSize : "Deoptimization rescue slot must be the first stack slot"; 141 return allocateSpillSlot(LIRKind.value(Kind.Long)); 142 } 143}