Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Truffle] Updated przlib to use Rubinius::ByteArray.
Browse files Browse the repository at this point in the history
Prior to this change, przlib used Strings as byte buffers. This owes a lot to the legacy of Ruby Strings being litle more than dumb byte arrays in Ruby < 1.9. However, these usage patterns do not work terribly well with alternative String representations, such as ropes. By switching to a dedicated byte buffer type we can achive much better performance than with rope-backed Strings and use a more suitable API.
nirvdrum committed Dec 18, 2016
1 parent ac82a4f commit 5dcfb9f
Showing 2 changed files with 98 additions and 98 deletions.
89 changes: 44 additions & 45 deletions lib/ruby/truffle/pr-zlib/lib/pr/rbzlib.rb
Original file line number Diff line number Diff line change
@@ -160,10 +160,9 @@ class Bytef_str
attr_accessor :buffer, :offset

def initialize(buffer, offset=0)
if buffer.class == String
if buffer.class == Rubinius::ByteArray
@buffer = buffer
@offset = offset
@buffer.force_encoding('ASCII-8BIT')
else
@buffer = buffer.buffer
@offset = offset
@@ -201,7 +200,7 @@ def set(val)
end

def current
@buffer[@offset..-1]
@buffer[@offset, @buffer.length - @offset]
end
end

@@ -245,15 +244,15 @@ def [](idx)
end

def []=(idx, val)
@buffer[(idx * 2) + @offset, 2] = [val].pack('v')
@buffer[(idx * 2) + @offset, 2] = Rubinius::ByteArray.from_string([val].pack('v'))
end

def get()
@buffer[@offset, 2].unpack('v').first
end

def set(val)
@buffer[@offset, 2] = [val].pack('v')
@buffer[@offset, 2] = Rubinius::ByteArray.from_string([val].pack('v'))
end
end

@@ -525,7 +524,7 @@ def gz_open(path, mode, fd)
elsif c == ?R.ord
strategy = Z_RLE
else
fmode += c.chr
fmode += c
end
end

@@ -544,15 +543,15 @@ def gz_open(path, mode, fd)
strategy
)

s.outbuf = 0.chr * Z_BUFSIZE
s.outbuf = Rubinius::ByteArray.new(Z_BUFSIZE, 0)
s.stream.next_out = Bytef.new(s.outbuf)

if err != Z_OK || s.outbuf.nil?
destroy(s)
return nil
end
else
s.inbuf = 0.chr * Z_BUFSIZE
s.inbuf = Rubinius::ByteArray.new(Z_BUFSIZE, 0)
s.stream.next_in = Bytef.new(s.inbuf)

err = inflateInit2_(s.stream, -MAX_WBITS, ZLIB_VERSION, s.stream.size)
@@ -568,17 +567,17 @@ def gz_open(path, mode, fd)
s.file = fd < 0 ? File.new(path, fmode) : IO.new(fd, fmode)

if s.mode == 'w'
gzheader = 0.chr * 10
gzheader = Rubinius::ByteArray.new(10, 0)
gzheader[0] = @@gz_magic[0]
gzheader[1] = @@gz_magic[1]
gzheader[2] = Z_DEFLATED.chr
gzheader[3] = 0.chr
gzheader[4] = 0.chr
gzheader[5] = 0.chr
gzheader[6] = 0.chr
gzheader[7] = 0.chr
gzheader[8] = 0.chr
gzheader[9] = OS_CODE.chr
gzheader[2] = Z_DEFLATED
gzheader[3] = 0
gzheader[4] = 0
gzheader[5] = 0
gzheader[6] = 0
gzheader[7] = 0
gzheader[8] = 0
gzheader[9] = OS_CODE
s.file.write(gzheader)
s.start = 10
else
@@ -660,12 +659,12 @@ def get_byte(s)
# Reads a long in LSB order from the given gz_stream. Sets z_err in case
# of error.
def getLong(s)
x = 0.chr * 4
x[0] = (get_byte(s)).chr
x[1] = (get_byte(s)).chr
x[2] = (get_byte(s)).chr
x = Rubinius::ByteArray.new(4, 0)
x[0] = get_byte(s)
x[1] = get_byte(s)
x[2] = get_byte(s)
c = get_byte(s)
x[3] = (c).chr
x[3] = c

