2 * Copyright (C) 2014, United States Government, as represented by the
3 * Administrator of the National Aeronautics and Space Administration.
6 * The Java Pathfinder core (jpf-core) platform is licensed under the
7 * Apache License, Version 2.0 (the "License"); you may not use this file except
8 * in compliance with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0.
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package gov.nasa.jpf.vm;
20 import gov.nasa.jpf.JPFException;
21 import gov.nasa.jpf.annotation.MJI;
22 import gov.nasa.jpf.vm.ArrayFields;
23 import gov.nasa.jpf.vm.ElementInfo;
24 import gov.nasa.jpf.vm.FieldInfo;
25 import gov.nasa.jpf.vm.MJIEnv;
26 import gov.nasa.jpf.vm.NativePeer;
27 import gov.nasa.jpf.vm.SystemState;
28 import gov.nasa.jpf.vm.ThreadInfo;
32 * we don't want this class! This is a hodgepodge of stuff that shouldn't be in Java, but
33 * is handy for some hacks. The reason we have it here - very rudimentary - is that
34 * java.util.concurrent makes use of the atomic compare&swap which is in it.
35 * The choice was to duplicate a lot of relatively difficult code in the "right" class
36 * (java.util.concurrent.locks.AbstractQueuedSynchronizer) or a small amount of straight forward
37 * code in the "wrong" class (sun.misc.Unsafe). Knowing a bit about the "library chase" game,
38 * we opt for the latter
40 * <2do> this might change with better modeling of high level java.util.concurrent constructs
42 public class JPF_sun_misc_Unsafe extends NativePeer {
45 public int getUnsafe____Lsun_misc_Unsafe_2 (MJIEnv env, int clsRef) {
46 int objRef = env.getStaticReferenceField("sun.misc.Unsafe", "theUnsafe");
51 public long objectFieldOffset__Ljava_lang_reflect_Field_2__J (MJIEnv env, int unsafeRef, int fieldRef) {
52 return fieldOffset__Ljava_lang_reflect_Field_2__I(env, unsafeRef, fieldRef);
56 * we don't really return an offset here, since that would be useless. What we really want is
57 * to identify the corresponding FieldInfo, and that's much easier done with the Field
61 public int fieldOffset__Ljava_lang_reflect_Field_2__I (MJIEnv env, int unsafeRef, int fieldRef) {
62 //FieldInfo fi = JPF_java_lang_reflect_Field.getFieldInfo(env, fieldRef);
63 //return fi.getStorageOffset();
64 return env.getIntField(fieldRef, "regIdx");
68 public boolean compareAndSwapObject__Ljava_lang_Object_2JLjava_lang_Object_2Ljava_lang_Object_2__Z (MJIEnv env, int unsafeRef,
69 int objRef, long fieldOffset,
70 int expectRef, int updateRef) {
71 int actual = getObject__Ljava_lang_Object_2J__Ljava_lang_Object_2(env, unsafeRef, objRef, fieldOffset);
72 if (actual == expectRef) {
73 putObject__Ljava_lang_Object_2JLjava_lang_Object_2__V(env, unsafeRef, objRef, fieldOffset, updateRef);
80 public boolean compareAndSwapInt__Ljava_lang_Object_2JII__Z (MJIEnv env, int unsafeRef,
81 int objRef, long fieldOffset, int expect, int update) {
82 int actual = getInt__Ljava_lang_Object_2J__I(env, unsafeRef, objRef, fieldOffset);
83 if (actual == expect) {
84 putInt__Ljava_lang_Object_2JI__V(env, unsafeRef, objRef, fieldOffset, update);
91 public boolean compareAndSwapLong__Ljava_lang_Object_2JJJ__Z (MJIEnv env, int unsafeRef,
92 int objRef, long fieldOffset, long expect, long update) {
93 long actual = getLong__Ljava_lang_Object_2J__J(env, unsafeRef, objRef, fieldOffset);
94 if (actual == expect) {
95 putLong__Ljava_lang_Object_2JJ__V(env, unsafeRef, objRef, fieldOffset, update);
102 // this is a specialized, native wait() for the current thread that does not require a lock, and that can
103 // be turned off by a preceding unpark() call (which is not accumulative)
104 // park can be interrupted, but it doesn't throw an InterruptedException, and it doesn't clear the status
105 // it can only be called from the current (parking) thread
107 public void park__ZJ__V (MJIEnv env, int unsafeRef, boolean isAbsoluteTime, long timeout) {
108 ThreadInfo ti = env.getThreadInfo();
109 int objRef = ti.getThreadObjectRef();
110 int permitRef = env.getReferenceField( objRef, "permit");
111 ElementInfo ei = env.getModifiableElementInfo(permitRef);
113 if (ti.isInterrupted(false)) {
114 // there is no lock, so we go directly back to running and therefore
115 // have to remove ourself from the contender list
116 ei.setMonitorWithoutLocked(ti);
118 // note that park() does not throw an InterruptedException
122 if (!ti.isFirstStepInsn()){
123 if (ei.getBooleanField("blockPark")) { // we have to wait, but don't need a lock
124 // running -> waiting | timeout_waiting
125 ei.wait(ti, timeout, false);
128 ei.setBooleanField("blockPark", true); // re-arm for next park
134 if (ti.getScheduler().setsParkCG( ti, isAbsoluteTime, timeout)) {
135 env.repeatInvocation();
139 switch (ti.getState()) {
141 case TIMEOUT_WAITING:
142 throw new JPFException("blocking park() without transition break");
157 public void unpark__Ljava_lang_Object_2__V (MJIEnv env, int unsafeRef, int objRef) {
158 ThreadInfo tiCurrent = env.getThreadInfo();
159 ThreadInfo tiParked = env.getThreadInfoForObjRef(objRef);
161 if (tiParked.isTerminated()){
162 return; // nothing to do
165 if (!tiCurrent.isFirstStepInsn()){
166 SystemState ss = env.getSystemState();
167 int permitRef = env.getReferenceField( objRef, "permit");
168 ElementInfo eiPermit = env.getModifiableElementInfo(permitRef);
170 if (tiParked.getLockObject() == eiPermit){
171 // note that 'permit' is only used in park/unpark, so there never is more than
172 // one waiter, which immediately becomes runnable again because it doesn't hold a lock
173 // (park is a lockfree wait). unpark() therefore has to be a right mover
174 // and we have to register a ThreadCG here
175 eiPermit.notifies(ss, tiCurrent, false);
178 eiPermit.setBooleanField("blockPark", false);
183 if (tiCurrent.getScheduler().setsUnparkCG(tiCurrent, tiParked)){
184 env.repeatInvocation();
190 public void ensureClassInitialized__Ljava_lang_Class_2__V (MJIEnv env, int unsafeRef, int clsObjRef) {
191 // <2do> not sure if we have to do anyting here - if we have a class object, the class should already
196 public int getObject__Ljava_lang_Object_2J__Ljava_lang_Object_2 (MJIEnv env, int unsafeRef,
197 int objRef, long fieldOffset) {
198 ElementInfo ei = env.getElementInfo(objRef);
200 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
201 return ei.getReferenceField(fi);
203 return ei.getReferenceElement((int)fieldOffset);
208 public int getObjectVolatile__Ljava_lang_Object_2J__Ljava_lang_Object_2 (MJIEnv env, int unsafeRef,
209 int objRef, long fieldOffset) {
210 return getObject__Ljava_lang_Object_2J__Ljava_lang_Object_2( env, unsafeRef, objRef, fieldOffset);
214 public void putObject__Ljava_lang_Object_2JLjava_lang_Object_2__V (MJIEnv env, int unsafeRef,
215 int objRef, long fieldOffset, int valRef) {
216 ElementInfo ei = env.getModifiableElementInfo(objRef);
219 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
220 ei.setReferenceField(fi, valRef);
222 ei.setReferenceElement((int)fieldOffset, valRef);
227 public void putObjectVolatile__Ljava_lang_Object_2JLjava_lang_Object_2__V (MJIEnv env, int unsafeRef,
228 int objRef, long fieldOffset, int valRef) {
229 putObject__Ljava_lang_Object_2JLjava_lang_Object_2__V( env, unsafeRef, objRef, fieldOffset, valRef);
233 public void putOrderedObject__Ljava_lang_Object_2JLjava_lang_Object_2__V(
239 putObject__Ljava_lang_Object_2JLjava_lang_Object_2__V(env, unsafeRef, objRef, fieldOffset, valRef);
243 public boolean getBoolean__Ljava_lang_Object_2J__Z(MJIEnv env,
247 ElementInfo ei = env.getElementInfo(objRef);
249 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
250 return ei.getBooleanField(fi);
252 return ei.getBooleanElement((int)fieldOffset);
257 public boolean getBooleanVolatile__Ljava_lang_Object_2J__Z(MJIEnv env, int unsafeRef,int objRef,long fieldOffset) {
258 return getBoolean__Ljava_lang_Object_2J__Z( env, unsafeRef, objRef, fieldOffset);
262 public void putBoolean__Ljava_lang_Object_2JZ__V (MJIEnv env, int unsafeRef,
263 int objRef, long fieldOffset, boolean val){
264 ElementInfo ei = env.getModifiableElementInfo(objRef);
266 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
267 ei.setBooleanField(fi, val);
269 ei.setBooleanElement((int)fieldOffset, val);
274 public void putBooleanVolatile__Ljava_lang_Object_2JZ__V (MJIEnv env, int unsafeRef, int objRef, long fieldOffset, boolean val){
275 putBoolean__Ljava_lang_Object_2JZ__V( env, unsafeRef, objRef, fieldOffset, val);
279 public byte getByte__Ljava_lang_Object_2J__B(MJIEnv env,
283 ElementInfo ei = env.getElementInfo(objRef);
285 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
286 return ei.getByteField(fi);
288 return ei.getByteElement((int)fieldOffset);
293 public byte getByteVolatile__Ljava_lang_Object_2J__B(MJIEnv env,int unsafeRef,int objRef,long fieldOffset) {
294 return getByte__Ljava_lang_Object_2J__B(env, unsafeRef, objRef, fieldOffset);
298 public void putByte__Ljava_lang_Object_2JB__V (MJIEnv env, int unsafeRef,
299 int objRef, long fieldOffset, byte val){
300 ElementInfo ei = env.getModifiableElementInfo(objRef);
302 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
303 ei.setByteField(fi, val);
305 ei.setByteElement((int)fieldOffset, val);
310 public void putByteVolatile__Ljava_lang_Object_2JB__V (MJIEnv env, int unsafeRef,int objRef, long fieldOffset, byte val){
311 putByte__Ljava_lang_Object_2JB__V( env, unsafeRef, objRef, fieldOffset, val);
315 public char getChar__Ljava_lang_Object_2J__C(MJIEnv env,
319 ElementInfo ei = env.getElementInfo(objRef);
321 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
322 return ei.getCharField(fi);
324 return ei.getCharElement((int)fieldOffset);
329 public char getCharVolatile__Ljava_lang_Object_2J__C(MJIEnv env,int unsafeRef,int objRef,long fieldOffset) {
330 return getChar__Ljava_lang_Object_2J__C( env, unsafeRef, objRef, fieldOffset);
334 public void putChar__Ljava_lang_Object_2JC__V (MJIEnv env, int unsafeRef,
335 int objRef, long fieldOffset, char val){
336 ElementInfo ei = env.getModifiableElementInfo(objRef);
338 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
339 ei.setCharField(fi, val);
341 ei.setCharElement((int)fieldOffset, val);
346 public void putCharVolatile__Ljava_lang_Object_2JC__V (MJIEnv env, int unsafeRef,int objRef, long fieldOffset, char val){
347 putChar__Ljava_lang_Object_2JC__V( env, unsafeRef, objRef, fieldOffset, val);
351 public short getShort__Ljava_lang_Object_2J__S(MJIEnv env,
355 ElementInfo ei = env.getElementInfo(objRef);
357 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
358 return ei.getShortField(fi);
360 return ei.getShortElement((int)fieldOffset);
365 public short getShortVolatile__Ljava_lang_Object_2J__S(MJIEnv env,int unsafeRef,int objRef,long fieldOffset) {
366 return getShort__Ljava_lang_Object_2J__S( env, unsafeRef, objRef, fieldOffset);
370 public void putShort__Ljava_lang_Object_2JS__V (MJIEnv env, int unsafeRef,
371 int objRef, long fieldOffset, short val){
372 ElementInfo ei = env.getModifiableElementInfo(objRef);
374 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
375 ei.setShortField(fi, val);
377 ei.setShortElement((int)fieldOffset, val);
382 public void putShortVolatile__Ljava_lang_Object_2JS__V (MJIEnv env, int unsafeRef,int objRef, long fieldOffset, short val){
383 putShort__Ljava_lang_Object_2JS__V( env, unsafeRef, objRef, fieldOffset, val);
387 public int getInt__Ljava_lang_Object_2J__I(MJIEnv env, int unsafeRef,
388 int objRef, long fieldOffset) {
389 ElementInfo ei = env.getElementInfo(objRef);
391 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
392 return ei.getIntField(fi);
394 return ei.getIntElement((int)fieldOffset);
399 public int getIntVolatile__Ljava_lang_Object_2J__I(MJIEnv env, int unsafeRef, int objRef, long fieldOffset) {
400 return getInt__Ljava_lang_Object_2J__I( env, unsafeRef, objRef, fieldOffset);
404 public void putInt__Ljava_lang_Object_2JI__V (MJIEnv env, int unsafeRef,
405 int objRef, long fieldOffset, int val){
406 ElementInfo ei = env.getModifiableElementInfo(objRef);
408 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
409 ei.setIntField(fi, val);
411 ei.setIntElement((int)fieldOffset, val);
416 public void putIntVolatile__Ljava_lang_Object_2JI__V (MJIEnv env, int unsafeRef, int objRef, long fieldOffset, int val){
417 putInt__Ljava_lang_Object_2JI__V(env, unsafeRef, objRef, fieldOffset, val);
421 public void putOrderedInt__Ljava_lang_Object_2JI__V(MJIEnv env,
427 putInt__Ljava_lang_Object_2JI__V(env, unsafeRef, objRef, fieldOffset, val);
431 public float getFloat__Ljava_lang_Object_2J__F(MJIEnv env,
435 ElementInfo ei = env.getElementInfo(objRef);
437 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
438 return ei.getFloatField(fi);
440 return ei.getFloatElement((int)fieldOffset);
445 public float getFloatVolatile__Ljava_lang_Object_2J__F(MJIEnv env,int unsafeRef,int objRef,long fieldOffset) {
446 return getFloat__Ljava_lang_Object_2J__F( env, unsafeRef, objRef, fieldOffset);
450 public void putFloat__Ljava_lang_Object_2JF__V (MJIEnv env, int unsafeRef,
451 int objRef, long fieldOffset, float val){
452 ElementInfo ei = env.getModifiableElementInfo(objRef);
454 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
455 ei.setFloatField(fi, val);
457 ei.setFloatElement((int)fieldOffset, val);
462 public void putFloatVolatile__Ljava_lang_Object_2JF__V (MJIEnv env, int unsafeRef,int objRef, long fieldOffset, float val){
463 putFloat__Ljava_lang_Object_2JF__V( env, unsafeRef, objRef, fieldOffset, val);
467 public long getLong__Ljava_lang_Object_2J__J(MJIEnv env,
471 ElementInfo ei = env.getElementInfo(objRef);
473 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
474 return ei.getLongField(fi);
476 return ei.getLongElement((int)fieldOffset);
481 public long getLongVolatile__Ljava_lang_Object_2J__J(MJIEnv env, int unsafeRef, int objRef, long fieldOffset) {
482 return getLong__Ljava_lang_Object_2J__J( env, unsafeRef, objRef, fieldOffset);
486 public void putLong__Ljava_lang_Object_2JJ__V (MJIEnv env, int unsafeRef,
487 int objRef, long fieldOffset, long val){
488 ElementInfo ei = env.getModifiableElementInfo(objRef);
490 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
491 ei.setLongField(fi, val);
493 ei.setLongElement((int)fieldOffset, val);
498 public void putLongVolatile__Ljava_lang_Object_2JJ__V (MJIEnv env, int unsafeRef, int objRef, long fieldOffset, long val){
499 putLong__Ljava_lang_Object_2JJ__V( env, unsafeRef, objRef, fieldOffset, val);
503 public void putOrderedLong__Ljava_lang_Object_2JJ__V (MJIEnv env, int unsafeRef,
504 int objRef, long fieldOffset, long val) {
505 putLong__Ljava_lang_Object_2JJ__V(env, unsafeRef, objRef, fieldOffset, val);
509 public double getDouble__Ljava_lang_Object_2J__D(MJIEnv env,
513 ElementInfo ei = env.getElementInfo(objRef);
515 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
516 return ei.getDoubleField(fi);
518 return ei.getDoubleElement((int)fieldOffset);
523 public double getDoubleVolatile__Ljava_lang_Object_2J__D(MJIEnv env,int unsafeRef,int objRef,long fieldOffset) {
524 return getDouble__Ljava_lang_Object_2J__D( env, unsafeRef, objRef, fieldOffset);
528 public void putDouble__Ljava_lang_Object_2JD__V (MJIEnv env, int unsafeRef,
529 int objRef, long fieldOffset, double val){
530 ElementInfo ei = env.getModifiableElementInfo(objRef);
532 FieldInfo fi = getRegisteredFieldInfo(fieldOffset);
533 ei.setDoubleField(fi, val);
535 ei.setDoubleElement((int)fieldOffset, val);
540 public void putDoubleVolatile__Ljava_lang_Object_2JD__V (MJIEnv env, int unsafeRef, int objRef, long fieldOffset, double val){
541 putDouble__Ljava_lang_Object_2JD__V( env, unsafeRef, objRef, fieldOffset, val);
545 public int arrayBaseOffset__Ljava_lang_Class_2__I (MJIEnv env, int unsafeRef, int clazz) {
550 public int arrayIndexScale__Ljava_lang_Class_2__I (MJIEnv env, int unsafeRef, int clazz) {
554 private static FieldInfo getRegisteredFieldInfo(long fieldOffset) {
555 return JPF_java_lang_reflect_Field.getRegisteredFieldInfo((int)fieldOffset);
559 //--- the explicit memory buffer allocation/free + access methods - evil pointer arithmetic
562 * we shy away from maintaining our own address table by means of knowing that
563 * the byte[] object stored in the ArrayFields will not be recycled, and hashCode() will
564 * return its address, so the start/endAdr pairs we get from that have to be
565 * non-overlapping. Of course that falls apart if hashCode() would do something
566 * different, which is the case for any address that exceeds 32bit
577 Alloc (MJIEnv env, int baRef, long length){
580 ElementInfo ei = env.getElementInfo(baRef);
581 ArrayFields afi = (ArrayFields) ei.getFields();
582 byte[] mem = afi.asByteArray();
584 startAdr = mem.hashCode();
585 endAdr = startAdr + (int)length -1;
589 public String toString(){
590 return String.format("Alloc[objRef=%x,startAdr=%x,endAdr=%x]", objRef, startAdr, endAdr);
596 // for debugging purposes only
597 private void dumpAllocs(){
598 System.out.println("Unsafe allocated memory blocks:{");
599 for (Alloc a = firstAlloc; a != null; a = a.next){
600 System.out.print(" ");
601 System.out.println(a);
603 System.out.println('}');
606 private void sortInAlloc(Alloc newAlloc){
607 int startAdr = newAlloc.startAdr;
609 if (firstAlloc == null){
610 firstAlloc = newAlloc;
614 for (Alloc a = firstAlloc; a != null; prev = a, a = a.next){
615 if (startAdr < a.startAdr){
618 firstAlloc = newAlloc;
620 prev.next = newAlloc;
627 private Alloc getAlloc (int address){
628 for (Alloc a = firstAlloc; a != null; a = a.next){
629 if (address >= a.startAdr && address <= a.endAdr){
637 private Alloc removeAlloc (int startAddress){
639 for (Alloc a = firstAlloc; a != null; prev = a, a = a.next) {
640 if (a.startAdr == startAddress){
655 public long allocateMemory__J__J (MJIEnv env, int unsafeRef, long nBytes) {
656 if (nBytes < 0 || nBytes > Integer.MAX_VALUE) {
657 env.throwException("java.lang.IllegalArgumentException", "invalid memory block size: " + nBytes);
661 // <2do> we should probably also throw OutOfMemoryErrors on configured thresholds
663 int baRef = env.newByteArray((int) nBytes);
664 // the corresponding objects have to be freed explicitly
665 env.registerPinDown(baRef);
667 Alloc alloc = new Alloc(env, baRef, nBytes);
670 return alloc.startAdr;
674 public void freeMemory__J__V (MJIEnv env, int unsafeRef, long startAddress) {
675 int addr = (int)startAddress;
677 if (startAddress != MJIEnv.NULL){
678 Alloc a = removeAlloc(addr);
680 env.throwException("java.lang.IllegalArgumentException", "invalid memory address: " + Integer.toHexString(addr));
682 env.releasePinDown(a.objRef);
688 public byte getByte__J__B (MJIEnv env, int unsafeRef, long address) {
689 int addr = (int)address;
690 Alloc a = getAlloc(addr);
693 env.throwException("java.lang.IllegalArgumentException", "invalid memory address: " + Integer.toHexString(addr));
697 ElementInfo ei = env.getElementInfo(a.objRef);
698 return ei.getByteElement(addr - a.startAdr);
702 public void putByte__JB__V (MJIEnv env, int unsafeRef, long address, byte val) {
703 int addr = (int)address;
704 Alloc a = getAlloc(addr);
707 env.throwException("java.lang.IllegalArgumentException", "invalid memory address: " + Integer.toHexString(addr));
711 ElementInfo ei = env.getModifiableElementInfo(a.objRef);
712 ei.setByteElement(addr - a.startAdr, val);
716 public char getChar__J__C (MJIEnv env, int unsafeRef, long address) {
717 int addr = (int)address;
718 Alloc a = getAlloc(addr);
721 env.throwException("java.lang.IllegalArgumentException", "invalid memory address: " + Integer.toHexString(addr));
725 ElementInfo ei = env.getElementInfo(a.objRef);
726 byte[] ba = ei.asByteArray();
729 byte b1 = ba[addr+1];
732 if (env.isBigEndianPlatform()){
733 val = (char) ((b0 << 8) | b1);
735 val = (char) ((b1 << 8) | b0);
742 public void putChar__JC__V (MJIEnv env, int unsafeRef, long address, char val) {
743 int addr = (int)address;
744 Alloc a = getAlloc(addr);
747 env.throwException("java.lang.IllegalArgumentException", "invalid memory address: " + Integer.toHexString(addr));
751 byte b1 = (byte)(0xff & val);
752 byte b0 = (byte)(0xff & (val >>> 8));
754 ElementInfo ei = env.getModifiableElementInfo(a.objRef);
756 if (env.isBigEndianPlatform()){
757 ei.setByteElement(addr, b0);
758 ei.setByteElement(addr+1, b1);
760 ei.setByteElement(addr, b1);
761 ei.setByteElement(addr+1, b0);
766 public int getInt__J__I (MJIEnv env, int unsafeRef, long address) {
767 int addr = (int)address;
768 Alloc a = getAlloc(addr);
771 env.throwException("java.lang.IllegalArgumentException", "invalid memory address: " + Integer.toHexString(addr));
775 ElementInfo ei = env.getElementInfo(a.objRef);
776 byte[] ba = ei.asByteArray();
779 byte b1 = ba[addr+1];
780 byte b2 = ba[addr+2];
781 byte b3 = ba[addr+3];
784 if (env.isBigEndianPlatform()){
786 val = (val << 8) | b1;
787 val = (val << 8) | b2;
788 val = (val << 8) | b3;
792 val = (val << 8) | b2;
793 val = (val << 8) | b1;
794 val = (val << 8) | b0;
801 public void putInt__JI__V (MJIEnv env, int unsafeRef, long address, int val) {
802 int addr = (int)address;
803 Alloc a = getAlloc(addr);
806 env.throwException("java.lang.IllegalArgumentException", "invalid memory address: " + Integer.toHexString(addr));
810 byte b3 = (byte)(0xff & val);
811 byte b2 = (byte)(0xff & (val >>> 8));
812 byte b1 = (byte)(0xff & (val >>> 16));
813 byte b0 = (byte)(0xff & (val >>> 24));
815 ElementInfo ei = env.getModifiableElementInfo(a.objRef);
817 if (env.isBigEndianPlatform()){
818 ei.setByteElement(addr, b0);
819 ei.setByteElement(addr+1, b1);
820 ei.setByteElement(addr+2, b2);
821 ei.setByteElement(addr+3, b3);
823 ei.setByteElement(addr, b3);
824 ei.setByteElement(addr+1, b2);
825 ei.setByteElement(addr+2, b1);
826 ei.setByteElement(addr+3, b0);
831 public long getLong__J__J (MJIEnv env, int unsafeRef, long address) {
832 int addr = (int)address;
833 Alloc a = getAlloc(addr);
836 env.throwException("java.lang.IllegalArgumentException", "invalid memory address: " + Integer.toHexString(addr));
840 ElementInfo ei = env.getElementInfo(a.objRef);
841 byte[] ba = ei.asByteArray();
842 int offset = addr - a.startAdr;
844 byte b0 = ba[offset];
845 byte b1 = ba[offset+1];
846 byte b2 = ba[offset+2];
847 byte b3 = ba[offset+3];
848 byte b4 = ba[offset+4];
849 byte b5 = ba[offset+5];
850 byte b6 = ba[offset+6];
851 byte b7 = ba[offset+7];
854 if (env.isBigEndianPlatform()){
856 val = (val << 8) | b1;
857 val = (val << 8) | b2;
858 val = (val << 8) | b3;
859 val = (val << 8) | b4;
860 val = (val << 8) | b5;
861 val = (val << 8) | b6;
862 val = (val << 8) | b7;
866 val = (val << 8) | b6;
867 val = (val << 8) | b5;
868 val = (val << 8) | b4;
869 val = (val << 8) | b3;
870 val = (val << 8) | b2;
871 val = (val << 8) | b1;
872 val = (val << 8) | b0;
879 public void putLong__JJ__V (MJIEnv env, int unsafeRef, long address, long val) {
880 int addr = (int)address;
881 Alloc a = getAlloc(addr);
884 env.throwException("java.lang.IllegalArgumentException", "invalid memory address: " + Integer.toHexString(addr));
888 byte b7 = (byte)(0xff & val);
889 byte b6 = (byte)(0xff & (val >>> 8));
890 byte b5 = (byte)(0xff & (val >>> 16));
891 byte b4 = (byte)(0xff & (val >>> 24));
892 byte b3 = (byte)(0xff & (val >>> 32));
893 byte b2 = (byte)(0xff & (val >>> 40));
894 byte b1 = (byte)(0xff & (val >>> 48));
895 byte b0 = (byte)(0xff & (val >>> 56));
897 ElementInfo ei = env.getModifiableElementInfo(a.objRef);
898 int offset = addr - a.startAdr;
900 if (env.isBigEndianPlatform()){
901 ei.setByteElement(offset, b0);
902 ei.setByteElement(offset+1, b1);
903 ei.setByteElement(offset+2, b2);
904 ei.setByteElement(offset+3, b3);
905 ei.setByteElement(offset+4, b4);
906 ei.setByteElement(offset+5, b5);
907 ei.setByteElement(offset+6, b6);
908 ei.setByteElement(offset+7, b7);
911 ei.setByteElement(offset, b7);
912 ei.setByteElement(offset+1, b6);
913 ei.setByteElement(offset+2, b5);
914 ei.setByteElement(offset+3, b4);
915 ei.setByteElement(offset+4, b3);
916 ei.setByteElement(offset+5, b2);
917 ei.setByteElement(offset+6, b1);
918 ei.setByteElement(offset+7, b0);