-
Notifications
You must be signed in to change notification settings - Fork 5.2k
/
CompilerToVM.java
1469 lines (1265 loc) · 65.7 KB
/
CompilerToVM.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.common.InitTimer.timer;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import jdk.internal.misc.Unsafe;
import jdk.vm.ci.code.BytecodeFrame;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.code.InvalidInstalledCodeException;
import jdk.vm.ci.code.stack.InspectedFrameVisitor;
import jdk.vm.ci.common.InitTimer;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
/**
* Calls from Java into HotSpot. The behavior of all the methods in this class that take a native
* pointer as an argument (e.g., {@link #getSymbol(long)}) is undefined if the argument does not
* denote a valid native object.
*
* Note also that some calls pass a raw VM value to avoid a JNI upcall. For example,
* {@link #getBytecode(HotSpotResolvedJavaMethodImpl, long)} needs the raw {@code Method*} value
* (stored in {@link HotSpotResolvedJavaMethodImpl#methodHandle}) in the C++ implementation. The
* {@link HotSpotResolvedJavaMethodImpl} wrapper is still passed as well as it may be the last
* reference keeping the raw value alive.
*/
final class CompilerToVM {
/**
* Initializes the native part of the JVMCI runtime.
*/
private static native void registerNatives();
/**
* These values mirror the equivalent values from {@code Unsafe} but are appropriate for the JVM
* being compiled against.
*/
final int ARRAY_BOOLEAN_BASE_OFFSET;
final int ARRAY_BYTE_BASE_OFFSET;
final int ARRAY_SHORT_BASE_OFFSET;
final int ARRAY_CHAR_BASE_OFFSET;
final int ARRAY_INT_BASE_OFFSET;
final int ARRAY_LONG_BASE_OFFSET;
final int ARRAY_FLOAT_BASE_OFFSET;
final int ARRAY_DOUBLE_BASE_OFFSET;
final int ARRAY_OBJECT_BASE_OFFSET;
final int ARRAY_BOOLEAN_INDEX_SCALE;
final int ARRAY_BYTE_INDEX_SCALE;
final int ARRAY_SHORT_INDEX_SCALE;
final int ARRAY_CHAR_INDEX_SCALE;
final int ARRAY_INT_INDEX_SCALE;
final int ARRAY_LONG_INDEX_SCALE;
final int ARRAY_FLOAT_INDEX_SCALE;
final int ARRAY_DOUBLE_INDEX_SCALE;
final int ARRAY_OBJECT_INDEX_SCALE;
@SuppressWarnings("try")
CompilerToVM() {
try (InitTimer t = timer("CompilerToVM.registerNatives")) {
registerNatives();
ARRAY_BOOLEAN_BASE_OFFSET = arrayBaseOffset(JavaKind.Boolean.getTypeChar());
ARRAY_BYTE_BASE_OFFSET = arrayBaseOffset(JavaKind.Byte.getTypeChar());
ARRAY_SHORT_BASE_OFFSET = arrayBaseOffset(JavaKind.Short.getTypeChar());
ARRAY_CHAR_BASE_OFFSET = arrayBaseOffset(JavaKind.Char.getTypeChar());
ARRAY_INT_BASE_OFFSET = arrayBaseOffset(JavaKind.Int.getTypeChar());
ARRAY_LONG_BASE_OFFSET = arrayBaseOffset(JavaKind.Long.getTypeChar());
ARRAY_FLOAT_BASE_OFFSET = arrayBaseOffset(JavaKind.Float.getTypeChar());
ARRAY_DOUBLE_BASE_OFFSET = arrayBaseOffset(JavaKind.Double.getTypeChar());
ARRAY_OBJECT_BASE_OFFSET = arrayBaseOffset(JavaKind.Object.getTypeChar());
ARRAY_BOOLEAN_INDEX_SCALE = arrayIndexScale(JavaKind.Boolean.getTypeChar());
ARRAY_BYTE_INDEX_SCALE = arrayIndexScale(JavaKind.Byte.getTypeChar());
ARRAY_SHORT_INDEX_SCALE = arrayIndexScale(JavaKind.Short.getTypeChar());
ARRAY_CHAR_INDEX_SCALE = arrayIndexScale(JavaKind.Char.getTypeChar());
ARRAY_INT_INDEX_SCALE = arrayIndexScale(JavaKind.Int.getTypeChar());
ARRAY_LONG_INDEX_SCALE = arrayIndexScale(JavaKind.Long.getTypeChar());
ARRAY_FLOAT_INDEX_SCALE = arrayIndexScale(JavaKind.Float.getTypeChar());
ARRAY_DOUBLE_INDEX_SCALE = arrayIndexScale(JavaKind.Double.getTypeChar());
ARRAY_OBJECT_INDEX_SCALE = arrayIndexScale(JavaKind.Object.getTypeChar());
}
}
native int arrayBaseOffset(char typeChar);
native int arrayIndexScale(char typeChar);
/**
* Gets the {@link CompilerToVM} instance associated with the singleton
* {@link HotSpotJVMCIRuntime} instance.
*/
public static CompilerToVM compilerToVM() {
return runtime().getCompilerToVM();
}
/**
* Copies the original bytecode of {@code method} into a new byte array and returns it.
*
* @return a new byte array containing the original bytecode of {@code method}
*/
byte[] getBytecode(HotSpotResolvedJavaMethodImpl method) {
return getBytecode(method, method.getMethodPointer());
}
private native byte[] getBytecode(HotSpotResolvedJavaMethodImpl method, long methodPointer);
/**
* Gets the number of entries in {@code method}'s exception handler table or 0 if it has no
* exception handler table.
*/
int getExceptionTableLength(HotSpotResolvedJavaMethodImpl method) {
return getExceptionTableLength(method, method.getMethodPointer());
}
private native int getExceptionTableLength(HotSpotResolvedJavaMethodImpl method, long methodPointer);
/**
* Gets the address of the first entry in {@code method}'s exception handler table.
*
* Each entry is a native object described by these fields:
*
* <ul>
* <li>{@link HotSpotVMConfig#exceptionTableElementSize}</li>
* <li>{@link HotSpotVMConfig#exceptionTableElementStartPcOffset}</li>
* <li>{@link HotSpotVMConfig#exceptionTableElementEndPcOffset}</li>
* <li>{@link HotSpotVMConfig#exceptionTableElementHandlerPcOffset}</li>
* <li>{@link HotSpotVMConfig#exceptionTableElementCatchTypeIndexOffset}
* </ul>
*
* @return 0 if {@code method} has no exception handlers (i.e.
* {@code getExceptionTableLength(method) == 0})
*/
long getExceptionTableStart(HotSpotResolvedJavaMethodImpl method) {
return getExceptionTableStart(method, method.getMethodPointer());
}
private native long getExceptionTableStart(HotSpotResolvedJavaMethodImpl method, long methodPointer);
/**
* Determines whether {@code method} is currently compilable by the JVMCI compiler being used by
* the VM. This can return false if JVMCI compilation failed earlier for {@code method}, a
* breakpoint is currently set in {@code method} or {@code method} contains other bytecode
* features that require special handling by the VM.
*/
boolean isCompilable(HotSpotResolvedJavaMethodImpl method) {
return isCompilable(method, method.getMethodPointer());
}
private native boolean isCompilable(HotSpotResolvedJavaMethodImpl method, long methodPointer);
/**
* Determines if {@code method} is targeted by a VM directive (e.g.,
* {@code -XX:CompileCommand=dontinline,<pattern>}) or annotation (e.g.,
* {@code jdk.internal.vm.annotation.DontInline}) that specifies it should not be inlined.
*/
boolean hasNeverInlineDirective(HotSpotResolvedJavaMethodImpl method) {
return hasNeverInlineDirective(method, method.getMethodPointer());
}
private native boolean hasNeverInlineDirective(HotSpotResolvedJavaMethodImpl method, long methodPointer);
/**
* Determines if {@code method} should be inlined at any cost. This could be because:
* <ul>
* <li>a CompileOracle directive may forces inlining of this methods</li>
* <li>an annotation forces inlining of this method</li>
* </ul>
*/
boolean shouldInlineMethod(HotSpotResolvedJavaMethodImpl method) {
return shouldInlineMethod(method, method.getMethodPointer());
}
private native boolean shouldInlineMethod(HotSpotResolvedJavaMethodImpl method, long methodPointer);
/**
* Used to implement {@link ResolvedJavaType#findUniqueConcreteMethod(ResolvedJavaMethod)}.
*
* @param actualHolderType the best known type of receiver
* @param method the method on which to base the search
* @return the method result or 0 is there is no unique concrete method for {@code method}
*/
HotSpotResolvedJavaMethodImpl findUniqueConcreteMethod(HotSpotResolvedObjectTypeImpl actualHolderType, HotSpotResolvedJavaMethodImpl method) {
return findUniqueConcreteMethod(actualHolderType, actualHolderType.getKlassPointer(), method, method.getMetaspacePointer());
}
private native HotSpotResolvedJavaMethodImpl findUniqueConcreteMethod(HotSpotResolvedObjectTypeImpl klass, long klassPointer, HotSpotResolvedJavaMethodImpl method, long methodPointer);
/**
* Gets the implementor for the interface class {@code type}.
*
* @return the implementor if there is a single implementor, {@code null} if there is no
* implementor, or {@code type} itself if there is more than one implementor
* @throws IllegalArgumentException if type is not an interface type
*/
HotSpotResolvedObjectTypeImpl getImplementor(HotSpotResolvedObjectTypeImpl type) {
return getImplementor(type, type.getKlassPointer());
}
private native HotSpotResolvedObjectTypeImpl getImplementor(HotSpotResolvedObjectTypeImpl type, long klassPointer);
/**
* Determines if {@code method} is ignored by security stack walks.
*/
boolean methodIsIgnoredBySecurityStackWalk(HotSpotResolvedJavaMethodImpl method) {
return methodIsIgnoredBySecurityStackWalk(method, method.getMetaspacePointer());
}
private native boolean methodIsIgnoredBySecurityStackWalk(HotSpotResolvedJavaMethodImpl method, long methodPointer);
/**
* Converts a name to a type.
*
* @param name a well formed Java type in {@linkplain JavaType#getName() internal} format
* @param accessingClass the class loader of this class is used for resolution. Must not be null.
* @param resolve force resolution to a {@link ResolvedJavaType}. If true, this method will
* either return a {@link ResolvedJavaType} or throw an exception
* @return the type for {@code name} or {@code null} if resolution failed and {@code resolve == false}
* @throws NoClassDefFoundError if {@code resolve == true} and the resolution failed
*/
HotSpotResolvedJavaType lookupType(String name, HotSpotResolvedObjectTypeImpl accessingClass, boolean resolve) throws NoClassDefFoundError {
return lookupType(name, accessingClass, accessingClass.getKlassPointer(), -1, resolve);
}
/**
* Converts a name to a type.
*
* @param classLoader the class loader to use for resolution. Must not be {@code null},
* {@link ClassLoader#getPlatformClassLoader} or {@link ClassLoader#getSystemClassLoader}
* @param name a well formed Java type in {@linkplain JavaType#getName() internal} format
* @return the type for {@code name}
* @throws NoClassDefFoundError if resolution failed
*/
HotSpotResolvedJavaType lookupType(ClassLoader classLoader, String name) throws NoClassDefFoundError {
int accessingClassLoader;
if (classLoader == null) {
accessingClassLoader = 0;
} else if (classLoader == ClassLoader.getPlatformClassLoader()) {
accessingClassLoader = 1;
} else if (classLoader == ClassLoader.getSystemClassLoader()) {
accessingClassLoader = 2;
} else {
throw new IllegalArgumentException("Unsupported class loader for lookup: " + classLoader);
}
return lookupType(name, null, 0L, accessingClassLoader, true);
}
/**
* @param accessingClassLoader ignored if {@code accessingKlassPointer != 0L}. Otherwise, the supported values are:
* 0 - boot class loader
* 1 - {@linkplain ClassLoader#getPlatformClassLoader() platform class loader}
* 2 - {@linkplain ClassLoader#getSystemClassLoader() system class loader}
*/
private native HotSpotResolvedJavaType lookupType(String name, HotSpotResolvedObjectTypeImpl accessingClass, long accessingKlassPointer, int accessingClassLoader, boolean resolve) throws NoClassDefFoundError;
/**
* Converts {@code javaClass} to a HotSpotResolvedJavaType.
*
* Must not be called if {@link Services#IS_IN_NATIVE_IMAGE} is {@code true}.
*/
native HotSpotResolvedJavaType lookupClass(Class<?> javaClass);
native HotSpotResolvedJavaType lookupJClass(long jclass);
/**
* Resolves the entry at index {@code cpi} in {@code constantPool} to an interned String object.
*
* The behavior of this method is undefined if {@code cpi} does not denote an
* {@code JVM_CONSTANT_String}.
*/
JavaConstant getUncachedStringInPool(HotSpotConstantPool constantPool, int cpi) {
return getUncachedStringInPool(constantPool, constantPool.getConstantPoolPointer(), cpi);
}
private native JavaConstant getUncachedStringInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi);
/**
* Gets the entry at index {@code cpi} in {@code constantPool}, looking in the
* constant pool cache first.
*
* The behavior of this method is undefined if {@code cpi} does not denote one of the following
* entry types: {@code JVM_CONSTANT_Dynamic}, {@code JVM_CONSTANT_String},
* {@code JVM_CONSTANT_MethodHandle}, {@code JVM_CONSTANT_MethodHandleInError},
* {@code JVM_CONSTANT_MethodType} and {@code JVM_CONSTANT_MethodTypeInError}.
*
* @param resolve specifies if a resolved entry is expected. If {@code false},
* {@code null} is returned for an unresolved entry.
*/
JavaConstant lookupConstantInPool(HotSpotConstantPool constantPool, int cpi, boolean resolve) {
return lookupConstantInPool(constantPool, constantPool.getConstantPoolPointer(), cpi, resolve);
}
private native JavaConstant lookupConstantInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi, boolean resolve);
/**
* Gets the {@code JVM_CONSTANT_NameAndType} index referenced by the {@code rawIndex}.
* The meaning of {@code rawIndex} is dependent on the given {@opcode}.
*
* The behavior of this method is undefined if the class holding the {@code constantPool}
* has not yet been rewritten, or {@code rawIndex} is not a valid index for
* this class for the given {@code opcode}
*/
int lookupNameAndTypeRefIndexInPool(HotSpotConstantPool constantPool, int rawIndex, int opcode) {
return lookupNameAndTypeRefIndexInPool(constantPool, constantPool.getConstantPoolPointer(), rawIndex, opcode);
}
private native int lookupNameAndTypeRefIndexInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int rawIndex, int opcode);
/**
* Gets the name of the {@code JVM_CONSTANT_NameAndType} entry in {@code constantPool}
* referenced by the {@code rawIndex}. The meaning of {@code rawIndex} is dependent
* on the given {@opcode}.
*
* The behavior of this method is undefined if the class holding the {@code constantPool}
* has not yet been rewritten, or {@code rawIndex} is not a valid index for
* this class for the given {@code opcode}
*/
String lookupNameInPool(HotSpotConstantPool constantPool, int rawIndex, int opcode) {
return lookupNameInPool(constantPool, constantPool.getConstantPoolPointer(), rawIndex, opcode);
}
private native String lookupNameInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int rawIndex, int opcode);
/**
* Gets the signature of the {@code JVM_CONSTANT_NameAndType} entry in {@code constantPool}
* referenced by the {@code rawIndex}. The meaning of {@code rawIndex} is dependent
* on the given {@opcode}.
*
* The behavior of this method is undefined if the class holding the {@code constantPool}
* has not yet been rewritten, or {@code rawIndex} is not a valid index for
* this class for the given {@code opcode}
*/
String lookupSignatureInPool(HotSpotConstantPool constantPool, int rawIndex, int opcode) {
return lookupSignatureInPool(constantPool, constantPool.getConstantPoolPointer(), rawIndex, opcode);
}
private native String lookupSignatureInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int rawIndex, int opcode);
/**
* Gets the {@code JVM_CONSTANT_Class} index from the entry in {@code constantPool}
* referenced by the {@code rawIndex}. The meaning of {@code rawIndex} is dependent
* on the given {@opcode}.
*
* The behavior of this method is undefined if the class holding the {@code constantPool}
* has not yet been rewritten, or {@code rawIndex} is not a valid index for
* this class for the given {@code opcode}
*/
int lookupKlassRefIndexInPool(HotSpotConstantPool constantPool, int rawIndex, int opcode) {
return lookupKlassRefIndexInPool(constantPool, constantPool.getConstantPoolPointer(), rawIndex, opcode);
}
private native int lookupKlassRefIndexInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int rawIndex, int opcode);
/**
* Looks up a class denoted by the {@code JVM_CONSTANT_Class} entry at index {@code cpi} in
* {@code constantPool}. This method does not perform any resolution.
*
* The behavior of this method is undefined if {@code cpi} does not denote a
* {@code JVM_CONSTANT_Class} entry.
*
* @return the resolved class entry or a String otherwise
*/
Object lookupKlassInPool(HotSpotConstantPool constantPool, int cpi) {
return lookupKlassInPool(constantPool, constantPool.getConstantPoolPointer(), cpi);
}
private native Object lookupKlassInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi);
/**
* Looks up a method denoted by the entry at index {@code cpi} in {@code constantPool}. This
* method does not perform any resolution.
*
* The behavior of this method is undefined if {@code cpi} does not denote an entry representing
* a method.
*
* @param opcode the opcode of the instruction for which the lookup is being performed or
* {@code -1}. If non-negative, then resolution checks specific to the bytecode it
* denotes are performed if the method is already resolved. Should any of these
* checks fail, 0 is returned.
* @param caller if non-null, do access checks in the context of {@code caller} calling the
* looked up method
* @return the resolved method entry, 0 otherwise
*/
HotSpotResolvedJavaMethodImpl lookupMethodInPool(HotSpotConstantPool constantPool, int cpi, byte opcode, HotSpotResolvedJavaMethodImpl caller) {
long callerMethodPointer = caller == null ? 0L : caller.getMethodPointer();
return lookupMethodInPool(constantPool, constantPool.getConstantPoolPointer(), cpi, opcode, caller, callerMethodPointer);
}
private native HotSpotResolvedJavaMethodImpl lookupMethodInPool(HotSpotConstantPool constantPool,
long constantPoolPointer,
int cpi,
byte opcode,
HotSpotResolvedJavaMethodImpl caller,
long callerMethodPointer);
/**
* Converts the encoded indy index operand of an invokedynamic instruction
* to an index directly into {@code constantPool}.
*
* @param resolve if {@true}, then resolve the entry (which may call a bootstrap method)
* @throws IllegalArgumentException if {@code encoded_indy_index} is not an encoded indy index
* @return {@code JVM_CONSTANT_InvokeDynamic} constant pool entry index for the invokedynamic
*/
int decodeIndyIndexToCPIndex(HotSpotConstantPool constantPool, int encoded_indy_index, boolean resolve) {
return decodeIndyIndexToCPIndex(constantPool, constantPool.getConstantPoolPointer(), encoded_indy_index, resolve);
}
private native int decodeIndyIndexToCPIndex(HotSpotConstantPool constantPool, long constantPoolPointer, int encoded_indy_index, boolean resolve);
/**
* Converts the {@code rawIndex} operand of a rewritten getfield/putfield/getstatic/putstatic instruction
* to an index directly into {@code constantPool}.
*
* @throws IllegalArgumentException if {@code rawIndex} is out of range.
* @return {@code JVM_CONSTANT_FieldRef} constant pool entry index for the invokedynamic
*/
int decodeFieldIndexToCPIndex(HotSpotConstantPool constantPool, int rawIndex) {
return decodeFieldIndexToCPIndex(constantPool, constantPool.getConstantPoolPointer(), rawIndex);
}
private native int decodeFieldIndexToCPIndex(HotSpotConstantPool constantPool, long constantPoolPointer, int rawIndex);
/**
* Resolves the details for invoking the bootstrap method associated with the
* {@code CONSTANT_Dynamic_info} or @{code CONSTANT_InvokeDynamic_info} entry at {@code cpi} in
* {@code constant pool}.
*
* The return value encodes the details in an object array that is described by the pseudo Java
* object {@code info} below:
*
* <pre>
* bsm_invocation = [
* ResolvedJavaMethod[] method,
* String name,
* Object type, // JavaConstant: reference to Class (condy) or MethodType (indy)
* Object staticArguments, // null: no static arguments
* // JavaConstant: single static argument
* // JavaConstant[]: multiple static arguments
* // int[]: static arguments to be resolved via BootstrapCallInfo
* ]
* </pre>
*
* @return bootstrap method invocation details as encoded above
*/
Object[] resolveBootstrapMethod(HotSpotConstantPool constantPool, int cpi) {
return resolveBootstrapMethod(constantPool, constantPool.getConstantPoolPointer(), cpi);
}
private native Object[] resolveBootstrapMethod(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi);
/**
* If {@code cpi} denotes an entry representing a signature polymorphic method ({@jvms 2.9}),
* this method ensures that the type referenced by the entry is loaded and initialized. It
* {@code cpi} does not denote a signature polymorphic method, this method does nothing.
*/
void resolveInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi) {
resolveInvokeHandleInPool(constantPool, constantPool.getConstantPoolPointer(), cpi);
}
private native void resolveInvokeHandleInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi);
/**
* If {@code cpi} denotes an entry representing a resolved dynamic adapter (see
* {@link #decodeIndyIndexToCPIndex} and {@link #resolveInvokeHandleInPool}), return the
* opcode of the instruction for which the resolution was performed ({@code invokedynamic} or
* {@code invokevirtual}), or {@code -1} otherwise.
*/
int isResolvedInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi) {
return isResolvedInvokeHandleInPool(constantPool, constantPool.getConstantPoolPointer(), cpi);
}
private native int isResolvedInvokeHandleInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi);
/**
* Gets the list of type names (in the format of {@link JavaType#getName()}) denoting the
* classes that define signature polymorphic methods.
*/
native String[] getSignaturePolymorphicHolders();
/**
* Gets the resolved type denoted by the entry at index {@code cpi} in {@code constantPool}.
*
* The behavior of this method is undefined if {@code cpi} does not denote an entry representing
* a class.
*
* @throws LinkageError if resolution failed
*/
HotSpotResolvedObjectTypeImpl resolveTypeInPool(HotSpotConstantPool constantPool, int cpi) throws LinkageError {
return resolveTypeInPool(constantPool, constantPool.getConstantPoolPointer(), cpi);
}
private native HotSpotResolvedObjectTypeImpl resolveTypeInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi) throws LinkageError;
/**
* Looks up and attempts to resolve the {@code JVM_CONSTANT_Field} entry denoted by
* {@code rawIndex}. For some opcodes, checks are performed that require the
* {@code method} that contains {@code opcode} to be specified. The values returned in
* {@code info} are:
*
* <pre>
* [ aflags, // fieldDescriptor::access_flags()
* offset, // fieldDescriptor::offset()
* index, // fieldDescriptor::index()
* fflags // fieldDescriptor::field_flags()
* ]
* </pre>
*
* The behavior of this method is undefined if {@code rawIndex} is invalid.
*
* @param info an array in which the details of the field are returned
* @return the type defining the field if resolution is successful, null otherwise
*/
HotSpotResolvedObjectTypeImpl resolveFieldInPool(HotSpotConstantPool constantPool, int rawIndex, HotSpotResolvedJavaMethodImpl method, byte opcode, int[] info) {
long methodPointer = method != null ? method.getMethodPointer() : 0L;
return resolveFieldInPool(constantPool, constantPool.getConstantPoolPointer(), rawIndex, method, methodPointer, opcode, info);
}
private native HotSpotResolvedObjectTypeImpl resolveFieldInPool(HotSpotConstantPool constantPool, long constantPoolPointer,
int rawIndex, HotSpotResolvedJavaMethodImpl method, long methodPointer, byte opcode, int[] info);
/**
* Converts {@code cpci} from an index into the cache for {@code constantPool} to an index
* directly into {@code constantPool}.
*
* The behavior of this method is undefined if {@code cpci} is an invalid constant pool cache
* index.
*/
int constantPoolRemapInstructionOperandFromCache(HotSpotConstantPool constantPool, int cpci) {
return constantPoolRemapInstructionOperandFromCache(constantPool, constantPool.getConstantPoolPointer(), cpci);
}
private native int constantPoolRemapInstructionOperandFromCache(HotSpotConstantPool constantPool, long constantPoolPointer, int cpci);
/**
* Gets the appendix object (if any) associated with the entry identified by {@code which}.
*
* @param which if negative, is treated as an encoded indy index for INVOKEDYNAMIC;
* Otherwise, it's treated as a constant pool cache index (returned by HotSpotConstantPool::rawIndexToConstantPoolCacheIndex)
* for INVOKE{VIRTUAL,SPECIAL,STATIC,INTERFACE}.
*/
HotSpotObjectConstantImpl lookupAppendixInPool(HotSpotConstantPool constantPool, int which) {
return lookupAppendixInPool(constantPool, constantPool.getConstantPoolPointer(), which);
}
private native HotSpotObjectConstantImpl lookupAppendixInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int which);
/**
* Installs the result of a compilation into the code cache.
*
* @param compiledCode the result of a compilation
* @param code the details of the installed CodeBlob are written to this object
*
* @return the outcome of the installation which will be one of
* {@link HotSpotVMConfig#codeInstallResultOk},
* {@link HotSpotVMConfig#codeInstallResultCacheFull},
* {@link HotSpotVMConfig#codeInstallResultCodeTooLarge} or
* {@link HotSpotVMConfig#codeInstallResultDependenciesFailed}.
* @throws JVMCIError if there is something wrong with the compiled code or the associated
* metadata.
*/
int installCode(HotSpotCompiledCode compiledCode, InstalledCode code, long failedSpeculationsAddress, byte[] speculations) {
int codeInstallFlags = getInstallCodeFlags();
boolean withComments = (codeInstallFlags & 0x0001) != 0;
boolean withMethods = (codeInstallFlags & 0x0002) != 0;
boolean withTypeInfo;
if ((codeInstallFlags & 0x0004) != 0 && HotSpotJVMCIRuntime.Option.CodeSerializationTypeInfo.isDefault) {
withTypeInfo = true;
} else {
withTypeInfo = HotSpotJVMCIRuntime.Option.CodeSerializationTypeInfo.getBoolean();
}
try (HotSpotCompiledCodeStream stream = new HotSpotCompiledCodeStream(compiledCode, withTypeInfo, withComments, withMethods)) {
return installCode0(stream.headChunk, stream.timeNS, withTypeInfo, compiledCode, stream.objectPool, code, failedSpeculationsAddress, speculations);
}
}
native int installCode0(long compiledCodeBuffer,
long serializationNS,
boolean withTypeInfo,
HotSpotCompiledCode compiledCode,
Object[] objectPool,
InstalledCode code,
long failedSpeculationsAddress,
byte[] speculations);
/**
* Gets flags specifying optional parts of code info. Only if a flag is set, will the
* corresponding code info being included in the {@linkplain HotSpotCompiledCodeStream
* serialized code stream}.
*
* <ul>
* <li>0x0001: code comments ({@link HotSpotCompiledCode#comments})</li>
* <li>0x0002: methods ({@link HotSpotCompiledCode#methods})</li>
* <li>0x0004: enable {@link Option#CodeSerializationTypeInfo} if it not explicitly specified
* (i.e., {@link Option#isDefault} is {@code true})</li>
* </ul>
*/
private native int getInstallCodeFlags();
/**
* Resets all compilation statistics.
*/
native void resetCompilationStatistics();
/**
* Reads the database of VM info. The return value encodes the info in a nested object array
* that is described by the pseudo Java object {@code info} below:
*
* <pre>
* info = [
* VMField[] vmFields,
* [String name, Long size, ...] vmTypeSizes,
* [String name, Long value, ...] vmConstants,
* [String name, Long value, ...] vmAddresses,
* VMFlag[] vmFlags
* VMIntrinsicMethod[] vmIntrinsics
* ]
* </pre>
*
* @return VM info as encoded above
*/
native Object[] readConfiguration();
/**
* Resolves the implementation of {@code method} for virtual dispatches on objects of dynamic
* type {@code exactReceiver}. This resolution process only searches "up" the class hierarchy of
* {@code exactReceiver}.
*
* @param exactReceiver the exact receiver type
* @param caller the caller or context type used to perform access checks
* @return the link-time resolved method (might be abstract) or {@code null} if it is either a
* signature polymorphic method or can not be linked.
*/
HotSpotResolvedJavaMethodImpl resolveMethod(HotSpotResolvedObjectTypeImpl exactReceiver, HotSpotResolvedJavaMethodImpl method, HotSpotResolvedObjectTypeImpl caller) {
return resolveMethod(exactReceiver, exactReceiver.getKlassPointer(), method, method.getMethodPointer(), caller, caller.getKlassPointer());
}
private native HotSpotResolvedJavaMethodImpl resolveMethod(HotSpotResolvedObjectTypeImpl exactReceiver, long exactReceiverKlass,
HotSpotResolvedJavaMethodImpl method, long methodPointer,
HotSpotResolvedObjectTypeImpl caller, long callerKlass);
/**
* Gets the static initializer of {@code type}.
*
* @return {@code null} if {@code type} has no static initializer
*/
HotSpotResolvedJavaMethodImpl getClassInitializer(HotSpotResolvedObjectTypeImpl type) {
return getClassInitializer(type, type.getKlassPointer());
}
private native HotSpotResolvedJavaMethodImpl getClassInitializer(HotSpotResolvedObjectTypeImpl type, long klassPointer);
/**
* Determines if {@code type} or any of its currently loaded subclasses overrides
* {@code Object.finalize()}.
*/
boolean hasFinalizableSubclass(HotSpotResolvedObjectTypeImpl type) {
return hasFinalizableSubclass(type, type.getKlassPointer());
}
private native boolean hasFinalizableSubclass(HotSpotResolvedObjectTypeImpl type, long klassPointer);
/**
* Gets the method corresponding to {@code executable}.
*/
native HotSpotResolvedJavaMethodImpl asResolvedJavaMethod(Executable executable);
/**
* Gets the maximum absolute offset of a PC relative call to {@code address} from any position
* in the code cache.
*
* @param address an address that may be called from any code in the code cache
* @return -1 if {@code address == 0}
*/
native long getMaxCallTargetOffset(long address);
/**
* Gets a textual disassembly of {@code codeBlob}.
*
* @return a non-zero length string containing a disassembly of {@code codeBlob} or null if
* {@code codeBlob} could not be disassembled for some reason
*/
// The HotSpot disassembler seems not to be thread safe so it's better to synchronize its usage
synchronized native String disassembleCodeBlob(InstalledCode installedCode);
/**
* Gets a stack trace element for {@code method} at bytecode index {@code bci}.
*/
StackTraceElement getStackTraceElement(HotSpotResolvedJavaMethodImpl method, int bci) {
return getStackTraceElement(method, method.getMethodPointer(), bci);
}
private native StackTraceElement getStackTraceElement(HotSpotResolvedJavaMethodImpl method, long methodPointer, int bci);
/**
* Executes some {@code installedCode} with arguments {@code args}.
*
* @return the result of executing {@code nmethodMirror}
* @throws InvalidInstalledCodeException if {@code nmethodMirror} has been invalidated
*/
native Object executeHotSpotNmethod(Object[] args, HotSpotNmethod nmethodMirror) throws InvalidInstalledCodeException;
/**
* Gets the line number table for {@code method}. The line number table is encoded as (bci,
* source line number) pairs.
*
* @return the line number table for {@code method} or null if it doesn't have one
*/
long[] getLineNumberTable(HotSpotResolvedJavaMethodImpl method) {
return getLineNumberTable(method, method.getMethodPointer());
}
private native long[] getLineNumberTable(HotSpotResolvedJavaMethodImpl method, long methodPointer);
/**
* Gets the number of entries in the local variable table for {@code method}.
*
* @return the number of entries in the local variable table for {@code method}
*/
int getLocalVariableTableLength(HotSpotResolvedJavaMethodImpl method) {
return getLocalVariableTableLength(method, method.getMethodPointer());
}
private native int getLocalVariableTableLength(HotSpotResolvedJavaMethodImpl method, long methodPointer);
/**
* Gets the address of the first entry in the local variable table for {@code method}.
*
* Each entry is a native object described by these fields:
*
* <ul>
* <li>{@link HotSpotVMConfig#localVariableTableElementSize}</li>
* <li>{@link HotSpotVMConfig#localVariableTableElementLengthOffset}</li>
* <li>{@link HotSpotVMConfig#localVariableTableElementNameCpIndexOffset}</li>
* <li>{@link HotSpotVMConfig#localVariableTableElementDescriptorCpIndexOffset}</li>
* <li>{@link HotSpotVMConfig#localVariableTableElementSlotOffset}
* <li>{@link HotSpotVMConfig#localVariableTableElementStartBciOffset}
* </ul>
*
* @return 0 if {@code method} does not have a local variable table
*/
long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method) {
return getLocalVariableTableStart(method, method.getMetaspacePointer());
}
private native long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method, long methodPointer);
/**
* Sets flags on {@code method} indicating that it should never be inlined or compiled by the
* VM.
*/
void setNotInlinableOrCompilable(HotSpotResolvedJavaMethodImpl method) {
setNotInlinableOrCompilable(method, method.getMethodPointer());
}
private native void setNotInlinableOrCompilable(HotSpotResolvedJavaMethodImpl method, long methodPointer);
/**
* Invalidates the profiling information for {@code method} and (re)initializes it such that
* profiling restarts upon its next invocation.
*/
void reprofile(HotSpotResolvedJavaMethodImpl method) {
reprofile(method, method.getMethodPointer());
}
private native void reprofile(HotSpotResolvedJavaMethodImpl method, long methodPointer);
/**
* Updates {@code nmethodMirror} such that {@link InvalidInstalledCodeException} will be raised
* the next time {@code nmethodMirror} is {@linkplain #executeHotSpotNmethod executed}. The
* {@code nmethod} associated with {@code nmethodMirror} is also made non-entrant and if
* {@code deoptimize == true} any current activations of the {@code nmethod} are deoptimized.
*/
native void invalidateHotSpotNmethod(HotSpotNmethod nmethodMirror, boolean deoptimize);
/**
* Collects the current values of all JVMCI benchmark counters, summed up over all threads.
*/
native long[] collectCounters();
/**
* Get the current number of counters allocated for use by JVMCI. Should be the same value as
* the flag {@code JVMCICounterSize}.
*/
native int getCountersSize();
/**
* Attempt to change the size of the counters allocated for JVMCI. This requires a safepoint to
* safely reallocate the storage but it's advisable to increase the size in reasonable chunks.
*/
native boolean setCountersSize(int newSize);
/**
* Determines if {@code methodData} is mature.
*
* @param methodData a {@code MethodData*} value
*/
native boolean isMature(long methodData);
/**
* Generate a unique id to identify the result of the compile.
*/
int allocateCompileId(HotSpotResolvedJavaMethodImpl method, int entryBCI) {
return allocateCompileId(method, method.getMethodPointer(), entryBCI);
}
private native int allocateCompileId(HotSpotResolvedJavaMethodImpl method, long methodPointer, int entryBCI);
/**
* Determines if {@code method} has OSR compiled code identified by {@code entryBCI} for
* compilation level {@code level}.
*/
boolean hasCompiledCodeForOSR(HotSpotResolvedJavaMethodImpl method, int entryBCI, int level) {
return hasCompiledCodeForOSR(method, method.getMethodPointer(), entryBCI, level);
}
private native boolean hasCompiledCodeForOSR(HotSpotResolvedJavaMethodImpl method, long methodPoiner, int entryBCI, int level);
/**
* Gets the value of {@code symbol} as a String.
*
* @param symbol a {@code Symbol*} value
*/
native String getSymbol(long symbol);
/**
* Gets the name for a {@code klass} as it would appear in a signature.
*
* @param klass a {@code Klass*} value
*/
native String getSignatureName(long klass);
/**
* @see jdk.vm.ci.code.stack.StackIntrospection#iterateFrames
*/
native <T> T iterateFrames(ResolvedJavaMethod[] initialMethods, ResolvedJavaMethod[] matchingMethods, int initialSkip, InspectedFrameVisitor<T> visitor);
/**
* Materializes all virtual objects within {@code stackFrame} and updates its locals.
*
* @param invalidate if {@code true}, the compiled method for the stack frame will be
* invalidated
*/
native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);
/**
* Gets the v-table index for interface method {@code method} in the receiver {@code type} or
* {@link HotSpotVMConfig#invalidVtableIndex} if {@code method} is not in {@code type}'s
* v-table.
*
* @throws InternalError if {@code type} is an interface, {@code method} is not defined by an
* interface, {@code type} does not implement the interface defining {@code method}
* or class represented by {@code type} is not initialized
*/
int getVtableIndexForInterfaceMethod(HotSpotResolvedObjectTypeImpl type, HotSpotResolvedJavaMethodImpl method) {
return getVtableIndexForInterfaceMethod(type, type.getKlassPointer(), method, method.getMethodPointer());
}
private native int getVtableIndexForInterfaceMethod(HotSpotResolvedObjectTypeImpl type, long klassPointer, HotSpotResolvedJavaMethodImpl method, long methodPointer);
/**
* Determines if debug info should also be emitted at non-safepoint locations.
*/
native boolean shouldDebugNonSafepoints();
/**
* Writes {@code length} bytes from {@code buffer} to HotSpot's log stream.
*
* @param buffer if {@code length <= 8}, then the bytes are encoded in this value in native
* endianness order otherwise this is the address of a native memory buffer holding
* the bytes
* @param flush specifies if the log stream should be flushed after writing
*/
native void writeDebugOutput(long buffer, int length, boolean flush);
/**
* Flush HotSpot's log stream.
*/
native void flushDebugOutput();
/**
* Read a HotSpot {@code Method*} value from the memory location described by {@code base} plus
* {@code displacement} and return the {@link HotSpotResolvedJavaMethodImpl} wrapping it. This
* method does no checking that the memory location actually contains a valid pointer and may
* crash the VM if an invalid location is provided. If {@code base == null} is null then
* {@code displacement} is used by itself. If {@code base} is a
* {@link HotSpotResolvedJavaMethodImpl}, {@link HotSpotConstantPool} or
* {@link HotSpotResolvedObjectTypeImpl} then the metaspace pointer is fetched from that object
* and added to {@code displacement}. Any other non-null object type causes an
* {@link IllegalArgumentException} to be thrown.
*
* @param base an object to read from or null
* @param displacement
* @return null or the resolved method for this location
*/
native HotSpotResolvedJavaMethodImpl getResolvedJavaMethod(HotSpotObjectConstantImpl base, long displacement);
/**
* Gets the {@code ConstantPool*} associated with {@code object} and returns a
* {@link HotSpotConstantPool} wrapping it.
*
* @param object a {@link HotSpotResolvedJavaMethodImpl} or
* {@link HotSpotResolvedObjectTypeImpl} object
* @return a {@link HotSpotConstantPool} wrapping the {@code ConstantPool*} associated with
* {@code object}
* @throws NullPointerException if {@code object == null}
* @throws IllegalArgumentException if {@code object} is neither a
* {@link HotSpotResolvedJavaMethodImpl} nor a {@link HotSpotResolvedObjectTypeImpl}
*/
HotSpotConstantPool getConstantPool(MetaspaceObject object) {
return getConstantPool(object, object.getMetaspacePointer(), object instanceof HotSpotResolvedJavaType);
}
native HotSpotConstantPool getConstantPool(Object object, long klassOrMethod, boolean isKlass);
/**
* Read a {@code Klass*} value from the memory location described by {@code base} plus
* {@code displacement} and return the {@link HotSpotResolvedObjectTypeImpl} wrapping it. This method
* only performs the read if the memory location is known to contain a valid Klass*. If
* {@code base} is a {@link HotSpotConstantPool}, {@link HotSpotMethodData}, {@link HotSpotObjectConstantImpl},
* or {@link HotSpotResolvedObjectTypeImpl} then the field
* corresopnding to {@code displacement} is fetched using the appropriate HotSpot accessor. Any
* other object type or an unexpected displacement causes an {@link IllegalArgumentException} to
* be thrown. The set of fields which can be read in this fashion corresponds to the {@link VMField}
* with type {@code Klass*} that are described in the {@link HotSpotVMConfigStore#getFields()}.
* Additionally several injected fields in {@link Class} are also handled.
*
* @param base an object to read from
* @param displacement
* @param compressed true if the location contains a compressed Klass*
* @return null or the resolved method for this location
* @throws NullPointerException if {@code base == null}
*/
private native HotSpotResolvedObjectTypeImpl getResolvedJavaType0(Object base, long displacement, boolean compressed);
HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotConstantPool base, long displacement) {
return getResolvedJavaType0(base, displacement, false);
}
HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotMethodData base, long displacement) {
return getResolvedJavaType0(base, displacement, false);
}
HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotResolvedObjectTypeImpl base, long displacement, boolean compressed) {
return getResolvedJavaType0(base, displacement, compressed);
}
HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotObjectConstantImpl base, long displacement, boolean compressed) {
return getResolvedJavaType0(base, displacement, compressed);
}
/**
* Reads a {@code Klass*} from {@code address} (i.e., {@code address} is a {@code Klass**}
* value) and wraps it in a {@link HotSpotResolvedObjectTypeImpl}. This VM call must be used for
* any {@code Klass*} value not known to be already wrapped in a
* {@link HotSpotResolvedObjectTypeImpl}. The VM call is necessary so that the {@code Klass*} is
* wrapped in a {@code JVMCIKlassHandle} to protect it from the concurrent scanning done by G1.
*/
HotSpotResolvedObjectTypeImpl getResolvedJavaType(long address) {
return getResolvedJavaType0(null, address, false);
}
/**
* Return the size of the HotSpot ProfileData* pointed at by {@code position}. If
* {@code position} is outside the space of the MethodData then an
* {@link IllegalArgumentException} is thrown. A {@code position} inside the MethodData but that
* isn't pointing at a valid ProfileData will crash the VM.
*
* @param metaspaceMethodData
* @param position
* @return the size of the ProfileData item pointed at by {@code position}
* @throws IllegalArgumentException if an out of range position is given
*/