From 6150b589993fc58817d6d1d2e4326c8ff135a0ea Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 30 Dec 2011 21:06:46 -0800 Subject: Low-level optimization. Eliminated a bunch of unnecessary array expense. --- src/compiler/scala/reflect/internal/Names.scala | 2 +- .../nsc/symtab/classfile/ClassfileParser.scala | 25 +++++++++++----------- src/library/scala/io/Codec.scala | 7 +++--- .../scala/tools/scalap/ByteArrayReader.scala | 2 +- .../scalax/rules/scalasig/ClassFileParser.scala | 7 ++++-- 5 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/compiler/scala/reflect/internal/Names.scala b/src/compiler/scala/reflect/internal/Names.scala index 11be9c80d1..8453b1e758 100644 --- a/src/compiler/scala/reflect/internal/Names.scala +++ b/src/compiler/scala/reflect/internal/Names.scala @@ -93,7 +93,7 @@ trait Names extends api.Names { /** Create a term name from the UTF8 encoded bytes in bs[offset..offset+len-1]. */ def newTermName(bs: Array[Byte], offset: Int, len: Int): TermName = { - val chars = Codec fromUTF8 bs.slice(offset, offset + len) + val chars = Codec.fromUTF8(bs, offset, len) newTermName(chars, 0, chars.length) } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index b73eaff524..94eb6d2afd 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -365,6 +365,13 @@ abstract class ClassfileParser { case arr: Type => Constant(arr) } } + + private def getSubArray(bytes: Array[Byte]): Array[Byte] = { + val decodedLength = ByteCodecs.decode(bytes) + val arr = new Array[Byte](decodedLength) + System.arraycopy(bytes, 0, arr, 0, decodedLength) + arr + } def getBytes(index: Int): Array[Byte] = { if (index <= 0 || len <= index) errorBadIndex(index) @@ -372,11 +379,10 @@ abstract class ClassfileParser { if (value eq null) { val start = starts(index) if (in.buf(start).toInt != CONSTANT_UTF8) errorBadTag(start) - val len = in.getChar(start + 1) + val len = in.getChar(start + 1) val bytes = new Array[Byte](len) - Array.copy(in.buf, start + 3, bytes, 0, len) - val decodedLength = ByteCodecs.decode(bytes) - value = bytes.take(decodedLength) + System.arraycopy(in.buf, start + 3, bytes, 0, len) + value = getSubArray(bytes) values(index) = value } value @@ -394,9 +400,7 @@ abstract class ClassfileParser { val len = in.getChar(start + 1) bytesBuffer ++= in.buf.view(start + 3, start + 3 + len) } - val bytes = bytesBuffer.toArray - val decodedLength = ByteCodecs.decode(bytes) - value = bytes.take(decodedLength) + value = getSubArray(bytesBuffer.toArray) values(indices.head) = value } value @@ -968,7 +972,7 @@ abstract class ClassfileParser { Some(ScalaSigBytes(pool getBytes in.nextChar)) } - def parseScalaLongSigBytes: Option[ScalaSigBytes] = try { + def parseScalaLongSigBytes: Option[ScalaSigBytes] = { val tag = in.nextByte.toChar assert(tag == ARRAY_TAG) val stringCount = in.nextChar @@ -980,11 +984,6 @@ abstract class ClassfileParser { } Some(ScalaSigBytes(pool.getBytes(entries.toList))) } - catch { - case e: Throwable => - e.printStackTrace - throw e - } /** Parse and return a single annotation. If it is malformed, * return None. diff --git a/src/library/scala/io/Codec.scala b/src/library/scala/io/Codec.scala index 8533ed493f..fa17f3eaeb 100644 --- a/src/library/scala/io/Codec.scala +++ b/src/library/scala/io/Codec.scala @@ -98,10 +98,11 @@ object Codec extends LowPriorityCodecImplicits { } @migration("This method was previously misnamed `toUTF8`. Converts from Array[Byte] to Array[Char].", "2.9.0") - def fromUTF8(bytes: Array[Byte]): Array[Char] = { - val bbuffer = java.nio.ByteBuffer wrap bytes + def fromUTF8(bytes: Array[Byte]): Array[Char] = fromUTF8(bytes, 0, bytes.length) + def fromUTF8(bytes: Array[Byte], offset: Int, len: Int): Array[Char] = { + val bbuffer = java.nio.ByteBuffer.wrap(bytes, offset, len) val cbuffer = UTF8.charSet decode bbuffer - val chars = new Array[Char](cbuffer.remaining()) + val chars = new Array[Char](cbuffer.remaining()) cbuffer get chars chars diff --git a/src/scalap/scala/tools/scalap/ByteArrayReader.scala b/src/scalap/scala/tools/scalap/ByteArrayReader.scala index 73220d1048..466ec53c79 100644 --- a/src/scalap/scala/tools/scalap/ByteArrayReader.scala +++ b/src/scalap/scala/tools/scalap/ByteArrayReader.scala @@ -72,7 +72,7 @@ class ByteArrayReader(content: Array[Byte]) { /** read an UTF8 encoded string */ def nextUTF8(len: Int): String = { - val cs = scala.io.Codec.fromUTF8(buf.slice(bp, bp + len)) + val cs = scala.io.Codec.fromUTF8(buf, bp, len) bp += len new String(cs) } diff --git a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala index d53d8e1fc1..84f28af7ce 100644 --- a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala +++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala @@ -65,8 +65,11 @@ class ByteCode(val bytes : Array[Byte], val pos : Int, val length : Int) { * stores and array of bytes for the decompiler */ def fromUTF8StringAndBytes = { - val chunk: Array[Byte] = bytes drop pos take length - StringBytesPair(io.Codec.fromUTF8(chunk).mkString, chunk) + val chunk: Array[Byte] = new Array[Byte](length) + System.arraycopy(bytes, pos, chunk, 0, length) + val str = new String(io.Codec.fromUTF8(bytes, pos, length)) + + StringBytesPair(str, chunk) } def byte(i : Int) = bytes(pos) & 0xFF -- cgit v1.2.3