import changes from `dev' branch of rmottola/Arctic-Fox:

- Bug 1256992 Part 2: Move SandboxBroker Initialization earlier and add telemetry and extra null checks. r=aklotz (acb4442402)
- Bug 1262753: P4. Add resampling capabilities to AudioConverter. r=kinetik (19788419ec)
- Bug 1233921 - Fix profiler crash when we're doing a debugger bailout. r=shu (6400ae545d)
- Bug 1166169 - Add MOZ_GONK_MEDIACODEC in configure and define it in moz.build. r=cpearce, r=glandium (812843d120)
- Bug 1236108: Modify sandbox initialization code to use directory service to obtain content process temp directory; r=bobowen,haik (8779ce1e57)
- Bug 1247832 - Adjust framePushed value in unboxed array baseline IC failure path, r=jandem. (f5914e1df4)
- Bug 1254122 - Don't bother saving scratch registers across TypeUpdate IC calls. (r=jandem) (4aea3f599e)
- Bug 1238815 - Limit baseline script size on ARM. r=jandem (7c13813ac6)
- Bug 1258349 - Remove a bogus assert. r=efaust (36d9edca40)
- Bug 1252903 - Add a missing OOM check in IonBuilder::inlineCalls. r=jonco (d7b146c7ef)
- Bug 1257929 - Instruction Reordering: Do not move instructions above the safeInsertTop location. r=bhackett (b5db952945)
- Bug 1258397 - Reorder Instruction: Renumber all instructions including the entry blocks. r=bhackett (0fe3de3028)
- Bug 1264429 - Trace script pointers in IonCache r=terrence (744354d567)
- Bug 1263558 - Part 0.2: Handle OOM inside SplitCriticalEdges and EliminatePhis at AnalyzeNewScriptDefiniteProperties and AnalyzeArgumentsUsage. r=jandem (8e3bad3c16)
- Bug 1236114 - IonMonkey: Move 'Sink' phase before the 'Remove Unnecessary Bitops' phase. r=sunfish (cbfd51d377)
- Bug 1259476 - Branch Pruning: Check if the Phi nodes have removed uses after popping them out of the worklist. r=jandem (8d5e1dca76)
- Bug 1186006 - Add a copy of the successor resume point to the split-edge blocks. r=bhackett (bf9ff0b37f)
- Bug 1246229 - Enable DCE to remove OSR guards if their values are optimized-out. r=h4writer (610dabfd1f)
- Bug 1247915 - IonMonkey adjustPhiInputs: Handle Phi operands artifact left by removing branches early. r=h4writer (9719e855f0)
- Bug 1258748 - adjustPhiInputs: Add MBox in the predecessor block instead of the definition block. r=jolesen (b0eafd8ff6)
- Bug 1263794 - IonMonkey: Crash when iterating graph and finding a nullptr MDefinition, r=jandem (fb3d0f2868)
- Bug 1257929 - Add assertions to ensure the safety of entry resume point encoding. r=h4writer (34c6410c56)
- Bug 1255949 - Check fallible flag in MBoundsCheck::congruentTo. r=h4writer (2aed033ca0)
- Bug 1240929 - Copy some HTTP request headers automatically on redirect, r=mcmanus (bff8d03edd)
- Bug 1236650 - make h2 push work in the face of redirects. r=mcmanus (9e0cd52a55)
This commit is contained in:
2024-05-07 22:20:46 +08:00
parent b1814c6e48
commit ce2aac9fa1
44 changed files with 722 additions and 269 deletions
+35 -27
View File
@@ -12,8 +12,13 @@
#include "mozilla/WindowsVersion.h"
#endif
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
#include <stdlib.h>
#endif
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
#include "mozilla/Preferences.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsDirectoryService.h"
#include "nsDirectoryServiceDefs.h"
#endif
@@ -33,12 +38,21 @@ IsSandboxTempDirRequired()
(Preferences::GetInt("security.sandbox.content.level") >= 1));
}
static const char*
SandboxTempDirParent()
static void
SetTmpEnvironmentVariable(nsIFile* aValue)
{
// On Windows, the sandbox-writable temp directory resides in the
// low integrity sandbox base directory.
return NS_WIN_LOW_INTEGRITY_TEMP_BASE;
// Save the TMP environment variable so that is is picked up by GetTempPath().
// Note that we specifically write to the TMP variable, as that is the first
// variable that is checked by GetTempPath() to determine its output.
nsAutoString fullTmpPath;
nsresult rv = aValue->GetPath(fullTmpPath);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
NS_WARN_IF(!SetEnvironmentVariableW(L"TMP", fullTmpPath.get()));
// We also set TEMP in case there is naughty third-party code that is
// referencing the environment variable directly.
NS_WARN_IF(!SetEnvironmentVariableW(L"TEMP", fullTmpPath.get()));
}
#endif
@@ -50,10 +64,15 @@ IsSandboxTempDirRequired()
return (Preferences::GetInt("security.sandbox.content.level") >= 1);
}
static const char*
SandboxTempDirParent()
static void
SetTmpEnvironmentVariable(nsIFile* aValue)
{
return NS_OS_TEMP_DIR;
nsAutoCString fullTmpPath;
nsresult rv = aValue->GetNativePath(fullTmpPath);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
NS_WARN_IF(setenv("TMPDIR", fullTmpPath.get(), 1) != 0);
}
#endif
@@ -68,24 +87,11 @@ SetUpSandboxEnvironment()
return;
}
nsAdoptingString tempDirSuffix =
Preferences::GetString("security.sandbox.content.tempDirSuffix");
if (tempDirSuffix.IsEmpty()) {
NS_WARNING("Sandbox-writable temp directory suffix pref not set.");
return;
}
// Get the parent of our sandbox writable temp directory.
nsCOMPtr<nsIFile> lowIntegrityTemp;
nsresult rv = nsDirectoryService::gService->Get(SandboxTempDirParent(),
NS_GET_IID(nsIFile),
getter_AddRefs(lowIntegrityTemp));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
// Append our profile specific temp name.
rv = lowIntegrityTemp->Append(NS_LITERAL_STRING("Temp-") + tempDirSuffix);
nsCOMPtr<nsIFile> sandboxedContentTemp;
nsresult rv =
nsDirectoryService::gService->Get(NS_APP_CONTENT_PROCESS_TEMP_DIR,
NS_GET_IID(nsIFile),
getter_AddRefs(sandboxedContentTemp));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
@@ -93,10 +99,12 @@ SetUpSandboxEnvironment()
// Change the gecko defined temp directory to our sandbox-writable one.
// Undefine returns a failure if the property is not already set.
Unused << nsDirectoryService::gService->Undefine(NS_OS_TEMP_DIR);
rv = nsDirectoryService::gService->Set(NS_OS_TEMP_DIR, lowIntegrityTemp);
rv = nsDirectoryService::gService->Set(NS_OS_TEMP_DIR, sandboxedContentTemp);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
SetTmpEnvironmentVariable(sandboxedContentTemp);
}
#endif
+76 -10
View File
@@ -6,6 +6,7 @@
#include "AudioConverter.h"
#include <string.h>
#include <speex/speex_resampler.h>
/*
* Parts derived from MythTV AudioConvert Class
@@ -20,9 +21,9 @@ namespace mozilla {
AudioConverter::AudioConverter(const AudioConfig& aIn, const AudioConfig& aOut)
: mIn(aIn)
, mOut(aOut)
, mResampler(nullptr)
{
MOZ_DIAGNOSTIC_ASSERT(aIn.Rate() == aOut.Rate() &&
aIn.Format() == aOut.Format() &&
MOZ_DIAGNOSTIC_ASSERT(aIn.Format() == aOut.Format() &&
aIn.Interleaved() == aOut.Interleaved(),
"No format or rate conversion is supported at this stage");
MOZ_DIAGNOSTIC_ASSERT((aIn.Channels() > aOut.Channels() && aOut.Channels() <= 2) ||
@@ -30,26 +31,57 @@ AudioConverter::AudioConverter(const AudioConfig& aIn, const AudioConfig& aOut)
"Only downmixing to mono or stereo is supported at this stage");
MOZ_DIAGNOSTIC_ASSERT(aOut.Interleaved(), "planar audio format not supported");
mIn.Layout().MappingTable(mOut.Layout(), mChannelOrderMap);
if (aIn.Rate() != aOut.Rate()) {
int error;
mResampler = speex_resampler_init(aOut.Channels(),
aIn.Rate(),
aOut.Rate(),
SPEEX_RESAMPLER_QUALITY_DEFAULT,
&error);
if (error == RESAMPLER_ERR_SUCCESS) {
speex_resampler_skip_zeros(mResampler);
} else {
NS_WARNING("Failed to initialize resampler.");
mResampler = nullptr;
}
}
}
AudioConverter::~AudioConverter()
{
if (mResampler) {
speex_resampler_destroy(mResampler);
mResampler = nullptr;
}
}
bool
AudioConverter::CanWorkInPlace() const
{
return mIn.Channels() * mIn.Rate() * AudioConfig::SampleSize(mIn.Format()) >=
mOut.Channels() * mOut.Rate() * AudioConfig::SampleSize(mOut.Format());
bool needDownmix = mIn.Channels() > mOut.Channels();
bool canDownmixInPlace =
mIn.Channels() * AudioConfig::SampleSize(mIn.Format()) >=
mOut.Channels() * AudioConfig::SampleSize(mOut.Format());
bool needResample = mIn.Rate() != mOut.Rate();
bool canResampleInPlace = mIn.Rate() >= mOut.Rate();
// We should be able to work in place if 1s of audio input takes less space
// than 1s of audio output. However, as we downmix before resampling we can't
// perform any upsampling in place (e.g. if incoming rate >= outgoing rate)
return (!needDownmix || canDownmixInPlace) &&
(!needResample || canResampleInPlace);
}
size_t
AudioConverter::Process(void* aOut, const void* aIn, size_t aBytes)
AudioConverter::ProcessInternal(void* aOut, const void* aIn, size_t aBytes)
{
if (!CanWorkInPlace()) {
return 0;
}
if (mIn.Channels() > mOut.Channels()) {
return DownmixAudio(aOut, aIn, aBytes);
} else if (mIn.Layout() != mOut.Layout() &&
CanReorderAudio()) {
ReOrderInterleavedChannels(aOut, aIn, aBytes);
} else if (aIn != aOut) {
memmove(aOut, aIn, aBytes);
}
return aBytes;
}
@@ -223,7 +255,41 @@ AudioConverter::DownmixAudio(void* aOut, const void* aIn, size_t aDataSize) cons
MOZ_DIAGNOSTIC_ASSERT(false, "Unsupported data type");
}
}
return frames * AudioConfig::SampleSize(mOut.Format()) * mOut.Channels();
return (size_t)frames * AudioConfig::SampleSize(mOut.Format()) * mOut.Channels();
}
} // namespace mozilla
size_t
AudioConverter::ResampleAudio(void* aOut, const void* aIn, size_t aDataSize)
{
if (!mResampler) {
return 0;
}
uint32_t frames =
aDataSize / AudioConfig::SampleSize(mOut.Format()) / mOut.Channels();
uint32_t outframes = ResampleRecipientFrames(frames);
uint32_t inframes = frames;
if (mOut.Format() == AudioConfig::FORMAT_FLT) {
const float* in = reinterpret_cast<const float*>(aIn);
float* out = reinterpret_cast<float*>(aOut);
speex_resampler_process_interleaved_float(mResampler, in, &inframes,
out, &outframes);
} else if (mOut.Format() == AudioConfig::FORMAT_S16) {
const int16_t* in = reinterpret_cast<const int16_t*>(aIn);
int16_t* out = reinterpret_cast<int16_t*>(aOut);
speex_resampler_process_interleaved_int(mResampler, in, &inframes,
out, &outframes);
} else {
MOZ_DIAGNOSTIC_ASSERT(false, "Unsupported data type");
}
MOZ_ASSERT(inframes == frames, "Some frames will be dropped");
return (size_t)outframes * AudioConfig::SampleSize(mOut.Format()) * mOut.Channels();
}
size_t
AudioConverter::ResampleRecipientFrames(size_t aFrames) const
{
return (uint64_t)aFrames * mOut.Rate() / mIn.Rate() + 1;
}
} // namespace mozilla
+73 -11
View File
@@ -9,6 +9,9 @@
#include "MediaInfo.h"
// Forward declaration
typedef struct SpeexResamplerState_ SpeexResamplerState;
namespace mozilla {
template <AudioConfig::SampleFormat T> struct AudioDataBufferTypeChooser;
@@ -115,23 +118,77 @@ typedef AudioDataBuffer<AudioConfig::FORMAT_DEFAULT> AudioSampleBuffer;
class AudioConverter {
public:
AudioConverter(const AudioConfig& aIn, const AudioConfig& aOut);
~AudioConverter();
// Convert the AudioDataBuffer.
// Conversion will be done in place if possible. Otherwise a new buffer will
// be returned.
template <AudioConfig::SampleFormat Format, typename Value>
AudioDataBuffer<Format, Value> Process(AudioDataBuffer<Format, Value>&& aBuffer)
{
MOZ_DIAGNOSTIC_ASSERT(mIn.Format() == mOut.Format() && mIn.Format() == Format);
AudioDataBuffer<Format, Value> buffer = Move(aBuffer);
if (CanWorkInPlace()) {
size_t bytes = ProcessInternal(buffer.Data(), buffer.Data(), buffer.Size());
if (bytes && mIn.Rate() != mOut.Rate()) {
bytes = ResampleAudio(buffer.Data(), buffer.Data(), bytes);
}
AlignedBuffer<Value> temp = buffer.Forget();
temp.SetLength(bytes / AudioConfig::SampleSize(mOut.Format()));
return AudioDataBuffer<Format, Value>(Move(temp));;
}
return Process(buffer);
}
template <AudioConfig::SampleFormat Format, typename Value>
AudioDataBuffer<Format, Value> Process(const AudioDataBuffer<Format, Value>& aBuffer)
{
MOZ_DIAGNOSTIC_ASSERT(mIn.Format() == mOut.Format() && mIn.Format() == Format);
// Perform the downmixing / reordering in temporary buffer.
uint32_t frames = aBuffer.Length() / mIn.Channels();
AlignedBuffer<Value> temp1;
if (!temp1.SetLength(frames * mOut.Channels())) {
return AudioDataBuffer<Format, Value>(Move(temp1));
}
size_t bytes = ProcessInternal(temp1.Data(), aBuffer.Data(), aBuffer.Size());
if (!bytes || mIn.Rate() == mOut.Rate()) {
temp1.SetLength(bytes / AudioConfig::SampleSize(mOut.Format()));
return AudioDataBuffer<Format, Value>(Move(temp1));
}
// At this point, temp1 contains the buffer reordered and downmixed.
// If we are downsampling we can re-use it.
AlignedBuffer<Value>* outputBuffer = &temp1;
AlignedBuffer<Value> temp2;
if (mOut.Rate() > mIn.Rate()) {
// We are upsampling, we can't work in place. Allocate another temporary
// buffer where the upsampling will occur.
temp2.SetLength(ResampleRecipientFrames(frames) * mOut.Channels());
outputBuffer = &temp2;
}
bytes = ResampleAudio(outputBuffer->Data(), temp1.Data(), bytes);
outputBuffer->SetLength(bytes / AudioConfig::SampleSize(mOut.Format()));
return AudioDataBuffer<Format, Value>(Move(*outputBuffer));
}
// Attempt to convert the AudioDataBuffer in place.
// Will return 0 if the conversion wasn't possible.
// Process may allocate memory internally should intermediary steps be
// required.
template <AudioConfig::SampleFormat Type, typename Value>
size_t Process(AudioDataBuffer<Type, Value>& aBuffer)
{
MOZ_DIAGNOSTIC_ASSERT(mIn.Format() == mOut.Format() && mIn.Format() == Type);
return Process(aBuffer.Data(), aBuffer.Data(), aBuffer.Size());
}
template <typename Value>
size_t Process(Value* aBuffer, size_t aSamples)
{
MOZ_DIAGNOSTIC_ASSERT(mIn.Format() == mOut.Format());
return Process(aBuffer, aBuffer, aSamples * AudioConfig::SampleSize(mIn.Format()));
if (!CanWorkInPlace()) {
return 0;
}
size_t bytes =
ProcessInternal(aBuffer, aBuffer,
aSamples * AudioConfig::SampleSize(mIn.Format()));
if (bytes && mIn.Rate() != mOut.Rate()) {
bytes = ResampleAudio(aBuffer, aBuffer, bytes);
}
return bytes;
}
bool CanWorkInPlace() const;
bool CanReorderAudio() const
{
@@ -146,7 +203,7 @@ private:
const AudioConfig mOut;
uint8_t mChannelOrderMap[MAX_AUDIO_CHANNELS];
/**
* Process
* ProcessInternal
* Parameters:
* aOut : destination buffer where converted samples will be copied
* aIn : source buffer
@@ -154,9 +211,14 @@ private:
*
* Return Value: size in bytes of samples converted or 0 if error
*/
size_t Process(void* aOut, const void* aIn, size_t aBytes);
size_t ProcessInternal(void* aOut, const void* aIn, size_t aBytes);
void ReOrderInterleavedChannels(void* aOut, const void* aIn, size_t aDataSize) const;
size_t DownmixAudio(void* aOut, const void* aIn, size_t aDataSize) const;
// Resampler context.
SpeexResamplerState* mResampler;
size_t ResampleAudio(void* aOut, const void* aIn, size_t aDataSize);
size_t ResampleRecipientFrames(size_t aFrames) const;
};
} // namespace mozilla
@@ -0,0 +1,22 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef dom_media_platforms_MediaTelemetryConstants_h___
#define dom_media_platforms_MediaTelemetryConstants_h___
namespace mozilla {
namespace media {
enum class MediaDecoderBackend : uint32_t
{
WMFSoftware = 0,
WMFDXVA2D3D9 = 1,
WMFDXVA2D3D11 = 2
};
} // namespace media
} // namespace mozilla
#endif // dom_media_platforms_MediaTelemetryConstants_h___
@@ -227,7 +227,7 @@ VorbisDataDecoder::DoDecode(MediaRawData* aSample)
}
MOZ_ASSERT(mAudioConverter->CanWorkInPlace());
AudioSampleBuffer data(Move(buffer));
mAudioConverter->Process(data);
data = mAudioConverter->Process(Move(data));
aTotalFrames += frames;
mCallback->Output(new AudioData(aOffset,
+1 -1
View File
@@ -287,7 +287,7 @@ AppleATDecoder::DecodeSample(MediaRawData* aSample)
}
if (mAudioConverter) {
MOZ_ASSERT(mAudioConverter->CanWorkInPlace());
mAudioConverter->Process(data);
data = mAudioConverter->Process(Move(data));
}
RefPtr<AudioData> audio = new AudioData(aSample->mOffset,
+2 -1
View File
@@ -9,6 +9,7 @@ EXPORTS += [
'agnostic/OpusDecoder.h',
'agnostic/VorbisDecoder.h',
'agnostic/VPXDecoder.h',
'MediaTelemetryConstants.h',
'PDMFactory.h',
'PlatformDecoderModule.h',
'wrappers/FuzzingWrapper.h',
@@ -73,7 +74,7 @@ if CONFIG['MOZ_APPLEMEDIA']:
'-framework AudioToolbox',
]
if CONFIG['MOZ_FMP4'] and CONFIG['ANDROID_VERSION'] >= '18'and CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
if CONFIG['MOZ_GONK_MEDIACODEC']:
DEFINES['MOZ_GONK_MEDIACODEC'] = True
DIRS += ['gonk']
+2
View File
@@ -13,6 +13,8 @@
#include "mozilla/layers/D3D11ShareHandleImage.h"
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/Preferences.h"
#include "mozilla/Telemetry.h"
#include "MediaTelemetryConstants.h"
#include "mfapi.h"
#include "MFTDecoder.h"
#include "DriverCrashGuard.h"
@@ -23,6 +23,7 @@
#include "mozilla/Preferences.h"
#include "mozilla/Telemetry.h"
#include "nsPrintfCString.h"
#include "MediaTelemetryConstants.h"
extern mozilla::LogModule* GetPDMLog();
#define LOG(...) MOZ_LOG(GetPDMLog(), mozilla::LogLevel::Debug, (__VA_ARGS__))
-1
View File
@@ -1257,4 +1257,3 @@ nsFind::CreateRange(nsINode* aNode)
range->SetMaySpanAnonymousSubtrees(true);
return range.forget();
}
@@ -0,0 +1,13 @@
// This program crashes the ARM code generator because the machine code is
// longer than the 32MB range of ARM branch instructions.
//
// Baseline should not attempt to compile the script.
i = 1;
function test(s) eval("line0 = Error.lineNumber\ndebugger\n" + s);
function repeat(s) {
return Array(65 << 13).join(s)
}
long_expr = repeat(" + i")
long_throw_stmt = long_expr;
test(long_throw_stmt);
@@ -0,0 +1,10 @@
function f() {
var o = {x: 1};
for (var i = 0; i < 300; i++)
o = Object.create(o);
for (var i = 0; i < 15; i++) {
assertEq(o.x, 1);
assertEq(o.y, undefined);
}
}
f();
+7
View File
@@ -0,0 +1,7 @@
// |jit-test| --ion-pgo=on
evaluate(`
var i = 0;
while (!inIon())
a = [] ? i: () => 5;
`);
@@ -0,0 +1,22 @@
// |jit-test| --ion-offthread-compile=off;
// We disable any off-main thread compilation, and set a definite trigger for
// Ion compilation, such that we can garantee that we would OSR into the inner
// loop before we reach the end of the loop.
setJitCompilerOption("ion.warmup.trigger", 30);
function f (n) {
while (!inIon()) {
var inner = 0;
let x = {};
for (var i = 0; i < n; i++) {
inner += inIon() == true ? 1 : 0;
if (inner <= 1)
bailout();
}
assertEq(inner != 1, true);
}
}
// Iterate enough to ensure that we OSR in this inner loop.
f(300);
@@ -0,0 +1,16 @@
// |jit-test| --ion-pgo=on;
try {
x = evalcx('');
x.__proto__ = 0;
} catch (e) {}
(function() {
for (var i = 0; i < 1; ++i) {
if (i % 5 == 0) {
for (let z of[0, 0, new Boolean(false), new Boolean(false),
new Boolean(false), new Boolean(false)]) {
this.x;
}
}
}
})()
@@ -0,0 +1,5 @@
function f(x) {
return (!(Math.round(Math.hypot(Number.MIN_VALUE, Math.fround(x))) | 0) | 0) !== (Math.atanh(x) ? false : Math.tan(0))
}
f(Number.MIN_VALUE)
assertEq(f(4294967295), true)
@@ -0,0 +1,19 @@
g = newGlobal();
g.parent = this;
g.eval("new Debugger(parent).onExceptionUnwind = function () {}");
enableSPSProfiling();
try {
enableSingleStepProfiling();
} catch(e) {
quit();
}
f();
f();
function $ERROR() {
throw Error;
}
function f() {
try {
$ERROR()
} catch (ex) {}
}
+2 -5
View File
@@ -1090,16 +1090,13 @@ InitFromBailout(JSContext* cx, HandleScript caller, jsbytecode* callerPC,
//
// Note that we never resume at this pc, it is set for the sake
// of frame iterators giving the correct answer.
//
// We also set nativeCodeForPC to nullptr as this address
// won't be used anywhere.
jsbytecode* throwPC = script->offsetToPC(iter.pcOffset());
builder.setResumePC(throwPC);
nativeCodeForPC = nullptr;
nativeCodeForPC = baselineScript->nativeCodeForPC(script, throwPC);
} else {
nativeCodeForPC = baselineScript->nativeCodeForPC(script, pc, &slotInfo);
MOZ_ASSERT(nativeCodeForPC);
}
MOZ_ASSERT(nativeCodeForPC);
unsigned numUnsynced = slotInfo.numUnsynced();
+9 -8
View File
@@ -2962,6 +2962,8 @@ ICSetElemDenseOrUnboxedArrayAddCompiler::generateStubCode(MacroAssembler& masm)
// But R0 and R1 still hold their values.
EmitStowICValues(masm, 2);
uint32_t framePushedAfterStow = masm.framePushed();
// We may need to free up some registers.
regs = availableGeneralRegs(0);
regs.take(R0);
@@ -3123,6 +3125,7 @@ ICSetElemDenseOrUnboxedArrayAddCompiler::generateStubCode(MacroAssembler& masm)
// Failure case - fail but first unstow R0 and R1
masm.bind(&failureUnstow);
masm.setFramePushed(framePushedAfterStow);
EmitUnstowICValues(masm, 2);
// Failure case - jump to next stub
@@ -4955,8 +4958,6 @@ ICSetProp_Unboxed::Compiler::generateStubCode(MacroAssembler& masm)
if (needsUpdateStubs()) {
// Stow both R0 and R1 (object and value).
masm.push(object);
masm.push(ICStubReg);
EmitStowICValues(masm, 2);
// Move RHS into R0 for TypeUpdate check.
@@ -4968,8 +4969,9 @@ ICSetProp_Unboxed::Compiler::generateStubCode(MacroAssembler& masm)
// Unstow R0 and R1 (object and key)
EmitUnstowICValues(masm, 2);
masm.pop(ICStubReg);
masm.pop(object);
// The TypeUpdate IC may have smashed object. Rederive it.
masm.unboxObject(R0, object);
// Trigger post barriers here on the values being written. Fields which
// objects can be written to also need update stubs.
@@ -5026,8 +5028,6 @@ ICSetProp_TypedObject::Compiler::generateStubCode(MacroAssembler& masm)
if (needsUpdateStubs()) {
// Stow both R0 and R1 (object and value).
masm.push(object);
masm.push(ICStubReg);
EmitStowICValues(masm, 2);
// Move RHS into R0 for TypeUpdate check.
@@ -5039,8 +5039,9 @@ ICSetProp_TypedObject::Compiler::generateStubCode(MacroAssembler& masm)
// Unstow R0 and R1 (object and key)
EmitUnstowICValues(masm, 2);
masm.pop(ICStubReg);
masm.pop(object);
// We may have clobbered object in the TypeUpdate IC. Rederive it.
masm.unboxObject(R0, object);
// Trigger post barriers here on the values being written. Descriptors
// which can write objects also need update stubs.
+8
View File
@@ -110,7 +110,15 @@ struct DependentWasmModuleImport
struct BaselineScript
{
public:
// Largest script that the baseline compiler will attempt to compile.
#if defined(JS_CODEGEN_ARM)
// ARM branches can only reach 32MB, and the macroassembler doesn't mitigate
// that limitation. Use a stricter limit on the acceptable script size to
// avoid crashing when branches go out of range.
static const uint32_t MAX_JSSCRIPT_LENGTH = 1000000u;
#else
static const uint32_t MAX_JSSCRIPT_LENGTH = 0x0fffffffu;
#endif
// Limit the locals on a given script so that stack check on baseline frames
// doesn't overflow a uint32_t value.
+1 -1
View File
@@ -162,8 +162,8 @@ class MOZ_RAII CacheIRWriter
}
void writeOperandId(OperandId opId) {
MOZ_ASSERT(size_t(opId.id()) <= UINT8_MAX);
if (opId.id() < MaxOperandIds) {
static_assert(MaxOperandIds <= UINT8_MAX, "operand id must fit in a single byte");
buffer_.writeByte(opId.id());
} else {
tooLarge_ = true;
+2 -2
View File
@@ -32,7 +32,7 @@ class FixedList
{ }
// Dynamic memory allocation requires the ability to report failure.
bool init(TempAllocator& alloc, size_t length) {
MOZ_WARN_UNUSED_RESULT bool init(TempAllocator& alloc, size_t length) {
length_ = length;
if (length == 0)
return true;
@@ -57,7 +57,7 @@ class FixedList
length_ -= num;
}
bool growBy(TempAllocator& alloc, size_t num) {
MOZ_WARN_UNUSED_RESULT bool growBy(TempAllocator& alloc, size_t num) {
size_t newlength = length_ + num;
if (newlength < length_)
return false;
+11 -8
View File
@@ -53,6 +53,13 @@ jit::ReorderInstructions(MIRGenerator* mir, MIRGraph& graph)
Vector<MBasicBlock*, 4, SystemAllocPolicy> loopHeaders;
for (ReversePostorderIterator block(graph.rpoBegin()); block != graph.rpoEnd(); block++) {
// Renumber all definitions inside the basic blocks.
for (MPhiIterator iter(block->phisBegin()); iter != block->phisEnd(); iter++)
iter->setId(nextId++);
for (MInstructionIterator iter(block->begin()); iter != block->end(); iter++)
iter->setId(nextId++);
// Don't reorder instructions within entry blocks, which have special requirements.
if (*block == graph.entryBlock() || *block == graph.osrBlock())
continue;
@@ -64,13 +71,9 @@ jit::ReorderInstructions(MIRGenerator* mir, MIRGraph& graph)
MBasicBlock* innerLoop = loopHeaders.empty() ? nullptr : loopHeaders.back();
for (MPhiIterator iter(block->phisBegin()); iter != block->phisEnd(); iter++)
iter->setId(nextId++);
for (MInstructionIterator iter(block->begin()); iter != block->end(); iter++)
iter->setId(nextId++);
for (MInstructionIterator iter(block->begin()); iter != block->end(); ) {
MInstruction* top = block->safeInsertTop();
MInstructionReverseIterator rtop = ++block->rbegin(top);
for (MInstructionIterator iter(block->begin(top)); iter != block->end(); ) {
MInstruction* ins = *iter;
// Filter out some instructions which are never reordered.
@@ -126,7 +129,7 @@ jit::ReorderInstructions(MIRGenerator* mir, MIRGraph& graph)
}
MInstruction* target = ins;
for (MInstructionReverseIterator riter = ++block->rbegin(ins); riter != block->rend(); riter++) {
for (MInstructionReverseIterator riter = ++block->rbegin(ins); riter != rtop; riter++) {
MInstruction* prev = *riter;
if (prev->isInterruptCheck())
break;
+28 -14
View File
@@ -1020,6 +1020,10 @@ IonScript::trace(JSTracer* trc)
ICEntry& ent = sharedStubList()[i];
ent.trace(trc);
}
// Trace caches so that the JSScript pointer can be updated if moved.
for (size_t i = 0; i < numCaches(); i++)
getCacheFromIndex(i).trace(trc);
}
/* static */ void
@@ -1508,8 +1512,7 @@ OptimizeMIR(MIRGenerator* mir)
{
AutoTraceLog log(logger, TraceLogger_RenumberBlocks);
if (!RenumberBlocks(graph))
return false;
RenumberBlocks(graph);
gs.spewPass("Renumber Blocks");
AssertGraphCoherency(graph);
@@ -1657,9 +1660,9 @@ OptimizeMIR(MIRGenerator* mir)
}
}
RangeAnalysis r(mir, graph);
if (mir->optimizationInfo().rangeAnalysisEnabled()) {
AutoTraceLog log(logger, TraceLogger_RangeAnalysis);
RangeAnalysis r(mir, graph);
if (!r.addBetaNodes())
return false;
gs.spewPass("Beta");
@@ -1726,6 +1729,28 @@ OptimizeMIR(MIRGenerator* mir)
}
}
{
AutoTraceLog log(logger, TraceLogger_Sink);
if (!Sink(mir, graph))
return false;
gs.spewPass("Sink");
AssertExtendedGraphCoherency(graph);
if (mir->shouldCancel("Sink"))
return false;
}
if (mir->optimizationInfo().rangeAnalysisEnabled()) {
AutoTraceLog log(logger, TraceLogger_RemoveUnnecessaryBitops);
if (!r.removeUnnecessaryBitops())
return false;
gs.spewPass("Remove Unnecessary Bitops");
AssertExtendedGraphCoherency(graph);
if (mir->shouldCancel("Remove Unnecessary Bitops"))
return false;
}
if (mir->optimizationInfo().eaaEnabled()) {
AutoTraceLog log(logger, TraceLogger_EffectiveAddressAnalysis);
EffectiveAddressAnalysis eaa(mir, graph);
@@ -1759,17 +1784,6 @@ OptimizeMIR(MIRGenerator* mir)
return false;
}
{
AutoTraceLog log(logger, TraceLogger_EliminateDeadCode);
if (!Sink(mir, graph))
return false;
gs.spewPass("Sink");
AssertExtendedGraphCoherency(graph);
if (mir->shouldCancel("Sink"))
return false;
}
if (mir->optimizationInfo().instructionReorderingEnabled()) {
AutoTraceLog log(logger, TraceLogger_ReorderInstructions);
if (!ReorderInstructions(mir, graph))
+76 -50
View File
@@ -120,6 +120,12 @@ FlagPhiInputsAsHavingRemovedUses(MBasicBlock* block, MBasicBlock* succ, MPhiVect
bool isUsed = false;
for (size_t idx = 0; !isUsed && idx < worklist.length(); idx++) {
phi = worklist[idx];
if (phi->isUseRemoved() || phi->isImplicitlyUsed()) {
// The phi is implicitly used.
isUsed = true;
break;
}
MUseIterator usesEnd(phi->usesEnd());
for (MUseIterator use(phi->usesBegin()); use != usesEnd; use++) {
MNode* consumer = (*use)->consumer();
@@ -144,12 +150,6 @@ FlagPhiInputsAsHavingRemovedUses(MBasicBlock* block, MBasicBlock* succ, MPhiVect
if (phi->isInWorklist())
continue;
if (phi->isUseRemoved() || phi->isImplicitlyUsed()) {
// The phi is implicitly used.
isUsed = true;
break;
}
phi->setInWorklist();
if (!worklist.append(phi))
return false;
@@ -421,27 +421,11 @@ SplitCriticalEdgesForBlock(MIRGraph& graph, MBasicBlock* block)
if (target->numPredecessors() < 2)
continue;
// Create a new block inheriting from the predecessor.
MBasicBlock* split = MBasicBlock::NewSplitEdge(graph, block->info(), block);
// Create a simple new block which contains a goto and which split the
// edge between block and target.
MBasicBlock* split = MBasicBlock::NewSplitEdge(graph, block->info(), block, i, target);
if (!split)
return false;
split->setLoopDepth(block->loopDepth());
graph.insertBlockAfter(block, split);
split->end(MGoto::New(graph.alloc(), target));
// The entry resume point won't properly reflect state at the start of
// the split edge, so remove it. Split edges start out empty, but might
// have fallible code moved into them later. Rather than immediately
// figure out a valid resume point and pc we can use for the split edge,
// we wait until lowering (see LIRGenerator::visitBlock), where this
// will be easier.
if (MResumePoint* rp = split->entryResumePoint()) {
rp->releaseUses();
split->clearEntryResumePoint();
}
block->replaceSuccessor(i, split);
target->replacePredecessor(block, split);
}
return true;
}
@@ -950,7 +934,9 @@ jit::EliminateDeadResumePointOperands(MIRGenerator* mir, MIRGraph& graph)
bool
js::jit::DeadIfUnused(const MDefinition* def)
{
return !def->isEffectful() && !def->isGuard() && !def->isGuardRangeBailouts() &&
return !def->isEffectful() &&
(!def->isGuard() || def->block() == def->block()->graph().osrBlock()) &&
!def->isGuardRangeBailouts() &&
!def->isControlInstruction() &&
(!def->isInstruction() || !def->toInstruction()->resumePoint());
}
@@ -1483,17 +1469,20 @@ TypeAnalyzer::adjustPhiInputs(MPhi* phi)
if (in->type() == MIRType_Value)
continue;
if (in->isUnbox() && phi->typeIncludes(in->toUnbox()->input())) {
// The input is being explicitly unboxed, so sneak past and grab
// the original box.
phi->replaceOperand(i, in->toUnbox()->input());
} else {
// The input is being explicitly unboxed, so sneak past and grab
// the original box.
if (in->isUnbox() && phi->typeIncludes(in->toUnbox()->input()))
in = in->toUnbox()->input();
if (in->type() != MIRType_Value) {
if (!alloc().ensureBallast())
return false;
MDefinition* box = AlwaysBoxAt(alloc(), in->block()->lastIns(), in);
phi->replaceOperand(i, box);
MBasicBlock* pred = phi->block()->getPredecessor(i);
in = AlwaysBoxAt(alloc(), pred->lastIns(), in);
}
phi->replaceOperand(i, in);
}
return true;
@@ -1848,6 +1837,9 @@ jit::MakeMRegExpHoistable(MIRGraph& graph)
for (ReversePostorderIterator block(graph.rpoBegin()); block != graph.rpoEnd(); block++) {
for (MDefinitionIterator iter(*block); iter; iter++) {
if (!*iter)
MOZ_CRASH("confirm bug 1263794.");
if (!iter->isRegExp())
continue;
@@ -1896,14 +1888,12 @@ jit::MakeMRegExpHoistable(MIRGraph& graph)
return true;
}
bool
void
jit::RenumberBlocks(MIRGraph& graph)
{
size_t id = 0;
for (ReversePostorderIterator block(graph.rpoBegin()); block != graph.rpoEnd(); block++)
block->setId(id++);
return true;
}
// A utility for code which deletes blocks. Renumber the remaining blocks,
@@ -2285,6 +2275,32 @@ CheckUse(const MDefinition* producer, const MUse* use, int32_t* usesBalance)
#endif
++*usesBalance;
}
// To properly encode entry resume points, we have to ensure that all the
// operands of the entry resume point are located before the safeInsertTop
// location.
static void
AssertOperandsBeforeSafeInsertTop(MResumePoint* resume)
{
MBasicBlock* block = resume->block();
if (block == block->graph().osrBlock())
return;
MInstruction* stop = block->safeInsertTop();
for (size_t i = 0, e = resume->numOperands(); i < e; ++i) {
MDefinition* def = resume->getOperand(i);
if (def->block() != block)
continue;
if (def->isPhi())
continue;
for (MInstructionIterator ins = block->begin(); true; ins++) {
if (*ins == def)
break;
MOZ_ASSERT(*ins != stop,
"Resume point operand located after the safeInsertTop location");
}
}
}
#endif // DEBUG
void
@@ -2322,13 +2338,14 @@ jit::AssertBasicGraphCoherency(MIRGraph& graph)
for (size_t i = 0; i < block->numPredecessors(); i++)
MOZ_ASSERT(CheckPredecessorImpliesSuccessor(*block, block->getPredecessor(i)));
if (block->entryResumePoint()) {
MOZ_ASSERT(!block->entryResumePoint()->instruction());
MOZ_ASSERT(block->entryResumePoint()->block() == *block);
if (MResumePoint* resume = block->entryResumePoint()) {
MOZ_ASSERT(!resume->instruction());
MOZ_ASSERT(resume->block() == *block);
AssertOperandsBeforeSafeInsertTop(resume);
}
if (block->outerResumePoint()) {
MOZ_ASSERT(!block->outerResumePoint()->instruction());
MOZ_ASSERT(block->outerResumePoint()->block() == *block);
if (MResumePoint* resume = block->outerResumePoint()) {
MOZ_ASSERT(!resume->instruction());
MOZ_ASSERT(resume->block() == *block);
}
for (MResumePointIterator iter(block->resumePointsBegin()); iter != block->resumePointsEnd(); iter++) {
// We cannot yet assert that is there is no instruction then this is
@@ -2834,6 +2851,9 @@ TryEliminateBoundsCheck(BoundsCheckMap& checks, size_t blockIndex, MBoundsCheck*
if (!dominated->isMovable())
return true;
if (!dominated->fallible())
return true;
MBoundsCheck* dominating = FindDominatingBoundsCheck(checks, dominated, blockIndex);
if (!dominating)
return false;
@@ -3755,19 +3775,22 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, JSFunction* fun,
FinishDefinitePropertiesAnalysis(cx, constraints);
if (!SplitCriticalEdges(graph))
if (!SplitCriticalEdges(graph)) {
ReportOutOfMemory(cx);
return false;
}
if (!RenumberBlocks(graph))
return false;
RenumberBlocks(graph);
if (!BuildDominatorTree(graph)) {
ReportOutOfMemory(cx);
return false;
}
if (!EliminatePhis(&builder, graph, AggressiveObservability))
if (!EliminatePhis(&builder, graph, AggressiveObservability)) {
ReportOutOfMemory(cx);
return false;
}
MDefinition* thisValue = graph.entryBlock()->getSlot(info.thisSlot());
@@ -3976,19 +3999,22 @@ jit::AnalyzeArgumentsUsage(JSContext* cx, JSScript* scriptArg)
return true;
}
if (!SplitCriticalEdges(graph))
if (!SplitCriticalEdges(graph)) {
ReportOutOfMemory(cx);
return false;
}
if (!RenumberBlocks(graph))
return false;
RenumberBlocks(graph);
if (!BuildDominatorTree(graph)) {
ReportOutOfMemory(cx);
return false;
}
if (!EliminatePhis(&builder, graph, AggressiveObservability))
if (!EliminatePhis(&builder, graph, AggressiveObservability)) {
ReportOutOfMemory(cx);
return false;
}
MDefinition* argumentsValue = graph.entryBlock()->getSlot(info.argsObjSlot());
+1 -1
View File
@@ -56,7 +56,7 @@ ApplyTypeInformation(MIRGenerator* mir, MIRGraph& graph);
bool
MakeMRegExpHoistable(MIRGraph& graph);
bool
void
RenumberBlocks(MIRGraph& graph);
bool
+2 -1
View File
@@ -5932,7 +5932,8 @@ IonBuilder::inlineCalls(CallInfo& callInfo, const ObjectVector& targets, BoolVec
returnBlock->push(retPhi);
// Create a resume point from current stack state.
returnBlock->initEntrySlots(alloc());
if (!returnBlock->initEntrySlots(alloc()))
return false;
// Reserve the capacity for the phi.
// Note: this is an upperbound. Unreachable targets and uninlineable natives are also counted.
+6
View File
@@ -383,6 +383,12 @@ IonCache::updateBaseAddress(JitCode* code, MacroAssembler& masm)
rejoinLabel_.repoint(code, &masm);
}
void IonCache::trace(JSTracer* trc)
{
if (script_)
TraceManuallyBarrieredEdge(trc, &script_, "IonCache::script_");
}
static void*
GetReturnAddressToIonCode(JSContext* cx)
{
+2
View File
@@ -341,6 +341,8 @@ class IonCache
MOZ_ASSERT(pc_);
return pc_;
}
void trace(JSTracer* trc);
};
// Define the cache kind and pre-declare data structures used for calling inline
+1 -21
View File
@@ -4718,6 +4718,7 @@ LIRGenerator::updateResumeState(MInstruction* ins)
void
LIRGenerator::updateResumeState(MBasicBlock* block)
{
MOZ_ASSERT_IF(!mir()->compilingAsmJS(), block->entryResumePoint());
lastResumePoint_ = block->entryResumePoint();
if (JitSpewEnabled(JitSpew_IonSnapshots) && lastResumePoint_)
SpewResumePoint(block, nullptr, lastResumePoint_);
@@ -4762,27 +4763,6 @@ LIRGenerator::visitBlock(MBasicBlock* block)
if (!visitInstruction(block->lastIns()))
return false;
// If we have a resume point check that all the following blocks have one,
// otherwise reuse the last resume point as the entry resume point of the
// basic block. This is used to handle fallible code which is moved/added
// into split edge blocks, which do not have resume points. See
// SplitCriticalEdgesForBlock.
//
// When folding conditions, we might create split-edge blocks which have
// multiple predecessors, in such case it is invalid to have any instruction
// in these blocks, as these blocks have no associated pc, thus we cannot
// safely bailout from such block.
if (lastResumePoint_) {
for (size_t s = 0; s < block->numSuccessors(); s++) {
MBasicBlock* succ = block->getSuccessor(s);
if (!succ->entryResumePoint() && succ->numPredecessors() == 1) {
MOZ_ASSERT(succ->isSplitEdge());
MOZ_ASSERT(succ->phisBegin() == succ->phisEnd());
succ->setEntryResumePoint(lastResumePoint_);
}
}
}
return true;
}
+12 -8
View File
@@ -1221,7 +1221,7 @@ class MVariadicT : public T
FixedList<MUse> operands_;
protected:
bool init(TempAllocator& alloc, size_t length) {
MOZ_WARN_UNUSED_RESULT bool init(TempAllocator& alloc, size_t length) {
return operands_.init(alloc, length);
}
void initOperand(size_t index, MDefinition* operand) {
@@ -2022,7 +2022,7 @@ class MSimdGeneralShuffle :
return new(alloc) MSimdGeneralShuffle(numVectors, numLanes, type);
}
bool init(TempAllocator& alloc) {
MOZ_WARN_UNUSED_RESULT bool init(TempAllocator& alloc) {
return MVariadicInstruction::init(alloc, numVectors_ + numLanes_);
}
void setVector(unsigned i, MDefinition* vec) {
@@ -2666,7 +2666,7 @@ class MTableSwitch final
return successors_.length();
}
bool addSuccessor(MBasicBlock* successor, size_t* index) {
MOZ_WARN_UNUSED_RESULT bool addSuccessor(MBasicBlock* successor, size_t* index) {
MOZ_ASSERT(successors_.length() < (size_t)(high_ - low_ + 2));
MOZ_ASSERT(!successors_.empty());
*index = successors_.length();
@@ -2711,14 +2711,14 @@ class MTableSwitch final
return high() - low() + 1;
}
bool addDefault(MBasicBlock* block, size_t* index = nullptr) {
MOZ_WARN_UNUSED_RESULT bool addDefault(MBasicBlock* block, size_t* index = nullptr) {
MOZ_ASSERT(successors_.empty());
if (index)
*index = 0;
return successors_.append(block);
}
bool addCase(size_t successorIndex) {
MOZ_WARN_UNUSED_RESULT bool addCase(size_t successorIndex) {
return cases_.append(successorIndex);
}
@@ -2727,7 +2727,7 @@ class MTableSwitch final
return blocks_[i];
}
bool addBlock(MBasicBlock* block) {
MOZ_WARN_UNUSED_RESULT bool addBlock(MBasicBlock* block) {
return blocks_.append(block);
}
@@ -3630,7 +3630,7 @@ class MArrayState
explicit MArrayState(MDefinition* arr);
bool init(TempAllocator& alloc, MDefinition* obj, MDefinition* len);
MOZ_WARN_UNUSED_RESULT bool init(TempAllocator& alloc, MDefinition* obj, MDefinition* len);
void initElement(uint32_t index, MDefinition* def) {
initOperand(index + 2, def);
@@ -9123,12 +9123,14 @@ class MBoundsCheck
return minimum_;
}
void setMinimum(int32_t n) {
MOZ_ASSERT(fallible_);
minimum_ = n;
}
int32_t maximum() const {
return maximum_;
}
void setMaximum(int32_t n) {
MOZ_ASSERT(fallible_);
maximum_ = n;
}
MDefinition* foldsTo(TempAllocator& alloc) override;
@@ -9138,6 +9140,8 @@ class MBoundsCheck
const MBoundsCheck* other = ins->toBoundsCheck();
if (minimum() != other->minimum() || maximum() != other->maximum())
return false;
if (fallible() != other->fallible())
return false;
return congruentIfOperandsEqual(other);
}
virtual AliasSet getAliasSet() const override {
@@ -13346,7 +13350,7 @@ class MResumePoint final :
protected:
// Initializes operands_ to an empty array of a fixed length.
// The array may then be filled in by inherit().
bool init(TempAllocator& alloc);
MOZ_WARN_UNUSED_RESULT bool init(TempAllocator& alloc);
void clearOperand(size_t index) {
// FixedList doesn't initialize its elements, so do an unchecked init.
+73 -6
View File
@@ -334,13 +334,76 @@ MBasicBlock::NewPendingLoopHeader(MIRGraph& graph, const CompileInfo& info,
}
MBasicBlock*
MBasicBlock::NewSplitEdge(MIRGraph& graph, const CompileInfo& info, MBasicBlock* pred)
MBasicBlock::NewSplitEdge(MIRGraph& graph, const CompileInfo& info, MBasicBlock* pred, size_t predEdgeIdx, MBasicBlock* succ)
{
return pred->pc()
? MBasicBlock::New(graph, nullptr, info, pred,
new(graph.alloc()) BytecodeSite(pred->trackedTree(), pred->pc()),
SPLIT_EDGE)
: MBasicBlock::NewAsmJS(graph, info, pred, SPLIT_EDGE);
MBasicBlock* split = nullptr;
if (!pred->pc()) {
// The predecessor does not have a PC, this is an AsmJS compilation.
split = MBasicBlock::NewAsmJS(graph, info, pred, SPLIT_EDGE);
if (!split)
return nullptr;
} else {
// The predecessor has a PC, this is an IonBuilder compilation.
MResumePoint* succEntry = succ->entryResumePoint();
BytecodeSite* site = new(graph.alloc()) BytecodeSite(succ->trackedTree(), succEntry->pc());
split = new(graph.alloc()) MBasicBlock(graph, info, site, SPLIT_EDGE);
if (!split->init())
return nullptr;
// A split edge is used to simplify the graph to avoid having a
// predecessor with multiple successors as well as a successor with
// multiple predecessors. As instructions can be moved in this
// split-edge block, we need to give this block a resume point. To do
// so, we copy the entry resume points of the successor and filter the
// phis to keep inputs from the current edge.
// Propagate the caller resume point from the inherited block.
split->callerResumePoint_ = succ->callerResumePoint();
// Split-edge are created after the interpreter stack emulation. Thus,
// there is no need for creating slots.
split->stackPosition_ = succEntry->stackDepth();
// Create a resume point using our initial stack position.
MResumePoint* splitEntry = new(graph.alloc()) MResumePoint(split, succEntry->pc(),
MResumePoint::ResumeAt);
if (!splitEntry->init(graph.alloc()))
return nullptr;
split->entryResumePoint_ = splitEntry;
// The target entry resume point might have phi operands, keep the
// operands of the phi coming from our edge.
size_t succEdgeIdx = succ->indexForPredecessor(pred);
for (size_t i = 0, e = splitEntry->numOperands(); i < e; i++) {
MDefinition* def = succEntry->getOperand(i);
// This early in the pipeline, we have no recover instructions in
// any entry resume point.
MOZ_ASSERT_IF(def->block() == succ, def->isPhi());
if (def->block() == succ)
def = def->toPhi()->getOperand(succEdgeIdx);
splitEntry->initOperand(i, def);
}
// This is done in the NewAsmJS, so we cannot keep this line below,
// where the rest of the graph is modified.
if (!split->predecessors_.append(pred))
return nullptr;
}
split->setLoopDepth(succ->loopDepth());
// Insert the split edge block in-between.
split->end(MGoto::New(graph.alloc(), succ));
graph.insertBlockAfter(pred, split);
pred->replaceSuccessor(predEdgeIdx, split);
succ->replacePredecessor(pred, split);
return split;
}
MBasicBlock*
@@ -849,6 +912,9 @@ MBasicBlock::moveBefore(MInstruction* at, MInstruction* ins)
MInstruction*
MBasicBlock::safeInsertTop(MDefinition* ins, IgnoreTop ignore)
{
MOZ_ASSERT(graph().osrBlock() != this,
"We are not supposed to add any instruction in OSR blocks.");
// Beta nodes and interrupt checks are required to be located at the
// beginnings of basic blocks, so we must insert new instructions after any
// such instructions.
@@ -858,6 +924,7 @@ MBasicBlock::safeInsertTop(MDefinition* ins, IgnoreTop ignore)
while (insertIter->isBeta() ||
insertIter->isInterruptCheck() ||
insertIter->isConstant() ||
insertIter->isParameter() ||
(!(ignore & IgnoreRecover) && insertIter->isRecoveredOnBailout()))
{
insertIter++;
+19 -17
View File
@@ -47,11 +47,11 @@ class MBasicBlock : public TempObject, public InlineListNode<MBasicBlock>
private:
MBasicBlock(MIRGraph& graph, const CompileInfo& info, BytecodeSite* site, Kind kind);
bool init();
MOZ_WARN_UNUSED_RESULT bool init();
void copySlots(MBasicBlock* from);
bool inherit(TempAllocator& alloc, BytecodeAnalysis* analysis, MBasicBlock* pred,
uint32_t popped, unsigned stackPhiCount = 0);
bool inheritResumePoint(MBasicBlock* pred);
MOZ_WARN_UNUSED_RESULT bool inherit(TempAllocator& alloc, BytecodeAnalysis* analysis, MBasicBlock* pred,
uint32_t popped, unsigned stackPhiCount = 0);
MOZ_WARN_UNUSED_RESULT bool inheritResumePoint(MBasicBlock* pred);
void assertUsesAreNotWithin(MUseIterator use, MUseIterator end);
// This block cannot be reached by any means.
@@ -116,7 +116,9 @@ class MBasicBlock : public TempObject, public InlineListNode<MBasicBlock>
static MBasicBlock* NewPendingLoopHeader(MIRGraph& graph, const CompileInfo& info,
MBasicBlock* pred, BytecodeSite* site,
unsigned loopStateSlots);
static MBasicBlock* NewSplitEdge(MIRGraph& graph, const CompileInfo& info, MBasicBlock* pred);
static MBasicBlock* NewSplitEdge(MIRGraph& graph, const CompileInfo& info,
MBasicBlock* pred, size_t predEdgeIdx,
MBasicBlock* succ);
static MBasicBlock* NewAsmJS(MIRGraph& graph, const CompileInfo& info,
MBasicBlock* pred, Kind kind);
@@ -152,8 +154,8 @@ class MBasicBlock : public TempObject, public InlineListNode<MBasicBlock>
MDefinition* argumentsObject();
// Increase the number of slots available
bool increaseSlots(size_t num);
bool ensureHasSlots(size_t num);
MOZ_WARN_UNUSED_RESULT bool increaseSlots(size_t num);
MOZ_WARN_UNUSED_RESULT bool ensureHasSlots(size_t num);
// Initializes a slot value; must not be called for normal stack
// operations, as it will not create new SSA names for copies.
@@ -164,7 +166,7 @@ class MBasicBlock : public TempObject, public InlineListNode<MBasicBlock>
// In an OSR block, set all MOsrValues to use the MResumePoint attached to
// the MStart.
bool linkOsrValues(MStart* start);
MOZ_WARN_UNUSED_RESULT bool linkOsrValues(MStart* start);
// Sets the instruction associated with various slot types. The
// instruction must lie at the top of the stack.
@@ -218,17 +220,17 @@ class MBasicBlock : public TempObject, public InlineListNode<MBasicBlock>
// Adds a predecessor. Every predecessor must have the same exit stack
// depth as the entry state to this block. Adding a predecessor
// automatically creates phi nodes and rewrites uses as needed.
bool addPredecessor(TempAllocator& alloc, MBasicBlock* pred);
bool addPredecessorPopN(TempAllocator& alloc, MBasicBlock* pred, uint32_t popped);
MOZ_WARN_UNUSED_RESULT bool addPredecessor(TempAllocator& alloc, MBasicBlock* pred);
MOZ_WARN_UNUSED_RESULT bool addPredecessorPopN(TempAllocator& alloc, MBasicBlock* pred, uint32_t popped);
// Add a predecessor which won't introduce any new phis to this block.
// This may be called after the contents of this block have been built.
void addPredecessorSameInputsAs(MBasicBlock* pred, MBasicBlock* existingPred);
// Stranger utilities used for inlining.
bool addPredecessorWithoutPhis(MBasicBlock* pred);
MOZ_WARN_UNUSED_RESULT bool addPredecessorWithoutPhis(MBasicBlock* pred);
void inheritSlots(MBasicBlock* parent);
bool initEntrySlots(TempAllocator& alloc);
MOZ_WARN_UNUSED_RESULT bool initEntrySlots(TempAllocator& alloc);
// Replaces an edge for a given block with a new block. This is
// used for critical edge splitting.
@@ -253,8 +255,8 @@ class MBasicBlock : public TempObject, public InlineListNode<MBasicBlock>
// Sets a back edge. This places phi nodes and rewrites instructions within
// the current loop as necessary. If the backedge introduces new types for
// phis at the loop header, returns a disabling abort.
AbortReason setBackedge(MBasicBlock* block);
bool setBackedgeAsmJS(MBasicBlock* block);
MOZ_WARN_UNUSED_RESULT AbortReason setBackedge(MBasicBlock* block);
MOZ_WARN_UNUSED_RESULT bool setBackedgeAsmJS(MBasicBlock* block);
// Resets a LOOP_HEADER block to a NORMAL block. This is needed when
// optimizations remove the backedge.
@@ -269,10 +271,10 @@ class MBasicBlock : public TempObject, public InlineListNode<MBasicBlock>
void inheritPhis(MBasicBlock* header);
// Propagates backedge slots into phis operands of the loop header.
bool inheritPhisFromBackedge(MBasicBlock* backedge, bool* hadTypeChange);
MOZ_WARN_UNUSED_RESULT bool inheritPhisFromBackedge(MBasicBlock* backedge, bool* hadTypeChange);
// Compute the types for phis in this block according to their inputs.
bool specializePhis();
MOZ_WARN_UNUSED_RESULT bool specializePhis();
void insertBefore(MInstruction* at, MInstruction* ins);
void insertAfter(MInstruction* at, MInstruction* ins);
@@ -771,7 +773,7 @@ class MIRGraph
return returnAccumulator_;
}
bool addReturn(MBasicBlock* returnBlock) {
MOZ_WARN_UNUSED_RESULT bool addReturn(MBasicBlock* returnBlock) {
if (!returnAccumulator_)
return true;
+17 -1
View File
@@ -3048,7 +3048,6 @@ RangeAnalysis::truncate()
MOZ_ASSERT(!mir->compilingAsmJS());
Vector<MDefinition*, 16, SystemAllocPolicy> worklist;
Vector<MBinaryBitwiseInstruction*, 16, SystemAllocPolicy> bitops;
for (PostorderIterator block(graph_.poBegin()); block != graph_.poEnd(); block++) {
for (MInstructionReverseIterator iter(block->rbegin()); iter != block->rend(); iter++) {
@@ -3147,11 +3146,26 @@ RangeAnalysis::truncate()
AdjustTruncatedInputs(alloc(), def);
}
return true;
}
bool
RangeAnalysis::removeUnnecessaryBitops()
{
// Note: This operation change the semantic of the program in a way which
// uniquely works with Int32, Recover Instructions added by the Sink phase
// expects the MIR Graph to still have a valid flow as-if they were double
// operations instead of Int32 operations. Thus, this phase should be
// executed after the Sink phase, and before DCE.
// Fold any unnecessary bitops in the graph, such as (x | 0) on an integer
// input. This is done after range analysis rather than during GVN as the
// presence of the bitop can change which instructions are truncated.
for (size_t i = 0; i < bitops.length(); i++) {
MBinaryBitwiseInstruction* ins = bitops[i];
if (ins->isRecoveredOnBailout())
continue;
MDefinition* folded = ins->foldUnnecessaryBitop();
if (folded != ins) {
ins->replaceAllLiveUsesWith(folded);
@@ -3159,9 +3173,11 @@ RangeAnalysis::truncate()
}
}
bitops.clear();
return true;
}
///////////////////////////////////////////////////////////////////////////////
// Collect Range information of operands
///////////////////////////////////////////////////////////////////////////////
+2
View File
@@ -95,6 +95,7 @@ class RangeAnalysis
protected:
MIRGenerator* mir;
MIRGraph& graph_;
Vector<MBinaryBitwiseInstruction*, 16, SystemAllocPolicy> bitops;
TempAllocator& alloc() const;
@@ -108,6 +109,7 @@ class RangeAnalysis
bool prepareForUCE(bool* shouldRemoveDeadCode);
bool tryRemovingGuards();
bool truncate();
bool removeUnnecessaryBitops();
// Any iteration bounds discovered for loops in the graph.
LoopIterationBoundVector loopIterationBounds;
+3 -3
View File
@@ -91,7 +91,7 @@ BEGIN_TEST(testJitDCEinGVN_phi)
thenBlock1->add(c3);
y->addInputSlow(c3);
thenBlock1->end(MGoto::New(func.alloc, joinBlock));
joinBlock->addPredecessor(func.alloc, thenBlock1);
MOZ_ALWAYS_TRUE(joinBlock->addPredecessor(func.alloc, thenBlock1));
// } else if (q) {
MParameter* q = func.createParameter();
@@ -107,7 +107,7 @@ BEGIN_TEST(testJitDCEinGVN_phi)
thenBlock2->add(c4);
y->addInputSlow(c4);
thenBlock2->end(MGoto::New(func.alloc, joinBlock));
joinBlock->addPredecessor(func.alloc, thenBlock2);
MOZ_ALWAYS_TRUE(joinBlock->addPredecessor(func.alloc, thenBlock2));
// } else {
// x = 1.0
@@ -118,7 +118,7 @@ BEGIN_TEST(testJitDCEinGVN_phi)
elseBlock->add(c5);
y->addInputSlow(c5);
elseBlock->end(MGoto::New(func.alloc, joinBlock));
joinBlock->addPredecessor(func.alloc, elseBlock);
MOZ_ALWAYS_TRUE(joinBlock->addPredecessor(func.alloc, elseBlock));
// x = phi(1.0, 2.0, 1.0)
// y = phi(3.0, 4.0, 5.0)
+2 -2
View File
@@ -156,7 +156,7 @@ BEGIN_TEST(testJitNotTest)
MReturn* ret = MReturn::New(func.alloc, p);
exit->end(ret);
exit->addPredecessorWithoutPhis(then);
MOZ_ALWAYS_TRUE(exit->addPredecessorWithoutPhis(then));
if (!func.runGVN())
return false;
@@ -195,7 +195,7 @@ BEGIN_TEST(testJitNotNotTest)
MReturn* ret = MReturn::New(func.alloc, p);
exit->end(ret);
exit->addPredecessorWithoutPhis(then);
MOZ_ALWAYS_TRUE(exit->addPredecessorWithoutPhis(then));
if (!func.runGVN())
return false;
+11 -11
View File
@@ -68,10 +68,10 @@ BEGIN_TEST(testJitGVN_FixupOSROnlyLoop)
exit->add(u);
exit->end(MReturn::New(func.alloc, u));
innerHeader->addPredecessorWithoutPhis(innerBackedge);
outerHeader->addPredecessorWithoutPhis(outerBackedge);
exit->addPredecessorWithoutPhis(entry);
merge->addPredecessorWithoutPhis(osrEntry);
MOZ_ALWAYS_TRUE(innerHeader->addPredecessorWithoutPhis(innerBackedge));
MOZ_ALWAYS_TRUE(outerHeader->addPredecessorWithoutPhis(outerBackedge));
MOZ_ALWAYS_TRUE(exit->addPredecessorWithoutPhis(entry));
MOZ_ALWAYS_TRUE(merge->addPredecessorWithoutPhis(osrEntry));
outerHeader->setLoopHeader(outerBackedge);
innerHeader->setLoopHeader(innerBackedge);
@@ -160,11 +160,11 @@ BEGIN_TEST(testJitGVN_FixupOSROnlyLoopNested)
exit->add(u);
exit->end(MReturn::New(func.alloc, u));
innerHeader->addPredecessorWithoutPhis(innerBackedge);
middleHeader->addPredecessorWithoutPhis(middleBackedge);
outerHeader->addPredecessorWithoutPhis(outerBackedge);
exit->addPredecessorWithoutPhis(entry);
merge->addPredecessorWithoutPhis(osrEntry);
MOZ_ALWAYS_TRUE(innerHeader->addPredecessorWithoutPhis(innerBackedge));
MOZ_ALWAYS_TRUE(middleHeader->addPredecessorWithoutPhis(middleBackedge));
MOZ_ALWAYS_TRUE(outerHeader->addPredecessorWithoutPhis(outerBackedge));
MOZ_ALWAYS_TRUE(exit->addPredecessorWithoutPhis(entry));
MOZ_ALWAYS_TRUE(merge->addPredecessorWithoutPhis(osrEntry));
outerHeader->setLoopHeader(outerBackedge);
middleHeader->setLoopHeader(middleBackedge);
@@ -269,8 +269,8 @@ BEGIN_TEST(testJitGVN_PinnedPhis)
exit->add(z7);
exit->end(MGoto::New(func.alloc, outerHeader));
innerHeader->addPredecessorWithoutPhis(innerBackedge);
outerHeader->addPredecessorWithoutPhis(exit);
MOZ_ALWAYS_TRUE(innerHeader->addPredecessorWithoutPhis(innerBackedge));
MOZ_ALWAYS_TRUE(outerHeader->addPredecessorWithoutPhis(exit));
outerHeader->setLoopHeader(exit);
innerHeader->setLoopHeader(innerBackedge);
+2 -4
View File
@@ -75,8 +75,7 @@ struct MinimalFunc : MinimalAlloc
{
if (!SplitCriticalEdges(graph))
return false;
if (!RenumberBlocks(graph))
return false;
RenumberBlocks(graph);
if (!BuildDominatorTree(graph))
return false;
if (!BuildPhiReverseMapping(graph))
@@ -93,8 +92,7 @@ struct MinimalFunc : MinimalAlloc
{
if (!SplitCriticalEdges(graph))
return false;
if (!RenumberBlocks(graph))
return false;
RenumberBlocks(graph);
if (!BuildDominatorTree(graph))
return false;
if (!BuildPhiReverseMapping(graph))
+2
View File
@@ -52,6 +52,8 @@
_(Sincos) \
_(RangeAnalysis) \
_(LoopUnrolling) \
_(Sink) \
_(RemoveUnnecessaryBitops) \
_(EffectiveAddressAnalysis) \
_(AlignmentMaskAnalysis) \
_(EliminateDeadCode) \
+71
View File
@@ -51,6 +51,7 @@
#include "mozilla/Telemetry.h"
#include "nsIURL.h"
#include "nsIConsoleService.h"
#include "mozilla/BinarySearch.h"
#include <algorithm>
@@ -2716,6 +2717,56 @@ HttpBaseChannel::ShouldRewriteRedirectToGET(uint32_t httpStatus,
return false;
}
static
bool IsHeaderBlacklistedForRedirectCopy(nsHttpAtom const& aHeader)
{
// IMPORTANT: keep this list ASCII-code sorted
static nsHttpAtom const* blackList[] = {
&nsHttp::Accept,
&nsHttp::Accept_Encoding,
&nsHttp::Accept_Language,
&nsHttp::Authentication,
&nsHttp::Authorization,
&nsHttp::Connection,
&nsHttp::Content_Length,
&nsHttp::Cookie,
&nsHttp::Host,
&nsHttp::If,
&nsHttp::If_Match,
&nsHttp::If_Modified_Since,
&nsHttp::If_None_Match,
&nsHttp::If_None_Match_Any,
&nsHttp::If_Range,
&nsHttp::If_Unmodified_Since,
&nsHttp::Proxy_Authenticate,
&nsHttp::Proxy_Authorization,
&nsHttp::Range,
&nsHttp::TE,
&nsHttp::Transfer_Encoding,
&nsHttp::Upgrade,
&nsHttp::User_Agent,
&nsHttp::WWW_Authenticate
};
class HttpAtomComparator
{
nsHttpAtom const& mTarget;
public:
explicit HttpAtomComparator(nsHttpAtom const& aTarget)
: mTarget(aTarget) {}
int operator()(nsHttpAtom const* aVal) const {
if (mTarget == *aVal) {
return 0;
}
return strcmp(mTarget._val, aVal->_val);
}
};
size_t unused;
return BinarySearchIf(blackList, 0, ArrayLength(blackList),
HttpAtomComparator(aHeader), &unused);
}
nsresult
HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
nsIChannel *newChannel,
@@ -2850,6 +2901,9 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
}
}
// share the scheduling context - see bug 1236650
httpChannel->SetSchedulingContextID(mSchedulingContextID);
if (httpInternal) {
// Convey third party cookie and spdy flags.
httpInternal->SetThirdPartyFlags(mThirdPartyFlags);
@@ -2950,6 +3004,23 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
}
}
if (redirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
nsIChannelEventSink::REDIRECT_STS_UPGRADE)) {
// Copy non-origin related headers to the new channel.
nsHttpHeaderArray& requestHeaders = mRequestHead.Headers();
uint32_t requestHeaderCount = requestHeaders.Count();
for (uint32_t i = 0; i < requestHeaderCount; ++i) {
nsHttpAtom header;
const char *val = requestHeaders.PeekHeaderAt(i, header);
if (!val || IsHeaderBlacklistedForRedirectCopy(header)) {
continue;
}
httpChannel->SetRequestHeader(nsDependentCString(header.get()),
nsDependentCString(val), false);
}
}
// This channel has been redirected. Don't report timing info.
mTimingEnabled = false;
return NS_OK;
@@ -406,6 +406,10 @@ SandboxBroker::SetSecurityLevelForGMPlugin()
bool
SandboxBroker::AllowReadFile(wchar_t const *file)
{
if (!mPolicy) {
return false;
}
auto result =
mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
sandbox::TargetPolicy::FILES_ALLOW_READONLY,
@@ -416,6 +420,10 @@ SandboxBroker::AllowReadFile(wchar_t const *file)
bool
SandboxBroker::AllowReadWriteFile(wchar_t const *file)
{
if (!mPolicy) {
return false;
}
auto result =
mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
sandbox::TargetPolicy::FILES_ALLOW_ANY,
@@ -426,6 +434,10 @@ SandboxBroker::AllowReadWriteFile(wchar_t const *file)
bool
SandboxBroker::AllowDirectory(wchar_t const *dir)
{
if (!mPolicy) {
return false;
}
auto result =
mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
sandbox::TargetPolicy::FILES_ALLOW_DIR_ANY,
@@ -436,6 +448,10 @@ SandboxBroker::AllowDirectory(wchar_t const *dir)
bool
SandboxBroker::AddTargetPeer(HANDLE aPeerProcess)
{
if (!sBrokerService) {
return false;
}
sandbox::ResultCode result = sBrokerService->AddTargetPeer(aPeerProcess);
return (sandbox::SBOX_ALL_OK == result);
}
@@ -10122,6 +10122,14 @@
"kind": "count",
"description": "Remote JAR protocol usage"
},
"MEDIA_DECODER_BACKEND_USED": {
"alert_emails": ["danderson@mozilla.com"],
"bug_numbers": [1259695],
"expires_in_version": "never",
"kind": "enumerated",
"n_values": 10,
"description": "Media decoder backend (0=WMF Software, 1=DXVA2D3D9, 2=DXVA2D3D11)"
},
"PLUGIN_BLOCKED_FOR_STABILITY": {
"alert_emails": ["cpeterson@mozilla.com"],
"expires_in_version": "52",
@@ -10155,5 +10163,12 @@
"n_buckets": 50,
"keyed": true,
"description": "Measures the size of message manager messages by message name"
},
"SANDBOX_BROKER_INITIALIZED": {
"alert_emails": ["bowen@mozilla.com"],
"bug_numbers": [1256992],
"expires_in_version": "55",
"kind": "boolean",
"description": "Result of call to SandboxBroker::Initialize"
}
}
+23 -54
View File
@@ -604,37 +604,15 @@ CanShowProfileManager()
return true;
}
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
static const char*
SandboxTempDirParent()
{
return NS_WIN_LOW_INTEGRITY_TEMP_BASE;
}
#endif
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
static const char*
SandboxTempDirParent()
{
return NS_OS_TEMP_DIR;
}
#endif
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
static already_AddRefed<nsIFile>
GetAndCleanTempDir(const nsAString& aTempDirSuffix)
GetAndCleanTempDir()
{
// Get the directory within which we'll place the
// sandbox-writable temp directory
nsCOMPtr<nsIFile> tempDir;
nsresult rv = NS_GetSpecialDirectory(SandboxTempDirParent(),
getter_AddRefs(tempDir));
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
// Append our profile specific temp name.
rv = tempDir->Append(NS_LITERAL_STRING("Temp-") + aTempDirSuffix);
nsresult rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR,
getter_AddRefs(tempDir));
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
@@ -715,7 +693,7 @@ SetUpSandboxEnvironment()
}
// Get (and clean up if still there) the sandbox-writable temp directory.
nsCOMPtr<nsIFile> tempDir = GetAndCleanTempDir(tempDirSuffix);
nsCOMPtr<nsIFile> tempDir = GetAndCleanTempDir();
if (!tempDir) {
NS_WARNING("Failed to get or clean sandboxed temp directory.");
return;
@@ -737,16 +715,9 @@ CleanUpSandboxEnvironment()
}
#endif
// Get temp directory suffix pref.
nsAdoptingString tempDirSuffix =
Preferences::GetString("security.sandbox.content.tempDirSuffix");
if (tempDirSuffix.IsEmpty()) {
return;
}
// Get and remove the sandbox-writable temp directory.
// This function already warns if the deletion fails.
unused << GetAndCleanTempDir(tempDirSuffix);
unused << GetAndCleanTempDir();
#if defined(NIGHTLY_BUILD)
// Temporary code to clean up the old low integrity temp directories.
@@ -3441,6 +3412,24 @@ XREMain::XRE_mainInit(bool* aExitFlag)
}
#endif
#if defined(MOZ_SANDBOX) && defined(XP_WIN)
bool brokerInitialized = SandboxBroker::Initialize();
Telemetry::Accumulate(Telemetry::SANDBOX_BROKER_INITIALIZED,
brokerInitialized);
if (!brokerInitialized) {
#if defined(MOZ_CONTENT_SANDBOX)
// If we're sandboxing content and we fail to initialize, then crashing here
// seems like the sensible option.
if (BrowserTabsRemoteAutostart()) {
MOZ_CRASH("Failed to initialize broker services, can't continue.");
}
#endif
// Otherwise just warn for the moment, as most things will work.
NS_WARNING("Failed to initialize broker services, sandboxed processes will "
"fail to start.");
}
#endif
#ifdef XP_MACOSX
if (EnvHasValue("MOZ_LAUNCHED_CHILD")) {
// This is needed, on relaunch, to force the OS to use the "Cocoa Dock
@@ -3795,12 +3784,6 @@ XREMain::XRE_mainStartup(bool* aExitFlag)
int result;
#ifdef XP_WIN
UseParentConsole();
#if defined(MOZ_SANDBOX)
if (!SandboxBroker::Initialize()) {
NS_WARNING("Failed to initialize broker services, sandboxed processes "
"will fail to start.");
}
#endif
#endif
// RunGTest will only be set if we're in xul-unit
if (mozilla::RunGTest) {
@@ -4425,20 +4408,6 @@ XREMain::XRE_mainRun()
}
#endif /* MOZ_INSTRUMENT_EVENT_LOOP */
#if defined(MOZ_SANDBOX) && defined(XP_WIN)
if (!SandboxBroker::Initialize()) {
#if defined(MOZ_CONTENT_SANDBOX)
// If we're sandboxing content and we fail to initialize, then crashing here
// seems like the sensible option.
if (BrowserTabsRemoteAutostart()) {
MOZ_CRASH("Failed to initialize broker services, can't continue.");
}
#endif
// Otherwise just warn for the moment, as most things will work.
NS_WARNING("Failed to initialize broker services, sandboxed processes will "
"fail to start.");
}
#endif
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
SetUpSandboxEnvironment();
#endif