HotSpotReferenceMapBuilder.java revision 13083:b9a173f12fe6
1/*
2 * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package org.graalvm.compiler.hotspot;
24
25import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
26import static jdk.vm.ci.code.ValueUtil.asRegister;
27import static jdk.vm.ci.code.ValueUtil.asStackSlot;
28import static jdk.vm.ci.code.ValueUtil.isRegister;
29
30import java.util.ArrayList;
31
32import org.graalvm.compiler.core.common.PermanentBailoutException;
33import org.graalvm.compiler.core.common.LIRKind;
34import org.graalvm.compiler.debug.GraalError;
35import org.graalvm.compiler.lir.LIRFrameState;
36import org.graalvm.compiler.lir.Variable;
37import org.graalvm.compiler.lir.framemap.ReferenceMapBuilder;
38
39import jdk.vm.ci.code.Location;
40import jdk.vm.ci.code.ReferenceMap;
41import jdk.vm.ci.code.StackSlot;
42import jdk.vm.ci.hotspot.HotSpotReferenceMap;
43import jdk.vm.ci.meta.PlatformKind;
44import jdk.vm.ci.meta.Value;
45
46public final class HotSpotReferenceMapBuilder extends ReferenceMapBuilder {
47
48    private int maxRegisterSize;
49
50    private final ArrayList<Value> objectValues;
51    private int objectCount;
52
53    private final int totalFrameSize;
54    private final int maxOopMapStackOffset;
55
56    public HotSpotReferenceMapBuilder(int totalFrameSize, int maxOopMapStackOffset) {
57        this.objectValues = new ArrayList<>();
58        this.objectCount = 0;
59        this.maxOopMapStackOffset = maxOopMapStackOffset;
60        this.totalFrameSize = totalFrameSize;
61    }
62
63    @Override
64    public void addLiveValue(Value v) {
65        if (isJavaConstant(v)) {
66            return;
67        }
68        LIRKind lirKind = (LIRKind) v.getValueKind();
69        if (!lirKind.isValue()) {
70            objectValues.add(v);
71            if (lirKind.isUnknownReference()) {
72                objectCount++;
73            } else {
74                objectCount += lirKind.getReferenceCount();
75            }
76        }
77        if (isRegister(v)) {
78            int size = lirKind.getPlatformKind().getSizeInBytes();
79            if (size > maxRegisterSize) {
80                maxRegisterSize = size;
81            }
82        }
83    }
84
85    private static final Location[] NO_LOCATIONS = {};
86    private static final int[] NO_SIZES = {};
87
88    @Override
89    public ReferenceMap finish(LIRFrameState state) {
90        Location[] objects;
91        Location[] derivedBase;
92        int[] sizeInBytes;
93        if (objectCount == 0) {
94            objects = NO_LOCATIONS;
95            derivedBase = NO_LOCATIONS;
96            sizeInBytes = NO_SIZES;
97        } else {
98            objects = new Location[objectCount];
99            derivedBase = new Location[objectCount];
100            sizeInBytes = new int[objectCount];
101        }
102        int idx = 0;
103        for (Value obj : objectValues) {
104            LIRKind kind = (LIRKind) obj.getValueKind();
105            int bytes = bytesPerElement(kind);
106            if (kind.isUnknownReference()) {
107                throw GraalError.shouldNotReachHere(String.format("unknown reference alive across safepoint: %s", obj));
108            } else {
109                Location base = null;
110                if (kind.isDerivedReference()) {
111                    Variable baseVariable = (Variable) kind.getDerivedReferenceBase();
112                    Value baseValue = state.getLiveBasePointers().get(baseVariable.index);
113                    assert baseValue.getPlatformKind().getVectorLength() == 1 && ((LIRKind) baseValue.getValueKind()).isReference(0) && !((LIRKind) baseValue.getValueKind()).isDerivedReference();
114                    base = toLocation(baseValue, 0);
115                }
116
117                for (int i = 0; i < kind.getPlatformKind().getVectorLength(); i++) {
118                    if (kind.isReference(i)) {
119                        objects[idx] = toLocation(obj, i * bytes);
120                        derivedBase[idx] = base;
121                        sizeInBytes[idx] = bytes;
122                        idx++;
123                    }
124                }
125            }
126        }
127
128        return new HotSpotReferenceMap(objects, derivedBase, sizeInBytes, maxRegisterSize);
129    }
130
131    private static int bytesPerElement(LIRKind kind) {
132        PlatformKind platformKind = kind.getPlatformKind();
133        return platformKind.getSizeInBytes() / platformKind.getVectorLength();
134    }
135
136    private Location toLocation(Value v, int offset) {
137        if (isRegister(v)) {
138            return Location.subregister(asRegister(v), offset);
139        } else {
140            StackSlot s = asStackSlot(v);
141            int totalOffset = s.getOffset(totalFrameSize) + offset;
142            if (totalOffset > maxOopMapStackOffset) {
143                throw new PermanentBailoutException("stack offset %d for oopmap is greater than encoding limit %d", totalOffset, maxOopMapStackOffset);
144            }
145            return Location.stack(totalOffset);
146        }
147    }
148}
149