Avoid an allocation in readCharCode().

readCharCode() returns two values, and currently allocates a length-2
array on every call to do so. This change makes it instead us a
passed-in object which can be reused.

This tiny change reduces the total JS allocations done for the document
in Mozilla bug 992125 by 4.2%.
This commit is contained in:
Nicholas Nethercote 2014-08-10 22:27:04 -07:00
parent 0e4d9061b2
commit 61e6b576d4
3 changed files with 21 additions and 16 deletions

View File

@ -281,7 +281,7 @@ var CMap = (function CMapClosure() {
return this._map; return this._map;
}, },
readCharCode: function(str, offset) { readCharCode: function(str, offset, out) {
var c = 0; var c = 0;
var codespaceRanges = this.codespaceRanges; var codespaceRanges = this.codespaceRanges;
var codespaceRangesLen = this.codespaceRanges.length; var codespaceRangesLen = this.codespaceRanges.length;
@ -295,12 +295,14 @@ var CMap = (function CMapClosure() {
var low = codespaceRange[k++]; var low = codespaceRange[k++];
var high = codespaceRange[k++]; var high = codespaceRange[k++];
if (c >= low && c <= high) { if (c >= low && c <= high) {
return [c, n + 1]; out.charcode = c;
out.length = n + 1;
return;
} }
} }
} }
out.charcode = 0;
return [0, 1]; out.length = 1;
} }
}; };
return CMap; return CMap;

View File

@ -4574,10 +4574,11 @@ var Font = (function FontClosure() {
if (this.cMap) { if (this.cMap) {
// composite fonts have multi-byte strings convert the string from // composite fonts have multi-byte strings convert the string from
// single-byte to multi-byte // single-byte to multi-byte
var c = {};
while (i < chars.length) { while (i < chars.length) {
var c = this.cMap.readCharCode(chars, i); this.cMap.readCharCode(chars, i, c);
charcode = c[0]; charcode = c.charcode;
var length = c[1]; var length = c.length;
i += length; i += length;
glyph = this.charToGlyph(charcode); glyph = this.charToGlyph(charcode);
glyphs.push(glyph); glyphs.push(glyph);

View File

@ -65,12 +65,13 @@ describe('cmap', function() {
'endcodespacerange\n'; 'endcodespacerange\n';
var stream = new StringStream(str); var stream = new StringStream(str);
var cmap = CMapFactory.create(stream); var cmap = CMapFactory.create(stream);
var c = cmap.readCharCode(String.fromCharCode(1), 0); var c = {};
expect(c[0]).toEqual(1); cmap.readCharCode(String.fromCharCode(1), 0, c);
expect(c[1]).toEqual(1); expect(c.charcode).toEqual(1);
c = cmap.readCharCode(String.fromCharCode(0, 0, 0, 3), 0); expect(c.length).toEqual(1);
expect(c[0]).toEqual(3); cmap.readCharCode(String.fromCharCode(0, 0, 0, 3), 0, c);
expect(c[1]).toEqual(4); expect(c.charcode).toEqual(3);
expect(c.length).toEqual(4);
}); });
it('decodes 4 byte codespace ranges', function() { it('decodes 4 byte codespace ranges', function() {
var str = '1 begincodespacerange\n' + var str = '1 begincodespacerange\n' +
@ -78,9 +79,10 @@ describe('cmap', function() {
'endcodespacerange\n'; 'endcodespacerange\n';
var stream = new StringStream(str); var stream = new StringStream(str);
var cmap = CMapFactory.create(stream); var cmap = CMapFactory.create(stream);
var c = cmap.readCharCode(String.fromCharCode(0x8E, 0xA1, 0xA1, 0xA1), 0); var c = {};
expect(c[0]).toEqual(0x8EA1A1A1); cmap.readCharCode(String.fromCharCode(0x8E, 0xA1, 0xA1, 0xA1), 0, c);
expect(c[1]).toEqual(4); expect(c.charcode).toEqual(0x8EA1A1A1);
expect(c.length).toEqual(4);
}); });
it('read usecmap', function() { it('read usecmap', function() {
var str = '/Adobe-Japan1-1 usecmap\n'; var str = '/Adobe-Japan1-1 usecmap\n';