diff options
Diffstat (limited to '')
-rw-r--r-- | js/public/CallArgs.h | 7 | ||||
-rw-r--r-- | js/public/CallNonGenericMethod.h | 2 | ||||
-rw-r--r-- | js/public/GCAPI.h | 14 | ||||
-rw-r--r-- | js/public/GCHashTable.h | 3 | ||||
-rw-r--r-- | js/public/HeapAPI.h | 49 | ||||
-rw-r--r-- | js/public/Modules.h | 2 | ||||
-rw-r--r-- | js/public/Promise.h | 6 | ||||
-rw-r--r-- | js/public/PropertySpec.h | 20 | ||||
-rw-r--r-- | js/public/RealmOptions.h | 11 | ||||
-rw-r--r-- | js/public/RootingAPI.h | 2 | ||||
-rw-r--r-- | js/public/ValueArray.h | 3 | ||||
-rw-r--r-- | js/public/experimental/JitInfo.h | 6 | ||||
-rw-r--r-- | js/public/friend/ErrorNumbers.msg | 21 |
13 files changed, 113 insertions, 33 deletions
diff --git a/js/public/CallArgs.h b/js/public/CallArgs.h index 16f8d6f904..8be1b382f2 100644 --- a/js/public/CallArgs.h +++ b/js/public/CallArgs.h @@ -112,7 +112,7 @@ class MOZ_STACK_CLASS NoUsedRval { }; template <class WantUsedRval> -class MOZ_STACK_CLASS CallArgsBase { +class MOZ_STACK_CLASS MOZ_NON_PARAM CallArgsBase { static_assert(std::is_same_v<WantUsedRval, IncludeUsedRval> || std::is_same_v<WantUsedRval, NoUsedRval>, "WantUsedRval can only be IncludeUsedRval or NoUsedRval"); @@ -294,7 +294,7 @@ class MOZ_STACK_CLASS CallArgsBase { } // namespace detail -class MOZ_STACK_CLASS CallArgs +class MOZ_STACK_CLASS MOZ_NON_PARAM CallArgs : public detail::CallArgsBase<detail::IncludeUsedRval> { private: friend CallArgs CallArgsFromVp(unsigned argc, Value* vp); @@ -315,6 +315,9 @@ class MOZ_STACK_CLASS CallArgs for (unsigned i = 0; i < argc; ++i) { AssertValueIsNotGray(argv[i]); } + if (constructing) { + AssertValueIsNotGray(args.newTarget()); + } #endif return args; } diff --git a/js/public/CallNonGenericMethod.h b/js/public/CallNonGenericMethod.h index 80359f7a6f..73613260b9 100644 --- a/js/public/CallNonGenericMethod.h +++ b/js/public/CallNonGenericMethod.h @@ -60,7 +60,7 @@ extern JS_PUBLIC_API bool CallMethodIfWrapped(JSContext* cx, // its interface is the same as that of JSNative. // // static bool -// answer_getAnswer_impl(JSContext* cx, JS::CallArgs args) +// answer_getAnswer_impl(JSContext* cx, const JS::CallArgs& args) // { // args.rval().setInt32(42); // return true; diff --git a/js/public/GCAPI.h b/js/public/GCAPI.h index 9bdaca9661..5773838e46 100644 --- a/js/public/GCAPI.h +++ b/js/public/GCAPI.h @@ -459,6 +459,15 @@ typedef enum JSGCParamKey { * Default: ParallelMarkingThresholdMB */ JSGC_PARALLEL_MARKING_THRESHOLD_MB = 50, + + /** + * Whether the semispace nursery is enabled. + * + * Pref: javascript.options.mem.gc_experimental_semispace_nursery + * Default: SemispaceNurseryEnabled + */ + JSGC_SEMISPACE_NURSERY_ENABLED = 51, + } JSGCParamKey; /* @@ -1344,6 +1353,11 @@ namespace gc { extern JS_PUBLIC_API JSObject* NewMemoryInfoObject(JSContext* cx); /* + * Return whether |obj| is a dead nursery object during a minor GC. + */ +JS_PUBLIC_API bool IsDeadNurseryObject(JSObject* obj); + +/* * Run the finalizer of a nursery-allocated JSObject that is known to be dead. * * This is a dangerous operation - only use this if you know what you're doing! diff --git a/js/public/GCHashTable.h b/js/public/GCHashTable.h index 69487b97a3..2c9a15072a 100644 --- a/js/public/GCHashTable.h +++ b/js/public/GCHashTable.h @@ -62,7 +62,8 @@ class GCHashMap : public js::HashMap<Key, Value, HashPolicy, AllocPolicy> { public: using EntryGCPolicy = MapEntryGCPolicy; - explicit GCHashMap(AllocPolicy a = AllocPolicy()) : Base(std::move(a)) {} + explicit GCHashMap() : Base(AllocPolicy()) {} + explicit GCHashMap(AllocPolicy a) : Base(std::move(a)) {} explicit GCHashMap(size_t length) : Base(length) {} GCHashMap(AllocPolicy a, size_t length) : Base(std::move(a), length) {} diff --git a/js/public/HeapAPI.h b/js/public/HeapAPI.h index 26cca9e1c3..cabadeb75d 100644 --- a/js/public/HeapAPI.h +++ b/js/public/HeapAPI.h @@ -45,7 +45,7 @@ const size_t ArenaShift = 12; const size_t ArenaSize = size_t(1) << ArenaShift; const size_t ArenaMask = ArenaSize - 1; -#if defined(XP_MACOSX) && defined(__aarch64__) +#if defined(XP_DARWIN) && defined(__aarch64__) const size_t PageShift = 14; #else const size_t PageShift = 12; @@ -82,28 +82,61 @@ const size_t ArenaBitmapBits = ArenaSize / CellBytesPerMarkBit; const size_t ArenaBitmapBytes = HowMany(ArenaBitmapBits, 8); const size_t ArenaBitmapWords = HowMany(ArenaBitmapBits, JS_BITS_PER_WORD); +enum class ChunkKind : uint8_t { + Invalid = 0, + TenuredHeap, + NurseryToSpace, + NurseryFromSpace +}; + // The base class for all GC chunks, either in the nursery or in the tenured // heap memory. This structure is locatable from any GC pointer by aligning to // the chunk size. -class alignas(CellAlignBytes) ChunkBase { +class ChunkBase { protected: - ChunkBase(JSRuntime* rt, StoreBuffer* sb) { + // Initialize a tenured heap chunk. + explicit ChunkBase(JSRuntime* rt) { MOZ_ASSERT((uintptr_t(this) & ChunkMask) == 0); - initBase(rt, sb); + initBaseForTenuredChunk(rt); } - void initBase(JSRuntime* rt, StoreBuffer* sb) { + void initBaseForTenuredChunk(JSRuntime* rt) { runtime = rt; - storeBuffer = sb; + storeBuffer = nullptr; + kind = ChunkKind::TenuredHeap; + nurseryChunkIndex = UINT8_MAX; + } + + // Initialize a nursery chunk. + ChunkBase(JSRuntime* rt, StoreBuffer* sb, ChunkKind kind, uint8_t chunkIndex) + : storeBuffer(sb), + runtime(rt), + kind(kind), + nurseryChunkIndex(chunkIndex) { + MOZ_ASSERT(kind == ChunkKind::NurseryFromSpace || + kind == ChunkKind::NurseryToSpace); + MOZ_ASSERT((uintptr_t(this) & ChunkMask) == 0); + MOZ_ASSERT(storeBuffer); } public: + ChunkKind getKind() const { + MOZ_ASSERT_IF(storeBuffer, kind == ChunkKind::NurseryToSpace || + kind == ChunkKind::NurseryFromSpace); + MOZ_ASSERT_IF(!storeBuffer, kind == ChunkKind::TenuredHeap); + return kind; + } + // The store buffer for pointers from tenured things to things in this // chunk. Will be non-null if and only if this is a nursery chunk. StoreBuffer* storeBuffer; // Provide quick access to the runtime from absolutely anywhere. JSRuntime* runtime; + + ChunkKind kind; + + uint8_t nurseryChunkIndex; }; // Information about tenured heap chunks. @@ -234,7 +267,7 @@ class TenuredChunkBase : public ChunkBase { ChunkPageBitmap decommittedPages; protected: - explicit TenuredChunkBase(JSRuntime* runtime) : ChunkBase(runtime, nullptr) { + explicit TenuredChunkBase(JSRuntime* runtime) : ChunkBase(runtime) { info.numArenasFree = ArenasPerChunk; } @@ -523,6 +556,7 @@ static MOZ_ALWAYS_INLINE ChunkBase* GetCellChunkBase(const Cell* cell) { MOZ_ASSERT(cell); auto* chunk = reinterpret_cast<ChunkBase*>(uintptr_t(cell) & ~ChunkMask); MOZ_ASSERT(chunk->runtime); + MOZ_ASSERT(chunk->kind != ChunkKind::Invalid); return chunk; } @@ -532,6 +566,7 @@ static MOZ_ALWAYS_INLINE TenuredChunkBase* GetCellChunkBase( auto* chunk = reinterpret_cast<TenuredChunkBase*>(uintptr_t(cell) & ~ChunkMask); MOZ_ASSERT(chunk->runtime); + MOZ_ASSERT(chunk->kind == ChunkKind::TenuredHeap); return chunk; } diff --git a/js/public/Modules.h b/js/public/Modules.h index 2e7192e120..4a8d45acb0 100644 --- a/js/public/Modules.h +++ b/js/public/Modules.h @@ -299,6 +299,8 @@ extern JS_PUBLIC_API JSObject* GetModuleEnvironment( */ extern JS_PUBLIC_API void ClearModuleEnvironment(JSObject* moduleObj); +extern JS_PUBLIC_API bool ModuleIsLinked(JSObject* moduleObj); + } // namespace JS #endif // js_Modules_h diff --git a/js/public/Promise.h b/js/public/Promise.h index 221d6fdfee..75bc7fd837 100644 --- a/js/public/Promise.h +++ b/js/public/Promise.h @@ -80,6 +80,12 @@ class JS_PUBLIC_API JobQueue { */ virtual bool empty() const = 0; + /** + * Returns true if the job queue stops draining, which results in `empty()` + * being false after `runJobs()`. + */ + virtual bool isDrainingStopped() const = 0; + protected: friend class AutoDebuggerJobQueueInterruption; diff --git a/js/public/PropertySpec.h b/js/public/PropertySpec.h index 9d8115508d..0c37e598fb 100644 --- a/js/public/PropertySpec.h +++ b/js/public/PropertySpec.h @@ -373,6 +373,10 @@ constexpr uint8_t CheckAccessorAttrs() { JSPropertySpec::nativeAccessors(::JS::SymbolCode::symbol, \ CheckAccessorAttrs<attributes>(), getter, \ nullptr) +#define JS_SYM_GETSET(symbol, getter, setter, attributes) \ + JSPropertySpec::nativeAccessors(::JS::SymbolCode::symbol, \ + CheckAccessorAttrs<attributes>(), getter, \ + nullptr, setter, nullptr) #define JS_SELF_HOSTED_GET(name, getterName, attributes) \ JSPropertySpec::selfHostedAccessors(name, CheckAccessorAttrs<attributes>(), \ getterName) @@ -417,11 +421,15 @@ struct JSFunctionSpec { #define JS_FS_END JS_FN(nullptr, nullptr, 0, 0) /* - * Initializer macros for a JSFunctionSpec array element. JS_FNINFO allows the - * simple adding of JSJitInfos. JS_SELF_HOSTED_FN declares a self-hosted - * function. JS_INLINABLE_FN allows specifying an InlinableNative enum value for - * natives inlined or specialized by the JIT. Finally JS_FNSPEC has slots for - * all the fields. + * Initializer macros for a JSFunctionSpec array element. + * + * - JS_FNINFO allows the simple adding of JSJitInfos. + * - JS_SELF_HOSTED_FN declares a self-hosted function. + * - JS_INLINABLE_FN allows specifying an InlinableNative enum value for natives + * inlined or specialized by the JIT. + * - JS_TRAMPOLINE_FN allows specifying a TrampolineNative enum value for + * natives that have a JitEntry trampoline. + * - JS_FNSPEC has slots for all the fields. * * The _SYM variants allow defining a function with a symbol key rather than a * string key. For example, use JS_SYM_FN(iterator, ...) to define an @@ -431,6 +439,8 @@ struct JSFunctionSpec { JS_FNSPEC(name, call, nullptr, nargs, flags, nullptr) #define JS_INLINABLE_FN(name, call, nargs, flags, native) \ JS_FNSPEC(name, call, &js::jit::JitInfo_##native, nargs, flags, nullptr) +#define JS_TRAMPOLINE_FN(name, call, nargs, flags, native) \ + JS_FNSPEC(name, call, &js::jit::JitInfo_##native, nargs, flags, nullptr) #define JS_SYM_FN(symbol, call, nargs, flags) \ JS_SYM_FNSPEC(symbol, call, nullptr, nargs, flags, nullptr) #define JS_FNINFO(name, call, info, nargs, flags) \ diff --git a/js/public/RealmOptions.h b/js/public/RealmOptions.h index 0a0c1faeff..b3ab20915a 100644 --- a/js/public/RealmOptions.h +++ b/js/public/RealmOptions.h @@ -178,14 +178,6 @@ class JS_PUBLIC_API RealmCreationOptions { return *this; } -#ifdef ENABLE_JSON_PARSE_WITH_SOURCE - bool getJSONParseWithSource() const { return jsonParseWithSource; } - RealmCreationOptions& setJSONParseWithSource(bool flag) { - jsonParseWithSource = flag; - return *this; - } -#endif - // This flag doesn't affect JS engine behavior. It is used by Gecko to // mark whether content windows and workers are "Secure Context"s. See // https://w3c.github.io/webappsec-secure-contexts/ @@ -246,9 +238,6 @@ class JS_PUBLIC_API RealmCreationOptions { bool defineSharedArrayBufferConstructor_ = true; bool coopAndCoep_ = false; bool toSource_ = false; -#ifdef ENABLE_JSON_PARSE_WITH_SOURCE - bool jsonParseWithSource = false; -#endif bool secureContext_ = false; bool freezeBuiltins_ = false; diff --git a/js/public/RootingAPI.h b/js/public/RootingAPI.h index e35a2c5bc8..eaae2db1b7 100644 --- a/js/public/RootingAPI.h +++ b/js/public/RootingAPI.h @@ -232,7 +232,7 @@ struct SafelyInitialized { // |T| per C++11 [expr.type.conv]p2 -- will produce a safely-initialized, // safely-usable T that it can return. -#if defined(XP_WIN) || defined(XP_MACOSX) || \ +#if defined(XP_WIN) || defined(XP_DARWIN) || \ (defined(XP_UNIX) && !defined(__clang__)) // That presumption holds for pointers, where value initialization produces diff --git a/js/public/ValueArray.h b/js/public/ValueArray.h index 0d520fb9b6..734d8aca65 100644 --- a/js/public/ValueArray.h +++ b/js/public/ValueArray.h @@ -57,6 +57,9 @@ class HandleValueArray { MOZ_IMPLICIT HandleValueArray(const RootedVector<Value>& values) : length_(values.length()), elements_(values.begin()) {} + MOZ_IMPLICIT HandleValueArray(const PersistentRootedVector<Value>& values) + : length_(values.length()), elements_(values.begin()) {} + template <size_t N> MOZ_IMPLICIT HandleValueArray(const RootedValueArray<N>& values) : length_(N), elements_(values.begin()) {} diff --git a/js/public/experimental/JitInfo.h b/js/public/experimental/JitInfo.h index 1b070021bd..896b5fef68 100644 --- a/js/public/experimental/JitInfo.h +++ b/js/public/experimental/JitInfo.h @@ -8,6 +8,7 @@ #define js_experimental_JitInfo_h #include "mozilla/Assertions.h" // MOZ_ASSERT +#include "mozilla/Attributes.h" // MOZ_NON_PARAM #include <stddef.h> // size_t #include <stdint.h> // uint16_t, uint32_t @@ -21,6 +22,7 @@ namespace js { namespace jit { enum class InlinableNative : uint16_t; +enum class TrampolineNative : uint16_t; } // namespace jit @@ -72,7 +74,7 @@ struct JSJitMethodCallArgsTraits; * A class, expected to be passed by reference, which represents the CallArgs * for a JSJitMethodOp. */ -class JSJitMethodCallArgs +class MOZ_NON_PARAM JSJitMethodCallArgs : protected JS::detail::CallArgsBase<JS::detail::NoUsedRval> { private: using Base = JS::detail::CallArgsBase<JS::detail::NoUsedRval>; @@ -137,6 +139,7 @@ class JSJitInfo { Method, StaticMethod, InlinableNative, + TrampolineNative, IgnoresReturnValueNative, // Must be last OpTypeCount @@ -226,6 +229,7 @@ class JSJitInfo { union { uint16_t protoID; js::jit::InlinableNative inlinableNative; + js::jit::TrampolineNative trampolineNative; }; union { diff --git a/js/public/friend/ErrorNumbers.msg b/js/public/friend/ErrorNumbers.msg index e75e7b973c..42f9a6615d 100644 --- a/js/public/friend/ErrorNumbers.msg +++ b/js/public/friend/ErrorNumbers.msg @@ -80,6 +80,8 @@ MSG_DEF(JSMSG_SPREAD_TOO_LARGE, 0, JSEXN_RANGEERR, "array too large due t MSG_DEF(JSMSG_BAD_WEAKMAP_KEY, 0, JSEXN_TYPEERR, "cannot use the given object as a weak map key") MSG_DEF(JSMSG_WEAKMAP_KEY_CANT_BE_HELD_WEAKLY, 1, JSEXN_TYPEERR, "WeakMap key {0} must be an object or an unregistered symbol") MSG_DEF(JSMSG_WEAKSET_VAL_CANT_BE_HELD_WEAKLY, 1, JSEXN_TYPEERR, "WeakSet value {0} must be an object or an unregistered symbol") +MSG_DEF(JSMSG_WEAKMAP_KEY_MUST_BE_AN_OBJECT, 1, JSEXN_TYPEERR, "WeakMap key {0} must be an object") +MSG_DEF(JSMSG_WEAKSET_VAL_MUST_BE_AN_OBJECT, 1, JSEXN_TYPEERR, "WeakSet value {0} must be an object") MSG_DEF(JSMSG_BAD_GETTER_OR_SETTER, 1, JSEXN_TYPEERR, "invalid {0} usage") MSG_DEF(JSMSG_BAD_ARRAY_LENGTH, 0, JSEXN_RANGEERR, "invalid array length") MSG_DEF(JSMSG_SOURCE_ARRAY_TOO_LONG, 0, JSEXN_RANGEERR, "source array is too long") @@ -137,6 +139,9 @@ MSG_DEF(JSMSG_CONSTRUCTOR_DISABLED, 1, JSEXN_TYPEERR, "{0} is disabled") // JSON MSG_DEF(JSMSG_JSON_BAD_PARSE, 3, JSEXN_SYNTAXERR, "JSON.parse: {0} at line {1} column {2} of the JSON data") MSG_DEF(JSMSG_JSON_CYCLIC_VALUE, 0, JSEXN_TYPEERR, "cyclic object value") +MSG_DEF(JSMSG_JSON_RAW_EMPTY, 0, JSEXN_SYNTAXERR, "JSON.rawJSON: argument cannot be empty when converted to string") +MSG_DEF(JSMSG_JSON_RAW_ARRAY_OR_OBJECT, 0, JSEXN_SYNTAXERR, "JSON.rawJSON: outermost value must not be an array or object") +MSG_DEF(JSMSG_JSON_RAW_WHITESPACE, 0, JSEXN_SYNTAXERR, "JSON.rawJSON: first or last character cannot be any of tab, line feed, carriage return, or space") // Runtime errors MSG_DEF(JSMSG_ASSIGN_TO_CALL, 0, JSEXN_REFERENCEERR, "cannot assign to function call") @@ -669,6 +674,15 @@ MSG_DEF(JSMSG_TYPED_ARRAY_CONSTRUCT_OFFSET_MISALIGNED, 2, JSEXN_RANGEERR, "buffe MSG_DEF(JSMSG_TYPED_ARRAY_CONSTRUCT_OFFSET_LENGTH_BOUNDS, 1, JSEXN_RANGEERR, "size of buffer is too small for {0}Array with byteOffset") MSG_DEF(JSMSG_TYPED_ARRAY_CONSTRUCT_ARRAY_LENGTH_BOUNDS, 1, JSEXN_RANGEERR, "attempting to construct out-of-bounds {0}Array on ArrayBuffer") MSG_DEF(JSMSG_TYPED_ARRAY_CONSTRUCT_TOO_LARGE, 1, JSEXN_RANGEERR, "{0}Array too large") +MSG_DEF(JSMSG_TYPED_ARRAY_BAD_HEX_STRING_LENGTH, 0, JSEXN_SYNTAXERR, "hex-string must have an even number of characters") +MSG_DEF(JSMSG_TYPED_ARRAY_BAD_HEX_DIGIT, 1, JSEXN_SYNTAXERR, "'{0}' is not a valid hex-digit") +MSG_DEF(JSMSG_TYPED_ARRAY_BAD_BASE64_ALPHABET, 0, JSEXN_TYPEERR, "\"alphabet\" option must be one of \"base64\" or \"base64url\"") +MSG_DEF(JSMSG_TYPED_ARRAY_BAD_BASE64_LAST_CHUNK_HANDLING, 0, JSEXN_TYPEERR, "\"lastChunkHandling\" option must be one of \"loose\", \"strict\", or \"stop-before-partial\"") +MSG_DEF(JSMSG_TYPED_ARRAY_BAD_BASE64_CHAR, 1, JSEXN_SYNTAXERR, "'{0}' is not a valid base64 character") +MSG_DEF(JSMSG_TYPED_ARRAY_BAD_INCOMPLETE_CHUNK, 0, JSEXN_SYNTAXERR, "unexpected incomplete base64 chunk") +MSG_DEF(JSMSG_TYPED_ARRAY_BAD_BASE64_AFTER_PADDING, 1, JSEXN_SYNTAXERR, "unexpected '{0}' after base64 padding") +MSG_DEF(JSMSG_TYPED_ARRAY_MISSING_BASE64_PADDING, 0, JSEXN_SYNTAXERR, "missing padding '=' character") +MSG_DEF(JSMSG_TYPED_ARRAY_EXTRA_BASE64_BITS, 0, JSEXN_SYNTAXERR, "unexpected extra bits in last character") MSG_DEF(JSMSG_TYPED_ARRAY_CALL_OR_CONSTRUCT, 1, JSEXN_TYPEERR, "cannot directly {0} builtin %TypedArray%") MSG_DEF(JSMSG_NON_TYPED_ARRAY_RETURNED, 0, JSEXN_TYPEERR, "constructor didn't return TypedArray object") @@ -714,10 +728,9 @@ MSG_DEF(JSMSG_CANT_DELETE_SUPER, 0, JSEXN_REFERENCEERR, "invalid delete involvin MSG_DEF(JSMSG_REINIT_THIS, 0, JSEXN_REFERENCEERR, "super() called twice in derived class constructor") // Modules -MSG_DEF(JSMSG_MISSING_INDIRECT_EXPORT, 0, JSEXN_SYNTAXERR, "indirect export not found") -MSG_DEF(JSMSG_AMBIGUOUS_INDIRECT_EXPORT, 0, JSEXN_SYNTAXERR, "ambiguous indirect export") -MSG_DEF(JSMSG_MISSING_IMPORT, 0, JSEXN_SYNTAXERR, "import not found") -MSG_DEF(JSMSG_AMBIGUOUS_IMPORT, 0, JSEXN_SYNTAXERR, "ambiguous import") +MSG_DEF(JSMSG_MODULE_NO_EXPORT, 2, JSEXN_SYNTAXERR, "The requested module '{0}' doesn't provide an export named: '{1}'") +MSG_DEF(JSMSG_MODULE_CIRCULAR_IMPORT, 2, JSEXN_SYNTAXERR, "The requested module '{0}' contains circular import: '{1}'") +MSG_DEF(JSMSG_MODULE_AMBIGUOUS, 4, JSEXN_SYNTAXERR, "The requested module '{0}' contains ambiguous star export: '{1}' from '{2}' and '{3}'") MSG_DEF(JSMSG_MISSING_EXPORT, 1, JSEXN_SYNTAXERR, "local binding for export '{0}' not found") MSG_DEF(JSMSG_BAD_MODULE_STATUS, 1, JSEXN_INTERNALERR, "module record has unexpected status: {0}") MSG_DEF(JSMSG_DYNAMIC_IMPORT_FAILED, 1, JSEXN_TYPEERR, "error loading dynamically imported module: {0}") |