001/* 002 * Copyright (c) 2009, 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.hotspot; 024 025import static jdk.internal.jvmci.code.ValueUtil.*; 026 027import java.util.*; 028 029import com.oracle.graal.lir.*; 030import com.oracle.graal.lir.framemap.*; 031 032import jdk.internal.jvmci.code.*; 033import jdk.internal.jvmci.common.*; 034import jdk.internal.jvmci.hotspot.*; 035import jdk.internal.jvmci.meta.*; 036 037public final class HotSpotReferenceMapBuilder extends ReferenceMapBuilder { 038 039 private int maxRegisterSize; 040 041 private final ArrayList<Value> objectValues; 042 private int objectCount; 043 044 private final TargetDescription target; 045 private final int totalFrameSize; 046 047 public HotSpotReferenceMapBuilder(TargetDescription target, int totalFrameSize) { 048 this.objectValues = new ArrayList<>(); 049 this.objectCount = 0; 050 051 this.target = target; 052 this.totalFrameSize = totalFrameSize; 053 } 054 055 @Override 056 public void addLiveValue(Value v) { 057 if (isConstant(v)) { 058 return; 059 } 060 LIRKind lirKind = v.getLIRKind(); 061 if (!lirKind.isValue()) { 062 objectValues.add(v); 063 if (lirKind.isUnknownReference()) { 064 objectCount++; 065 } else { 066 objectCount += lirKind.getReferenceCount(); 067 } 068 } 069 if (isRegister(v)) { 070 int size = target.getSizeInBytes(lirKind.getPlatformKind()); 071 if (size > maxRegisterSize) { 072 maxRegisterSize = size; 073 } 074 } 075 } 076 077 @Override 078 public ReferenceMap finish(LIRFrameState state) { 079 Location[] objects = new Location[objectCount]; 080 Location[] derivedBase = new Location[objectCount]; 081 int[] sizeInBytes = new int[objectCount]; 082 083 int idx = 0; 084 for (Value obj : objectValues) { 085 LIRKind kind = obj.getLIRKind(); 086 int bytes = bytesPerElement(kind); 087 if (kind.isUnknownReference()) { 088 throw JVMCIError.unimplemented("derived references not yet implemented"); 089 } else { 090 Location base = null; 091 if (kind.isDerivedReference()) { 092 Variable baseVariable = (Variable) kind.getDerivedReferenceBase(); 093 Value baseValue = state.getLiveBasePointers().get(baseVariable.index); 094 assert baseValue.getPlatformKind().getVectorLength() == 1 && baseValue.getLIRKind().isReference(0) && !baseValue.getLIRKind().isDerivedReference(); 095 base = toLocation(baseValue, 0); 096 } 097 098 for (int i = 0; i < kind.getPlatformKind().getVectorLength(); i++) { 099 if (kind.isReference(i)) { 100 objects[idx] = toLocation(obj, i * bytes); 101 derivedBase[idx] = base; 102 sizeInBytes[idx] = bytes; 103 idx++; 104 } 105 } 106 } 107 } 108 109 return new HotSpotReferenceMap(objects, derivedBase, sizeInBytes, maxRegisterSize); 110 } 111 112 private int bytesPerElement(LIRKind kind) { 113 PlatformKind platformKind = kind.getPlatformKind(); 114 return target.getSizeInBytes(platformKind) / platformKind.getVectorLength(); 115 } 116 117 private Location toLocation(Value v, int offset) { 118 if (isRegister(v)) { 119 return Location.subregister(asRegister(v), offset); 120 } else { 121 StackSlot s = asStackSlot(v); 122 return Location.stack(s.getOffset(totalFrameSize) + offset); 123 } 124 } 125}