Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  profiling.js   Sprache: JAVA

 
// |jit-test| skip-if: !WasmHelpers.isSingleStepProfilingEnabled

const Module = WebAssembly.Module;
const Instance = WebAssembly.Instance;
const Table = WebAssembly.Table;

const {
    assertEqImpreciseStacks,
    assertEqPreciseStacks,
    startProfiling,
    endProfiling
} = WasmHelpers;

function test(code, importObj, expectedStacks)
{
    enableGeckoProfiling();

    var f = wasmEvalText(code, importObj).exports[""];
    startProfiling();
    f();
    assertEqImpreciseStacks(endProfiling(), expectedStacks);

    disableGeckoProfiling();
}

test(
`(module
    (func (result i32) (i32.const 42))
    (export "" (func 0))
)`,
{},
[""">""0,>"">"""]);

test(
`(module
    (func (result i32) (i32.add (call 1) (i32.const 1)))
    (func (result i32) (i32.const 42))
    (export "" (func 0))
)`,
{},
[""">""0,>""1,0,>""0,>"">"""]);

test(
`(module
    (func $foo (call_indirect (type 0) (i32.const 0)))
    (func $bar)
    (table funcref (elem $bar))
    (export "" (func $foo))
)`,
{},
[""">""foo,>""bar,foo,>""foo,>"">"""]);

test(
`(module
    (import "" "foo" (func $foo))
    (table funcref (elem $foo))
    (func $bar (call_indirect (type 0) (i32.const 0)))
    (export "" (func $bar))
)`,
{"":{foo:()=>{}}},
[""">""bar,>""foo,bar,>""<,foo,bar,>""foo,bar,>""bar,>"">"""]);

test(`(module
    (import "Math" "sin" (func $f32 (param f32) (result f32)))
    (func (export "") (param f32) (result f32)
        local.get 0
        call $f32
    )
)`,
this,
[""">""1,>""<,1,>""1,>"">"""]);

if (getBuildConfiguration("arm-simulator")) {
    // On ARM, some int64 operations are calls to C++.
    for (let op of ['div_s''rem_s''div_u''rem_u']) {
        test(`(module
            (func (export "") (param i32) (result i32)
                local.get 0
                i64.extend_i32_s
                i64.const 0x1a2b3c4d5e6f
                i64.${op}
                i32.wrap_i64
            )
        )`,
        this,
        [""">""0,>""<,0,>", `i64.${op},0,>`, "<,0,>""0,>"">"""],
        );
    }
}

// memory.size is a callout.
test(`(module
    (memory 1)
    (func (export "") (result i32)
         memory.size
    )
)`,
this,
[""">""0,>""<,0,>""memory.size m32,0,>""<,0,>""0,>"">"""],
);

// memory.grow is a callout.
test(`(module
    (memory 1)
    (func (export "") (result i32)
         i32.const 1
         memory.grow
    )
)`,
this,
[""">""0,>""<,0,>""memory.grow m32,0,>""<,0,>""0,>"">"""],
);

// A few math builtins.
for (let type of ['f32''f64']) {
    for (let func of ['ceil''floor''nearest''trunc']) {
        if (getBuildConfiguration("arm64")) {
            continue;
        }
        test(`(module
            (func (export "") (param ${type}) (result ${type})
                local.get 0
                ${type}.${func}
            )
        )`,
        this,
        [""">""0,>""<,0,>", `${type}.${func},0,>`, "<,0,>""0,>"">"""]);
    }
}

(function() {
    // Error handling.
    function testError(code, error, expect)
    {
        enableGeckoProfiling();
        var f = wasmEvalText(code).exports[""];
        enableSingleStepProfiling();
        assertThrowsInstanceOf(f, error);
        assertEqImpreciseStacks(disableSingleStepProfiling(), expect);
        disableGeckoProfiling();
    }

    testError(
    `(module
        (func $foo (unreachable))
        (func (export "") (call $foo))
    )`,
    WebAssembly.RuntimeError,
    [""">""1,>""foo,1,>""1,>"""">"""]);

    testError(
    `(module
        (type $good (func))
        (type $bad (func (param i32)))
        (func $foo (call_indirect (type $bad) (i32.const 1) (i32.const 0)))
        (func $bar (type $good))
        (table funcref (elem $bar))
        (export "" (func $foo))
    )`,
    WebAssembly.RuntimeError,
    [""">""foo,>""bar,foo,>"">"""">"""]);
})();

