36 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_INSTANCE; |
37 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_INSTANCE; |
37 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_INSTANCE_OR_NULL; |
38 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_INSTANCE_OR_NULL; |
38 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_MULTI_ARRAY; |
39 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_MULTI_ARRAY; |
39 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_MULTI_ARRAY_OR_NULL; |
40 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_MULTI_ARRAY_OR_NULL; |
40 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_ARRAY_KLASS_LOCATION; |
41 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_ARRAY_KLASS_LOCATION; |
|
42 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_INIT_STATE_LOCATION; |
41 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.HUB_WRITE_LOCATION; |
43 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.HUB_WRITE_LOCATION; |
42 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.MARK_WORD_LOCATION; |
44 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.MARK_WORD_LOCATION; |
43 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.PROTOTYPE_MARK_WORD_LOCATION; |
45 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.PROTOTYPE_MARK_WORD_LOCATION; |
44 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_END_LOCATION; |
46 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_END_LOCATION; |
45 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_TOP_LOCATION; |
47 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_TOP_LOCATION; |
51 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayAllocationSize; |
53 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayAllocationSize; |
52 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayKlassOffset; |
54 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayKlassOffset; |
53 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayLengthOffset; |
55 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayLengthOffset; |
54 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.initializeObjectHeader; |
56 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.initializeObjectHeader; |
55 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.instanceHeaderSize; |
57 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.instanceHeaderSize; |
|
58 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.instanceKlassStateBeingInitialized; |
56 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.isInstanceKlassFullyInitialized; |
59 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.isInstanceKlassFullyInitialized; |
57 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperHeaderSizeMask; |
60 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperHeaderSizeMask; |
58 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperHeaderSizeShift; |
61 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperHeaderSizeShift; |
59 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperLog2ElementSizeMask; |
62 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperLog2ElementSizeMask; |
60 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperLog2ElementSizeShift; |
63 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperLog2ElementSizeShift; |
61 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.loadKlassFromObject; |
64 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.loadKlassFromObject; |
62 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.prototypeMarkWordOffset; |
65 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.prototypeMarkWordOffset; |
|
66 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readInstanceKlassInitState; |
|
67 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readInstanceKlassInitThread; |
63 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readLayoutHelper; |
68 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readLayoutHelper; |
64 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readTlabEnd; |
69 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readTlabEnd; |
65 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readTlabTop; |
70 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readTlabTop; |
66 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord; |
71 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord; |
67 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useBiasedLocking; |
72 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useBiasedLocking; |
70 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.writeTlabTop; |
75 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.writeTlabTop; |
71 import static org.graalvm.compiler.hotspot.replacements.HotspotSnippetsOptions.ProfileAllocations; |
76 import static org.graalvm.compiler.hotspot.replacements.HotspotSnippetsOptions.ProfileAllocations; |
72 import static org.graalvm.compiler.hotspot.replacements.HotspotSnippetsOptions.ProfileAllocationsContext; |
77 import static org.graalvm.compiler.hotspot.replacements.HotspotSnippetsOptions.ProfileAllocationsContext; |
73 import static org.graalvm.compiler.nodes.PiArrayNode.piArrayCastToSnippetReplaceeStamp; |
78 import static org.graalvm.compiler.nodes.PiArrayNode.piArrayCastToSnippetReplaceeStamp; |
74 import static org.graalvm.compiler.nodes.PiNode.piCastToSnippetReplaceeStamp; |
79 import static org.graalvm.compiler.nodes.PiNode.piCastToSnippetReplaceeStamp; |
|
80 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.DEOPT_PROBABILITY; |
75 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FAST_PATH_PROBABILITY; |
81 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FAST_PATH_PROBABILITY; |
76 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FREQUENT_PROBABILITY; |
82 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FREQUENT_PROBABILITY; |
77 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.SLOW_PATH_PROBABILITY; |
83 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.SLOW_PATH_PROBABILITY; |
|
84 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.VERY_FAST_PATH_PROBABILITY; |
78 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability; |
85 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability; |
79 import static org.graalvm.compiler.replacements.ReplacementsUtil.REPLACEMENTS_ASSERTIONS_ENABLED; |
86 import static org.graalvm.compiler.replacements.ReplacementsUtil.REPLACEMENTS_ASSERTIONS_ENABLED; |
80 import static org.graalvm.compiler.replacements.ReplacementsUtil.runtimeAssert; |
87 import static org.graalvm.compiler.replacements.ReplacementsUtil.runtimeAssert; |
81 import static org.graalvm.compiler.replacements.ReplacementsUtil.staticAssert; |
88 import static org.graalvm.compiler.replacements.ReplacementsUtil.staticAssert; |
82 import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER; |
89 import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER; |
209 } |
218 } |
210 } |
219 } |
211 } |
220 } |
212 |
221 |
213 @Snippet |
222 @Snippet |
214 public static Object allocateInstance(@ConstantParameter long size, KlassPointer hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents, |
223 public static Object allocateInstance(@ConstantParameter long size, |
215 @ConstantParameter Register threadRegister, @ConstantParameter boolean constantSize, @ConstantParameter String typeContext, |
224 KlassPointer hub, |
|
225 Word prototypeMarkWord, |
|
226 @ConstantParameter boolean fillContents, |
|
227 @ConstantParameter boolean emitMemoryBarrier, |
|
228 @ConstantParameter Register threadRegister, |
|
229 @ConstantParameter boolean constantSize, |
|
230 @ConstantParameter String typeContext, |
216 @ConstantParameter Counters counters) { |
231 @ConstantParameter Counters counters) { |
217 return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, hub, prototypeMarkWord, fillContents, threadRegister, constantSize, typeContext, counters)); |
232 return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, hub, prototypeMarkWord, fillContents, emitMemoryBarrier, threadRegister, constantSize, typeContext, counters)); |
218 } |
233 } |
219 |
234 |
220 public static Object allocateInstanceHelper(long size, KlassPointer hub, Word prototypeMarkWord, boolean fillContents, |
235 public static Object allocateInstanceHelper(long size, |
221 Register threadRegister, boolean constantSize, String typeContext, Counters counters) { |
236 KlassPointer hub, |
|
237 Word prototypeMarkWord, |
|
238 boolean fillContents, |
|
239 boolean emitMemoryBarrier, |
|
240 Register threadRegister, |
|
241 boolean constantSize, |
|
242 String typeContext, |
|
243 Counters counters) { |
222 Object result; |
244 Object result; |
223 Word thread = registerAsWord(threadRegister); |
245 Word thread = registerAsWord(threadRegister); |
224 Word top = readTlabTop(thread); |
246 Word top = readTlabTop(thread); |
225 Word end = readTlabEnd(thread); |
247 Word end = readTlabEnd(thread); |
226 Word newTop = top.add(WordFactory.unsigned(size)); |
248 Word newTop = top.add(WordFactory.unsigned(size)); |
227 if (useTLAB(INJECTED_VMCONFIG) && probability(FAST_PATH_PROBABILITY, newTop.belowOrEqual(end))) { |
249 if (useTLAB(INJECTED_VMCONFIG) && probability(FAST_PATH_PROBABILITY, newTop.belowOrEqual(end))) { |
228 writeTlabTop(thread, newTop); |
250 writeTlabTop(thread, newTop); |
229 emitPrefetchAllocate(newTop, false); |
251 emitPrefetchAllocate(newTop, false); |
230 result = formatObject(hub, size, top, prototypeMarkWord, fillContents, constantSize, counters); |
252 result = formatObject(hub, size, top, prototypeMarkWord, fillContents, emitMemoryBarrier, constantSize, counters); |
231 } else { |
253 } else { |
232 Counters theCounters = counters; |
254 Counters theCounters = counters; |
233 if (theCounters != null && theCounters.stub != null) { |
255 if (theCounters != null && theCounters.stub != null) { |
234 theCounters.stub.inc(); |
256 theCounters.stub.inc(); |
235 } |
257 } |
252 |
274 |
253 @NodeIntrinsic(value = ForeignCallNode.class, injectedStampIsNonNull = false) |
275 @NodeIntrinsic(value = ForeignCallNode.class, injectedStampIsNonNull = false) |
254 private static native Object newInstanceOrNull(@ConstantNodeParameter ForeignCallDescriptor descriptor, KlassPointer hub); |
276 private static native Object newInstanceOrNull(@ConstantNodeParameter ForeignCallDescriptor descriptor, KlassPointer hub); |
255 |
277 |
256 @Snippet |
278 @Snippet |
257 public static Object allocateInstancePIC(@ConstantParameter long size, KlassPointer hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents, |
279 public static Object allocateInstancePIC(@ConstantParameter long size, |
258 @ConstantParameter Register threadRegister, @ConstantParameter boolean constantSize, @ConstantParameter String typeContext, |
280 KlassPointer hub, |
|
281 Word prototypeMarkWord, |
|
282 @ConstantParameter boolean fillContents, |
|
283 @ConstantParameter boolean emitMemoryBarrier, |
|
284 @ConstantParameter Register threadRegister, |
|
285 @ConstantParameter boolean constantSize, |
|
286 @ConstantParameter String typeContext, |
259 @ConstantParameter Counters counters) { |
287 @ConstantParameter Counters counters) { |
260 // Klass must be initialized by the time the first instance is allocated, therefore we can |
288 // Klass must be initialized by the time the first instance is allocated, therefore we can |
261 // just load it from the corresponding cell and avoid the resolution check. We have to use a |
289 // just load it from the corresponding cell and avoid the resolution check. We have to use a |
262 // fixed load though, to prevent it from floating above the initialization. |
290 // fixed load though, to prevent it from floating above the initialization. |
263 KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub); |
291 KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub); |
264 return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, picHub, prototypeMarkWord, fillContents, threadRegister, constantSize, typeContext, counters)); |
292 return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, picHub, prototypeMarkWord, fillContents, emitMemoryBarrier, threadRegister, constantSize, typeContext, counters)); |
265 } |
293 } |
266 |
294 |
267 @Snippet |
295 @Snippet |
268 public static Object allocateInstanceDynamic(Class<?> type, Class<?> classClass, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, |
296 public static Object allocateInstanceDynamic(Class<?> type, Class<?> classClass, |
|
297 @ConstantParameter boolean fillContents, |
|
298 @ConstantParameter boolean emitMemoryBarrier, |
|
299 @ConstantParameter Register threadRegister, |
269 @ConstantParameter Counters counters) { |
300 @ConstantParameter Counters counters) { |
270 if (probability(SLOW_PATH_PROBABILITY, type == null)) { |
301 if (probability(DEOPT_PROBABILITY, type == null)) { |
271 DeoptimizeNode.deopt(None, RuntimeConstraint); |
302 DeoptimizeNode.deopt(None, RuntimeConstraint); |
272 } |
303 } |
273 Class<?> nonNullType = PiNode.piCastNonNullClass(type, SnippetAnchorNode.anchor()); |
304 Class<?> nonNullType = PiNode.piCastNonNullClass(type, SnippetAnchorNode.anchor()); |
274 |
305 |
275 if (probability(SLOW_PATH_PROBABILITY, DynamicNewInstanceNode.throwsInstantiationException(type, classClass))) { |
306 if (probability(DEOPT_PROBABILITY, DynamicNewInstanceNode.throwsInstantiationException(type, classClass))) { |
276 DeoptimizeNode.deopt(None, RuntimeConstraint); |
307 DeoptimizeNode.deopt(None, RuntimeConstraint); |
277 } |
308 } |
278 |
309 |
279 return PiNode.piCastToSnippetReplaceeStamp(allocateInstanceDynamicHelper(type, fillContents, threadRegister, counters, nonNullType)); |
310 return PiNode.piCastToSnippetReplaceeStamp(allocateInstanceDynamicHelper(type, fillContents, emitMemoryBarrier, threadRegister, counters, nonNullType)); |
280 } |
311 } |
281 |
312 |
282 private static Object allocateInstanceDynamicHelper(Class<?> type, boolean fillContents, Register threadRegister, Counters counters, Class<?> nonNullType) { |
313 private static Object allocateInstanceDynamicHelper(Class<?> type, |
|
314 boolean fillContents, |
|
315 boolean emitMemoryBarrier, |
|
316 Register threadRegister, |
|
317 Counters counters, |
|
318 Class<?> nonNullType) { |
283 KlassPointer hub = ClassGetHubNode.readClass(nonNullType); |
319 KlassPointer hub = ClassGetHubNode.readClass(nonNullType); |
284 if (probability(FAST_PATH_PROBABILITY, !hub.isNull())) { |
320 if (probability(FAST_PATH_PROBABILITY, !hub.isNull())) { |
285 KlassPointer nonNullHub = ClassGetHubNode.piCastNonNull(hub, SnippetAnchorNode.anchor()); |
321 KlassPointer nonNullHub = ClassGetHubNode.piCastNonNull(hub, SnippetAnchorNode.anchor()); |
286 |
322 |
287 if (probability(FAST_PATH_PROBABILITY, isInstanceKlassFullyInitialized(nonNullHub))) { |
323 if (probability(VERY_FAST_PATH_PROBABILITY, isInstanceKlassFullyInitialized(nonNullHub))) { |
288 int layoutHelper = readLayoutHelper(nonNullHub); |
324 int layoutHelper = readLayoutHelper(nonNullHub); |
289 /* |
325 /* |
290 * src/share/vm/oops/klass.hpp: For instances, layout helper is a positive number, |
326 * src/share/vm/oops/klass.hpp: For instances, layout helper is a positive number, |
291 * the instance size. This size is already passed through align_object_size and |
327 * the instance size. This size is already passed through align_object_size and |
292 * scaled to bytes. The low order bit is set if instances of this class cannot be |
328 * scaled to bytes. The low order bit is set if instances of this class cannot be |
317 int length, |
353 int length, |
318 Word prototypeMarkWord, |
354 Word prototypeMarkWord, |
319 @ConstantParameter int headerSize, |
355 @ConstantParameter int headerSize, |
320 @ConstantParameter int log2ElementSize, |
356 @ConstantParameter int log2ElementSize, |
321 @ConstantParameter boolean fillContents, |
357 @ConstantParameter boolean fillContents, |
|
358 @ConstantParameter boolean emitMemoryBarrier, |
322 @ConstantParameter Register threadRegister, |
359 @ConstantParameter Register threadRegister, |
323 @ConstantParameter boolean maybeUnroll, |
360 @ConstantParameter boolean maybeUnroll, |
324 @ConstantParameter String typeContext, |
361 @ConstantParameter String typeContext, |
325 @ConstantParameter boolean useBulkZeroing, |
362 @ConstantParameter boolean supportsBulkZeroing, |
326 @ConstantParameter Counters counters) { |
363 @ConstantParameter Counters counters) { |
327 // Primitive array types are eagerly pre-resolved. We can use a floating load. |
364 // Primitive array types are eagerly pre-resolved. We can use a floating load. |
328 KlassPointer picHub = LoadConstantIndirectlyNode.loadKlass(hub); |
365 KlassPointer picHub = LoadConstantIndirectlyNode.loadKlass(hub); |
329 return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, |
366 return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, |
330 threadRegister, maybeUnroll, typeContext, useBulkZeroing, counters); |
367 emitMemoryBarrier, threadRegister, maybeUnroll, typeContext, supportsBulkZeroing, counters); |
331 } |
368 } |
332 |
369 |
333 @Snippet |
370 @Snippet |
334 public static Object allocateArrayPIC(KlassPointer hub, |
371 public static Object allocateArrayPIC(KlassPointer hub, |
335 int length, |
372 int length, |
336 Word prototypeMarkWord, |
373 Word prototypeMarkWord, |
337 @ConstantParameter int headerSize, |
374 @ConstantParameter int headerSize, |
338 @ConstantParameter int log2ElementSize, |
375 @ConstantParameter int log2ElementSize, |
339 @ConstantParameter boolean fillContents, |
376 @ConstantParameter boolean fillContents, |
|
377 @ConstantParameter boolean emitMemoryBarrier, |
340 @ConstantParameter Register threadRegister, |
378 @ConstantParameter Register threadRegister, |
341 @ConstantParameter boolean maybeUnroll, |
379 @ConstantParameter boolean maybeUnroll, |
342 @ConstantParameter String typeContext, |
380 @ConstantParameter String typeContext, |
343 @ConstantParameter boolean useBulkZeroing, |
381 @ConstantParameter boolean supportsBulkZeroing, |
344 @ConstantParameter Counters counters) { |
382 @ConstantParameter Counters counters) { |
345 // Array type would be resolved by dominating resolution. |
383 // Array type would be resolved by dominating resolution. |
346 KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub); |
384 KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub); |
347 return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, |
385 return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, |
348 threadRegister, maybeUnroll, typeContext, useBulkZeroing, counters); |
386 emitMemoryBarrier, threadRegister, maybeUnroll, typeContext, supportsBulkZeroing, counters); |
349 } |
387 } |
350 |
388 |
351 @Snippet |
389 @Snippet |
352 public static Object allocateArray(KlassPointer hub, |
390 public static Object allocateArray(KlassPointer hub, |
353 int length, |
391 int length, |
354 Word prototypeMarkWord, |
392 Word prototypeMarkWord, |
355 @ConstantParameter int headerSize, |
393 @ConstantParameter int headerSize, |
356 @ConstantParameter int log2ElementSize, |
394 @ConstantParameter int log2ElementSize, |
357 @ConstantParameter boolean fillContents, |
395 @ConstantParameter boolean fillContents, |
|
396 @ConstantParameter boolean emitMemoryBarrier, |
358 @ConstantParameter Register threadRegister, |
397 @ConstantParameter Register threadRegister, |
359 @ConstantParameter boolean maybeUnroll, |
398 @ConstantParameter boolean maybeUnroll, |
360 @ConstantParameter String typeContext, |
399 @ConstantParameter String typeContext, |
361 @ConstantParameter boolean useBulkZeroing, |
400 @ConstantParameter boolean supportsBulkZeroing, |
362 @ConstantParameter Counters counters) { |
401 @ConstantParameter Counters counters) { |
363 Object result = allocateArrayImpl(hub, |
402 Object result = allocateArrayImpl(hub, |
364 length, |
403 length, |
365 prototypeMarkWord, |
404 prototypeMarkWord, |
366 headerSize, |
405 headerSize, |
367 log2ElementSize, |
406 log2ElementSize, |
368 fillContents, |
407 fillContents, |
369 threadRegister, |
408 emitMemoryBarrier, threadRegister, |
370 maybeUnroll, |
409 maybeUnroll, |
371 typeContext, |
410 typeContext, |
372 useBulkZeroing, |
411 supportsBulkZeroing, |
373 counters); |
412 counters); |
374 return piArrayCastToSnippetReplaceeStamp(verifyOop(result), length); |
413 return piArrayCastToSnippetReplaceeStamp(verifyOop(result), length); |
375 } |
414 } |
376 |
415 |
377 /** |
416 /** |
381 @Fold |
420 @Fold |
382 static boolean useNullAllocationStubs(@InjectedParameter GraalHotSpotVMConfig config) { |
421 static boolean useNullAllocationStubs(@InjectedParameter GraalHotSpotVMConfig config) { |
383 return config.areNullAllocationStubsAvailable(); |
422 return config.areNullAllocationStubsAvailable(); |
384 } |
423 } |
385 |
424 |
386 private static Object allocateArrayImpl(KlassPointer hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents, Register threadRegister, |
425 private static Object allocateArrayImpl(KlassPointer hub, |
387 boolean maybeUnroll, String typeContext, boolean useBulkZeroing, Counters counters) { |
426 int length, |
|
427 Word prototypeMarkWord, |
|
428 int headerSize, |
|
429 int log2ElementSize, |
|
430 boolean fillContents, |
|
431 boolean emitMemoryBarrier, |
|
432 Register threadRegister, |
|
433 boolean maybeUnroll, |
|
434 String typeContext, |
|
435 boolean supportsBulkZeroing, |
|
436 Counters counters) { |
388 Object result; |
437 Object result; |
389 long allocationSize = arrayAllocationSize(length, headerSize, log2ElementSize); |
438 long allocationSize = arrayAllocationSize(length, headerSize, log2ElementSize); |
390 Word thread = registerAsWord(threadRegister); |
439 Word thread = registerAsWord(threadRegister); |
391 Word top = readTlabTop(thread); |
440 Word top = readTlabTop(thread); |
392 Word end = readTlabEnd(thread); |
441 Word end = readTlabEnd(thread); |
397 emitPrefetchAllocate(newTop, true); |
446 emitPrefetchAllocate(newTop, true); |
398 Counters theCounters = counters; |
447 Counters theCounters = counters; |
399 if (theCounters != null && theCounters.arrayLoopInit != null) { |
448 if (theCounters != null && theCounters.arrayLoopInit != null) { |
400 theCounters.arrayLoopInit.inc(); |
449 theCounters.arrayLoopInit.inc(); |
401 } |
450 } |
402 result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents, maybeUnroll, useBulkZeroing, counters); |
451 result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents, emitMemoryBarrier, maybeUnroll, supportsBulkZeroing, counters); |
403 } else { |
452 } else { |
404 result = newArrayStub(hub, length); |
453 result = newArrayStub(hub, length); |
405 } |
454 } |
406 profileAllocation("array", allocationSize, typeContext); |
455 profileAllocation("array", allocationSize, typeContext); |
407 return result; |
456 return result; |
458 @Snippet |
507 @Snippet |
459 public static Object allocateArrayDynamic(Class<?> elementType, |
508 public static Object allocateArrayDynamic(Class<?> elementType, |
460 Class<?> voidClass, |
509 Class<?> voidClass, |
461 int length, |
510 int length, |
462 @ConstantParameter boolean fillContents, |
511 @ConstantParameter boolean fillContents, |
|
512 @ConstantParameter boolean emitMemoryBarrier, |
463 @ConstantParameter Register threadRegister, |
513 @ConstantParameter Register threadRegister, |
464 @ConstantParameter JavaKind knownElementKind, |
514 @ConstantParameter JavaKind knownElementKind, |
465 @ConstantParameter int knownLayoutHelper, |
515 @ConstantParameter int knownLayoutHelper, |
466 @ConstantParameter boolean useBulkZeroing, |
516 @ConstantParameter boolean supportsBulkZeroing, |
467 Word prototypeMarkWord, |
517 Word prototypeMarkWord, |
468 @ConstantParameter Counters counters) { |
518 @ConstantParameter Counters counters) { |
469 Object result = allocateArrayDynamicImpl(elementType, voidClass, length, fillContents, threadRegister, knownElementKind, |
519 Object result = allocateArrayDynamicImpl(elementType, voidClass, length, fillContents, emitMemoryBarrier, threadRegister, knownElementKind, |
470 knownLayoutHelper, useBulkZeroing, prototypeMarkWord, counters); |
520 knownLayoutHelper, supportsBulkZeroing, prototypeMarkWord, counters); |
471 return result; |
521 return result; |
472 } |
522 } |
473 |
523 |
474 private static Object allocateArrayDynamicImpl(Class<?> elementType, Class<?> voidClass, int length, boolean fillContents, Register threadRegister, JavaKind knownElementKind, |
524 private static Object allocateArrayDynamicImpl(Class<?> elementType, |
475 int knownLayoutHelper, boolean useBulkZeroing, Word prototypeMarkWord, Counters counters) { |
525 Class<?> voidClass, |
|
526 int length, |
|
527 boolean fillContents, |
|
528 boolean emitMemoryBarrier, |
|
529 Register threadRegister, |
|
530 JavaKind knownElementKind, |
|
531 int knownLayoutHelper, |
|
532 boolean supportsBulkZeroing, |
|
533 Word prototypeMarkWord, |
|
534 Counters counters) { |
476 /* |
535 /* |
477 * We only need the dynamic check for void when we have no static information from |
536 * We only need the dynamic check for void when we have no static information from |
478 * knownElementKind. |
537 * knownElementKind. |
479 */ |
538 */ |
480 staticAssert(knownElementKind != JavaKind.Void, "unsupported knownElementKind"); |
539 staticAssert(knownElementKind != JavaKind.Void, "unsupported knownElementKind"); |
481 if (knownElementKind == JavaKind.Illegal && probability(SLOW_PATH_PROBABILITY, elementType == null || DynamicNewArrayNode.throwsIllegalArgumentException(elementType, voidClass))) { |
540 if (knownElementKind == JavaKind.Illegal && probability(SLOW_PATH_PROBABILITY, elementType == null || DynamicNewArrayNode.throwsIllegalArgumentException(elementType, voidClass))) { |
482 DeoptimizeNode.deopt(None, RuntimeConstraint); |
541 DeoptimizeNode.deopt(None, RuntimeConstraint); |
483 } |
542 } |
484 |
543 |
485 KlassPointer klass = loadKlassFromObject(elementType, arrayKlassOffset(INJECTED_VMCONFIG), CLASS_ARRAY_KLASS_LOCATION); |
544 KlassPointer klass = loadKlassFromObject(elementType, arrayKlassOffset(INJECTED_VMCONFIG), CLASS_ARRAY_KLASS_LOCATION); |
486 if (klass.isNull()) { |
545 if (probability(DEOPT_PROBABILITY, klass.isNull())) { |
487 DeoptimizeNode.deopt(None, RuntimeConstraint); |
546 DeoptimizeNode.deopt(None, RuntimeConstraint); |
488 } |
547 } |
489 KlassPointer nonNullKlass = ClassGetHubNode.piCastNonNull(klass, SnippetAnchorNode.anchor()); |
548 KlassPointer nonNullKlass = ClassGetHubNode.piCastNonNull(klass, SnippetAnchorNode.anchor()); |
490 |
549 |
491 if (length < 0) { |
550 if (probability(DEOPT_PROBABILITY, length < 0)) { |
492 DeoptimizeNode.deopt(None, RuntimeConstraint); |
551 DeoptimizeNode.deopt(None, RuntimeConstraint); |
493 } |
552 } |
494 int layoutHelper; |
553 int layoutHelper; |
495 if (knownElementKind == JavaKind.Illegal) { |
554 if (knownElementKind == JavaKind.Illegal) { |
496 layoutHelper = readLayoutHelper(nonNullKlass); |
555 layoutHelper = readLayoutHelper(nonNullKlass); |
561 |
620 |
562 /** |
621 /** |
563 * Zero uninitialized memory in a newly allocated object, unrolling as necessary and ensuring |
622 * Zero uninitialized memory in a newly allocated object, unrolling as necessary and ensuring |
564 * that stores are aligned. |
623 * that stores are aligned. |
565 * |
624 * |
566 * @param size number of bytes to zero |
|
567 * @param memory beginning of object which is being zeroed |
625 * @param memory beginning of object which is being zeroed |
568 * @param constantSize is {@code size} known to be constant in the snippet |
626 * @param startOffset offset to begin zeroing (inclusive). May not be word aligned. |
569 * @param startOffset offset to begin zeroing. May not be word aligned. |
627 * @param endOffset offset to stop zeroing (exclusive). May not be word aligned. |
|
628 * @param isEndOffsetConstant is {@code endOffset} known to be constant in the snippet |
570 * @param manualUnroll maximally unroll zeroing |
629 * @param manualUnroll maximally unroll zeroing |
571 * @param useBulkZeroing apply bulk zeroing |
630 * @param supportsBulkZeroing whether bulk zeroing is supported by the backend |
572 */ |
631 */ |
573 private static void zeroMemory(long size, Word memory, boolean constantSize, int startOffset, boolean manualUnroll, |
632 private static void zeroMemory(Word memory, int startOffset, long endOffset, boolean isEndOffsetConstant, boolean manualUnroll, |
574 boolean useBulkZeroing, Counters counters) { |
633 boolean supportsBulkZeroing, Counters counters) { |
575 fillMemory(0, size, memory, constantSize, startOffset, manualUnroll, useBulkZeroing, counters); |
634 fillMemory(0, memory, startOffset, endOffset, isEndOffsetConstant, manualUnroll, supportsBulkZeroing, counters); |
576 } |
635 } |
577 |
636 |
578 private static void fillMemory(long value, long size, Word memory, boolean constantSize, int startOffset, boolean manualUnroll, |
637 private static void fillMemory(long value, Word memory, int startOffset, long endOffset, boolean constantOffsetLimit, boolean manualUnroll, |
579 boolean useBulkZeroing, Counters counters) { |
638 boolean supportsBulkZeroing, Counters counters) { |
580 ReplacementsUtil.runtimeAssert((size & 0x7) == 0, "unaligned object size"); |
639 ReplacementsUtil.runtimeAssert((endOffset & 0x7) == 0, "unaligned object size"); |
581 int offset = startOffset; |
640 int offset = startOffset; |
582 if ((offset & 0x7) != 0) { |
641 if ((offset & 0x7) != 0) { |
583 memory.writeInt(offset, (int) value, LocationIdentity.init()); |
642 memory.writeInt(offset, (int) value, LocationIdentity.init()); |
584 offset += 4; |
643 offset += 4; |
585 } |
644 } |
586 ReplacementsUtil.runtimeAssert((offset & 0x7) == 0, "unaligned offset"); |
645 ReplacementsUtil.runtimeAssert((offset & 0x7) == 0, "unaligned offset"); |
587 Counters theCounters = counters; |
646 Counters theCounters = counters; |
588 if (manualUnroll && ((size - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) { |
647 if (manualUnroll && ((endOffset - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) { |
589 ReplacementsUtil.staticAssert(!constantSize, "size shouldn't be constant at instantiation time"); |
648 ReplacementsUtil.staticAssert(!constantOffsetLimit, "size shouldn't be constant at instantiation time"); |
590 // This case handles arrays of constant length. Instead of having a snippet variant for |
649 // This case handles arrays of constant length. Instead of having a snippet variant for |
591 // each length, generate a chain of stores of maximum length. Once it's inlined the |
650 // each length, generate a chain of stores of maximum length. Once it's inlined the |
592 // break statement will trim excess stores. |
651 // break statement will trim excess stores. |
593 if (theCounters != null && theCounters.instanceSeqInit != null) { |
652 if (theCounters != null && theCounters.instanceSeqInit != null) { |
594 theCounters.instanceSeqInit.inc(); |
653 theCounters.instanceSeqInit.inc(); |
595 } |
654 } |
596 |
655 |
597 explodeLoop(); |
656 explodeLoop(); |
598 for (int i = 0; i < MAX_UNROLLED_OBJECT_ZEROING_STORES; i++, offset += 8) { |
657 for (int i = 0; i < MAX_UNROLLED_OBJECT_ZEROING_STORES; i++, offset += 8) { |
599 if (offset == size) { |
658 if (offset == endOffset) { |
600 break; |
659 break; |
601 } |
660 } |
602 memory.initializeLong(offset, value, LocationIdentity.init()); |
661 memory.initializeLong(offset, value, LocationIdentity.init()); |
603 } |
662 } |
604 } else { |
663 } else { |
605 // Use Word instead of int to avoid extension to long in generated code |
664 // Use Word instead of int to avoid extension to long in generated code |
606 Word off = WordFactory.signed(offset); |
665 Word off = WordFactory.signed(offset); |
607 if (useBulkZeroing && probability(SLOW_PATH_PROBABILITY, size >= getMinimalBulkZeroingSize(INJECTED_OPTIONVALUES))) { |
666 if (supportsBulkZeroing && value == 0 && probability(SLOW_PATH_PROBABILITY, (endOffset - offset) >= getMinimalBulkZeroingSize(INJECTED_OPTIONVALUES))) { |
608 if (theCounters != null && theCounters.instanceBulkInit != null) { |
667 if (theCounters != null && theCounters.instanceBulkInit != null) { |
609 theCounters.instanceBulkInit.inc(); |
668 theCounters.instanceBulkInit.inc(); |
610 } |
669 } |
611 ZeroMemoryNode.zero(memory.add(off), size - offset, LocationIdentity.init()); |
670 ZeroMemoryNode.zero(memory.add(off), endOffset - offset, true, LocationIdentity.init()); |
612 } else { |
671 } else { |
613 if (constantSize && ((size - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) { |
672 if (constantOffsetLimit && ((endOffset - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) { |
614 if (theCounters != null && theCounters.instanceSeqInit != null) { |
673 if (theCounters != null && theCounters.instanceSeqInit != null) { |
615 theCounters.instanceSeqInit.inc(); |
674 theCounters.instanceSeqInit.inc(); |
616 } |
675 } |
617 explodeLoop(); |
676 explodeLoop(); |
618 } else { |
677 } else { |
619 if (theCounters != null && theCounters.instanceLoopInit != null) { |
678 if (theCounters != null && theCounters.instanceLoopInit != null) { |
620 theCounters.instanceLoopInit.inc(); |
679 theCounters.instanceLoopInit.inc(); |
621 } |
680 } |
622 } |
681 } |
623 for (; off.rawValue() < size; off = off.add(8)) { |
682 for (; off.rawValue() < endOffset; off = off.add(8)) { |
624 memory.initializeLong(off, value, LocationIdentity.init()); |
683 memory.initializeLong(off, value, LocationIdentity.init()); |
625 } |
684 } |
626 |
|
627 } |
685 } |
628 } |
686 } |
629 } |
687 } |
630 |
688 |
631 @Fold |
689 @Fold |
635 |
693 |
636 /** |
694 /** |
637 * Fill uninitialized memory with garbage value in a newly allocated object, unrolling as |
695 * Fill uninitialized memory with garbage value in a newly allocated object, unrolling as |
638 * necessary and ensuring that stores are aligned. |
696 * necessary and ensuring that stores are aligned. |
639 * |
697 * |
640 * @param size number of bytes to zero |
|
641 * @param memory beginning of object which is being zeroed |
698 * @param memory beginning of object which is being zeroed |
642 * @param constantSize is {@code size} known to be constant in the snippet |
699 * @param startOffset offset to begin filling garbage value (inclusive). May not be word |
643 * @param startOffset offset to begin zeroing. May not be word aligned. |
700 * aligned. |
|
701 * @param endOffset offset to stop filling garbage value (exclusive). May not be word aligned. |
|
702 * @param isEndOffsetConstant is {@code endOffset} known to be constant in the snippet |
644 * @param manualUnroll maximally unroll zeroing |
703 * @param manualUnroll maximally unroll zeroing |
645 */ |
704 */ |
646 private static void fillWithGarbage(long size, Word memory, boolean constantSize, int startOffset, boolean manualUnroll, Counters counters) { |
705 private static void fillWithGarbage(Word memory, int startOffset, long endOffset, boolean isEndOffsetConstant, boolean manualUnroll, Counters counters) { |
647 fillMemory(0xfefefefefefefefeL, size, memory, constantSize, startOffset, manualUnroll, false, counters); |
706 fillMemory(0xfefefefefefefefeL, memory, startOffset, endOffset, isEndOffsetConstant, manualUnroll, false, counters); |
648 } |
707 } |
649 |
708 |
650 /** |
709 /** |
651 * Formats some allocated memory with an object header and zeroes out the rest. |
710 * Formats some allocated memory with an object header and zeroes out the rest. |
652 */ |
711 */ |
653 private static Object formatObject(KlassPointer hub, long size, Word memory, Word compileTimePrototypeMarkWord, boolean fillContents, boolean constantSize, Counters counters) { |
712 private static Object formatObject(KlassPointer hub, |
|
713 long size, |
|
714 Word memory, |
|
715 Word compileTimePrototypeMarkWord, |
|
716 boolean fillContents, |
|
717 boolean emitMemoryBarrier, |
|
718 boolean constantSize, |
|
719 Counters counters) { |
654 Word prototypeMarkWord = useBiasedLocking(INJECTED_VMCONFIG) ? hub.readWord(prototypeMarkWordOffset(INJECTED_VMCONFIG), PROTOTYPE_MARK_WORD_LOCATION) : compileTimePrototypeMarkWord; |
720 Word prototypeMarkWord = useBiasedLocking(INJECTED_VMCONFIG) ? hub.readWord(prototypeMarkWordOffset(INJECTED_VMCONFIG), PROTOTYPE_MARK_WORD_LOCATION) : compileTimePrototypeMarkWord; |
655 initializeObjectHeader(memory, prototypeMarkWord, hub); |
721 initializeObjectHeader(memory, prototypeMarkWord, hub); |
656 if (fillContents) { |
722 if (fillContents) { |
657 zeroMemory(size, memory, constantSize, instanceHeaderSize(INJECTED_VMCONFIG), false, false, counters); |
723 zeroMemory(memory, instanceHeaderSize(INJECTED_VMCONFIG), size, constantSize, false, false, counters); |
658 } else if (REPLACEMENTS_ASSERTIONS_ENABLED) { |
724 } else if (REPLACEMENTS_ASSERTIONS_ENABLED) { |
659 fillWithGarbage(size, memory, constantSize, instanceHeaderSize(INJECTED_VMCONFIG), false, counters); |
725 fillWithGarbage(memory, instanceHeaderSize(INJECTED_VMCONFIG), size, constantSize, false, counters); |
660 } |
726 } |
661 MembarNode.memoryBarrier(MemoryBarriers.STORE_STORE, LocationIdentity.init()); |
727 if (emitMemoryBarrier) { |
|
728 MembarNode.memoryBarrier(MemoryBarriers.STORE_STORE, LocationIdentity.init()); |
|
729 } |
662 return memory.toObjectNonNull(); |
730 return memory.toObjectNonNull(); |
663 } |
731 } |
664 |
732 |
665 @Snippet |
733 @Snippet |
666 private static void verifyHeap(@ConstantParameter Register threadRegister) { |
734 private static void verifyHeap(@ConstantParameter Register threadRegister) { |
672 AssertionSnippets.vmMessageC(AssertionSnippets.ASSERTION_VM_MESSAGE_C, true, cstring("overzeroing of TLAB detected"), 0L, 0L, 0L); |
740 AssertionSnippets.vmMessageC(AssertionSnippets.ASSERTION_VM_MESSAGE_C, true, cstring("overzeroing of TLAB detected"), 0L, 0L, 0L); |
673 } |
741 } |
674 } |
742 } |
675 } |
743 } |
676 |
744 |
|
745 @Snippet |
|
746 private static void threadBeingInitializedCheck(@ConstantParameter Register threadRegister, KlassPointer klass) { |
|
747 int state = readInstanceKlassInitState(klass); |
|
748 if (state != instanceKlassStateBeingInitialized(INJECTED_VMCONFIG)) { |
|
749 // The klass is no longer being initialized so force recompilation |
|
750 DeoptimizeNode.deopt(InvalidateRecompile, RuntimeConstraint); |
|
751 } else if (registerAsWord(threadRegister) != readInstanceKlassInitThread(klass)) { |
|
752 // The klass is being initialized but this isn't the initializing thread so |
|
753 // so deopt and allow execution to resume in the interpreter where it should block. |
|
754 DeoptimizeNode.deopt(None, RuntimeConstraint); |
|
755 } |
|
756 } |
|
757 |
677 /** |
758 /** |
678 * Formats some allocated memory with an object header and zeroes out the rest. |
759 * Formats some allocated memory with an object header and zeroes out the rest. |
679 */ |
760 */ |
680 private static Object formatArray(KlassPointer hub, long allocationSize, int length, int headerSize, Word memory, Word prototypeMarkWord, boolean fillContents, boolean maybeUnroll, |
761 private static Object formatArray(KlassPointer hub, |
681 boolean useBulkZeroing, Counters counters) { |
762 long allocationSize, |
|
763 int length, |
|
764 int headerSize, |
|
765 Word memory, |
|
766 Word prototypeMarkWord, |
|
767 boolean fillContents, |
|
768 boolean emitMemoryBarrier, |
|
769 boolean maybeUnroll, |
|
770 boolean supportsBulkZeroing, |
|
771 Counters counters) { |
682 memory.writeInt(arrayLengthOffset(INJECTED_VMCONFIG), length, LocationIdentity.init()); |
772 memory.writeInt(arrayLengthOffset(INJECTED_VMCONFIG), length, LocationIdentity.init()); |
683 /* |
773 /* |
684 * store hub last as the concurrent garbage collectors assume length is valid if hub field |
774 * store hub last as the concurrent garbage collectors assume length is valid if hub field |
685 * is not null |
775 * is not null |
686 */ |
776 */ |
687 initializeObjectHeader(memory, prototypeMarkWord, hub); |
777 initializeObjectHeader(memory, prototypeMarkWord, hub); |
688 if (fillContents) { |
778 if (fillContents) { |
689 zeroMemory(allocationSize, memory, false, headerSize, maybeUnroll, useBulkZeroing, counters); |
779 zeroMemory(memory, headerSize, allocationSize, false, maybeUnroll, supportsBulkZeroing, counters); |
690 } else if (REPLACEMENTS_ASSERTIONS_ENABLED) { |
780 } else if (REPLACEMENTS_ASSERTIONS_ENABLED) { |
691 fillWithGarbage(allocationSize, memory, false, headerSize, maybeUnroll, counters); |
781 fillWithGarbage(memory, headerSize, allocationSize, false, maybeUnroll, counters); |
692 } |
782 } |
693 MembarNode.memoryBarrier(MemoryBarriers.STORE_STORE, LocationIdentity.init()); |
783 if (emitMemoryBarrier) { |
|
784 MembarNode.memoryBarrier(MemoryBarriers.STORE_STORE, LocationIdentity.init()); |
|
785 } |
694 return memory.toObjectNonNull(); |
786 return memory.toObjectNonNull(); |
695 } |
787 } |
696 |
788 |
697 static class Counters { |
789 static class Counters { |
698 Counters(SnippetCounter.Group.Factory factory) { |
790 Counters(SnippetCounter.Group.Factory factory) { |
712 final SnippetCounter stub; |
804 final SnippetCounter stub; |
713 } |
805 } |
714 |
806 |
715 public static class Templates extends AbstractTemplates { |
807 public static class Templates extends AbstractTemplates { |
716 |
808 |
717 private final SnippetInfo allocateInstance = snippet(NewObjectSnippets.class, "allocateInstance", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION); |
809 private final SnippetInfo allocateInstance = snippet(NewObjectSnippets.class, "allocateInstance", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION, |
|
810 PROTOTYPE_MARK_WORD_LOCATION); |
718 private final SnippetInfo allocateInstancePIC = snippet(NewObjectSnippets.class, "allocateInstancePIC", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, |
811 private final SnippetInfo allocateInstancePIC = snippet(NewObjectSnippets.class, "allocateInstancePIC", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, |
719 TLAB_END_LOCATION); |
812 TLAB_END_LOCATION, PROTOTYPE_MARK_WORD_LOCATION); |
720 private final SnippetInfo allocateArray = snippet(NewObjectSnippets.class, "allocateArray", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION); |
813 private final SnippetInfo allocateArray = snippet(NewObjectSnippets.class, "allocateArray", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION); |
721 private final SnippetInfo allocateArrayPIC = snippet(NewObjectSnippets.class, "allocateArrayPIC", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION); |
814 private final SnippetInfo allocateArrayPIC = snippet(NewObjectSnippets.class, "allocateArrayPIC", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION); |
722 private final SnippetInfo allocatePrimitiveArrayPIC = snippet(NewObjectSnippets.class, "allocatePrimitiveArrayPIC", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, |
815 private final SnippetInfo allocatePrimitiveArrayPIC = snippet(NewObjectSnippets.class, "allocatePrimitiveArrayPIC", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, |
723 TLAB_END_LOCATION); |
816 TLAB_END_LOCATION); |
724 private final SnippetInfo allocateArrayDynamic = snippet(NewObjectSnippets.class, "allocateArrayDynamic", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, |
817 private final SnippetInfo allocateArrayDynamic = snippet(NewObjectSnippets.class, "allocateArrayDynamic", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, |
725 TLAB_END_LOCATION); |
818 TLAB_END_LOCATION); |
726 private final SnippetInfo allocateInstanceDynamic = snippet(NewObjectSnippets.class, "allocateInstanceDynamic", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, |
819 private final SnippetInfo allocateInstanceDynamic = snippet(NewObjectSnippets.class, "allocateInstanceDynamic", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, |
727 TLAB_END_LOCATION); |
820 TLAB_END_LOCATION, PROTOTYPE_MARK_WORD_LOCATION, CLASS_INIT_STATE_LOCATION); |
728 private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray", TLAB_TOP_LOCATION, TLAB_END_LOCATION); |
821 private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray", TLAB_TOP_LOCATION, TLAB_END_LOCATION); |
729 private final SnippetInfo newmultiarrayPIC = snippet(NewObjectSnippets.class, "newmultiarrayPIC", TLAB_TOP_LOCATION, TLAB_END_LOCATION); |
822 private final SnippetInfo newmultiarrayPIC = snippet(NewObjectSnippets.class, "newmultiarrayPIC", TLAB_TOP_LOCATION, TLAB_END_LOCATION); |
730 private final SnippetInfo verifyHeap = snippet(NewObjectSnippets.class, "verifyHeap"); |
823 private final SnippetInfo verifyHeap = snippet(NewObjectSnippets.class, "verifyHeap"); |
|
824 private final SnippetInfo threadBeingInitializedCheck = snippet(NewObjectSnippets.class, "threadBeingInitializedCheck"); |
731 private final GraalHotSpotVMConfig config; |
825 private final GraalHotSpotVMConfig config; |
732 private final Counters counters; |
826 private final Counters counters; |
733 |
827 |
734 public Templates(OptionValues options, Iterable<DebugHandlersFactory> factories, SnippetCounter.Group.Factory factory, HotSpotProviders providers, TargetDescription target, |
828 public Templates(OptionValues options, Iterable<DebugHandlersFactory> factories, SnippetCounter.Group.Factory factory, HotSpotProviders providers, TargetDescription target, |
735 GraalHotSpotVMConfig config) { |
829 GraalHotSpotVMConfig config) { |
753 Arguments args = new Arguments(snippet, graph.getGuardsStage(), tool.getLoweringStage()); |
847 Arguments args = new Arguments(snippet, graph.getGuardsStage(), tool.getLoweringStage()); |
754 args.addConst("size", size); |
848 args.addConst("size", size); |
755 args.add("hub", hub); |
849 args.add("hub", hub); |
756 args.add("prototypeMarkWord", type.prototypeMarkWord()); |
850 args.add("prototypeMarkWord", type.prototypeMarkWord()); |
757 args.addConst("fillContents", newInstanceNode.fillContents()); |
851 args.addConst("fillContents", newInstanceNode.fillContents()); |
|
852 args.addConst("emitMemoryBarrier", newInstanceNode.emitMemoryBarrier()); |
758 args.addConst("threadRegister", registers.getThreadRegister()); |
853 args.addConst("threadRegister", registers.getThreadRegister()); |
759 args.addConst("constantSize", true); |
854 args.addConst("constantSize", true); |
760 args.addConst("typeContext", ProfileAllocations.getValue(localOptions) ? type.toJavaName(false) : ""); |
855 args.addConst("typeContext", ProfileAllocations.getValue(localOptions) ? type.toJavaName(false) : ""); |
761 args.addConst("counters", counters); |
856 args.addConst("counters", counters); |
762 |
857 |
796 assert arrayType.prototypeMarkWord() == lookupArrayClass(tool, JavaKind.Object).prototypeMarkWord() : "all array types are assumed to have the same prototypeMarkWord"; |
891 assert arrayType.prototypeMarkWord() == lookupArrayClass(tool, JavaKind.Object).prototypeMarkWord() : "all array types are assumed to have the same prototypeMarkWord"; |
797 args.add("prototypeMarkWord", arrayType.prototypeMarkWord()); |
892 args.add("prototypeMarkWord", arrayType.prototypeMarkWord()); |
798 args.addConst("headerSize", headerSize); |
893 args.addConst("headerSize", headerSize); |
799 args.addConst("log2ElementSize", log2ElementSize); |
894 args.addConst("log2ElementSize", log2ElementSize); |
800 args.addConst("fillContents", newArrayNode.fillContents()); |
895 args.addConst("fillContents", newArrayNode.fillContents()); |
|
896 args.addConst("emitMemoryBarrier", newArrayNode.emitMemoryBarrier()); |
801 args.addConst("threadRegister", registers.getThreadRegister()); |
897 args.addConst("threadRegister", registers.getThreadRegister()); |
802 args.addConst("maybeUnroll", length.isConstant()); |
898 args.addConst("maybeUnroll", length.isConstant()); |
803 args.addConst("typeContext", ProfileAllocations.getValue(localOptions) ? arrayType.toJavaName(false) : ""); |
899 args.addConst("typeContext", ProfileAllocations.getValue(localOptions) ? arrayType.toJavaName(false) : ""); |
804 args.addConst("useBulkZeroing", tool.getLowerer().supportBulkZeroing()); |
900 args.addConst("supportsBulkZeroing", tool.getLowerer().supportsBulkZeroing()); |
805 args.addConst("counters", counters); |
901 args.addConst("counters", counters); |
806 SnippetTemplate template = template(newArrayNode, args); |
902 SnippetTemplate template = template(newArrayNode, args); |
807 graph.getDebug().log("Lowering allocateArray in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, args); |
903 graph.getDebug().log("Lowering allocateArray in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, args); |
808 template.instantiate(providers.getMetaAccess(), newArrayNode, DEFAULT_REPLACER, args); |
904 template.instantiate(providers.getMetaAccess(), newArrayNode, DEFAULT_REPLACER, args); |
809 } |
905 } |
813 args.add("type", newInstanceNode.getInstanceType()); |
909 args.add("type", newInstanceNode.getInstanceType()); |
814 ValueNode classClass = newInstanceNode.getClassClass(); |
910 ValueNode classClass = newInstanceNode.getClassClass(); |
815 assert classClass != null; |
911 assert classClass != null; |
816 args.add("classClass", classClass); |
912 args.add("classClass", classClass); |
817 args.addConst("fillContents", newInstanceNode.fillContents()); |
913 args.addConst("fillContents", newInstanceNode.fillContents()); |
|
914 args.addConst("emitMemoryBarrier", newInstanceNode.emitMemoryBarrier()); |
818 args.addConst("threadRegister", registers.getThreadRegister()); |
915 args.addConst("threadRegister", registers.getThreadRegister()); |
819 args.addConst("counters", counters); |
916 args.addConst("counters", counters); |
820 |
917 |
821 SnippetTemplate template = template(newInstanceNode, args); |
918 SnippetTemplate template = template(newInstanceNode, args); |
822 template.instantiate(providers.getMetaAccess(), newInstanceNode, DEFAULT_REPLACER, args); |
919 template.instantiate(providers.getMetaAccess(), newInstanceNode, DEFAULT_REPLACER, args); |
841 if (newArrayNode.getKnownElementKind() != null) { |
939 if (newArrayNode.getKnownElementKind() != null) { |
842 args.addConst("knownLayoutHelper", lookupArrayClass(tool, newArrayNode.getKnownElementKind()).layoutHelper()); |
940 args.addConst("knownLayoutHelper", lookupArrayClass(tool, newArrayNode.getKnownElementKind()).layoutHelper()); |
843 } else { |
941 } else { |
844 args.addConst("knownLayoutHelper", 0); |
942 args.addConst("knownLayoutHelper", 0); |
845 } |
943 } |
846 args.addConst("useBulkZeroing", tool.getLowerer().supportBulkZeroing()); |
944 args.addConst("supportsBulkZeroing", tool.getLowerer().supportsBulkZeroing()); |
847 args.add("prototypeMarkWord", lookupArrayClass(tool, JavaKind.Object).prototypeMarkWord()); |
945 args.add("prototypeMarkWord", lookupArrayClass(tool, JavaKind.Object).prototypeMarkWord()); |
848 args.addConst("counters", counters); |
946 args.addConst("counters", counters); |
849 SnippetTemplate template = template(newArrayNode, args); |
947 SnippetTemplate template = template(newArrayNode, args); |
850 template.instantiate(providers.getMetaAccess(), newArrayNode, DEFAULT_REPLACER, args); |
948 template.instantiate(providers.getMetaAccess(), newArrayNode, DEFAULT_REPLACER, args); |
851 } |
949 } |