Compare commits

...
62 Commits
Author SHA1 Message Date
Moonchild ce68156cf4 Revert "[widget] Linux GTK3: Detach accessible from moz_container before it's deleted"
This reverts commit 465a18f342.
Resolves #2168
2023-03-18 19:57:56 +01:00
Moonchild 5032ad9593 Issue #2117 - Follow-up: Run precomplete cmd during package staging
We rely on this for all OSes except Mac where precomplete should not
be in the root (it uses Mozilla's fallback packaging that places it in
$RESPATH)
2023-03-17 22:11:30 +01:00
Moonchild b55f765f2e Issue #1911 - Follow-up: Filter out illegal file extensions also.
We already did this for file names, just not extensions.
2023-03-17 12:02:55 +01:00
Moonchild 856078d435 [widget] Linux GTK3: Detach accessible from moz_container before it's deleted 2023-03-17 12:02:46 +01:00
Moonchild c74c262d2f [GFX] Add some sanity checks and clamps to SurfaceData calculations. 2023-03-17 12:02:38 +01:00
Moonchild 787e29e374 No Issue - Ensure more OsiSpace
ensureOsiSpace(); was very much under-used. This adds more instances
where it makes sense to ensure Osi space before placing masm calls.
2023-03-17 12:02:31 +01:00
FranklinDM e439896c9b Issue #2148 - Shrink Vector from (usually) four pointers in size to three
when no inline storage is used.

See Bug 1338374
2023-03-17 12:02:20 +01:00
FranklinDM 15b508f1fb Issue #2148 - Make Vector not use AlignedStorage for its inline element storage
See Bug 1338374 1/2
2023-03-17 12:02:12 +01:00
Job Bautista 5651ebfc76 Issue #2148 - Discard RegExpShared data tables when discarding regexp JIT code.
Based on Mozilla bug 1378736's part 2.
Should fix the double-free.
Follow-up for #2083
2023-03-17 12:02:04 +01:00
Job Bautista 593bfc1ce8 Issue #2148 - Don't null out RegExpObject -> RegExpShared pointer on GC.
Follow-up for issue #2083.
Taken from Mozilla bug 1378736.
2023-03-17 12:01:50 +01:00
Brian Smith 28953cda7a Issue #2160 - Initial support for notarizing during DMG package.
Added --with-macbundle-idenity configure option to set a codesign identity.
If no identity is set or cross-compiling from Linux no codesigning will be
done. Currently doing a full deep bundle v2 sign, instead of limited v1.
2023-03-15 15:10:52 +01:00
Moonchild 516f3f545d Merge branch 'master' into release
# Conflicts:
#	CLOBBER
#	js/src/vm/RegExpObject.cpp
#	security/nss/lib/nss/nss.h
#	security/nss/lib/pkcs12/p12d.c
#	security/nss/lib/softoken/softkver.h
#	security/nss/lib/util/nssutil.h
2023-03-13 13:11:20 +01:00
Moonchild 83aff65a42 Force clobber 2023-02-19 17:53:31 +01:00
Moonchild 5bd97df957 [NSS] Update NSS to 3.52.9 to pick up fixes. 2023-02-19 17:51:26 +01:00
Moonchild 8772711181 [DOM] Check whether module load request was already cancelled when a load fails 2023-02-19 17:51:18 +01:00
Moonchild dc9526f4c6 [widget] Properly test for and handle errors in target-surface creation
and mapping.
2023-02-19 17:51:10 +01:00
Moonchild 9ab36e7ae0 Issue #2103 - Fix typo in RegExp Parser
This corrects the typo where the left-hand character would determine if
the right-hand character would be added or not.

Resolves #2103
2023-02-02 10:50:47 +01:00
Job Bautista e8d30841e7 Issue #2091 - Parse \p{Extended_Pictographic} too.
This is essentially a follow up to Issue #1286. We already have
 UCHAR_EXTENDED_PICTOGRAPHIC in our in-tree ICU, so there's no reason to comment
 this case out.
2023-01-27 05:01:53 +01:00
Martok 9faf29374e Issue #2093 - Trace HeapPtr<RegExpShared::groupsTemplate_> for GC move/compact events, regression from #2072 2023-01-26 20:11:28 +01:00
Moonchild 75e4818d36 Merge branch 'master' into release 2023-01-19 00:42:00 +01:00
Moonchild a65144e9e0 Fix merge conflicts. 2023-01-13 12:55:52 +01:00
Moonchild 4f29548526 Merge branch 'master' into release
# Conflicts:
#	image/decoders/nsJXLDecoder.cpp
#	js/src/irregexp/NativeRegExpMacroAssembler.cpp
#	js/src/irregexp/RegExpAST.h
#	js/src/irregexp/RegExpEngine.cpp
#	js/src/irregexp/RegExpParser.cpp
#	js/src/irregexp/RegExpParser.h
#	xpcom/io/nsLocalFileUnix.cpp
2023-01-13 12:11:56 +01:00
Moonchild 528db2cbd8 Issue #1818 - Remove obsolete path hack in widget code. 2022-12-16 09:13:48 +00:00
Moonchild 84e6bcc1e6 [network] Align cookie checks with RFC 6265 (bis) 2022-12-16 09:13:38 +00:00
Moonchild 0dc9ff518d [libjar] Add some extra sanity checks to our Zip reader. 2022-12-16 09:13:25 +00:00
Moonchild a2e3bd44aa [network] move some generic websocket code to the baseclass 2022-12-16 09:13:09 +00:00
Moonchild 163a0e7caf Revert "Issue #1279 - Implement regular expressions lookbehind (v2)"
This reverts commit d10e8a5b06.
2022-12-15 09:11:02 +00:00
Moonchild 49a86db5f3 Issue #2040 - Pre-multiply the alpha values in our JXL decode buffer. (uplift)
Using selective calculation (only if not opaque) and fast integer
math here should optimize well in compilers.
2022-12-15 09:09:19 +00:00
Moonchild 2640953d8b Issue #2019 - Follow-up: Make nsPluginInstanceOwner also listen to keypress events in the system event group.
nsPluginInstanceOwner only listens to keypress events in the default event group.
However, in our changed operating mode, keypress events are not fired in the
default event group if the key does not result in something printable.
This means that nsPluginInstanceOwner should also listen to keypress events
in the system event group and should handle each keypress that way, but
only once. I.e., if a printable keypress event is received in the system event
group, it should be ignored, since it would've already been handled in the
default event group in that case.
2022-11-26 18:18:09 +00:00
Moonchild 7eb7d67f7a Issue #2033 - Temporary fix of R<->B channel swap.
We have a BGR/RGB channel ordering mismatch here. to at least
provide proper display, a quick&dirty byte swap on the output
buffer will fix this for now, but we should look into seeing where
the surface mismatch is caused.
std::swap() should optimize pretty well in any of the used
compilers, but if necessary, a full buffer ASM routine can be
slotted in (although on current hardware I doubt this will be
even noticeable as it is)
2022-11-26 02:43:18 +00:00
Moonchild e28860ba7f Revert "[XPCOM] Deal with lstat potentially lying in nsLocalFileUnix."
This reverts commit c127f58ef3.
2022-11-20 14:14:48 +00:00
Moonchild 49a96b1d91 Merge branch 'master' into release 2022-11-19 20:15:23 +00:00
Moonchild 3130812693 Merge branch 'master' into release 2022-11-12 18:34:07 +00:00
Moonchild 71ae69aea8 [WebGL] Implement webgl.max-size-per-texture-mib 2022-10-26 14:50:05 +00:00
Moonchild 9e34d697c7 [XPCOM] Fix Base64 off-by-one issue and safeguard against this mistake in the future. 2022-10-26 14:49:55 +00:00
Moonchild 8fa9125d02 [No issue] Hold some strong references on nsRefreshDriver 2022-10-26 14:49:46 +00:00
Brian Smith 4b4488c3e4 Issue #2022 - Part 2 - Add Ventura version detection.
Also add Monterey and Ventura to the graphics driver blocklist.
2022-10-26 14:49:33 +00:00
Brian Smith 248db7d301 Issue #2022 - Part 1 - Fix transparent windows on MacOS 13 Ventura.
During the BaseWindow creation contenView is nil on Ventura...
So create a NSView with the requested dimensions and set is as the contenView.
2022-10-26 14:49:23 +00:00
Moonchild e199f2949b [No issue] Ensure LockImpl::Try() returns the correct bool value. 2022-10-26 14:45:39 +00:00
Moonchild 456b5450a4 Issue #2010 - Ensure raw tagnames are safe exiting internalEntityParser
This resolves #2010
2022-09-28 13:50:10 +00:00
Moonchild d8e629c4a3 Merge branch 'master' into release 2022-09-27 20:12:40 +00:00
Moonchild 4898c4f297 Merge branch 'master' into release 2022-09-24 12:16:59 +00:00
Moonchild 7cd578bbc6 Merge branch 'master' into release 2022-09-22 13:16:48 +00:00
Moonchild 1e91df628a Merge branch 'master' into release 2022-09-22 11:52:16 +00:00
Moonchild b110549cbd Merge branch 'master' into release 2022-07-27 06:07:45 +00:00
Moonchild 971047835a Merge branch 'master' into release
# Conflicts:
#	config/milestone.txt
#	toolkit/mozapps/extensions/internal/XPIProvider.jsm
2022-07-25 20:47:06 +00:00
Moonchild dd4d9eb032 [XPCOM] Crash safely when TArray replacements are OOB.
In the unlikely event of TArray element replacement calls are OOB, crash safely
with a debug breakpoint instead of corrupting memory.
2022-07-03 15:49:44 +00:00
Moonchild 8b94f1e480 [DOM] use the sanitizer to restrict href in svg:use to fragment-only URLs 2022-07-03 15:49:34 +00:00
Moonchild c89610a5c7 [network] Clear PAC loader when the load failed 2022-07-03 15:49:23 +00:00
Moonchild 217963cbed Update NSS to 3.52.7 2022-07-03 15:49:14 +00:00
Moonchild c4f4e18340 [DOM media] Remove potentially unsafe type accesses when debug logging 2022-07-03 15:49:04 +00:00
Moonchild 8a7c0e7345 [network] Clean up and update the list of external protocol handlers. 2022-07-03 15:48:54 +00:00
Moonchild 52e304d450 Issue #1053 - Follow-up: Correct conditional define on POSIX systems. (uplift)
This conditional was incorrectly changed when removing Android support.
This potentially causes issues on Linux systems by not using pthreads correctly,
which may lead to high idle CPU usage.
2022-06-28 13:28:20 +00:00
Moonchild cfc0eeca53 Revert "Issue #1909 - Guard against empty update manifest URL"
This reverts commit d7fadcdef9.
2022-06-07 11:59:07 +00:00
Moonchild ebd3dd9228 Merge branch 'master' into release 2022-06-03 21:50:44 +00:00
Moonchild cb40e4e7ef Merge branch 'master' into release 2022-06-01 13:54:11 +00:00
Moonchild 662dba55fd Merge branch 'master' into release 2022-05-29 11:13:44 +00:00
Moonchild 8760ce023c Issue #1895 - Implement queueMicroTask(callback()) (uplift) 2022-05-07 14:40:14 +00:00
Moonchild b86e148bb7 Roll back milestone version to release. 2022-05-06 12:43:43 +00:00
Moonchild 9e83721e5e Merge branch 'master' into release 2022-05-06 12:43:00 +00:00
Moonchild dc2d6c2e60 Revert "No Issue - Make content-type on JAR channels behave the same as HTTP channels."
This reverts commit 425677ada7.
2022-05-03 17:38:19 +00:00
Moonchild 4ada6f6762 Update 7zSD for v31 2022-05-03 17:38:12 +00:00
23 changed files with 381 additions and 185 deletions