s.z_err = Z_DATA_ERROR if (c == Z_EOF)

@@ -915,7 +914,7 @@ def gzread(file,buf,len)
# or -1 in case of end of file or error.
#
def gzgetc(file)
c = 0.chr
c = 0
if (gzread(file,c,1) == 1)
return c
else
@@ -947,18 +946,18 @@ def gzgets(file,buf,len)
return nil if buf.nil? || (len <= 0)

i = 0
gzchar = 0.chr
gzchar = 0

loop do
len-=1
bytes = gzread(file, gzchar, 1)
buf[i] = gzchar[0]
i += 1
break if len == 0 || (bytes != 1) || (gzchar == (13).chr)
break if len == 0 || (bytes != 1) || (gzchar == 13)
end

buf[i..-1] = ''
buf.chomp!(0.chr)
buf[i, buf.length - i] = Rubinius::ByteArray.new(0, 0)
buf.chomp!(0)

if i == 0 && (len > 0)
return nil
@@ -1121,7 +1120,7 @@ def gzseek(file,offset,whence)
end

if (s.inbuf.nil?)
s.inbuf = 0.chr*Z_BUFSIZE
s.inbuf = Rubinius::ByteArray.new(Z_BUFSIZE, 0)
end

while (offset > 0)
@@ -1166,7 +1165,7 @@ def gzseek(file,offset,whence)
end

