haikuwebkit/LayoutTests/workers/tests/string-tagcloud.js

275 lines
171 KiB
JavaScript
Raw Permalink Normal View History

Source/JavaScriptCore: Repeatedly creating and destroying workers that enqueue DFG plans can outpace the DFG worklist, which then causes VM shutdown to stall, which then causes memory growth https://bugs.webkit.org/show_bug.cgi?id=159754 Reviewed by Geoffrey Garen. If you create and destroy workers at a high rate and those workers enqueue some DFG plans that are still not compiled at the time that the worker is closed, then the closed workers end up stalling in VM::~VM waiting for the DFG worklist thread to finish those plans. Since we don't actually cancel the plans, it's easy to create a situation where the workers outpace the DFG worklist, especially if you create many workers at a time and each one finishes just after enqueueing those plans. The solution is to allow VM::~VM to remove plans from the DFG worklist that are related to that VM but aren't currently being worked on. That turns out to be an easy change. I have a test that repros this, but it's quite long-running. I call it workers/bomb.html. We may want to exclude it from test runs because of how long it takes. * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::removeDeadPlans): (JSC::DFG::Worklist::removeNonCompilingPlansForVM): (JSC::DFG::Worklist::queueLength): (JSC::DFG::Worklist::runThread): * dfg/DFGWorklist.h: * runtime/VM.cpp: (JSC::VM::~VM): LayoutTests: Repeatedly creating and destroying workers that enqueue DFG plans can outpace the DFG worklist, which then causes VM shutdown to stall, which then causes a memory growth https://bugs.webkit.org/show_bug.cgi?id=159754 Reviewed by Geoffrey Garen. Adds two tests that create a lot of workers that do sophisticated things. These are long-running tests so we may want to skip them. It's OK if we end up only running them manually occasionally. * workers: Added. * workers/bomb.html: Added. * workers/bomb-expected.txt: Added. * workers/bomb-with-v8.html: Added. * workers/tests: Added. * workers/tests/3d-cube.js: Added. * workers/tests/3d-morph.js: Added. * workers/tests/3d-raytrace.js: Added. * workers/tests/access-binary-trees.js: Added. * workers/tests/access-fannkuch.js: Added. * workers/tests/access-nbody.js: Added. * workers/tests/access-nsieve.js: Added. * workers/tests/bitops-3bit-bits-in-byte.js: Added. * workers/tests/bitops-bits-in-byte.js: Added. * workers/tests/bitops-bitwise-and.js: Added. * workers/tests/bitops-nsieve-bits.js: Added. * workers/tests/controlflow-recursive.js: Added. * workers/tests/crypto-aes.js: Added. * workers/tests/crypto-md5.js: Added. * workers/tests/crypto-sha1.js: Added. * workers/tests/date-format-tofte.js: Added. * workers/tests/date-format-xparb.js: Added. * workers/tests/math-cordic.js: Added. * workers/tests/math-partial-sums.js: Added. * workers/tests/math-spectral-norm.js: Added. * workers/tests/regexp-dna.js: Added. * workers/tests/string-base64.js: Added. * workers/tests/string-fasta.js: Added. * workers/tests/string-tagcloud.js: Added. * workers/tests/string-unpack-code.js: Added. * workers/tests/string-validate-input.js: Added. * workers/tests/v8-crypto.js: Added. * workers/tests/v8-deltablue.js: Added. * workers/tests/v8-earley-boyer.js: Added. * workers/tests/v8-raytrace.js: Added. * workers/tests/v8-regexp.js: Added. * workers/tests/v8-richards.js: Added. * workers/tests/v8-splay.js: Added. Canonical link: https://commits.webkit.org/178055@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@203370 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-07-18 20:31:20 +00:00
/*
* Copyright (C) 2007 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
Portions from:
json.js
2007-10-10
Public Domain
*/
// This test parses a JSON string giving tag names and popularity, and
// generates html markup for a "tagcloud" view.
if (!Object.prototype.toJSONString) {
Array.prototype.toJSONString = function (w) {
var a = [], // The array holding the partial texts.
i, // Loop counter.
l = this.length,
v; // The value to be stringified.
for (i = 0; i < l; i += 1) {
v = this[i];
switch (typeof v) {
case 'object':
if (v && typeof v.toJSONString === 'function') {
a.push(v.toJSONString(w));
} else {
a.push('null');
}
break;
case 'string':
case 'number':
case 'boolean':
a.push(v.toJSONString());
break;
default:
a.push('null');
}
}
return '[' + a.join(',') + ']';
};
Boolean.prototype.toJSONString = function () {
return String(this);
};
Date.prototype.toJSONString = function () {
function f(n) {
return n < 10 ? '0' + n : n;
}
return '"' + this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z"';
};
Number.prototype.toJSONString = function () {
return isFinite(this) ? String(this) : 'null';
};
Object.prototype.toJSONString = function (w) {
var a = [], // The array holding the partial texts.
k, // The current key.
i, // The loop counter.
v; // The current value.
if (w) {
for (i = 0; i < w.length; i += 1) {
k = w[i];
if (typeof k === 'string') {
v = this[k];
switch (typeof v) {
case 'object':
if (v) {
if (typeof v.toJSONString === 'function') {
a.push(k.toJSONString() + ':' +
v.toJSONString(w));
}
} else {
a.push(k.toJSONString() + ':null');
}
break;
case 'string':
case 'number':
case 'boolean':
a.push(k.toJSONString() + ':' + v.toJSONString());
}
}
}
} else {
for (k in this) {
if (typeof k === 'string' &&
Object.prototype.hasOwnProperty.apply(this, [k])) {
v = this[k];
switch (typeof v) {
case 'object':
if (v) {
if (typeof v.toJSONString === 'function') {
a.push(k.toJSONString() + ':' +
v.toJSONString());
}
} else {
a.push(k.toJSONString() + ':null');
}
break;
case 'string':
case 'number':
case 'boolean':
a.push(k.toJSONString() + ':' + v.toJSONString());
}
}
}
}
return '{' + a.join(',') + '}';
};
(function (s) {
var m = {
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
};
s.parseJSON = function (filter) {
var j;
function walk(k, v) {
var i, n;
if (v && typeof v === 'object') {
for (i in v) {
if (Object.prototype.hasOwnProperty.apply(v, [i])) {
n = walk(i, v[i]);
if (n !== undefined) {
v[i] = n;
}
}
}
}
return filter(k, v);
}
if (/^[\],:{}\s]*$/.test(this.replace(/\\./g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
j = eval('(' + this + ')');
return typeof filter === 'function' ? walk('', j) : j;
}
throw new SyntaxError('parseJSON');
};
s.toJSONString = function () {
if (/["\\\x00-\x1f]/.test(this)) {
return '"' + this.replace(/[\x00-\x1f\\"]/g, function (a) {
var c = m[a];
if (c) {
return c;
}
c = a.charCodeAt();
return '\\u00' + Math.floor(c / 16).toString(16) +
(c % 16).toString(16);
}) + '"';
}
return '"' + this + '"';
};
})(String.prototype);
}
var tagInfoJSON = '[\n {\n \"tag\": "titillation",\n \"popularity\": 4294967296\n },\n {\n \"tag\": "foamless",\n \"popularity\": 1257718401\n },\n {\n \"tag\": "snarler",\n \"popularity\": 613166183\n },\n {\n \"tag\": "multangularness",\n \"popularity\": 368304452\n },\n {\n \"tag\": "Fesapo unventurous",\n \"popularity\": 248026512\n },\n {\n \"tag\": "esthesioblast",\n \"popularity\": 179556755\n },\n {\n \"tag\": "echeneidoid",\n \"popularity\": 136641578\n },\n {\n \"tag\": "embryoctony",\n \"popularity\": 107852576\n },\n {\n \"tag\": "undilatory",\n \"popularity\": 87537981\n },\n {\n \"tag\": "predisregard",\n \"popularity\": 72630939\n },\n {\n \"tag\": "allergenic",\n \"popularity\": 61345190\n },\n {\n \"tag\": "uncloudy",\n \"popularity\": 52580571\n },\n {\n \"tag\": "unforeseeably",\n \"popularity\": 45628109\n },\n {\n \"tag\": "sturniform",\n \"popularity\": 40013489\n },\n {\n \"tag\": "anesthetize",\n \"popularity\": 35409226\n },\n {\n \"tag\": "ametabolia",\n \"popularity\": 31583050\n },\n {\n \"tag\": "angiopathy",\n \"popularity\": 28366350\n },\n {\n \"tag\": "sultanaship",\n \"popularity\": 25634218\n },\n {\n \"tag\": "Frenchwise",\n \"popularity\": 23292461\n },\n {\n \"tag\": "cerviconasal",\n \"popularity\": 21268909\n },\n {\n \"tag\": "mercurialness",\n \"popularity\": 19507481\n },\n {\n \"tag\": "glutelin venditate",\n \"popularity\": 17964042\n },\n {\n \"tag\": "acred overblack",\n \"popularity\": 16603454\n },\n {\n \"tag\": "Atik",\n \"popularity\": 15397451\n },\n {\n \"tag\": "puncturer",\n \"popularity\": 14323077\n },\n {\n \"tag\": "pukatea",\n \"popularity\": 13361525\n },\n {\n \"tag\": "suberize",\n \"popularity\": 12497261\n },\n {\n \"tag\": "Godfrey",\n \"popularity\": 11717365\n },\n {\n \"tag\": "tetraptote",\n \"popularity\": 11011011\n },\n {\n \"tag\": "lucidness",\n \"popularity\": 10369074\n },\n {\n \"tag\": "tartness",\n \"popularity\": 9783815\n },\n {\n \"tag\": "axfetch",\n \"popularity\": 9248634\n },\n {\n \"tag\": "preacquittal",\n \"popularity\": 8757877\n },\n {\n \"tag\": "matris",\n \"popularity\": 8306671\n },\n {\n \"tag\": "hyphenate",\n \"popularity\": 7890801\n },\n {\n \"tag\": "semifabulous",\n \"popularity\": 7506606\n },\n {\n \"tag\": "oppressiveness",\n \"popularity\": 7150890\n },\n {\n \"tag\": "Protococcales",\n \"popularity\": 6820856\n },\n {\n \"tag\": "unpreventive",\n \"popularity\": 6514045\n },\n {\n \"tag\": "Cordia",\n \"popularity\": 6228289\n },\n {\n \"tag\": "Wakamba leaflike",\n \"popularity\": 5961668\n },\n {\n \"tag\": "dacryoma",\n \"popularity\": 5712480\n },\n {\n \"tag\": "inguinal",\n \"popularity\": 5479211\n },\n {\n \"tag\": "responseless",\n \"popularity\": 5260507\n },\n {\n \"tag\": "supplementarily",\n \"popularity\": 5055158\n },\n {\n \"tag\": "emu",\n \"popularity\": 4862079\n },\n {\n \"tag\": "countermeet",\n \"popularity\": 4680292\n },\n {\n \"tag\": "purrer",\n \"popularity\": 4508918\n },\n {\n \"tag\": "Corallinaceae",\n \"popularity\": 4347162\n },\n {\n \"tag\": "speculum",\n \"popularity\": 4194304\n },\n {\n \"tag\": "crimpness",\n \"popularity\": 4049690\n },\n {\n \"tag\": "antidetonant",\n \"popularity\": 3912727\n },\n {\n \"tag\": "topeewallah",\n \"popularity\": 3782875\n },\n {\n \"tag\": "fidalgo ballant",\n \"popularity\": 3659640\n },\n {\n \"tag\": "utriculose",\n \"popularity\": 3542572\n },\n {\n \"tag\": "testata",\n \"popularity\": 3431259\n },\n {\n \"tag\": "beltmaking",\n \"popularity\": 3325322\n },\n {\n \"tag\": "necrotype",\n \"popularity\": 3224413\n },\n {\n \"tag\": "ovistic",\n \"popularity\": 3128215\n },\n
var log2 = Math.log(2);
var tagInfo = tagInfoJSON.parseJSON(function(a, b) { if (a == "popularity") { return Math.log(b) / log2; } else {return b; } });
function makeTagCloud(tagInfo)
{
var output = '<div class="tagCloud" style="width: 100%">';
tagInfo.sort(function(a, b) { if (a.tag < b.tag) { return -1; } else if (a.tag == b.tag) { return 0; } else return 1; });
for (var i = 0; i < tagInfo.length; i++) {
var tag = tagInfo[i].tag;
var validates = true;
for (var j = 0; j < tag.length; j++) {
var ch = tag.charCodeAt(j);
if (ch < 0x20 || ch >= 0x7f) {
validates = false;
break;
}
}
if (!validates)
continue;
var url = "http://example.com/tag/" + tag.replace(" ", "").toLowerCase();
var popularity = tagInfo[i].popularity;
var color = 'rgb(' + Math.floor(255 * (popularity - 12) / 20) + ', 0, 255)';
output += ' <a href="' + url + '" style="font-size: ' + popularity + 'px; color: ' + color + '">' + tag + '</a> \n';
}
output += '</div>';
output.replace(" ", "&nbsp;");
return output;
}
var tagcloud = makeTagCloud(tagInfo);
var expectedMinLength = 315000;
if (tagcloud.length < expectedMinLength)
throw "ERROR: bad result: expected length at least " + expectedMinLength + " but got " + tagcloud.length;
tagInfo = null;
postMessage("done");
close();