IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
Unsafe.cs
Go to the documentation of this file.
1using System;
2using System.Linq;
3using System.Linq.Expressions;
4using System.Reflection;
5using System.Reflection.Emit;
7using System.Runtime.InteropServices;
8using System.Runtime.Serialization;
9using System.Threading;
10
11using IKVM.ByteCode;
12using IKVM.Runtime;
13
15{
16
17 static class Unsafe
18 {
19
24 class ArrayDelegateRef
25 {
26
27 readonly Lazy<Delegate> volatileGetter;
28 readonly Lazy<Delegate> volatilePutter;
29 readonly Lazy<Delegate> compareExchange;
30
35 public ArrayDelegateRef(RuntimeJavaType type)
36 {
37 volatileGetter = new Lazy<Delegate>(() => CreateGetArrayVolatileDelegate(type), true);
38 volatilePutter = new Lazy<Delegate>(() => CreatePutArrayVolatileDelegate(type), true);
39 compareExchange = new Lazy<Delegate>(() => CreateCompareExchangeArrayDelegate(type), true);
40 }
41
45 public Delegate VolatileGetter => volatileGetter.Value;
46
50 public Delegate VolatilePutter => volatilePutter.Value;
51
55 public Delegate CompareExchange => compareExchange.Value;
56
57 }
58
62 static readonly ConditionalWeakTable<RuntimeJavaType, ArrayDelegateRef> arrayRefCache = new ConditionalWeakTable<RuntimeJavaType, ArrayDelegateRef>();
63
67 static readonly MethodInfo compareAndSwapArrayMethodInfo = typeof(Unsafe).GetMethods(BindingFlags.NonPublic | BindingFlags.Static)
68 .Where(i => i.Name == nameof(CompareAndSwapArray) && i.IsGenericMethodDefinition && i.GetGenericArguments().Length == 1)
69 .FirstOrDefault();
70
77 static void EmitLdind(ILGenerator il, Type t)
78 {
79 if (t == typeof(bool))
80 il.Emit(OpCodes.Ldind_U1);
81 else if (t == typeof(byte))
82 il.Emit(OpCodes.Ldind_U1);
83 else if (t == typeof(char))
84 il.Emit(OpCodes.Ldind_U2);
85 else if (t == typeof(short))
86 il.Emit(OpCodes.Ldind_I2);
87 else if (t == typeof(int))
88 il.Emit(OpCodes.Ldind_I4);
89 else if (t == typeof(long))
90 il.Emit(OpCodes.Ldind_I8);
91 else if (t == typeof(float))
92 il.Emit(OpCodes.Ldind_R4);
93 else if (t == typeof(double))
94 il.Emit(OpCodes.Ldind_R8);
95 else
96 il.Emit(OpCodes.Ldind_Ref);
97 }
98
105 static void EmitStind(ILGenerator il, Type t)
106 {
107 if (t == typeof(bool))
108 il.Emit(OpCodes.Stind_I1);
109 else if (t == typeof(byte))
110 il.Emit(OpCodes.Stind_I1);
111 else if (t == typeof(char))
112 il.Emit(OpCodes.Stind_I2);
113 else if (t == typeof(short))
114 il.Emit(OpCodes.Stind_I2);
115 else if (t == typeof(int))
116 il.Emit(OpCodes.Stind_I4);
117 else if (t == typeof(long))
118 il.Emit(OpCodes.Stind_I8);
119 else if (t == typeof(float))
120 il.Emit(OpCodes.Stind_R4);
121 else if (t == typeof(double))
122 il.Emit(OpCodes.Stind_R8);
123 else
124 il.Emit(OpCodes.Stind_Ref);
125 }
126
130 public static void registerNatives()
131 {
132
133 }
134
143 static T GetField<T>(object o, long offset)
144 {
145#if FIRST_PASS
146 throw new NotImplementedException();
147#else
148 var f = RuntimeJavaField.FromCookie((IntPtr)offset);
149 if (o is RuntimeJavaType w)
150 {
151 if (w != f.DeclaringType)
152 throw new global::java.lang.IllegalArgumentException();
153
154 return f.UnsafeGetValue<T>(null);
155 }
156
157 return f.UnsafeGetValue<T>(o);
158#endif
159 }
160
169 static void PutField<T>(object o, long offset, T value)
170 {
171#if FIRST_PASS
172 throw new NotImplementedException();
173#else
174 var f = RuntimeJavaField.FromCookie((IntPtr)offset);
175 if (o is RuntimeJavaType w)
176 {
177 if (w != f.DeclaringType)
178 throw new global::java.lang.IllegalArgumentException();
179
180 f.UnsafeSetValue<T>(null, value);
181 }
182
183 f.UnsafeSetValue<T>(o, value);
184#endif
185 }
186
194 public static object getObject(object self, object o, long offset)
195 {
196#if FIRST_PASS
197 throw new NotImplementedException();
198#else
199 try
200 {
201 return o switch
202 {
203 RuntimeJavaType w => GetField<object>(null, offset),
204 object[] array => array[offset / IntPtr.Size],
205 object obj => GetField<object>(obj, offset),
206 _ => throw new global::java.lang.IllegalArgumentException(),
207 };
208 }
209 catch (Exception e) when (e is not global::java.lang.Throwable)
210 {
211 throw new global::java.lang.InternalError(e);
212 }
213#endif
214 }
215
223 public static void putObject(object self, object o, long offset, object x)
224 {
225#if FIRST_PASS
226 throw new NotImplementedException();
227#else
228 try
229 {
230 switch (o)
231 {
232 case RuntimeJavaType w:
233 PutField(w, offset, x);
234 break;
235 case object[] array:
236 array[offset / IntPtr.Size] = x;
237 break;
238 case object obj:
239 PutField(obj, offset, x);
240 break;
241 default:
242 throw new global::java.lang.IllegalArgumentException();
243 }
244 }
245 catch (Exception e) when (e is not global::java.lang.Throwable)
246 {
247 throw new global::java.lang.InternalError(e);
248 }
249#endif
250 }
251
259 public static bool getBoolean(object self, object o, long offset)
260 {
261#if FIRST_PASS
262 throw new NotImplementedException();
263#else
264 try
265 {
266 return o switch
267 {
268 null => Marshal.ReadByte((IntPtr)offset) != 0,
269 RuntimeJavaType w => GetField<bool>(null, offset),
270 Array array => Buffer.GetByte(array, (int)offset) != 0,
271 _ => GetField<bool>(o, offset)
272 };
273 }
274 catch (Exception e) when (e is not global::java.lang.Throwable)
275 {
276 throw new global::java.lang.InternalError(e);
277 }
278#endif
279 }
280
288 public static void putBoolean(object self, object o, long offset, bool x)
289 {
290#if FIRST_PASS
291 throw new NotImplementedException();
292#else
293 try
294 {
295 switch (o)
296 {
297 case null:
298 Marshal.WriteByte((IntPtr)offset, x ? (byte)1 : (byte)0);
299 break;
300 case RuntimeJavaType w:
301 PutField(w, offset, x);
302 break;
303 case Array array:
304 Buffer.SetByte(array, (int)offset, x ? (byte)1 : (byte)0);
305 break;
306 default:
307 PutField(o, offset, x);
308 break;
309 }
310 }
311 catch (Exception e) when (e is not global::java.lang.Throwable)
312 {
313 throw new global::java.lang.InternalError(e);
314 }
315#endif
316 }
317
325 public static byte getByte(object self, object o, long offset)
326 {
327#if FIRST_PASS
328 throw new NotImplementedException();
329#else
330 try
331 {
332 return o switch
333 {
334 null => Marshal.ReadByte((IntPtr)offset),
335 RuntimeJavaType w => GetField<byte>(null, offset),
336 Array array => Buffer.GetByte(array, (int)offset),
337 _ => GetField<byte>(o, offset)
338 };
339 }
340 catch (Exception e) when (e is not global::java.lang.Throwable)
341 {
342 throw new global::java.lang.InternalError(e);
343 }
344#endif
345 }
346
354 public static void putByte(object self, object o, long offset, byte x)
355 {
356#if FIRST_PASS
357 throw new NotImplementedException();
358#else
359 try
360 {
361 switch (o)
362 {
363 case null:
364 Marshal.WriteByte((IntPtr)offset, x);
365 break;
366 case RuntimeJavaType w:
367 PutField(w, offset, x);
368 break;
369 case Array array:
370 Buffer.SetByte(array, (int)offset, x);
371 break;
372 default:
373 PutField(o, offset, x);
374 break;
375 }
376 }
377 catch (Exception e) when (e is not global::java.lang.Throwable)
378 {
379 throw new global::java.lang.InternalError(e);
380 }
381#endif
382 }
383
391 public static short getShort(object self, object o, long offset)
392 {
393#if FIRST_PASS
394 throw new NotImplementedException();
395#else
396 try
397 {
398 return o switch
399 {
400 null => Marshal.ReadInt16((IntPtr)offset),
401 RuntimeJavaType w => GetField<short>(null, offset),
402 Array array => ReadInt16(array, offset),
403 _ => GetField<short>(o, offset)
404 };
405 }
406 catch (Exception e) when (e is not global::java.lang.Throwable)
407 {
408 throw new global::java.lang.InternalError(e);
409 }
410#endif
411 }
412
420 public static void putShort(object self, object o, long offset, short x)
421 {
422#if FIRST_PASS
423 throw new NotImplementedException();
424#else
425 try
426 {
427 switch (o)
428 {
429 case null:
430 Marshal.WriteInt16((IntPtr)offset, x);
431 break;
432 case RuntimeJavaType w:
433 PutField(w, offset, x);
434 break;
435 case Array array:
436 WriteInt16(array, offset, x);
437 break;
438 default:
439 PutField(o, offset, x);
440 break;
441 }
442 }
443 catch (Exception e) when (e is not global::java.lang.Throwable)
444 {
445 throw new global::java.lang.InternalError(e);
446 }
447#endif
448 }
449
457 public static char getChar(object self, object o, long offset)
458 {
459#if FIRST_PASS
460 throw new NotImplementedException();
461#else
462 try
463 {
464 return o switch
465 {
466 null => (char)Marshal.ReadInt16((IntPtr)offset),
467 RuntimeJavaType w => GetField<char>(null, offset),
468 Array array => (char)ReadInt16(array, offset),
469 _ => GetField<char>(o, offset)
470 };
471 }
472 catch (Exception e) when (e is not global::java.lang.Throwable)
473 {
474 throw new global::java.lang.InternalError(e);
475 }
476#endif
477 }
478
486 public static void putChar(object self, object o, long offset, char x)
487 {
488#if FIRST_PASS
489 throw new NotImplementedException();
490#else
491 try
492 {
493 switch (o)
494 {
495 case null:
496 Marshal.WriteInt16((IntPtr)offset, (short)x);
497 break;
498 case RuntimeJavaType w:
499 PutField(w, offset, x);
500 break;
501 case Array array:
502 WriteInt16(array, offset, (short)x);
503 break;
504 default:
505 PutField(o, offset, x);
506 break;
507 }
508 }
509 catch (Exception e) when (e is not global::java.lang.Throwable)
510 {
511 throw new global::java.lang.InternalError(e);
512 }
513#endif
514 }
515
523 public static int getInt(object self, object o, long offset)
524 {
525#if FIRST_PASS
526 throw new NotImplementedException();
527#else
528 try
529 {
530 return o switch
531 {
532 null => Marshal.ReadInt32((IntPtr)offset),
533 RuntimeJavaType w => GetField<int>(null, offset),
534 Array array => ReadInt32(array, offset),
535 _ => GetField<int>(o, offset)
536 };
537 }
538 catch (Exception e) when (e is not global::java.lang.Throwable)
539 {
540 throw new global::java.lang.InternalError(e);
541 }
542#endif
543 }
544
552 public static void putInt(object self, object o, long offset, int x)
553 {
554#if FIRST_PASS
555 throw new NotImplementedException();
556#else
557 try
558 {
559 switch (o)
560 {
561 case null:
562 Marshal.WriteInt32((IntPtr)offset, x);
563 break;
564 case RuntimeJavaType w:
565 PutField(w, offset, x);
566 break;
567 case Array array:
568 WriteInt32(array, offset, x);
569 break;
570 default:
571 PutField(o, offset, x);
572 break;
573 }
574 }
575 catch (Exception e) when (e is not global::java.lang.Throwable)
576 {
577 throw new global::java.lang.InternalError(e);
578 }
579#endif
580 }
581
589 public static long getLong(object self, object o, long offset)
590 {
591#if FIRST_PASS
592 throw new NotImplementedException();
593#else
594 try
595 {
596 return o switch
597 {
598 null => Marshal.ReadInt64((IntPtr)offset),
599 RuntimeJavaType w => GetField<long>(null, offset),
600 Array array => ReadInt64(array, offset),
601 _ => GetField<long>(o, offset)
602 };
603 }
604 catch (Exception e) when (e is not global::java.lang.Throwable)
605 {
606 throw new global::java.lang.InternalError(e);
607 }
608#endif
609 }
610
618 public static void putLong(object self, object o, long offset, long x)
619 {
620#if FIRST_PASS
621 throw new NotImplementedException();
622#else
623 try
624 {
625 switch (o)
626 {
627 case null:
628 Marshal.WriteInt64((IntPtr)offset, x);
629 break;
630 case RuntimeJavaType w:
631 PutField(w, offset, x);
632 break;
633 case Array array:
634 WriteInt64(array, offset, x);
635 break;
636 default:
637 PutField(o, offset, x);
638 break;
639 }
640 }
641 catch (Exception e) when (e is not global::java.lang.Throwable)
642 {
643 throw new global::java.lang.InternalError(e);
644 }
645#endif
646 }
647
655 public static float getFloat(object self, object o, long offset)
656 {
657#if FIRST_PASS
658 throw new NotImplementedException();
659#else
660 try
661 {
662 return o switch
663 {
664 null => global::java.lang.Float.intBitsToFloat(Marshal.ReadInt32((IntPtr)offset)),
665 RuntimeJavaType w => GetField<float>(null, offset),
666 Array array => global::java.lang.Float.intBitsToFloat(ReadInt32(array, offset)),
667 _ => GetField<float>(o, offset)
668 };
669 }
670 catch (Exception e) when (e is not global::java.lang.Throwable)
671 {
672 throw new global::java.lang.InternalError(e);
673 }
674#endif
675 }
676
684 public static void putFloat(object self, object o, long offset, float x)
685 {
686#if FIRST_PASS
687 throw new NotImplementedException();
688#else
689 try
690 {
691 switch (o)
692 {
693 case null:
694 Marshal.WriteInt32((IntPtr)offset, global::java.lang.Float.floatToRawIntBits(x));
695 break;
696 case RuntimeJavaType w:
697 PutField(w, offset, x);
698 break;
699 case Array array:
700 WriteInt32(array, offset, global::java.lang.Float.floatToRawIntBits(x));
701 break;
702 default:
703 PutField(o, offset, x);
704 break;
705 }
706 }
707 catch (Exception e) when (e is not global::java.lang.Throwable)
708 {
709 throw new global::java.lang.InternalError(e);
710 }
711#endif
712 }
713
721 public static double getDouble(object self, object o, long offset)
722 {
723#if FIRST_PASS
724 throw new NotImplementedException();
725#else
726 try
727 {
728 return o switch
729 {
730 null => global::java.lang.Double.longBitsToDouble(Marshal.ReadInt64((IntPtr)offset)),
731 RuntimeJavaType w => GetField<double>(null, offset),
732 Array array => global::java.lang.Double.longBitsToDouble(ReadInt64(array, offset)),
733 _ => GetField<double>(o, offset)
734 };
735 }
736 catch (Exception e) when (e is not global::java.lang.Throwable)
737 {
738 throw new global::java.lang.InternalError(e);
739 }
740#endif
741 }
742
750 public static void putDouble(object self, object o, long offset, double x)
751 {
752#if FIRST_PASS
753 throw new NotImplementedException();
754#else
755 try
756 {
757 switch (o)
758 {
759 case null:
760 Marshal.WriteInt64((IntPtr)offset, global::java.lang.Double.doubleToRawLongBits(x));
761 break;
762 case RuntimeJavaType w:
763 PutField(w, offset, x);
764 break;
765 case Array array:
766 WriteInt64(array, offset, global::java.lang.Double.doubleToRawLongBits(x));
767 break;
768 default:
769 PutField(o, offset, x);
770 break;
771 }
772 }
773 catch (Exception e) when (e is not global::java.lang.Throwable)
774 {
775 throw new global::java.lang.InternalError(e);
776 }
777#endif
778 }
779
786 public static byte getByte(object self, long address)
787 {
788#if FIRST_PASS
789 throw new NotImplementedException();
790#else
791 try
792 {
793 return Marshal.ReadByte((IntPtr)address);
794 }
795 catch (Exception e) when (e is not global::java.lang.Throwable)
796 {
797 throw new global::java.lang.InternalError(e);
798 }
799#endif
800 }
801
808 public static void putByte(object self, long address, byte x)
809 {
810#if FIRST_PASS
811 throw new NotImplementedException();
812#else
813 try
814 {
815 Marshal.WriteByte((IntPtr)address, x);
816 }
817 catch (Exception e) when (e is not global::java.lang.Throwable)
818 {
819 throw new global::java.lang.InternalError(e);
820 }
821#endif
822 }
823
830 public static short getShort(object self, long address)
831 {
832#if FIRST_PASS
833 throw new NotImplementedException();
834#else
835 try
836 {
837 return Marshal.ReadInt16((IntPtr)address);
838 }
839 catch (Exception e) when (e is not global::java.lang.Throwable)
840 {
841 throw new global::java.lang.InternalError(e);
842 }
843#endif
844 }
845
852 public static void putShort(object self, long address, short x)
853 {
854#if FIRST_PASS
855 throw new NotImplementedException();
856#else
857 try
858 {
859 Marshal.WriteInt16((IntPtr)address, x);
860 }
861 catch (Exception e) when (e is not global::java.lang.Throwable)
862 {
863 throw new global::java.lang.InternalError(e);
864 }
865#endif
866 }
867
874 public static char getChar(object self, long address)
875 {
876#if FIRST_PASS
877 throw new NotImplementedException();
878#else
879 try
880 {
881 return (char)Marshal.ReadInt16((IntPtr)address);
882 }
883 catch (Exception e) when (e is not global::java.lang.Throwable)
884 {
885 throw new global::java.lang.InternalError(e);
886 }
887#endif
888 }
889
896 public static void putChar(object self, long address, char x)
897 {
898#if FIRST_PASS
899 throw new NotImplementedException();
900#else
901 try
902 {
903 Marshal.WriteInt16((IntPtr)address, (short)x);
904 }
905 catch (Exception e) when (e is not global::java.lang.Throwable)
906 {
907 throw new global::java.lang.InternalError(e);
908 }
909#endif
910 }
911
918 public static int getInt(object self, long address)
919 {
920#if FIRST_PASS
921 throw new NotImplementedException();
922#else
923 try
924 {
925 return Marshal.ReadInt32((IntPtr)address);
926 }
927 catch (Exception e) when (e is not global::java.lang.Throwable)
928 {
929 throw new global::java.lang.InternalError(e);
930 }
931#endif
932 }
933
940 public static void putInt(object self, long address, int x)
941 {
942#if FIRST_PASS
943 throw new NotImplementedException();
944#else
945 try
946 {
947 Marshal.WriteInt32((IntPtr)address, x);
948 }
949 catch (Exception e) when (e is not global::java.lang.Throwable)
950 {
951 throw new global::java.lang.InternalError(e);
952 }
953#endif
954 }
955
962 public static long getLong(object self, long address)
963 {
964#if FIRST_PASS
965 throw new NotImplementedException();
966#else
967 try
968 {
969 return Marshal.ReadInt64((IntPtr)address);
970 }
971 catch (Exception e) when (e is not global::java.lang.Throwable)
972 {
973 throw new global::java.lang.InternalError(e);
974 }
975#endif
976 }
977
984 public static void putLong(object self, long address, long x)
985 {
986#if FIRST_PASS
987 throw new NotImplementedException();
988#else
989 try
990 {
991 Marshal.WriteInt64((IntPtr)address, x);
992 }
993 catch (Exception e) when (e is not global::java.lang.Throwable)
994 {
995 throw new global::java.lang.InternalError(e);
996 }
997#endif
998 }
999
1006 public static float getFloat(object self, long address)
1007 {
1008#if FIRST_PASS
1009 throw new NotImplementedException();
1010#else
1011 try
1012 {
1013 return global::java.lang.Float.intBitsToFloat(getInt(self, address));
1014 }
1015 catch (Exception e) when (e is not global::java.lang.Throwable)
1016 {
1017 throw new global::java.lang.InternalError(e);
1018 }
1019#endif
1020 }
1021
1028 public static void putFloat(object self, long address, float x)
1029 {
1030#if FIRST_PASS
1031 throw new NotImplementedException();
1032#else
1033 putInt(self, address, global::java.lang.Float.floatToIntBits(x));
1034#endif
1035 }
1036
1043 public static double getDouble(object self, long address)
1044 {
1045#if FIRST_PASS
1046 throw new NotImplementedException();
1047#else
1048 try
1049 {
1050 return global::java.lang.Double.longBitsToDouble(getLong(self, address));
1051 }
1052 catch (Exception e) when (e is not global::java.lang.Throwable)
1053 {
1054 throw new global::java.lang.InternalError(e);
1055 }
1056#endif
1057 }
1058
1065 public static void putDouble(object self, long address, double x)
1066 {
1067#if FIRST_PASS
1068 throw new NotImplementedException();
1069#else
1070 putLong(self, address, global::java.lang.Double.doubleToLongBits(x));
1071#endif
1072 }
1073
1080 public static long getAddress(object self, long address)
1081 {
1082#if FIRST_PASS
1083 throw new NotImplementedException();
1084#else
1085 try
1086 {
1087 return Marshal.ReadIntPtr((IntPtr)address).ToInt64();
1088 }
1089 catch (Exception e) when (e is not global::java.lang.Throwable)
1090 {
1091 throw new global::java.lang.InternalError(e);
1092 }
1093#endif
1094 }
1095
1102 public static void putAddress(object self, long address, long x)
1103 {
1104#if FIRST_PASS
1105 throw new NotImplementedException();
1106#else
1107 try
1108 {
1109 Marshal.WriteIntPtr((IntPtr)address, (IntPtr)x);
1110 }
1111 catch (Exception e) when (e is not global::java.lang.Throwable)
1112 {
1113 throw new global::java.lang.InternalError(e);
1114 }
1115#endif
1116 }
1117
1125 public static unsafe long allocateMemory(object self, long bytes)
1126 {
1127#if FIRST_PASS
1128 throw new NotImplementedException();
1129#else
1130 try
1131 {
1132 if (bytes == 0)
1133 return 0;
1134
1135 var len = (IntPtr)bytes + sizeof(IntPtr);
1136 var ptr = Marshal.AllocHGlobal(len);
1137 Marshal.WriteIntPtr(ptr, len);
1138 System.GC.AddMemoryPressure((long)len);
1139 return (long)ptr + sizeof(IntPtr);
1140 }
1141 catch (OutOfMemoryException e)
1142 {
1143 throw new global::java.lang.OutOfMemoryError(e.Message).initCause(e);
1144 }
1145 catch (Exception e) when (e is not global::java.lang.Throwable)
1146 {
1147 throw new global::java.lang.InternalError(e);
1148 }
1149#endif
1150 }
1151
1160 public static unsafe long reallocateMemory(object self, long address, long bytes)
1161 {
1162#if FIRST_PASS
1163 throw new NotImplementedException();
1164#else
1165 try
1166 {
1167 if (bytes == 0)
1168 {
1169 freeMemory(self, address);
1170 return 0;
1171 }
1172
1173 // remove memory pressure
1174 var ptr = (IntPtr)address - sizeof(IntPtr);
1175 var len = Marshal.ReadIntPtr(ptr);
1176 System.GC.RemoveMemoryPressure((long)len);
1177
1178 // reallocate and add memory pressure
1179 len = (IntPtr)bytes + sizeof(IntPtr);
1180 ptr = Marshal.ReAllocHGlobal(ptr, len);
1181 Marshal.WriteIntPtr(ptr, len);
1182 System.GC.AddMemoryPressure((long)len);
1183 return (long)ptr + sizeof(IntPtr);
1184 }
1185 catch (OutOfMemoryException e)
1186 {
1187 throw new global::java.lang.OutOfMemoryError(e.Message).initCause(e);
1188 }
1189 catch (Exception e) when (e is not global::java.lang.Throwable)
1190 {
1191 throw new global::java.lang.InternalError(e);
1192 }
1193#endif
1194 }
1195
1205 public static unsafe void setMemory(object self, object o, long offset, long bytes, byte value)
1206 {
1207#if FIRST_PASS
1208 throw new NotImplementedException();
1209#else
1210 try
1211 {
1212 if (o == null)
1213 new Span<byte>((void*)(IntPtr)offset, (int)bytes).Fill(value);
1214 else if (o is byte[] array)
1215 ((Span<byte>)array).Slice((int)offset, (int)bytes).Fill(value);
1216 else if (o is Array array2)
1217 {
1218 GCHandle h = new();
1219
1220 try
1221 {
1222 h = GCHandle.Alloc(array2, GCHandleType.Pinned);
1223 new Span<byte>((byte*)h.AddrOfPinnedObject(), Buffer.ByteLength(array2)).Slice((int)offset, (int)bytes).Fill(value);
1224 }
1225 finally
1226 {
1227 if (h.IsAllocated)
1228 h.Free();
1229 }
1230 }
1231 else
1232 throw new global::java.lang.IllegalArgumentException();
1233 }
1234 catch (Exception e) when (e is not global::java.lang.Throwable)
1235 {
1236 throw new global::java.lang.InternalError(e);
1237 }
1238#endif
1239 }
1240
1251 public static unsafe void copyMemory(object self, object srcBase, long srcOffset, object destBase, long destOffset, long bytes)
1252 {
1253#if FIRST_PASS
1254 throw new NotImplementedException();
1255#else
1256 try
1257 {
1258 if (srcBase == null)
1259 {
1260 if (destBase is byte[] byteArray)
1261 {
1262 Marshal.Copy((IntPtr)srcOffset, byteArray, (int)destOffset, (int)bytes);
1263 }
1264 else if (destBase is bool[])
1265 {
1266 var tmp = new byte[(int)bytes];
1267 copyMemory(self, srcBase, srcOffset, tmp, 0, bytes);
1268 copyMemory(self, tmp, 0, destBase, destOffset, bytes);
1269 }
1270 else if (destBase is short[] shortArray)
1271 {
1272 Marshal.Copy((IntPtr)srcOffset, shortArray, (int)(destOffset >> 1), (int)(bytes >> 1));
1273 }
1274 else if (destBase is char[] charArray)
1275 {
1276 Marshal.Copy((IntPtr)srcOffset, charArray, (int)(destOffset >> 1), (int)(bytes >> 1));
1277 }
1278 else if (destBase is int[] intArray)
1279 {
1280 Marshal.Copy((IntPtr)srcOffset, intArray, (int)(destOffset >> 2), (int)(bytes >> 2));
1281 }
1282 else if (destBase is float[] floatArray)
1283 {
1284 Marshal.Copy((IntPtr)srcOffset, floatArray, (int)(destOffset >> 2), (int)(bytes >> 2));
1285 }
1286 else if (destBase is long[] longArray)
1287 {
1288 Marshal.Copy((IntPtr)srcOffset, longArray, (int)(destOffset >> 3), (int)(bytes >> 3));
1289 }
1290 else if (destBase is double[] doubleArray)
1291 {
1292 Marshal.Copy((IntPtr)srcOffset, doubleArray, (int)(destOffset >> 3), (int)(bytes >> 3));
1293 }
1294 else if (destBase == null)
1295 {
1296 Buffer.MemoryCopy((void*)(IntPtr)srcOffset, (void*)(IntPtr)destOffset, long.MaxValue, bytes);
1297 }
1298 else
1299 {
1300 throw new global::java.lang.IllegalArgumentException();
1301 }
1302 }
1303 else if (srcBase is Array && destBase is Array)
1304 {
1305 Buffer.BlockCopy((Array)srcBase, (int)srcOffset, (Array)destBase, (int)destOffset, (int)bytes);
1306 }
1307 else
1308 {
1309 if (srcBase is byte[] byteArray)
1310 {
1311 Marshal.Copy(byteArray, (int)srcOffset, (IntPtr)destOffset, (int)bytes);
1312 }
1313 else if (srcBase is bool[])
1314 {
1315 var tmp = new byte[(int)bytes];
1316 copyMemory(self, srcBase, srcOffset, tmp, 0, bytes);
1317 copyMemory(self, tmp, 0, destBase, destOffset, bytes);
1318 }
1319 else if (srcBase is short[] shortArray)
1320 {
1321 Marshal.Copy(shortArray, (int)(srcOffset >> 1), (IntPtr)(destOffset), (int)(bytes >> 1));
1322 }
1323 else if (srcBase is char[] charArray)
1324 {
1325 Marshal.Copy(charArray, (int)(srcOffset >> 1), (IntPtr)(destOffset), (int)(bytes >> 1));
1326 }
1327 else if (srcBase is int[] intArray)
1328 {
1329 Marshal.Copy(intArray, (int)(srcOffset >> 2), (IntPtr)(destOffset), (int)(bytes >> 2));
1330 }
1331 else if (srcBase is float[] floatArray)
1332 {
1333 Marshal.Copy(floatArray, (int)(srcOffset >> 2), (IntPtr)(destOffset), (int)(bytes >> 2));
1334 }
1335 else if (srcBase is long[] longArray)
1336 {
1337 Marshal.Copy(longArray, (int)(srcOffset >> 3), (IntPtr)(destOffset), (int)(bytes >> 3));
1338 }
1339 else if (srcBase is double[] doubleArray)
1340 {
1341 Marshal.Copy(doubleArray, (int)(srcOffset >> 3), (IntPtr)(destOffset), (int)(bytes >> 3));
1342 }
1343 else
1344 {
1345 throw new global::java.lang.IllegalArgumentException();
1346 }
1347 }
1348 }
1349 catch (Exception e) when (e is not global::java.lang.Throwable)
1350 {
1351 throw new global::java.lang.InternalError(e);
1352 }
1353#endif
1354 }
1355
1361 public static unsafe void freeMemory(object self, long address)
1362 {
1363 var adr = (nint)address;
1364 if (adr == 0)
1365 return;
1366
1367 var ptr = adr - sizeof(nint);
1368 var len = Marshal.ReadIntPtr(ptr);
1369 Marshal.FreeHGlobal(ptr);
1370 System.GC.RemoveMemoryPressure((long)len);
1371 }
1372
1379 public static object staticFieldBase(object self, global::java.lang.reflect.Field f)
1380 {
1381 var w = RuntimeJavaField.FromField(f);
1382 if (w.IsStatic == false)
1383 throw new global::java.lang.IllegalArgumentException();
1384
1385 return w.DeclaringType;
1386 }
1387
1394 public static long staticFieldOffset(object self, global::java.lang.reflect.Field f)
1395 {
1396 var w = RuntimeJavaField.FromField(f);
1397 if (w.IsStatic == false)
1398 throw new global::java.lang.IllegalArgumentException();
1399
1400 return (long)w.Cookie;
1401 }
1402
1409 public static long objectFieldOffset(object self, global::java.lang.reflect.Field f)
1410 {
1411 var w = RuntimeJavaField.FromField(f);
1412 if (w.IsStatic)
1413 throw new global::java.lang.IllegalArgumentException();
1414
1415 return (long)w.Cookie;
1416 }
1417
1424 public static bool shouldBeInitialized(object self, global::java.lang.Class c)
1425 {
1426 return RuntimeJavaType.FromClass(c).HasStaticInitializer;
1427 }
1428
1434 public static void ensureClassInitialized(object self, global::java.lang.Class c)
1435 {
1436 var tw = RuntimeJavaType.FromClass(c);
1437 if (tw.IsArray == false)
1438 {
1439 try
1440 {
1441 tw.Finish();
1442 }
1444 {
1445 throw x.ToJava();
1446 }
1447
1448 tw.RunClassInit();
1449 }
1450 }
1451
1458 public static int arrayBaseOffset(object self, global::java.lang.Class arrayClass)
1459 {
1460 return 0;
1461 }
1462
1468 static int ArrayIndexScale(RuntimeJavaType tw)
1469 {
1470#if FIRST_PASS
1471 throw new NotImplementedException();
1472#else
1473 var context = tw.Context;
1474
1475 var et = tw.ElementTypeWrapper;
1476 if (et == context.PrimitiveJavaTypeFactory.BYTE || et == context.PrimitiveJavaTypeFactory.BOOLEAN)
1477 return 1;
1478 else if (et == context.PrimitiveJavaTypeFactory.CHAR || et == context.PrimitiveJavaTypeFactory.SHORT)
1479 return 2;
1480 else if (et == context.PrimitiveJavaTypeFactory.INT || et == context.PrimitiveJavaTypeFactory.FLOAT)
1481 return 4;
1482 else if (et == context.PrimitiveJavaTypeFactory.LONG || et == context.PrimitiveJavaTypeFactory.DOUBLE)
1483 return 8;
1484 else if (et.IsPrimitive == false && et.IsNonPrimitiveValueType)
1485 return Marshal.SizeOf(et.TypeAsTBD);
1486 else if (et.IsPrimitive == false && et.IsNonPrimitiveValueType == false)
1487 return IntPtr.Size;
1488 else
1489 return 1;
1490#endif
1491 }
1492
1499 public static int arrayIndexScale(object self, global::java.lang.Class arrayClass)
1500 {
1501 return ArrayIndexScale(RuntimeJavaType.FromClass(arrayClass));
1502 }
1503
1509 public static int addressSize(object self)
1510 {
1511 return IntPtr.Size;
1512 }
1513
1519 public static int pageSize(object self)
1520 {
1521 return Environment.SystemPageSize;
1522 }
1523
1535 public static global::java.lang.Class defineClass(object self, string name, byte[] b, int off, int len, global::java.lang.ClassLoader loader, global::java.security.ProtectionDomain protectionDomain)
1536 {
1537 return IKVM.Java.Externs.java.lang.ClassLoader.defineClass1(loader, name.Replace('/', '.'), b, off, len, protectionDomain, null);
1538 }
1539
1549 public static global::java.lang.Class defineAnonymousClass(object self, global::java.lang.Class hostClass, byte[] data, object[] cpPatches)
1550 {
1551#if FIRST_PASS
1552 throw new NotImplementedException();
1553#else
1554 try
1555 {
1556 var tw = RuntimeJavaType.FromClass(hostClass);
1557 var cl = tw.ClassLoader;
1558 var cf = new IKVM.Runtime.ClassFile(JVM.Context, JVM.Context.Diagnostics, ReadClass(data), "<Unknown>", cl.ClassFileParseOptions, cpPatches);
1559
1560 // if this happens, the OpenJDK is probably trying to load an OpenJDK class file as a resource,
1561 // make sure the build process includes the original class file as a resource in that case
1562 if (cf.IKVMAssemblyAttribute != null)
1563 throw new global::java.lang.ClassFormatError("Trying to define anonymous class based on stub class: " + cf.Name);
1564
1565 return cl.GetTypeWrapperFactory().DefineClassImpl(null, tw, cf, cl, hostClass.pd).ClassObject;
1566 }
1568 {
1569 throw e.ToJava();
1570 }
1571#endif
1572 }
1573
1574#if FIRST_PASS == false
1575
1581 static IKVM.ByteCode.Decoding.ClassFile ReadClass(byte[] buffer)
1582 {
1583 try
1584 {
1585 return IKVM.ByteCode.Decoding.ClassFile.Read(buffer);
1586 }
1587 catch (InvalidClassMagicException)
1588 {
1589 throw new global::java.lang.ClassFormatError("Incompatible magic value");
1590 }
1591 catch (ByteCodeException e)
1592 {
1593 throw new global::java.lang.ClassFormatError(e.Message);
1594 }
1595 }
1596
1597#endif
1598
1605 public static object allocateInstance(object self, global::java.lang.Class cls)
1606 {
1607 var wrapper = RuntimeJavaType.FromClass(cls);
1608 try
1609 {
1610 wrapper.Finish();
1611 }
1613 {
1614 throw x.ToJava();
1615 }
1616
1617#if NETFRAMEWORK
1618 return FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType);
1619#else
1620 return RuntimeHelpers.GetUninitializedObject(wrapper.TypeAsBaseType);
1621#endif
1622 }
1623
1629 public static void monitorEnter(object self, object o)
1630 {
1631 Monitor.Enter(o);
1632 }
1633
1639 public static void monitorExit(object self, object o)
1640 {
1641 Monitor.Exit(o);
1642 }
1643
1650 public static bool tryMonitorEnter(object self, object o)
1651 {
1652 return Monitor.TryEnter(o);
1653 }
1654
1660 public static void throwException(object self, Exception ee)
1661 {
1662 throw ee;
1663 }
1664
1673 static T GetFieldVolatile<T>(object o, long offset)
1674 {
1675#if FIRST_PASS
1676 throw new NotImplementedException();
1677#else
1678 var f = RuntimeJavaField.FromCookie((IntPtr)offset);
1679 if (o is RuntimeJavaType w)
1680 {
1681 if (w != f.DeclaringType)
1682 throw new global::java.lang.IllegalArgumentException();
1683
1684 return f.UnsafeVolatileGet<T>(null);
1685 }
1686
1687 return f.UnsafeVolatileGet<T>(o);
1688#endif
1689 }
1690
1699 static void PutFieldVolatile<T>(object o, long offset, T value)
1700 {
1701#if FIRST_PASS
1702 throw new NotImplementedException();
1703#else
1704 var f = RuntimeJavaField.FromCookie((IntPtr)offset);
1705 if (o is RuntimeJavaType w)
1706 {
1707 if (w != f.DeclaringType)
1708 throw new global::java.lang.IllegalArgumentException();
1709
1710 f.UnsafeVolatileSet<T>(null, value);
1711 }
1712
1713 f.UnsafeVolatileSet<T>(o, value);
1714#endif
1715 }
1716
1722 static Delegate CreateGetArrayVolatileDelegate(RuntimeJavaType tw)
1723 {
1724 var et = tw.IsPrimitive ? tw.TypeAsTBD : typeof(object);
1725 var dm = DynamicMethodUtil.Create($"__<UnsafeGetArrayVolatile>__{tw.Name.Replace(".", "_")}", tw.TypeAsTBD, true, et, new[] { typeof(object[]), typeof(long) });
1726 var il = dm.GetILGenerator();
1727
1728 // load reference to element
1729 il.Emit(OpCodes.Ldarg_0);
1730 il.Emit(OpCodes.Ldarg_1);
1731 il.Emit(OpCodes.Conv_Ovf_I);
1732 il.Emit(OpCodes.Ldc_I4, ArrayIndexScale(tw.MakeArrayType(1)));
1733 il.Emit(OpCodes.Div);
1734 il.Emit(OpCodes.Conv_Ovf_I);
1735 il.Emit(OpCodes.Ldelema, tw.TypeAsLocalOrStackType);
1736
1737 if (tw.IsWidePrimitive == false)
1738 {
1739 il.Emit(OpCodes.Volatile);
1740 EmitLdind(il, tw.TypeAsLocalOrStackType);
1741 }
1742 else
1743 {
1744 // Java volatile semantics require atomicity, CLR volatile semantics do not
1745 var mi = typeof(Unsafe).GetMethod(nameof(InterlockedRead), BindingFlags.NonPublic | BindingFlags.Static, null, new[] { tw.TypeAsTBD.MakeByRefType() }, null);
1746 il.Emit(OpCodes.Call, mi);
1747 }
1748
1749 il.Emit(OpCodes.Ret);
1750 return dm.CreateDelegate(typeof(Func<,,>).MakeGenericType(typeof(object[]), typeof(long), et));
1751 }
1752
1759 static object GetArrayObjectVolatile(object[] array, long offset)
1760 {
1761#if FIRST_PASS
1762 throw new NotImplementedException();
1763#else
1764 return ((Func<object[], long, object>)arrayRefCache.GetValue(JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(array.GetType().GetElementType()), _ => new ArrayDelegateRef(_)).VolatileGetter)(array, offset);
1765#endif
1766 }
1767
1773 static Delegate CreatePutArrayVolatileDelegate(RuntimeJavaType tw)
1774 {
1775 var et = tw.IsPrimitive ? tw.TypeAsTBD : typeof(object);
1776 var dm = DynamicMethodUtil.Create($"__<UnsafePutArrayVolatile>__{tw.Name.Replace(".", "_")}", tw.TypeAsTBD, true, typeof(void), new[] { typeof(object[]), typeof(long), et });
1777 var il = dm.GetILGenerator();
1778
1779 // load reference to element
1780 il.Emit(OpCodes.Ldarg_0);
1781 il.Emit(OpCodes.Ldarg_1);
1782 il.Emit(OpCodes.Conv_Ovf_I);
1783 il.Emit(OpCodes.Ldc_I4, ArrayIndexScale(tw.MakeArrayType(1)));
1784 il.Emit(OpCodes.Div);
1785 il.Emit(OpCodes.Conv_Ovf_I);
1786 il.Emit(OpCodes.Ldelema, tw.TypeAsLocalOrStackType);
1787
1788 il.Emit(OpCodes.Ldarg_2);
1789
1790 if (tw.IsWidePrimitive == false)
1791 {
1792 il.Emit(OpCodes.Volatile);
1793 EmitStind(il, tw.TypeAsLocalOrStackType);
1794 }
1795 else
1796 {
1797 // Java volatile semantics require atomicity, CLR volatile semantics do not
1798 var mi = typeof(Interlocked).GetMethod(nameof(Interlocked.Exchange), new[] { tw.TypeAsTBD.MakeByRefType() });
1799 il.Emit(OpCodes.Call, mi);
1800 }
1801
1802 il.Emit(OpCodes.Ret);
1803 return dm.CreateDelegate(typeof(Action<,,>).MakeGenericType(typeof(object[]), typeof(long), et));
1804 }
1805
1813 static void PutArrayObjectVolatile(object[] array, long offset, object value)
1814 {
1815#if FIRST_PASS
1816 throw new NotImplementedException();
1817#else
1818 ((Action<object[], long, object>)arrayRefCache.GetValue(JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(array.GetType().GetElementType()), _ => new ArrayDelegateRef(_)).VolatilePutter)(array, offset, value);
1819#endif
1820 }
1821
1829 public static object getObjectVolatile(object self, object o, long offset)
1830 {
1831#if FIRST_PASS
1832 throw new NotImplementedException();
1833#else
1834 try
1835 {
1836 return o switch
1837 {
1838 RuntimeJavaType w => GetField<object>(null, offset),
1839 object[] array when array.GetType() == typeof(object[]) => Volatile.Read(ref array[offset / IntPtr.Size]),
1840 object[] array => GetArrayObjectVolatile(array, offset),
1841 object obj => GetFieldVolatile<object>(obj, offset),
1842 _ => throw new global::java.lang.IllegalArgumentException(),
1843 };
1844 }
1845 catch (Exception e) when (e is not global::java.lang.Throwable)
1846 {
1847 throw new global::java.lang.InternalError(e);
1848 }
1849#endif
1850 }
1851
1859 public static void putObjectVolatile(object self, object o, long offset, object x)
1860 {
1861#if FIRST_PASS
1862 throw new NotImplementedException();
1863#else
1864 try
1865 {
1866 switch (o)
1867 {
1868 case RuntimeJavaType w:
1869 PutField(w, offset, x);
1870 break;
1871 case object[] array when array.GetType() == typeof(object[]):
1872 Volatile.Write(ref array[offset / IntPtr.Size], x);
1873 break;
1874 case object[] array:
1875 PutArrayObjectVolatile(array, offset, x);
1876 break;
1877 case object obj:
1878 PutFieldVolatile(o, offset, x);
1879 break;
1880 default:
1881 throw new global::java.lang.IllegalArgumentException();
1882 }
1883 }
1884 catch (Exception e) when (e is not global::java.lang.Throwable)
1885 {
1886 throw new global::java.lang.InternalError(e);
1887 }
1888#endif
1889 }
1890
1898 public static unsafe int getIntVolatile(object self, object o, long offset)
1899 {
1900#if FIRST_PASS
1901 throw new NotImplementedException();
1902#else
1903 try
1904 {
1905 return o switch
1906 {
1907 null => Volatile.Read(ref System.Runtime.CompilerServices.Unsafe.AsRef<int>((void*)(IntPtr)offset)),
1908 RuntimeJavaType w => GetFieldVolatile<int>(null, offset),
1909 Array array => ReadInt32Volatile(array, offset),
1910 _ => GetFieldVolatile<int>(o, offset)
1911 };
1912 }
1913 catch (Exception e) when (e is not global::java.lang.Throwable)
1914 {
1915 throw new global::java.lang.InternalError(e);
1916 }
1917#endif
1918 }
1919
1927 public static unsafe void putIntVolatile(object self, object o, long offset, int x)
1928 {
1929#if FIRST_PASS
1930 throw new NotImplementedException();
1931#else
1932 try
1933 {
1934 switch (o)
1935 {
1936 case null:
1937 Volatile.Write(ref System.Runtime.CompilerServices.Unsafe.AsRef<int>((void*)(IntPtr)offset), x);
1938 break;
1939 case RuntimeJavaType w:
1940 PutFieldVolatile(w, offset, x);
1941 break;
1942 case Array array:
1943 WriteInt32Volatile(array, offset, x);
1944 break;
1945 default:
1946 PutFieldVolatile(o, offset, x);
1947 break;
1948 }
1949 }
1950 catch (Exception e) when (e is not global::java.lang.Throwable)
1951 {
1952 throw new global::java.lang.InternalError(e);
1953 }
1954#endif
1955 }
1956
1964 public static unsafe bool getBooleanVolatile(object self, object o, long offset)
1965 {
1966#if FIRST_PASS
1967 throw new NotImplementedException();
1968#else
1969 try
1970 {
1971 return o switch
1972 {
1973 null => Volatile.Read(ref System.Runtime.CompilerServices.Unsafe.AsRef<byte>((void*)(IntPtr)offset)) != 0,
1974 RuntimeJavaType w => GetFieldVolatile<bool>(null, offset),
1975 Array array => ReadByteVolatile(array, offset) != 0,
1976 _ => GetFieldVolatile<bool>(o, offset)
1977 };
1978 }
1979 catch (Exception e) when (e is not global::java.lang.Throwable)
1980 {
1981 throw new global::java.lang.InternalError(e);
1982 }
1983#endif
1984 }
1985
1993 public static unsafe void putBooleanVolatile(object self, object o, long offset, bool x)
1994 {
1995#if FIRST_PASS
1996 throw new NotImplementedException();
1997#else
1998 try
1999 {
2000 switch (o)
2001 {
2002 case null:
2003 Volatile.Write(ref System.Runtime.CompilerServices.Unsafe.AsRef<byte>((void*)(IntPtr)offset), x ? (byte)1 : (byte)0);
2004 break;
2005 case RuntimeJavaType w:
2006 PutFieldVolatile(w, offset, x);
2007 break;
2008 case Array array:
2009 WriteByteVolatile(array, offset, x ? (byte)1 : (byte)0);
2010 break;
2011 default:
2012 PutFieldVolatile(o, offset, x);
2013 break;
2014 }
2015 }
2016 catch (Exception e) when (e is not global::java.lang.Throwable)
2017 {
2018 throw new global::java.lang.InternalError(e);
2019 }
2020#endif
2021 }
2022
2030 public static unsafe byte getByteVolatile(object self, object o, long offset)
2031 {
2032#if FIRST_PASS
2033 throw new NotImplementedException();
2034#else
2035 try
2036 {
2037 return o switch
2038 {
2039 null => Volatile.Read(ref System.Runtime.CompilerServices.Unsafe.AsRef<byte>((void*)(IntPtr)offset)),
2040 RuntimeJavaType w => GetFieldVolatile<byte>(null, offset),
2041 Array array => ReadByteVolatile(array, offset),
2042 _ => GetFieldVolatile<byte>(o, offset)
2043 };
2044 }
2045 catch (Exception e) when (e is not global::java.lang.Throwable)
2046 {
2047 throw new global::java.lang.InternalError(e);
2048 }
2049#endif
2050 }
2051
2059 public static unsafe void putByteVolatile(object self, object o, long offset, byte x)
2060 {
2061#if FIRST_PASS
2062 throw new NotImplementedException();
2063#else
2064 try
2065 {
2066 switch (o)
2067 {
2068 case null:
2069 Volatile.Write(ref System.Runtime.CompilerServices.Unsafe.AsRef<byte>((void*)(IntPtr)offset), x);
2070 break;
2071 case RuntimeJavaType w:
2072 PutFieldVolatile(w, offset, x);
2073 break;
2074 case Array array:
2075 WriteByteVolatile(array, offset, x);
2076 break;
2077 default:
2078 PutFieldVolatile(o, offset, x);
2079 break;
2080 }
2081 }
2082 catch (Exception e) when (e is not global::java.lang.Throwable)
2083 {
2084 throw new global::java.lang.InternalError(e);
2085 }
2086#endif
2087 }
2088
2096 public static short getShortVolatile(object self, object o, long offset)
2097 {
2098#if FIRST_PASS
2099 throw new NotImplementedException();
2100#else
2101 try
2102 {
2103 return o switch
2104 {
2105 Array array => ReadInt16Volatile(array, offset),
2106 _ => GetFieldVolatile<short>(o, offset)
2107 };
2108 }
2109 catch (Exception e) when (e is not global::java.lang.Throwable)
2110 {
2111 throw new global::java.lang.InternalError(e);
2112 }
2113#endif
2114 }
2115
2123 public static unsafe void putShortVolatile(object self, object o, long offset, short x)
2124 {
2125#if FIRST_PASS
2126 throw new NotImplementedException();
2127#else
2128 try
2129 {
2130 switch (o)
2131 {
2132 case null:
2133 Volatile.Write(ref System.Runtime.CompilerServices.Unsafe.AsRef<short>((void*)(IntPtr)offset), x);
2134 break;
2135 case RuntimeJavaType w:
2136 PutFieldVolatile(w, offset, x);
2137 break;
2138 case Array array:
2139 WriteInt16Volatile(array, offset, x);
2140 break;
2141 default:
2142 PutFieldVolatile(o, offset, x);
2143 break;
2144 }
2145 }
2146 catch (Exception e) when (e is not global::java.lang.Throwable)
2147 {
2148 throw new global::java.lang.InternalError(e);
2149 }
2150#endif
2151 }
2152
2160 public static char getCharVolatile(object self, object o, long offset)
2161 {
2162#if FIRST_PASS
2163 throw new NotImplementedException();
2164#else
2165 try
2166 {
2167 return o switch
2168 {
2169 Array array => (char)ReadInt16Volatile(array, offset),
2170 _ => GetFieldVolatile<char>(o, offset)
2171 };
2172 }
2173 catch (Exception e) when (e is not global::java.lang.Throwable)
2174 {
2175 throw new global::java.lang.InternalError(e);
2176 }
2177#endif
2178 }
2179
2187 public static unsafe void putCharVolatile(object self, object o, long offset, char x)
2188 {
2189#if FIRST_PASS
2190 throw new NotImplementedException();
2191#else
2192 try
2193 {
2194 switch (o)
2195 {
2196 case null:
2197 Volatile.Write(ref System.Runtime.CompilerServices.Unsafe.AsRef<short>((void*)(IntPtr)offset), (short)x);
2198 break;
2199 case RuntimeJavaType w:
2200 PutFieldVolatile(w, offset, x);
2201 break;
2202 case Array array:
2203 WriteInt16Volatile(array, offset, (short)x);
2204 break;
2205 default:
2206 PutFieldVolatile(o, offset, x);
2207 break;
2208 }
2209 }
2210 catch (Exception e) when (e is not global::java.lang.Throwable)
2211 {
2212 throw new global::java.lang.InternalError(e);
2213 }
2214#endif
2215 }
2216
2224 public static long getLongVolatile(object self, object o, long offset)
2225 {
2226#if FIRST_PASS
2227 throw new NotImplementedException();
2228#else
2229 try
2230 {
2231 return o switch
2232 {
2233 Array array => ReadInt64Volatile(array, offset),
2234 _ => GetFieldVolatile<long>(o, offset)
2235 };
2236 }
2237 catch (Exception e) when (e is not global::java.lang.Throwable)
2238 {
2239 throw new global::java.lang.InternalError(e);
2240 }
2241#endif
2242 }
2243
2251 public static unsafe void putLongVolatile(object self, object o, long offset, long x)
2252 {
2253#if FIRST_PASS
2254 throw new NotImplementedException();
2255#else
2256 try
2257 {
2258 switch (o)
2259 {
2260 case null:
2261 Volatile.Write(ref System.Runtime.CompilerServices.Unsafe.AsRef<long>((void*)(IntPtr)offset), x);
2262 break;
2263 case RuntimeJavaType w:
2264 PutFieldVolatile(w, offset, x);
2265 break;
2266 case Array array:
2267 WriteInt64Volatile(array, offset, x);
2268 break;
2269 default:
2270 PutFieldVolatile(o, offset, x);
2271 break;
2272 }
2273 }
2274 catch (Exception e) when (e is not global::java.lang.Throwable)
2275 {
2276 throw new global::java.lang.InternalError(e);
2277 }
2278#endif
2279 }
2280
2289 public static float getFloatVolatile(object self, object o, long offset)
2290 {
2291#if FIRST_PASS
2292 throw new NotImplementedException();
2293#else
2294 try
2295 {
2296 return o switch
2297 {
2298 Array array => global::java.lang.Float.intBitsToFloat(ReadInt32Volatile(array, offset)),
2299 _ => GetFieldVolatile<float>(o, offset)
2300 };
2301 }
2302 catch (Exception e) when (e is not global::java.lang.Throwable)
2303 {
2304 throw new global::java.lang.InternalError(e);
2305 }
2306#endif
2307 }
2308
2316 public static unsafe void putFloatVolatile(object self, object o, long offset, float x)
2317 {
2318#if FIRST_PASS
2319 throw new NotImplementedException();
2320#else
2321 try
2322 {
2323 switch (o)
2324 {
2325 case null:
2326 Volatile.Write(ref System.Runtime.CompilerServices.Unsafe.AsRef<float>((void*)(IntPtr)offset), x);
2327 break;
2328 case RuntimeJavaType w:
2329 PutFieldVolatile(w, offset, x);
2330 break;
2331 case Array array:
2332 WriteInt32Volatile(array, offset, global::java.lang.Float.floatToRawIntBits(x));
2333 break;
2334 default:
2335 PutFieldVolatile(o, offset, x);
2336 break;
2337 }
2338 }
2339 catch (Exception e) when (e is not global::java.lang.Throwable)
2340 {
2341 throw new global::java.lang.InternalError(e);
2342 }
2343#endif
2344 }
2345
2354 public static double getDoubleVolatile(object self, object o, long offset)
2355 {
2356#if FIRST_PASS
2357 throw new NotImplementedException();
2358#else
2359 try
2360 {
2361 return o switch
2362 {
2363 Array array => global::java.lang.Double.longBitsToDouble(ReadInt64Volatile(array, offset)),
2364 _ => GetFieldVolatile<double>(o, offset)
2365 };
2366 }
2367 catch (Exception e) when (e is not global::java.lang.Throwable)
2368 {
2369 throw new global::java.lang.InternalError(e);
2370 }
2371#endif
2372 }
2373
2381 public static unsafe void putDoubleVolatile(object self, object o, long offset, double x)
2382 {
2383#if FIRST_PASS
2384 throw new NotImplementedException();
2385#else
2386 try
2387 {
2388 switch (o)
2389 {
2390 case null:
2391 Volatile.Write(ref System.Runtime.CompilerServices.Unsafe.AsRef<double>((void*)(IntPtr)offset), x);
2392 break;
2393 case RuntimeJavaType w:
2394 PutFieldVolatile(w, offset, x);
2395 break;
2396 case Array array:
2397 WriteInt64Volatile(array, offset, global::java.lang.Double.doubleToRawLongBits(x));
2398 break;
2399 default:
2400 PutFieldVolatile(o, offset, x);
2401 break;
2402 }
2403 }
2404 catch (Exception e) when (e is not global::java.lang.Throwable)
2405 {
2406 throw new global::java.lang.InternalError(e);
2407 }
2408#endif
2409 }
2410
2411 public static void putOrderedObject(object self, object o, long offset, object x)
2412 {
2413 putObjectVolatile(self, o, offset, x);
2414 }
2415
2416 public static void putOrderedInt(object self, object o, long offset, int x)
2417 {
2418 putIntVolatile(self, o, offset, x);
2419 }
2420
2421 public static void putOrderedLong(object self, object o, long offset, long x)
2422 {
2423 putLongVolatile(self, o, offset, x);
2424 }
2425
2436 static bool CompareAndSwapField<T>(object o, long offset, T expected, T value)
2437 {
2438#if FIRST_PASS
2439 throw new NotImplementedException();
2440#else
2441 return RuntimeJavaField.FromCookie((IntPtr)offset).UnsafeCompareAndSwap(o, expected, value);
2442#endif
2443 }
2444
2450 static Delegate CreateCompareExchangeArrayDelegate(RuntimeJavaType tw)
2451 {
2452 var p = Expression.Parameter(typeof(object[]));
2453 var i = Expression.Parameter(typeof(long));
2454 var v = Expression.Parameter(typeof(object));
2455 var e = Expression.Parameter(typeof(object));
2456 return Expression.Lambda<Func<object[], long, object, object, object>>(
2457 Expression.Call(
2458 compareAndSwapArrayMethodInfo.MakeGenericMethod(tw.TypeAsTBD),
2459 Expression.Convert(p, tw.MakeArrayType(1).TypeAsTBD),
2460 i,
2461 Expression.Convert(v, tw.TypeAsTBD),
2462 Expression.Convert(e, tw.TypeAsTBD)),
2463 p, i, v, e)
2464 .Compile();
2465 }
2466
2476 static object CompareAndSwapArray<T>(T[] o, long offset, T value, T comparand)
2477 where T : class
2478 {
2479#if FIRST_PASS
2480 throw new NotImplementedException();
2481#else
2482 return Interlocked.CompareExchange<T>(ref o[offset / ArrayIndexScale(JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(o.GetType()))], value, comparand);
2483#endif
2484 }
2485
2496 static object CompareAndSwapObjectArray(object[] o, long offset, object value, object expected)
2497 {
2498#if FIRST_PASS
2499 throw new NotImplementedException();
2500#else
2501 return ((Func<object[], long, object, object, object>)arrayRefCache.GetValue(JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(o.GetType().GetElementType()), _ => new ArrayDelegateRef(_)).CompareExchange)(o, offset, value, expected);
2502#endif
2503 }
2504
2514 public static bool compareAndSwapObject(object self, object o, long offset, object expected, object x)
2515 {
2516#if FIRST_PASS
2517 throw new NotImplementedException();
2518#else
2519 try
2520 {
2521 return o switch
2522 {
2523 object[] array when array.GetType() == typeof(object[]) => Interlocked.CompareExchange(ref array[offset / IntPtr.Size], x, expected) == expected,
2524 object[] array => CompareAndSwapObjectArray(array, offset, x, expected) == expected,
2525 _ => CompareAndSwapField(o, offset, expected, x)
2526 };
2527 }
2528 catch (Exception e) when (e is not global::java.lang.Throwable)
2529 {
2530 throw new global::java.lang.InternalError(e);
2531 }
2532#endif
2533 }
2534
2544 public static bool compareAndSwapInt(object self, object o, long offset, int expected, int x)
2545 {
2546#if FIRST_PASS
2547 throw new NotImplementedException();
2548#else
2549 try
2550 {
2551 if (o is int[] array && (offset % sizeof(int)) == 0)
2552 {
2553 return Interlocked.CompareExchange(ref array[offset / sizeof(int)], x, expected) == expected;
2554 }
2555 else if (o is Array array1 && (offset % sizeof(int)) == 0)
2556 {
2557 return CompareExchangeInt32(array1, offset, x, expected) == expected;
2558 }
2559 else if (o is Array array2)
2560 {
2561 return CompareExchangeInt32Unaligned(array2, offset, x, expected) == expected;
2562 }
2563 else
2564 {
2565 return CompareAndSwapField(o, offset, expected, x);
2566 }
2567 }
2568 catch (Exception e) when (e is not global::java.lang.Throwable)
2569 {
2570 throw new global::java.lang.InternalError(e);
2571 }
2572#endif
2573 }
2574
2584 public static bool compareAndSwapLong(object self, object o, long offset, long expected, long x)
2585 {
2586#if FIRST_PASS
2587 throw new NotImplementedException();
2588#else
2589 try
2590 {
2591 if (o is long[] array && (offset % sizeof(long)) == 0)
2592 {
2593 return Interlocked.CompareExchange(ref array[offset / sizeof(long)], x, expected) == expected;
2594 }
2595 else if (o is Array array1 && (offset % sizeof(long)) == 0)
2596 {
2597 return CompareExchangeInt64(array1, offset, x, expected) == expected;
2598 }
2599 else if (o is Array array2)
2600 {
2601 return CompareExchangeInt64Unaligned(array2, offset, x, expected) == expected;
2602 }
2603 else
2604 {
2605 return CompareAndSwapField(o, offset, expected, x);
2606 }
2607 }
2608 catch (Exception e) when (e is not global::java.lang.Throwable)
2609 {
2610 throw new global::java.lang.InternalError(e);
2611 }
2612#endif
2613 }
2614
2615 const int PARK_STATE_RUNNING = 0;
2616 const int PARK_STATE_PERMIT = 1;
2617 const int PARK_STATE_PARKED = 2;
2618
2624 public static void unpark(object self, object thread)
2625 {
2626#if FIRST_PASS
2627 throw new NotImplementedException();
2628#else
2629 var currentThread = (global::java.lang.Thread)thread;
2630 if (currentThread == null)
2631 throw new global::java.lang.IllegalStateException();
2632
2633 if (currentThread != null)
2634 {
2635 if (Interlocked.CompareExchange(ref currentThread.parkState, PARK_STATE_PERMIT, PARK_STATE_RUNNING) == PARK_STATE_PARKED)
2636 {
2637 if (Interlocked.CompareExchange(ref currentThread.parkState, PARK_STATE_RUNNING, PARK_STATE_PARKED) == PARK_STATE_PARKED)
2638 {
2639 // initialize lock
2640 Interlocked.CompareExchange(ref currentThread.parkLock, new global::java.lang.Object(), null);
2641
2642 // thread is currently blocking, so we have to release it
2643 lock (currentThread.parkLock)
2644 Monitor.Pulse(currentThread.parkLock);
2645 }
2646 }
2647 }
2648#endif
2649 }
2650
2657 public static void park(object self, bool isAbsolute, long time)
2658 {
2659#if FIRST_PASS
2660 throw new NotImplementedException();
2661#else
2662 var currentThread = global::java.lang.Thread.currentThread();
2663 if (currentThread == null)
2664 throw new global::java.lang.IllegalStateException();
2665
2666 if (Interlocked.CompareExchange(ref currentThread.parkState, PARK_STATE_RUNNING, PARK_STATE_PERMIT) == PARK_STATE_PERMIT)
2667 return;
2668
2669 // initialize lock
2670 Interlocked.CompareExchange(ref currentThread.parkLock, new global::java.lang.Object(), null);
2671
2672 // lock thread
2673 lock (currentThread.parkLock)
2674 {
2675 if (Interlocked.CompareExchange(ref currentThread.parkState, PARK_STATE_PARKED, PARK_STATE_RUNNING) == PARK_STATE_PERMIT)
2676 {
2677 Interlocked.CompareExchange(ref currentThread.parkState, PARK_STATE_RUNNING, PARK_STATE_PERMIT);
2678 return;
2679 }
2680
2681 if (isAbsolute)
2682 {
2683 time *= 1000000;
2684 time -= global::java.lang.System.currentTimeMillis() * 1000000;
2685 }
2686
2687 if (time >= 0)
2688 {
2689 try
2690 {
2691 ((global::java.lang.Object)currentThread.parkLock).wait(time / 1000000, (int)(time % 1000000));
2692 }
2693 catch (global::java.lang.InterruptedException)
2694 {
2695 currentThread.interrupt();
2696 }
2697 }
2698
2699 Interlocked.CompareExchange(ref currentThread.parkState, PARK_STATE_RUNNING, PARK_STATE_PARKED);
2700 }
2701#endif
2702 }
2703
2704 public static int getLoadAverage(object self, double[] loadavg, int nelems)
2705 {
2706 return -1;
2707 }
2708
2709 public static void loadFence(object self)
2710 {
2711 Thread.MemoryBarrier();
2712 }
2713
2714 public static void storeFence(object self)
2715 {
2716 Thread.MemoryBarrier();
2717 }
2718
2719 public static void fullFence(object self)
2720 {
2721 Thread.MemoryBarrier();
2722 }
2723
2730 static unsafe byte ReadByte(Array obj, long offset)
2731 {
2732#if FIRST_PASS
2733 throw new NotImplementedException();
2734#else
2735 GCHandle h = new();
2736
2737 try
2738 {
2739 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
2740 var v = System.Runtime.CompilerServices.Unsafe.ReadUnaligned<byte>((byte*)h.AddrOfPinnedObject() + offset);
2741 return v;
2742 }
2743 finally
2744 {
2745 if (h.IsAllocated)
2746 h.Free();
2747 }
2748#endif
2749 }
2750
2757 static unsafe byte ReadByteVolatile(Array obj, long offset)
2758 {
2759#if FIRST_PASS
2760 throw new NotImplementedException();
2761#else
2762 GCHandle h = new();
2763
2764 try
2765 {
2766 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
2767 ref var r = ref System.Runtime.CompilerServices.Unsafe.AsRef<byte>((byte*)h.AddrOfPinnedObject() + offset);
2768 var v = Volatile.Read(ref r);
2769 return v;
2770 }
2771 finally
2772 {
2773 if (h.IsAllocated)
2774 h.Free();
2775 }
2776#endif
2777 }
2778
2785 static unsafe short ReadInt16(Array obj, long offset)
2786 {
2787#if FIRST_PASS
2788 throw new NotImplementedException();
2789#else
2790 GCHandle h = new();
2791
2792 try
2793 {
2794 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
2795 var v = System.Runtime.CompilerServices.Unsafe.ReadUnaligned<short>((byte*)h.AddrOfPinnedObject() + offset);
2796 return v;
2797 }
2798 finally
2799 {
2800 if (h.IsAllocated)
2801 h.Free();
2802 }
2803#endif
2804 }
2805
2812 static unsafe short ReadInt16Volatile(Array obj, long offset)
2813 {
2814#if FIRST_PASS
2815 throw new NotImplementedException();
2816#else
2817 GCHandle h = new();
2818
2819 try
2820 {
2821 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
2822 ref var r = ref System.Runtime.CompilerServices.Unsafe.AsRef<short>((byte*)h.AddrOfPinnedObject() + offset);
2823 var v = Volatile.Read(ref r);
2824 return v;
2825 }
2826 finally
2827 {
2828 if (h.IsAllocated)
2829 h.Free();
2830 }
2831#endif
2832 }
2833
2840 static unsafe int ReadInt32(Array obj, long offset)
2841 {
2842#if FIRST_PASS
2843 throw new NotImplementedException();
2844#else
2845 GCHandle h = new();
2846
2847 try
2848 {
2849 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
2850 var v = System.Runtime.CompilerServices.Unsafe.ReadUnaligned<int>((byte*)h.AddrOfPinnedObject() + offset);
2851 return v;
2852 }
2853 finally
2854 {
2855 if (h.IsAllocated)
2856 h.Free();
2857 }
2858#endif
2859 }
2860
2867 static unsafe int ReadInt32Volatile(Array obj, long offset)
2868 {
2869#if FIRST_PASS
2870 throw new NotImplementedException();
2871#else
2872 GCHandle h = new();
2873
2874 try
2875 {
2876 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
2877 ref var r = ref System.Runtime.CompilerServices.Unsafe.AsRef<int>((byte*)h.AddrOfPinnedObject() + offset);
2878 var v = Volatile.Read(ref r);
2879 return v;
2880 }
2881 finally
2882 {
2883 if (h.IsAllocated)
2884 h.Free();
2885 }
2886#endif
2887 }
2888
2895 static unsafe long ReadInt64(Array obj, long offset)
2896 {
2897#if FIRST_PASS
2898 throw new NotImplementedException();
2899#else
2900 GCHandle h = new();
2901
2902 try
2903 {
2904 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
2905 var v = System.Runtime.CompilerServices.Unsafe.ReadUnaligned<long>((byte*)h.AddrOfPinnedObject() + offset);
2906 return v;
2907 }
2908 finally
2909 {
2910 if (h.IsAllocated)
2911 h.Free();
2912 }
2913#endif
2914 }
2915
2922 static unsafe long ReadInt64Volatile(Array obj, long offset)
2923 {
2924#if FIRST_PASS
2925 throw new NotImplementedException();
2926#else
2927 GCHandle h = new();
2928
2929 try
2930 {
2931 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
2932 ref var r = ref System.Runtime.CompilerServices.Unsafe.AsRef<long>((byte*)h.AddrOfPinnedObject() + offset);
2933 var v = Interlocked.Read(ref r); // java considers volatile to be atomic
2934 return v;
2935 }
2936 finally
2937 {
2938 if (h.IsAllocated)
2939 h.Free();
2940 }
2941#endif
2942 }
2943
2950 static unsafe void WriteByte(Array obj, long offset, byte value)
2951 {
2952#if FIRST_PASS
2953 throw new NotImplementedException();
2954#else
2955 GCHandle h = new();
2956
2957 try
2958 {
2959 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
2960 System.Runtime.CompilerServices.Unsafe.WriteUnaligned((byte*)h.AddrOfPinnedObject() + offset, value);
2961 }
2962 finally
2963 {
2964 if (h.IsAllocated)
2965 h.Free();
2966 }
2967#endif
2968 }
2969
2976 static unsafe void WriteByteVolatile(Array obj, long offset, byte value)
2977 {
2978#if FIRST_PASS
2979 throw new NotImplementedException();
2980#else
2981 GCHandle h = new();
2982
2983 try
2984 {
2985 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
2986 Volatile.Write(ref System.Runtime.CompilerServices.Unsafe.AsRef<byte>((byte*)h.AddrOfPinnedObject() + offset), value);
2987 }
2988 finally
2989 {
2990 if (h.IsAllocated)
2991 h.Free();
2992 }
2993#endif
2994 }
2995
3002 static unsafe void WriteInt16(Array obj, long offset, short value)
3003 {
3004#if FIRST_PASS
3005 throw new NotImplementedException();
3006#else
3007 GCHandle h = new();
3008
3009 try
3010 {
3011 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
3012 System.Runtime.CompilerServices.Unsafe.WriteUnaligned((byte*)h.AddrOfPinnedObject() + offset, value);
3013 }
3014 finally
3015 {
3016 if (h.IsAllocated)
3017 h.Free();
3018 }
3019#endif
3020 }
3021
3028 static unsafe void WriteInt16Volatile(Array obj, long offset, short value)
3029 {
3030#if FIRST_PASS
3031 throw new NotImplementedException();
3032#else
3033 GCHandle h = new();
3034
3035 try
3036 {
3037 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
3038 Volatile.Write(ref System.Runtime.CompilerServices.Unsafe.AsRef<short>((byte*)h.AddrOfPinnedObject() + offset), value);
3039 }
3040 finally
3041 {
3042 if (h.IsAllocated)
3043 h.Free();
3044 }
3045#endif
3046 }
3047
3054 static unsafe void WriteInt32(Array obj, long offset, int value)
3055 {
3056#if FIRST_PASS
3057 throw new NotImplementedException();
3058#else
3059 GCHandle h = new();
3060
3061 try
3062 {
3063 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
3064 System.Runtime.CompilerServices.Unsafe.WriteUnaligned((byte*)h.AddrOfPinnedObject() + offset, value);
3065 }
3066 finally
3067 {
3068 if (h.IsAllocated)
3069 h.Free();
3070 }
3071#endif
3072 }
3073
3080 static unsafe void WriteInt32Volatile(Array obj, long offset, int value)
3081 {
3082#if FIRST_PASS
3083 throw new NotImplementedException();
3084#else
3085 GCHandle h = new();
3086
3087 try
3088 {
3089 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
3090 Volatile.Write(ref System.Runtime.CompilerServices.Unsafe.AsRef<int>((byte*)h.AddrOfPinnedObject() + offset), value);
3091 }
3092 finally
3093 {
3094 if (h.IsAllocated)
3095 h.Free();
3096 }
3097#endif
3098 }
3099
3106 static unsafe void WriteInt64(Array obj, long offset, long value)
3107 {
3108#if FIRST_PASS
3109 throw new NotImplementedException();
3110#else
3111 GCHandle h = new();
3112
3113 try
3114 {
3115 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
3116 System.Runtime.CompilerServices.Unsafe.WriteUnaligned((byte*)h.AddrOfPinnedObject() + offset, value);
3117 }
3118 finally
3119 {
3120 if (h.IsAllocated)
3121 h.Free();
3122 }
3123#endif
3124 }
3125
3132 static unsafe void WriteInt64Volatile(Array obj, long offset, long value)
3133 {
3134#if FIRST_PASS
3135 throw new NotImplementedException();
3136#else
3137 GCHandle h = new();
3138
3139 try
3140 {
3141 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
3142 Interlocked.Exchange(ref System.Runtime.CompilerServices.Unsafe.AsRef<long>((byte*)h.AddrOfPinnedObject() + offset), value);
3143 }
3144 finally
3145 {
3146 if (h.IsAllocated)
3147 h.Free();
3148 }
3149#endif
3150 }
3151
3160 static unsafe int CompareExchangeInt32(Array obj, long offset, int value, int expected)
3161 {
3162#if FIRST_PASS
3163 throw new NotImplementedException();
3164#else
3165 GCHandle h = new();
3166
3167 try
3168 {
3169 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
3170 var r = Interlocked.CompareExchange(ref System.Runtime.CompilerServices.Unsafe.AsRef<int>((byte*)h.AddrOfPinnedObject() + offset), value, expected);
3171 return r;
3172 }
3173 finally
3174 {
3175 if (h.IsAllocated)
3176 h.Free();
3177 }
3178#endif
3179 }
3180
3189 static unsafe int CompareExchangeInt32Unaligned(Array obj, long offset, int value, int expected)
3190 {
3191#if FIRST_PASS
3192 throw new NotImplementedException();
3193#else
3194 GCHandle h = new();
3195
3196 try
3197 {
3198 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
3199 var r = Interlocked.CompareExchange(ref System.Runtime.CompilerServices.Unsafe.AsRef<int>((byte*)h.AddrOfPinnedObject() + offset), value, expected);
3200 return r;
3201 }
3202 finally
3203 {
3204 if (h.IsAllocated)
3205 h.Free();
3206 }
3207#endif
3208 }
3209
3218 static unsafe long CompareExchangeInt64(Array obj, long offset, long value, long expected)
3219 {
3220#if FIRST_PASS
3221 throw new NotImplementedException();
3222#else
3223 GCHandle h = new();
3224
3225 try
3226 {
3227 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
3228 var r = Interlocked.CompareExchange(ref System.Runtime.CompilerServices.Unsafe.AsRef<long>((byte*)h.AddrOfPinnedObject() + offset), value, expected);
3229 return r;
3230 }
3231 finally
3232 {
3233 if (h.IsAllocated)
3234 h.Free();
3235 }
3236#endif
3237 }
3238
3247 static unsafe long CompareExchangeInt64Unaligned(Array obj, long offset, long value, long expected)
3248 {
3249#if FIRST_PASS
3250 throw new NotImplementedException();
3251#else
3252 GCHandle h = new();
3253
3254 try
3255 {
3256 h = GCHandle.Alloc(obj, GCHandleType.Pinned);
3257 var r = Interlocked.CompareExchange(ref System.Runtime.CompilerServices.Unsafe.AsRef<long>((byte*)h.AddrOfPinnedObject() + offset), value, expected);
3258 return r;
3259 }
3260 finally
3261 {
3262 if (h.IsAllocated)
3263 h.Free();
3264 }
3265#endif
3266 }
3267
3273 static long InterlockedRead(ref long location)
3274 {
3275#if FIRST_PASS
3276 throw new NotImplementedException();
3277#else
3278 try
3279 {
3280 return Interlocked.Read(ref location);
3281 }
3282 catch (Exception e)
3283 {
3284 throw new global::java.lang.InternalError(e);
3285 }
3286#endif
3287 }
3288
3294 static double InterlockedRead(ref double location)
3295 {
3296#if FIRST_PASS
3297 throw new NotImplementedException();
3298#else
3299 try
3300 {
3301 return Interlocked.CompareExchange(ref location, 0, 0);
3302 }
3303 catch (Exception e)
3304 {
3305 throw new global::java.lang.InternalError(e);
3306 }
3307#endif
3308 }
3309
3315 static void InterlockedWrite(ref long location, long value)
3316 {
3317#if FIRST_PASS
3318 throw new NotImplementedException();
3319#else
3320 try
3321 {
3322 Interlocked.Exchange(ref location, value);
3323 }
3324 catch (Exception e)
3325 {
3326 throw new global::java.lang.InternalError(e);
3327 }
3328#endif
3329 }
3330
3336 static void InterlockedWrite(ref double location, double value)
3337 {
3338#if FIRST_PASS
3339 throw new NotImplementedException();
3340#else
3341 try
3342 {
3343 Interlocked.Exchange(ref location, value);
3344 }
3345 catch (Exception e)
3346 {
3347 throw new global::java.lang.InternalError(e);
3348 }
3349#endif
3350 }
3351
3352 }
3353
3354}
System.Threading.Interlocked Interlocked
IKVM.Reflection.Type Type
IKVM.Reflection.MethodInfo MethodInfo
static global::java.lang.Class defineClass1(global::java.lang.ClassLoader self, string name, byte[] b, int off, int len, global::java.security.ProtectionDomain pd, string source)
Implements the native method 'defineClass1'.
static bool compareAndSwapObject(object self, object o, long offset, object expected, object x)
Implementation of native method 'compareAndSwapObject'.
Definition Unsafe.cs:2514
static unsafe void setMemory(object self, object o, long offset, long bytes, byte value)
Implementation of native method 'setMemory'.
Definition Unsafe.cs:1205
static void park(object self, bool isAbsolute, long time)
Implements the native method 'park'.
Definition Unsafe.cs:2657
static unsafe void putDoubleVolatile(object self, object o, long offset, double x)
Implementation of native method 'putDoubleVolatile'.
Definition Unsafe.cs:2381
static global::java.lang.Class defineAnonymousClass(object self, global::java.lang.Class hostClass, byte[] data, object[] cpPatches)
Implementation of native method 'defineAnonymousClass'.
Definition Unsafe.cs:1549
static long getAddress(object self, long address)
Implementation of native method 'getAddress'.
Definition Unsafe.cs:1080
static void putShort(object self, long address, short x)
Implementation of native method 'putShort'.
Definition Unsafe.cs:852
static short getShort(object self, object o, long offset)
Implementation of native method 'getShort'.
Definition Unsafe.cs:391
static unsafe void putIntVolatile(object self, object o, long offset, int x)
Implementation of native method 'putIntVolatile'.
Definition Unsafe.cs:1927
static long staticFieldOffset(object self, global::java.lang.reflect.Field f)
Implementation of native method 'staticFieldOffset'.
Definition Unsafe.cs:1394
static void putOrderedInt(object self, object o, long offset, int x)
Definition Unsafe.cs:2416
static object allocateInstance(object self, global::java.lang.Class cls)
Implementation of native method 'allocateInstance'.
Definition Unsafe.cs:1605
static void putChar(object self, object o, long offset, char x)
Implementation of native method 'putChar'.
Definition Unsafe.cs:486
static int arrayIndexScale(object self, global::java.lang.Class arrayClass)
Implementation of native method 'arrayIndexScale'.
Definition Unsafe.cs:1499
static void monitorExit(object self, object o)
Implementation of native method 'monitorExit'.
Definition Unsafe.cs:1639
static object staticFieldBase(object self, global::java.lang.reflect.Field f)
Implementation of native method 'staticFieldBase'.
Definition Unsafe.cs:1379
static object getObjectVolatile(object self, object o, long offset)
Implementation of native method 'getObjectVolatile'.
Definition Unsafe.cs:1829
static void putBoolean(object self, object o, long offset, bool x)
Implementation of native method 'putBoolean'.
Definition Unsafe.cs:288
static long objectFieldOffset(object self, global::java.lang.reflect.Field f)
Implementation of native method 'objectFieldOffset'.
Definition Unsafe.cs:1409
static void ensureClassInitialized(object self, global::java.lang.Class c)
Implementation of native method 'ensureClassInitialized'.
Definition Unsafe.cs:1434
static long getLong(object self, long address)
Implementation of native method 'getLong'.
Definition Unsafe.cs:962
static void putObject(object self, object o, long offset, object x)
Implementation of native method 'putObject'.
Definition Unsafe.cs:223
static short getShort(object self, long address)
Implementation of native method 'getShort'.
Definition Unsafe.cs:830
static char getChar(object self, object o, long offset)
Implementation of native method 'getChar'.
Definition Unsafe.cs:457
static bool shouldBeInitialized(object self, global::java.lang.Class c)
Implementation of native method 'shouldBeInitialized'.
Definition Unsafe.cs:1424
static void putInt(object self, object o, long offset, int x)
Implementation of native method 'putInt'.
Definition Unsafe.cs:552
static bool compareAndSwapInt(object self, object o, long offset, int expected, int x)
Implementation of native method 'compareAndSwapInt'.
Definition Unsafe.cs:2544
static unsafe long allocateMemory(object self, long bytes)
Implementation of native method 'allocateMemory'.
Definition Unsafe.cs:1125
static void putDouble(object self, object o, long offset, double x)
Implementation of native method 'putDouble'.
Definition Unsafe.cs:750
static void putLong(object self, object o, long offset, long x)
Implementation of native method 'putLong'.
Definition Unsafe.cs:618
static unsafe byte getByteVolatile(object self, object o, long offset)
Implementation of native method 'getByteVolatile'.
Definition Unsafe.cs:2030
static unsafe void putByteVolatile(object self, object o, long offset, byte x)
Implementation of native method 'putByteVolatile'.
Definition Unsafe.cs:2059
static unsafe long reallocateMemory(object self, long address, long bytes)
Implementation of native method 'reallocateMemory'.
Definition Unsafe.cs:1160
static object getObject(object self, object o, long offset)
Implementation of native method 'getObject'.
Definition Unsafe.cs:194
static int getLoadAverage(object self, double[] loadavg, int nelems)
Definition Unsafe.cs:2704
static double getDouble(object self, long address)
Implementation of native method 'getDouble'.
Definition Unsafe.cs:1043
static unsafe void putShortVolatile(object self, object o, long offset, short x)
Implementation of native method 'putShortVolatile'.
Definition Unsafe.cs:2123
static void registerNatives()
Implementation of native method 'registerNatives'.
Definition Unsafe.cs:130
static unsafe void putCharVolatile(object self, object o, long offset, char x)
Implementation of native method 'putCharVolatile'.
Definition Unsafe.cs:2187
static global::java.lang.Class defineClass(object self, string name, byte[] b, int off, int len, global::java.lang.ClassLoader loader, global::java.security.ProtectionDomain protectionDomain)
Implementation of native method 'defineClass'.
Definition Unsafe.cs:1535
static float getFloat(object self, object o, long offset)
Implementation of native method 'getFloat'.
Definition Unsafe.cs:655
static char getCharVolatile(object self, object o, long offset)
Implementation of native method 'getCharVolatile'.
Definition Unsafe.cs:2160
static void putShort(object self, object o, long offset, short x)
Implementation of native method 'putShort'.
Definition Unsafe.cs:420
static char getChar(object self, long address)
Implementation of native method 'getChar'.
Definition Unsafe.cs:874
static unsafe bool getBooleanVolatile(object self, object o, long offset)
Implementation of native method 'getBooleanVolatile'.
Definition Unsafe.cs:1964
static void putOrderedLong(object self, object o, long offset, long x)
Definition Unsafe.cs:2421
static void putLong(object self, long address, long x)
Implementation of native method 'putLong'.
Definition Unsafe.cs:984
static float getFloatVolatile(object self, object o, long offset)
Implementation of native method 'getFloatVolatile'.
Definition Unsafe.cs:2289
static unsafe int getIntVolatile(object self, object o, long offset)
Implementation of native method 'getIntVolatile'.
Definition Unsafe.cs:1898
static void unpark(object self, object thread)
Implements the native method 'unpark'.
Definition Unsafe.cs:2624
static bool tryMonitorEnter(object self, object o)
Implementation of native method 'tryMonitorEnter'.
Definition Unsafe.cs:1650
static int addressSize(object self)
Implementation of native method 'addressSize'.
Definition Unsafe.cs:1509
static unsafe void copyMemory(object self, object srcBase, long srcOffset, object destBase, long destOffset, long bytes)
Implementation of native method 'copyMemory'.
Definition Unsafe.cs:1251
static void putInt(object self, long address, int x)
Implementation of native method 'putInt'.
Definition Unsafe.cs:940
static bool compareAndSwapLong(object self, object o, long offset, long expected, long x)
Implementation of native method 'compareAndSwapLong'.
Definition Unsafe.cs:2584
static long getLong(object self, object o, long offset)
Implementation of native method 'getLong'.
Definition Unsafe.cs:589
static void putAddress(object self, long address, long x)
Implementation of native method 'putAddress'.
Definition Unsafe.cs:1102
static void putDouble(object self, long address, double x)
Implementation of native method 'putDouble'.
Definition Unsafe.cs:1065
static int getInt(object self, object o, long offset)
Implementation of native method 'getInt'.
Definition Unsafe.cs:523
static void putByte(object self, object o, long offset, byte x)
Implementation of native method 'putByte'.
Definition Unsafe.cs:354
static short getShortVolatile(object self, object o, long offset)
Implementation of native method 'getShortVolatile'.
Definition Unsafe.cs:2096
static int pageSize(object self)
Implementation of native method 'pageSize'.
Definition Unsafe.cs:1519
static int getInt(object self, long address)
Implementation of native method 'getInt'.
Definition Unsafe.cs:918
static long getLongVolatile(object self, object o, long offset)
Implementation of native method 'getLongVolatile'.
Definition Unsafe.cs:2224
static void putFloat(object self, long address, float x)
Implementation of native method 'putFloat'.
Definition Unsafe.cs:1028
static void loadFence(object self)
Definition Unsafe.cs:2709
static void putByte(object self, long address, byte x)
Implementation of native method 'putByte'.
Definition Unsafe.cs:808
static byte getByte(object self, long address)
Implementation of native method 'getByte'.
Definition Unsafe.cs:786
static unsafe void freeMemory(object self, long address)
Implementation of native method 'freeMemory'.
Definition Unsafe.cs:1361
static unsafe void putLongVolatile(object self, object o, long offset, long x)
Implementation of native method 'putLongVolatile'.
Definition Unsafe.cs:2251
static void storeFence(object self)
Definition Unsafe.cs:2714
static void putOrderedObject(object self, object o, long offset, object x)
Definition Unsafe.cs:2411
static void throwException(object self, Exception ee)
Implementation of native method 'throwException'.
Definition Unsafe.cs:1660
static void monitorEnter(object self, object o)
Implementation of native method 'monitorEnter'.
Definition Unsafe.cs:1629
static void putFloat(object self, object o, long offset, float x)
Implementation of native method 'putFloat'.
Definition Unsafe.cs:684
static byte getByte(object self, object o, long offset)
Implementation of native method 'getByte'.
Definition Unsafe.cs:325
static bool getBoolean(object self, object o, long offset)
Implementation of native method 'getBoolean'.
Definition Unsafe.cs:259
static void putChar(object self, long address, char x)
Implementation of native method 'putChar'.
Definition Unsafe.cs:896
static void fullFence(object self)
Definition Unsafe.cs:2719
static int arrayBaseOffset(object self, global::java.lang.Class arrayClass)
Implementation of native method 'arrayBaseOffset'.
Definition Unsafe.cs:1458
static float getFloat(object self, long address)
Implementation of native method 'getFloat'.
Definition Unsafe.cs:1006
static unsafe void putBooleanVolatile(object self, object o, long offset, bool x)
Implementation of native method 'putBooleanVolatile'.
Definition Unsafe.cs:1993
static unsafe void putFloatVolatile(object self, object o, long offset, float x)
Implementation of native method 'putFloatVolatile'.
Definition Unsafe.cs:2316
static double getDouble(object self, object o, long offset)
Implementation of native method 'getDouble'.
Definition Unsafe.cs:721
static double getDoubleVolatile(object self, object o, long offset)
Implementation of native method 'getDoubleVolatile'.
Definition Unsafe.cs:2354
static void putObjectVolatile(object self, object o, long offset, object x)
Implementation of native method 'putObjectVolatile'.
Definition Unsafe.cs:1859
Provides utilities for working with dynamic methods.
Main state of the running JVM.
.NET exception that corresponds to a Java exception.
IDiagnosticHandler Diagnostics
Gets the IDiagnosticHandler where events should be sent.
RuntimeClassLoaderFactory ClassLoaderFactory
Gets the RuntimeClassLoaderFactory associated with this instance of the runtime.