mozilla / pluotsorbet

[ARCHIVED] PluotSorbet is a J2ME-compatible virtual machine written in JavaScript.
GNU General Public License v2.0
238 stars 46 forks source link

Optimize array copies. #1792

Open mbebenita opened 9 years ago

mbebenita commented 9 years ago

We implement unchecked array copies as:

Native["com/sun/cldchi/jvm/JVM.unchecked_char_arraycopy.([CI[CII)V"] =
function(addr, srcAddr, srcOffset, dstAddr, dstOffset, length) {
  var src = J2ME.getArrayFromAddr(srcAddr);
  var dst = J2ME.getArrayFromAddr(dstAddr);
  dst.set(src.subarray(srcOffset, srcOffset + length), dstOffset);
};

We could implemented it directly as:

Native["com/sun/cldchi/jvm/JVM.unchecked_char_arraycopy.([CI[CII)V"] =
function(addr, srcAddr, srcOffset, dstAddr, dstOffset, length) {
  var src = (srcAddr + 8 >> 1) + srcOffset;
  var dst = (dstAddr + 8 >> 1) + dstOffset;
  for (var i = 0; i < length; i++) {
    i16[dst++] = i16[src++];
  }
};

This speeds up the following microbenchmark by 2X:

for (int k = 0; k < 100000; k++) {
  Double.parseDouble(Double.toString(k));
}
mbebenita commented 9 years ago

We can still use set w/ subarray, but on the i16 array.

mbebenita commented 9 years ago

This is great! However, java/lang/System.arraycopy needs a similar treatment. In DataInputOutputStreamBench it is responsible for much of the execution time. I prototyped two cases, and the perf improved considerably form 1067ms to 783ms.

if (i32[srcAddr + J2ME.Constants.OBJ_CLASS_ID_OFFSET >> 2] ===
    i32[dstAddr + J2ME.Constants.OBJ_CLASS_ID_OFFSET >> 2]) {
  var classId = i32[srcAddr + J2ME.Constants.OBJ_CLASS_ID_OFFSET >> 2];
  var classInfo = J2ME.classIdToClassInfoMap[classId];
  if (classInfo instanceof J2ME.PrimitiveArrayClassInfo) {
    if (classInfo.bytesPerElement === 1) {
      var src = (srcAddr + J2ME.Constants.ARRAY_HDR_SIZE) + srcOffset;
      var dst = (dstAddr + J2ME.Constants.ARRAY_HDR_SIZE) + dstOffset;
      i8.set(i8.subarray(src, src + length), dst);
      return;
    } else if (classInfo.bytesPerElement === 2) {
      var src = (srcAddr + J2ME.Constants.ARRAY_HDR_SIZE >> 1) + srcOffset;
      var dst = (dstAddr + J2ME.Constants.ARRAY_HDR_SIZE >> 1) + dstOffset;
      i16.set(i16.subarray(src, src + length), dst);
      return;
    }
  }
}
marco-c commented 9 years ago

https://github.com/mozilla/pluotsorbet/pull/1801 optimizes System::arraycopy.

mykmelez commented 9 years ago

1801 was reverted in #1816 for causing a regression.

marco-c commented 9 years ago

1801 was reverted in #1816 for causing a regression.

And re-enabled in #1821.

marco-c commented 9 years ago

This is almost done, I want to test one more thing before closing.