summaryrefslogtreecommitdiffstats
path: root/js/src/jsapi-tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
commitd8bbc7858622b6d9c278469aab701ca0b609cddf (patch)
treeeff41dc61d9f714852212739e6b3738b82a2af87 /js/src/jsapi-tests
parentReleasing progress-linux version 125.0.3-1~progress7.99u1. (diff)
downloadfirefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.tar.xz
firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.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.build1
-rw-r--r--js/src/jsapi-tests/testDeduplication.cpp2
-rw-r--r--js/src/jsapi-tests/testGCHeapBarriers.cpp1
-rw-r--r--js/src/jsapi-tests/testGCMarking.cpp1
-rw-r--r--js/src/jsapi-tests/testGCUniqueId.cpp1
-rw-r--r--js/src/jsapi-tests/testIsInsideNursery.cpp83
-rw-r--r--js/src/jsapi-tests/testSparseBitmap.cpp47
-rw-r--r--js/src/jsapi-tests/testWasmEncoder.cpp117
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)