Changeset 192664 in webkit


Ignore:
Timestamp:
Nov 19, 2015 3:32:09 PM (8 years ago)
Author:
mark.lam@apple.com
Message:

Create correctness tests for binary snippet operators.
https://bugs.webkit.org/show_bug.cgi?id=151465

Reviewed by Geoffrey Garen.

Implement a common infrastructure for generating and running tests on binary
operators. Also re-implemented the op_add, op_sub, and op_mul tests to be based
on this new infrastructure.

  • tests/stress/op_add.js:
  • tests/stress/op_mul.js:
  • tests/stress/op_sub.js:
  • These were reimplemented using binary-op-test.js.
  • tests/stress/op_div.js: Added.
  • tests/stress/op_mod.js: Added.
  • tests/stress/op_bitand.js: Added.
  • tests/stress/op_bitor.js: Added.
  • tests/stress/op_bitxor.js: Added.
  • tests/stress/op_lshift.js: Added.
  • tests/stress/op_rshift.js: Added.
  • tests/stress/op_urshift.js: Added.
  • tests/stress/resources/binary-op-test.js: Added.
  • Common code for generating and running tests.
Location:
trunk/Source/JavaScriptCore
Files:
9 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r192661 r192664  
     12015-11-19  Mark Lam  <mark.lam@apple.com>
     2
     3        Create correctness tests for binary snippet operators.
     4        https://bugs.webkit.org/show_bug.cgi?id=151465
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Implement a common infrastructure for generating and running tests on binary
     9        operators.  Also re-implemented the op_add, op_sub, and op_mul tests to be based
     10        on this new infrastructure.
     11
     12        * tests/stress/op_add.js:
     13        * tests/stress/op_mul.js:
     14        * tests/stress/op_sub.js:
     15        - These were reimplemented using binary-op-test.js.
     16
     17        * tests/stress/op_div.js: Added.
     18        * tests/stress/op_mod.js: Added.
     19
     20        * tests/stress/op_bitand.js: Added.
     21        * tests/stress/op_bitor.js: Added.
     22        * tests/stress/op_bitxor.js: Added.
     23
     24        * tests/stress/op_lshift.js: Added.
     25        * tests/stress/op_rshift.js: Added.
     26        * tests/stress/op_urshift.js: Added.
     27
     28        * tests/stress/resources/binary-op-test.js: Added.
     29        - Common code for generating and running tests.
     30
    1312015-11-19  Caitlin Potter  <caitp@igalia.com>
    232
  • trunk/Source/JavaScriptCore/tests/stress/op_add.js

    r192531 r192664  
    11//@ runFTLNoCJIT
    22
    3 // This test module aims to test the addition operator by comparing its runtime
    4 // behavior (using the different tiers) with expected values computed at initialization
    5 // time using the LLINT / bytecode generator.
    6 //
    7 // It works by generating test scenarios from permutations of value pairs to exercise
    8 // the addition operator. It computes the expected results by evaluating an expression
    9 // to add the values in an initialization pass. The scenarios are later applied to
    10 // a set of test functions of the forms:
    11 //
    12 //     variable + variable
    13 //     constant + variable
    14 //     variable + constant
    15 //
    16 // See generateScenarios() and initializeTestCases() for details on how the test
    17 // cases are generated.
    18 //
    193// If all goes well, this test module will terminate silently. If not, it will print
    20 // errors.
     4// errors. See binary-op-test.js for debugging options if needed.
    215
    22 var verbose = false;
    23 var abortOnFirstFail = false;
     6load("./resources/binary-op-test.js");
     7
     8//============================================================================
     9// Test configuration data:
     10
     11var opName = "add";
     12var op = "+";
    2413
    2514var o1 = {
     
    2716};
    2817
    29 var set1 = [
     18var posInfinity = 1 / 0;
     19var negInfinity = -1 / 0;
     20
     21var values = [
    3022    'o1',
    3123    'null',
    3224    'undefined',
     25    'true',
     26    'false',
     27
    3328    'NaN',
     29    'posInfinity',
     30    'negInfinity',
     31    '100.2', // Some random small double value.
     32    '-100.2',
     33    '54294967296.2923', // Some random large double value.
     34    '-54294967296.2923',
     35
     36    '0',
     37    '-0',
     38    '1',
     39    '-1',
     40    '0x3fff',
     41    '-0x3fff',
     42    '0x7fff',
     43    '-0x7fff',
     44    '0x10000',
     45    '-0x10000',
     46    '0x7ffffff',
     47    '-0x7ffffff',
     48    '0x100000000',
     49    '-0x100000000',
     50
    3451    '"abc"',
     52    '"0"',
     53    '"-0"',
     54    '"1"',
     55    '"-1"',
    3556];
    3657
    37 var set2 = [
    38     '10',
    39     '-10',
    40     '2147483647',
    41     '-2147483647',
    42     '4294967296',
    43     '-4294967296',
    44     '100.2',
    45     '-100.2',
    46     'true',
    47     'false',
    48 ];
     58tests = [];
     59generateBinaryTests(tests, opName, op, "VarVar", values, values);
     60generateBinaryTests(tests, opName, op, "VarConst", values, values);
     61generateBinaryTests(tests, opName, op, "ConstVar", values, values);
    4962
    50 // Assemble the values that we'll be testing with:
    51 var values = [];
    52 for (var i = 0; i < set1.length; i++)
    53     values.push(set1[i]);
    54 for (var i = 0; i < set2.length; i++)
    55     values.push(set2[i]);
    56 for (var i = 0; i < set2.length; i++)
    57     values.push('"' + set2[i] + '"');
    58 
    59 function generateScenarios(xvalues, yvalues) {
    60     var scenarios = [];
    61     for (var i = 0; i < xvalues.length; i++) {
    62         for (var j = 0; j < yvalues.length; j++) {
    63             var xStr = xvalues[i];
    64             var yStr = yvalues[j];
    65             var x = eval(xStr);
    66             var y = eval(yStr);
    67             var name = "(" + xStr + " + " + yStr + ")";
    68             var expected = eval("" + xStr + " + " + yStr);
    69             var scenario = { name: name, x: x, y: y, expected: expected };
    70 
    71             scenarios.push(scenario);
    72         }
    73     }
    74     return scenarios;
    75 }
    76 
    77 function printScenarios(scenarios) {
    78     for (var i = 0; i < scenarios.length; i++) {
    79         var scenario = scenarios[i];
    80         print("scenario[" + i + "]: { name: " + scenario.name + ", x: " + scenario.x, ", y: " + scenario.y + ", expected: " + scenario.expected + " }");
    81     }
    82 }
    83 
    84 var testCases = [
    85     {
    86         name: "add",
    87         func: function(x, y) { return x + y; },
    88         xvalues: values,
    89         yvalues: values
    90     },
    91     {
    92         name: "addI32V",
    93         func: function(x, y) { return 10 + y; },
    94         xvalues: [ '10' ],
    95         yvalues: values
    96     },
    97     {
    98         name: "addVI32",
    99         func: function(x, y) { return x + 10; },
    100         xvalues: values,
    101         yvalues: [ '10' ]
    102     },
    103     {
    104         name: "addI32oV",
    105         func: function(x, y) { return 2147483647 + y; },
    106         xvalues: [ '2147483647' ],
    107         yvalues: values
    108     },
    109     {
    110         name: "addVI32o",
    111         func: function(x, y) { return x + 2147483647; },
    112         xvalues: values,
    113         yvalues: [ '2147483647' ]
    114     },
    115     {
    116         name: "addI32onV",
    117         func: function(x, y) { return -2147483647 + y; },
    118         xvalues: [ '-2147483647' ],
    119         yvalues: values
    120     },
    121     {
    122         name: "addVI32on",
    123         func: function(x, y) { return x + (-2147483647); },
    124         xvalues: values,
    125         yvalues: [ '-2147483647' ]
    126     },
    127     {
    128         name: "addI52V",
    129         func: function(x, y) { return 4294967296 + y; },
    130         xvalues: [ '4294967296' ],
    131         yvalues: values
    132     },
    133     {
    134         name: "addVI52",
    135         func: function(x, y) { return x + 4294967296; },
    136         xvalues: values,
    137         yvalues: [ '4294967296' ]
    138     },
    139     {
    140         name: "addI52nV",
    141         func: function(x, y) { return -4294967296 + y; },
    142         xvalues: [ '-4294967296' ],
    143         yvalues: values
    144     },
    145     {
    146         name: "addVI52n",
    147         func: function(x, y) { return x + (-4294967296); },
    148         xvalues: values,
    149         yvalues: [ '-4294967296' ]
    150     },
    151     {
    152         name: "addDV",
    153         func: function(x, y) { return 100.2 + y; },
    154         xvalues: [ '100.2' ],
    155         yvalues: values
    156     },
    157     {
    158         name: "addVD",
    159         func: function(x, y) { return x + 100.2; },
    160         xvalues: values,
    161         yvalues: [ '100.2' ]
    162     },
    163     {
    164         name: "addBV",
    165         func: function(x, y) { return true + y; },
    166         xvalues: [ 'true' ],
    167         yvalues: values
    168     },
    169     {
    170         name: "addVB",
    171         func: function(x, y) { return x + true; },
    172         xvalues: values,
    173         yvalues: [ 'true' ]
    174     },
    175     {
    176         name: "addSi32V",
    177         func: function(x, y) { return "10" + y; },
    178         xvalues: [ '"10"' ],
    179         yvalues: values
    180     },
    181     {
    182         name: "addVSi32",
    183         func: function(x, y) { return x + "10"; },
    184         xvalues: values,
    185         yvalues: [ '"10"' ]
    186     },
    187 
    188     {
    189         name: "addSi32oV",
    190         func: function(x, y) { return "2147483647" + y; },
    191         xvalues: [ '"2147483647"' ],
    192         yvalues: values
    193     },
    194     {
    195         name: "addVSi32o",
    196         func: function(x, y) { return x + "2147483647"; },
    197         xvalues: values,
    198         yvalues: [ '"2147483647"' ]
    199     },
    200     {
    201         name: "addSi32onV",
    202         func: function(x, y) { return "-2147483647" + y; },
    203         xvalues: [ '"-2147483647"' ],
    204         yvalues: values
    205     },
    206     {
    207         name: "addVSi32on",
    208         func: function(x, y) { return x + "-2147483647"; },
    209         xvalues: values,
    210         yvalues: [ '"-2147483647"' ]
    211     },
    212     {
    213         name: "addSi52V",
    214         func: function(x, y) { return "4294967296" + y; },
    215         xvalues: [ '"4294967296"' ],
    216         yvalues: values
    217     },
    218     {
    219         name: "addVSi52",
    220         func: function(x, y) { return x + "4294967296"; },
    221         xvalues: values,
    222         yvalues: [ '"4294967296"' ]
    223     },
    224     {
    225         name: "addSi52nV",
    226         func: function(x, y) { return "-4294967296" + y; },
    227         xvalues: [ '"-4294967296"' ],
    228         yvalues: values
    229     },
    230     {
    231         name: "addVSi52n",
    232         func: function(x, y) { return x + "-4294967296"; },
    233         xvalues: values,
    234         yvalues: [ '"-4294967296"' ]
    235     },
    236     {
    237         name: "addSdV",
    238         func: function(x, y) { return "100.2" + y; },
    239         xvalues: [ '"100.2"' ],
    240         yvalues: values
    241     },
    242     {
    243         name: "addVSd",
    244         func: function(x, y) { return x + "100.2"; },
    245         xvalues: values,
    246         yvalues: [ '"100.2"' ]
    247     },
    248     {
    249         name: "addSbV",
    250         func: function(x, y) { return "true" + y; },
    251         xvalues: [ '"true"' ],
    252         yvalues: values
    253     },
    254     {
    255         name: "addVSb",
    256         func: function(x, y) { return x + "true"; },
    257         xvalues: values,
    258         yvalues: [ '"true"' ]
    259     },
    260 
    261     {
    262         name: "addSV",
    263         func: function(x, y) { return "abc" + y; },
    264         xvalues: [ '"abc"' ],
    265         yvalues: values
    266     },
    267     {
    268         name: "addVS",
    269         func: function(x, y) { return x + "abc"; },
    270         xvalues: values,
    271         yvalues: [ '"abc"' ]
    272     },
    273     {
    274         name: "addNV",
    275         func: function(x, y) { return null + y; },
    276         xvalues: [ 'null' ],
    277         yvalues: values
    278     },
    279     {
    280         name: "addVN",
    281         func: function(x, y) { return x + null; },
    282         xvalues: values,
    283         yvalues: [ 'null' ]
    284     },
    285     {
    286         name: "addOV",
    287         func: function(x, y) { return o1 + y; },
    288         xvalues: [ 'o1' ],
    289         yvalues: values
    290     },
    291     {
    292         name: "addVO",
    293         func: function(x, y) { return x + o1; },
    294         xvalues: values,
    295         yvalues: [ 'o1' ]
    296     },
    297     {
    298         name: "addNaNV",
    299         func: function(x, y) { return NaN + y; },
    300         xvalues: [ 'NaN' ],
    301         yvalues: values
    302     },
    303     {
    304         name: "addVNaN",
    305         func: function(x, y) { return x + NaN; },
    306         xvalues: values,
    307         yvalues: [ 'NaN' ]
    308     },
    309 ];
    310 
    311 function initializeTestCases() {
    312     for (var test of testCases) {
    313         noInline(test.func);
    314         test.scenarios = generateScenarios(test.xvalues, test.yvalues);
    315     }
    316 }
    317 initializeTestCases();
    318 
    319 var errorReport = "";
    320 
    321 function stringifyIfNeeded(x) {
    322     if (typeof x == "string")
    323         return '"' + x + '"';
    324     return x;
    325 }
    326 
    327 function runTest(test) {
    328     var failedScenario = [];
    329     var scenarios = test.scenarios;
    330     var testFunc = test.func;
    331     try {
    332         for (var i = 0; i < 10000; i++) {
    333             for (var scenarioID = 0; scenarioID < scenarios.length; scenarioID++) {
    334                 var scenario = scenarios[scenarioID];
    335                 if (verbose)
    336                     print("Testing " + test.name + ":" + scenario.name + " on iteration " + i + ": expecting " + stringifyIfNeeded(scenario.expected));
    337 
    338                 var result = testFunc(scenario.x, scenario.y);
    339                 if (result == scenario.expected)
    340                     continue;
    341                 if (Number.isNaN(result) && Number.isNaN(scenario.expected))
    342                     continue;
    343                 if (!failedScenario[scenarioID]) {
    344                     errorReport += "FAIL: " + test.name + ":" + scenario.name + " started failing on iteration " + i
    345                         + ": expected " + stringifyIfNeeded(scenario.expected) + ", actual " + stringifyIfNeeded(result) + "\n";
    346                     if (abortOnFirstFail)
    347                         throw errorReport;
    348                     failedScenario[scenarioID] = scenario;
    349                 }
    350             }
    351         }
    352     } catch(e) {
    353         if (abortOnFirstFail)
    354             throw e; // Negate the catch by re-throwing.
    355         errorReport += "Unexpected exception: " + e + "\n";
    356     }
    357 }
    358 
    359 for (var test of testCases)
    360     runTest(test);
    361 
    362 if (errorReport !== "")
    363     throw "Error: bad result:\n" + errorReport;
     63run();
  • trunk/Source/JavaScriptCore/tests/stress/op_mul.js

    r192600 r192664  
    11//@ runFTLNoCJIT
    22
    3 // This test module aims to test the multiplication operator by comparing its runtime
    4 // behavior (using the different tiers) with expected values computed at initialization
    5 // time using the LLINT / bytecode generator.
    6 //
    7 // It works by generating test scenarios from permutations of value pairs to exercise
    8 // the multiplication operator. It computes the expected results by evaluating an
    9 // expression to multiply the values in an initialization pass. The scenarios are later
    10 // applied to a set of test functions of the forms:
    11 //
    12 //     variable * variable
    13 //     constant * variable
    14 //     variable * constant
    15 //
    16 // See generateScenarios() and initializeTestCases() for details on how the test
    17 // cases are generated.
    18 //
    193// If all goes well, this test module will terminate silently. If not, it will print
    20 // errors.
     4// errors. See binary-op-test.js for debugging options if needed.
    215
    22 var verbose = false;
    23 var abortOnFirstFail = false;
     6load("./resources/binary-op-test.js");
     7
     8//============================================================================
     9// Test configuration data:
     10
     11var opName = "mul";
     12var op = "*";
    2413
    2514var o1 = {
     
    3019var negInfinity = -1 / 0;
    3120
    32 var set1 = [
     21var values = [
    3322    'o1',
    3423    'null',
    3524    'undefined',
     25    'true',
     26    'false',
     27
    3628    'NaN',
    3729    'posInfinity',
    3830    'negInfinity',
    39     '"abc"',
    40 ];
     31    '100.2', // Some random small double value.
     32    '-100.2',
     33    '54294967296.2923', // Some random large double value.
     34    '-54294967296.2923',
    4135
    42 var set2 = [
    4336    '0',
    4437    '-0',
     
    5144    '0x10000',
    5245    '-0x10000',
    53     '2147483647',
    54     '-2147483647',
    55     '4294967296',
    56     '-4294967296',
    57     '100.2',
    58     '-100.2',
    59     'true',
    60     'false',
     46    '0x7ffffff',
     47    '-0x7ffffff',
     48    '0x100000000',
     49    '-0x100000000',
     50
     51    '"abc"',
     52    '"0"',
     53    '"-0"',
     54    '"1"',
     55    '"-1"',
     56    '"0x3fff"',
     57    '"-0x3fff"',
     58    '"0x7fff"',
     59    '"-0x7fff"',
     60    '"0x10000"',
     61    '"-0x10000"',
     62    '"0x7ffffff"',
     63    '"-0x7ffffff"',
     64    '"0x100000000"',
     65    '"-0x100000000"',
    6166];
    6267
    63 // Assemble the values that we'll be testing with:
    64 var values = [];
    65 for (var i = 0; i < set1.length; i++)
    66     values.push(set1[i]);
    67 for (var i = 0; i < set2.length; i++)
    68     values.push(set2[i]);
    69 for (var i = 0; i < set2.length; i++)
    70     values.push('"' + set2[i] + '"');
     68tests = [];
     69generateBinaryTests(tests, opName, op, "VarVar", values, values);
     70generateBinaryTests(tests, opName, op, "VarConst", values, values);
     71generateBinaryTests(tests, opName, op, "ConstVar", values, values);
    7172
    72 function generateScenarios(xvalues, yvalues) {
    73     var scenarios = [];
    74     for (var i = 0; i < xvalues.length; i++) {
    75         for (var j = 0; j < yvalues.length; j++) {
    76             var xStr = xvalues[i];
    77             var yStr = yvalues[j];
    78             var x = eval(xStr);
    79             var y = eval(yStr);
    80             var name = "(" + xStr + " * " + yStr + ")";
    81             var expected = eval("" + xStr + " * " + yStr);
    82             var scenario = { name: name, x: x, y: y, expected: expected };
    83 
    84             scenarios.push(scenario);
    85         }
    86     }
    87     return scenarios;
    88 }
    89 
    90 function printScenarios(scenarios) {
    91     for (var i = 0; i < scenarios.length; i++) {
    92         var scenario = scenarios[i];
    93         print("scenario[" + i + "]: { name: " + scenario.name + ", x: " + scenario.x, ", y: " + scenario.y + ", expected: " + scenario.expected + " }");
    94     }
    95 }
    96 
    97 var testCases = [
    98     {
    99         name: "mul",
    100         func: function(x, y) { return x * y; },
    101         xvalues: values,
    102         yvalues: values
    103     },
    104     {
    105         name: "mulI32V",
    106         func: function(x, y) { return 1 * y; },
    107         xvalues: [ '1' ],
    108         yvalues: values
    109     },
    110     {
    111         name: "mulVI32",
    112         func: function(x, y) { return x * 1; },
    113         xvalues: values,
    114         yvalues: [ '1' ]
    115     },
    116     {
    117         name: "mulI32oV",
    118         func: function(x, y) { return 2147483647 * y; },
    119         xvalues: [ '2147483647' ],
    120         yvalues: values
    121     },
    122     {
    123         name: "mulVI32o",
    124         func: function(x, y) { return x * 2147483647; },
    125         xvalues: values,
    126         yvalues: [ '2147483647' ]
    127     },
    128     {
    129         name: "mulI32onV",
    130         func: function(x, y) { return -2147483647 * y; },
    131         xvalues: [ '-2147483647' ],
    132         yvalues: values
    133     },
    134     {
    135         name: "mulVI32on",
    136         func: function(x, y) { return x * (-2147483647); },
    137         xvalues: values,
    138         yvalues: [ '-2147483647' ]
    139     },
    140     {
    141         name: "mulI52V",
    142         func: function(x, y) { return 4294967296 * y; },
    143         xvalues: [ '4294967296' ],
    144         yvalues: values
    145     },
    146     {
    147         name: "mulVI52",
    148         func: function(x, y) { return x * 4294967296; },
    149         xvalues: values,
    150         yvalues: [ '4294967296' ]
    151     },
    152     {
    153         name: "mulI52nV",
    154         func: function(x, y) { return -4294967296 * y; },
    155         xvalues: [ '-4294967296' ],
    156         yvalues: values
    157     },
    158     {
    159         name: "mulVI52n",
    160         func: function(x, y) { return x * (-4294967296); },
    161         xvalues: values,
    162         yvalues: [ '-4294967296' ]
    163     },
    164     {
    165         name: "mulDV",
    166         func: function(x, y) { return 100.2 * y; },
    167         xvalues: [ '100.2' ],
    168         yvalues: values
    169     },
    170     {
    171         name: "mulVD",
    172         func: function(x, y) { return x * 100.2; },
    173         xvalues: values,
    174         yvalues: [ '100.2' ]
    175     },
    176     {
    177         name: "mulBV",
    178         func: function(x, y) { return true * y; },
    179         xvalues: [ 'true' ],
    180         yvalues: values
    181     },
    182     {
    183         name: "mulVB",
    184         func: function(x, y) { return x * true; },
    185         xvalues: values,
    186         yvalues: [ 'true' ]
    187     },
    188     {
    189         name: "mulSi32V",
    190         func: function(x, y) { return "10" * y; },
    191         xvalues: [ '"10"' ],
    192         yvalues: values
    193     },
    194     {
    195         name: "mulVSi32",
    196         func: function(x, y) { return x * "10"; },
    197         xvalues: values,
    198         yvalues: [ '"10"' ]
    199     },
    200 
    201     {
    202         name: "mulSi32oV",
    203         func: function(x, y) { return "2147483647" * y; },
    204         xvalues: [ '"2147483647"' ],
    205         yvalues: values
    206     },
    207     {
    208         name: "mulVSi32o",
    209         func: function(x, y) { return x * "2147483647"; },
    210         xvalues: values,
    211         yvalues: [ '"2147483647"' ]
    212     },
    213     {
    214         name: "mulSi32onV",
    215         func: function(x, y) { return "-2147483647" * y; },
    216         xvalues: [ '"-2147483647"' ],
    217         yvalues: values
    218     },
    219     {
    220         name: "mulVSi32on",
    221         func: function(x, y) { return x * "-2147483647"; },
    222         xvalues: values,
    223         yvalues: [ '"-2147483647"' ]
    224     },
    225     {
    226         name: "mulSi52V",
    227         func: function(x, y) { return "4294967296" * y; },
    228         xvalues: [ '"4294967296"' ],
    229         yvalues: values
    230     },
    231     {
    232         name: "mulVSi52",
    233         func: function(x, y) { return x * "4294967296"; },
    234         xvalues: values,
    235         yvalues: [ '"4294967296"' ]
    236     },
    237     {
    238         name: "mulSi52nV",
    239         func: function(x, y) { return "-4294967296" * y; },
    240         xvalues: [ '"-4294967296"' ],
    241         yvalues: values
    242     },
    243     {
    244         name: "mulVSi52n",
    245         func: function(x, y) { return x * "-4294967296"; },
    246         xvalues: values,
    247         yvalues: [ '"-4294967296"' ]
    248     },
    249     {
    250         name: "mulSdV",
    251         func: function(x, y) { return "100.2" * y; },
    252         xvalues: [ '"100.2"' ],
    253         yvalues: values
    254     },
    255     {
    256         name: "mulVSd",
    257         func: function(x, y) { return x * "100.2"; },
    258         xvalues: values,
    259         yvalues: [ '"100.2"' ]
    260     },
    261     {
    262         name: "mulSbV",
    263         func: function(x, y) { return "true" * y; },
    264         xvalues: [ '"true"' ],
    265         yvalues: values
    266     },
    267     {
    268         name: "mulVSb",
    269         func: function(x, y) { return x * "true"; },
    270         xvalues: values,
    271         yvalues: [ '"true"' ]
    272     },
    273 
    274     {
    275         name: "mulSV",
    276         func: function(x, y) { return "abc" * y; },
    277         xvalues: [ '"abc"' ],
    278         yvalues: values
    279     },
    280     {
    281         name: "mulVS",
    282         func: function(x, y) { return x * "abc"; },
    283         xvalues: values,
    284         yvalues: [ '"abc"' ]
    285     },
    286     {
    287         name: "mulNV",
    288         func: function(x, y) { return null * y; },
    289         xvalues: [ 'null' ],
    290         yvalues: values
    291     },
    292     {
    293         name: "mulVN",
    294         func: function(x, y) { return x * null; },
    295         xvalues: values,
    296         yvalues: [ 'null' ]
    297     },
    298     {
    299         name: "mulOV",
    300         func: function(x, y) { return o1 * y; },
    301         xvalues: [ 'o1' ],
    302         yvalues: values
    303     },
    304     {
    305         name: "mulVO",
    306         func: function(x, y) { return x * o1; },
    307         xvalues: values,
    308         yvalues: [ 'o1' ]
    309     },
    310     {
    311         name: "mulNaNV",
    312         func: function(x, y) { return NaN * y; },
    313         xvalues: [ 'NaN' ],
    314         yvalues: values
    315     },
    316     {
    317         name: "mulVNaN",
    318         func: function(x, y) { return x * NaN; },
    319         xvalues: values,
    320         yvalues: [ 'NaN' ]
    321     },
    322 ];
    323 
    324 function initializeTestCases() {
    325     for (var test of testCases) {
    326         noInline(test.func);
    327         test.scenarios = generateScenarios(test.xvalues, test.yvalues);
    328     }
    329 }
    330 initializeTestCases();
    331 
    332 var errorReport = "";
    333 
    334 function stringifyIfNeeded(x) {
    335     if (typeof x == "string")
    336         return '"' + x + '"';
    337     return x;
    338 }
    339 
    340 function isIdentical(x, y) {
    341     if (x == y) {
    342         if (x)
    343             return true;
    344         // Distinguish between 0 and negative 0.
    345         if (1 / x == 1 / y)
    346             return true;
    347     } else if (Number.isNaN(x) && Number.isNaN(y))
    348         return true;
    349     return false;
    350 }
    351 
    352 function runTest(test) {
    353     var failedScenario = [];
    354     var scenarios = test.scenarios;
    355     var testFunc = test.func;
    356     try {
    357         for (var i = 0; i < 10000; i++) {
    358             for (var scenarioID = 0; scenarioID < scenarios.length; scenarioID++) {
    359                 var scenario = scenarios[scenarioID];
    360                 if (verbose)
    361                     print("Testing " + test.name + ":" + scenario.name + " on iteration " + i + ": expecting " + stringifyIfNeeded(scenario.expected));
    362 
    363                 var result = testFunc(scenario.x, scenario.y);
    364                 if (isIdentical(result, scenario.expected))
    365                     continue;
    366                 if (!failedScenario[scenarioID]) {
    367                     errorReport += "FAIL: " + test.name + ":" + scenario.name + " started failing on iteration " + i
    368                         + ": expected " + stringifyIfNeeded(scenario.expected) + ", actual " + stringifyIfNeeded(result) + "\n";
    369                     if (abortOnFirstFail)
    370                         throw errorReport;
    371                     failedScenario[scenarioID] = scenario;
    372                 }
    373             }
    374         }
    375     } catch(e) {
    376         if (abortOnFirstFail)
    377             throw e; // Negate the catch by re-throwing.
    378         errorReport += "Unexpected exception: " + e + "\n";
    379     }
    380 }
    381 
    382 for (var test of testCases)
    383     runTest(test);
    384 
    385 if (errorReport !== "")
    386     throw "Error: bad result:\n" + errorReport;
     73run();
  • trunk/Source/JavaScriptCore/tests/stress/op_sub.js

    r191683 r192664  
    11//@ runFTLNoCJIT
    22
    3 // This test module aims to test the subtraction operator by comparing its runtime
    4 // behavior (using the different tiers) with expected values computed at initialization
    5 // time using the LLINT / bytecode generator.
    6 //
    7 // It works by generating test scenarios from permutations of value pairs to exercise
    8 // the subtraction operator. It computes the expected results by evaluating an expression
    9 // to subtract the values in an initialization pass. The scenarios are later applied to
    10 // a set of test functions of the forms:
    11 //
    12 //     variable - variable
    13 //     constant - variable
    14 //     variable - constant
    15 //
    16 // See generateScenarios() and initializeTestCases() for details on how the test
    17 // cases are generated.
    18 //
    193// If all goes well, this test module will terminate silently. If not, it will print
    20 // errors.
     4// errors. See binary-op-test.js for debugging options if needed.
    215
    22 var verbose = false;
    23 var abortOnFirstFail = false;
     6load("./resources/binary-op-test.js");
     7
     8//============================================================================
     9// Test configuration data:
     10
     11var opName = "sub";
     12var op = "-";
    2413
    2514var o1 = {
     
    2716};
    2817
    29 var set1 = [
     18var posInfinity = 1 / 0;
     19var negInfinity = -1 / 0;
     20
     21var values = [
    3022    'o1',
    3123    'null',
    3224    'undefined',
     25    'true',
     26    'false',
     27
    3328    'NaN',
     29    'posInfinity',
     30    'negInfinity',
     31    '100.2', // Some random small double value.
     32    '-100.2',
     33    '54294967296.2923', // Some random large double value.
     34    '-54294967296.2923',
     35
     36    '0',
     37    '-0',
     38    '1',
     39    '-1',
     40    '0x3fff',
     41    '-0x3fff',
     42    '0x7fff',
     43    '-0x7fff',
     44    '0x10000',
     45    '-0x10000',
     46    '0x7ffffff',
     47    '-0x7ffffff',
     48    '0x100000000',
     49    '-0x100000000',
     50
    3451    '"abc"',
     52    '"0"',
     53    '"-0"',
     54    '"1"',
     55    '"-1"',
     56    '"0x3fff"',
     57    '"-0x3fff"',
     58    '"0x7fff"',
     59    '"-0x7fff"',
     60    '"0x10000"',
     61    '"-0x10000"',
     62    '"0x7ffffff"',
     63    '"-0x7ffffff"',
     64    '"0x100000000"',
     65    '"-0x100000000"',
    3566];
    3667
    37 var set2 = [
    38     '10',
    39     '-10',
    40     '2147483647',
    41     '-2147483647',
    42     '4294967296',
    43     '-4294967296',
    44     '100.2',
    45     '-100.2',
    46     'true',
    47     'false',
    48 ];
     68tests = [];
     69generateBinaryTests(tests, opName, op, "VarVar", values, values);
     70generateBinaryTests(tests, opName, op, "VarConst", values, values);
     71generateBinaryTests(tests, opName, op, "ConstVar", values, values);
    4972
    50 // Assemble the values that we'll be testing with:
    51 var values = [];
    52 for (var i = 0; i < set1.length; i++)
    53     values.push(set1[i]);
    54 for (var i = 0; i < set2.length; i++)
    55     values.push(set2[i]);
    56 for (var i = 0; i < set2.length; i++)
    57     values.push('"' + set2[i] + '"');
    58 
    59 function generateScenarios(xvalues, yvalues) {
    60     var scenarios = [];
    61     for (var i = 0; i < xvalues.length; i++) {
    62         for (var j = 0; j < yvalues.length; j++) {
    63             var xStr = xvalues[i];
    64             var yStr = yvalues[j];
    65             var x = eval(xStr);
    66             var y = eval(yStr);
    67             var name = "(" + xStr + " - " + yStr + ")";
    68             var expected = eval("" + xStr + " - " + yStr);
    69             var scenario = { name: name, x: x, y: y, expected: expected };
    70 
    71             scenarios.push(scenario);
    72         }
    73     }
    74     return scenarios;
    75 }
    76 
    77 function printScenarios(scenarios) {
    78     for (var i = 0; i < scenarios.length; i++) {
    79         var scenario = scenarios[i];
    80         print("scenario[" + i + "]: { name: " + scenario.name + ", x: " + scenario.x, ", y: " + scenario.y + ", expected: " + scenario.expected + " }");
    81     }
    82 }
    83 
    84 var testCases = [
    85     {
    86         name: "sub",
    87         func: function(x, y) { return x - y; },
    88         xvalues: values,
    89         yvalues: values
    90     },
    91     {
    92         name: "subI32V",
    93         func: function(x, y) { return 10 - y; },
    94         xvalues: [ '10' ],
    95         yvalues: values
    96     },
    97     {
    98         name: "subVI32",
    99         func: function(x, y) { return x - 10; },
    100         xvalues: values,
    101         yvalues: [ '10' ]
    102     },
    103     {
    104         name: "subI32oV",
    105         func: function(x, y) { return -2147483647 - y; },
    106         xvalues: [ '-2147483647' ],
    107         yvalues: values
    108     },
    109     {
    110         name: "subVI32o",
    111         func: function(x, y) { return x - 2147483647; },
    112         xvalues: values,
    113         yvalues: [ '2147483647' ]
    114     },
    115     {
    116         name: "subI52V",
    117         func: function(x, y) { return 4294967296 - y; },
    118         xvalues: [ '4294967296' ],
    119         yvalues: values
    120     },
    121     {
    122         name: "subVI52",
    123         func: function(x, y) { return x - 4294967296; },
    124         xvalues: values,
    125         yvalues: [ '4294967296' ]
    126     },
    127     {
    128         name: "subDV",
    129         func: function(x, y) { return 100.2 - y; },
    130         xvalues: [ '100.2' ],
    131         yvalues: values
    132     },
    133     {
    134         name: "subVD",
    135         func: function(x, y) { return x - 100.2; },
    136         xvalues: values,
    137         yvalues: [ '100.2' ]
    138     },
    139     {
    140         name: "subBV",
    141         func: function(x, y) { return true - y; },
    142         xvalues: [ 'true' ],
    143         yvalues: values
    144     },
    145     {
    146         name: "subVB",
    147         func: function(x, y) { return x - true; },
    148         xvalues: values,
    149         yvalues: [ 'true' ]
    150     },
    151     {
    152         name: "subSi32V",
    153         func: function(x, y) { return "10" - y; },
    154         xvalues: [ '"10"' ],
    155         yvalues: values
    156     },
    157     {
    158         name: "subVSi32",
    159         func: function(x, y) { return x - "10"; },
    160         xvalues: values,
    161         yvalues: [ '"10"' ]
    162     },
    163 
    164     {
    165         name: "subSi32oV",
    166         func: function(x, y) { return "-2147483647" - y; },
    167         xvalues: [ '"-2147483647"' ],
    168         yvalues: values
    169     },
    170     {
    171         name: "subVSi32o",
    172         func: function(x, y) { return x - "2147483647"; },
    173         xvalues: values,
    174         yvalues: [ '"2147483647"' ]
    175     },
    176     {
    177         name: "subSi52V",
    178         func: function(x, y) { return "4294967296" - y; },
    179         xvalues: [ '"4294967296"' ],
    180         yvalues: values
    181     },
    182     {
    183         name: "subVSi52",
    184         func: function(x, y) { return x - "4294967296"; },
    185         xvalues: values,
    186         yvalues: [ '"4294967296"' ]
    187     },
    188     {
    189         name: "subSdV",
    190         func: function(x, y) { return "100.2" - y; },
    191         xvalues: [ '"100.2"' ],
    192         yvalues: values
    193     },
    194     {
    195         name: "subVSd",
    196         func: function(x, y) { return x - "100.2"; },
    197         xvalues: values,
    198         yvalues: [ '"100.2"' ]
    199     },
    200     {
    201         name: "subSbV",
    202         func: function(x, y) { return "true" - y; },
    203         xvalues: [ '"true"' ],
    204         yvalues: values
    205     },
    206     {
    207         name: "subVSb",
    208         func: function(x, y) { return x - "true"; },
    209         xvalues: values,
    210         yvalues: [ '"true"' ]
    211     },
    212 
    213     {
    214         name: "subSV",
    215         func: function(x, y) { return "abc" - y; },
    216         xvalues: [ '"abc"' ],
    217         yvalues: values
    218     },
    219     {
    220         name: "subVS",
    221         func: function(x, y) { return x - "abc"; },
    222         xvalues: values,
    223         yvalues: [ '"abc"' ]
    224     },
    225     {
    226         name: "subNV",
    227         func: function(x, y) { return null - y; },
    228         xvalues: [ 'null' ],
    229         yvalues: values
    230     },
    231     {
    232         name: "subVN",
    233         func: function(x, y) { return x - null; },
    234         xvalues: values,
    235         yvalues: [ 'null' ]
    236     },
    237     {
    238         name: "subOV",
    239         func: function(x, y) { return o1 - y; },
    240         xvalues: [ 'o1' ],
    241         yvalues: values
    242     },
    243     {
    244         name: "subVO",
    245         func: function(x, y) { return x - o1; },
    246         xvalues: values,
    247         yvalues: [ 'o1' ]
    248     },
    249     {
    250         name: "subNaNV",
    251         func: function(x, y) { return NaN - y; },
    252         xvalues: [ 'NaN' ],
    253         yvalues: values
    254     },
    255     {
    256         name: "subVNaN",
    257         func: function(x, y) { return x - NaN; },
    258         xvalues: values,
    259         yvalues: [ 'NaN' ]
    260     },
    261 ];
    262 
    263 function initializeTestCases() {
    264     for (var test of testCases) {
    265         noInline(test.func);
    266         test.scenarios = generateScenarios(test.xvalues, test.yvalues);
    267     }
    268 }
    269 initializeTestCases();
    270 
    271 var errorReport = "";
    272 
    273 function runTest(test) {
    274     var failedScenario = [];
    275     var scenarios = test.scenarios;
    276     var testFunc = test.func;
    277     try {
    278         for (var i = 0; i < 10000; i++) {
    279             for (var scenarioID = 0; scenarioID < scenarios.length; scenarioID++) {
    280                 var scenario = scenarios[scenarioID];
    281                 if (verbose)
    282                     print("Testing " + test.name + ":" + scenario.name + " on iteration " + i + ": expecting " + scenario.expected);
    283 
    284                 var result = testFunc(scenario.x, scenario.y);
    285                 if (result == scenario.expected)
    286                     continue;
    287                 if (Number.isNaN(result) && Number.isNaN(scenario.expected))
    288                     continue;
    289                 if (!failedScenario[scenarioID]) {
    290                     errorReport += "FAIL: " + test.name + ":" + scenario.name + " started failing on iteration " + i + ": expected " + scenario.expected + ", actual " + result + "\n";
    291                     if (abortOnFirstFail)
    292                         throw errorReport;
    293                     failedScenario[scenarioID] = scenario;
    294                 }
    295             }
    296         }
    297     } catch(e) {
    298         if (abortOnFirstFail)
    299             throw e; // Negate the catch by re-throwing.
    300         errorReport += "Unexpected exception: " + e + "\n";
    301     }
    302 }
    303 
    304 for (var test of testCases)
    305     runTest(test);
    306 
    307 if (errorReport !== "")
    308     throw "Error: bad result:\n" + errorReport;
     73run();
Note: See TracChangeset for help on using the changeset viewer.