No files matched your search

+1
View File
@@ -274,6 +274,7 @@ def old_configure_options(*options):
'--with-ios-sdk',
'--with-jitreport-granularity',
'--with-macbundlename-prefix',
'--with-macbundle-identity',
'--with-macos-private-frameworks',
'--with-macos-sdk',
'--with-nspr-cflags',
+19 -11
View File
@@ -84,8 +84,9 @@ DataAtOffset(DataSourceSurface* aSurface,
MOZ_ASSERT(Factory::CheckSurfaceSize(aSurface->GetSize()),
"surface size overflows - this should have been prevented when the surface was created");
uint8_t* data = aMap->mData + aPoint.y * aMap->mStride +
aPoint.x * BytesPerPixel(aSurface->GetFormat());
uint8_t* data = aMap->mData +
size_t(aPoint.y) * size_t(aMap->mStride) +
size_t(aPoint.x) * size_t(BytesPerPixel(aSurface->GetFormat()));
if (data < aMap->mData) {
MOZ_CRASH("GFX: out-of-range data access");
@@ -124,22 +125,29 @@ void
CopySurfaceDataToPackedArray(uint8_t* aSrc, uint8_t* aDst, IntSize aSrcSize,
int32_t aSrcStride, int32_t aBytesPerPixel)
{
MOZ_ASSERT(aBytesPerPixel > 0,
"Negative stride for aDst not currently supported");
MOZ_ASSERT(BufferSizeFromStrideAndHeight(aSrcStride, aSrcSize.height) > 0,
"How did we end up with a surface with such a big buffer?");
CheckedInt<size_t> packedStride(aBytesPerPixel);
packedStride *= aSrcSize.width;
if (!packedStride.isValid()) {
MOZ_ASSERT(false, "Invalid stride");
return;
}
int packedStride = aSrcSize.width * aBytesPerPixel;
CheckedInt<size_t> totalSize(aSrcStride);
totalSize *= aSrcSize.height;
if (!totalSize.isValid()) {
MOZ_ASSERT(false, "Invalid surface size");
return;
}
if (aSrcStride == packedStride) {
if (size_t(aSrcStride) == packedStride.value()) {
// aSrc is already packed, so we can copy with a single memcpy.
memcpy(aDst, aSrc, packedStride * aSrcSize.height);
memcpy(aDst, aSrc, totalSize.value());
} else {
// memcpy one row at a time.
for (int row = 0; row < aSrcSize.height; ++row) {
memcpy(aDst, aSrc, packedStride);
memcpy(aDst, aSrc, packedStride.value());
aSrc += aSrcStride;
aDst += packedStride;
aDst += packedStride.value();
}
}
}
+14 -6
View File
@@ -63,10 +63,11 @@ using namespace js::jit;
* The tempN registers are free to use for computations.
*/
NativeRegExpMacroAssembler::NativeRegExpMacroAssembler(JSContext* cx, LifoAlloc* alloc, RegExpShared* shared,
JSRuntime* rt, Mode mode, int registers_to_save)
: RegExpMacroAssembler(cx, *alloc, shared, registers_to_save),
cx(cx), runtime(rt), mode_(mode)
NativeRegExpMacroAssembler::NativeRegExpMacroAssembler(LifoAlloc* alloc, JSRuntime* rt,
Mode mode, int registers_to_save,
RegExpShared::JitCodeTables& tables)
: RegExpMacroAssembler(*alloc, registers_to_save),
tables(tables), runtime(rt), mode_(mode)
{
// Find physical registers for each compiler register.
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
@@ -886,11 +887,11 @@ NativeRegExpMacroAssembler::CheckCharacterNotInRange(char16_t from, char16_t to,
}
void
NativeRegExpMacroAssembler::CheckBitInTable(uint8_t* table, Label* on_bit_set)
NativeRegExpMacroAssembler::CheckBitInTable(RegExpShared::JitCodeTable table, Label* on_bit_set)
{
JitSpew(SPEW_PREFIX "CheckBitInTable");
masm.movePtr(ImmPtr(table), temp0);
masm.movePtr(ImmPtr(table.get()), temp0);
// kTableMask is currently 127, so we need to mask even if the input is
// Latin1. V8 has the same issue.
@@ -901,6 +902,13 @@ NativeRegExpMacroAssembler::CheckBitInTable(uint8_t* table, Label* on_bit_set)
masm.load8ZeroExtend(BaseIndex(temp0, temp1, TimesOne), temp0);
masm.branchTest32(Assembler::NonZero, temp0, temp0, BranchOrBacktrack(on_bit_set));
// Transfer ownership of |table| to the |tables| Vector.
{
AutoEnterOOMUnsafeRegion oomUnsafe;
if (!tables.append(Move(table)))
oomUnsafe.crash("RegExp table append");
}
}
void
+4 -4
View File
@@ -87,8 +87,8 @@ class MOZ_STACK_CLASS NativeRegExpMacroAssembler final : public RegExpMacroAssem
// Type of input string to generate code for.
enum Mode { ASCII = 1, CHAR16 = 2 };
NativeRegExpMacroAssembler(JSContext* cx, LifoAlloc* alloc, RegExpShared* shared,
JSRuntime* rt, Mode mode, int registers_to_save);
NativeRegExpMacroAssembler(LifoAlloc* alloc, JSRuntime* rt, Mode mode, int registers_to_save,
RegExpShared::JitCodeTables& tables);
// Inherited virtual methods.
RegExpCode GenerateCode(JSContext* cx, bool match_only);
@@ -116,7 +116,7 @@ class MOZ_STACK_CLASS NativeRegExpMacroAssembler final : public RegExpMacroAssem
jit::Label* on_in_range);
void CheckCharacterNotInRange(char16_t from, char16_t to,
jit::Label* on_not_in_range);
void CheckBitInTable(uint8_t* table, jit::Label* on_bit_set);
void CheckBitInTable(RegExpShared::JitCodeTable table, jit::Label* on_bit_set);
void CheckPosition(int cp_offset, jit::Label* on_outside_input);
void JumpOrBacktrack(jit::Label* to);
bool CheckSpecialCharacterClass(char16_t type, jit::Label* on_no_match);
@@ -173,8 +173,8 @@ class MOZ_STACK_CLASS NativeRegExpMacroAssembler final : public RegExpMacroAssem
private:
jit::MacroAssembler masm;
RegExpShared::JitCodeTables& tables;
JSContext* cx;
JSRuntime* runtime;
Mode mode_;
jit::Label entry_label_;
+12 -12
View File
@@ -1262,7 +1262,7 @@ RegExpCode
irregexp::CompilePattern(JSContext* cx, HandleRegExpShared shared, RegExpCompileData* data,
HandleLinearString sample, bool is_global, bool ignore_case,
bool is_ascii, bool match_only, bool force_bytecode, bool sticky,
bool unicode)
bool unicode, RegExpShared::JitCodeTables& tables)
{
if ((data->capture_count + 1) * 2 - 1 > RegExpMacroAssembler::kMaxRegister) {
JS_ReportErrorASCII(cx, "regexp too big");
@@ -1350,10 +1350,10 @@ irregexp::CompilePattern(JSContext* cx, HandleRegExpShared shared, RegExpCompile
: NativeRegExpMacroAssembler::CHAR16;
ctx.emplace(cx, (jit::TempAllocator*) nullptr);
native_assembler.emplace(cx, &alloc, shared, cx->runtime(), mode, (data->capture_count + 1) * 2);
native_assembler.emplace(&alloc, cx->runtime(), mode, (data->capture_count + 1) * 2, tables);
assembler = native_assembler.ptr();
} else {
interpreted_assembler.emplace(cx, &alloc, shared, (data->capture_count + 1) * 2);
interpreted_assembler.emplace(&alloc, (data->capture_count + 1) * 2);
assembler = interpreted_assembler.ptr();
}
@@ -2040,21 +2040,21 @@ BoyerMooreLookahead::EmitSkipInstructions(RegExpMacroAssembler* masm)
return true;
}
uint8_t* boolean_skip_table;
RegExpShared::JitCodeTable boolean_skip_table;
{
AutoEnterOOMUnsafeRegion oomUnsafe;
boolean_skip_table = static_cast<uint8_t*>(js_malloc(kSize));
if (!boolean_skip_table || !masm->shared->addTable(boolean_skip_table))
boolean_skip_table.reset(static_cast<uint8_t*>(js_malloc(kSize)));
if (!boolean_skip_table)
oomUnsafe.crash("Table malloc");
}
int skip_distance = GetSkipTable(min_lookahead, max_lookahead, boolean_skip_table);
int skip_distance = GetSkipTable(min_lookahead, max_lookahead, boolean_skip_table.get());
MOZ_ASSERT(skip_distance != 0);
jit::Label cont, again;
masm->Bind(&again);
masm->LoadCurrentCharacter(max_lookahead, &cont, true);
masm->CheckBitInTable(boolean_skip_table, &cont);
masm->CheckBitInTable(Move(boolean_skip_table), &cont);
masm->AdvanceCurrentPosition(skip_distance);
masm->JumpOrBacktrack(&again);
masm->Bind(&cont);
@@ -2832,18 +2832,18 @@ EmitUseLookupTable(RegExpMacroAssembler* masm,
}
// TODO(erikcorry): Cache these.
uint8_t* ba;
RegExpShared::JitCodeTable ba;
{
AutoEnterOOMUnsafeRegion oomUnsafe;
ba = static_cast<uint8_t*>(js_malloc(kSize));
if (!ba || !masm->shared->addTable(ba))
ba.reset(static_cast<uint8_t*>(js_malloc(kSize)));
if (!ba)
oomUnsafe.crash("Table malloc");
}
for (int i = 0; i < kSize; i++)
ba[i] = templ[i];
masm->CheckBitInTable(ba, on_bit_set);
masm->CheckBitInTable(Move(ba), on_bit_set);
if (on_bit_clear != fall_through)
masm->JumpOrBacktrack(on_bit_clear);
}
+1 -1
View File
@@ -106,7 +106,7 @@ RegExpCode
CompilePattern(JSContext* cx, HandleRegExpShared shared, RegExpCompileData* data,
HandleLinearString sample, bool is_global, bool ignore_case,
bool is_ascii, bool match_only, bool force_bytecode, bool sticky,
bool unicode);
bool unicode, RegExpShared::JitCodeTables& tables);
// Note: this may return RegExpRunStatus_Error if an interrupt was requested
// while the code was executing.
+4 -4
View File
@@ -96,10 +96,9 @@ irregexp::CaseInsensitiveCompareUCStrings(const char16_t* substring1,
const char16_t* substring2,
size_t byteLength);
InterpretedRegExpMacroAssembler::InterpretedRegExpMacroAssembler(JSContext* cx, LifoAlloc* alloc,
RegExpShared* shared,
InterpretedRegExpMacroAssembler::InterpretedRegExpMacroAssembler(LifoAlloc* alloc,
size_t numSavedRegisters)
: RegExpMacroAssembler(cx, *alloc, shared, numSavedRegisters),
: RegExpMacroAssembler(*alloc, numSavedRegisters),
pc_(0),
advance_current_start_(0),
advance_current_offset_(0),
@@ -317,7 +316,8 @@ InterpretedRegExpMacroAssembler::CheckCharacterNotInRange(char16_t from, char16_
}
void
InterpretedRegExpMacroAssembler::CheckBitInTable(uint8_t* table, jit::Label* on_bit_set)
InterpretedRegExpMacroAssembler::CheckBitInTable(RegExpShared::JitCodeTable table,
jit::Label* on_bit_set)
{
static const int kBitsPerByte = 8;
+5 -11
View File
@@ -40,14 +40,12 @@ namespace irregexp {
class MOZ_STACK_CLASS RegExpMacroAssembler
{
public:
RegExpMacroAssembler(JSContext* cx, LifoAlloc& alloc, RegExpShared* shared,
size_t numSavedRegisters)
RegExpMacroAssembler(LifoAlloc& alloc, size_t numSavedRegisters)
: slow_safe_compiler_(false),
global_mode_(NOT_GLOBAL),
alloc_(alloc),
num_registers_(numSavedRegisters),
num_saved_registers_(numSavedRegisters),
shared(cx, shared)
num_saved_registers_(numSavedRegisters)
{}
enum StackCheckFlag {
@@ -137,7 +135,7 @@ class MOZ_STACK_CLASS RegExpMacroAssembler
// The current character (modulus the kTableSize) is looked up in the byte
// array, and if the found byte is non-zero, we jump to the on_bit_set label.
virtual void CheckBitInTable(uint8_t* table, jit::Label* on_bit_set) = 0;
virtual void CheckBitInTable(RegExpShared::JitCodeTable table, jit::Label* on_bit_set) = 0;
// Checks whether the given offset from the current position is before
// the end of the string. May overwrite the current character.
@@ -213,9 +211,6 @@ class MOZ_STACK_CLASS RegExpMacroAssembler
if (num_registers_ <= reg)
num_registers_ = reg + 1;
}
public:
RootedRegExpShared shared;
};
template <typename CharT>
@@ -230,8 +225,7 @@ CaseInsensitiveCompareUCStrings(const CharT* substring1, const CharT* substring2
class MOZ_STACK_CLASS InterpretedRegExpMacroAssembler final : public RegExpMacroAssembler
{
public:
InterpretedRegExpMacroAssembler(JSContext* cx, LifoAlloc* alloc, RegExpShared* shared,
size_t numSavedRegisters);
InterpretedRegExpMacroAssembler(LifoAlloc* alloc, size_t numSavedRegisters);
~InterpretedRegExpMacroAssembler();
// Inherited virtual methods.
@@ -258,7 +252,7 @@ class MOZ_STACK_CLASS InterpretedRegExpMacroAssembler final : public RegExpMacro
jit::Label* on_in_range);
void CheckCharacterNotInRange(char16_t from, char16_t to,
jit::Label* on_not_in_range);
void CheckBitInTable(uint8_t* table, jit::Label* on_bit_set);
void CheckBitInTable(RegExpShared::JitCodeTable table, jit::Label* on_bit_set);
void JumpOrBacktrack(jit::Label* to);
void Fail();
void IfRegisterGE(int reg, int comparand, jit::Label* if_ge);
+6
View File
@@ -3757,6 +3757,7 @@ CodeGenerator::visitCallNative(LCallNative* call)
if (jitInfo && jitInfo->type() == JSJitInfo::IgnoresReturnValueNative)
native = jitInfo->ignoresReturnValueMethod;
}
ensureOsiSpace();
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, native));
emitTracelogStopEvent(TraceLogger_Call);
@@ -3881,6 +3882,7 @@ CodeGenerator::visitCallDOMNative(LCallDOMNative* call)
masm.passABIArg(argObj);
masm.passABIArg(argPrivate);
masm.passABIArg(argArgs);
ensureOsiSpace();
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, target->jitInfo()->method));
if (target->jitInfo()->isInfallible) {
@@ -4006,6 +4008,7 @@ CodeGenerator::visitCallGeneric(LCallGeneric* call)
// Finally call the function in objreg.
masm.bind(&makeCall);
ensureOsiSpace();
uint32_t callOffset = masm.callJit(objreg);
markSafepointAt(callOffset, call);
@@ -4104,6 +4107,7 @@ CodeGenerator::visitCallKnown(LCallKnown* call)
masm.Push(Imm32(descriptor));
// Finally call the function in objreg.
ensureOsiSpace();
uint32_t callOffset = masm.callJit(objreg);
markSafepointAt(callOffset, call);
@@ -4436,6 +4440,7 @@ CodeGenerator::emitApplyGeneric(T* apply)
masm.bind(&rejoin);
// Finally call the function in objreg, as assigned by one of the paths above.
ensureOsiSpace();
uint32_t callOffset = masm.callJit(objreg);
markSafepointAt(callOffset, apply);
@@ -11244,6 +11249,7 @@ CodeGenerator::visitGetDOMProperty(LGetDOMProperty* ins)
masm.passABIArg(ObjectReg);
masm.passABIArg(PrivateReg);
masm.passABIArg(ValueReg);
ensureOsiSpace();
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, ins->mir()->fun()));
if (ins->mir()->isInfallible()) {
+5 -3
View File
@@ -46,7 +46,8 @@ struct LoopIterationBound : public TempObject
// of the loop header. This will use loop invariant terms and header phis.
LinearSum currentSum;
LoopIterationBound(MBasicBlock* header, MTest* test, LinearSum boundSum, LinearSum currentSum)
LoopIterationBound(MBasicBlock* header, MTest* test,
const LinearSum& boundSum, const LinearSum& currentSum)
: header(header), test(test),
boundSum(boundSum), currentSum(currentSum)
{
@@ -59,7 +60,7 @@ typedef Vector<LoopIterationBound*, 0, SystemAllocPolicy> LoopIterationBoundVect
struct SymbolicBound : public TempObject
{
private:
SymbolicBound(LoopIterationBound* loop, LinearSum sum)
SymbolicBound(LoopIterationBound* loop, const LinearSum& sum)
: loop(loop), sum(sum)
{
}
@@ -73,7 +74,8 @@ struct SymbolicBound : public TempObject
// If nullptr, then 'sum' is always valid.
LoopIterationBound* loop;
static SymbolicBound* New(TempAllocator& alloc, LoopIterationBound* loop, LinearSum sum) {
static SymbolicBound*
New(TempAllocator& alloc, LoopIterationBound* loop, const LinearSum& sum) {
return new(alloc) SymbolicBound(loop, sum);
}
+1 -1
View File
@@ -1112,7 +1112,6 @@ CodeGeneratorShared::ensureOsiSpace()
}
MOZ_ASSERT_IF(!masm.oom(),
masm.currentOffset() - lastOsiPointOffset_ >= Assembler::PatchWrite_NearCallSize());
lastOsiPointOffset_ = masm.currentOffset();
}
uint32_t
@@ -1124,6 +1123,7 @@ CodeGeneratorShared::markOsiPoint(LOsiPoint* ins)
uint32_t offset = masm.currentOffset();
SnapshotOffset so = ins->snapshot()->snapshotOffset();
masm.propagateOOM(osiIndices_.append(OsiIndex(offset, so)));
lastOsiPointOffset_ = offset;
return offset;
}
+27 -8
View File
@@ -23,6 +23,7 @@
/* Note: Aborts on OOM. */
class JSAPITestString {
js::Vector<char, 0, js::SystemAllocPolicy> chars;
public:
JSAPITestString() {}
explicit JSAPITestString(const char* s) { *this += s; }
@@ -32,21 +33,34 @@ class JSAPITestString {
const char* end() const { return chars.end(); }
size_t length() const { return chars.length(); }
JSAPITestString & operator +=(const char* s) {
JSAPITestString& operator +=(const char* s) {
if (!chars.append(s, strlen(s)))
abort();
return *this;
}
JSAPITestString & operator +=(const JSAPITestString& s) {
JSAPITestString& operator +=(const JSAPITestString& s) {
if (!chars.append(s.begin(), s.length()))
abort();
return *this;
}
};
inline JSAPITestString operator+(JSAPITestString a, const char* b) { return a += b; }
inline JSAPITestString operator+(JSAPITestString a, const JSAPITestString& b) { return a += b; }
inline JSAPITestString
operator+(const JSAPITestString& a, const char* b)
{
JSAPITestString result = a;
result += b;
return result;
}
inline JSAPITestString
operator+(const JSAPITestString& a, const JSAPITestString& b)
{
JSAPITestString result = a;
result += b;
return result;
}
class JSAPITest
{
@@ -205,7 +219,11 @@ class JSAPITest
return fail(JSAPITestString("CHECK failed: " #expr), __FILE__, __LINE__); \
} while (false)
bool fail(JSAPITestString msg = JSAPITestString(), const char* filename = "-", int lineno = 0) {
bool fail(const JSAPITestString& msg = JSAPITestString(),
const char* filename = "-",
int lineno = 0)
{
JSAPITestString message = msg;
if (JS_IsExceptionPending(cx)) {
js::gc::AutoSuppressGC gcoff(cx);
JS::RootedValue v(cx);
@@ -215,11 +233,12 @@ class JSAPITest
if (s) {
JSAutoByteString bytes(cx, s);
if (!!bytes)
msg += bytes.ptr();
message += bytes.ptr();
}
}
fprintf(stderr, "%s:%d:%.*s\n", filename, lineno, (int) msg.length(), msg.begin());
msgs += msg;
fprintf(stderr, "%s:%d:%.*s\n",
filename, lineno, int(message.length()), message.begin());
msgs += message;
return false;
}
+19 -11
View File
@@ -187,11 +187,6 @@ IsMarkingTrace(JSTracer* trc)
void
RegExpObject::trace(JSTracer* trc)
{
// When marking the object normally we have the option of unlinking the
// object from its RegExpShared so that the RegExpShared may be collected.
if (IsMarkingTrace(trc) && !zone()->isPreservingCode())
sharedRef() = nullptr;
TraceNullableEdge(trc, &sharedRef(), "RegExpObject shared");
}
@@ -970,6 +965,9 @@ RegExpShared::discardJitCode()
{
for (auto& comp : compilationArray)
comp.jitCode = nullptr;
// We can also purge the tables used by JIT code.
tables.clearAndFree();
}
void
@@ -977,8 +975,6 @@ RegExpShared::finalize(FreeOp* fop)
{
for (auto& comp : compilationArray)
js_free(comp.byteCode);
for (size_t i = 0; i < tables.length(); i++)
js_free(tables[i]);
tables.~JitCodeTables();
}
@@ -1075,6 +1071,7 @@ RegExpShared::compile(JSContext* cx, MutableHandleRegExpShared re, HandleAtom pa
}
}
JitCodeTables tables;
irregexp::RegExpCode code = irregexp::CompilePattern(cx, re, &data, input,
false /* global() */,
re->ignoreCase(),
@@ -1082,7 +1079,8 @@ RegExpShared::compile(JSContext* cx, MutableHandleRegExpShared re, HandleAtom pa
mode == MatchOnly,
force == ForceByteCode,
re->sticky(),
re->unicode());
re->unicode(),
tables);
if (code.empty())
return false;
@@ -1090,10 +1088,20 @@ RegExpShared::compile(JSContext* cx, MutableHandleRegExpShared re, HandleAtom pa
MOZ_ASSERT_IF(force == ForceByteCode, code.byteCode);
RegExpCompilation& compilation = re->compilation(mode, input->hasLatin1Chars());
if (code.jitCode)
if (code.jitCode) {
// First copy the tables. GC can purge the tables if the RegExpShared
// has no JIT code, so it's important to do this right before setting
// compilation.jitCode (to ensure no purging happens between adding the
// tables and setting the JIT code).
for (size_t i = 0; i < tables.length(); i++) {
if (!re->addTable(Move(tables[i])))
return false;
}
compilation.jitCode = code.jitCode;
else if (code.byteCode)
} else if (code.byteCode) {
MOZ_ASSERT(tables.empty(), "RegExpInterpreter does not use data tables");
compilation.byteCode = code.byteCode;
}
return true;
}
@@ -1249,7 +1257,7 @@ RegExpShared::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
n += tables.sizeOfExcludingThis(mallocSizeOf);
for (size_t i = 0; i < tables.length(); i++)
n += mallocSizeOf(tables[i]);
n += mallocSizeOf(tables[i].get());
return n;
}
+8 -6
View File
@@ -109,6 +109,9 @@ class RegExpShared : public gc::TenuredCell
ForceByteCode
};
using JitCodeTable = UniquePtr<uint8_t[], JS::FreePolicy>;
using JitCodeTables = Vector<JitCodeTable, 0, SystemAllocPolicy>;
private:
friend class RegExpCompartment;
friend class RegExpStatics;
@@ -148,7 +151,6 @@ class RegExpShared : public gc::TenuredCell
}
// Tables referenced by JIT code.
using JitCodeTables = Vector<uint8_t*, 0, SystemAllocPolicy>;
JitCodeTables tables;
/* Internal functions. */
@@ -181,8 +183,8 @@ class RegExpShared : public gc::TenuredCell
MatchPairs* matches, size_t* endIndex);
// Register a table with this RegExpShared, and take ownership.
bool addTable(uint8_t* table) {
return tables.append(table);
bool addTable(JitCodeTable table) {
return tables.append(Move(table));
}
/* Accessors */
@@ -464,7 +466,7 @@ class RegExpObject : public NativeObject
void setShared(RegExpShared& shared) {
MOZ_ASSERT(!hasShared());
sharedRef() = &shared;
sharedRef().init(&shared);
}
static void trace(JSTracer* trc, JSObject* obj);
@@ -490,9 +492,9 @@ class RegExpObject : public NativeObject
static MOZ_MUST_USE bool createShared(JSContext* cx, Handle<RegExpObject*> regexp,
MutableHandleRegExpShared shared);
ReadBarriered<RegExpShared*>& sharedRef() {
PreBarriered<RegExpShared*>& sharedRef() {
auto& ref = NativeObject::privateRef(PRIVATE_SLOT);
return reinterpret_cast<ReadBarriered<RegExpShared*>&>(ref);
return reinterpret_cast<PreBarriered<RegExpShared*>&>(ref);
}
/* Call setShared in preference to setPrivate. */
+175 -103
View File
@@ -146,7 +146,7 @@ struct VectorImpl
aV.free_(aV.mBegin);
aV.mBegin = newbuf;
/* aV.mLength is unchanged. */
aV.mCapacity = aNewCap;
aV.mTail.mCapacity = aNewCap;
return true;
}
};
@@ -225,28 +225,30 @@ struct VectorImpl<T, N, AP, true>
{
MOZ_ASSERT(!aV.usingInlineStorage());
MOZ_ASSERT(!CapacityHasExcessSpace<T>(aNewCap));
T* newbuf = aV.template pod_realloc<T>(aV.mBegin, aV.mCapacity, aNewCap);
T* newbuf =
aV.template pod_realloc<T>(aV.mBegin, aV.mTail.mCapacity, aNewCap);
if (MOZ_UNLIKELY(!newbuf)) {
return false;
}
aV.mBegin = newbuf;
/* aV.mLength is unchanged. */
aV.mCapacity = aNewCap;
aV.mTail.mCapacity = aNewCap;
return true;
}
static inline void
podResizeToFit(Vector<T, N, AP>& aV)
{
if (aV.usingInlineStorage() || aV.mLength == aV.mCapacity) {
if (aV.usingInlineStorage() || aV.mLength == aV.mTail.mCapacity) {
return;
}
T* newbuf = aV.template pod_realloc<T>(aV.mBegin, aV.mCapacity, aV.mLength);
T* newbuf =
aV.template pod_realloc<T>(aV.mBegin, aV.mTail.mCapacity, aV.mLength);
if (MOZ_UNLIKELY(!newbuf)) {
return;
}
aV.mBegin = newbuf;
aV.mCapacity = aV.mLength;
aV.mTail.mCapacity = aV.mLength;
}
};
@@ -277,7 +279,7 @@ struct VectorTesting;
template<typename T,
size_t MinInlineCapacity = 0,
class AllocPolicy = MallocAllocPolicy>
class Vector final : private AllocPolicy
class MOZ_NON_PARAM Vector final : private AllocPolicy
{
/* utilities */
@@ -293,36 +295,39 @@ class Vector final : private AllocPolicy
/* magic constants */
static const int kMaxInlineBytes = 1024;
/* compute constants */
/*
* Consider element size to be 1 for buffer sizing if there are 0 inline
* elements. This allows us to compile when the definition of the element
* type is not visible here.
/**
* The maximum space allocated for inline element storage.
*
* Explicit specialization is only allowed at namespace scope, so in order
* to keep everything here, we use a dummy template parameter with partial
* specialization.
* We reduce space by what the AllocPolicy base class and prior Vector member
* fields likely consume to attempt to play well with binary size classes.
*/
template<int M, int Dummy>
struct ElemSize
{
static const size_t value = sizeof(T);
};
template<int Dummy>
struct ElemSize<0, Dummy>
{
static const size_t value = 1;
static constexpr size_t kMaxInlineBytes =
1024 -
(sizeof(AllocPolicy) + sizeof(T*) + sizeof(size_t) + sizeof(size_t));
/**
* The number of T elements of inline capacity built into this Vector. This
* is usually |MinInlineCapacity|, but it may be less (or zero!) for large T.
*
* We use a partially-specialized template (not explicit specialization, which
* is only allowed at namespace scope) to compute this value. The benefit is
* that |sizeof(T)| need not be computed, and |T| doesn't have to be fully
* defined at the time |Vector<T>| appears, if no inline storage is requested.
*/
template <size_t MinimumInlineCapacity, size_t Dummy>
struct ComputeCapacity {
static constexpr size_t value =
tl::Min<MinimumInlineCapacity, kMaxInlineBytes / sizeof(T)>::value;
};
static const size_t kInlineCapacity =
tl::Min<MinInlineCapacity, kMaxInlineBytes / ElemSize<MinInlineCapacity, 0>::value>::value;
template <size_t Dummy>
struct ComputeCapacity<0, Dummy> {
static constexpr size_t value = 0;
};
/* Calculate inline buffer size; avoid 0-sized array. */
static const size_t kInlineBytes =
tl::Max<1, kInlineCapacity * ElemSize<MinInlineCapacity, 0>::value>::value;
/** The actual inline capacity in number of elements T. This may be zero! */
static constexpr size_t kInlineCapacity =
ComputeCapacity<MinInlineCapacity, 0>::value;
/* member data */
@@ -338,16 +343,84 @@ class Vector final : private AllocPolicy
/* Number of elements in the vector. */
size_t mLength;
/* Max number of elements storable in the vector without resizing. */
size_t mCapacity;
/*
* Memory used to store capacity, reserved element count (debug builds only),
* and inline storage. The simple "answer" is:
*
* size_t mCapacity;
* #ifdef DEBUG
* size_t mReserved;
* #endif
* alignas(T) unsigned char mBytes[kInlineCapacity * sizeof(T)];
*
* but there are complications. First, C++ forbids zero-sized arrays that
* might result. Second, we don't want zero capacity to affect Vector's size
* (even empty classes take up a byte, unless they're base classes).
*
* Yet again, we eliminate the zero-sized array using partial specialization.
* And we eliminate potential size hit by putting capacity/reserved in one
* struct, then putting the array (if any) in a derived struct. If no array
* is needed, the derived struct won't consume extra space.
*/
struct CapacityAndReserved
{
explicit CapacityAndReserved(size_t aCapacity, size_t aReserved)
: mCapacity(aCapacity)
#ifdef DEBUG
, mReserved(aReserved)
#endif
{}
CapacityAndReserved() = default;
/* Max number of elements storable in the vector without resizing. */
size_t mCapacity;
#ifdef DEBUG
/* Max elements of reserved or used space in this vector. */
size_t mReserved;
/* Max elements of reserved or used space in this vector. */
size_t mReserved;
#endif
};
/* Memory used for inline storage. */
AlignedStorage<kInlineBytes> mStorage;
// Silence warnings about this struct possibly being padded dued to the
// alignas() in it -- there's nothing we can do to avoid it.
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4324)
#endif // _MSC_VER
template<size_t Capacity, size_t Dummy>
struct CRAndStorage : CapacityAndReserved
{
explicit CRAndStorage(size_t aCapacity, size_t aReserved)
: CapacityAndReserved(aCapacity, aReserved)
{}
CRAndStorage() = default;
alignas(T) unsigned char mBytes[Capacity * sizeof(T)];
// GCC fails due to -Werror=strict-aliasing if |mBytes| is directly cast to
// T*. Indirecting through this function addresses the problem.
void* data() { return mBytes; }
T* storage() { return static_cast<T*>(data()); }
};
template<size_t Dummy>
struct CRAndStorage<0, Dummy> : CapacityAndReserved
{
explicit CRAndStorage(size_t aCapacity, size_t aReserved)
: CapacityAndReserved(aCapacity, aReserved)
{}
CRAndStorage() = default;
T* storage() { return nullptr; }
};
CRAndStorage<kInlineCapacity, 0> mTail;
#ifdef _MSC_VER
# pragma warning(pop)
#endif // _MSC_VER
#ifdef DEBUG
friend class ReentrancyGuard;
@@ -363,7 +436,7 @@ class Vector final : private AllocPolicy
T* inlineStorage()
{
return static_cast<T*>(mStorage.addr());
return mTail.storage();
}
T* beginNoCheck() const
@@ -391,9 +464,9 @@ class Vector final : private AllocPolicy
*/
size_t reserved() const
{
MOZ_ASSERT(mLength <= mReserved);
MOZ_ASSERT(mReserved <= mCapacity);
return mReserved;
MOZ_ASSERT(mLength <= mTail.mReserved);
MOZ_ASSERT(mTail.mReserved <= mTail.mCapacity);
return mTail.mReserved;
}
#endif
@@ -426,7 +499,7 @@ public:
bool empty() const { return mLength == 0; }
size_t capacity() const { return mCapacity; }
size_t capacity() const { return mTail.mCapacity; }
T* begin()
{
@@ -753,10 +826,10 @@ private:
/* This does the re-entrancy check plus several other sanity checks. */
#define MOZ_REENTRANCY_GUARD_ET_AL \
ReentrancyGuard g(*this); \
MOZ_ASSERT_IF(usingInlineStorage(), mCapacity == kInlineCapacity); \
MOZ_ASSERT(reserved() <= mCapacity); \
MOZ_ASSERT_IF(usingInlineStorage(), mTail.mCapacity == kInlineCapacity); \
MOZ_ASSERT(reserved() <= mTail.mCapacity); \
MOZ_ASSERT(mLength <= reserved()); \
MOZ_ASSERT(mLength <= mCapacity)
MOZ_ASSERT(mLength <= mTail.mCapacity)
/* Vector Implementation */
@@ -765,13 +838,12 @@ MOZ_ALWAYS_INLINE
Vector<T, N, AP>::Vector(AP aAP)
: AP(aAP)
, mLength(0)
, mCapacity(kInlineCapacity)
, mTail(kInlineCapacity, 0)
#ifdef DEBUG
, mReserved(0)
, mEntered(false)
#endif
{
mBegin = static_cast<T*>(mStorage.addr());
mBegin = inlineStorage();
}
/* Move constructor. */
@@ -784,14 +856,14 @@ Vector<T, N, AllocPolicy>::Vector(Vector&& aRhs)
#endif
{
mLength = aRhs.mLength;
mCapacity = aRhs.mCapacity;
mTail.mCapacity = aRhs.mTail.mCapacity;
#ifdef DEBUG
mReserved = aRhs.mReserved;
mTail.mReserved = aRhs.mTail.mReserved;
#endif
if (aRhs.usingInlineStorage()) {
/* We can't move the buffer over in this case, so copy elements. */
mBegin = static_cast<T*>(mStorage.addr());
mBegin = inlineStorage();
Impl::moveConstruct(mBegin, aRhs.beginNoCheck(), aRhs.endNoCheck());
/*
* Leave aRhs's mLength, mBegin, mCapacity, and mReserved as they are.
@@ -803,11 +875,11 @@ Vector<T, N, AllocPolicy>::Vector(Vector&& aRhs)
* in-line storage.
*/
mBegin = aRhs.mBegin;
aRhs.mBegin = static_cast<T*>(aRhs.mStorage.addr());
aRhs.mCapacity = kInlineCapacity;
aRhs.mBegin = aRhs.inlineStorage();
aRhs.mTail.mCapacity = kInlineCapacity;
aRhs.mLength = 0;
#ifdef DEBUG
aRhs.mReserved = 0;
aRhs.mTail.mReserved = 0;
#endif
}
}
@@ -871,7 +943,7 @@ Vector<T, N, AP>::convertToHeapStorage(size_t aNewCap)
/* Switch in heap buffer. */
mBegin = newBuf;
/* mLength is unchanged. */
mCapacity = aNewCap;
mTail.mCapacity = aNewCap;
return true;
}
@@ -879,7 +951,7 @@ template<typename T, size_t N, class AP>
MOZ_NEVER_INLINE bool
Vector<T, N, AP>::growStorageBy(size_t aIncr)
{
MOZ_ASSERT(mLength + aIncr > mCapacity);
MOZ_ASSERT(mLength + aIncr > mTail.mCapacity);
/*
* When choosing a new capacity, its size should is as close to 2**N bytes
@@ -971,9 +1043,9 @@ Vector<T, N, AP>::initCapacity(size_t aRequest)
return false;
}
mBegin = newbuf;
mCapacity = aRequest;
mTail.mCapacity = aRequest;
#ifdef DEBUG
mReserved = aRequest;
mTail.mReserved = aRequest;
#endif
return true;
}
@@ -998,7 +1070,7 @@ Vector<T, N, AP>::maybeCheckSimulatedOOM(size_t aRequestedSize)
}
#ifdef DEBUG
if (aRequestedSize <= mReserved) {
if (aRequestedSize <= mTail.mReserved) {
return true;
}
#endif
@@ -1011,7 +1083,7 @@ inline bool
Vector<T, N, AP>::reserve(size_t aRequest)
{
MOZ_REENTRANCY_GUARD_ET_AL;
if (aRequest > mCapacity) {
if (aRequest > mTail.mCapacity) {
if (MOZ_UNLIKELY(!growStorageBy(aRequest - mLength))) {
return false;
}
@@ -1019,11 +1091,11 @@ Vector<T, N, AP>::reserve(size_t aRequest)
return false;
}
#ifdef DEBUG
if (aRequest > mReserved) {
mReserved = aRequest;
if (aRequest > mTail.mReserved) {
mTail.mReserved = aRequest;
}
MOZ_ASSERT(mLength <= mReserved);
MOZ_ASSERT(mReserved <= mCapacity);
MOZ_ASSERT(mLength <= mTail.mReserved);
MOZ_ASSERT(mTail.mReserved <= mTail.mCapacity);
#endif
return true;
}
@@ -1051,20 +1123,20 @@ MOZ_ALWAYS_INLINE bool
Vector<T, N, AP>::growBy(size_t aIncr)
{
MOZ_REENTRANCY_GUARD_ET_AL;
if (aIncr > mCapacity - mLength) {
if (aIncr > mTail.mCapacity - mLength) {
if (MOZ_UNLIKELY(!growStorageBy(aIncr))) {
return false;
}
} else if (!maybeCheckSimulatedOOM(mLength + aIncr)) {
return false;
}
MOZ_ASSERT(mLength + aIncr <= mCapacity);
MOZ_ASSERT(mLength + aIncr <= mTail.mCapacity);
T* newend = endNoCheck() + aIncr;
Impl::initialize(endNoCheck(), newend);
mLength += aIncr;
#ifdef DEBUG
if (mLength > mReserved) {
mReserved = mLength;
if (mLength > mTail.mReserved) {
mTail.mReserved = mLength;
}
#endif
return true;
@@ -1075,7 +1147,7 @@ MOZ_ALWAYS_INLINE bool
Vector<T, N, AP>::growByUninitialized(size_t aIncr)
{
MOZ_REENTRANCY_GUARD_ET_AL;
if (aIncr > mCapacity - mLength) {
if (aIncr > mTail.mCapacity - mLength) {
if (MOZ_UNLIKELY(!growStorageBy(aIncr))) {
return false;
}
@@ -1083,8 +1155,8 @@ Vector<T, N, AP>::growByUninitialized(size_t aIncr)
return false;
}
#ifdef DEBUG
if (mLength + aIncr > mReserved) {
mReserved = mLength + aIncr;
if (mLength + aIncr > mTail.mReserved) {
mTail.mReserved = mLength + aIncr;
}
#endif
infallibleGrowByUninitialized(aIncr);
@@ -1142,10 +1214,10 @@ Vector<T, N, AP>::clearAndFree()
return;
}
this->free_(beginNoCheck());
mBegin = static_cast<T*>(mStorage.addr());
mCapacity = kInlineCapacity;
mBegin = inlineStorage();
mTail.mCapacity = kInlineCapacity;
#ifdef DEBUG
mReserved = 0;
mTail.mReserved = 0;
#endif
}
@@ -1162,7 +1234,7 @@ template<typename T, size_t N, class AP>
inline bool
Vector<T, N, AP>::canAppendWithoutRealloc(size_t aNeeded) const
{
return mLength + aNeeded <= mCapacity;
return mLength + aNeeded <= mTail.mCapacity;
}
template<typename T, size_t N, class AP>
@@ -1178,8 +1250,8 @@ template<typename U>
MOZ_ALWAYS_INLINE void
Vector<T, N, AP>::internalAppend(U&& aU)
{
MOZ_ASSERT(mLength + 1 <= mReserved);
MOZ_ASSERT(mReserved <= mCapacity);
MOZ_ASSERT(mLength + 1 <= mTail.mReserved);
MOZ_ASSERT(mTail.mReserved <= mTail.mCapacity);
Impl::new_(endNoCheck(), Forward<U>(aU));
++mLength;
}
@@ -1189,7 +1261,7 @@ MOZ_ALWAYS_INLINE bool
Vector<T, N, AP>::appendN(const T& aT, size_t aNeeded)
{
MOZ_REENTRANCY_GUARD_ET_AL;
if (mLength + aNeeded > mCapacity) {
if (mLength + aNeeded > mTail.mCapacity) {
if (MOZ_UNLIKELY(!growStorageBy(aNeeded))) {
return false;
}
@@ -1197,8 +1269,8 @@ Vector<T, N, AP>::appendN(const T& aT, size_t aNeeded)
return false;
}
#ifdef DEBUG
if (mLength + aNeeded > mReserved) {
mReserved = mLength + aNeeded;
if (mLength + aNeeded > mTail.mReserved) {
mTail.mReserved = mLength + aNeeded;
}
#endif
internalAppendN(aT, aNeeded);
@@ -1209,8 +1281,8 @@ template<typename T, size_t N, class AP>
MOZ_ALWAYS_INLINE void
Vector<T, N, AP>::internalAppendN(const T& aT, size_t aNeeded)
{
MOZ_ASSERT(mLength + aNeeded <= mReserved);
MOZ_ASSERT(mReserved <= mCapacity);
MOZ_ASSERT(mLength + aNeeded <= mTail.mReserved);
MOZ_ASSERT(mTail.mReserved <= mTail.mCapacity);
Impl::copyConstructN(endNoCheck(), aNeeded, aT);
mLength += aNeeded;
}
@@ -1275,7 +1347,7 @@ Vector<T, N, AP>::append(const U* aInsBegin, const U* aInsEnd)
{
MOZ_REENTRANCY_GUARD_ET_AL;
size_t aNeeded = PointerRangeSize(aInsBegin, aInsEnd);
if (mLength + aNeeded > mCapacity) {
if (mLength + aNeeded > mTail.mCapacity) {
if (MOZ_UNLIKELY(!growStorageBy(aNeeded))) {
return false;
}
@@ -1283,8 +1355,8 @@ Vector<T, N, AP>::append(const U* aInsBegin, const U* aInsEnd)
return false;
}
#ifdef DEBUG
if (mLength + aNeeded > mReserved) {
mReserved = mLength + aNeeded;
if (mLength + aNeeded > mTail.mReserved) {
mTail.mReserved = mLength + aNeeded;
}
#endif
internalAppend(aInsBegin, aNeeded);
@@ -1296,8 +1368,8 @@ template<typename U>
MOZ_ALWAYS_INLINE void
Vector<T, N, AP>::internalAppend(const U* aInsBegin, size_t aInsLength)
{
MOZ_ASSERT(mLength + aInsLength <= mReserved);
MOZ_ASSERT(mReserved <= mCapacity);
MOZ_ASSERT(mLength + aInsLength <= mTail.mReserved);
MOZ_ASSERT(mTail.mReserved <= mTail.mCapacity);
Impl::copyConstruct(endNoCheck(), aInsBegin, aInsBegin + aInsLength);
mLength += aInsLength;
}
@@ -1308,7 +1380,7 @@ MOZ_ALWAYS_INLINE bool
Vector<T, N, AP>::append(U&& aU)
{
MOZ_REENTRANCY_GUARD_ET_AL;
if (mLength == mCapacity) {
if (mLength == mTail.mCapacity) {
if (MOZ_UNLIKELY(!growStorageBy(1))) {
return false;
}
@@ -1316,8 +1388,8 @@ Vector<T, N, AP>::append(U&& aU)
return false;
}
#ifdef DEBUG
if (mLength + 1 > mReserved) {
mReserved = mLength + 1;
if (mLength + 1 > mTail.mReserved) {
mTail.mReserved = mLength + 1;
}
#endif
internalAppend(Forward<U>(aU));
@@ -1370,11 +1442,11 @@ Vector<T, N, AP>::extractRawBuffer()
}
T* ret = mBegin;
mBegin = static_cast<T*>(mStorage.addr());
mBegin = inlineStorage();
mLength = 0;
mCapacity = kInlineCapacity;
mTail.mCapacity = kInlineCapacity;
#ifdef DEBUG
mReserved = 0;
mTail.mReserved = 0;
#endif
return ret;
}
@@ -1396,11 +1468,11 @@ Vector<T, N, AP>::extractOrCopyRawBuffer()
Impl::moveConstruct(copy, beginNoCheck(), endNoCheck());
Impl::destroy(beginNoCheck(), endNoCheck());
mBegin = static_cast<T*>(mStorage.addr());
mBegin = inlineStorage();
mLength = 0;
mCapacity = kInlineCapacity;
mTail.mCapacity = kInlineCapacity;
#ifdef DEBUG
mReserved = 0;
mTail.mReserved = 0;
#endif
return copy;
}
@@ -1424,19 +1496,19 @@ Vector<T, N, AP>::replaceRawBuffer(T* aP, size_t aLength)
* otherwise be acceptable. Maybe this behaviour should be
* specifiable with an argument to this function.
*/
mBegin = static_cast<T*>(mStorage.addr());
mBegin = inlineStorage();
mLength = aLength;
mCapacity = kInlineCapacity;
mTail.mCapacity = kInlineCapacity;
Impl::moveConstruct(mBegin, aP, aP + aLength);
Impl::destroy(aP, aP + aLength);
this->free_(aP);
} else {
mBegin = aP;
mLength = aLength;
mCapacity = aLength;
mTail.mCapacity = aLength;
}
#ifdef DEBUG
mReserved = aLength;
mTail.mReserved = aLength;
#endif
}
@@ -1475,9 +1547,9 @@ Vector<T, N, AP>::swap(Vector& aOther)
}
Swap(mLength, aOther.mLength);
Swap(mCapacity, aOther.mCapacity);
Swap(mTail.mCapacity, aOther.mTail.mCapacity);
#ifdef DEBUG
Swap(mReserved, aOther.mReserved);
Swap(mTail.mReserved, aOther.mTail.mReserved);
#endif
}
+43
View File
@@ -396,6 +396,49 @@ mozilla::detail::VectorTesting::testInsert()
MOZ_RELEASE_ASSERT(S::destructCount == 1);
}
// Declare but leave (permanently) incomplete.
struct Incomplete;
// We could even *construct* a Vector<Incomplete, 0> if we wanted. But we can't
// destruct it, so it's not worth the trouble.
static_assert(sizeof(Vector<Incomplete, 0>) > 0,
"Vector of an incomplete type will compile");
// Vector with no inline storage should occupy the absolute minimum space in
// non-debug builds. (Debug adds a laundry list of other constraints, none
// directly relevant to shipping builds, that aren't worth precisely modeling.)
#ifndef DEBUG
template<typename T>
struct NoInlineStorageLayout
{
T* mBegin;
size_t mLength;
struct CRAndStorage {
size_t mCapacity;
} mTail;
};
// Only one of these should be necessary, but test a few of them for good
// measure.
static_assert(sizeof(Vector<int, 0>) == sizeof(NoInlineStorageLayout<int>),
"Vector of int without inline storage shouldn't occupy dead "
"space for that absence of storage");
static_assert(sizeof(Vector<bool, 0>) == sizeof(NoInlineStorageLayout<bool>),
"Vector of bool without inline storage shouldn't occupy dead "
"space for that absence of storage");
static_assert(sizeof(Vector<S, 0>) == sizeof(NoInlineStorageLayout<S>),
"Vector of S without inline storage shouldn't occupy dead "
"space for that absence of storage");
static_assert(sizeof(Vector<Incomplete, 0>) == sizeof(NoInlineStorageLayout<Incomplete>),
"Vector of an incomplete class without inline storage shouldn't "
"occupy dead space for that absence of storage");
#endif // DEBUG
int
main()
{
+10
View File
@@ -4742,6 +4742,16 @@ fi
AC_DEFINE_UNQUOTED(MOZ_MACBUNDLE_ID,$MOZ_MACBUNDLE_ID)
AC_SUBST(MOZ_MACBUNDLE_ID)
dnl ========================================================
dnl = Mac bundle codesign identity
dnl ========================================================
MOZ_ARG_WITH_STRING(macbundle-identity,
[ --with-macbundle-identity=identity
Identity to codesign the Mac application bundle],
[ MOZ_MACBUNDLE_IDENTITY="$withval"])
AC_SUBST(MOZ_MACBUNDLE_IDENTITY)
dnl ========================================================
dnl = Child Process Name for IPC
dnl ========================================================
+6
View File
@@ -102,6 +102,7 @@ def create_dmg(source_directory, output_dmg, volume_name, extra_files):
if is_linux:
check_tools('DMG_TOOL', 'GENISOIMAGE')
with mozfile.TemporaryDirectory() as tmpdir:
import buildconfig
stagedir = os.path.join(tmpdir, 'stage')
os.mkdir(stagedir)
# Copy the app bundle over using rsync
@@ -118,4 +119,9 @@ def create_dmg(source_directory, output_dmg, volume_name, extra_files):
# Set the folder attributes to use a custom icon
set_folder_icon(stagedir)
chmod(stagedir)
if not is_linux:
identity = buildconfig.substs['MOZ_MACBUNDLE_IDENTITY']
if identity != '':
appbundle = os.path.join(stagedir, buildconfig.substs['MOZ_MACBUNDLE_NAME'])
subprocess.check_call(['codesign', '--deep', '-s', identity, appbundle])
create_dmg_from_staged(stagedir, output_dmg, tmpdir, volume_name)
+9 -2
View File
@@ -172,10 +172,17 @@ CTLogVerifier::Verify(const LogEntry& entry,
if (rv != Success) {
return rv;
}
// sct.extensions may be empty. If it is, sctExtensionsInput will remain in
// its default state, which is valid but of length 0.
Input sctExtensionsInput;
rv = BufferToInput(sct.extensions, sctExtensionsInput);
if (rv != Success) {
return rv;
if (sct.extensions.length() > 0) {
rv = sctExtensionsInput.Init(sct.extensions.begin(),
sct.extensions.length());
if (rv != Success) {
return rv;
}
}
Buffer serializedData;
@@ -115,6 +115,9 @@ struct SignedCertificateTimestamp
inline pkix::Result BufferToInput(const Buffer& buffer, pkix::Input& input)
{
if (buffer.length() == 0) {
return pkix::Result::FATAL_ERROR_LIBRARY_FAILURE;
}
return input.Init(buffer.begin(), buffer.length());
}
@@ -15,7 +15,6 @@ ifeq (,$(filter SunOS Linux WINNT,$(OS_ARCH)))
else
$(MAKE) stage-package make-buildinfo-file
@echo 'Compressing...'
cd $(DIST)/$(MOZ_PKG_DIR); $(CREATE_PRECOMPLETE_CMD)
ifeq (WINNT,$(OS_ARCH))
cd $(DIST); $(CYGWIN_WRAPPER) 7z a -t7z -m0=lzma2 -mx=9 -aoa -bb3 $(PKG_BASENAME).7z $(MOZ_PKG_DIR)
else
+4
View File
@@ -55,6 +55,10 @@ stage-package: $(MOZ_PKG_MANIFEST) $(MOZ_PKG_MANIFEST_DEPS)
$(MOZ_PKG_MANIFEST) '$(DIST)' '$(DIST)'/$(STAGEPATH)$(MOZ_PKG_DIR)$(if $(MOZ_PKG_MANIFEST),,$(_BINPATH)) \
$(if $(filter omni,$(MOZ_PACKAGER_FORMAT)),$(if $(NON_OMNIJAR_FILES),--non-resource $(NON_OMNIJAR_FILES)))
$(PYTHON) $(MOZILLA_DIR)/toolkit/mozapps/installer/find-dupes.py $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)
ifneq (Darwin, $(OS_ARCH))
# We don't want to do this on Mac as it will end up in the package root which is not how Mac packages things
cd $(DIST)/$(MOZ_PKG_DIR) && $(CREATE_PRECOMPLETE_CMD)
endif
ifdef MOZ_PACKAGE_JSSHELL
# Package JavaScript Shell
@echo 'Packaging JavaScript Shell...'
+5 -1
View File
@@ -355,7 +355,11 @@ nsFilePicker::ShowFilePicker(const nsString& aInitialDir)
// default extension to append to new files
if (!mDefaultExtension.IsEmpty()) {
hr = dialog->SetDefaultExtension(mDefaultExtension.get());
// We don't want environment variables expanded in the extension either.
nsAutoString sanitizedExtension(mDefaultExtension);
sanitizedExtension.ReplaceChar('%', '_');
hr = dialog->SetDefaultExtension(sanitizedExtension.get());
if (FAILED(hr)) {
return false;
}