1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-11-07 03:12:33 +01:00

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

View File

@ -539,8 +539,10 @@ const roundToPageSize = v => (v + PAGE_SIZE-1) & ~(PAGE_SIZE-1);
}
}
optimize() {
this.shrinkBuf();
optimize(shrink = false) {
if ( shrink ) {
this.shrinkBuf();
}
return {
byteLength: this.buf8.byteLength,
char0: this.buf32[CHAR0_SLOT],
@ -569,15 +571,7 @@ const roundToPageSize = v => (v + PAGE_SIZE-1) & ~(PAGE_SIZE-1);
? decoder.decodeSize(selfie)
: selfie.length << 2;
if ( byteLength === 0 ) { return false; }
byteLength = roundToPageSize(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
);
}
this.reallocateBuf(byteLength);
if ( shouldDecode ) {
decoder.decode(selfie, this.buf8.buffer);
} else {
@ -738,51 +732,8 @@ const roundToPageSize = v => (v + PAGE_SIZE-1) & ~(PAGE_SIZE-1);
roundToPageSize(char1 + charGrow),
this.buf8.length
);
this.resizeBuf(bufLen, char0);
}
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 ( bufLen > this.buf8.length ) {
this.reallocateBuf(bufLen);
}
if ( char0 !== this.buf32[CHAR0_SLOT] ) {
this.buf8.copyWithin(
@ -791,9 +742,52 @@ const roundToPageSize = v => (v + PAGE_SIZE-1) & ~(PAGE_SIZE-1);
this.buf32[CHAR1_SLOT]
);
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
);
}
};
/*******************************************************************************