diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:34:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:34:50 +0000 |
commit | def92d1b8e9d373e2f6f27c366d578d97d8960c6 (patch) | |
tree | 2ef34b9ad8bb9a9220e05d60352558b15f513894 /js/src/jsapi-tests | |
parent | Adding debian version 125.0.3-1. (diff) | |
download | firefox-def92d1b8e9d373e2f6f27c366d578d97d8960c6.tar.xz firefox-def92d1b8e9d373e2f6f27c366d578d97d8960c6.zip |
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/jsapi-tests')
-rw-r--r-- | js/src/jsapi-tests/moz.build | 1 | ||||
-rw-r--r-- | js/src/jsapi-tests/testDeduplication.cpp | 2 | ||||
-rw-r--r-- | js/src/jsapi-tests/testGCHeapBarriers.cpp | 1 | ||||
-rw-r--r-- | js/src/jsapi-tests/testGCMarking.cpp | 1 | ||||
-rw-r--r-- | js/src/jsapi-tests/testGCUniqueId.cpp | 1 | ||||
-rw-r--r-- | js/src/jsapi-tests/testIsInsideNursery.cpp | 83 | ||||
-rw-r--r-- | js/src/jsapi-tests/testSparseBitmap.cpp | 47 | ||||
-rw-r--r-- | js/src/jsapi-tests/testWasmEncoder.cpp | 117 |
8 files changed, 248 insertions, 5 deletions
diff --git a/js/src/jsapi-tests/moz.build b/js/src/jsapi-tests/moz.build index 9e2c99cfa6..f6cc3b3f70 100644 --- a/js/src/jsapi-tests/moz.build +++ b/js/src/jsapi-tests/moz.build @@ -138,6 +138,7 @@ UNIFIED_SOURCES += [ "testUbiNode.cpp", "testUncaughtSymbol.cpp", "testUTF8.cpp", + "testWasmEncoder.cpp", "testWasmLEB128.cpp", "testWasmReturnCalls.cpp", "testWeakMap.cpp", diff --git a/js/src/jsapi-tests/testDeduplication.cpp b/js/src/jsapi-tests/testDeduplication.cpp index 6ee3cb989d..7f5eb68e37 100644 --- a/js/src/jsapi-tests/testDeduplication.cpp +++ b/js/src/jsapi-tests/testDeduplication.cpp @@ -33,6 +33,8 @@ static bool SameChars(JSContext* cx, JSString* str1, JSString* str2, } BEGIN_TEST(testDeduplication_ASSC) { + AutoGCParameter disableSemispace(cx, JSGC_SEMISPACE_NURSERY_ENABLED, 0); + // Test with a long enough string to avoid inline chars allocation. const char text[] = "Andthebeastshallcomeforthsurroundedbyaroilingcloudofvengeance." diff --git a/js/src/jsapi-tests/testGCHeapBarriers.cpp b/js/src/jsapi-tests/testGCHeapBarriers.cpp index 9493049e16..a23e41ae6e 100644 --- a/js/src/jsapi-tests/testGCHeapBarriers.cpp +++ b/js/src/jsapi-tests/testGCHeapBarriers.cpp @@ -169,6 +169,7 @@ static void MakeGray(const JS::ArrayBufferOrView& view) { // - WeakHeapPtr BEGIN_TEST(testGCHeapPostBarriers) { AutoLeaveZeal nozeal(cx); + AutoGCParameter disableSemispace(cx, JSGC_SEMISPACE_NURSERY_ENABLED, 0); /* Sanity check - objects start in the nursery and then become tenured. */ JS_GC(cx); diff --git a/js/src/jsapi-tests/testGCMarking.cpp b/js/src/jsapi-tests/testGCMarking.cpp index dc2f1e0f4d..0a51bf21bc 100644 --- a/js/src/jsapi-tests/testGCMarking.cpp +++ b/js/src/jsapi-tests/testGCMarking.cpp @@ -344,6 +344,7 @@ BEGIN_TEST(testIncrementalRoots) { // Tenure everything so intentionally unrooted objects don't move before we // can use them. + AutoGCParameter disableSemispace(cx, JSGC_SEMISPACE_NURSERY_ENABLED, 0); cx->runtime()->gc.minorGC(JS::GCReason::API); // Release all roots except for the RootedObjectVector. diff --git a/js/src/jsapi-tests/testGCUniqueId.cpp b/js/src/jsapi-tests/testGCUniqueId.cpp index 1c5652f280..577582837d 100644 --- a/js/src/jsapi-tests/testGCUniqueId.cpp +++ b/js/src/jsapi-tests/testGCUniqueId.cpp @@ -23,6 +23,7 @@ static void MinimizeHeap(JSContext* cx) { BEGIN_TEST(testGCUID) { AutoLeaveZeal nozeal(cx); + AutoGCParameter gcparam(cx, JSGC_SEMISPACE_NURSERY_ENABLED, 0); uint64_t uid = 0; uint64_t tmp = 0; diff --git a/js/src/jsapi-tests/testIsInsideNursery.cpp b/js/src/jsapi-tests/testIsInsideNursery.cpp index 793a1ed3cc..c7383f460b 100644 --- a/js/src/jsapi-tests/testIsInsideNursery.cpp +++ b/js/src/jsapi-tests/testIsInsideNursery.cpp @@ -9,6 +9,8 @@ #include "vm/JSContext-inl.h" +using namespace js; + BEGIN_TEST(testIsInsideNursery) { /* Non-GC things are never inside the nursery. */ CHECK(!cx->nursery().isInside(cx)); @@ -30,9 +32,9 @@ BEGIN_TEST(testIsInsideNursery) { JS::Rooted<JSString*> string(cx, JS_NewStringCopyZ(cx, oolstr)); /* Objects are initially allocated in the nursery. */ - CHECK(js::gc::IsInsideNursery(object)); + CHECK(gc::IsInsideNursery(object)); /* As are strings. */ - CHECK(js::gc::IsInsideNursery(string)); + CHECK(gc::IsInsideNursery(string)); /* And their contents. */ { JS::AutoCheckCannotGC nogc; @@ -44,8 +46,8 @@ BEGIN_TEST(testIsInsideNursery) { JS_GC(cx); /* And are tenured if still live after a GC. */ - CHECK(!js::gc::IsInsideNursery(object)); - CHECK(!js::gc::IsInsideNursery(string)); + CHECK(!gc::IsInsideNursery(object)); + CHECK(!gc::IsInsideNursery(string)); { JS::AutoCheckCannotGC nogc; const JS::Latin1Char* strdata = @@ -56,3 +58,76 @@ BEGIN_TEST(testIsInsideNursery) { return true; } END_TEST(testIsInsideNursery) + +BEGIN_TEST(testSemispaceNursery) { + AutoGCParameter enableSemispace(cx, JSGC_SEMISPACE_NURSERY_ENABLED, 1); + + JS_GC(cx); + + /* Objects are initially allocated in the nursery. */ + RootedObject object(cx, JS_NewPlainObject(cx)); + CHECK(gc::IsInsideNursery(object)); + + /* Minor GC with the evict reason tenures them. */ + cx->minorGC(JS::GCReason::EVICT_NURSERY); + CHECK(!gc::IsInsideNursery(object)); + + /* Minor GC with other reasons gives them a second chance. */ + object = JS_NewPlainObject(cx); + void* ptr = object; + CHECK(gc::IsInsideNursery(object)); + cx->minorGC(JS::GCReason::API); + CHECK(ptr != object); + CHECK(gc::IsInsideNursery(object)); + ptr = object; + cx->minorGC(JS::GCReason::API); + CHECK(!gc::IsInsideNursery(object)); + CHECK(ptr != object); + + CHECK(testReferencesBetweenGenerations(0)); + CHECK(testReferencesBetweenGenerations(1)); + CHECK(testReferencesBetweenGenerations(2)); + + return true; +} + +bool testReferencesBetweenGenerations(size_t referrerGeneration) { + MOZ_ASSERT(referrerGeneration <= 2); + + RootedObject referrer(cx, JS_NewPlainObject(cx)); + CHECK(referrer); + CHECK(gc::IsInsideNursery(referrer)); + + for (size_t i = 0; i < referrerGeneration; i++) { + cx->minorGC(JS::GCReason::API); + } + MOZ_ASSERT(IsInsideNursery(referrer) == (referrerGeneration < 2)); + + RootedObject object(cx, JS_NewPlainObject(cx)); + CHECK(gc::IsInsideNursery(object)); + RootedValue value(cx, JS::ObjectValue(*object)); + CHECK(JS_DefineProperty(cx, referrer, "prop", value, 0)); + CHECK(JS_GetProperty(cx, referrer, "prop", &value)); + CHECK(&value.toObject() == object); + CHECK(JS_SetElement(cx, referrer, 0, value)); + CHECK(JS_GetElement(cx, referrer, 0, &value)); + CHECK(&value.toObject() == object); + + cx->minorGC(JS::GCReason::API); + CHECK(gc::IsInsideNursery(object)); + CHECK(JS_GetProperty(cx, referrer, "prop", &value)); + CHECK(&value.toObject() == object); + CHECK(JS_GetElement(cx, referrer, 0, &value)); + CHECK(&value.toObject() == object); + + cx->minorGC(JS::GCReason::API); + CHECK(!gc::IsInsideNursery(object)); + CHECK(JS_GetProperty(cx, referrer, "prop", &value)); + CHECK(&value.toObject() == object); + CHECK(JS_GetElement(cx, referrer, 0, &value)); + CHECK(&value.toObject() == object); + + return true; +} + +END_TEST(testSemispaceNursery) diff --git a/js/src/jsapi-tests/testSparseBitmap.cpp b/js/src/jsapi-tests/testSparseBitmap.cpp index bd5e7fee95..936132ab0c 100644 --- a/js/src/jsapi-tests/testSparseBitmap.cpp +++ b/js/src/jsapi-tests/testSparseBitmap.cpp @@ -111,5 +111,50 @@ BEGIN_TEST(testSparseBitmapExternalOR) { return true; } - END_TEST(testSparseBitmapExternalOR) + +BEGIN_TEST(testSparseBitmapExternalAND) { + // Testing ANDing data from an external array. + + const size_t wordCount = 4; + + // Create a bitmap with two bits set per word based on the word index. + SparseBitmap bitmap; + for (size_t i = 0; i < wordCount; i++) { + bitmap.setBit(i * JS_BITS_PER_WORD + i); + bitmap.setBit(i * JS_BITS_PER_WORD + i + 1); + } + + // Update a single word, clearing one of the bits. + uintptr_t source[wordCount]; + CHECK(bitmap.getBit(0)); + CHECK(bitmap.getBit(1)); + source[0] = ~(1 << 1); + bitmap.bitwiseAndRangeWith(0, 1, source); + CHECK(bitmap.getBit(0)); + CHECK(!bitmap.getBit(1)); + + // Update a word at an offset. + CHECK(bitmap.getBit(JS_BITS_PER_WORD + 1)); + CHECK(bitmap.getBit(JS_BITS_PER_WORD + 2)); + source[0] = ~(1 << 2); + bitmap.bitwiseAndRangeWith(1, 1, source); + CHECK(bitmap.getBit(JS_BITS_PER_WORD + 1)); + CHECK(!bitmap.getBit(JS_BITS_PER_WORD + 2)); + + // Update multiple words at an offset. + CHECK(bitmap.getBit(JS_BITS_PER_WORD * 2 + 2)); + CHECK(bitmap.getBit(JS_BITS_PER_WORD * 2 + 3)); + CHECK(bitmap.getBit(JS_BITS_PER_WORD * 3 + 3)); + CHECK(bitmap.getBit(JS_BITS_PER_WORD * 3 + 4)); + source[0] = ~(1 << 3); + source[1] = ~(1 << 4); + bitmap.bitwiseAndRangeWith(2, 2, source); + CHECK(bitmap.getBit(JS_BITS_PER_WORD * 2 + 2)); + CHECK(!bitmap.getBit(JS_BITS_PER_WORD * 2 + 3)); + CHECK(bitmap.getBit(JS_BITS_PER_WORD * 3 + 3)); + CHECK(!bitmap.getBit(JS_BITS_PER_WORD * 3 + 4)); + + return true; +} +END_TEST(testSparseBitmapExternalAND) diff --git a/js/src/jsapi-tests/testWasmEncoder.cpp b/js/src/jsapi-tests/testWasmEncoder.cpp new file mode 100644 index 0000000000..a90249264c --- /dev/null +++ b/js/src/jsapi-tests/testWasmEncoder.cpp @@ -0,0 +1,117 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set ts=8 sts=2 et sw=2 tw=80: + */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "jit/MacroAssembler.h" + +#include "jsapi-tests/tests.h" +#include "jsapi-tests/testsJit.h" + +#include "wasm/WasmConstants.h" +#include "wasm/WasmFeatures.h" // AnyCompilerAvailable +#include "wasm/WasmGenerator.h" +#include "wasm/WasmSignalHandlers.h" // EnsureFullSignalHandlers +#include "wasm/WasmValType.h" + +using namespace js; +using namespace js::jit; +using namespace js::wasm; + +static bool TestTruncFn(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + double d = args[0].toDouble(); + args.rval().setInt32((int)d); + return true; +} + +// Check if wasm modules can be encoded in C++ and run. +BEGIN_TEST(testWasmEncodeBasic) { + if (!AnyCompilerAvailable(cx)) { + knownFail = true; + return false; + } + + EnsureFullSignalHandlers(cx); + + FeatureOptions options; + ScriptedCaller scriptedCaller; + SharedCompileArgs compileArgs = + CompileArgs::buildAndReport(cx, std::move(scriptedCaller), options); + + ModuleEnvironment moduleEnv(compileArgs->features); + CompilerEnvironment compilerEnv(CompileMode::Once, Tier::Optimized, + DebugEnabled::False); + compilerEnv.computeParameters(); + MOZ_ALWAYS_TRUE(moduleEnv.init()); + + ValTypeVector paramsImp, resultsImp; + MOZ_ALWAYS_TRUE(paramsImp.emplaceBack(ValType::F64) && + resultsImp.emplaceBack(ValType::I32)); + + CacheableName ns; + CacheableName impName; + MOZ_ALWAYS_TRUE(CacheableName::fromUTF8Chars("t", &impName)); + MOZ_ALWAYS_TRUE(moduleEnv.addImportedFunc(std::move(paramsImp), + std::move(resultsImp), + std::move(ns), std::move(impName))); + + ValTypeVector params, results; + MOZ_ALWAYS_TRUE(results.emplaceBack(ValType::I32)); + CacheableName expName; + MOZ_ALWAYS_TRUE(CacheableName::fromUTF8Chars("r", &expName)); + MOZ_ALWAYS_TRUE(moduleEnv.addDefinedFunc(std::move(params), + std::move(results), true, + mozilla::Some(std::move(expName)))); + + ModuleGenerator mg(*compileArgs, &moduleEnv, &compilerEnv, nullptr, nullptr, + nullptr); + MOZ_ALWAYS_TRUE(mg.init(nullptr)); + + // Build function and keep bytecode around until the end. + Bytes bytecode; + { + Encoder encoder(bytecode); + MOZ_ALWAYS_TRUE(EncodeLocalEntries(encoder, ValTypeVector())); + MOZ_ALWAYS_TRUE(encoder.writeOp(Op::F64Const) && + encoder.writeFixedF64(42.3)); + MOZ_ALWAYS_TRUE(encoder.writeOp(Op::Call) && encoder.writeVarU32(0)); + MOZ_ALWAYS_TRUE(encoder.writeOp(Op::End)); + } + MOZ_ALWAYS_TRUE(mg.compileFuncDef(1, 0, bytecode.begin(), + bytecode.begin() + bytecode.length())); + MOZ_ALWAYS_TRUE(mg.finishFuncDefs()); + + SharedBytes shareableBytes = js_new<ShareableBytes>(); + MOZ_ALWAYS_TRUE(shareableBytes); + SharedModule module = mg.finishModule(*shareableBytes); + MOZ_ALWAYS_TRUE(module); + + MOZ_ASSERT(module->imports().length() == 1); + MOZ_ASSERT(module->exports().length() == 1); + + // Instantiate and run. + { + Rooted<ImportValues> imports(cx); + RootedFunction func(cx, NewNativeFunction(cx, TestTruncFn, 0, nullptr)); + MOZ_ALWAYS_TRUE(func); + MOZ_ALWAYS_TRUE(imports.get().funcs.append(func)); + + Rooted<WasmInstanceObject*> instance(cx); + MOZ_ALWAYS_TRUE(module->instantiate(cx, imports.get(), nullptr, &instance)); + RootedFunction wasmFunc(cx); + MOZ_ALWAYS_TRUE( + WasmInstanceObject::getExportedFunction(cx, instance, 1, &wasmFunc)); + + JSAutoRealm ar(cx, wasmFunc); + RootedValue rval(cx); + RootedValue fval(cx); + MOZ_ALWAYS_TRUE( + JS::Call(cx, fval, wasmFunc, JS::HandleValueArray::empty(), &rval)); + MOZ_RELEASE_ASSERT(rval.toInt32() == 42); + } + return true; +} +END_TEST(testWasmEncodeBasic) |