(function() {
    // Tables fun.
    var e = wasmEvalText(`
    (module
        (func $foo (result i32) (i32.const 42))
        (export "foo" (func $foo))
        (func $bar (result i32) (i32.const 13))
        (table 10 funcref)
        (elem (i32.const 0) $foo $bar)
        (export "tbl" (table 0))
    )`).exports;
    assertEq(e.foo(), 42);
    assertEq(e.tbl.get(0)(), 42);
    assertEq(e.tbl.get(1)(), 13);

    enableGeckoProfiling();
    enableSingleStepProfiling();
    assertEq(e.tbl.get(0)(), 42);
    assertEqImpreciseStacks(disableSingleStepProfiling(), [""">""foo,>"">"""]);
    disableGeckoProfiling();

    assertEq(e.foo(), 42);
    assertEq(e.tbl.get(0)(), 42);
    assertEq(e.tbl.get(1)(), 13);

    enableGeckoProfiling();
    enableSingleStepProfiling();
    assertEq(e.tbl.get(1)(), 13);
    assertEqImpreciseStacks(disableSingleStepProfiling(), [""">""bar,>"">"""]);
    disableGeckoProfiling();

    assertEq(e.tbl.get(0)(), 42);
    assertEq(e.tbl.get(1)(), 13);
    assertEq(e.foo(), 42);

    enableGeckoProfiling();
    enableSingleStepProfiling();
    assertEq(e.foo(), 42);
    assertEq(e.tbl.get(1)(), 13);
    assertEqImpreciseStacks(disableSingleStepProfiling(), [""">""foo,>"">"""">""bar,>"">"""]);
    disableGeckoProfiling();

    var e2 = wasmEvalText(`
    (module
        (type $v2i (func (result i32)))
        (import "a" "b" (table 10 funcref))
        (elem (i32.const 2) $bar)
        (func $bar (result i32) (i32.const 99))
        (func $baz (param $i i32) (result i32) (call_indirect (type $v2i) (local.get $i)))
        (export "baz" (func $baz))
    )`, {a:{b:e.tbl}}).exports;

    enableGeckoProfiling();
    enableSingleStepProfiling();
    assertEq(e2.baz(0), 42);
    assertEqImpreciseStacks(disableSingleStepProfiling(), [""">""baz,>""foo,baz,>""baz,>"">"""]);
    disableGeckoProfiling();

    enableGeckoProfiling();
    enableSingleStepProfiling();
    assertEq(e2.baz(1), 13);
    assertEqImpreciseStacks(disableSingleStepProfiling(), [""">""baz,>""bar,baz,>""baz,>"">"""]);
    disableGeckoProfiling();

    enableGeckoProfiling();
    enableSingleStepProfiling();
    assertEq(e2.baz(2), 99);
    assertEqImpreciseStacks(disableSingleStepProfiling(), [""">""baz,>""bar,baz,>""baz,>"">"""]);
    disableGeckoProfiling();
})();

(function() {
    // Optimized wasm->wasm import.
    var m1 = new Module(wasmTextToBinary(`(module
        (func $foo (result i32) (i32.const 42))
        (export "foo" (func $foo))
    )`));
    var m2 = new Module(wasmTextToBinary(`(module
        (import "a" "foo" (func $foo (result i32)))
        (func $bar (result i32) (call $foo))
        (export "bar" (func $bar))
    )`));

    // Instantiate while not active:
    var e1 = new Instance(m1).exports;
    var e2 = new Instance(m2, {a:e1}).exports;
    enableGeckoProfiling();
    enableSingleStepProfiling();
    assertEq(e2.bar(), 42);
    assertEqImpreciseStacks(disableSingleStepProfiling(), [""">""bar,>""foo,bar,>""bar,>"">"""]);
    disableGeckoProfiling();
    assertEq(e2.bar(), 42);

    // Instantiate while active:
    enableGeckoProfiling();
    var e3 = new Instance(m1).exports;
    var e4 = new Instance(m2, {a:e3}).exports;
    enableSingleStepProfiling();
    assertEq(e4.bar(), 42);
    assertEqImpreciseStacks(disableSingleStepProfiling(), [""">""bar,>""foo,bar,>""bar,>"">"""]);
    disableGeckoProfiling();
    assertEq(e4.bar(), 42);
})();

