/** * Low level copy of <code>len</code> elements from <code>src[srcPos]</code> to <code>dst[dstPos] * </code>. * * <p>Assumption <code>src != dst || (srcPos >= dstPos)</code> and element size is 8 bytes. * * @param src the source array * @param srcIdx index in the source array to begin copy * @param dst the destination array * @param dstIdx index in the destination array to being copy * @param len number of array elements to copy */ @Inline public static void arraycopy64Bit(Object src, int srcIdx, Object dst, int dstIdx, int len) { Address srcPtr = VM_Magic.objectAsAddress(src).plus(srcIdx << LOG_BYTES_IN_DOUBLE); Address dstPtr = VM_Magic.objectAsAddress(dst).plus(dstIdx << LOG_BYTES_IN_DOUBLE); int copyBytes = len << LOG_BYTES_IN_DOUBLE; if (USE_NATIVE && len > (NATIVE_THRESHOLD >> LOG_BYTES_IN_DOUBLE)) { memcopy(dstPtr, srcPtr, copyBytes); } else { // The elements of long[] and double[] are always doubleword aligned // therefore we can do 64 bit load/stores without worrying about alignment. Address endPtr = srcPtr.plus(copyBytes); while (srcPtr.LT(endPtr)) { // We generate abysmal code on IA32 if we try to use the FP registers, // so use the gprs instead even though it results in more instructions. if (VM.BuildForIA32) { dstPtr.store(srcPtr.loadInt()); dstPtr.store(srcPtr.loadInt(Offset.fromIntSignExtend(4)), Offset.fromIntSignExtend(4)); } else { dstPtr.store(srcPtr.loadDouble()); } srcPtr = srcPtr.plus(8); dstPtr = dstPtr.plus(8); } } }
// - overrides Thread // public void run() { int tid = VM_Magic.getThreadIdRegister() >> VM_ObjectLayoutConstants.OBJECT_THREAD_ID_SHIFT; int retval = 0; int loopcntr = 75; float fp = (float) 17.8; if (name == "pong") loopcntr = 75; for (int i = 0; i < loopcntr; ++i) { if ((name == "ping") || (name == "ping2")) { // call a native function say(name, "calling nativeFoo"); retval = tNativeThreads.nativeFoo(VM_Processor.getCurrentProcessor().id); // retval = tNativeThreads.nativeFoo(tid); //// System.out.println(1.0f); say(name, "return from nativeFoo"); // VM.debugBreakpoint(); // try to print a string // say(name, " before s created"); // String s = java.lang.Float.toString(fp); // say(name, " after s created"); // String s2 = " return value = " + s; // say(name, s2); // try { // say(name, "sleeping"); // sleep(300); // } // catch (InterruptedException e) {} } else { // pong story // others sleep for a while and then call java function say(name, "about to sleep for 100 msec"); try { say(name, "sleeping"); sleep(100); } catch (InterruptedException e) { } say(name, "after sleep -calling javaFoo"); retval = tNativeThreads.javaFoo(10); say(name, "return from javaFoo"); } if (name == "pong") { // someone calls gc say(name, "about to call gc"); // say(name, "first dump VM"); // VM_Scheduler.dumpVirtualMachine(); // say(name, "skipping gc"); System.gc(); say(name, "gc completed"); } } // test complete /// say(name, "dump before -bye"); /// VM_Scheduler.dumpVirtualMachine(); say(name, "complete -bye"); isFinished = true; }
/** * Low level copy of <code>len</code> elements from <code>src[srcPos]</code> to <code>dst[dstPos] * </code>. * * <p>Assumption: <code>src != dst || (srcPos >= dstPos)</code> and element size is 4 bytes. * * @param src the source array * @param srcIdx index in the source array to begin copy * @param dst the destination array * @param dstIdx index in the destination array to being copy * @param len number of array elements to copy */ @Inline public static void arraycopy32Bit(Object src, int srcIdx, Object dst, int dstIdx, int len) { Address srcPtr = VM_Magic.objectAsAddress(src).plus(srcIdx << LOG_BYTES_IN_INT); Address dstPtr = VM_Magic.objectAsAddress(dst).plus(dstIdx << LOG_BYTES_IN_INT); int copyBytes = len << LOG_BYTES_IN_INT; if (USE_NATIVE && len > (NATIVE_THRESHOLD >> LOG_BYTES_IN_INT)) { memcopy(dstPtr, srcPtr, copyBytes); } else { // The elements of int[] and float[] are always 32 bit aligned // therefore we can do 32 bit load/stores without worrying about alignment. // TODO: do measurements to determine if on PPC it is a good idea to check // for compatible doubleword alignment and handle that case via the FPRs in 64 bit // chunks. // Unclear if this will be a big enough win to justify checking because for big copies // we are going into memcopy anyways and that will be faster than anything we do here. Address endPtr = srcPtr.plus(copyBytes); while (srcPtr.LT(endPtr)) { dstPtr.store(srcPtr.loadInt()); srcPtr = srcPtr.plus(4); dstPtr = dstPtr.plus(4); } } }
/** * Load a dynamic library and maintain it in this object. * * @param libraryName library name */ private VM_DynamicLibrary(String libraryName) { // Convert file name from unicode to filesystem character set. // (Assume file name is ASCII, for now). // byte[] asciiName = VM_StringUtilities.stringToBytesNullTerminated(libraryName); // make sure we have enough stack to load the library. // This operation has been known to require more than 20K of stack. VM_Thread myThread = VM_Scheduler.getCurrentThread(); Offset remaining = VM_Magic.getFramePointer().diff(myThread.stackLimit); int stackNeededInBytes = VM_StackframeLayoutConstants.STACK_SIZE_DLOPEN - remaining.toInt(); if (stackNeededInBytes > 0) { if (myThread.hasNativeStackFrame()) { throw new java.lang.StackOverflowError("dlopen"); } else { VM_Thread.resizeCurrentStack(myThread.getStackLength() + stackNeededInBytes, null); } } libHandler = VM_SysCall.sysCall.sysDlopen(asciiName); if (libHandler.isZero()) { VM.sysWriteln("error loading library: " + libraryName); throw new UnsatisfiedLinkError(); } libName = libraryName; try { callOnLoad(); } catch (UnsatisfiedLinkError e) { unload(); throw e; } if (VM.verboseJNI) { VM.sysWriteln("[Loaded native library: " + libName + "]"); } }
/** * Low level copy of len elements from src[srcPos] to dst[dstPos]. * * <p>Assumptions: <code> src != dst || (scrPos >= dstPos + 4) </code> and src and dst are 8Bit * arrays. * * @param src the source array * @param srcPos index in the source array to begin copy * @param dst the destination array * @param dstPos index in the destination array to being copy * @param len number of array elements to copy */ @Inline public static void arraycopy8Bit(Object src, int srcPos, Object dst, int dstPos, int len) { if (USE_NATIVE && len > NATIVE_THRESHOLD) { memcopy( VM_Magic.objectAsAddress(dst).plus(dstPos), VM_Magic.objectAsAddress(src).plus(srcPos), len); } else { if (len >= BYTES_IN_ADDRESS && (srcPos & (BYTES_IN_ADDRESS - 1)) == (dstPos & (BYTES_IN_ADDRESS - 1))) { // relative alignment is the same int byteStart = srcPos; int wordStart = alignUp(srcPos, BYTES_IN_ADDRESS); int wordEnd = alignDown(srcPos + len, BYTES_IN_ADDRESS); int byteEnd = srcPos + len; int startDiff = wordStart - byteStart; int endDiff = byteEnd - wordEnd; int wordLen = wordEnd - wordStart; Address srcPtr = VM_Magic.objectAsAddress(src).plus(srcPos + startDiff); Address dstPtr = VM_Magic.objectAsAddress(dst).plus(dstPos + startDiff); if (VM.BuildFor64Addr) { switch (startDiff) { case 7: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(-7)), Offset.fromIntSignExtend(-7)); case 6: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(-6)), Offset.fromIntSignExtend(-6)); case 5: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(-5)), Offset.fromIntSignExtend(-5)); case 4: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(-4)), Offset.fromIntSignExtend(-4)); case 3: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(-3)), Offset.fromIntSignExtend(-3)); case 2: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(-2)), Offset.fromIntSignExtend(-2)); case 1: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(-1)), Offset.fromIntSignExtend(-1)); } } else { switch (startDiff) { case 3: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(-3)), Offset.fromIntSignExtend(-3)); case 2: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(-2)), Offset.fromIntSignExtend(-2)); case 1: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(-1)), Offset.fromIntSignExtend(-1)); } } Address endPtr = srcPtr.plus(wordLen); while (srcPtr.LT(endPtr)) { dstPtr.store(srcPtr.loadWord()); srcPtr = srcPtr.plus(BYTES_IN_ADDRESS); dstPtr = dstPtr.plus(BYTES_IN_ADDRESS); } if (VM.BuildFor64Addr) { switch (endDiff) { case 7: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(6)), Offset.fromIntSignExtend(6)); case 6: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(5)), Offset.fromIntSignExtend(5)); case 5: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(4)), Offset.fromIntSignExtend(4)); case 4: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(3)), Offset.fromIntSignExtend(3)); case 3: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(2)), Offset.fromIntSignExtend(2)); case 2: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(1)), Offset.fromIntSignExtend(1)); case 1: dstPtr.store(srcPtr.loadByte()); } } else { switch (endDiff) { case 3: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(2)), Offset.fromIntSignExtend(2)); case 2: dstPtr.store( srcPtr.loadByte(Offset.fromIntSignExtend(1)), Offset.fromIntSignExtend(1)); case 1: dstPtr.store(srcPtr.loadByte()); } } } else { Address srcPtr = VM_Magic.objectAsAddress(src).plus(srcPos); Address dstPtr = VM_Magic.objectAsAddress(dst).plus(dstPos); Address endPtr = srcPtr.plus(len); while (srcPtr.LT(endPtr)) { dstPtr.store(srcPtr.loadByte()); srcPtr = srcPtr.plus(1); dstPtr = dstPtr.plus(1); } } } }
public static void memcopy(LocalAddress dst, LocalAddress src, int cnt) { VM_SysCall.sysCall.sysCopy( VM_Magic.localAddressAsAddress(dst), VM_Magic.localAddressAsAddress(src), Extent.fromIntSignExtend(cnt)); }
/** * Copy a region of local memory. * * @param dst Destination address * @param src Source address * @param cnt Number of bytes to copy Assumption: source and destination regions do not overlap */ public static void memcopy(LocalAddress dst, LocalAddress src, Extent cnt) { VM_SysCall.sysCall.sysCopy( VM_Magic.localAddressAsAddress(dst), VM_Magic.localAddressAsAddress(src), cnt); }
/** * Low level copy of len elements from src[srcPos] to dst[dstPos]. * * <p>Assumption src != dst || (srcPos >= dstPos + 2). * * @param src the source array * @param srcPos index in the source array to begin copy * @param dst the destination array * @param dstPos index in the destination array to being copy * @param len number of array elements to copy */ @Inline public static void arraycopy16Bit(Object src, int srcPos, Object dst, int dstPos, int len) { if (USE_NATIVE && len > (NATIVE_THRESHOLD >> LOG_BYTES_IN_SHORT)) { memcopy( VM_Magic.objectAsAddress(dst).plus(dstPos << LOG_BYTES_IN_SHORT), VM_Magic.objectAsAddress(src).plus(srcPos << LOG_BYTES_IN_SHORT), len << LOG_BYTES_IN_SHORT); } else { if (len >= (BYTES_IN_ADDRESS >>> LOG_BYTES_IN_SHORT) && (srcPos & ((BYTES_IN_ADDRESS - 1) >>> LOG_BYTES_IN_SHORT)) == (dstPos & ((BYTES_IN_ADDRESS - 1) >>> LOG_BYTES_IN_SHORT))) { // relative alignment is the same int byteStart = srcPos << LOG_BYTES_IN_SHORT; int wordStart = alignUp(byteStart, BYTES_IN_ADDRESS); int wordEnd = alignDown(byteStart + (len << LOG_BYTES_IN_SHORT), BYTES_IN_ADDRESS); int byteEnd = byteStart + (len << LOG_BYTES_IN_SHORT); int startDiff = wordStart - byteStart; int endDiff = byteEnd - wordEnd; int wordLen = wordEnd - wordStart; Address srcPtr = VM_Magic.objectAsAddress(src).plus((srcPos << LOG_BYTES_IN_SHORT) + startDiff); Address dstPtr = VM_Magic.objectAsAddress(dst).plus((dstPos << LOG_BYTES_IN_SHORT) + startDiff); if (VM.BuildFor64Addr) { switch (startDiff) { case 6: dstPtr.store( srcPtr.loadChar(Offset.fromIntSignExtend(-6)), Offset.fromIntSignExtend(-6)); case 4: dstPtr.store( srcPtr.loadChar(Offset.fromIntSignExtend(-4)), Offset.fromIntSignExtend(-4)); case 2: dstPtr.store( srcPtr.loadChar(Offset.fromIntSignExtend(-2)), Offset.fromIntSignExtend(-2)); } } else { if (startDiff == 2) { dstPtr.store( srcPtr.loadChar(Offset.fromIntSignExtend(-2)), Offset.fromIntSignExtend(-2)); } } Address endPtr = srcPtr.plus(wordLen); while (srcPtr.LT(endPtr)) { dstPtr.store(srcPtr.loadWord()); srcPtr = srcPtr.plus(BYTES_IN_ADDRESS); dstPtr = dstPtr.plus(BYTES_IN_ADDRESS); } if (VM.BuildFor64Addr) { switch (endDiff) { case 6: dstPtr.store( srcPtr.loadChar(Offset.fromIntSignExtend(4)), Offset.fromIntSignExtend(4)); case 4: dstPtr.store( srcPtr.loadChar(Offset.fromIntSignExtend(2)), Offset.fromIntSignExtend(2)); case 2: dstPtr.store(srcPtr.loadChar()); } } else { if (endDiff == 2) { dstPtr.store(srcPtr.loadChar()); } } } else { Address srcPtr = VM_Magic.objectAsAddress(src).plus(srcPos << LOG_BYTES_IN_CHAR); Address dstPtr = VM_Magic.objectAsAddress(dst).plus(dstPos << LOG_BYTES_IN_CHAR); Address endPtr = srcPtr.plus(len << LOG_BYTES_IN_CHAR); while (srcPtr.LT(endPtr)) { dstPtr.store(srcPtr.loadChar()); srcPtr = srcPtr.plus(2); dstPtr = dstPtr.plus(2); } } } }