             rs.mem_start_addrs.push(next_addr + size)
             return gLong.fromNumber(next_addr)
         o 'copyMemory(Ljava/lang/Object;JLjava/lang/Object;JJ)V', (rs, _this, src_base, src_offset, dest_base, dest_offset, num_bytes) ->
-            # XXX assumes base object is an array if non-null
-            # TODO: optimize by copying chunks at a time
-            if src_base?
-              src_offset = src_offset.toNumber()
-              if dest_base?
-                # both are java arrays
-                arraycopy_no_check(src_base, src_offset, dest_base, dest_offset.toNumber(), num_bytes)
-              else
-                # src is an array, dest is a mem block
-                dest_addr = rs.block_addr(dest_offset)
-                if DataView?
-                  for i in [0...num_bytes] by 1
-                    rs.mem_blocks[dest_addr].setInt8(i, src_base.array[src_offset+i])
-                else
-                  for i in [0...num_bytes] by 1
-                    rs.mem_blocks[dest_addr+i] = src_base.array[src_offset+i]
-            else
-              src_addr = rs.block_addr(src_offset)
-              if dest_base?
-                # src is a mem block, dest is an array
-                dest_offset = dest_offset.toNumber()
-                if DataView?
-                  for i in [0...num_bytes] by 1
-                    dest_base.array[dest_offset+i] = rs.mem_blocks[src_addr].getInt8(i)
-                else
-                  for i in [0...num_bytes] by 1
-                    dest_base.array[dest_offset+i] = rs.mem_blocks[src_addr+i]
-              else
-                # both are mem blocks
-                dest_addr = rs.block_addr(dest_offset)
-                if DataView?
-                  for i in [0...num_bytes] by 1
-                    rs.mem_blocks[dest_addr].setInt8(i, rs.mem_blocks[src_addr].getInt8(i))
-                else
-                  for i in [0...num_bytes] by 1
-                    rs.mem_blocks[dest_addr+i] = rs.mem_blocks[src_addr+i]
+            unsafe_memcpy rs, src_base, src_offset, dest_base, dest_offset, num_bytes
         o 'setMemory(JJB)V', (rs, _this, address, bytes, value) ->
             block_addr = rs.block_addr(address)
             for i in [0...bytes] by 1

    j++
  # CoffeeScript, we are not returning an array.
  return

unsafe_compare_and_swap = (rs, _this, obj, offset, expected, x) ->
  actual = obj.get_field_from_offset rs, offset

            return bytes_read
          o 'preClose0(Ljava/io/FileDescriptor;)V', (rs, fd_obj) ->
            # NOP, I think the actual fs.close is called later. If not, NBD.
        ]
        NativeThread: [
          o "init()V", (rs) -> # NOP
          o "current()J", (rs) ->
              # -1 means that we do not require signaling according to the
              # docs.
              gLong.fromNumber(-1)
        ]
    reflect:
      ConstantPool: [