if offset != 0 && s.outbuf.nil?
s.outbuf = 0.chr * Z_BUFSIZE
s.outbuf = Rubinius::ByteArray.new(Z_BUFSIZE, 0)
end
if(offset != 0 && s.back != Z_EOF)
s.back = Z_EOF
@@ -1369,13 +1368,13 @@ def deflateInit2_(strm,level,method,windowBits,memLevel,strategy,version,stream_
s.hash_mask = s.hash_size - 1
s.hash_shift = ((s.hash_bits+MIN_MATCH-1) / MIN_MATCH)

s.window = 0.chr * (s.w_size * 2)
s.window = Rubinius::ByteArray.new(s.w_size * 2, 0)
s.prev = Array.new(s.w_size,0)
s.head = Array.new(s.hash_size,0)

s.lit_bufsize = 1 << (memLevel + 6)

overlay = 0.chr * (s.lit_bufsize * (2+2))
overlay = Rubinius::ByteArray.new(s.lit_bufsize * (2+2), 0)
s.pending_buf = Bytef.new(overlay)
s.pending_buf_size = (s.lit_bufsize) * (2+2)

@@ -2236,8 +2235,8 @@ def fill_window(s)
# Flush the current block, with given end-of-file flag.
# IN assertion: strstart is set to the end of the current match.
def FLUSH_BLOCK_ONLY(s,eof)
if (s.block_start >= (0))
_tr_flush_block(s, s.window[(s.block_start)..-1],
if (s.block_start >= 0)
_tr_flush_block(s, s.window[s.block_start, s.window.length - s.block_start],
((s.strstart) - s.block_start), eof)
else
_tr_flush_block(s, nil,
@@ -4084,7 +4083,7 @@ def updatewindow(strm, out)
state = strm.state

if state.window.nil?
state.window = 0.chr * (1 << state.wbits)
state.window = Rubinius::ByteArray.new(1 << state.wbits, 0)
return true if state.window.nil?
end

@@ -4127,19 +4126,19 @@ def UPDATE(state, check, buf)

# compute crc
def CRC2(check, word)
hbuf = 0.chr * 2
hbuf[0] = (word & 0xff).chr
hbuf[1] = ((word >> 8) & 0xff).chr
hbuf = Rubinius::ByteArray.new(2, 0)
hbuf[0] = (word & 0xff)
hbuf[1] = ((word >> 8) & 0xff)
check = crc32(check, hbuf)
end

# compute crc
def CRC4(check, word)
hbuf = 0.chr * 4
hbuf[0] = (word & 0xff).chr
hbuf[1] = ((word >> 8) & 0xff).chr
hbuf[2] = ((word >> 16) & 0xff).chr
hbuf[3] = ((word >> 24) & 0xff).chr
hbuf = Rubinius::ByteArray.new(4, 0)
hbuf[0] = (word & 0xff)
hbuf[1] = ((word >> 8) & 0xff)
hbuf[2] = ((word >> 16) & 0xff)
hbuf[3] = ((word >> 24) & 0xff)
check = crc32(check, hbuf)
end

@@ -4959,14 +4958,14 @@ def inflateSync(strm)
state = strm.state
return Z_BUF_ERROR if (strm.avail_in == 0 && state.bits < 8)

buf = 0.chr * 4
buf = Rubinius::ByteArray.new(4, 0)
if (state.mode != SYNC)
state.mode = SYNC
state.hold <<= state.bits & 7
state.bits -= state.bits & 7
len = 0
while (state.bits >= 8)
buf[len] = (state.hold).chr
buf[len] = state.hold
len+=1
state.hold >>= 8
state.bits -= 8
@@ -5012,7 +5011,7 @@ def inflateCopy(dest, source)
return Z_MEM_ERROR if copy.nil?
window = nil
if state.window
window = 0.chr * (1 << state.wbits)
window = Rubinius::ByteArray.new(1 << state.wbits, 0)
if window.nil?
copy = nil
return Z_MEM_ERROR
107 changes: 54 additions & 53 deletions lib/ruby/truffle/pr-zlib/lib/pr/zlib.rb
Original file line number Diff line number Diff line change
@@ -113,7 +113,7 @@ def raise_zlib_error(err, msg)

def zstream_expand_buffer()
if @buf.nil?
@buf = Bytef.new(0.chr * ZSTREAM_INITIAL_BUFSIZE)
@buf = Bytef.new(Rubinius::ByteArray.new(ZSTREAM_INITIAL_BUFSIZE, 0))
@stream.next_out = Bytef.new(@buf)
@stream.avail_out = ZSTREAM_INITIAL_BUFSIZE
return
@@ -127,7 +127,7 @@ def zstream_expand_buffer()
inc = ZSTREAM_AVAIL_OUT_STEP_MIN
end
if @buf.length < @buf.offset + inc
@buf.buffer << 0.chr * (@buf.offset + inc - @buf.length)
@buf.buffer << Rubinius::ByteArray.new(@buf.offset + inc - @buf.length, 0)
end
@stream.avail_out = (inc < ZSTREAM_AVAIL_OUT_STEP_MAX) ?
inc : ZSTREAM_AVAIL_OUT_STEP_MAX
@@ -143,7 +143,7 @@ def zstream_append_buffer(src, len)
return
end
if (@buf.length < @buf.offset + len)
@buf.buffer << (0.chr * (@buf.offset + len - @buf.length))
@buf.buffer << Rubinius::ByteArray.new(@buf.offset + len - @buf.length, 0)
@stream.avail_out = 0
else
if (@stream.avail_out >= len)
@@ -159,17 +159,17 @@ def zstream_append_buffer(src, len)

def zstream_detach_buffer()
if @buf.nil?
dst = ''
dst = Rubinius::ByteArray.new(0, 0)
else
dst = @buf.buffer[0,@buf.offset]
end

@buf = Bytef.new(0.chr * ZSTREAM_INITIAL_BUFSIZE)
@buf = Bytef.new(Rubinius::ByteArray.new(ZSTREAM_INITIAL_BUFSIZE, 0))
@stream.next_out = Bytef.new(@buf)
@stream.avail_out = ZSTREAM_INITIAL_BUFSIZE
@buf_filled = 0

return dst
return dst.to_str
end

def zstream_shift_buffer(len)
@@ -192,7 +192,7 @@ def zstream_buffer_ungetc(c)
if (@buf.nil? || (@buf.length - @buf.offset).zero?)
zstream_expand_buffer()
end
@buf.buffer[0,0] = c.chr
@buf.buffer[0,0] = c
@buf += 1
if (@stream.avail_out > 0)
@stream.next_out+=1
@@ -202,7 +202,7 @@ def zstream_buffer_ungetc(c)

def zstream_append_input(src, len)
return if (len <= 0)
src = src.current if src.class != String
src = src.current if src.class != Rubinius::ByteArray
if @input.nil?
@input = src[0,len]
else
@@ -214,7 +214,7 @@ def zstream_discard_input(len)
if (@input.nil? || @input.length <= len)
@input = nil
else
@input[0,len] = ''
@input[0,len] = Rubinius::ByteArray.new(0, 0)
end
end

@@ -406,12 +406,12 @@ def avail_out()

def avail_out=(size)
if @z.buf.nil?
@z.buf = Bytef.new(0.chr * size)
@z.buf = Bytef.new(Rubinius::ByteArray.new(size, 0))
@z.stream.next_out = Bytef.new(@z.buf)
@z.stream.avail_out = size
elsif @z.stream.avail_out != size
if @z.buf.offset + size > @z.buf.length
@z.buf.buffer << 0.chr * (@z.buf.offset + size - @z.buf.length)
@z.buf.buffer << Rubinius::ByteArray.new(@z.buf.offset + size - @z.buf.length, 0)
end
@z.stream.next_out = Bytef.new(@z.buf,@z.buf.offset)
@z.stream.avail_out = size
@@ -482,7 +482,7 @@ def reset()
end

def finish()
@z.zstream_run("", 0, Z_FINISH)
@z.zstream_run(Rubinius::ByteArray.new(0,0), 0, Z_FINISH)
@z.zstream_detach_buffer()
end

@@ -518,11 +518,11 @@ def self.deflate(src,level=Z_DEFAULT_COMPRESSION)
@z.ZSTREAM_READY()

begin
dst = deflate_run(src)
dst = deflate_run(Rubinius::ByteArray.from_string(src))
ensure
@z.zstream_end()
end
dst
dst.to_str
end

def initialize(level=Z_DEFAULT_COMPRESSION,wbits=MAX_WBITS,memlevel=DEF_MEM_LEVEL,strategy=Z_DEFAULT_STRATEGY)
@@ -547,11 +547,11 @@ def initialize_copy(orig)

def do_deflate(src,flush)
if src.nil?
@z.zstream_run('',0,Z_FINISH)
@z.zstream_run(Rubinius::ByteArray.new(0,0),0,Z_FINISH)
return
end
if (flush != Z_NO_FLUSH || (src && src.length>0))
@z.zstream_run(src,src.length,flush)
@z.zstream_run(Rubinius::ByteArray.from_string(src),src.length,flush)
end
end
private :do_deflate
@@ -568,7 +568,7 @@ def <<(src)

def flush(v_flush)
if(v_flush != Z_NO_FLUSH)
@z.zstream_run("", 0, flush)
@z.zstream_run(Rubinius::ByteArray.new(0, 0), 0, flush)
end
@z.zstream_detach_buffer()
end
@@ -588,7 +588,7 @@ def params(level=Z_DEFAULT_COMPRESSION,strategy=Z_DEFAULT_STRATEGY)
end

def set_dictionary(dic)
err = deflateSetDictionary(@z.stream,dic,dic.length)
err = deflateSetDictionary(@z.stream,Rubinius::ByteArray.from_string(dic),dic.length)
if (err != Z_OK)
raise_zlib_error(err, @z.stream.msg)
end
@@ -599,8 +599,8 @@ def set_dictionary(dic)
class Inflate < ZStream

def self.inflate_run(src)
@z.zstream_run(src,src.length,Z_SYNC_FLUSH)
@z.zstream_run('',0,Z_FINISH)
@z.zstream_run(Rubinius::ByteArray.from_string(src),src.length,Z_SYNC_FLUSH)
@z.zstream_run(Rubinius::ByteArray.new(0, 0),0,Z_FINISH)
@z.zstream_detach_buffer()
end

@@ -613,20 +613,20 @@ def self.inflate(src)
end
@z.ZSTREAM_READY()
begin
dst = inflate_run(src)
dst = inflate_run(Rubinius::ByteArray.from_string(src))
ensure
@z.zstream_end
end
dst
dst.to_str
end

def do_inflate(src)
if(src.nil?)
@z.zstream_run("", 0, Z_FINISH)
@z.zstream_run(Rubinius::ByteArray.new(0, 0), 0, Z_FINISH)
return
end
if (src.length>0)
@z.zstream_run(src,src.length,Z_SYNC_FLUSH)
@z.zstream_run(Rubinius::ByteArray.from_string(src),src.length,Z_SYNC_FLUSH)
end
end
private :do_inflate
@@ -647,7 +647,7 @@ def inflate(src)
dst = @z.zstream_detach_buffer()
else
@z.zstream_append_buffer(src,src.lenth)
dst = ''
dst = Rubinius::ByteArray.new(0, 0)
end
else
do_inflate(src)
@@ -657,16 +657,16 @@ def inflate(src)
end
end
if block_given?
yield dst
yield dst.to_str
else
dst
dst.to_str
end
end

def <<(src)
if @z.ZSTREAM_IS_FINISHED()
if src
@z.zstream_append_buffer(src,src.length)
@z.zstream_append_buffer(Rubinius::ByteArray.from_string(src),src.length)
end
else
do_inflate(src)
@@ -694,7 +694,7 @@ def sync_point?()
end

def set_dictionary(dic)
src = dic
src = Rubinius::ByteArray.from_string(dic)
err = inflateSetDictionary(@z.stream,src,src.length)

if err != Z_OK
@@ -885,11 +885,11 @@ def gzfile_get32(src)
end

def gzfile_set32(n)
[n].pack('V')
Rubinius::ByteArray.from_string([n].pack('V'))
end

def gzfile_make_header
buf = 0.chr * 10
buf = Rubinius::ByteArray.new(10, 0)
flags = 0
extraflags = 0
if @gz.orig_name
@@ -906,29 +906,28 @@ def gzfile_make_header
elsif (@gz.level == Z_BEST_COMPRESSION)
extraflags |= GZ_EXTRAFLAG_SLOW
end
buf[0] = GZ_MAGIC1.chr
buf[1] = GZ_MAGIC2.chr
buf[2] = GZ_METHOD_DEFLATE.chr
buf[3] = flags.chr
buf[0] = GZ_MAGIC1
buf[1] = GZ_MAGIC2
buf[2] = GZ_METHOD_DEFLATE
buf[3] = flags
buf[4,4] = gzfile_set32(@gz.mtime)
buf[8] = extraflags.chr
buf[9] = @gz.os_code.chr
buf[8] = extraflags
buf[9] = @gz.os_code
@gz.z.zstream_append_buffer(buf,buf.length)

if @gz.orig_name
@gz.z.zstream_append_buffer(@gz.orig_name,@gz.orig_name.length)
@gz.z.zstream_append_buffer("\0", 1)
@gz.z.zstream_append_buffer(Rubinius::ByteArray.from_string(@gz.orig_name),@gz.orig_name.length)
@gz.z.zstream_append_buffer(Rubinius::ByteArray.new(1, 0), 1)
end
if @gz.comment
@gz.z.zstream_append_buffer(@gz.comment,@gz.comment.length)
@gz.z.zstream_append_buffer("\0", 1)
@gz.z.zstream_append_buffer(Rubinius::ByteArray.from_string(@gz.comment),@gz.comment.length)
@gz.z.zstream_append_buffer(Rubinius::ByteArray.new(1, 0), 1)
end

@gz.z.flags |= GZFILE_FLAG_HEADER_FINISHED
end

def gzfile_make_footer()
buf = 0.chr * 8
buf = Rubinius::ByteArray.new(8, 0)
buf[0,4] = gzfile_set32(@gz.crc)
buf[4,4] = gzfile_set32(@gz.z.stream.total_in)
@gz.z.zstream_append_buffer(buf, buf.length)
@@ -1100,7 +1099,7 @@ def flush(v_flush=Z_SYNC_FLUSH)
raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()

if v_flush != Z_NO_FLUSH
@gz.z.zstream_run("", 0, v_flush)
@gz.z.zstream_run(Rubinius::ByteArray.new(0, 0), 0, v_flush)
end

gzfile_write_raw()
@@ -1121,7 +1120,7 @@ def write(str)

def putc(ch)
raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
gzfile_write(ch.chr, 1)
gzfile_write(ch, 1)
ch
end

@@ -1154,10 +1153,11 @@ def gzfile_write_raw
private :gzfile_write_raw

def gzfile_write(str,len)
str = Rubinius::ByteArray.from_string(str)

if (@gz.z.flags & GZFILE_FLAG_HEADER_FINISHED).zero?
gzfile_make_header()
end

if (len > 0 || (@gz.z.flags & GZFILE_FLAG_SYNC))
@gz.crc = crc32(@gz.crc, str, len)
@gz.z.zstream_run(str, len, (@gz.z.flags & GZFILE_FLAG_SYNC).nonzero? ?
@@ -1172,7 +1172,7 @@ def gzfile_writer_end_run
if (@gz.z.flags & GZFILE_FLAG_HEADER_FINISHED).zero?
gzfile_make_header()
end
@gz.z.zstream_run("", 0, Z_FINISH)
@gz.z.zstream_run(Rubinius::ByteArray.new(0, 0), 0, Z_FINISH)
gzfile_make_footer()
gzfile_write_raw()

@@ -1266,7 +1266,7 @@ def readchar()
if dst.nil?
raise EOFError, "end of file reached"
end
dst
dst.to_str
end

def each_byte()
@@ -1283,6 +1283,7 @@ def ungetc(ch)

def gets(rs=$/)
dst = gzreader_gets(rs)
dst = dst.to_str if dst
$_ = dst if dst
dst
end
@@ -1412,7 +1413,7 @@ def gzreader_gets(rs=$/)
if (rspara)
gzreader_skip_linebreaks()
end
dst
dst.to_str
end

def gzfile_read(len)
@@ -1437,7 +1438,7 @@ def gzfile_read(len)

dst = @gz.z.zstream_shift_buffer(len)
gzfile_calc_crc(dst)
dst
dst.to_str
end

def gzfile_read_all()
@@ -1453,15 +1454,15 @@ def gzfile_read_all()

dst = @gz.z.zstream_detach_buffer()
gzfile_calc_crc(dst)
dst
dst.to_str
end

def gzfile_read_raw()
str = @gz.io.read(GZFILE_READ_SIZE)
if str && str.class != String
raise TypeError,"wrong argument type #{rs.class} (expected String)"
end
str
Rubinius::ByteArray.from_string(str)
end

def gzfile_read_raw_ensure(size)
@@ -1477,7 +1478,7 @@ def gzfile_read_raw_until_zero(offset)
ap = nil

loop do
ap = @gz.z.input[offset, @gz.z.input.length-offset].index(0.chr)
ap = @gz.z.input[offset, @gz.z.input.length-offset].index(0)
break if ap
str = gzfile_read_raw()

0 comments on commit 5dcfb9f

Please sign in to comment.