Fix WASM memory allocation in bidi-trie

Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/764
This commit is contained in:
Raymond Hill 2019-10-27 08:36:17 -04:00
parent 92235adeec
commit 40de7d6489
No known key found for this signature in database
GPG key ID: 25E1490B761470C2
2 changed files with 54 additions and 59 deletions

View file

@ -326,8 +326,8 @@ const bidiTrie = (( ) => {
return trie; return trie;
})(); })();
const bidiTrieOptimize = function() { const bidiTrieOptimize = function(shrink = false) {
const trieDetails = bidiTrie.optimize(); const trieDetails = bidiTrie.optimize(shrink);
vAPI.localStorage.setItem( vAPI.localStorage.setItem(
'SNFE.bidiTrieDetails', 'SNFE.bidiTrieDetails',
JSON.stringify(trieDetails) JSON.stringify(trieDetails)
@ -2804,6 +2804,7 @@ FilterContainer.prototype.toSelfie = function(path) {
return selfie; return selfie;
}; };
bidiTrieOptimize(true);
filterOrigin.optimize(); filterOrigin.optimize();
return Promise.all([ return Promise.all([

View file

@ -539,8 +539,10 @@ const roundToPageSize = v => (v + PAGE_SIZE-1) & ~(PAGE_SIZE-1);
} }
} }
optimize() { optimize(shrink = false) {
this.shrinkBuf(); if ( shrink ) {
this.shrinkBuf();
}
return { return {
byteLength: this.buf8.byteLength, byteLength: this.buf8.byteLength,
char0: this.buf32[CHAR0_SLOT], char0: this.buf32[CHAR0_SLOT],
@ -569,15 +571,7 @@ const roundToPageSize = v => (v + PAGE_SIZE-1) & ~(PAGE_SIZE-1);
? decoder.decodeSize(selfie) ? decoder.decodeSize(selfie)
: selfie.length << 2; : selfie.length << 2;
if ( byteLength === 0 ) { return false; } if ( byteLength === 0 ) { return false; }
byteLength = roundToPageSize(byteLength); this.reallocateBuf(byteLength);
if ( byteLength > this.buf8.length ) {
this.buf8 = new Uint8Array(byteLength);
this.buf32 = new Uint32Array(this.buf8.buffer);
this.haystack = this.buf8.subarray(
HAYSTACK_START,
HAYSTACK_START + HAYSTACK_SIZE
);
}
if ( shouldDecode ) { if ( shouldDecode ) {
decoder.decode(selfie, this.buf8.buffer); decoder.decode(selfie, this.buf8.buffer);
} else { } else {
@ -738,51 +732,8 @@ const roundToPageSize = v => (v + PAGE_SIZE-1) & ~(PAGE_SIZE-1);
roundToPageSize(char1 + charGrow), roundToPageSize(char1 + charGrow),
this.buf8.length this.buf8.length
); );
this.resizeBuf(bufLen, char0); if ( bufLen > this.buf8.length ) {
} this.reallocateBuf(bufLen);
shrinkBuf() {
if ( this.wasmMemory !== null ) { return; }
const char0 = this.buf32[TRIE1_SLOT] + MIN_FREE_CELL_BYTE_LENGTH;
const char1 = char0 + this.buf32[CHAR1_SLOT] - this.buf32[CHAR0_SLOT];
const bufLen = char1 + 256;
this.resizeBuf(bufLen, char0);
}
resizeBuf(bufLen, char0) {
bufLen = roundToPageSize(bufLen);
if ( bufLen === this.buf8.length && char0 === this.buf32[CHAR0_SLOT] ) {
return;
}
const charDataLen = this.buf32[CHAR1_SLOT] - this.buf32[CHAR0_SLOT];
if ( bufLen !== this.buf8.length ) {
let newBuf;
if ( this.wasmMemory === null ) {
newBuf = new Uint8Array(bufLen);
newBuf.set(this.buf8.subarray(0, this.buf32[TRIE1_SLOT]), 0);
newBuf.set(
this.buf8.subarray(
this.buf32[CHAR0_SLOT],
this.buf32[CHAR1_SLOT]
),
char0
);
} else {
const oldPageCount = this.buf8.length >>> 16;
const newPageCount = (bufLen + 0xFFFF) >>> 16;
if ( newPageCount > oldPageCount ) {
this.wasmMemory.grow(newPageCount - oldPageCount);
}
newBuf = new Uint8Array(this.wasmMemory.buffer);
}
this.buf8 = newBuf;
this.buf32 = new Uint32Array(this.buf8.buffer);
this.buf32[CHAR0_SLOT] = char0;
this.buf32[CHAR1_SLOT] = char0 + charDataLen;
this.haystack = this.buf8.subarray(
HAYSTACK_START,
HAYSTACK_START + HAYSTACK_SIZE
);
} }
if ( char0 !== this.buf32[CHAR0_SLOT] ) { if ( char0 !== this.buf32[CHAR0_SLOT] ) {
this.buf8.copyWithin( this.buf8.copyWithin(
@ -791,9 +742,52 @@ const roundToPageSize = v => (v + PAGE_SIZE-1) & ~(PAGE_SIZE-1);
this.buf32[CHAR1_SLOT] this.buf32[CHAR1_SLOT]
); );
this.buf32[CHAR0_SLOT] = char0; this.buf32[CHAR0_SLOT] = char0;
this.buf32[CHAR1_SLOT] = char0 + charDataLen; this.buf32[CHAR1_SLOT] = char1;
} }
} }
shrinkBuf() {
const char0 = this.buf32[TRIE1_SLOT] + MIN_FREE_CELL_BYTE_LENGTH;
const char1 = char0 + this.buf32[CHAR1_SLOT] - this.buf32[CHAR0_SLOT];
const bufLen = char1 + 256;
if ( char0 !== this.buf32[CHAR0_SLOT] ) {
this.buf8.copyWithin(
char0,
this.buf32[CHAR0_SLOT],
this.buf32[CHAR1_SLOT]
);
this.buf32[CHAR0_SLOT] = char0;
this.buf32[CHAR1_SLOT] = char1;
}
if ( bufLen < this.buf8.length ) {
this.reallocateBuf(bufLen);
}
}
reallocateBuf(newSize) {
newSize = roundToPageSize(newSize);
if ( newSize === this.buf8.length ) { return; }
if ( this.wasmMemory === null ) {
const newBuf = new Uint8Array(newSize);
newBuf.set(
newBuf.length < this.buf8.length
? this.buf8.subarray(0, newBuf.length)
: this.buf8
);
this.buf8 = newBuf;
} else {
const growBy =
((newSize + 0xFFFF) >>> 16) - (this.buf8.length >>> 16);
if ( growBy <= 0 ) { return; }
this.wasmMemory.grow(growBy);
this.buf8 = new Uint8Array(this.wasmMemory.buffer);
}
this.buf32 = new Uint32Array(this.buf8.buffer);
this.haystack = this.buf8.subarray(
HAYSTACK_START,
HAYSTACK_START + HAYSTACK_SIZE
);
}
}; };
/******************************************************************************* /*******************************************************************************