(function() {
    // FFIs test.
    let prevOptions = getJitCompilerOptions();

    // Skip tests if baseline isn't enabled, since the stacks might differ by
    // a few instructions.
    if (prevOptions['baseline.enable'] === 0)
        return;

    setJitCompilerOption("baseline.warmup.trigger", 10);

    enableGeckoProfiling();

    var m = new Module(wasmTextToBinary(`(module
        (import "a" "ffi" (func $ffi (param i32) (result i32)))

        (import "a" "sumTwo" (func $missingOneArg (param i32) (result i32)))

        (func (export "foo") (param i32) (result i32)
         local.get 0
         call $ffi)

        (func (export "id") (param i32) (result i32)
         local.get 0
         call $missingOneArg
        )
    )`));

    var valueToConvert = 0;
    function ffi(n) {
        new Error().stack; // enter VM to clobber FP register.
        if (n == 1337) { return valueToConvert };
        return 42;
    }

    function sumTwo(a, b) {
        return (a|0)+(b|0)|0;
    }

    // Baseline compile ffi.
    for (var i = 20; i --> 0;) {
        ffi(i);
        sumTwo(i-1, i+1);
    }

    var imports = {
        a: {
            ffi,
            sumTwo
        }
    };

    var i = new Instance(m, imports).exports;

    // Enable the jit exit.
    assertEq(i.foo(0), 42);
    assertEq(i.id(13), 13);

    // Test normal conditions.
    enableSingleStepProfiling();
    assertEq(i.foo(0), 42);
    assertEqImpreciseStacks(disableSingleStepProfiling(), [""">""2,>""<,2,>",
        // Losing stack information while the JIT func prologue sets profiler
        // virtual FP.
        "",
        // Callee time.
        "<,2,>",
        // Losing stack information while we're exiting JIT func epilogue and
        // recovering wasm FP.
        "",
        // Back into the jit exit (frame info has been recovered).
        "<,2,>",
        // Normal unwinding.
        "2,>"">"""]);

    // Test rectifier frame.
    enableSingleStepProfiling();
    assertEq(i.id(100), 100);
    assertEqImpreciseStacks(disableSingleStepProfiling(), [""">""3,>""<,3,>",
        // Rectifier frame time is spent here (lastProfilingFrame has not been
        // set).
        "",
        "<,3,>",
        // Rectifier frame unwinding time is spent here.
        "",
        "<,3,>",
        "3,>"">"""]);

    // Test OOL coercion path.
    valueToConvert = 2**31;

    enableSingleStepProfiling();
    assertEq(i.foo(1337), -(2**31));
    assertEqImpreciseStacks(disableSingleStepProfiling(), [""">""2,>""<,2,>""""<,2,>""",
        // Back into the jit exit (frame info has been recovered).
        // Inline conversion fails, we skip to the OOL path, call from there
        // and get back to the jit exit.
        "<,2,>",
        // Normal unwinding.
        "2,>"">"""]);

    disableGeckoProfiling();
    setJitCompilerOption("baseline.warmup.trigger", prevOptions["baseline.warmup.trigger"]);
})();

// Make sure it's possible to single-step through call through debug-enabled code.
(function() {
 if (wasmCompileMode().includes("ion")) return;

 enableGeckoProfiling();

 let g = newGlobal({newCompartment: true});
 let dbg = new Debugger(g);
 dbg.onEnterFrame = () => {};
 enableSingleStepProfiling();
 g.eval(`
    var code = wasmTextToBinary('(module (func (export "run") (result i32) i32.const 42))');
    var i = new WebAssembly.Instance(new WebAssembly.Module(code));
    assertEq(i.exports.run(), 42);
 `);

 disableSingleStepProfiling();
 disableGeckoProfiling();
})();

// Ion->wasm calls.
let func = wasmEvalText(`(module
    (func $inner (param i32) (param i32) (result i32)
        local.get 0
        local.get 1
        i32.add
    )
    (func (export "add") (param i32) (param i32) (result i32)
     local.get 0
     local.get 1
     call $inner
    )
)`).exports.add;

(function() {
    enableGeckoProfiling();
    // 10 is enough in ion eager mode.
    for (let i = 0; i < 10; i++) {
        enableSingleStepProfiling();
        let res = func(i - 1, i + 1);
        assertEqPreciseStacks(disableSingleStepProfiling(), [
            ['''>''1,>''inner,1,>' , '1,>''>'''],      // slow entry
            ['''!>''1,!>''inner,1,!>' , '1,!>''!>'''], // fast entry
            ['''1''inner,1' , '1'''],                      // inlined jit call
        ]);
        assertEq(res, i+i);
    }
    disableGeckoProfiling();
})();

Messung V0.5
C=94 H=88 G=90

¤ Dauer der Verarbeitung: 0.6 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge