|
26 | 26 |
|
27 | 27 | import java.util.ArrayDeque;
|
28 | 28 | import java.util.ArrayList;
|
29 |
| -import java.util.Arrays; |
30 |
| -import java.util.Comparator; |
31 | 29 | import java.util.List;
|
32 |
| -import java.util.Map; |
33 | 30 | import java.util.NavigableMap;
|
34 | 31 | import java.util.Queue;
|
35 | 32 | import java.util.TreeMap;
|
36 | 33 |
|
37 | 34 | import com.oracle.svm.core.config.ConfigurationValues;
|
38 | 35 | import com.oracle.svm.core.image.ImageHeapObject;
|
39 | 36 | import com.oracle.svm.core.image.ImageHeapPartition;
|
40 |
| -import com.oracle.svm.core.meta.SubstrateObjectConstant; |
41 | 37 |
|
42 | 38 | import jdk.graal.compiler.debug.Assertions;
|
43 | 39 |
|
@@ -124,63 +120,44 @@ private ImageHeapObject dequeueBestFit(NavigableMap<Long, Queue<ImageHeapObject>
|
124 | 120 | if (nbytes < minimumObjectSize) {
|
125 | 121 | return null;
|
126 | 122 | }
|
127 |
| - Map.Entry<Long, Queue<ImageHeapObject>> entry = sortedObjects.floorEntry(nbytes); |
128 |
| - if (entry == null) { |
| 123 | + |
| 124 | + /** |
| 125 | + * Find a floor entry. We are purposefully not calling {@link TreeMap#getFloorEntry(Object)} |
| 126 | + * as that method allocates a new entry object. Instead, we fetch the floor key and get the |
| 127 | + * value for the returned key. |
| 128 | + */ |
| 129 | + Long floorKey = sortedObjects.floorKey(nbytes); |
| 130 | + if (floorKey == null) { |
129 | 131 | return null;
|
130 | 132 | }
|
131 |
| - Queue<ImageHeapObject> queue = entry.getValue(); |
132 |
| - ImageHeapObject info = queue.remove(); |
| 133 | + Queue<ImageHeapObject> queue = sortedObjects.get(floorKey); |
| 134 | + ImageHeapObject obj = queue.remove(); |
133 | 135 | if (queue.isEmpty()) {
|
134 |
| - sortedObjects.remove(entry.getKey()); |
| 136 | + sortedObjects.remove(floorKey); |
135 | 137 | }
|
136 |
| - return info; |
| 138 | + return obj; |
137 | 139 | }
|
138 | 140 |
|
139 | 141 | private NavigableMap<Long, Queue<ImageHeapObject>> createSortedObjectsMap() {
|
140 |
| - ImageHeapObject[] sorted = objects.toArray(new ImageHeapObject[0]); |
141 |
| - Arrays.sort(sorted, new SizeComparator()); |
142 |
| - |
143 | 142 | NavigableMap<Long, Queue<ImageHeapObject>> map = new TreeMap<>();
|
144 |
| - Queue<ImageHeapObject> currentQueue = null; |
145 |
| - long currentObjectsSize = -1; |
146 |
| - for (ImageHeapObject obj : sorted) { |
| 143 | + for (ImageHeapObject obj : objects) { |
147 | 144 | long objSize = obj.getSize();
|
148 |
| - if (objSize != currentObjectsSize) { |
149 |
| - assert objSize > currentObjectsSize && objSize >= ConfigurationValues.getObjectLayout().getMinImageHeapObjectSize() : Assertions.errorMessage(obj, objSize); |
150 |
| - currentObjectsSize = objSize; |
151 |
| - currentQueue = new ArrayDeque<>(); |
152 |
| - map.put(currentObjectsSize, currentQueue); |
153 |
| - } |
154 |
| - assert currentQueue != null; |
155 |
| - currentQueue.add(obj); |
| 145 | + assert objSize >= ConfigurationValues.getObjectLayout().getMinImageHeapObjectSize() : Assertions.errorMessage(obj, objSize); |
| 146 | + Queue<ImageHeapObject> q = map.computeIfAbsent(objSize, k -> new ArrayDeque<>()); |
| 147 | + q.add(obj); |
156 | 148 | }
|
157 | 149 | return map;
|
158 | 150 | }
|
159 | 151 |
|
160 | 152 | private void appendAllocatedObject(ImageHeapObject info, long allocationOffset) {
|
161 | 153 | if (firstObject == null) {
|
162 |
| - firstObject = extractObject(info); |
| 154 | + firstObject = info.getObjectOrHostedConstant(); |
163 | 155 | }
|
164 | 156 | assert info.getPartition() == this;
|
165 | 157 | long offsetInPartition = allocationOffset - startOffset;
|
166 | 158 | assert ConfigurationValues.getObjectLayout().isAligned(offsetInPartition) : "start: " + offsetInPartition + " must be aligned.";
|
167 | 159 | info.setOffsetInPartition(offsetInPartition);
|
168 |
| - lastObject = extractObject(info); |
169 |
| - } |
170 |
| - |
171 |
| - private static Object extractObject(ImageHeapObject info) { |
172 |
| - if (info.getConstant() instanceof SubstrateObjectConstant) { |
173 |
| - return info.getObject(); |
174 |
| - } else { |
175 |
| - /* |
176 |
| - * The info wraps an ImageHeapObject, i.e., a build time representation of an object |
177 |
| - * that is not backed by a raw hosted object. We set the partition limit to the actual |
178 |
| - * constant. The constant reflection provider knows that this is a build time value, and |
179 |
| - * it will not wrap it in a JavaConstant when reading it. This case is not different |
180 |
| - * from normal objects referencing simulated objects. |
181 |
| - */ |
182 |
| - return info.getConstant(); |
183 |
| - } |
| 160 | + lastObject = info.getObjectOrHostedConstant(); |
184 | 161 | }
|
185 | 162 |
|
186 | 163 | @Override
|
@@ -229,11 +206,4 @@ public boolean isFiller() {
|
229 | 206 | public String toString() {
|
230 | 207 | return name;
|
231 | 208 | }
|
232 |
| - |
233 |
| - private static final class SizeComparator implements Comparator<ImageHeapObject> { |
234 |
| - @Override |
235 |
| - public int compare(ImageHeapObject o1, ImageHeapObject o2) { |
236 |
| - return Long.signum(o1.getSize() - o2.getSize()); |
237 |
| - } |
238 |
| - } |
239 | 209 | }
|
0 commit comments