diff --git a/config/external/ffi/moz.build b/config/external/ffi/moz.build index 8710ebab7a..543d07a975 100644 --- a/config/external/ffi/moz.build +++ b/config/external/ffi/moz.build @@ -101,6 +101,8 @@ else: ASFLAGS += ['-no-integrated-as'] elif CONFIG['FFI_TARGET'] == 'AARCH64': ffi_srcs = ('sysv.S', 'ffi.c') + elif CONFIG['FFI_TARGET'] == 'LOONGARCH64': + ffi_srcs = ('ffi.c', 'sysv.S') elif CONFIG['FFI_TARGET'] == 'X86': ffi_srcs = ('ffi.c', 'sysv.S', 'win32.S') elif CONFIG['FFI_TARGET'] == 'X86_64': diff --git a/config/system-headers b/config/system-headers index 1ad701fe03..3bc25a459e 100644 --- a/config/system-headers +++ b/config/system-headers @@ -335,8 +335,6 @@ curses.h cxxabi.h DateTimeUtils.h dbus/dbus.h -dbus/dbus-glib.h -dbus/dbus-glib-lowlevel.h ddeml.h Debug.h dem.h diff --git a/dom/base/ImageEncoder.cpp b/dom/base/ImageEncoder.cpp index 968c440b7f..cb9fbddf25 100644 --- a/dom/base/ImageEncoder.cpp +++ b/dom/base/ImageEncoder.cpp @@ -400,6 +400,7 @@ ImageEncoder::ExtractDataInternal(const nsAString& aType, layers::PlanarYCbCrImage* ycbcrImage = static_cast (aImage); gfxImageFormat format = SurfaceFormat::A8R8G8B8_UINT32; uint32_t stride = GetAlignedStride<16>(aSize.width, 4); + auto size = stride * aSize.height; size_t length = BufferSizeFromStrideAndHeight(stride, aSize.height); if (length == 0) { return NS_ERROR_INVALID_ARG; @@ -413,10 +414,10 @@ ImageEncoder::ExtractDataInternal(const nsAString& aType, stride); rv = aEncoder->InitFromData(data.Elements(), - aSize.width * aSize.height * 4, + size, aSize.width, aSize.height, - aSize.width * 4, + stride, imgIEncoder::INPUT_FORMAT_HOSTARGB, aOptions); } else { @@ -433,10 +434,10 @@ ImageEncoder::ExtractDataInternal(const nsAString& aType, return NS_ERROR_INVALID_ARG; } rv = aEncoder->InitFromData(map.mData, - aSize.width * aSize.height * 4, + map.mStride * aSize.height, aSize.width, aSize.height, - aSize.width * 4, + map.mStride, imgIEncoder::INPUT_FORMAT_HOSTARGB, aOptions); dataSurface->Unmap(); @@ -467,10 +468,10 @@ ImageEncoder::ExtractDataInternal(const nsAString& aType, return NS_ERROR_INVALID_ARG; } rv = aEncoder->InitFromData(map.mData, - aSize.width * aSize.height * 4, + map.mStride * aSize.height, aSize.width, aSize.height, - aSize.width * 4, + map.mStride, imgIEncoder::INPUT_FORMAT_HOSTARGB, aOptions); emptyCanvas->Unmap(); diff --git a/dom/gamepad/moz.build b/dom/gamepad/moz.build index eabd460fc2..9a3fbe4cfe 100644 --- a/dom/gamepad/moz.build +++ b/dom/gamepad/moz.build @@ -77,6 +77,4 @@ if CONFIG['MOZ_GAMEPAD']: ] CFLAGS += CONFIG['GLIB_CFLAGS'] - CFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS'] CXXFLAGS += CONFIG['GLIB_CFLAGS'] - CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS'] diff --git a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp index 7c18838ff2..71fc7f74af 100644 --- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp +++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp @@ -15,6 +15,7 @@ #include "DXVA2Manager.h" #include "nsThreadUtils.h" #include "Layers.h" +#include "mozilla/CheckedInt.h" #include "mozilla/ClearOnShutdown.h" #include "mozilla/layers/LayersTypes.h" #include "MediaInfo.h" @@ -741,6 +742,10 @@ WMFVideoMFTManager::CreateBasicVideoFrame(IMFSample* aSample, NS_ENSURE_TRUE(SUCCEEDED(hr), hr); stride = mVideoStride; } + if (stride <= 0) { + LOG("CreateBasicVideoFrame: invalid stride %ld", stride); + return E_FAIL; + } // YV12, planar format: [YYYY....][VVVV....][UUUU....] // i.e., Y, then V, then U. @@ -763,9 +768,16 @@ WMFVideoMFTManager::CreateBasicVideoFrame(IMFSample* aSample, if (videoHeight % 16 != 0) { padding = 16 - (videoHeight % 16); } - uint32_t y_size = stride * (videoHeight + padding); - uint32_t v_size = stride * (videoHeight + padding) / 4; - uint32_t halfStride = (stride + 1) / 2; + mozilla::CheckedInt y_size_checked = + mozilla::CheckedInt(static_cast(stride)) * + (videoHeight + padding); + if (!y_size_checked.isValid()) { + LOG("CreateBasicVideoFrame: plane size too large"); + return E_FAIL; + } + uint32_t y_size = y_size_checked.value(); + uint32_t v_size = y_size / 4; + uint32_t halfStride = static_cast((static_cast(stride) + 1) / 2); uint32_t halfHeight = (videoHeight + 1) / 2; uint32_t halfWidth = (videoWidth + 1) / 2; diff --git a/gfx/cairo/libpixman/src/pixman-arm-simd-asm.S b/gfx/cairo/libpixman/src/pixman-arm-simd-asm.S index a74a0a8f34..959a0ba798 100644 --- a/gfx/cairo/libpixman/src/pixman-arm-simd-asm.S +++ b/gfx/cairo/libpixman/src/pixman-arm-simd-asm.S @@ -818,13 +818,13 @@ generate_composite_function \ .macro over_white_8888_8888_ca_1pixel_tail mvn TMP0, WK1 teq WK1, WK1, asr #32 - bne 01f - bcc 03f + bne 1f + bcc 3f mov WK3, WK1 - b 02f -01: over_white_8888_8888_ca_combine WK1, WK3 -02: pixst , 4, 3, DST -03: + b 2f +1: over_white_8888_8888_ca_combine WK1, WK3 +2: pixst , 4, 3, DST +3: .endm .macro over_white_8888_8888_ca_2pixels_head @@ -835,21 +835,21 @@ generate_composite_function \ pixld , 8, 3, DST mvn TMP0, WK1 teq WK1, WK1, asr #32 - bne 01f + bne 1f movcs WK3, WK1 - bcs 02f + bcs 2f teq WK2, #0 - beq 05f - b 02f -01: over_white_8888_8888_ca_combine WK1, WK3 -02: mvn TMP0, WK2 + beq 5f + b 2f +1: over_white_8888_8888_ca_combine WK1, WK3 +2: mvn TMP0, WK2 teq WK2, WK2, asr #32 - bne 03f + bne 3f movcs WK4, WK2 - b 04f -03: over_white_8888_8888_ca_combine WK2, WK4 -04: pixst , 8, 3, DST -05: + b 4f +3: over_white_8888_8888_ca_combine WK2, WK4 +4: pixst , 8, 3, DST +5: .endm .macro over_white_8888_8888_ca_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload @@ -1065,9 +1065,9 @@ generate_composite_function \ .if offset != 0 ldrb ORIG_W, [SRC, #offset] .endif - beq 01f + beq 1f teq STRIDE_M, #0xFF - beq 02f + beq 2f .endif uxtb16 SCRATCH, d /* rb_dest */ uxtb16 d, d, ror #8 /* ag_dest */ @@ -1077,13 +1077,13 @@ generate_composite_function \ uxtab16 d, d, d, ror #8 mov SCRATCH, SCRATCH, ror #8 sel d, SCRATCH, d - b 02f + b 2f .if offset == 0 48: /* Last mov d,#0 of the set - used as part of shortcut for * source values all 0 */ .endif -01: mov d, #0 -02: +1: mov d, #0 +2: .endm .macro in_reverse_8888_8888_tail numbytes, reg1, reg2, reg3, reg4 diff --git a/hal/moz.build b/hal/moz.build index fefd56fcf1..9943a090d2 100644 --- a/hal/moz.build +++ b/hal/moz.build @@ -99,6 +99,4 @@ if CONFIG['MOZ_GAMEPAD']: ] CFLAGS += CONFIG['GLIB_CFLAGS'] -CFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS'] CXXFLAGS += CONFIG['GLIB_CFLAGS'] -CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS'] diff --git a/ipc/dbus/moz.build b/ipc/dbus/moz.build index 81626d1108..8a60affa66 100644 --- a/ipc/dbus/moz.build +++ b/ipc/dbus/moz.build @@ -27,6 +27,4 @@ FINAL_LIBRARY = 'xul' if CONFIG['MOZ_ENABLE_DBUS']: CFLAGS += CONFIG['MOZ_DBUS_CFLAGS'] - CFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS'] CXXFLAGS += CONFIG['MOZ_DBUS_CFLAGS'] - CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS'] diff --git a/js/ffi.configure b/js/ffi.configure index 96b6ad6d69..641105e78a 100644 --- a/js/ffi.configure +++ b/js/ffi.configure @@ -6,7 +6,7 @@ @depends(target) def force_system_ffi(target): # Pre-emptively move to system ffi for non-tier one platforms. - if target.cpu not in ('x86', 'x86_64', 'arm', 'aarch64'): + if target.cpu not in ('x86', 'x86_64', 'arm', 'aarch64', 'loongarch64'): return True imply_option('--with-system-ffi', force_system_ffi, "target") @@ -27,7 +27,7 @@ add_old_configure_assignment('MOZ_SYSTEM_FFI', depends_if(system_ffi)(lambda _: # Target selection, based on ffi/configure.ac. @depends_when(target, when=building_ffi) def ffi_target(target): - if target.cpu not in ('x86', 'x86_64', 'arm', 'aarch64'): + if target.cpu not in ('x86', 'x86_64', 'arm', 'aarch64', 'loongarch64'): die('Building libffi from the tree is not supported on this platform. ' 'Use --with-system-ffi instead.') @@ -50,6 +50,9 @@ def ffi_target(target): elif target.cpu == 'aarch64': target_dir = 'aarch64' target_name = 'AARCH64' + elif target.cpu == 'loongarch64': + target_dir = 'loongarch64' + target_name = 'LOONGARCH64' else: target_dir = 'x86' target_name = target.cpu.upper() diff --git a/js/src/ctypes/libffi/src/loongarch64/ffi.c b/js/src/ctypes/libffi/src/loongarch64/ffi.c new file mode 100644 index 0000000000..234afba673 --- /dev/null +++ b/js/src/ctypes/libffi/src/loongarch64/ffi.c @@ -0,0 +1,600 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2022 Xu Chenghua + 2022 Cheng Lulu + Based on RISC-V port + + LoongArch Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#include +#include + +#include +#include + +#if defined(__loongarch_soft_float) +# define ABI_FRLEN 0 +#elif defined(__loongarch_single_float) +# define ABI_FRLEN 32 +# define ABI_FLOAT float +#elif defined(__loongarch_double_float) +# define ABI_FRLEN 64 +# define ABI_FLOAT double +#else +#error unsupported LoongArch floating-point ABI +#endif + +#define NARGREG 8 +#define STKALIGN 16 +#define MAXCOPYARG (2 * sizeof (double)) + +/* call_context registers + - 8 floating point parameter/result registers. + - 8 integer parameter/result registers. + - 2 registers used by the assembly code to in-place construct its own + stack frame + - frame register + - return register +*/ +typedef struct call_context +{ + ABI_FLOAT fa[8]; + size_t a[10]; +} call_context; + +typedef struct call_builder +{ + call_context *aregs; + int used_integer; + int used_float; + size_t *used_stack; + size_t *stack; + size_t next_struct_area; +} call_builder; + +/* Integer (not pointer) less than ABI GRLEN. */ +/* FFI_TYPE_INT does not appear to be used. */ +#if __SIZEOF_POINTER__ == 8 +# define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT64) +#else +# define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT32) +#endif + +#if ABI_FRLEN +typedef struct float_struct_info +{ + char as_elements; + char type1; + char offset2; + char type2; +} float_struct_info; + +#if ABI_FRLEN >= 64 +# define IS_FLOAT(type) ((type) >= FFI_TYPE_FLOAT && (type) <= FFI_TYPE_DOUBLE) +#else +# define IS_FLOAT(type) ((type) == FFI_TYPE_FLOAT) +#endif + +static ffi_type ** +flatten_struct (ffi_type *in, ffi_type **out, ffi_type **out_end) +{ + int i; + + if (out == out_end) + return out; + if (in->type != FFI_TYPE_STRUCT) + *(out++) = in; + else + for (i = 0; in->elements[i]; i++) + out = flatten_struct (in->elements[i], out, out_end); + return out; +} + +/* Structs with at most two fields after flattening, one of which is of + floating point type, are passed in multiple registers if sufficient + registers are available. */ +static float_struct_info +struct_passed_as_elements (call_builder *cb, ffi_type *top) +{ + float_struct_info ret = {0, 0, 0, 0}; + ffi_type *fields[3]; + int num_floats, num_ints; + int num_fields = flatten_struct (top, fields, fields + 3) - fields; + + if (num_fields == 1) + { + if (IS_FLOAT (fields[0]->type)) + { + ret.as_elements = 1; + ret.type1 = fields[0]->type; + } + } + else if (num_fields == 2) + { + num_floats = IS_FLOAT (fields[0]->type) + IS_FLOAT (fields[1]->type); + num_ints = IS_INT (fields[0]->type) + IS_INT (fields[1]->type); + if (num_floats == 0 || num_floats + num_ints != 2) + return ret; + if (cb->used_float + num_floats > NARGREG + || cb->used_integer + (2 - num_floats) > NARGREG) + return ret; + if (!IS_FLOAT (fields[0]->type) && !IS_FLOAT (fields[1]->type)) + return ret; + + ret.type1 = fields[0]->type; + ret.type2 = fields[1]->type; + ret.offset2 = ALIGN (fields[0]->size, fields[1]->alignment); + ret.as_elements = 1; + } + return ret; +} +#endif + +/* Allocates a single register, float register, or GRLEN-sized stack slot to a + datum. */ +static void +marshal_atom (call_builder *cb, int type, void *data) +{ + size_t value = 0; + switch (type) + { + case FFI_TYPE_UINT8: + value = *(uint8_t *) data; + break; + case FFI_TYPE_SINT8: + value = *(int8_t *) data; + break; + case FFI_TYPE_UINT16: + value = *(uint16_t *) data; + break; + case FFI_TYPE_SINT16: + value = *(int16_t *) data; + break; + /* 32-bit quantities are always sign-extended in the ABI. */ + case FFI_TYPE_UINT32: + value = *(int32_t *) data; + break; + case FFI_TYPE_SINT32: + value = *(int32_t *) data; + break; +#if __SIZEOF_POINTER__ == 8 + case FFI_TYPE_UINT64: + value = *(uint64_t *) data; + break; + case FFI_TYPE_SINT64: + value = *(int64_t *) data; + break; +#endif + case FFI_TYPE_POINTER: + value = *(size_t *) data; + break; + +#if ABI_FRLEN >= 32 + case FFI_TYPE_FLOAT: + *(float *)(cb->aregs->fa + cb->used_float++) = *(float *) data; + return; +#endif +#if ABI_FRLEN >= 64 + case FFI_TYPE_DOUBLE: + (cb->aregs->fa[cb->used_float++]) = *(double *) data; + return; +#endif + default: + FFI_ASSERT (0); + break; + } + + if (cb->used_integer == NARGREG) + *cb->used_stack++ = value; + else + cb->aregs->a[cb->used_integer++] = value; +} + +static void +unmarshal_atom (call_builder *cb, int type, void *data) +{ + size_t value; + switch (type) + { +#if ABI_FRLEN >= 32 + case FFI_TYPE_FLOAT: + *(float *) data = *(float *)(cb->aregs->fa + cb->used_float++); + return; +#endif +#if ABI_FRLEN >= 64 + case FFI_TYPE_DOUBLE: + *(double *) data = cb->aregs->fa[cb->used_float++]; + return; +#endif + } + + if (cb->used_integer == NARGREG) + value = *cb->used_stack++; + else + value = cb->aregs->a[cb->used_integer++]; + + switch (type) + { + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: +#if __SIZEOF_POINTER__ == 8 + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: +#endif + case FFI_TYPE_POINTER: + *(ffi_arg *)data = value; + break; + default: + FFI_ASSERT (0); + break; + } +} + +/* Allocate and copy a structure that is passed by value on the stack and + return a pointer to it. */ +static void * +allocate_and_copy_struct_to_stack (call_builder *cb, void *data, + ffi_type *type) +{ + size_t dest = cb->next_struct_area - type->size; + + dest = ALIGN_DOWN (dest, type->alignment); + cb->next_struct_area = dest; + + return memcpy ((char *)cb->stack + dest, data, type->size); +} + +/* Adds an argument to a call, or a not by reference return value. */ +static void +marshal (call_builder *cb, ffi_type *type, int var, void *data) +{ + size_t realign[2]; + +#if ABI_FRLEN + if (!var && type->type == FFI_TYPE_STRUCT) + { + float_struct_info fsi = struct_passed_as_elements (cb, type); + if (fsi.as_elements) + { + marshal_atom (cb, fsi.type1, data); + if (fsi.offset2) + marshal_atom (cb, fsi.type2, ((char *) data) + fsi.offset2); + return; + } + } + + if (!var && cb->used_float < NARGREG + && IS_FLOAT (type->type)) + { + marshal_atom (cb, type->type, data); + return; + } + + double promoted; + if (var && type->type == FFI_TYPE_FLOAT) + { + /* C standard requires promoting float -> double for variable arg. */ + promoted = *(float *) data; + type = &ffi_type_double; + data = &promoted; + } +#endif + + if (type->size > 2 * __SIZEOF_POINTER__) + /* Pass by reference. */ + { + allocate_and_copy_struct_to_stack (cb, data, type); + data = (char *)cb->stack + cb->next_struct_area; + marshal_atom (cb, FFI_TYPE_POINTER, &data); + } + else if (IS_INT (type->type) || type->type == FFI_TYPE_POINTER) + marshal_atom (cb, type->type, data); + else + { + /* Overlong integers, soft-float floats, and structs without special + float handling are treated identically from this point on. */ + + /* Variadics are aligned even in registers. */ + if (type->alignment > __SIZEOF_POINTER__) + { + if (var) + cb->used_integer = ALIGN (cb->used_integer, 2); + cb->used_stack + = (size_t *) ALIGN (cb->used_stack, 2 * __SIZEOF_POINTER__); + } + + memcpy (realign, data, type->size); + if (type->size > 0) + marshal_atom (cb, FFI_TYPE_POINTER, realign); + if (type->size > __SIZEOF_POINTER__) + marshal_atom (cb, FFI_TYPE_POINTER, realign + 1); + } +} + +/* For arguments passed by reference returns the pointer, otherwise the arg + is copied (up to MAXCOPYARG bytes). */ +static void * +unmarshal (call_builder *cb, ffi_type *type, int var, void *data) +{ + size_t realign[2]; + void *pointer; + +#if ABI_FRLEN + if (!var && type->type == FFI_TYPE_STRUCT) + { + float_struct_info fsi = struct_passed_as_elements (cb, type); + if (fsi.as_elements) + { + unmarshal_atom (cb, fsi.type1, data); + if (fsi.offset2) + unmarshal_atom (cb, fsi.type2, ((char *) data) + fsi.offset2); + return data; + } + } + + if (!var && cb->used_float < NARGREG + && IS_FLOAT (type->type)) + { + unmarshal_atom (cb, type->type, data); + return data; + } + + if (var && type->type == FFI_TYPE_FLOAT) + { + int m = cb->used_integer; + void *promoted + = m < NARGREG ? cb->aregs->a + m : cb->used_stack + m - NARGREG + 1; + *(float *) promoted = *(double *) promoted; + } +#endif + + if (type->size > 2 * __SIZEOF_POINTER__) + { + /* Pass by reference. */ + unmarshal_atom (cb, FFI_TYPE_POINTER, (char *) &pointer); + return pointer; + } + else if (IS_INT (type->type) || type->type == FFI_TYPE_POINTER) + { + unmarshal_atom (cb, type->type, data); + return data; + } + else + { + /* Overlong integers, soft-float floats, and structs without special + float handling are treated identically from this point on. */ + + /* Variadics are aligned even in registers. */ + if (type->alignment > __SIZEOF_POINTER__) + { + if (var) + cb->used_integer = ALIGN (cb->used_integer, 2); + cb->used_stack + = (size_t *) ALIGN (cb->used_stack, 2 * __SIZEOF_POINTER__); + } + + if (type->size > 0) + unmarshal_atom (cb, FFI_TYPE_POINTER, realign); + if (type->size > __SIZEOF_POINTER__) + unmarshal_atom (cb, FFI_TYPE_POINTER, realign + 1); + memcpy (data, realign, type->size); + return data; + } +} + +static int +passed_by_ref (call_builder *cb, ffi_type *type, int var) +{ +#if ABI_FRLEN + if (!var && type->type == FFI_TYPE_STRUCT) + { + float_struct_info fsi = struct_passed_as_elements (cb, type); + if (fsi.as_elements) + return 0; + } +#endif + + return type->size > 2 * __SIZEOF_POINTER__; +} + +/* Perform machine dependent cif processing. */ +ffi_status +ffi_prep_cif_machdep (ffi_cif *cif) +{ + cif->loongarch_nfixedargs = cif->nargs; + return FFI_OK; +} + +/* Perform machine dependent cif processing when we have a variadic + function. */ +ffi_status +ffi_prep_cif_machdep_var (ffi_cif *cif, unsigned int nfixedargs, + unsigned int ntotalargs) +{ + cif->loongarch_nfixedargs = nfixedargs; + return FFI_OK; +} + +/* Low level routine for calling functions. */ +extern void ffi_call_asm (void *stack, struct call_context *regs, + void (*fn) (void), void *closure) FFI_HIDDEN; + +static void +ffi_call_int (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue, + void *closure) +{ + /* This is a conservative estimate, assuming a complex return value and + that all remaining arguments are long long / __int128 */ + size_t arg_bytes = cif->bytes; + size_t rval_bytes = 0; + if (rvalue == NULL && cif->rtype->size > 2 * __SIZEOF_POINTER__) + rval_bytes = ALIGN (cif->rtype->size, STKALIGN); + size_t alloc_size = arg_bytes + rval_bytes + sizeof (call_context); + + /* The assembly code will deallocate all stack data at lower addresses + than the argument region, so we need to allocate the frame and the + return value after the arguments in a single allocation. */ + /* Argument region must be 16-byte aligned in LP64 ABIs. */ + size_t alloc_base = ALIGN (alloca (alloc_size + STKALIGN - 1), STKALIGN); + + if (rval_bytes) + rvalue = (void *) (alloc_base + arg_bytes); + + call_builder cb; + cb.used_float = cb.used_integer = 0; + cb.aregs = (call_context *) (alloc_base + arg_bytes + rval_bytes); + cb.used_stack = (void *) alloc_base; + cb.stack = (void *) alloc_base; + cb.next_struct_area = arg_bytes; + + int return_by_ref = passed_by_ref (&cb, cif->rtype, 0); + if (return_by_ref) + cb.aregs->a[cb.used_integer++] = (size_t)rvalue; + + int i; + for (i = 0; i < cif->nargs; i++) + marshal (&cb, cif->arg_types[i], i >= cif->loongarch_nfixedargs, + avalue[i]); + + ffi_call_asm ((void *) alloc_base, cb.aregs, fn, closure); + + cb.used_float = cb.used_integer = 0; + if (!return_by_ref && rvalue) + unmarshal (&cb, cif->rtype, 0, rvalue); +} + +void +ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue) +{ + ffi_call_int (cif, fn, rvalue, avalue, NULL); +} + +void +ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue, + void *closure) +{ + ffi_call_int (cif, fn, rvalue, avalue, closure); +} + +extern void ffi_closure_asm (void) FFI_HIDDEN; + +ffi_status +ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, void *codeloc) +{ + uint32_t *tramp = (uint32_t *) &closure->tramp[0]; + uint64_t fn = (uint64_t) (uintptr_t) ffi_closure_asm; + + if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI) + return FFI_BAD_ABI; + +#if defined(FFI_EXEC_STATIC_TRAMP) + if (ffi_tramp_is_present(closure)) + { + ffi_tramp_set_parms (closure->ftramp, ffi_closure_asm, closure); + goto out; + } +#endif + + /* Fill the dynamic trampoline. We will call ffi_closure_inner with codeloc, + not closure, but as long as the memory is readable it should work. */ + tramp[0] = 0x1800000c; /* pcaddi $t0, 0 (i.e. $t0 <- tramp) */ + tramp[1] = 0x28c0418d; /* ld.d $t1, $t0, 16 */ + tramp[2] = 0x4c0001a0; /* jirl $zero, $t1, 0 */ + tramp[3] = 0x03400000; /* nop */ + tramp[4] = fn; + tramp[5] = fn >> 32; + + __builtin___clear_cache (codeloc, codeloc + FFI_TRAMPOLINE_SIZE); + +#if defined(FFI_EXEC_STATIC_TRAMP) +out: +#endif + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + +/* Called by the assembly code with aregs pointing to saved argument registers + and stack pointing to the stacked arguments. Return values passed in + registers will be reloaded from aregs. */ +void FFI_HIDDEN +ffi_closure_inner (ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, size_t *stack, call_context *aregs) +{ + void **avalue = alloca (cif->nargs * sizeof (void *)); + /* Storage for arguments which will be copied by unmarshal(). We could + theoretically avoid the copies in many cases and use at most 128 bytes + of memory, but allocating disjoint storage for each argument is + simpler. */ + char *astorage = alloca (cif->nargs * MAXCOPYARG); + void *rvalue; + call_builder cb; + int return_by_ref; + int i; + + cb.aregs = aregs; + cb.used_integer = cb.used_float = 0; + cb.used_stack = stack; + + return_by_ref = passed_by_ref (&cb, cif->rtype, 0); + if (return_by_ref) + unmarshal (&cb, &ffi_type_pointer, 0, &rvalue); + else + rvalue = alloca (cif->rtype->size); + + for (i = 0; i < cif->nargs; i++) + avalue[i] + = unmarshal (&cb, cif->arg_types[i], i >= cif->loongarch_nfixedargs, + astorage + i * MAXCOPYARG); + + fun (cif, rvalue, avalue, user_data); + + if (!return_by_ref && cif->rtype->type != FFI_TYPE_VOID) + { + cb.used_integer = cb.used_float = 0; + marshal (&cb, cif->rtype, 0, rvalue); + } +} + +#if defined(FFI_EXEC_STATIC_TRAMP) +void * +ffi_tramp_arch (size_t *tramp_size, size_t *map_size) +{ + extern void *trampoline_code_table; + + *tramp_size = 16; + /* A mapping size of 64K is chosen to cover the page sizes of 4K, 16K, and + 64K. */ + *map_size = 1 << 16; + return &trampoline_code_table; +} +#endif diff --git a/js/src/ctypes/libffi/src/loongarch64/ffitarget.h b/js/src/ctypes/libffi/src/loongarch64/ffitarget.h new file mode 100644 index 0000000000..f7d90c5773 --- /dev/null +++ b/js/src/ctypes/libffi/src/loongarch64/ffitarget.h @@ -0,0 +1,81 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2022 Xu Chenghua + 2022 Cheng Lulu + + Target configuration macros for LoongArch. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error \ + "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifndef __loongarch__ +#error \ + "libffi was configured for a LoongArch target but this does not appear to be a LoongArch compiler." +#endif + +#ifndef LIBFFI_ASM + +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi +{ + FFI_FIRST_ABI = 0, + FFI_LP64S, + FFI_LP64F, + FFI_LP64D, + FFI_LAST_ABI, + +#if defined(__loongarch64) +#if defined(__loongarch_soft_float) + FFI_DEFAULT_ABI = FFI_LP64S +#elif defined(__loongarch_single_float) + FFI_DEFAULT_ABI = FFI_LP64F +#elif defined(__loongarch_double_float) + FFI_DEFAULT_ABI = FFI_LP64D +#else +#error unsupported LoongArch floating-point ABI +#endif +#else +#error unsupported LoongArch base architecture +#endif +} ffi_abi; + +#endif /* LIBFFI_ASM */ + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 24 +#define FFI_NATIVE_RAW_API 0 +#define FFI_EXTRA_CIF_FIELDS \ + unsigned loongarch_nfixedargs; \ + unsigned loongarch_unused; +#define FFI_TARGET_SPECIFIC_VARIADIC +#endif diff --git a/js/src/ctypes/libffi/src/loongarch64/sysv.S b/js/src/ctypes/libffi/src/loongarch64/sysv.S new file mode 100644 index 0000000000..aa7bde2c1e --- /dev/null +++ b/js/src/ctypes/libffi/src/loongarch64/sysv.S @@ -0,0 +1,327 @@ +/* ----------------------------------------------------------------------- + sysv.S - Copyright (c) 2022 Xu Chenghua + 2022 Cheng Lulu + + LoongArch Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#define LIBFFI_ASM +#include +#include + +/* Define aliases so that we can handle all ABIs uniformly. */ + +#if __SIZEOF_POINTER__ == 8 +# define PTRS 8 +# define LARG ld.d +# define SARG st.d +#else +# define PTRS 4 +# define LARG ld.w +# define SARG st.w +#endif + +#if defined(__loongarch_single_float) +# define FLTS 4 +# define FLD fld.w +# define FST fst.w +#elif defined(__loongarch_double_float) +# define FLTS 8 +# define FLARG fld.d +# define FSARG fst.d +#elif defined(__loongarch_soft_float) +# define FLTS 0 +#else +#error unsupported LoongArch floating-point ABI +#endif + + .text + .globl ffi_call_asm + .type ffi_call_asm, @function + .hidden ffi_call_asm +/* struct call_context + { + ABI_FLOAT fa[8]; + size_t a[10]; + } + + - 8 floating point parameter/result registers (fa[0] - fa[7]) + - 8 integer parameter/result registers (a[0] - a[7]) + - 2 registers used by the assembly code to in-place construct its own stack + frame. + - frame pointer (a[8]) + - return address (a[9]) + + void ffi_call_asm (size_t *stackargs, struct call_context *regargs, + void (*fn)(void), void *closure); */ + +#define FRAME_LEN (8 * FLTS + 10 * PTRS) + +ffi_call_asm: + .cfi_startproc + + /* We are NOT going to set up an ordinary stack frame. In order to pass + the stacked args to the called function, we adjust our stack pointer + to a0, which is in the _caller's_ alloca area. We establish our own + stack frame at the end of the call_context. + + Anything below the arguments will be freed at this point, although + we preserve the call_context so that it can be read back in the + caller. */ + + .cfi_def_cfa 5, FRAME_LEN # Interim CFA based on a1. + SARG $fp, $a1, FRAME_LEN - 2*PTRS + .cfi_offset 22, -2*PTRS + SARG $ra, $a1, FRAME_LEN - 1*PTRS + .cfi_offset 1, -1*PTRS + + addi.d $fp, $a1, FRAME_LEN + move $sp, $a0 + .cfi_def_cfa 22, 0 # Our frame is fully set up. + + # Load arguments. + move $t1, $a2 + move $t2, $a3 + +#if FLTS + FLARG $fa0, $fp, -FRAME_LEN+0*FLTS + FLARG $fa1, $fp, -FRAME_LEN+1*FLTS + FLARG $fa2, $fp, -FRAME_LEN+2*FLTS + FLARG $fa3, $fp, -FRAME_LEN+3*FLTS + FLARG $fa4, $fp, -FRAME_LEN+4*FLTS + FLARG $fa5, $fp, -FRAME_LEN+5*FLTS + FLARG $fa6, $fp, -FRAME_LEN+6*FLTS + FLARG $fa7, $fp, -FRAME_LEN+7*FLTS +#endif + + LARG $a0, $fp, -FRAME_LEN+8*FLTS+0*PTRS + LARG $a1, $fp, -FRAME_LEN+8*FLTS+1*PTRS + LARG $a2, $fp, -FRAME_LEN+8*FLTS+2*PTRS + LARG $a3, $fp, -FRAME_LEN+8*FLTS+3*PTRS + LARG $a4, $fp, -FRAME_LEN+8*FLTS+4*PTRS + LARG $a5, $fp, -FRAME_LEN+8*FLTS+5*PTRS + LARG $a6, $fp, -FRAME_LEN+8*FLTS+6*PTRS + LARG $a7, $fp, -FRAME_LEN+8*FLTS+7*PTRS + + /* Call */ + jirl $ra, $t1, 0 + +#if FLTS + /* Save return values - only a0/a1 (fa0/fa1) are used. */ + FSARG $fa0, $fp, -FRAME_LEN+0*FLTS + FSARG $fa1, $fp, -FRAME_LEN+1*FLTS +#endif + + SARG $a0, $fp, -FRAME_LEN+8*FLTS+0*PTRS + SARG $a1, $fp, -FRAME_LEN+8*FLTS+1*PTRS + + /* Restore and return. */ + addi.d $sp, $fp, -FRAME_LEN + .cfi_def_cfa 3, FRAME_LEN + LARG $ra, $fp, -1*PTRS + .cfi_restore 1 + LARG $fp, $fp, -2*PTRS + .cfi_restore 22 + jr $ra + .cfi_endproc + .size ffi_call_asm, .-ffi_call_asm + + +/* ffi_closure_asm. Expects address of the passed-in ffi_closure in t0. + void ffi_closure_inner (ffi_cif *cif, + void (*fun)(ffi_cif *, void *, void **, void *), + void *user_data, + size_t *stackargs, struct call_context *regargs) */ + + .globl ffi_closure_asm + .hidden ffi_closure_asm + .type ffi_closure_asm, @function + +ffi_closure_asm: + .cfi_startproc + addi.d $sp, $sp, -FRAME_LEN + .cfi_def_cfa_offset FRAME_LEN + + /* Make a frame. */ + SARG $fp, $sp, FRAME_LEN - 2*PTRS + .cfi_offset 22, -2*PTRS + SARG $ra, $sp, FRAME_LEN - 1*PTRS + .cfi_offset 1, -1*PTRS + addi.d $fp, $sp, FRAME_LEN + + /* Save arguments. */ +#if FLTS + FSARG $fa0, $sp, 0*FLTS + FSARG $fa1, $sp, 1*FLTS + FSARG $fa2, $sp, 2*FLTS + FSARG $fa3, $sp, 3*FLTS + FSARG $fa4, $sp, 4*FLTS + FSARG $fa5, $sp, 5*FLTS + FSARG $fa6, $sp, 6*FLTS + FSARG $fa7, $sp, 7*FLTS +#endif + + SARG $a0, $sp, 8*FLTS+0*PTRS + SARG $a1, $sp, 8*FLTS+1*PTRS + SARG $a2, $sp, 8*FLTS+2*PTRS + SARG $a3, $sp, 8*FLTS+3*PTRS + SARG $a4, $sp, 8*FLTS+4*PTRS + SARG $a5, $sp, 8*FLTS+5*PTRS + SARG $a6, $sp, 8*FLTS+6*PTRS + SARG $a7, $sp, 8*FLTS+7*PTRS + + /* Enter C */ + LARG $a0, $t0, FFI_TRAMPOLINE_SIZE+0*PTRS + LARG $a1, $t0, FFI_TRAMPOLINE_SIZE+1*PTRS + LARG $a2, $t0, FFI_TRAMPOLINE_SIZE+2*PTRS + addi.d $a3, $sp, FRAME_LEN + move $a4, $sp + + bl ffi_closure_inner + + /* Return values. */ +#if FLTS + FLARG $fa0, $sp, 0*FLTS + FLARG $fa1, $sp, 1*FLTS +#endif + + LARG $a0, $sp, 8*FLTS+0*PTRS + LARG $a1, $sp, 8*FLTS+1*PTRS + + /* Restore and return. */ + LARG $ra, $sp, FRAME_LEN-1*PTRS + .cfi_restore 1 + LARG $fp, $sp, FRAME_LEN-2*PTRS + .cfi_restore 22 + addi.d $sp, $sp, FRAME_LEN + .cfi_def_cfa_offset 0 + jr $ra + .cfi_endproc + .size ffi_closure_asm, .-ffi_closure_asm + +/* Static trampoline code table, in which each element is a trampoline. + + The trampoline clobbers t0 and t1, but we don't save them on the stack + because our psABI explicitly says they are scratch registers, at least for + ELF. Our dynamic trampoline is already clobbering them anyway. + + The trampoline has two parameters - target code to jump to and data for + the target code. The trampoline extracts the parameters from its parameter + block (see tramp_table_map()). The trampoline saves the data address in + t0 and jumps to the target code. As ffi_closure_asm() already expects the + data address to be in t0, we don't need a "ffi_closure_asm_alt". */ + +#if defined(FFI_EXEC_STATIC_TRAMP) + .align 16 + .globl trampoline_code_table + .hidden trampoline_code_table + .type trampoline_code_table, @function + +trampoline_code_table: + + .rept 65536 / 16 + pcaddu12i $t1, 16 # 65536 >> 12 + ld.d $t0, $t1, 0 + ld.d $t1, $t1, 8 + jirl $zero, $t1, 0 + .endr + .size trampoline_code_table, .-trampoline_code_table + + .align 2 +#endif + +/* ffi_go_closure_asm. Expects address of the passed-in ffi_go_closure in t2. + void ffi_closure_inner (ffi_cif *cif, + void (*fun)(ffi_cif *, void *, void **, void *), + void *user_data, + size_t *stackargs, struct call_context *regargs) */ + + .globl ffi_go_closure_asm + .hidden ffi_go_closure_asm + .type ffi_go_closure_asm, @function + +ffi_go_closure_asm: + .cfi_startproc + addi.d $sp, $sp, -FRAME_LEN + .cfi_def_cfa_offset FRAME_LEN + + /* Make a frame. */ + SARG $fp, $sp, FRAME_LEN - 2*PTRS + .cfi_offset 22, -2*PTRS + SARG $ra, $sp, FRAME_LEN - 1*PTRS + .cfi_offset 1, -1*PTRS + addi.d $fp, $sp, FRAME_LEN + + /* Save arguments. */ +#if FLTS + FSARG $fa0, $sp, 0*FLTS + FSARG $fa1, $sp, 1*FLTS + FSARG $fa2, $sp, 2*FLTS + FSARG $fa3, $sp, 3*FLTS + FSARG $fa4, $sp, 4*FLTS + FSARG $fa5, $sp, 5*FLTS + FSARG $fa6, $sp, 6*FLTS + FSARG $fa7, $sp, 7*FLTS +#endif + + SARG $a0, $sp, 8*FLTS+0*PTRS + SARG $a1, $sp, 8*FLTS+1*PTRS + SARG $a2, $sp, 8*FLTS+2*PTRS + SARG $a3, $sp, 8*FLTS+3*PTRS + SARG $a4, $sp, 8*FLTS+4*PTRS + SARG $a5, $sp, 8*FLTS+5*PTRS + SARG $a6, $sp, 8*FLTS+6*PTRS + SARG $a7, $sp, 8*FLTS+7*PTRS + + /* Enter C */ + LARG $a0, $t2, 1*PTRS + LARG $a1, $t2, 2*PTRS + move $a2, $t2 + addi.d $a3, $sp, FRAME_LEN + move $a4, $sp + + bl ffi_closure_inner + + /* Return values. */ +#if FLTS + FLARG $fa0, $sp, 0*FLTS + FLARG $fa1, $sp, 1*FLTS +#endif + + LARG $a0, $sp, 8*FLTS+0*PTRS + LARG $a1, $sp, 8*FLTS+1*PTRS + + /* Restore and return. */ + LARG $ra, $sp, FRAME_LEN-1*PTRS + .cfi_restore 1 + LARG $fp, $sp, FRAME_LEN-2*PTRS + .cfi_restore 22 + addi.d $sp, $sp, FRAME_LEN + .cfi_def_cfa_offset 0 + jr $ra + .cfi_endproc + .size ffi_go_closure_asm, .-ffi_go_closure_asm + +#if defined __ELF__ && defined __linux__ + .section .note.GNU-stack,"",%progbits +#endif diff --git a/js/src/vm/HelperThreads.cpp b/js/src/vm/HelperThreads.cpp index b264b3bb9c..6d86db53d6 100644 --- a/js/src/vm/HelperThreads.cpp +++ b/js/src/vm/HelperThreads.cpp @@ -860,19 +860,30 @@ GlobalHelperThreadState::waitForAllThreads() template bool -GlobalHelperThreadState::checkTaskThreadLimit(size_t maxThreads) const +GlobalHelperThreadState::checkTaskThreadLimit(size_t maxThreads, bool isMaster) const { if (maxThreads >= threadCount) return true; size_t count = 0; + size_t idle = 0; for (auto& thread : *threads) { - if (thread.currentTask.isSome() && thread.currentTask->is()) - count++; + if (thread.currentTask.isSome()) { + if (thread.currentTask->is()) + count++; + } else { + idle++; + } if (count >= maxThreads) return false; } + // At least the current thread is idle. + MOZ_ASSERT(idle > 0); + + if (isMaster && idle <= 1) + return false; + return true; } @@ -916,11 +927,7 @@ GlobalHelperThreadState::maxParseThreads() const if (IsHelperThreadSimulatingOOM(js::oom::THREAD_TYPE_PARSE)) return 1; - // Don't allow simultaneous off thread parses, to reduce contention on the - // atoms table. Note that wasm compilation depends on this to avoid - // stalling the helper thread, as off thread parse tasks can trigger and - // block on other off thread wasm compilation tasks. - return 1; + return threadCount; } size_t @@ -1091,7 +1098,8 @@ GlobalHelperThreadState::pendingIonCompileHasSufficientPriority( bool GlobalHelperThreadState::canStartParseTask(const AutoLockHelperThreadState& lock) { - return !parseWorklist(lock).empty() && checkTaskThreadLimit(maxParseThreads()); + return !parseWorklist(lock).empty() && + checkTaskThreadLimit(maxParseThreads(), /* isMaster = */ true); } bool @@ -1892,49 +1900,68 @@ HelperThread::threadLoop() while (true) { MOZ_ASSERT(idle()); - // Block until a task is available. Save the value of whether we are - // going to do an Ion compile, in case the value returned by the method - // changes. - bool ionCompile = false; + js::oom::ThreadType task; while (true) { if (terminate) return; - if ((ionCompile = HelperThreadState().pendingIonCompileHasSufficientPriority(lock)) || - HelperThreadState().canStartWasmCompile(lock) || - HelperThreadState().canStartPromiseTask(lock) || - HelperThreadState().canStartParseTask(lock) || - HelperThreadState().canStartCompressionTask(lock) || - HelperThreadState().canStartGCHelperTask(lock) || - HelperThreadState().canStartGCParallelTask(lock)) - { + + // Select the task type to run. Task priority is determined + // exclusively here. + // + // The selectors may depend on the HelperThreadState not changing + // between task selection and task execution, in particular, on new + // tasks not being added (because of the lifo structure of the work + // lists). Unlocking the HelperThreadState between task selection + // and execution is not well-defined. + if (HelperThreadState().canStartGCParallelTask(lock)) + task = js::oom::THREAD_TYPE_GCPARALLEL; + else if (HelperThreadState().canStartGCHelperTask(lock)) + task = js::oom::THREAD_TYPE_GCHELPER; + else if (HelperThreadState().pendingIonCompileHasSufficientPriority(lock)) + task = js::oom::THREAD_TYPE_ION; + else if (HelperThreadState().canStartWasmCompile(lock)) + task = js::oom::THREAD_TYPE_ASMJS; + else if (HelperThreadState().canStartPromiseTask(lock)) + task = js::oom::THREAD_TYPE_PROMISE_TASK; + else if (HelperThreadState().canStartParseTask(lock)) + task = js::oom::THREAD_TYPE_PARSE; + else if (HelperThreadState().canStartCompressionTask(lock)) + task = js::oom::THREAD_TYPE_COMPRESS; + else + task = js::oom::THREAD_TYPE_NONE; + + if (task != js::oom::THREAD_TYPE_NONE) break; - } + HelperThreadState().wait(lock, GlobalHelperThreadState::PRODUCER); } - if (ionCompile) { - js::oom::SetThreadType(js::oom::THREAD_TYPE_ION); - handleIonWorkload(lock); - } else if (HelperThreadState().canStartWasmCompile(lock)) { - js::oom::SetThreadType(js::oom::THREAD_TYPE_ASMJS); - handleWasmWorkload(lock); - } else if (HelperThreadState().canStartPromiseTask(lock)) { - js::oom::SetThreadType(js::oom::THREAD_TYPE_PROMISE_TASK); - handlePromiseTaskWorkload(lock); - } else if (HelperThreadState().canStartParseTask(lock)) { - js::oom::SetThreadType(js::oom::THREAD_TYPE_PARSE); - handleParseWorkload(lock, stackLimit); - } else if (HelperThreadState().canStartCompressionTask(lock)) { - js::oom::SetThreadType(js::oom::THREAD_TYPE_COMPRESS); - handleCompressionWorkload(lock); - } else if (HelperThreadState().canStartGCHelperTask(lock)) { - js::oom::SetThreadType(js::oom::THREAD_TYPE_GCHELPER); - handleGCHelperWorkload(lock); - } else if (HelperThreadState().canStartGCParallelTask(lock)) { - js::oom::SetThreadType(js::oom::THREAD_TYPE_GCPARALLEL); + js::oom::SetThreadType(task); + switch (task) { + case js::oom::THREAD_TYPE_GCPARALLEL: handleGCParallelWorkload(lock); - } else { + break; + case js::oom::THREAD_TYPE_GCHELPER: + handleGCHelperWorkload(lock); + break; + case js::oom::THREAD_TYPE_ION: + handleIonWorkload(lock); + break; + case js::oom::THREAD_TYPE_ASMJS: + handleWasmWorkload(lock); + break; + case js::oom::THREAD_TYPE_PROMISE_TASK: + handlePromiseTaskWorkload(lock); + break; + case js::oom::THREAD_TYPE_PARSE: + handleParseWorkload(lock, stackLimit); + break; + case js::oom::THREAD_TYPE_COMPRESS: + handleCompressionWorkload(lock); + break; + default: MOZ_CRASH("No task to perform"); } + js::oom::SetThreadType(js::oom::THREAD_TYPE_NONE); } } diff --git a/js/src/vm/HelperThreads.h b/js/src/vm/HelperThreads.h index ebd4c9b9cb..5a1cc02e9a 100644 --- a/js/src/vm/HelperThreads.h +++ b/js/src/vm/HelperThreads.h @@ -256,7 +256,7 @@ class GlobalHelperThreadState void waitForAllThreads(); template - bool checkTaskThreadLimit(size_t maxThreads) const; + bool checkTaskThreadLimit(size_t maxThreads, bool isMaster = false) const; private: diff --git a/media/webrtc/trunk/build/install-build-deps.sh b/media/webrtc/trunk/build/install-build-deps.sh index b77e23a6d9..7da5b923a2 100644 --- a/media/webrtc/trunk/build/install-build-deps.sh +++ b/media/webrtc/trunk/build/install-build-deps.sh @@ -58,7 +58,7 @@ chromeos_dev_list="libbluetooth-dev libpulse-dev" # Packages need for development dev_list="apache2.2-bin bison curl elfutils fakeroot flex g++ gperf language-pack-fr libapache2-mod-php5 libasound2-dev libbz2-dev - libcairo2-dev libcups2-dev libcurl4-gnutls-dev libdbus-glib-1-dev + libcairo2-dev libcups2-dev libcurl4-gnutls-dev libelf-dev libgconf2-dev libgl1-mesa-dev libglib2.0-dev libglu1-mesa-dev libgnome-keyring-dev libgtk2.0-dev libkrb5-dev libnspr4-dev libnss3-dev libpam0g-dev libsctp-dev @@ -80,7 +80,7 @@ fi chromeos_lib_list="libpulse0 libbz2-1.0 libcurl4-gnutls-dev" # Full list of required run-time libraries -lib_list="libatk1.0-0 libc6 libasound2 libcairo2 libcups2 libdbus-glib-1-2 +lib_list="libatk1.0-0 libc6 libasound2 libcairo2 libcups2 libexpat1 libfontconfig1 libfreetype6 libglib2.0-0 libgnome-keyring0 libgtk2.0-0 libpam0g libpango1.0-0 libpcre3 libpixman-1-0 libpng12-0 libstdc++6 libsqlite3-0 libudev0 libx11-6 libxau6 libxcb1 @@ -89,7 +89,7 @@ lib_list="libatk1.0-0 libc6 libasound2 libcairo2 libcups2 libdbus-glib-1-2 $chromeos_lib_list" # Debugging symbols for all of the run-time libraries -dbg_list="libatk1.0-dbg libc6-dbg libcairo2-dbg libdbus-glib-1-2-dbg +dbg_list="libatk1.0-dbg libc6-dbg libcairo2-dbg libfontconfig1-dbg libglib2.0-0-dbg libgtk2.0-0-dbg libpango1.0-0-dbg libpcre3-dbg libpixman-1-0-dbg libsqlite3-0-dbg diff --git a/media/webrtc/trunk/build/linux/system.gyp b/media/webrtc/trunk/build/linux/system.gyp index e36e558a8b..78bc380d49 100644 --- a/media/webrtc/trunk/build/linux/system.gyp +++ b/media/webrtc/trunk/build/linux/system.gyp @@ -112,27 +112,6 @@ ], }, ], # targets - }, { # chromeos==1 - 'targets': [ - { - # TODO(satorux): Remove this once dbus-glib clients are gone. - 'target_name': 'dbus-glib', - 'type': 'none', - 'direct_dependent_settings': { - 'cflags': [ - ' - # is still not found even if the execution of - # build/config/linux/pkg-config.py dbus-glib-1 returns correct include - # dirs on Linux. - all_dependent_configs = [ "dbus-glib" ] - } - if (build_with_chromium) { defines += [ "LOGGING_INSIDE_WEBRTC" ] } else { diff --git a/media/webrtc/trunk/webrtc/base/BUILD.gn b/media/webrtc/trunk/webrtc/base/BUILD.gn index 0f7a3f2fbe..f0901993c3 100644 --- a/media/webrtc/trunk/webrtc/base/BUILD.gn +++ b/media/webrtc/trunk/webrtc/base/BUILD.gn @@ -426,10 +426,6 @@ static_library("rtc_base") { if (is_linux) { sources += [ - "dbus.cc", - "dbus.h", - "libdbusglibsymboltable.cc", - "libdbusglibsymboltable.h", "linuxfdwalk.c", "linuxfdwalk.h", ] diff --git a/media/webrtc/trunk/webrtc/base/base.gyp b/media/webrtc/trunk/webrtc/base/base.gyp index d269f41603..38a913fa2a 100644 --- a/media/webrtc/trunk/webrtc/base/base.gyp +++ b/media/webrtc/trunk/webrtc/base/base.gyp @@ -204,8 +204,6 @@ 'crc32.h', 'cryptstring.cc', 'cryptstring.h', - 'dbus.cc', - 'dbus.h', 'diskcache.cc', 'diskcache.h', 'diskcache_win32.cc', @@ -246,8 +244,6 @@ 'json.h', 'latebindingsymboltable.cc', 'latebindingsymboltable.h', - 'libdbusglibsymboltable.cc', - 'libdbusglibsymboltable.h', 'linux.cc', 'linux.h', 'linuxfdwalk.c', @@ -456,8 +452,6 @@ 'bandwidthsmoother.h', 'bind.h', 'callback.h', - 'dbus.cc', - 'dbus.h', 'diskcache_win32.cc', 'diskcache_win32.h', 'fileutils_mock.h', @@ -468,8 +462,6 @@ 'json.h', 'latebindingsymboltable.cc', 'latebindingsymboltable.h', - 'libdbusglibsymboltable.cc', - 'libdbusglibsymboltable.h', 'linuxfdwalk.c', 'linuxfdwalk.h', 'x11windowpicker.cc', @@ -627,10 +619,6 @@ }, }, { 'sources!': [ - 'dbus.cc', - 'dbus.h', - 'libdbusglibsymboltable.cc', - 'libdbusglibsymboltable.h', 'linuxfdwalk.c', ], }], diff --git a/media/webrtc/trunk/webrtc/base/dbus.cc b/media/webrtc/trunk/webrtc/base/dbus.cc deleted file mode 100644 index 312bad0509..0000000000 --- a/media/webrtc/trunk/webrtc/base/dbus.cc +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifdef HAVE_DBUS_GLIB - -#include "webrtc/base/dbus.h" - -#include - -#include "webrtc/base/logging.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -// Avoid static object construction/destruction on startup/shutdown. -static pthread_once_t g_dbus_init_once = PTHREAD_ONCE_INIT; -static LibDBusGlibSymbolTable *g_dbus_symbol = NULL; - -// Releases DBus-Glib symbols. -static void ReleaseDBusGlibSymbol() { - if (g_dbus_symbol != NULL) { - delete g_dbus_symbol; - g_dbus_symbol = NULL; - } -} - -// Loads DBus-Glib symbols. -static void InitializeDBusGlibSymbol() { - // This is thread safe. - if (NULL == g_dbus_symbol) { - g_dbus_symbol = new LibDBusGlibSymbolTable(); - - // Loads dbus-glib - if (NULL == g_dbus_symbol || !g_dbus_symbol->Load()) { - LOG(LS_WARNING) << "Failed to load dbus-glib symbol table."; - ReleaseDBusGlibSymbol(); - } else { - // Nothing we can do if atexit() failed. Just ignore its returned value. - atexit(ReleaseDBusGlibSymbol); - } - } -} - -inline static LibDBusGlibSymbolTable *GetSymbols() { - return DBusMonitor::GetDBusGlibSymbolTable(); -} - -// Implementation of class DBusSigMessageData -DBusSigMessageData::DBusSigMessageData(DBusMessage *message) - : TypedMessageData(message) { - GetSymbols()->dbus_message_ref()(data()); -} - -DBusSigMessageData::~DBusSigMessageData() { - GetSymbols()->dbus_message_unref()(data()); -} - -// Implementation of class DBusSigFilter - -// Builds a DBus filter string from given DBus path, interface and member. -std::string DBusSigFilter::BuildFilterString(const std::string &path, - const std::string &interface, - const std::string &member) { - std::string ret(DBUS_TYPE "='" DBUS_SIGNAL "'"); - if (!path.empty()) { - ret += ("," DBUS_PATH "='"); - ret += path; - ret += "'"; - } - if (!interface.empty()) { - ret += ("," DBUS_INTERFACE "='"); - ret += interface; - ret += "'"; - } - if (!member.empty()) { - ret += ("," DBUS_MEMBER "='"); - ret += member; - ret += "'"; - } - return ret; -} - -// Forwards the message to the given instance. -DBusHandlerResult DBusSigFilter::DBusCallback(DBusConnection *dbus_conn, - DBusMessage *message, - void *instance) { - ASSERT(instance); - if (instance) { - return static_cast(instance)->Callback(message); - } - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -// Posts a message to caller thread. -DBusHandlerResult DBusSigFilter::Callback(DBusMessage *message) { - if (caller_thread_) { - caller_thread_->Post(this, DSM_SIGNAL, new DBusSigMessageData(message)); - } - // Don't "eat" the message here. Let it pop up. - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -// From MessageHandler. -void DBusSigFilter::OnMessage(Message *message) { - if (message != NULL && DSM_SIGNAL == message->message_id) { - DBusSigMessageData *msg = - static_cast(message->pdata); - if (msg) { - ProcessSignal(msg->data()); - delete msg; - } - } -} - -// Definition of private class DBusMonitoringThread. -// It creates a worker-thread to listen signals on DBus. The worker-thread will -// be running in a priate GMainLoop forever until either Stop() has been invoked -// or it hits an error. -class DBusMonitor::DBusMonitoringThread : public rtc::Thread { - public: - explicit DBusMonitoringThread(DBusMonitor *monitor, - GMainContext *context, - GMainLoop *mainloop, - std::vector *filter_list) - : monitor_(monitor), - context_(context), - mainloop_(mainloop), - connection_(NULL), - idle_source_(NULL), - filter_list_(filter_list) { - ASSERT(monitor_); - ASSERT(context_); - ASSERT(mainloop_); - ASSERT(filter_list_); - } - - virtual ~DBusMonitoringThread() { - Stop(); - } - - // Override virtual method of Thread. Context: worker-thread. - virtual void Run() { - ASSERT(NULL == connection_); - - // Setup DBus connection and start monitoring. - monitor_->OnMonitoringStatusChanged(DMS_INITIALIZING); - if (!Setup()) { - LOG(LS_ERROR) << "DBus monitoring setup failed."; - monitor_->OnMonitoringStatusChanged(DMS_FAILED); - CleanUp(); - return; - } - monitor_->OnMonitoringStatusChanged(DMS_RUNNING); - g_main_loop_run(mainloop_); - monitor_->OnMonitoringStatusChanged(DMS_STOPPED); - - // Done normally. Clean up DBus connection. - CleanUp(); - return; - } - - // Override virtual method of Thread. Context: caller-thread. - virtual void Stop() { - ASSERT(NULL == idle_source_); - // Add an idle source and let the gmainloop quit on idle. - idle_source_ = g_idle_source_new(); - if (idle_source_) { - g_source_set_callback(idle_source_, &Idle, this, NULL); - g_source_attach(idle_source_, context_); - } else { - LOG(LS_ERROR) << "g_idle_source_new() failed."; - QuitGMainloop(); // Try to quit anyway. - } - - Thread::Stop(); // Wait for the thread. - } - - private: - // Registers all DBus filters. - void RegisterAllFilters() { - ASSERT(NULL != GetSymbols()->dbus_g_connection_get_connection()( - connection_)); - - for (std::vector::iterator it = filter_list_->begin(); - it != filter_list_->end(); ++it) { - DBusSigFilter *filter = (*it); - if (!filter) { - LOG(LS_ERROR) << "DBusSigFilter list corrupted."; - continue; - } - - GetSymbols()->dbus_bus_add_match()( - GetSymbols()->dbus_g_connection_get_connection()(connection_), - filter->filter().c_str(), NULL); - - if (!GetSymbols()->dbus_connection_add_filter()( - GetSymbols()->dbus_g_connection_get_connection()(connection_), - &DBusSigFilter::DBusCallback, filter, NULL)) { - LOG(LS_ERROR) << "dbus_connection_add_filter() failed." - << "Filter: " << filter->filter(); - continue; - } - } - } - - // Unregisters all DBus filters. - void UnRegisterAllFilters() { - ASSERT(NULL != GetSymbols()->dbus_g_connection_get_connection()( - connection_)); - - for (std::vector::iterator it = filter_list_->begin(); - it != filter_list_->end(); ++it) { - DBusSigFilter *filter = (*it); - if (!filter) { - LOG(LS_ERROR) << "DBusSigFilter list corrupted."; - continue; - } - GetSymbols()->dbus_connection_remove_filter()( - GetSymbols()->dbus_g_connection_get_connection()(connection_), - &DBusSigFilter::DBusCallback, filter); - } - } - - // Sets up the monitoring thread. - bool Setup() { - g_main_context_push_thread_default(context_); - - // Start connection to dbus. - // If dbus daemon is not running, returns false immediately. - connection_ = GetSymbols()->dbus_g_bus_get_private()(monitor_->type_, - context_, NULL); - if (NULL == connection_) { - LOG(LS_ERROR) << "dbus_g_bus_get_private() unable to get connection."; - return false; - } - if (NULL == GetSymbols()->dbus_g_connection_get_connection()(connection_)) { - LOG(LS_ERROR) << "dbus_g_connection_get_connection() returns NULL. " - << "DBus daemon is probably not running."; - return false; - } - - // Application don't exit if DBus daemon die. - GetSymbols()->dbus_connection_set_exit_on_disconnect()( - GetSymbols()->dbus_g_connection_get_connection()(connection_), FALSE); - - // Connect all filters. - RegisterAllFilters(); - - return true; - } - - // Cleans up the monitoring thread. - void CleanUp() { - if (idle_source_) { - // We did an attach() with the GSource, so we need to destroy() it. - g_source_destroy(idle_source_); - // We need to unref() the GSource to end the last reference we got. - g_source_unref(idle_source_); - idle_source_ = NULL; - } - if (connection_) { - if (GetSymbols()->dbus_g_connection_get_connection()(connection_)) { - UnRegisterAllFilters(); - GetSymbols()->dbus_connection_close()( - GetSymbols()->dbus_g_connection_get_connection()(connection_)); - } - GetSymbols()->dbus_g_connection_unref()(connection_); - connection_ = NULL; - } - g_main_loop_unref(mainloop_); - mainloop_ = NULL; - g_main_context_unref(context_); - context_ = NULL; - } - - // Handles callback on Idle. We only add this source when ready to stop. - static gboolean Idle(gpointer data) { - static_cast(data)->QuitGMainloop(); - return TRUE; - } - - // We only hit this when ready to quit. - void QuitGMainloop() { - g_main_loop_quit(mainloop_); - } - - DBusMonitor *monitor_; - - GMainContext *context_; - GMainLoop *mainloop_; - DBusGConnection *connection_; - GSource *idle_source_; - - std::vector *filter_list_; -}; - -// Implementation of class DBusMonitor - -// Returns DBus-Glib symbol handle. Initialize it first if hasn't. -LibDBusGlibSymbolTable *DBusMonitor::GetDBusGlibSymbolTable() { - // This is multi-thread safe. - pthread_once(&g_dbus_init_once, InitializeDBusGlibSymbol); - - return g_dbus_symbol; -}; - -// Creates an instance of DBusMonitor -DBusMonitor *DBusMonitor::Create(DBusBusType type) { - if (NULL == DBusMonitor::GetDBusGlibSymbolTable()) { - return NULL; - } - return new DBusMonitor(type); -} - -DBusMonitor::DBusMonitor(DBusBusType type) - : type_(type), - status_(DMS_NOT_INITIALIZED), - monitoring_thread_(NULL) { - ASSERT(type_ == DBUS_BUS_SYSTEM || type_ == DBUS_BUS_SESSION); -} - -DBusMonitor::~DBusMonitor() { - StopMonitoring(); -} - -bool DBusMonitor::AddFilter(DBusSigFilter *filter) { - if (monitoring_thread_) { - return false; - } - if (!filter) { - return false; - } - filter_list_.push_back(filter); - return true; -} - -bool DBusMonitor::StartMonitoring() { - if (!monitoring_thread_) { - g_type_init(); - // g_thread_init API is deprecated since glib 2.31.0, see release note: - // http://mail.gnome.org/archives/gnome-announce-list/2011-October/msg00041.html -#if !GLIB_CHECK_VERSION(2, 31, 0) - g_thread_init(NULL); -#endif - GetSymbols()->dbus_g_thread_init()(); - - GMainContext *context = g_main_context_new(); - if (NULL == context) { - LOG(LS_ERROR) << "g_main_context_new() failed."; - return false; - } - - GMainLoop *mainloop = g_main_loop_new(context, FALSE); - if (NULL == mainloop) { - LOG(LS_ERROR) << "g_main_loop_new() failed."; - g_main_context_unref(context); - return false; - } - - monitoring_thread_ = new DBusMonitoringThread(this, context, mainloop, - &filter_list_); - if (monitoring_thread_ == NULL) { - LOG(LS_ERROR) << "Failed to create DBus monitoring thread."; - g_main_context_unref(context); - g_main_loop_unref(mainloop); - return false; - } - monitoring_thread_->Start(); - } - return true; -} - -bool DBusMonitor::StopMonitoring() { - if (monitoring_thread_) { - monitoring_thread_->Stop(); - monitoring_thread_ = NULL; - } - return true; -} - -DBusMonitor::DBusMonitorStatus DBusMonitor::GetStatus() { - return status_; -} - -void DBusMonitor::OnMonitoringStatusChanged(DBusMonitorStatus status) { - status_ = status; -} - -#undef LATE - -} // namespace rtc - -#endif // HAVE_DBUS_GLIB diff --git a/media/webrtc/trunk/webrtc/base/dbus.h b/media/webrtc/trunk/webrtc/base/dbus.h deleted file mode 100644 index fb90638bc3..0000000000 --- a/media/webrtc/trunk/webrtc/base/dbus.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_DBUS_H_ -#define WEBRTC_BASE_DBUS_H_ - -#ifdef HAVE_DBUS_GLIB - -#include - -#include -#include - -#include "webrtc/base/libdbusglibsymboltable.h" -#include "webrtc/base/messagehandler.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -#define DBUS_TYPE "type" -#define DBUS_SIGNAL "signal" -#define DBUS_PATH "path" -#define DBUS_INTERFACE "interface" -#define DBUS_MEMBER "member" - -#ifdef CHROMEOS -#define CROS_PM_PATH "/" -#define CROS_PM_INTERFACE "org.chromium.PowerManager" -#define CROS_SIG_POWERCHANGED "PowerStateChanged" -#define CROS_VALUE_SLEEP "mem" -#define CROS_VALUE_RESUME "on" -#else -#define UP_PATH "/org/freedesktop/UPower" -#define UP_INTERFACE "org.freedesktop.UPower" -#define UP_SIG_SLEEPING "Sleeping" -#define UP_SIG_RESUMING "Resuming" -#endif // CHROMEOS - -// Wraps a DBus messages. -class DBusSigMessageData : public TypedMessageData { - public: - explicit DBusSigMessageData(DBusMessage *message); - ~DBusSigMessageData(); -}; - -// DBusSigFilter is an abstract class that defines the interface of DBus -// signal handling. -// The subclasses implement ProcessSignal() for various purposes. -// When a DBus signal comes, a DSM_SIGNAL message is posted to the caller thread -// which will then invokes ProcessSignal(). -class DBusSigFilter : protected MessageHandler { - public: - enum DBusSigMessage { DSM_SIGNAL }; - - // This filter string should ususally come from BuildFilterString() - explicit DBusSigFilter(const std::string &filter) - : caller_thread_(Thread::Current()), filter_(filter) { - } - - // Builds a DBus monitor filter string from given DBus path, interface, and - // member. - // See http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html - static std::string BuildFilterString(const std::string &path, - const std::string &interface, - const std::string &member); - - // Handles callback on DBus messages by DBus system. - static DBusHandlerResult DBusCallback(DBusConnection *dbus_conn, - DBusMessage *message, - void *instance); - - // Handles callback on DBus messages to each DBusSigFilter instance. - DBusHandlerResult Callback(DBusMessage *message); - - // From MessageHandler. - virtual void OnMessage(Message *message); - - // Returns the DBus monitor filter string. - const std::string &filter() const { return filter_; } - - private: - // On caller thread. - virtual void ProcessSignal(DBusMessage *message) = 0; - - Thread *caller_thread_; - const std::string filter_; -}; - -// DBusMonitor is a class for DBus signal monitoring. -// -// The caller-thread calls AddFilter() first to add the signals that it wants to -// monitor and then calls StartMonitoring() to start the monitoring. -// This will create a worker-thread which listens on DBus connection and sends -// DBus signals back through the callback. -// The worker-thread will be running forever until either StopMonitoring() is -// called from the caller-thread or the worker-thread hit some error. -// -// Programming model: -// 1. Caller-thread: Creates an object of DBusMonitor. -// 2. Caller-thread: Calls DBusMonitor::AddFilter() one or several times. -// 3. Caller-thread: StartMonitoring(). -// ... -// 4. Worker-thread: DBus signal recieved. Post a message to caller-thread. -// 5. Caller-thread: DBusFilterBase::ProcessSignal() is invoked. -// ... -// 6. Caller-thread: StopMonitoring(). -// -// Assumption: -// AddFilter(), StartMonitoring(), and StopMonitoring() methods are called by -// a single thread. Hence, there is no need to make them thread safe. -class DBusMonitor { - public: - // Status of DBus monitoring. - enum DBusMonitorStatus { - DMS_NOT_INITIALIZED, // Not initialized. - DMS_INITIALIZING, // Initializing the monitoring thread. - DMS_RUNNING, // Monitoring. - DMS_STOPPED, // Not monitoring. Stopped normally. - DMS_FAILED, // Not monitoring. Failed. - }; - - // Returns the DBus-Glib symbol table. - // We should only use this function to access DBus-Glib symbols. - static LibDBusGlibSymbolTable *GetDBusGlibSymbolTable(); - - // Creates an instance of DBusMonitor. - static DBusMonitor *Create(DBusBusType type); - ~DBusMonitor(); - - // Adds a filter to DBusMonitor. - bool AddFilter(DBusSigFilter *filter); - - // Starts DBus message monitoring. - bool StartMonitoring(); - - // Stops DBus message monitoring. - bool StopMonitoring(); - - // Gets the status of DBus monitoring. - DBusMonitorStatus GetStatus(); - - private: - // Forward declaration. Defined in the .cc file. - class DBusMonitoringThread; - - explicit DBusMonitor(DBusBusType type); - - // Updates status_ when monitoring status has changed. - void OnMonitoringStatusChanged(DBusMonitorStatus status); - - DBusBusType type_; - DBusMonitorStatus status_; - DBusMonitoringThread *monitoring_thread_; - std::vector filter_list_; -}; - -} // namespace rtc - -#endif // HAVE_DBUS_GLIB - -#endif // WEBRTC_BASE_DBUS_H_ diff --git a/media/webrtc/trunk/webrtc/base/dbus_unittest.cc b/media/webrtc/trunk/webrtc/base/dbus_unittest.cc deleted file mode 100644 index 17752f143f..0000000000 --- a/media/webrtc/trunk/webrtc/base/dbus_unittest.cc +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifdef HAVE_DBUS_GLIB - -#include "webrtc/base/dbus.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -#define SIG_NAME "NameAcquired" - -static const uint32_t kTimeoutMs = 5000U; - -class DBusSigFilterTest : public DBusSigFilter { - public: - // DBusSigFilterTest listens on DBus service itself for "NameAcquired" signal. - // This signal should be received when the application connects to DBus - // service and gains ownership of a name. - // http://dbus.freedesktop.org/doc/dbus-specification.html - DBusSigFilterTest() - : DBusSigFilter(GetFilter()), - message_received_(false) { - } - - bool MessageReceived() { - return message_received_; - } - - private: - static std::string GetFilter() { - return rtc::DBusSigFilter::BuildFilterString("", "", SIG_NAME); - } - - // Implement virtual method of DBusSigFilter. On caller thread. - virtual void ProcessSignal(DBusMessage *message) { - EXPECT_TRUE(message != NULL); - message_received_ = true; - } - - bool message_received_; -}; - -TEST(DBusMonitorTest, StartStopStartStop) { - DBusSigFilterTest filter; - rtc::scoped_ptr monitor; - monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM)); - if (monitor) { - EXPECT_TRUE(monitor->AddFilter(&filter)); - - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_NOT_INITIALIZED); - - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs); - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED); - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED); - - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs); - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_RUNNING); - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED); - } else { - LOG(LS_WARNING) << "DBus Monitor not started. Skipping test."; - } -} - -// DBusMonitorTest listens on DBus service itself for "NameAcquired" signal. -// This signal should be received when the application connects to DBus -// service and gains ownership of a name. -// This test is to make sure that we capture the "NameAcquired" signal. -TEST(DBusMonitorTest, ReceivedNameAcquiredSignal) { - DBusSigFilterTest filter; - rtc::scoped_ptr monitor; - monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM)); - if (monitor) { - EXPECT_TRUE(monitor->AddFilter(&filter)); - - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs); - EXPECT_TRUE_WAIT(filter.MessageReceived(), kTimeoutMs); - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED); - } else { - LOG(LS_WARNING) << "DBus Monitor not started. Skipping test."; - } -} - -TEST(DBusMonitorTest, ConcurrentMonitors) { - DBusSigFilterTest filter1; - rtc::scoped_ptr monitor1; - monitor1.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM)); - if (monitor1) { - EXPECT_TRUE(monitor1->AddFilter(&filter1)); - DBusSigFilterTest filter2; - rtc::scoped_ptr monitor2; - monitor2.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM)); - EXPECT_TRUE(monitor2->AddFilter(&filter2)); - - EXPECT_TRUE(monitor1->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor1->GetStatus(), kTimeoutMs); - EXPECT_TRUE(monitor2->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor2->GetStatus(), kTimeoutMs); - - EXPECT_TRUE_WAIT(filter2.MessageReceived(), kTimeoutMs); - EXPECT_TRUE(monitor2->StopMonitoring()); - EXPECT_EQ(monitor2->GetStatus(), DBusMonitor::DMS_STOPPED); - - EXPECT_TRUE_WAIT(filter1.MessageReceived(), kTimeoutMs); - EXPECT_TRUE(monitor1->StopMonitoring()); - EXPECT_EQ(monitor1->GetStatus(), DBusMonitor::DMS_STOPPED); - } else { - LOG(LS_WARNING) << "DBus Monitor not started. Skipping test."; - } -} - -TEST(DBusMonitorTest, ConcurrentFilters) { - DBusSigFilterTest filter1; - DBusSigFilterTest filter2; - rtc::scoped_ptr monitor; - monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM)); - if (monitor) { - EXPECT_TRUE(monitor->AddFilter(&filter1)); - EXPECT_TRUE(monitor->AddFilter(&filter2)); - - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs); - - EXPECT_TRUE_WAIT(filter1.MessageReceived(), kTimeoutMs); - EXPECT_TRUE_WAIT(filter2.MessageReceived(), kTimeoutMs); - - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED); - } else { - LOG(LS_WARNING) << "DBus Monitor not started. Skipping test."; - } -} - -TEST(DBusMonitorTest, NoAddFilterIfRunning) { - DBusSigFilterTest filter1; - DBusSigFilterTest filter2; - rtc::scoped_ptr monitor; - monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM)); - if (monitor) { - EXPECT_TRUE(monitor->AddFilter(&filter1)); - - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs); - EXPECT_FALSE(monitor->AddFilter(&filter2)); - - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED); - } else { - LOG(LS_WARNING) << "DBus Monitor not started. Skipping test."; - } -} - -TEST(DBusMonitorTest, AddFilterAfterStop) { - DBusSigFilterTest filter1; - DBusSigFilterTest filter2; - rtc::scoped_ptr monitor; - monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM)); - if (monitor) { - EXPECT_TRUE(monitor->AddFilter(&filter1)); - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs); - EXPECT_TRUE_WAIT(filter1.MessageReceived(), kTimeoutMs); - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED); - - EXPECT_TRUE(monitor->AddFilter(&filter2)); - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs); - EXPECT_TRUE_WAIT(filter1.MessageReceived(), kTimeoutMs); - EXPECT_TRUE_WAIT(filter2.MessageReceived(), kTimeoutMs); - EXPECT_TRUE(monitor->StopMonitoring()); - EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED); - } else { - LOG(LS_WARNING) << "DBus Monitor not started. Skipping test."; - } -} - -TEST(DBusMonitorTest, StopRightAfterStart) { - DBusSigFilterTest filter; - rtc::scoped_ptr monitor; - monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM)); - if (monitor) { - EXPECT_TRUE(monitor->AddFilter(&filter)); - - EXPECT_TRUE(monitor->StartMonitoring()); - EXPECT_TRUE(monitor->StopMonitoring()); - - // Stop the monitoring thread right after it had been started. - // If the monitoring thread got a chance to receive a DBus signal, it would - // post a message to the main thread and signal the main thread wakeup. - // This message will be cleaned out automatically when the filter get - // destructed. Here we also consume the wakeup signal (if there is one) so - // that the testing (main) thread is reset to a clean state. - rtc::Thread::Current()->ProcessMessages(1); - } else { - LOG(LS_WARNING) << "DBus Monitor not started."; - } -} - -TEST(DBusSigFilter, BuildFilterString) { - EXPECT_EQ(DBusSigFilter::BuildFilterString("", "", ""), - (DBUS_TYPE "='" DBUS_SIGNAL "'")); - EXPECT_EQ(DBusSigFilter::BuildFilterString("p", "", ""), - (DBUS_TYPE "='" DBUS_SIGNAL "'," DBUS_PATH "='p'")); - EXPECT_EQ(DBusSigFilter::BuildFilterString("p","i", ""), - (DBUS_TYPE "='" DBUS_SIGNAL "'," DBUS_PATH "='p'," - DBUS_INTERFACE "='i'")); - EXPECT_EQ(DBusSigFilter::BuildFilterString("p","i","m"), - (DBUS_TYPE "='" DBUS_SIGNAL "'," DBUS_PATH "='p'," - DBUS_INTERFACE "='i'," DBUS_MEMBER "='m'")); -} - -} // namespace rtc - -#endif // HAVE_DBUS_GLIB diff --git a/media/webrtc/trunk/webrtc/base/libdbusglibsymboltable.cc b/media/webrtc/trunk/webrtc/base/libdbusglibsymboltable.cc deleted file mode 100644 index ad51064bc5..0000000000 --- a/media/webrtc/trunk/webrtc/base/libdbusglibsymboltable.cc +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifdef HAVE_DBUS_GLIB - -#include "webrtc/base/libdbusglibsymboltable.h" - -namespace rtc { - -#define LATE_BINDING_SYMBOL_TABLE_CLASS_NAME LIBDBUS_GLIB_CLASS_NAME -#define LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST LIBDBUS_GLIB_SYMBOLS_LIST -#define LATE_BINDING_SYMBOL_TABLE_DLL_NAME "libdbus-glib-1.so.2" -#include "webrtc/base/latebindingsymboltable.cc.def" - -} // namespace rtc - -#endif // HAVE_DBUS_GLIB diff --git a/media/webrtc/trunk/webrtc/base/libdbusglibsymboltable.h b/media/webrtc/trunk/webrtc/base/libdbusglibsymboltable.h deleted file mode 100644 index b87b4c1744..0000000000 --- a/media/webrtc/trunk/webrtc/base/libdbusglibsymboltable.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_LIBDBUSGLIBSYMBOLTABLE_H_ -#define WEBRTC_BASE_LIBDBUSGLIBSYMBOLTABLE_H_ - -#ifdef HAVE_DBUS_GLIB - -#include -#include - -#include "webrtc/base/latebindingsymboltable.h" - -namespace rtc { - -#define LIBDBUS_GLIB_CLASS_NAME LibDBusGlibSymbolTable -// The libdbus-glib symbols we need, as an X-Macro list. -// This list must contain precisely every libdbus-glib function that is used in -// dbus.cc. -#define LIBDBUS_GLIB_SYMBOLS_LIST \ - X(dbus_bus_add_match) \ - X(dbus_connection_add_filter) \ - X(dbus_connection_close) \ - X(dbus_connection_remove_filter) \ - X(dbus_connection_set_exit_on_disconnect) \ - X(dbus_g_bus_get) \ - X(dbus_g_bus_get_private) \ - X(dbus_g_connection_get_connection) \ - X(dbus_g_connection_unref) \ - X(dbus_g_thread_init) \ - X(dbus_message_get_interface) \ - X(dbus_message_get_member) \ - X(dbus_message_get_path) \ - X(dbus_message_get_type) \ - X(dbus_message_iter_get_arg_type) \ - X(dbus_message_iter_get_basic) \ - X(dbus_message_iter_init) \ - X(dbus_message_ref) \ - X(dbus_message_unref) - -#define LATE_BINDING_SYMBOL_TABLE_CLASS_NAME LIBDBUS_GLIB_CLASS_NAME -#define LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST LIBDBUS_GLIB_SYMBOLS_LIST -#include "webrtc/base/latebindingsymboltable.h.def" - -} // namespace rtc - -#endif // HAVE_DBUS_GLIB - -#endif // WEBRTC_BASE_LIBDBUSGLIBSYMBOLTABLE_H_ diff --git a/media/webrtc/trunk/webrtc/build/common.gypi b/media/webrtc/trunk/webrtc/build/common.gypi index 5793a10e0d..93612f902e 100644 --- a/media/webrtc/trunk/webrtc/build/common.gypi +++ b/media/webrtc/trunk/webrtc/build/common.gypi @@ -108,9 +108,6 @@ 'build_protobuf%': 1, 'build_ssl%': 1, - # Disable by default - 'have_dbus_glib%': 0, - # Make it possible to provide custom locations for some libraries. 'libvpx_dir%': '<(DEPTH)/third_party/libvpx_new', 'libyuv_dir%': '<(DEPTH)/third_party/libyuv', @@ -237,14 +234,6 @@ 'WEBRTC_MOZILLA_BUILD', ], }], - ['have_dbus_glib==1', { - 'defines': [ - 'HAVE_DBUS_GLIB', - ], - 'cflags': [ - '= $DBUS_VERSION) - PKG_CHECK_MODULES(MOZ_DBUS_GLIB, dbus-glib-1 >= $DBUS_VERSION) AC_DEFINE(MOZ_ENABLE_DBUS) fi fi diff --git a/security/nss/gtests/mozpkix_gtest/pkixnames_tests.cpp b/security/nss/gtests/mozpkix_gtest/pkixnames_tests.cpp index e90c63b6b4..4ca4a90e08 100644 --- a/security/nss/gtests/mozpkix_gtest/pkixnames_tests.cpp +++ b/security/nss/gtests/mozpkix_gtest/pkixnames_tests.cpp @@ -2082,6 +2082,45 @@ static const NameConstraintParams NAME_CONSTRAINT_PARAMS[] = Result::ERROR_BAD_DER, Result::ERROR_BAD_DER }, + // Wildcard SANs have subtle outcomes. + { ByteString(), DNSName("*.example.com"), + GeneralSubtree(DNSName(".example.com")), + Success, + Result::ERROR_CERT_NOT_IN_NAME_SPACE + }, + { ByteString(), DNSName("*.example.com"), + GeneralSubtree(DNSName("example.com")), + Success, + Result::ERROR_CERT_NOT_IN_NAME_SPACE + }, + // A certificate with a wildcard SAN entry like `*.example.com` can't be + // issued by a CA with a DNSName name constraint entry like `foo.example.com` + // in either the permitted or excluded subtrees. If in the permitted subtree, + // the certificate would be valid for `bar.example.com`, which would violate + // the constraint. If in the excluded subtree, the certificate would be valid + // for `foo.example.com`, which would violate the constraint. + { ByteString(), DNSName("*.example.com"), + GeneralSubtree(DNSName("foo.example.com")), + Result::ERROR_CERT_NOT_IN_NAME_SPACE, + Result::ERROR_CERT_NOT_IN_NAME_SPACE + }, + { ByteString(), DNSName("*.foo.example.com"), + GeneralSubtree(DNSName("example.com")), + Success, + Result::ERROR_CERT_NOT_IN_NAME_SPACE + }, + { ByteString(), DNSName("*.example.com"), + GeneralSubtree(DNSName("foo.example.org")), + Result::ERROR_CERT_NOT_IN_NAME_SPACE, + Success + }, + // `*invalid.example.com` is an invalid presented DNSID. + { ByteString(), DNSName("*invalid.example.com"), + GeneralSubtree(DNSName("invalid.example.com")), + Result::ERROR_BAD_DER, + Result::ERROR_BAD_DER + }, + ///////////////////////////////////////////////////////////////////////////// // Basic IP Address constraints (non-CN-ID) diff --git a/security/nss/lib/mozpkix/lib/pkixnames.cpp b/security/nss/lib/mozpkix/lib/pkixnames.cpp index 2956000636..70faf199ae 100644 --- a/security/nss/lib/mozpkix/lib/pkixnames.cpp +++ b/security/nss/lib/mozpkix/lib/pkixnames.cpp @@ -7,6 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Copyright 2014 Mozilla Contributors + * Copyright 2026 Moonchild Productions * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -170,6 +171,12 @@ enum class IDRole NameConstraint = 2, }; +enum class NameConstraintsSubtrees : uint8_t +{ + permittedSubtrees = der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 0, + excludedSubtrees = der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 1 +}; + enum class AllowWildcards { No = 0, Yes = 1 }; // DNSName constraints implicitly allow subdomain matching when there is no @@ -182,16 +189,22 @@ enum class AllowDotlessSubdomainMatches { No = 0, Yes = 1 }; bool IsValidDNSID(Input hostname, IDRole idRole, AllowWildcards allowWildcards); +// `subtreesType` is relevant only when `referenceDNSIDRole` is +// `IDRole::NameConstraint`. Result MatchPresentedDNSIDWithReferenceDNSID( Input presentedDNSID, AllowWildcards allowWildcards, AllowDotlessSubdomainMatches allowDotlessSubdomainMatches, IDRole referenceDNSIDRole, + /*optional*/ const NameConstraintsSubtrees* subtreesType, Input referenceDNSID, /*out*/ bool& matches); +// `subtreesType` is relevant only when `referenceDNSIDRole` is +// `IDRole::NameConstraint`. Result MatchPresentedRFC822NameWithReferenceRFC822Name( Input presentedRFC822Name, IDRole referenceRFC822NameRole, + /*optional*/ const NameConstraintsSubtrees* subtreesType, Input referenceRFC822Name, /*out*/ bool& matches); } // namespace @@ -210,7 +223,7 @@ MatchPresentedDNSIDWithReferenceDNSID(Input presentedDNSID, return MatchPresentedDNSIDWithReferenceDNSID( presentedDNSID, AllowWildcards::Yes, AllowDotlessSubdomainMatches::Yes, IDRole::ReferenceID, - referenceDNSID, matches); + nullptr, referenceDNSID, matches); } // Verify that the given end-entity cert, which is assumed to have been already @@ -694,7 +707,7 @@ MatchPresentedIDWithReferenceID(GeneralNameType presentedIDType, rv = MatchPresentedDNSIDWithReferenceDNSID( presentedID, AllowWildcards::Yes, AllowDotlessSubdomainMatches::Yes, IDRole::ReferenceID, - referenceID, foundMatch); + nullptr, referenceID, foundMatch); break; case GeneralNameType::iPAddress: @@ -704,7 +717,7 @@ MatchPresentedIDWithReferenceID(GeneralNameType presentedIDType, case GeneralNameType::rfc822Name: rv = MatchPresentedRFC822NameWithReferenceRFC822Name( - presentedID, IDRole::ReferenceID, referenceID, foundMatch); + presentedID, IDRole::ReferenceID, nullptr, referenceID, foundMatch); break; case GeneralNameType::directoryName: @@ -730,12 +743,6 @@ MatchPresentedIDWithReferenceID(GeneralNameType presentedIDType, return Success; } -enum class NameConstraintsSubtrees : uint8_t -{ - permittedSubtrees = der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 0, - excludedSubtrees = der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 1 -}; - Result CheckPresentedIDConformsToNameConstraintsSubtrees( GeneralNameType presentedIDType, Input presentedID, @@ -849,7 +856,7 @@ CheckPresentedIDConformsToNameConstraintsSubtrees( rv = MatchPresentedDNSIDWithReferenceDNSID( presentedID, AllowWildcards::Yes, AllowDotlessSubdomainMatches::Yes, IDRole::NameConstraint, - base, matches); + &subtreesType, base, matches); if (rv != Success) { return rv; } @@ -874,7 +881,7 @@ CheckPresentedIDConformsToNameConstraintsSubtrees( case GeneralNameType::rfc822Name: rv = MatchPresentedRFC822NameWithReferenceRFC822Name( - presentedID, IDRole::NameConstraint, base, matches); + presentedID, IDRole::NameConstraint, &subtreesType, base, matches); if (rv != Success) { return rv; } @@ -1057,6 +1064,7 @@ MatchPresentedDNSIDWithReferenceDNSID( AllowWildcards allowWildcards, AllowDotlessSubdomainMatches allowDotlessSubdomainMatches, IDRole referenceDNSIDRole, + /*optional*/ const NameConstraintsSubtrees* subtreesType, Input referenceDNSID, /*out*/ bool& matches) { @@ -1147,18 +1155,28 @@ MatchPresentedDNSIDWithReferenceDNSID( return NotReached("Skipping '*' failed", Result::FATAL_ERROR_LIBRARY_FAILURE); } - do { - // This will happen if reference is a single, relative label - if (reference.AtEnd()) { - matches = false; - return Success; - } - uint8_t referenceByte; - if (reference.Read(referenceByte) != Success) { - return NotReached("invalid reference ID", - Result::FATAL_ERROR_INVALID_ARGS); - } - } while (!reference.Peek('.')); + // For the permittedSubtrees of a name constraint, wildcard presented + // DNSIDs of the form `*.example.com` only match if the name constraint is + // of the form `.example.com` or `example.com`. To put it another way, a + // permittedSubtrees of `foo.example.com` does not match a wildcard + // presented DNSID of `*.example.com`, because in that case, the + // certificate could be valid for `bar.example.com`, which does not match + // the name constraint. + if (referenceDNSIDRole != IDRole::NameConstraint || + (subtreesType && *subtreesType != NameConstraintsSubtrees::permittedSubtrees)) { + do { + // This will happen if reference is a single, relative label + if (reference.AtEnd()) { + matches = false; + return Success; + } + uint8_t referenceByte; + if (reference.Read(referenceByte) != Success) { + return NotReached("invalid reference ID", + Result::FATAL_ERROR_INVALID_ARGS); + } + } while (!reference.Peek('.')); + } } for (;;) { @@ -1515,9 +1533,12 @@ IsValidRFC822Name(Input input) } } +// `subtreesType` is relevant only when `referenceRFC822NameRole` is +// `IDRole::NameConstraint`. Result MatchPresentedRFC822NameWithReferenceRFC822Name(Input presentedRFC822Name, IDRole referenceRFC822NameRole, + /*optional*/ const NameConstraintsSubtrees* subtreesType, Input referenceRFC822Name, /*out*/ bool& matches) { @@ -1562,6 +1583,7 @@ MatchPresentedRFC822NameWithReferenceRFC822Name(Input presentedRFC822Name, return MatchPresentedDNSIDWithReferenceDNSID( presentedDNSID, AllowWildcards::No, AllowDotlessSubdomainMatches::No, IDRole::NameConstraint, + subtreesType, referenceRFC822Name, matches); } } diff --git a/testing/docker/base-test/Dockerfile b/testing/docker/base-test/Dockerfile index dd0bf77feb..32471e350a 100644 --- a/testing/docker/base-test/Dockerfile +++ b/testing/docker/base-test/Dockerfile @@ -44,7 +44,6 @@ RUN apt-get update && apt-get install -y --force-yes \ libcanberra-pulse \ libcurl4-openssl-dev \ libdbus-1-dev \ - libdbus-glib-1-dev \ libdrm-intel1:i386 \ libdrm-nouveau1a:i386 \ libdrm-radeon1:i386 \ diff --git a/testing/docker/centos6-build/system-setup.sh b/testing/docker/centos6-build/system-setup.sh index ddb529eed7..458db2b7dd 100644 --- a/testing/docker/centos6-build/system-setup.sh +++ b/testing/docker/centos6-build/system-setup.sh @@ -50,10 +50,6 @@ install check-devel.i686 install check-devel.x86_64 install check.i686 install check.x86_64 -install dbus-glib-devel.i686 -install dbus-glib-devel.x86_64 -install dbus-glib.i686 -install dbus-glib.x86_64 install fontconfig-devel.i686 install fontconfig-devel.x86_64 install fontconfig.i686 diff --git a/testing/docker/firefox-snap/snapcraft.yaml.in b/testing/docker/firefox-snap/snapcraft.yaml.in index 9448c104db..0c1d67cd41 100644 --- a/testing/docker/firefox-snap/snapcraft.yaml.in +++ b/testing/docker/firefox-snap/snapcraft.yaml.in @@ -29,7 +29,6 @@ parts: source: source stage-packages: - libxt6 - - libdbus-glib-1-2 - libasound2 - libpulse0 - libgl1-mesa-dri diff --git a/testing/docker/recipes/ubuntu1204-test-system-setup.sh b/testing/docker/recipes/ubuntu1204-test-system-setup.sh index 4edcf00a12..1a7efce475 100644 --- a/testing/docker/recipes/ubuntu1204-test-system-setup.sh +++ b/testing/docker/recipes/ubuntu1204-test-system-setup.sh @@ -44,7 +44,6 @@ apt_packages+=('libasound2-plugins:i386') apt_packages+=('libcanberra-pulse') apt_packages+=('libcurl4-openssl-dev') apt_packages+=('libdbus-1-dev') -apt_packages+=('libdbus-glib-1-dev') apt_packages+=('libdrm-intel1:i386') apt_packages+=('libdrm-nouveau1a:i386') apt_packages+=('libdrm-radeon1:i386') diff --git a/testing/docker/recipes/ubuntu1604-test-system-setup.sh b/testing/docker/recipes/ubuntu1604-test-system-setup.sh index b58ee7cb18..0a00cf47ec 100644 --- a/testing/docker/recipes/ubuntu1604-test-system-setup.sh +++ b/testing/docker/recipes/ubuntu1604-test-system-setup.sh @@ -37,7 +37,6 @@ apt_packages+=('libasound2-dev') apt_packages+=('libcanberra-pulse') apt_packages+=('libcurl4-openssl-dev') apt_packages+=('libdbus-1-dev') -apt_packages+=('libdbus-glib-1-dev') apt_packages+=('libgconf2-dev') apt_packages+=('libgstreamer-plugins-base0.10-dev') apt_packages+=('libgstreamer0.10-dev') diff --git a/testing/mozharness/configs/builds/releng_base_linux_32_builds.py b/testing/mozharness/configs/builds/releng_base_linux_32_builds.py index 393cf8983e..e7d6b2fe5d 100644 --- a/testing/mozharness/configs/builds/releng_base_linux_32_builds.py +++ b/testing/mozharness/configs/builds/releng_base_linux_32_builds.py @@ -134,7 +134,7 @@ config = { # -devel packages dependencies. So manually install the dependencies # of the above packages. 'ORBit2-devel.i686', 'atk-devel.i686', 'cairo-devel.i686', - 'check-devel.i686', 'dbus-devel.i686', 'dbus-glib-devel.i686', + 'check-devel.i686', 'dbus-devel.i686', 'fontconfig-devel.i686', 'glib2-devel.i686', 'hal-devel.i686', 'libICE-devel.i686', 'libIDL-devel.i686', 'libSM-devel.i686', 'libXau-devel.i686', 'libXcomposite-devel.i686', diff --git a/testing/mozharness/configs/builds/releng_sub_linux_configs/32_artifact.py b/testing/mozharness/configs/builds/releng_sub_linux_configs/32_artifact.py index f016d56069..7d36640842 100644 --- a/testing/mozharness/configs/builds/releng_sub_linux_configs/32_artifact.py +++ b/testing/mozharness/configs/builds/releng_sub_linux_configs/32_artifact.py @@ -90,7 +90,7 @@ config = { # -devel packages dependencies. So manually install the dependencies # of the above packages. 'ORBit2-devel.i686', 'atk-devel.i686', 'cairo-devel.i686', - 'check-devel.i686', 'dbus-devel.i686', 'dbus-glib-devel.i686', + 'check-devel.i686', 'dbus-devel.i686', 'fontconfig-devel.i686', 'glib2-devel.i686', 'hal-devel.i686', 'libICE-devel.i686', 'libIDL-devel.i686', 'libSM-devel.i686', 'libXau-devel.i686', 'libXcomposite-devel.i686', diff --git a/testing/mozharness/configs/builds/releng_sub_linux_configs/32_debug_artifact.py b/testing/mozharness/configs/builds/releng_sub_linux_configs/32_debug_artifact.py index 88ff8450a3..ae4de07176 100644 --- a/testing/mozharness/configs/builds/releng_sub_linux_configs/32_debug_artifact.py +++ b/testing/mozharness/configs/builds/releng_sub_linux_configs/32_debug_artifact.py @@ -96,7 +96,7 @@ config = { # -devel packages dependencies. So manually install the dependencies # of the above packages. 'ORBit2-devel.i686', 'atk-devel.i686', 'cairo-devel.i686', - 'check-devel.i686', 'dbus-devel.i686', 'dbus-glib-devel.i686', + 'check-devel.i686', 'dbus-devel.i686', 'fontconfig-devel.i686', 'glib2-devel.i686', 'hal-devel.i686', 'libICE-devel.i686', 'libIDL-devel.i686', 'libSM-devel.i686', 'libXau-devel.i686', 'libXcomposite-devel.i686', diff --git a/testing/mozharness/configs/hazards/common.py b/testing/mozharness/configs/hazards/common.py index f8d751044e..bfe4a36449 100644 --- a/testing/mozharness/configs/hazards/common.py +++ b/testing/mozharness/configs/hazards/common.py @@ -58,7 +58,7 @@ config = { "gmp-devel", "nspr", "nspr-devel", # For building the browser - "dbus-devel", "dbus-glib-devel", "hal-devel", + "dbus-devel", "hal-devel", "libICE-devel", "libIDL-devel", # For mach resource-usage diff --git a/testing/mozharness/configs/single_locale/linux.py b/testing/mozharness/configs/single_locale/linux.py index 3aa2c03494..a32a52d077 100644 --- a/testing/mozharness/configs/single_locale/linux.py +++ b/testing/mozharness/configs/single_locale/linux.py @@ -92,7 +92,7 @@ config = { # -devel packages dependencies. So manually install the dependencies # of the above packages. 'ORBit2-devel.i686', 'atk-devel.i686', 'cairo-devel.i686', - 'check-devel.i686', 'dbus-devel.i686', 'dbus-glib-devel.i686', + 'check-devel.i686', 'dbus-devel.i686', 'fontconfig-devel.i686', 'glib2-devel.i686', 'hal-devel.i686', 'libICE-devel.i686', 'libIDL-devel.i686', 'libSM-devel.i686', 'libXau-devel.i686', 'libXcomposite-devel.i686', diff --git a/toolkit/library/moz.build b/toolkit/library/moz.build index ff7ff5561e..664241bb28 100644 --- a/toolkit/library/moz.build +++ b/toolkit/library/moz.build @@ -218,7 +218,7 @@ if CONFIG['MOZ_SNDIO']: ] if CONFIG['MOZ_ENABLE_DBUS']: - OS_LIBS += CONFIG['MOZ_DBUS_GLIB_LIBS'] + OS_LIBS += CONFIG['MOZ_DBUS_LIBS'] if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']: if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk3': diff --git a/toolkit/xre/moz.build b/toolkit/xre/moz.build index 4072fe134f..216d866317 100644 --- a/toolkit/xre/moz.build +++ b/toolkit/xre/moz.build @@ -134,7 +134,6 @@ if CONFIG['MOZ_ENABLE_XREMOTE']: CXXFLAGS += CONFIG['TK_CFLAGS'] CXXFLAGS += CONFIG['MOZ_DBUS_CFLAGS'] -CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS'] if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']: CXXFLAGS += CONFIG['MOZ_PANGO_CFLAGS'] diff --git a/uriloader/exthandler/moz.build b/uriloader/exthandler/moz.build index 127e4da2bd..633c56e26d 100644 --- a/uriloader/exthandler/moz.build +++ b/uriloader/exthandler/moz.build @@ -122,4 +122,3 @@ if CONFIG['MOZ_ENABLE_DBUS']: if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3'): CXXFLAGS += CONFIG['TK_CFLAGS'] - CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS'] diff --git a/xpcom/io/nsLocalFileWin.cpp b/xpcom/io/nsLocalFileWin.cpp index 0aa430d9dd..1d5e3da020 100644 --- a/xpcom/io/nsLocalFileWin.cpp +++ b/xpcom/io/nsLocalFileWin.cpp @@ -3020,6 +3020,7 @@ nsLocalFile::IsExecutable(bool* aResult) "air", // Adobe AIR installer "app", // executable application "application", // from bug 348763 + "appref-ms", // ClickOnce link "appx", "appxbundle", "asp", @@ -3080,6 +3081,7 @@ nsLocalFile::IsExecutable(bool* aResult) "scf", // Windows explorer command "scr", "sct", + "search-ms", // Windows Saved Search "settingcontent-ms", "shb", "shs",