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

- Bug 1240411: P6. Clean up OMX headers. r=ayang (114a1df4be)
- Bug 1230385, part 1 - Use MOZ_CRASH in ContentChild::AllocP*() methods. r=billm (6f8016bb29)
- Bug 1230385, part 2 - Use NS_WARNING in unimplemented TabChild methods. r=billm (28a7165773)
- Bug 1234026 - Pass a --display option to gtk_init in content processes. r=karlt (8e3e17858e)
- Bug 1218816 - Remove useless semicolons. Found by coccinelle. r=Ehsan (e029c51e58)
- Bug 1240796 - Implement Uint32x4 <==> Float32x4 conversions. r=sunfish (5a42f571ea)
- Bug 1240796 - Implement unsigned SIMD compares. r=sunfish (93d4979730)
- Bug 1240796 - Implement Uint32x4 extractLane in Ion. r=nbp (b5b7c782b6)
- Bug 1240796 - Add Uint32x4 support to jit-test/lib/simd.js. r=bbouvier (187cbbb1d0)
- Bug 1245547 - Implement RSimdBox for Uint32x4. r=nbp (0186f0355f)
- Bug 1244254 - Move SimdTypeToMIRType into the header. r=nbp (5b15375c4e)
- Bug 1217236 - Block trackers loaded by Flash movies. r=gcp (a1318a33da)
- Bug 1237402 - Allow certain plugins to be loaded in parent process (r=jimm) (e951737778)
- Bug 1172304 - Fix to handle short read in Plugin code. r=johns (625dadd61b)
- Bug 377630 - Preventing filename disclosure, by putting downloaded files in a private directory. r=bz (5aca752a5c)
- Bug 579517 follow-up: Remove NSPR types that crept in (c7cb9ffc11)
- Bug 1245724 - Make plugin network requests bypass service worker interception. r=ehsan (a0b7fab3ee)
- Please enter the commit message for your chang Bug 1244254 - Pass a SimdType to inlineSimd(). r=nbp (6fcacd3c5d)
- Bug 1244254 - Add IonBuilder::unboxSimd(). r=nbp (d5f0922fd9)
- Bug 1244254 - Check SIMD arguments in IonBuilder. r=nbp (832d38940f)
- Bug 1244254 - Replace MaybeSimdUnbox with assertions. r=nbp (9c2ad4a8c5)
- Bug 1244254 - Add SimdType to MSimdBox and MSimdUnbox. r=nbp (74412371f5)
- Bug 1238003 - Part 1: Add BooleanPolicy. r=jandem (79c1716cac)
- Bug 1238003 - Part 2: Use Policy in RegExpMatcher and RegExpTester. r=jandem (a2ef8feec4)
- Bug 1238003 - Part 3: Add test for Policy in RegExpMatcher and RegExpTester. r=jandem (1653bec783)
- Bug 1244254 - Simplify MSimd* constructors. r=nbp (0ab2efcb4c)
- Bug 1244889 - Remove trivial SIMD NewAsmJS factories. r=bbouvier (2f9c41713c)
- Bug 1244828 - Ensure enough ballast space in CallPolicy::adjustInputs. r=bbouvier (d84dae2175)
- Bug 1244828 - Ensure enough ballast space in AllDoublePolicy::adjustInputs. r=bbouvier (361092db86)
- Bug 1245421: Remove dead function CoercesToDouble; r=h4writer (502b9efcee)
This commit is contained in:
2023-09-11 09:34:11 +08:00
parent 75be9ceb09
commit fc9fb8b315
89 changed files with 1441 additions and 634 deletions
+1 -1
View File
@@ -672,7 +672,7 @@ getRoleCB(AtkObject *aAtkObj)
#include "RoleMap.h"
default:
MOZ_CRASH("Unknown role.");
};
}
#undef ROLE
+1 -1
View File
@@ -251,7 +251,7 @@ ia2Accessible::role(long* aRole)
#include "RoleMap.h"
default:
MOZ_CRASH("Unknown role.");
};
}
#undef ROLE
+1 -1
View File
@@ -455,7 +455,7 @@ AccessibleWrap::get_accRole(
#include "RoleMap.h"
default:
MOZ_CRASH("Unknown role.");
};
}
#undef ROLE
+1 -1
View File
@@ -346,7 +346,7 @@ xpcAccessible::GetBounds(int32_t* aX, int32_t* aY,
*aX = rect.x;
*aY = rect.y;
*aWidth = rect.width;
*aHeight = rect.height;;
*aHeight = rect.height;
return NS_OK;
}
+1 -1
View File
@@ -11641,7 +11641,7 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
fireMozStorageChanged = mLocalStorage == changingStorage;
if (fireMozStorageChanged) {
eventType.AssignLiteral("MozLocalStorageChanged");
};
}
break;
}
default:
+13 -8
View File
@@ -1436,7 +1436,7 @@ nsObjectLoadingContent::ObjectState() const
case eFallbackVulnerableNoUpdate:
return NS_EVENT_STATE_VULNERABLE_NO_UPDATE;
}
};
}
NS_NOTREACHED("unknown type?");
return NS_EVENT_STATE_LOADING;
}
@@ -2354,7 +2354,7 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
case eType_Null:
// Handled below, silence compiler warnings
break;
};
}
//
// Loaded, handle notifications and fallback
@@ -3218,12 +3218,17 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason, bool aIgnoreCurrentTyp
sPrefsInitialized = true;
}
if (XRE_IsParentProcess() &&
BrowserTabsRemoteAutostart()) {
// Plugins running OOP from the chrome process along with plugins running
// OOP from the content process will hang. Let's prevent that situation.
aReason = eFallbackDisabled;
return false;
if (BrowserTabsRemoteAutostart()) {
bool shouldLoadInParent = nsPluginHost::ShouldLoadTypeInParent(mContentType);
bool inParent = XRE_IsParentProcess();
if (shouldLoadInParent != inParent) {
// Plugins need to be locked to either the parent process or the content
// process. If a plugin is locked to one process type, it can't be used in
// the other. Otherwise we'll get hangs.
aReason = eFallbackDisabled;
return false;
}
}
RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
+1 -1
View File
@@ -1256,7 +1256,7 @@ MatchByVaryHeader(mozIStorageConnection* aConn,
ErrorResult errorResult;
cachedHeaders->Append(name, value, errorResult);
if (errorResult.Failed()) { return errorResult.StealNSResult(); };
if (errorResult.Failed()) { return errorResult.StealNSResult(); }
}
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+3 -3
View File
@@ -140,7 +140,7 @@ void MurmurHash3_x86_32 ( const void * key, int len,
case 2: k1 ^= tail[1] << 8;
case 1: k1 ^= tail[0];
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
};
}
//----------
// finalization
@@ -233,7 +233,7 @@ void MurmurHash3_x86_128 ( const void * key, const int len,
case 2: k1 ^= tail[ 1] << 8;
case 1: k1 ^= tail[ 0] << 0;
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
};
}
//----------
// finalization
@@ -318,7 +318,7 @@ void MurmurHash3_x64_128 ( const void * key, const int len,
case 2: k1 ^= uint64_t(tail[ 1]) << 8;
case 1: k1 ^= uint64_t(tail[ 0]) << 0;
k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
};
}
//----------
// finalization
+1 -1
View File
@@ -192,7 +192,7 @@ GetDirectoryListingTask::Work()
NS_FAILED(currFile->IsSpecial(&isSpecial))) ||
isLink || isSpecial) {
continue;
};
}
if (NS_WARN_IF(NS_FAILED(currFile->IsFile(&isFile)) ||
NS_FAILED(currFile->IsDirectory(&isDir))) ||
!(isFile || isDir)) {
+31 -12
View File
@@ -617,7 +617,26 @@ ContentChild::Init(MessageLoop* aIOLoop,
IPC::Channel* aChannel)
{
#ifdef MOZ_WIDGET_GTK
gtk_init(nullptr, nullptr);
// We need to pass a display down to gtk_init because it's not going to
// use the one from the environment on its own when deciding which backend
// to use, and when starting under XWayland, it may choose to start with
// the wayland backend instead of the x11 backend.
// The DISPLAY environment variable is normally set by the parent process.
char* display_name = PR_GetEnv("DISPLAY");
if (display_name) {
int argc = 3;
char option_name[] = "--display";
char* argv[] = {
nullptr,
option_name,
display_name,
nullptr
};
char** argvp = argv;
gtk_init(&argc, &argvp);
} else {
gtk_init(nullptr, nullptr);
}
#endif
#ifdef MOZ_WIDGET_QT
@@ -1571,7 +1590,7 @@ ContentChild::AllocPBlobChild(const BlobConstructorParams& aParams)
mozilla::PRemoteSpellcheckEngineChild *
ContentChild::AllocPRemoteSpellcheckEngineChild()
{
NS_NOTREACHED("Default Constructor for PRemoteSpellcheckEngineChild should never be called");
MOZ_CRASH("Default Constructor for PRemoteSpellcheckEngineChild should never be called");
return nullptr;
}
@@ -1598,7 +1617,7 @@ ContentChild::SendPBlobConstructor(PBlobChild* aActor,
PPresentationChild*
ContentChild::AllocPPresentationChild()
{
NS_NOTREACHED("We should never be manually allocating PPresentationChild actors");
MOZ_CRASH("We should never be manually allocating PPresentationChild actors");
return nullptr;
}
@@ -1703,7 +1722,7 @@ ContentChild::SendPIccConstructor(PIccChild* aActor,
PIccChild*
ContentChild::AllocPIccChild(const uint32_t& aServiceId)
{
NS_NOTREACHED("No one should be allocating PIccChild actors");
MOZ_CRASH("No one should be allocating PIccChild actors");
return nullptr;
}
@@ -1759,7 +1778,7 @@ ContentChild::DeallocPDeviceStorageRequestChild(PDeviceStorageRequestChild* aDev
PFileSystemRequestChild*
ContentChild::AllocPFileSystemRequestChild(const FileSystemParams& aParams)
{
NS_NOTREACHED("Should never get here!");
MOZ_CRASH("Should never get here!");
return nullptr;
}
@@ -1784,7 +1803,7 @@ ContentChild::SendPMobileConnectionConstructor(PMobileConnectionChild* aActor,
static_cast<MobileConnectionChild*>(aActor)->AddRef();
return PContentChild::SendPMobileConnectionConstructor(aActor, aClientId);
#else
MOZ_CRASH("No support for mobileconnection on this platform!");;
MOZ_CRASH("No support for mobileconnection on this platform!");
#endif
}
@@ -1792,10 +1811,10 @@ PMobileConnectionChild*
ContentChild::AllocPMobileConnectionChild(const uint32_t& aClientId)
{
#ifdef MOZ_B2G_RIL
NS_NOTREACHED("No one should be allocating PMobileConnectionChild actors");
MOZ_CRASH("No one should be allocating PMobileConnectionChild actors");
return nullptr;
#else
MOZ_CRASH("No support for mobileconnection on this platform!");;
MOZ_CRASH("No support for mobileconnection on this platform!");
#endif
}
@@ -1831,7 +1850,7 @@ ContentChild::AllocPPrintingChild()
// which implements PPrintingChild. Instead, the nsPrintingProxy service is
// requested and instantiated via XPCOM, and the constructor of
// nsPrintingProxy sets up the IPC connection.
NS_NOTREACHED("Should never get here!");
MOZ_CRASH("Should never get here!");
return nullptr;
}
@@ -1850,7 +1869,7 @@ ContentChild::AllocPScreenManagerChild(uint32_t* aNumberOfScreens,
// nsScreenManagerProxy. Instead, the nsScreenManagerProxy
// service is requested and instantiated via XPCOM, and the
// constructor of nsScreenManagerProxy sets up the IPC connection.
NS_NOTREACHED("Should never get here!");
MOZ_CRASH("Should never get here!");
return nullptr;
}
@@ -2006,7 +2025,7 @@ ContentChild::DeallocPMediaChild(media::PMediaChild *aActor)
PStorageChild*
ContentChild::AllocPStorageChild()
{
NS_NOTREACHED("We should never be manually allocating PStorageChild actors");
MOZ_CRASH("We should never be manually allocating PStorageChild actors");
return nullptr;
}
@@ -3018,7 +3037,7 @@ ContentChild::RecvUpdateWindow(const uintptr_t& aChildId)
}
return true;
#else
NS_NOTREACHED("ContentChild::RecvUpdateWindow calls unexpected on this platform.");
MOZ_ASSERT(false, "ContentChild::RecvUpdateWindow calls unexpected on this platform.");
return false;
#endif
}
+9 -9
View File
@@ -866,7 +866,7 @@ TabChild::SetStatus(uint32_t aStatusType, const char16_t* aStatus)
NS_IMETHODIMP
TabChild::GetWebBrowser(nsIWebBrowser** aWebBrowser)
{
NS_NOTREACHED("TabChild::GetWebBrowser not supported in TabChild");
NS_WARNING("TabChild::GetWebBrowser not supported in TabChild");
return NS_ERROR_NOT_IMPLEMENTED;
}
@@ -874,7 +874,7 @@ TabChild::GetWebBrowser(nsIWebBrowser** aWebBrowser)
NS_IMETHODIMP
TabChild::SetWebBrowser(nsIWebBrowser* aWebBrowser)
{
NS_NOTREACHED("TabChild::SetWebBrowser not supported in TabChild");
NS_WARNING("TabChild::SetWebBrowser not supported in TabChild");
return NS_ERROR_NOT_IMPLEMENTED;
}
@@ -889,7 +889,7 @@ TabChild::GetChromeFlags(uint32_t* aChromeFlags)
NS_IMETHODIMP
TabChild::SetChromeFlags(uint32_t aChromeFlags)
{
NS_NOTREACHED("trying to SetChromeFlags from content process?");
NS_WARNING("trying to SetChromeFlags from content process?");
return NS_ERROR_NOT_IMPLEMENTED;
}
@@ -897,7 +897,7 @@ TabChild::SetChromeFlags(uint32_t aChromeFlags)
NS_IMETHODIMP
TabChild::DestroyBrowserWindow()
{
NS_NOTREACHED("TabChild::DestroyBrowserWindow not supported in TabChild");
NS_WARNING("TabChild::DestroyBrowserWindow not supported in TabChild");
return NS_ERROR_NOT_IMPLEMENTED;
}
@@ -905,7 +905,7 @@ TabChild::DestroyBrowserWindow()
NS_IMETHODIMP
TabChild::SizeBrowserTo(int32_t aCX, int32_t aCY)
{
NS_NOTREACHED("TabChild::SizeBrowserTo not supported in TabChild");
NS_WARNING("TabChild::SizeBrowserTo not supported in TabChild");
return NS_ERROR_NOT_IMPLEMENTED;
}
@@ -913,7 +913,7 @@ TabChild::SizeBrowserTo(int32_t aCX, int32_t aCY)
NS_IMETHODIMP
TabChild::ShowAsModal()
{
NS_NOTREACHED("TabChild::ShowAsModal not supported in TabChild");
NS_WARNING("TabChild::ShowAsModal not supported in TabChild");
return NS_ERROR_NOT_IMPLEMENTED;
}
@@ -928,7 +928,7 @@ TabChild::IsWindowModal(bool* aRetVal)
NS_IMETHODIMP
TabChild::ExitModalEventLoop(nsresult aStatus)
{
NS_NOTREACHED("TabChild::ExitModalEventLoop not supported in TabChild");
NS_WARNING("TabChild::ExitModalEventLoop not supported in TabChild");
return NS_ERROR_NOT_IMPLEMENTED;
}
@@ -1000,7 +1000,7 @@ TabChild::SetVisibility(bool aVisibility)
NS_IMETHODIMP
TabChild::GetTitle(char16_t** aTitle)
{
NS_NOTREACHED("TabChild::GetTitle not supported in TabChild");
NS_WARNING("TabChild::GetTitle not supported in TabChild");
return NS_ERROR_NOT_IMPLEMENTED;
}
@@ -1016,7 +1016,7 @@ TabChild::SetTitle(const char16_t* aTitle)
NS_IMETHODIMP
TabChild::GetSiteWindow(void** aSiteWindow)
{
NS_NOTREACHED("TabChild::GetSiteWindow not supported in TabChild");
NS_WARNING("TabChild::GetSiteWindow not supported in TabChild");
return NS_ERROR_NOT_IMPLEMENTED;
}
+1 -1
View File
@@ -1448,7 +1448,7 @@ bool SkeletonState::DecodeFisbone(ogg_packet* aPacket)
}
msgLength--;
msgProbe++;
};
}
if (!mMsgFieldStore.Contains(serialno)) {
mMsgFieldStore.Put(serialno, field.forget());
+8 -8
View File
@@ -78,27 +78,27 @@ public:
~AudioOffloadPlayer();
// Caller retains ownership of "aSource".
virtual void SetSource(const android::sp<MediaSource> &aSource) override;
void SetSource(const android::sp<MediaSource> &aSource) override;
// Start the source if it's not already started and open the GonkAudioSink to
// create an offloaded audio track
virtual status_t Start(bool aSourceAlreadyStarted = false) override;
status_t Start(bool aSourceAlreadyStarted = false) override;
virtual status_t ChangeState(MediaDecoder::PlayState aState) override;
status_t ChangeState(MediaDecoder::PlayState aState) override;
virtual void SetVolume(double aVolume) override;
void SetVolume(double aVolume) override;
virtual int64_t GetMediaTimeUs() override;
int64_t GetMediaTimeUs() override;
// To update progress bar when the element is visible
virtual void SetElementVisibility(bool aIsVisible) override;;
void SetElementVisibility(bool aIsVisible) override;
// Update ready state based on current play state. Not checking data
// availability since offloading is currently done only when whole compressed
// data is available
virtual MediaDecoderOwner::NextFrameStatus GetNextFrameStatus() override;
MediaDecoderOwner::NextFrameStatus GetNextFrameStatus() override;
virtual RefPtr<MediaDecoder::SeekPromise> Seek(SeekTarget aTarget) override;
RefPtr<MediaDecoder::SeekPromise> Seek(SeekTarget aTarget) override;
void TimeUpdate();
+17 -17
View File
@@ -47,28 +47,28 @@ public:
AudioOutput(int aSessionId, int aUid);
virtual ~AudioOutput();
virtual ssize_t FrameSize() const;
virtual status_t GetPosition(uint32_t* aPosition) const;
virtual status_t SetVolume(float aVolume) const;
virtual status_t SetParameters(const String8& aKeyValuePairs);
ssize_t FrameSize() const override;
status_t GetPosition(uint32_t* aPosition) const override;
status_t SetVolume(float aVolume) const override;
status_t SetParameters(const String8& aKeyValuePairs) override;
// Creates an offloaded audio track with the given parameters
// TODO: Try to recycle audio tracks instead of creating new audio tracks
// every time
virtual status_t Open(uint32_t aSampleRate,
int aChannelCount,
audio_channel_mask_t aChannelMask,
audio_format_t aFormat,
AudioCallback aCb,
void* aCookie,
audio_output_flags_t aFlags = AUDIO_OUTPUT_FLAG_NONE,
const audio_offload_info_t* aOffloadInfo = nullptr);
status_t Open(uint32_t aSampleRate,
int aChannelCount,
audio_channel_mask_t aChannelMask,
audio_format_t aFormat,
AudioCallback aCb,
void* aCookie,
audio_output_flags_t aFlags = AUDIO_OUTPUT_FLAG_NONE,
const audio_offload_info_t* aOffloadInfo = nullptr) override;
virtual status_t Start();
virtual void Stop();
virtual void Flush();
virtual void Pause();
virtual void Close();
status_t Start() override;
void Stop() override;
void Flush() override;
void Pause() override;
void Close() override;
private:
static void CallbackWrapper(int aEvent, void* aMe, void* aInfo);
+13 -13
View File
@@ -23,22 +23,22 @@ class MediaOmxCommonDecoder : public MediaDecoder
public:
explicit MediaOmxCommonDecoder(MediaDecoderOwner* aOwner);
virtual void FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
MediaDecoderEventVisibility aEventVisibility) override;
virtual void ChangeState(PlayState aState) override;
virtual void CallSeek(const SeekTarget& aTarget) override;
virtual void SetVolume(double aVolume) override;
virtual int64_t CurrentPosition() override;
virtual MediaDecoderOwner::NextFrameStatus NextFrameStatus() override;
virtual void SetElementVisibility(bool aIsVisible) override;
virtual void SetPlatformCanOffloadAudio(bool aCanOffloadAudio) override;
virtual void AddOutputStream(ProcessedMediaStream* aStream,
bool aFinishWhenEnded) override;
virtual void SetPlaybackRate(double aPlaybackRate) override;
void FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
MediaDecoderEventVisibility aEventVisibility) override;
void ChangeState(PlayState aState) override;
void CallSeek(const SeekTarget& aTarget) override;
void SetVolume(double aVolume) override;
int64_t CurrentPosition() override;
MediaDecoderOwner::NextFrameStatus NextFrameStatus() override;
void SetElementVisibility(bool aIsVisible) override;
void SetPlatformCanOffloadAudio(bool aCanOffloadAudio) override;
void AddOutputStream(ProcessedMediaStream* aStream,
bool aFinishWhenEnded) override;
void SetPlaybackRate(double aPlaybackRate) override;
void AudioOffloadTearDown();
virtual MediaDecoderStateMachine* CreateStateMachine() override;
MediaDecoderStateMachine* CreateStateMachine() override;
virtual MediaOmxCommonReader* CreateReader() = 0;
virtual MediaDecoderStateMachine* CreateStateMachineFromReader(MediaOmxCommonReader* aReader) = 0;
+11 -12
View File
@@ -71,30 +71,29 @@ public:
~MediaOmxReader();
protected:
virtual void NotifyDataArrivedInternal() override;
void NotifyDataArrivedInternal() override;
public:
virtual nsresult ResetDecode()
nsresult ResetDecode() override
{
mSeekRequest.DisconnectIfExists();
mSeekPromise.RejectIfExists(NS_OK, __func__);
return MediaDecoderReader::ResetDecode();
}
virtual bool DecodeAudioData();
virtual bool DecodeVideoFrame(bool &aKeyframeSkip,
int64_t aTimeThreshold);
bool DecodeAudioData() override;
bool DecodeVideoFrame(bool &aKeyframeSkip, int64_t aTimeThreshold) override;
virtual void ReleaseMediaResources();
void ReleaseMediaResources() override;
virtual RefPtr<MediaDecoderReader::MetadataPromise> AsyncReadMetadata() override;
RefPtr<MediaDecoderReader::MetadataPromise> AsyncReadMetadata() override;
virtual RefPtr<SeekPromise>
RefPtr<SeekPromise>
Seek(int64_t aTime, int64_t aEndTime) override;
virtual void SetIdle() override;
void SetIdle() override;
virtual RefPtr<ShutdownPromise> Shutdown() override;
RefPtr<ShutdownPromise> Shutdown() override;
android::sp<android::MediaSource> GetAudioOffloadTrack();
@@ -106,8 +105,8 @@ private:
class ProcessCachedDataTask;
class NotifyDataArrivedRunnable;
virtual bool HasAudio() override { return mHasAudio; }
virtual bool HasVideo() override { return mHasVideo; }
bool HasAudio() override { return mHasAudio; }
bool HasVideo() override { return mHasVideo; }
bool IsShutdown() {
MutexAutoLock lock(mShutdownMutex);
+10 -8
View File
@@ -27,8 +27,16 @@ class MediaStreamSource : public DataSource {
public:
MediaStreamSource(MediaResource* aResource);
virtual status_t initCheck() const;
virtual ssize_t readAt(off64_t offset, void *data, size_t size);
status_t initCheck() const override;
ssize_t readAt(off64_t offset, void *data, size_t size) override;
status_t getSize(off64_t *size) override;
uint32_t flags() override {
return kWantsPrefetching;
}
int64_t Tell();
// Apparently unused.
virtual ssize_t readAt(off_t offset, void *data, size_t size) {
return readAt(static_cast<off64_t>(offset), data, size);
}
@@ -38,12 +46,6 @@ public:
*size = size64;
return status;
}
virtual status_t getSize(off64_t *size);
virtual uint32_t flags() {
return kWantsPrefetching;
}
int64_t Tell();
virtual ~MediaStreamSource();
+6 -6
View File
@@ -51,15 +51,15 @@ public:
void ResourceReserveFailed() override;
// MediaSource
virtual status_t start(MetaData *params = nullptr);
virtual status_t stop();
status_t start(MetaData *params = nullptr) override;
status_t stop() override;
virtual sp<MetaData> getFormat();
sp<MetaData> getFormat() override;
virtual status_t read(
MediaBuffer **buffer, const ReadOptions *options = nullptr);
status_t read(
MediaBuffer **buffer, const ReadOptions *options = nullptr) override;
virtual status_t pause();
status_t pause() override;
protected:
OMXCodecProxy(
+5 -5
View File
@@ -35,14 +35,14 @@ public:
, mBuffer(nullptr)
, mFrameMaxSize(aFrameMaxSize) {}
virtual ~RtspMediaSource() {}
virtual status_t start(MetaData* params = nullptr) override;
virtual status_t stop() override;
virtual sp<MetaData> getFormat() override {
status_t start(MetaData* params = nullptr) override;
status_t stop() override;
sp<MetaData> getFormat() override {
ReentrantMonitorAutoEnter mon(mMonitor);
return mFormat;
}
virtual status_t read(MediaBuffer** buffer,
const ReadOptions* options = nullptr) override ;
status_t read(MediaBuffer** buffer,
const ReadOptions* options = nullptr) override ;
private:
RefPtr<RtspMediaResource> mRtspResource;
sp<MetaData> mFormat;
+4 -4
View File
@@ -25,12 +25,12 @@ namespace mozilla {
class RtspExtractor: public android::MediaExtractor
{
public:
virtual size_t countTracks() final override;
virtual android::sp<android::MediaSource> getTrack(size_t index)
size_t countTracks() final override;
android::sp<android::MediaSource> getTrack(size_t index)
final override;
virtual android::sp<android::MetaData> getTrackMetaData(
android::sp<android::MetaData> getTrackMetaData(
size_t index, uint32_t flag = 0) final override;
virtual uint32_t flags() const final override;
uint32_t flags() const final override;
RtspExtractor(RtspMediaResource* aResource)
: mRtspResource(aResource) {
+4 -4
View File
@@ -17,13 +17,13 @@ public:
explicit RtspMediaCodecDecoder(MediaDecoderOwner* aOwner)
: MediaOmxCommonDecoder(aOwner) {}
virtual MediaDecoder* Clone(MediaDecoderOwner* aOwner) override;
MediaDecoder* Clone(MediaDecoderOwner* aOwner) override;
virtual MediaOmxCommonReader* CreateReader() override;
MediaOmxCommonReader* CreateReader() override;
virtual MediaDecoderStateMachine* CreateStateMachineFromReader(MediaOmxCommonReader* aReader) override;
MediaDecoderStateMachine* CreateStateMachineFromReader(MediaOmxCommonReader* aReader) override;
virtual void ChangeState(PlayState aState) override;
void ChangeState(PlayState aState) override;
};
} // namespace mozilla
+3 -3
View File
@@ -29,9 +29,9 @@ public:
MOZ_COUNT_DTOR(RtspOmxDecoder);
}
virtual MediaDecoder* Clone(MediaDecoderOwner* aOwner) override final;
virtual MediaDecoderStateMachine* CreateStateMachine() override final;
virtual void ChangeState(PlayState aState) override final;
MediaDecoder* Clone(MediaDecoderOwner* aOwner) override final;
MediaDecoderStateMachine* CreateStateMachine() override final;
void ChangeState(PlayState aState) override final;
};
} // namespace mozilla
+7 -9
View File
@@ -28,7 +28,7 @@ class RtspOmxReader : public MediaOmxReader
protected:
// Provide a Rtsp extractor.
nsresult InitOmxDecoder() final override;
virtual void EnsureActive() override;
void EnsureActive() override;
public:
RtspOmxReader(AbstractMediaDecoder* aDecoder)
@@ -43,13 +43,12 @@ public:
MOZ_ASSERT(mRtspResource);
}
virtual ~RtspOmxReader() override {
virtual ~RtspOmxReader() {
MOZ_COUNT_DTOR(RtspOmxReader);
}
// Implement a time-based seek instead of byte-based..
virtual RefPtr<SeekPromise>
Seek(int64_t aTime, int64_t aEndTime) final override;
RefPtr<SeekPromise> Seek(int64_t aTime, int64_t aEndTime) final override;
// Override GetBuffered() to do nothing for below reasons:
// 1. Because the Rtsp stream is a/v separated. The buffered data in a/v
@@ -60,16 +59,15 @@ public:
// we returned are not useful for the MediaDecodeStateMachine. Unlike the
// ChannelMediaResource, it has a "cache" that can store the whole streaming
// data so the |GetBuffered| function can retrieve useful time ranges.
virtual media::TimeIntervals GetBuffered() final override {
media::TimeIntervals GetBuffered() final override {
return media::TimeIntervals::Invalid();
}
virtual void SetIdle() override;
void SetIdle() override;
virtual RefPtr<MediaDecoderReader::MetadataPromise> AsyncReadMetadata()
override;
RefPtr<MediaDecoderReader::MetadataPromise> AsyncReadMetadata() override;
virtual void HandleResourceAllocated() override;
void HandleResourceAllocated() override;
private:
// A pointer to RtspMediaResource for calling the Rtsp specific function.
+2 -2
View File
@@ -72,7 +72,7 @@ TCPServerSocketParent::GetAppId()
} else {
return nsIScriptSecurityManager::UNKNOWN_APP_ID;
}
};
}
bool
TCPServerSocketParent::GetInBrowser()
@@ -113,7 +113,7 @@ TCPServerSocketParent::SendCallbackAccept(TCPSocketParent *socket)
}
else {
NS_ERROR("Sending data from PTCPSocketParent was failed.");
};
}
}
else {
NS_ERROR("The member value for NeckoParent is wrong.");
+47 -2
View File
@@ -133,6 +133,7 @@ using mozilla::dom::FakePluginTagInit;
#define kPluginTmpDirName NS_LITERAL_CSTRING("plugtmp")
static const char *kPrefWhitelist = "plugin.allowed_types";
static const char *kPrefLoadInParentPrefix = "plugin.load_in_parent_process.";
static const char *kPrefDisableFullPage = "plugin.disable_full_page_plugin_for_types";
static const char *kPrefJavaMIME = "plugin.java.mime";
@@ -183,6 +184,37 @@ LazyLogModule nsPluginLogging::gPluginLog(PLUGIN_LOG_NAME);
nsIFile *nsPluginHost::sPluginTempDir;
nsPluginHost *nsPluginHost::sInst;
/* to cope with short read */
/* we should probably put this into a global library now that this is the second
time we need this. */
static
int32_t
busy_beaver_PR_Read(PRFileDesc *fd, void * start, int32_t len)
{
int n;
int32_t remaining = len;
while (remaining > 0)
{
n = PR_Read(fd, start, remaining);
if (n < 0)
{
/* may want to repeat if errno == EINTR */
if( (len - remaining) == 0 ) // no octet is ever read
return -1;
break;
}
else
{
remaining -= n;
char *cp = (char *) start;
cp += n;
start = cp;
}
}
return len - remaining;
}
NS_IMPL_ISUPPORTS0(nsInvalidPluginTag)
nsInvalidPluginTag::nsInvalidPluginTag(const char* aFullPath, int64_t aLastModifiedTime)
@@ -2681,6 +2713,14 @@ nsPluginHost::IsTypeWhitelisted(const char *aMimeType)
return IsTypeInList(wrap, whitelist);
}
/* static */ bool
nsPluginHost::ShouldLoadTypeInParent(const nsACString& aMimeType)
{
nsCString prefName(kPrefLoadInParentPrefix);
prefName += aMimeType;
return Preferences::GetBool(prefName.get(), false);
}
void
nsPluginHost::RegisterWithCategoryManager(const nsCString& aMimeType,
nsRegisterType aType)
@@ -2943,7 +2983,9 @@ nsPluginHost::ReadPluginInfo()
// set rv to return an error on goto out
rv = NS_ERROR_FAILURE;
int32_t bread = PR_Read(fd, registry, flen);
// We know how many octes we are supposed to read.
// So let use the busy_beaver_PR_Read version.
int32_t bread = busy_beaver_PR_Read(fd, registry, flen);
PRStatus prrc;
prrc = PR_Close(fd);
@@ -2954,6 +2996,7 @@ nsPluginHost::ReadPluginInfo()
return rv;
}
// short read error, so to speak.
if (flen > bread)
return rv;
@@ -3314,7 +3357,9 @@ nsresult nsPluginHost::NewPluginURLStream(const nsString& aURL,
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
nsIContentPolicy::TYPE_OBJECT_SUBREQUEST,
nullptr, // aLoadGroup
listenerPeer);
listenerPeer,
nsIRequest::LOAD_NORMAL | nsIChannel::LOAD_CLASSIFY_URI |
nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
NS_ENSURE_SUCCESS(rv, rv);
if (doc) {
+5
View File
@@ -190,6 +190,11 @@ public:
// Always returns true if plugin.allowed_types is not set
static bool IsTypeWhitelisted(const char *aType);
// Helper that checks if a plugin of a given MIME type can be loaded by the
// parent process. It checks the plugin.load_in_parent_process.<mime> pref.
// Always returns false if plugin.load_in_parent_process.<mime> is not set.
static bool ShouldLoadTypeInParent(const nsACString& aMimeType);
// checks whether aType is a type we recognize for potential special handling
enum SpecialType { eSpecialType_None,
// Needed to whitelist for async init support
@@ -695,7 +695,8 @@ nsPluginStreamListenerPeer::RequestRead(NPByteRange* rangeList)
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
loadGroup,
callbacks);
callbacks,
nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
}
else {
// in this else branch we really don't know where the load is coming
@@ -709,7 +710,8 @@ nsPluginStreamListenerPeer::RequestRead(NPByteRange* rangeList)
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
loadGroup,
callbacks);
callbacks,
nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
}
if (NS_FAILED(rv))
+1 -1
View File
@@ -135,7 +135,7 @@ BrowserStreamParent::RecvNPN_DestroyStream(const NPReason& reason)
default:
NS_ERROR("Unexpected state");
return false;
};
}
mNPP->mNPNIface->destroystream(mNPP->mNPP, mStream, reason);
return true;
+2 -2
View File
@@ -1179,7 +1179,7 @@ nsHTMLEditor::CollapseSelectionToDeepestNonTableFirstChild(
break;
}
node = child;
};
}
selection->Collapse(node, 0);
}
@@ -2705,7 +2705,7 @@ nsHTMLEditor::SetHTMLBackgroundColor(const nsAString& aColor)
if (NS_FAILED(res)) break;
GetNextSelectedCell(nullptr, getter_AddRefs(cell));
};
}
return res;
}
}
+2 -2
View File
@@ -259,7 +259,7 @@ nsHTMLEditor::GetFirstRow(nsIDOMElement* aTableElement, nsIDOMNode** aRowNode)
NS_ENSURE_SUCCESS(res, res);
tableChild = nextChild;
};
}
// If here, row was not found
return NS_EDITOR_ELEMENT_NOT_FOUND;
}
@@ -360,7 +360,7 @@ nsHTMLEditor::GetLastCellInRow(nsIDOMNode* aRowNode, nsIDOMNode** aCellNode)
NS_ENSURE_SUCCESS(res, res);
rowChild = previousChild;
};
}
if (rowChild)
{
*aCellNode = rowChild.get();
+1 -1
View File
@@ -79,7 +79,7 @@ nsTransactionStack::Clear()
{
while (!mDeque.empty()) {
RefPtr<nsTransactionItem> tx = mType == FOR_UNDO ? Pop() : PopBottom();
};
}
}
void
@@ -186,7 +186,7 @@ nsWebBrowserFind::FindNext(bool* aResult)
if (curItem.get() == startingItem.get()) {
doFind = true; // start looking in frames after this one
}
};
}
if (!mWrapFind) {
// remember where we left off
+1 -1
View File
@@ -143,7 +143,7 @@ gssInit()
libSpec.type = PR_LibSpec_Pathname;
libSpec.value.pathname = verLibNames[i];
lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_GLOBAL);
};
}
#else
+1 -1
View File
@@ -1403,7 +1403,7 @@ gfxFontFamily::CheckForSimpleFamily()
// already checked this family
if (mIsSimpleFamily) {
return;
};
}
uint32_t count = mAvailableFonts.Length();
if (count > 4 || count == 0) {
+1 -1
View File
@@ -1151,7 +1151,7 @@ GetFMBandSettings(FMRadioCountry aCountry) {
default:
MOZ_ASSERT(0);
break;
};
}
return settings;
}
+17 -13
View File
@@ -242,7 +242,7 @@ class FunctionCompiler
return nullptr;
MOZ_ASSERT(IsSimdType(input->type()) && input->type() == type);
MInstruction* ins = MSimdUnaryArith::NewAsmJS(alloc(), input, op, type);
MInstruction* ins = MSimdUnaryArith::New(alloc(), input, op);
curBlock_->add(ins);
return ins;
}
@@ -255,7 +255,7 @@ class FunctionCompiler
MOZ_ASSERT(IsSimdType(lhs->type()) && rhs->type() == lhs->type());
MOZ_ASSERT(lhs->type() == type);
MSimdBinaryArith* ins = MSimdBinaryArith::NewAsmJS(alloc(), lhs, rhs, op, type);
MSimdBinaryArith* ins = MSimdBinaryArith::NewAsmJS(alloc(), lhs, rhs, op);
curBlock_->add(ins);
return ins;
}
@@ -268,7 +268,7 @@ class FunctionCompiler
MOZ_ASSERT(IsSimdType(lhs->type()) && rhs->type() == lhs->type());
MOZ_ASSERT(lhs->type() == type);
MSimdBinaryBitwise* ins = MSimdBinaryBitwise::NewAsmJS(alloc(), lhs, rhs, op, type);
MSimdBinaryBitwise* ins = MSimdBinaryBitwise::NewAsmJS(alloc(), lhs, rhs, op);
curBlock_->add(ins);
return ins;
}
@@ -290,7 +290,8 @@ class FunctionCompiler
if (inDeadCode())
return nullptr;
MSimdSwizzle* ins = MSimdSwizzle::New(alloc(), vector, type, X, Y, Z, W);
MOZ_ASSERT(vector->type() == type);
MSimdSwizzle* ins = MSimdSwizzle::New(alloc(), vector, X, Y, Z, W);
curBlock_->add(ins);
return ins;
}
@@ -301,7 +302,8 @@ class FunctionCompiler
if (inDeadCode())
return nullptr;
MInstruction* ins = MSimdShuffle::New(alloc(), lhs, rhs, type, X, Y, Z, W);
MOZ_ASSERT(lhs->type() == type);
MInstruction* ins = MSimdShuffle::New(alloc(), lhs, rhs, X, Y, Z, W);
curBlock_->add(ins);
return ins;
}
@@ -312,8 +314,8 @@ class FunctionCompiler
return nullptr;
MOZ_ASSERT(IsSimdType(vec->type()) && vec->type() == type);
MOZ_ASSERT(!IsSimdType(val->type()));
MSimdInsertElement* ins = MSimdInsertElement::NewAsmJS(alloc(), vec, val, type, lane);
MOZ_ASSERT(SimdTypeToLaneArgumentType(vec->type()) == val->type());
MSimdInsertElement* ins = MSimdInsertElement::New(alloc(), vec, val, lane);
curBlock_->add(ins);
return ins;
}
@@ -326,7 +328,7 @@ class FunctionCompiler
MOZ_ASSERT(IsSimdType(mask->type()));
MOZ_ASSERT(IsSimdType(lhs->type()) && rhs->type() == lhs->type());
MOZ_ASSERT(lhs->type() == type);
MSimdSelect* ins = MSimdSelect::NewAsmJS(alloc(), mask, lhs, rhs, type);
MSimdSelect* ins = MSimdSelect::New(alloc(), mask, lhs, rhs);
curBlock_->add(ins);
return ins;
}
@@ -336,7 +338,7 @@ class FunctionCompiler
if (inDeadCode())
return nullptr;
MSimdAllTrue* ins = MSimdAllTrue::NewAsmJS(alloc(), boolVector);
MSimdAllTrue* ins = MSimdAllTrue::New(alloc(), boolVector, MIRType_Int32);
curBlock_->add(ins);
return ins;
}
@@ -346,7 +348,7 @@ class FunctionCompiler
if (inDeadCode())
return nullptr;
MSimdAnyTrue* ins = MSimdAnyTrue::NewAsmJS(alloc(), boolVector);
MSimdAnyTrue* ins = MSimdAnyTrue::New(alloc(), boolVector, MIRType_Int32);
curBlock_->add(ins);
return ins;
}
@@ -357,8 +359,9 @@ class FunctionCompiler
if (inDeadCode())
return nullptr;
MOZ_ASSERT(vec->type() == from);
MOZ_ASSERT(IsSimdType(from) && IsSimdType(to) && from != to);
T* ins = T::NewAsmJS(alloc(), vec, from, to);
T* ins = T::NewAsmJS(alloc(), vec, to);
curBlock_->add(ins);
return ins;
}
@@ -369,7 +372,8 @@ class FunctionCompiler
return nullptr;
MOZ_ASSERT(IsSimdType(type));
MSimdSplatX4* ins = MSimdSplatX4::NewAsmJS(alloc(), v, type);
MOZ_ASSERT(SimdTypeToLaneArgumentType(type) == v->type());
MSimdSplatX4* ins = MSimdSplatX4::New(alloc(), v, type);
curBlock_->add(ins);
return ins;
}
@@ -620,7 +624,7 @@ class FunctionCompiler
return nullptr;
MOZ_ASSERT(IsSimdType(type));
T* ins = T::NewAsmJS(alloc(), type, x, y, z, w);
T* ins = T::New(alloc(), type, x, y, z, w);
curBlock_->add(ins);
return ins;
}
+31
View File
@@ -872,6 +872,37 @@ GetBooleanSimdType(SimdType t)
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Bad SIMD type");
}
// Get the number of lanes in a SIMD type.
inline unsigned
GetSimdLanes(SimdType t)
{
switch(t) {
case SimdType::Int8x16:
case SimdType::Uint8x16:
case SimdType::Bool8x16:
return 16;
case SimdType::Int16x8:
case SimdType::Uint16x8:
case SimdType::Bool16x8:
return 8;
case SimdType::Int32x4:
case SimdType::Uint32x4:
case SimdType::Float32x4:
case SimdType::Bool32x4:
return 4;
case SimdType::Float64x2:
case SimdType::Bool64x2:
return 2;
case SimdType::Count:
break;
}
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Bad SIMD type");
}
// Complete set of SIMD operations.
//
// No SIMD types implement all of these operations.
+19
View File
@@ -34,6 +34,7 @@ function GetType(v) {
var pt = Object.getPrototypeOf(v);
switch (pt) {
case SIMD.Int32x4.prototype: return SIMD.Int32x4;
case SIMD.Uint32x4.prototype: return SIMD.Uint32x4;
case SIMD.Float32x4.prototype: return SIMD.Float32x4;
case SIMD.Bool32x4.prototype: return SIMD.Bool32x4;
}
@@ -60,6 +61,7 @@ function assertEqX4(vec, arr, ...opts) {
}
var Type = GetType(vec);
if (Type === SIMD.Int32x4) {
assertFunc(SIMD.Int32x4.extractLane(vec, 0), arr[0]);
assertFunc(SIMD.Int32x4.extractLane(vec, 1), arr[1]);
@@ -68,6 +70,14 @@ function assertEqX4(vec, arr, ...opts) {
return;
}
if (Type === SIMD.Uint32x4) {
assertFunc(SIMD.Uint32x4.extractLane(vec, 0), arr[0]);
assertFunc(SIMD.Uint32x4.extractLane(vec, 1), arr[1]);
assertFunc(SIMD.Uint32x4.extractLane(vec, 2), arr[2]);
assertFunc(SIMD.Uint32x4.extractLane(vec, 3), arr[3]);
return;
}
if (Type === SIMD.Float32x4) {
assertFunc(SIMD.Float32x4.extractLane(vec, 0), arr[0]);
assertFunc(SIMD.Float32x4.extractLane(vec, 1), arr[1]);
@@ -99,6 +109,15 @@ function simdToArray(vec) {
];
}
if (Type === SIMD.Uint32x4) {
return [
SIMD.Uint32x4.extractLane(vec, 0),
SIMD.Uint32x4.extractLane(vec, 1),
SIMD.Uint32x4.extractLane(vec, 2),
SIMD.Uint32x4.extractLane(vec, 3),
];
}
if (Type === SIMD.Float32x4) {
return [
SIMD.Float32x4.extractLane(vec, 0),
+10
View File
@@ -9,6 +9,9 @@ function f() {
var i1 = SIMD.Int32x4(1, 2, -3, 4);
var i2 = SIMD.Int32x4(1, -2, 3, 0);
var u1 = SIMD.Uint32x4(1, 2, -3, 4);
var u2 = SIMD.Uint32x4(1, -2, 3, 0x80000000);
for (var i = 0; i < 150; i++) {
assertEqX4(SIMD.Int32x4.lessThan(i1, i2), [false, false, true, false]);
assertEqX4(SIMD.Int32x4.lessThanOrEqual(i1, i2), [true, false, true, false]);
@@ -17,6 +20,13 @@ function f() {
assertEqX4(SIMD.Int32x4.greaterThan(i1, i2), [false, true, false, true]);
assertEqX4(SIMD.Int32x4.greaterThanOrEqual(i1, i2), [true, true, false, true]);
assertEqX4(SIMD.Uint32x4.lessThan(u1, u2), [false, true, false, true]);
assertEqX4(SIMD.Uint32x4.lessThanOrEqual(u1, u2), [true, true, false, true]);
assertEqX4(SIMD.Uint32x4.equal(u1, u2), [true, false, false, false]);
assertEqX4(SIMD.Uint32x4.notEqual(u1, u2), [false, true, true, true]);
assertEqX4(SIMD.Uint32x4.greaterThan(u1, u2), [false, false, true, false]);
assertEqX4(SIMD.Uint32x4.greaterThanOrEqual(u1, u2), [true, false, true, false]);
assertEqX4(SIMD.Float32x4.lessThan(f1, f2), [false, true, true, false]);
assertEqX4(SIMD.Float32x4.lessThanOrEqual(f1, f2), [false, true, true, false]);
assertEqX4(SIMD.Float32x4.equal(f1, f2), [false, false, false, false]);
+6
View File
@@ -4,6 +4,7 @@ setJitCompilerOption("ion.warmup.trigger", 50);
function f() {
var i4 = SIMD.Int32x4(1, -2, 3, -4);
var u4 = SIMD.Uint32x4(1, -2, 3, 0x88000000);
var b4 = SIMD.Bool32x4(true, true, false, true);
@@ -19,6 +20,11 @@ function f() {
assertEq(SIMD.Int32x4.extractLane(i4, 2), 3);
assertEq(SIMD.Int32x4.extractLane(i4, 3), -4);
assertEq(SIMD.Uint32x4.extractLane(u4, 0), 1);
assertEq(SIMD.Uint32x4.extractLane(u4, 1), -2 >>> 0);
assertEq(SIMD.Uint32x4.extractLane(u4, 2), 3);
assertEq(SIMD.Uint32x4.extractLane(u4, 3), 0x88000000);
assertEq(SIMD.Float32x4.extractLane(f4, 0), v);
assertEq(SIMD.Float32x4.extractLane(f4, 1), NaN);
assertEq(SIMD.Float32x4.extractLane(f4, 2), Infinity);
+10
View File
@@ -32,6 +32,15 @@ function simdBox_i4(i) {
return 0;
}
var uceFault_simdBox_u4 = eval(uneval(uceFault).replace('uceFault', 'uceFault_simdBox_u4'));
function simdBox_u4(i) {
var a = SIMD.Uint32x4(i, 98 - i, i + 0x7ffffff0, i + 0xffffff00);
if (uceFault_simdBox_u4(i) || uceFault_simdBox_u4(i))
assertEqX4(a, [i, 98 - i, i + 0x7ffffff0, i + 0xffffff00].map(x => x >>> 0));
assertRecoveredOnBailout(a, true);
return 0;
}
var uceFault_simdBox_f4 = eval(uneval(uceFault).replace('uceFault', 'uceFault_simdBox_f4'));
function simdBox_f4(i) {
var a = SIMD.Float32x4(i, i + 0.1, i + 0.2, i + 0.3);
@@ -55,6 +64,7 @@ function simdBox_b4(i) {
for (var i = 0; i < 100; i++) {
simdBox_i4(i);
simdBox_u4(i);
simdBox_f4(i);
simdBox_b4(i);
}
+81
View File
@@ -0,0 +1,81 @@
load(libdir + 'simd.js');
setJitCompilerOption("ion.warmup.trigger", 30);
// Testing Uint32 <-> Float32 conversions.
// These conversions deserve special attention because SSE doesn't provide
// simple conversion instructions.
// Convert an Uint32Array to a Float32Array using scalar conversions.
function cvt_utof_scalar(u32s, f32s) {
assertEq(u32s.length, f32s.length);
for (var i = 0; i < u32s.length; i++) {
f32s[i] = u32s[i];
}
}
// Convert an Uint32Array to a Float32Array using simd conversions.
function cvt_utof_simd(u32s, f32s) {
assertEq(u32s.length, f32s.length);
for (var i = 0; i < u32s.length; i += 4) {
SIMD.Float32x4.store(f32s, i, SIMD.Float32x4.fromUint32x4(SIMD.Uint32x4.load(u32s, i)));
}
}
// Convert a Float32Array to an Uint32Array using scalar conversions.
function cvt_ftou_scalar(f32s, u32s) {
assertEq(f32s.length, u32s.length);
for (var i = 0; i < f32s.length; i++) {
u32s[i] = f32s[i];
}
}
// Convert a Float32Array to an Uint32Array using simd conversions.
function cvt_ftou_simd(f32s, u32s) {
assertEq(f32s.length, u32s.length);
for (var i = 0; i < f32s.length; i += 4) {
SIMD.Uint32x4.store(u32s, i, SIMD.Uint32x4.fromFloat32x4(SIMD.Float32x4.load(f32s, i)));
}
}
function check(a, b) {
assertEq(a.length, b.length);
for (var i = 0; i < a.length; i++) {
assertEq(a[i], b[i]);
}
}
// Uint32x4 --> Float32x4 tests.
var src = new Uint32Array(8000);
var dst1 = new Float32Array(8000);
var dst2 = new Float32Array(8000);
for (var i = 0; i < 2000; i++) {
src[i] = i;
src[i + 2000] = 0x7fffffff - i;
src[i + 4000] = 0x80000000 + i;
src[i + 6000] = 0xffffffff - i;
}
for (var n = 0; n < 10; n++) {
cvt_utof_scalar(src, dst1);
cvt_utof_simd(src, dst2);
check(dst1, dst2);
}
// Float32x4 --> Uint32x4 tests.
var fsrc = dst1;
var fdst1 = new Uint32Array(8000);
var fdst2 = new Uint32Array(8000);
// The 0xffffffff entries in fsrc round to 0x1.0p32f which throws.
// Go as high as 0x0.ffffffp32f.
for (var i = 0; i < 2000; i++) {
fsrc[i + 6000] = 0xffffff7f - i;
}
for (var n = 0; n < 10; n++) {
cvt_ftou_scalar(fsrc, fdst1);
cvt_ftou_simd(fsrc, fdst2);
check(fdst1, fdst2);
}
+15
View File
@@ -0,0 +1,15 @@
function f(str) {
if (typeof str === 'string')
str = new RegExp(str);
for (var i = 0; i < 2000; i++)
str.test('foo');
}
f("abc");
function g(str) {
if (typeof str === 'string')
str = new RegExp(str);
for (var i = 0; i < 2000; i++)
str.exec('foo');
}
g("abc");
+6 -7
View File
@@ -5009,10 +5009,10 @@ CodeGenerator::visitSimdBox(LSimdBox* lir)
InlineTypedObject* templateObject = lir->mir()->templateObject();
gc::InitialHeap initialHeap = lir->mir()->initialHeap();
MIRType type = lir->mir()->input()->type();
registerSimdTemplate(templateObject);
MOZ_ASSERT(lir->safepoint()->liveRegs().has(in),
"Save the input register across the oolCallVM");
registerSimdTemplate(lir->mir()->simdType());
MOZ_ASSERT(lir->safepoint()->liveRegs().has(in), "Save the input register across oolCallVM");
OutOfLineCode* ool = oolCallVM(NewTypedObjectInfo, lir,
ArgList(ImmGCPtr(templateObject), Imm32(initialHeap)),
StoreRegisterTo(object));
@@ -5035,10 +5035,9 @@ CodeGenerator::visitSimdBox(LSimdBox* lir)
}
void
CodeGenerator::registerSimdTemplate(InlineTypedObject* templateObject)
CodeGenerator::registerSimdTemplate(SimdType simdType)
{
simdRefreshTemplatesDuringLink_ |=
1 << uint32_t(templateObject->typeDescr().as<SimdTypeDescr>().type());
simdRefreshTemplatesDuringLink_ |= 1 << uint32_t(simdType);
}
void
@@ -5088,7 +5087,7 @@ CodeGenerator::visitSimdUnbox(LSimdUnbox* lir)
"MOZ_ASSERT(obj->type()->typeDescr()->getReservedSlot(JS_DESCR_SLOT_KIND).isInt32())");
masm.branch32(Assembler::NotEqual, masm.ToPayload(typeDescrKind), Imm32(js::type::Simd), &bail);
SimdType type = MIRTypeToSimdType(lir->mir()->type());
SimdType type = lir->mir()->simdType();
// Check if the SimdTypeDescr /Type/ match the specialization of this
// MSimdUnbox instruction.
+1 -1
View File
@@ -538,7 +538,7 @@ class CodeGenerator : public CodeGeneratorSpecific
// Barriered objects in a bit mask.
uint32_t simdRefreshTemplatesDuringLink_;
void registerSimdTemplate(InlineTypedObject* templateObject);
void registerSimdTemplate(SimdType simdType);
void captureSimdTemplate(JSContext* cx);
};
+12 -11
View File
@@ -16,17 +16,18 @@ namespace jit {
// Do not optimize any Phi instruction which has conflicting Unbox operations,
// as this might imply some intended polymorphism.
static bool
CanUnboxSimdPhi(const JitCompartment* jitCompartment, MPhi* phi, MIRType unboxType)
CanUnboxSimdPhi(const JitCompartment* jitCompartment, MPhi* phi, SimdType unboxType)
{
MOZ_ASSERT(phi->type() == MIRType_Object);
// If we are unboxing, we are more than likely to have boxed this SIMD type
// once in baseline, otherwise, we cannot create a MSimdBox as we have no
// template object to use.
if (!jitCompartment->maybeGetSimdTemplateObjectFor(MIRTypeToSimdType(unboxType)))
if (!jitCompartment->maybeGetSimdTemplateObjectFor(unboxType))
return false;
MResumePoint* entry = phi->block()->entryResumePoint();
MIRType mirType = SimdTypeToMIRType(unboxType);
for (MUseIterator i(phi->usesBegin()), e(phi->usesEnd()); i != e; i++) {
// If we cannot recover the Simd object at the entry of the basic block,
// then we would have to box the content anyways.
@@ -37,7 +38,7 @@ CanUnboxSimdPhi(const JitCompartment* jitCompartment, MPhi* phi, MIRType unboxTy
continue;
MDefinition* def = (*i)->consumer()->toDefinition();
if (def->isSimdUnbox() && def->toSimdUnbox()->type() != unboxType)
if (def->isSimdUnbox() && def->toSimdUnbox()->type() != mirType)
return false;
}
@@ -45,7 +46,7 @@ CanUnboxSimdPhi(const JitCompartment* jitCompartment, MPhi* phi, MIRType unboxTy
}
static void
UnboxSimdPhi(const JitCompartment* jitCompartment, MIRGraph& graph, MPhi* phi, MIRType unboxType)
UnboxSimdPhi(const JitCompartment* jitCompartment, MIRGraph& graph, MPhi* phi, SimdType unboxType)
{
TempAllocator& alloc = graph.alloc();
@@ -58,7 +59,8 @@ UnboxSimdPhi(const JitCompartment* jitCompartment, MIRGraph& graph, MPhi* phi, M
}
// Change the MIRType of the Phi.
phi->setResultType(unboxType);
MIRType mirType = SimdTypeToMIRType(unboxType);
phi->setResultType(mirType);
MBasicBlock* phiBlock = phi->block();
MInstruction* atRecover = phiBlock->safeInsertTop(nullptr, MBasicBlock::IgnoreRecover);
@@ -68,10 +70,9 @@ UnboxSimdPhi(const JitCompartment* jitCompartment, MIRGraph& graph, MPhi* phi, M
MUseIterator i(phi->usesBegin()), e(phi->usesEnd());
// Add a MSimdBox, and replace all the Phi uses with it.
JSObject* templateObject =
jitCompartment->maybeGetSimdTemplateObjectFor(MIRTypeToSimdType(unboxType));
JSObject* templateObject = jitCompartment->maybeGetSimdTemplateObjectFor(unboxType);
InlineTypedObject* inlineTypedObject = &templateObject->as<InlineTypedObject>();
MSimdBox* recoverBox = MSimdBox::New(alloc, nullptr, phi, inlineTypedObject, gc::DefaultHeap);
MSimdBox* recoverBox = MSimdBox::New(alloc, nullptr, phi, inlineTypedObject, unboxType, gc::DefaultHeap);
recoverBox->setRecoveredOnBailout();
phiBlock->insertBefore(atRecover, recoverBox);
@@ -88,7 +89,7 @@ UnboxSimdPhi(const JitCompartment* jitCompartment, MIRGraph& graph, MPhi* phi, M
}
if (!box) {
box = MSimdBox::New(alloc, nullptr, phi, inlineTypedObject, gc::DefaultHeap);
box = MSimdBox::New(alloc, nullptr, phi, inlineTypedObject, unboxType, gc::DefaultHeap);
phiBlock->insertBefore(at, box);
}
@@ -113,10 +114,10 @@ EagerSimdUnbox(MIRGenerator* mir, MIRGraph& graph)
continue;
MPhi* phi = unbox->input()->toPhi();
if (!CanUnboxSimdPhi(jitCompartment, phi, unbox->type()))
if (!CanUnboxSimdPhi(jitCompartment, phi, unbox->simdType()))
continue;
UnboxSimdPhi(jitCompartment, graph, phi, unbox->type());
UnboxSimdPhi(jitCompartment, graph, phi, unbox->simdType());
}
}
+20 -20
View File
@@ -861,41 +861,41 @@ class IonBuilder
// SIMD helpers.
bool canInlineSimd(CallInfo& callInfo, JSNative native, unsigned numArgs,
InlineTypedObject** templateObj);
IonBuilder::InliningStatus boxSimd(CallInfo& callInfo, MInstruction* ins,
MDefinition* unboxSimd(MDefinition* ins, SimdType type);
IonBuilder::InliningStatus boxSimd(CallInfo& callInfo, MDefinition* ins,
InlineTypedObject* templateObj);
MDefinition* convertToBooleanSimdLane(MDefinition* scalar);
InliningStatus inlineSimd(CallInfo& callInfo, JSFunction* target,
MIRType simdType, SimdSign sign = SimdSign::NotApplicable);
InliningStatus inlineSimd(CallInfo& callInfo, JSFunction* target, SimdType type);
template <typename T>
InliningStatus inlineSimdBinary(CallInfo& callInfo, JSNative native,
typename T::Operation op, MIRType mirType);
typename T::Operation op, SimdType type);
InliningStatus inlineSimdShift(CallInfo& callInfo, JSNative native, MSimdShift::Operation op,
SimdType type);
InliningStatus inlineSimdComp(CallInfo& callInfo, JSNative native,
MSimdBinaryComp::Operation op,
MIRType compType, SimdSign sign);
MSimdBinaryComp::Operation op, SimdType type);
InliningStatus inlineSimdUnary(CallInfo& callInfo, JSNative native,
MSimdUnaryArith::Operation op, MIRType mirType);
InliningStatus inlineSimdExtractLane(CallInfo& callInfo, JSNative native,
MIRType vecType, SimdSign sign);
InliningStatus inlineSimdReplaceLane(CallInfo& callInfo, JSNative native, MIRType mirType);
InliningStatus inlineSimdSplat(CallInfo& callInfo, JSNative native, MIRType mirType);
InliningStatus inlineSimdShuffle(CallInfo& callInfo, JSNative native, MIRType type,
unsigned numVectors, unsigned numLanes);
InliningStatus inlineSimdCheck(CallInfo& callInfo, JSNative native, MIRType type);
MSimdUnaryArith::Operation op, SimdType type);
InliningStatus inlineSimdExtractLane(CallInfo& callInfo, JSNative native, SimdType type);
InliningStatus inlineSimdReplaceLane(CallInfo& callInfo, JSNative native, SimdType type);
InliningStatus inlineSimdSplat(CallInfo& callInfo, JSNative native, SimdType type);
InliningStatus inlineSimdShuffle(CallInfo& callInfo, JSNative native, SimdType type,
unsigned numVectors);
InliningStatus inlineSimdCheck(CallInfo& callInfo, JSNative native, SimdType type);
InliningStatus inlineSimdConvert(CallInfo& callInfo, JSNative native, bool isCast,
MIRType from, MIRType to,
SimdSign sign = SimdSign::NotApplicable);
InliningStatus inlineSimdSelect(CallInfo& callInfo, JSNative native, MIRType type);
SimdType from, SimdType to);
InliningStatus inlineSimdSelect(CallInfo& callInfo, JSNative native, SimdType type);
bool prepareForSimdLoadStore(CallInfo& callInfo, Scalar::Type simdType, MInstruction** elements,
MDefinition** index, Scalar::Type* arrayType);
InliningStatus inlineSimdLoad(CallInfo& callInfo, JSNative native, MIRType type,
InliningStatus inlineSimdLoad(CallInfo& callInfo, JSNative native, SimdType type,
unsigned numElems);
InliningStatus inlineSimdStore(CallInfo& callInfo, JSNative native, MIRType type,
InliningStatus inlineSimdStore(CallInfo& callInfo, JSNative native, SimdType type,
unsigned numElems);
InliningStatus inlineSimdAnyAllTrue(CallInfo& callInfo, bool IsAllTrue, JSNative native);
InliningStatus inlineSimdAnyAllTrue(CallInfo& callInfo, bool IsAllTrue, JSNative native,
SimdType type);
// Utility intrinsics.
InliningStatus inlineIsCallable(CallInfo& callInfo);
+1 -1
View File
@@ -1108,7 +1108,7 @@ MarkBailoutFrame(JSTracer* trc, const JitFrameIterator& frame)
if (!snapIter.moreInstructions())
break;
snapIter.nextInstruction();
};
}
}
+33 -6
View File
@@ -4114,7 +4114,7 @@ LIRGenerator::visitSimdUnbox(MSimdUnbox* ins)
break;
default:
MOZ_CRASH("Unexpected SIMD Type.");
};
}
LSimdUnbox* lir = new(alloc()) LSimdUnbox(in, temp());
assignSnapshot(lir, kind);
@@ -4147,12 +4147,28 @@ LIRGenerator::visitSimdConvert(MSimdConvert* ins)
LUse use = useRegister(input);
if (ins->type() == MIRType_Int32x4) {
MOZ_ASSERT(input->type() == MIRType_Float32x4);
LFloat32x4ToInt32x4* lir = new(alloc()) LFloat32x4ToInt32x4(use, temp());
if (!gen->compilingAsmJS())
assignSnapshot(lir, Bailout_BoundsCheck);
define(lir, ins);
switch (ins->signedness()) {
case SimdSign::Signed: {
LFloat32x4ToInt32x4* lir = new(alloc()) LFloat32x4ToInt32x4(use, temp());
if (!gen->compilingAsmJS())
assignSnapshot(lir, Bailout_BoundsCheck);
define(lir, ins);
break;
}
case SimdSign::Unsigned: {
LFloat32x4ToUint32x4* lir =
new (alloc()) LFloat32x4ToUint32x4(use, temp(), temp(LDefinition::INT32X4));
if (!gen->compilingAsmJS())
assignSnapshot(lir, Bailout_BoundsCheck);
define(lir, ins);
break;
}
default:
MOZ_CRASH("Unexpected SimdConvert sign");
}
} else if (ins->type() == MIRType_Float32x4) {
MOZ_ASSERT(input->type() == MIRType_Int32x4);
MOZ_ASSERT(ins->signedness() == SimdSign::Signed, "Unexpected SimdConvert sign");
define(new(alloc()) LInt32x4ToFloat32x4(use), ins);
} else {
MOZ_CRASH("Unknown SIMD kind when generating constant");
@@ -4179,18 +4195,27 @@ LIRGenerator::visitSimdExtractElement(MSimdExtractElement* ins)
switch (ins->input()->type()) {
case MIRType_Int32x4: {
MOZ_ASSERT(ins->signedness() != SimdSign::NotApplicable);
// Note: there could be int16x8 in the future, which doesn't use the
// same instruction. We either need to pass the arity or create new LIns.
LUse use = useRegisterAtStart(ins->input());
define(new(alloc()) LSimdExtractElementI(use), ins);
if (ins->type() == MIRType_Double) {
// Extract an Uint32 lane into a double.
MOZ_ASSERT(ins->signedness() == SimdSign::Unsigned);
define(new (alloc()) LSimdExtractElementU2D(use, temp()), ins);
} else {
define(new (alloc()) LSimdExtractElementI(use), ins);
}
break;
}
case MIRType_Float32x4: {
MOZ_ASSERT(ins->signedness() == SimdSign::NotApplicable);
LUse use = useRegisterAtStart(ins->input());
define(new(alloc()) LSimdExtractElementF(use), ins);
break;
}
case MIRType_Bool32x4: {
MOZ_ASSERT(ins->signedness() == SimdSign::NotApplicable);
LUse use = useRegisterAtStart(ins->input());
define(new(alloc()) LSimdExtractElementB(use), ins);
break;
@@ -4340,9 +4365,11 @@ LIRGenerator::visitSimdBinaryComp(MSimdBinaryComp* ins)
ins->reverse();
if (ins->specialization() == MIRType_Int32x4) {
MOZ_ASSERT(ins->signedness() == SimdSign::Signed);
LSimdBinaryCompIx4* add = new(alloc()) LSimdBinaryCompIx4();
lowerForCompIx4(add, ins, ins->lhs(), ins->rhs());
} else if (ins->specialization() == MIRType_Float32x4) {
MOZ_ASSERT(ins->signedness() == SimdSign::NotApplicable);
LSimdBinaryCompFx4* add = new(alloc()) LSimdBinaryCompFx4();
lowerForCompFx4(add, ins, ins->lhs(), ins->rhs());
} else {
+207 -156
View File
@@ -203,13 +203,13 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target)
// SIMD natives.
case InlinableNative::SimdInt32x4:
return inlineSimd(callInfo, target, MIRType_Int32x4, SimdSign::Signed);
return inlineSimd(callInfo, target, SimdType::Int32x4);
case InlinableNative::SimdUint32x4:
return inlineSimd(callInfo, target, MIRType_Int32x4, SimdSign::Unsigned);
return inlineSimd(callInfo, target, SimdType::Uint32x4);
case InlinableNative::SimdFloat32x4:
return inlineSimd(callInfo, target, MIRType_Float32x4);
return inlineSimd(callInfo, target, SimdType::Float32x4);
case InlinableNative::SimdBool32x4:
return inlineSimd(callInfo, target, MIRType_Bool32x4);
return inlineSimd(callInfo, target, SimdType::Bool32x4);
// Testing functions.
case InlinableNative::TestBailout:
@@ -3070,7 +3070,7 @@ IonBuilder::inlineConstructTypedObject(CallInfo& callInfo, TypeDescr* descr)
// When the controlling simdType is an integer type, sign indicates whether the lanes should
// be treated as signed or unsigned integers.
IonBuilder::InliningStatus
IonBuilder::inlineSimd(CallInfo& callInfo, JSFunction* target, MIRType simdType, SimdSign sign)
IonBuilder::inlineSimd(CallInfo& callInfo, JSFunction* target, SimdType type)
{
if (!JitSupportsSimd()) {
trackOptimizationOutcome(TrackedOutcome::NoSimdJitSupport);
@@ -3082,10 +3082,6 @@ IonBuilder::inlineSimd(CallInfo& callInfo, JSFunction* target, MIRType simdType,
MOZ_ASSERT(jitInfo && jitInfo->type() == JSJitInfo::InlinableNative);
SimdOperation simdOp = SimdOperation(jitInfo->nativeOp);
MOZ_ASSERT(IsSimdType(simdType));
MOZ_ASSERT((sign != SimdSign::NotApplicable) == IsIntegerSimdType(simdType),
"Signedness must be specified for ints, and only for ints");
switch(simdOp) {
case SimdOperation::Constructor:
// SIMD constructor calls are handled via inlineNonFunctionCall(), so
@@ -3093,150 +3089,142 @@ IonBuilder::inlineSimd(CallInfo& callInfo, JSFunction* target, MIRType simdType,
// See also inlineConstructSimdObject().
MOZ_CRASH("SIMD constructor call not expected.");
case SimdOperation::Fn_check:
return inlineSimdCheck(callInfo, native, simdType);
return inlineSimdCheck(callInfo, native, type);
case SimdOperation::Fn_splat:
return inlineSimdSplat(callInfo, native, simdType);
return inlineSimdSplat(callInfo, native, type);
case SimdOperation::Fn_extractLane:
return inlineSimdExtractLane(callInfo, native, simdType, sign);
return inlineSimdExtractLane(callInfo, native, type);
case SimdOperation::Fn_replaceLane:
return inlineSimdReplaceLane(callInfo, native, simdType);
return inlineSimdReplaceLane(callInfo, native, type);
case SimdOperation::Fn_select:
return inlineSimdSelect(callInfo, native, simdType);
return inlineSimdSelect(callInfo, native, type);
case SimdOperation::Fn_swizzle:
return inlineSimdShuffle(callInfo, native, simdType, 1, SimdTypeToLength(simdType));
return inlineSimdShuffle(callInfo, native, type, 1);
case SimdOperation::Fn_shuffle:
return inlineSimdShuffle(callInfo, native, simdType, 2, SimdTypeToLength(simdType));
return inlineSimdShuffle(callInfo, native, type, 2);
// Unary arithmetic.
case SimdOperation::Fn_abs:
return inlineSimdUnary(callInfo, native, MSimdUnaryArith::abs, simdType);
return inlineSimdUnary(callInfo, native, MSimdUnaryArith::abs, type);
case SimdOperation::Fn_neg:
return inlineSimdUnary(callInfo, native, MSimdUnaryArith::neg, simdType);
return inlineSimdUnary(callInfo, native, MSimdUnaryArith::neg, type);
case SimdOperation::Fn_not:
return inlineSimdUnary(callInfo, native, MSimdUnaryArith::not_, simdType);
return inlineSimdUnary(callInfo, native, MSimdUnaryArith::not_, type);
case SimdOperation::Fn_reciprocalApproximation:
return inlineSimdUnary(callInfo, native, MSimdUnaryArith::reciprocalApproximation,
simdType);
type);
case SimdOperation::Fn_reciprocalSqrtApproximation:
return inlineSimdUnary(callInfo, native, MSimdUnaryArith::reciprocalSqrtApproximation,
simdType);
type);
case SimdOperation::Fn_sqrt:
return inlineSimdUnary(callInfo, native, MSimdUnaryArith::sqrt, simdType);
return inlineSimdUnary(callInfo, native, MSimdUnaryArith::sqrt, type);
// Binary arithmetic.
case SimdOperation::Fn_add:
return inlineSimdBinary<MSimdBinaryArith>(callInfo, native, MSimdBinaryArith::Op_add,
simdType);
type);
case SimdOperation::Fn_sub:
return inlineSimdBinary<MSimdBinaryArith>(callInfo, native, MSimdBinaryArith::Op_sub,
simdType);
type);
case SimdOperation::Fn_mul:
return inlineSimdBinary<MSimdBinaryArith>(callInfo, native, MSimdBinaryArith::Op_mul,
simdType);
type);
case SimdOperation::Fn_div:
return inlineSimdBinary<MSimdBinaryArith>(callInfo, native, MSimdBinaryArith::Op_div,
simdType);
type);
case SimdOperation::Fn_max:
return inlineSimdBinary<MSimdBinaryArith>(callInfo, native, MSimdBinaryArith::Op_max,
simdType);
type);
case SimdOperation::Fn_min:
return inlineSimdBinary<MSimdBinaryArith>(callInfo, native, MSimdBinaryArith::Op_min,
simdType);
type);
case SimdOperation::Fn_maxNum:
return inlineSimdBinary<MSimdBinaryArith>(callInfo, native, MSimdBinaryArith::Op_maxNum,
simdType);
type);
case SimdOperation::Fn_minNum:
return inlineSimdBinary<MSimdBinaryArith>(callInfo, native, MSimdBinaryArith::Op_minNum,
simdType);
type);
// Binary bitwise.
case SimdOperation::Fn_and:
return inlineSimdBinary<MSimdBinaryBitwise>(callInfo, native, MSimdBinaryBitwise::and_,
simdType);
type);
case SimdOperation::Fn_or:
return inlineSimdBinary<MSimdBinaryBitwise>(callInfo, native, MSimdBinaryBitwise::or_,
simdType);
type);
case SimdOperation::Fn_xor:
return inlineSimdBinary<MSimdBinaryBitwise>(callInfo, native, MSimdBinaryBitwise::xor_,
simdType);
type);
// Shifts.
case SimdOperation::Fn_shiftLeftByScalar:
return inlineSimdBinary<MSimdShift>(callInfo, native, MSimdShift::lsh, simdType);
return inlineSimdShift(callInfo, native, MSimdShift::lsh, type);
case SimdOperation::Fn_shiftRightByScalar:
return inlineSimdBinary<MSimdShift>(callInfo, native, MSimdShift::rshForSign(sign),
simdType);
return inlineSimdShift(callInfo, native, MSimdShift::rshForSign(GetSimdSign(type)), type);
case SimdOperation::Fn_shiftRightArithmeticByScalar:
return inlineSimdBinary<MSimdShift>(callInfo, native, MSimdShift::rsh, simdType);
return inlineSimdShift(callInfo, native, MSimdShift::rsh, type);
case SimdOperation::Fn_shiftRightLogicalByScalar:
return inlineSimdBinary<MSimdShift>(callInfo, native, MSimdShift::ursh, simdType);
return inlineSimdShift(callInfo, native, MSimdShift::ursh, type);
// Boolean unary.
case SimdOperation::Fn_allTrue:
return inlineSimdAnyAllTrue(callInfo, /* IsAllTrue= */true, native);
return inlineSimdAnyAllTrue(callInfo, /* IsAllTrue= */true, native, type);
case SimdOperation::Fn_anyTrue:
return inlineSimdAnyAllTrue(callInfo, /* IsAllTrue= */false, native);
return inlineSimdAnyAllTrue(callInfo, /* IsAllTrue= */false, native, type);
// Comparisons.
case SimdOperation::Fn_lessThan:
return inlineSimdComp(callInfo, native, MSimdBinaryComp::lessThan,
simdType, sign);
return inlineSimdComp(callInfo, native, MSimdBinaryComp::lessThan, type);
case SimdOperation::Fn_lessThanOrEqual:
return inlineSimdComp(callInfo, native, MSimdBinaryComp::lessThanOrEqual,
simdType, sign);
return inlineSimdComp(callInfo, native, MSimdBinaryComp::lessThanOrEqual, type);
case SimdOperation::Fn_equal:
return inlineSimdComp(callInfo, native, MSimdBinaryComp::equal,
simdType, sign);
return inlineSimdComp(callInfo, native, MSimdBinaryComp::equal, type);
case SimdOperation::Fn_notEqual:
return inlineSimdComp(callInfo, native, MSimdBinaryComp::notEqual,
simdType, sign);
return inlineSimdComp(callInfo, native, MSimdBinaryComp::notEqual, type);
case SimdOperation::Fn_greaterThan:
return inlineSimdComp(callInfo, native, MSimdBinaryComp::greaterThan,
simdType, sign);
return inlineSimdComp(callInfo, native, MSimdBinaryComp::greaterThan, type);
case SimdOperation::Fn_greaterThanOrEqual:
return inlineSimdComp(callInfo, native, MSimdBinaryComp::greaterThanOrEqual,
simdType, sign);
return inlineSimdComp(callInfo, native, MSimdBinaryComp::greaterThanOrEqual, type);
// Int <-> Float conversions.
case SimdOperation::Fn_fromInt32x4:
return inlineSimdConvert(callInfo, native, false, MIRType_Int32x4,
simdType, SimdSign::Signed);
return inlineSimdConvert(callInfo, native, false, SimdType::Int32x4, type);
case SimdOperation::Fn_fromUint32x4:
return inlineSimdConvert(callInfo, native, false, MIRType_Int32x4,
simdType, SimdSign::Unsigned);
return inlineSimdConvert(callInfo, native, false, SimdType::Uint32x4, type);
case SimdOperation::Fn_fromFloat32x4:
return inlineSimdConvert(callInfo, native, false, MIRType_Float32x4, simdType, sign);
return inlineSimdConvert(callInfo, native, false, SimdType::Float32x4, type);
// Load/store.
case SimdOperation::Fn_load:
return inlineSimdLoad(callInfo, native, simdType, SimdTypeToLength(simdType));
return inlineSimdLoad(callInfo, native, type, GetSimdLanes(type));
case SimdOperation::Fn_load1:
return inlineSimdLoad(callInfo, native, simdType, 1);
return inlineSimdLoad(callInfo, native, type, 1);
case SimdOperation::Fn_load2:
return inlineSimdLoad(callInfo, native, simdType, 2);
return inlineSimdLoad(callInfo, native, type, 2);
case SimdOperation::Fn_load3:
return inlineSimdLoad(callInfo, native, simdType, 3);
return inlineSimdLoad(callInfo, native, type, 3);
case SimdOperation::Fn_store:
return inlineSimdStore(callInfo, native, simdType, SimdTypeToLength(simdType));
return inlineSimdStore(callInfo, native, type, GetSimdLanes(type));
case SimdOperation::Fn_store1:
return inlineSimdStore(callInfo, native, simdType, 1);
return inlineSimdStore(callInfo, native, type, 1);
case SimdOperation::Fn_store2:
return inlineSimdStore(callInfo, native, simdType, 2);
return inlineSimdStore(callInfo, native, type, 2);
case SimdOperation::Fn_store3:
return inlineSimdStore(callInfo, native, simdType, 3);
return inlineSimdStore(callInfo, native, type, 3);
// Bitcasts. One for each type with a memory representation.
case SimdOperation::Fn_fromInt8x16Bits:
case SimdOperation::Fn_fromInt16x8Bits:
return InliningStatus_NotInlined;
case SimdOperation::Fn_fromInt32x4Bits:
return inlineSimdConvert(callInfo, native, true, SimdType::Int32x4, type);
case SimdOperation::Fn_fromUint32x4Bits:
return inlineSimdConvert(callInfo, native, true, MIRType_Int32x4, simdType);
return inlineSimdConvert(callInfo, native, true, SimdType::Uint32x4, type);
case SimdOperation::Fn_fromUint8x16Bits:
case SimdOperation::Fn_fromUint16x8Bits:
return InliningStatus_NotInlined;
case SimdOperation::Fn_fromFloat32x4Bits:
return inlineSimdConvert(callInfo, native, true, MIRType_Float32x4, simdType);
return inlineSimdConvert(callInfo, native, true, SimdType::Float32x4, type);
case SimdOperation::Fn_fromFloat64x2Bits:
return InliningStatus_NotInlined;
}
@@ -3275,17 +3263,6 @@ IonBuilder::convertToBooleanSimdLane(MDefinition* scalar)
return result;
}
static inline
bool SimdTypeToMIRType(SimdType type, MIRType* mirType)
{
switch (type) {
case SimdType::Int32x4: *mirType = MIRType_Int32x4; return true;
case SimdType::Float32x4: *mirType = MIRType_Float32x4; return true;
case SimdType::Bool32x4: *mirType = MIRType_Bool32x4; return true;
default: return false;
}
}
IonBuilder::InliningStatus
IonBuilder::inlineConstructSimdObject(CallInfo& callInfo, SimdTypeDescr* descr)
{
@@ -3296,8 +3273,10 @@ IonBuilder::inlineConstructSimdObject(CallInfo& callInfo, SimdTypeDescr* descr)
// Generic constructor of SIMD valuesX4.
MIRType simdType;
if (!SimdTypeToMIRType(descr->type(), &simdType))
if (!MaybeSimdTypeToMIRType(descr->type(), &simdType)) {
trackOptimizationOutcome(TrackedOutcome::SimdTypeNotOptimized);
return InliningStatus_NotInlined;
}
// Take the templateObject out of Baseline ICs, such that we can box
// SIMD value type in the same kind of objects.
@@ -3341,7 +3320,7 @@ IonBuilder::inlineConstructSimdObject(CallInfo& callInfo, SimdTypeDescr* descr)
MSimdValueX4::New(alloc(), simdType, lane[0], lane[1], lane[2], lane[3]);
current->add(values);
MSimdBox* obj = MSimdBox::New(alloc(), constraints(), values, inlineTypedObject,
MSimdBox* obj = MSimdBox::New(alloc(), constraints(), values, inlineTypedObject, descr->type(),
inlineTypedObject->group()->initialHeap(constraints()));
current->add(obj);
current->push(obj);
@@ -3366,26 +3345,66 @@ IonBuilder::canInlineSimd(CallInfo& callInfo, JSNative native, unsigned numArgs,
}
IonBuilder::InliningStatus
IonBuilder::inlineSimdCheck(CallInfo& callInfo, JSNative native, MIRType mirType)
IonBuilder::inlineSimdCheck(CallInfo& callInfo, JSNative native, SimdType type)
{
InlineTypedObject* templateObj = nullptr;
if (!canInlineSimd(callInfo, native, 1, &templateObj))
return InliningStatus_NotInlined;
MSimdUnbox* unbox = MSimdUnbox::New(alloc(), callInfo.getArg(0), mirType);
current->add(unbox);
current->push(callInfo.getArg(0));
// Unboxing checks the SIMD object type and throws a TypeError if it doesn't
// match type.
MDefinition *arg = unboxSimd(callInfo.getArg(0), type);
callInfo.setImplicitlyUsedUnchecked();
return InliningStatus_Inlined;
// Create an unbox/box pair, expecting the box to be optimized away if
// anyone use the return value from this check() call. This is what you want
// for code like this:
//
// function f(x) {
// x = Int32x4.check(x)
// for(...) {
// y = Int32x4.add(x, ...)
// }
//
// The unboxing of x happens as early as possible, and only once.
return boxSimd(callInfo, arg, templateObj);
}
// Given a value or object, insert a dynamic check that this is a SIMD object of
// the required SimdType, and unbox it into the corresponding SIMD MIRType.
//
// This represents the standard type checking that all the SIMD operations
// perform on their arguments.
MDefinition*
IonBuilder::unboxSimd(MDefinition* ins, SimdType type)
{
// Trivial optimization: If ins is a MSimdBox of the same SIMD type, there
// is no way the unboxing could fail, and we can skip it altogether.
// This is the same thing MSimdUnbox::foldsTo() does, but we can save the
// memory allocation here.
if (ins->isSimdBox()) {
MSimdBox* box = ins->toSimdBox();
if (box->simdType() == type) {
MDefinition* value = box->input();
MOZ_ASSERT(value->type() == SimdTypeToMIRType(type));
return value;
}
}
MSimdUnbox* unbox = MSimdUnbox::New(alloc(), ins, type);
current->add(unbox);
return unbox;
}
IonBuilder::InliningStatus
IonBuilder::boxSimd(CallInfo& callInfo, MInstruction* ins, InlineTypedObject* templateObj)
IonBuilder::boxSimd(CallInfo& callInfo, MDefinition* ins, InlineTypedObject* templateObj)
{
MSimdBox* obj = MSimdBox::New(alloc(), constraints(), ins, templateObj,
SimdType simdType = templateObj->typeDescr().as<SimdTypeDescr>().type();
MSimdBox* obj = MSimdBox::New(alloc(), constraints(), ins, templateObj, simdType,
templateObj->group()->initialHeap(constraints()));
current->add(ins);
// In some cases, ins has already been added to current.
if (!ins->block() && ins->isInstruction())
current->add(ins->toInstruction());
current->add(obj);
current->push(obj);
@@ -3393,68 +3412,75 @@ IonBuilder::boxSimd(CallInfo& callInfo, MInstruction* ins, InlineTypedObject* te
return InliningStatus_Inlined;
}
// Inline a binary SIMD operation where both arguments are SIMD types.
template<typename T>
IonBuilder::InliningStatus
IonBuilder::inlineSimdBinary(CallInfo& callInfo, JSNative native, typename T::Operation op,
MIRType mirType)
SimdType type)
{
InlineTypedObject* templateObj = nullptr;
if (!canInlineSimd(callInfo, native, 2, &templateObj))
return InliningStatus_NotInlined;
// If the type of any of the arguments is neither a SIMD type, an Object
// type, or a Value, then the applyTypes phase will add a fallible box &
// unbox sequence. This does not matter much as all binary SIMD
// instructions are supposed to produce a TypeError when they're called
// with non SIMD-arguments.
T* ins = T::New(alloc(), callInfo.getArg(0), callInfo.getArg(1), op, mirType);
MDefinition* lhs = unboxSimd(callInfo.getArg(0), type);
MDefinition* rhs = unboxSimd(callInfo.getArg(1), type);
T* ins = T::New(alloc(), lhs, rhs, op);
return boxSimd(callInfo, ins, templateObj);
}
// Inline a SIMD shiftByScalar operation.
IonBuilder::InliningStatus
IonBuilder::inlineSimdShift(CallInfo& callInfo, JSNative native, MSimdShift::Operation op,
SimdType type)
{
InlineTypedObject* templateObj = nullptr;
if (!canInlineSimd(callInfo, native, 2, &templateObj))
return InliningStatus_NotInlined;
MDefinition* vec = unboxSimd(callInfo.getArg(0), type);
MInstruction* ins = MSimdShift::New(alloc(), vec, callInfo.getArg(1), op);
return boxSimd(callInfo, ins, templateObj);
}
IonBuilder::InliningStatus
IonBuilder::inlineSimdComp(CallInfo& callInfo, JSNative native, MSimdBinaryComp::Operation op,
MIRType mirType, SimdSign sign)
SimdType type)
{
InlineTypedObject* templateObj = nullptr;
if (!canInlineSimd(callInfo, native, 2, &templateObj))
return InliningStatus_NotInlined;
// TODO JSO: Implement unsigned integer comparisons.
if (sign == SimdSign::Unsigned)
return InliningStatus_NotInlined;
// If the type of any of the arguments is neither a SIMD type, an Object
// type, or a Value, then the applyTypes phase will add a fallible box &
// unbox sequence. This does not matter much as all binary SIMD
// instructions are supposed to produce a TypeError when they're called
// with non SIMD-arguments.
MDefinition* lhs = callInfo.getArg(0);
MDefinition* rhs = callInfo.getArg(1);
MSimdBinaryComp* ins = MSimdBinaryComp::New(alloc(), lhs, rhs, op, mirType);
MDefinition* lhs = unboxSimd(callInfo.getArg(0), type);
MDefinition* rhs = unboxSimd(callInfo.getArg(1), type);
MInstruction* ins =
MSimdBinaryComp::AddLegalized(alloc(), current, lhs, rhs, op, GetSimdSign(type));
return boxSimd(callInfo, ins, templateObj);
}
IonBuilder::InliningStatus
IonBuilder::inlineSimdUnary(CallInfo& callInfo, JSNative native, MSimdUnaryArith::Operation op,
MIRType mirType)
SimdType type)
{
InlineTypedObject* templateObj = nullptr;
if (!canInlineSimd(callInfo, native, 1, &templateObj))
return InliningStatus_NotInlined;
// See comment in inlineSimdBinary
MSimdUnaryArith* ins = MSimdUnaryArith::New(alloc(), callInfo.getArg(0), op, mirType);
MDefinition* arg = unboxSimd(callInfo.getArg(0), type);
MSimdUnaryArith* ins = MSimdUnaryArith::New(alloc(), arg, op);
return boxSimd(callInfo, ins, templateObj);
}
IonBuilder::InliningStatus
IonBuilder::inlineSimdSplat(CallInfo& callInfo, JSNative native, MIRType mirType)
IonBuilder::inlineSimdSplat(CallInfo& callInfo, JSNative native, SimdType type)
{
InlineTypedObject* templateObj = nullptr;
if (!canInlineSimd(callInfo, native, 1, &templateObj))
return InliningStatus_NotInlined;
// See comment in inlineSimdBinary
MIRType mirType = SimdTypeToMIRType(type);
MDefinition* arg = callInfo.getArg(0);
// Convert to 0 / -1 before splatting a boolean lane.
@@ -3466,8 +3492,7 @@ IonBuilder::inlineSimdSplat(CallInfo& callInfo, JSNative native, MIRType mirType
}
IonBuilder::InliningStatus
IonBuilder::inlineSimdExtractLane(CallInfo& callInfo, JSNative native,
MIRType vecType, SimdSign sign)
IonBuilder::inlineSimdExtractLane(CallInfo& callInfo, JSNative native, SimdType type)
{
// extractLane() returns a scalar, so don't use canInlineSimd() which looks
// for a template object.
@@ -3476,21 +3501,26 @@ IonBuilder::inlineSimdExtractLane(CallInfo& callInfo, JSNative native,
return InliningStatus_NotInlined;
}
// TODO JSO: Implement unsigned integer lane values.
if (sign == SimdSign::Unsigned)
return InliningStatus_NotInlined;
// Lane index.
MDefinition* arg = callInfo.getArg(1);
if (!arg->isConstantValue() || arg->type() != MIRType_Int32)
return InliningStatus_NotInlined;
int32_t lane = callInfo.getArg(1)->constantValue().toInt32();
int32_t lane = arg->constantValue().toInt32();
if (lane < 0 || lane >= 4)
return InliningStatus_NotInlined;
// See comment in inlineSimdBinary
// Original vector.
MDefinition* orig = unboxSimd(callInfo.getArg(0), type);
MIRType vecType = orig->type();
MIRType laneType = SimdTypeToLaneType(vecType);
MSimdExtractElement* ins = MSimdExtractElement::New(alloc(), callInfo.getArg(0),
vecType, laneType, SimdLane(lane));
SimdSign sign = GetSimdSign(type);
// An Uint32 lane can't be represented in MIRType_Int32. Get it as a double.
if (type == SimdType::Uint32x4)
laneType = MIRType_Double;
MSimdExtractElement* ins =
MSimdExtractElement::New(alloc(), orig, laneType, SimdLane(lane), sign);
current->add(ins);
current->push(ins);
callInfo.setImplicitlyUsedUnchecked();
@@ -3498,12 +3528,13 @@ IonBuilder::inlineSimdExtractLane(CallInfo& callInfo, JSNative native,
}
IonBuilder::InliningStatus
IonBuilder::inlineSimdReplaceLane(CallInfo& callInfo, JSNative native, MIRType mirType)
IonBuilder::inlineSimdReplaceLane(CallInfo& callInfo, JSNative native, SimdType type)
{
InlineTypedObject* templateObj = nullptr;
if (!canInlineSimd(callInfo, native, 3, &templateObj))
return InliningStatus_NotInlined;
// Lane index.
MDefinition* arg = callInfo.getArg(1);
if (!arg->isConstantValue() || arg->type() != MIRType_Int32)
return InliningStatus_NotInlined;
@@ -3512,13 +3543,16 @@ IonBuilder::inlineSimdReplaceLane(CallInfo& callInfo, JSNative native, MIRType m
if (lane < 0 || lane >= 4)
return InliningStatus_NotInlined;
// Original vector.
MDefinition* orig = unboxSimd(callInfo.getArg(0), type);
MIRType vecType = orig->type();
// Convert to 0 / -1 before inserting a boolean lane.
MDefinition* value = callInfo.getArg(2);
if (SimdTypeToLaneType(mirType) == MIRType_Boolean)
if (SimdTypeToLaneType(vecType) == MIRType_Boolean)
value = convertToBooleanSimdLane(value);
MSimdInsertElement* ins =
MSimdInsertElement::New(alloc(), callInfo.getArg(0), value, mirType, SimdLane(lane));
MSimdInsertElement* ins = MSimdInsertElement::New(alloc(), orig, value, SimdLane(lane));
return boxSimd(callInfo, ins, templateObj);
}
@@ -3526,55 +3560,66 @@ IonBuilder::inlineSimdReplaceLane(CallInfo& callInfo, JSNative native, MIRType m
// must be floating point and the other integer. In this case, sign indicates if
// the integer lanes should be treated as signed or unsigned integers.
IonBuilder::InliningStatus
IonBuilder::inlineSimdConvert(CallInfo& callInfo, JSNative native, bool isCast,
MIRType fromType, MIRType toType, SimdSign sign)
IonBuilder::inlineSimdConvert(CallInfo& callInfo, JSNative native, bool isCast, SimdType fromType,
SimdType toType)
{
InlineTypedObject* templateObj = nullptr;
if (!canInlineSimd(callInfo, native, 1, &templateObj))
return InliningStatus_NotInlined;
// TODO JSO: Implement unsigned integer conversions.
if (sign == SimdSign::Unsigned)
return InliningStatus_NotInlined;
MDefinition* arg = unboxSimd(callInfo.getArg(0), fromType);
MIRType mirType = SimdTypeToMIRType(toType);
// See comment in inlineSimdBinary
MInstruction* ins;
if (isCast)
ins = MSimdReinterpretCast::New(alloc(), callInfo.getArg(0), fromType, toType);
else
ins = MSimdConvert::New(alloc(), callInfo.getArg(0), fromType, toType);
if (isCast) {
// Signed/Unsigned doesn't matter for bitcasts.
ins = MSimdReinterpretCast::New(alloc(), arg, mirType);
} else {
// Exactly one of fromType, toType must be an integer type.
SimdSign sign = GetSimdSign(fromType);
if (sign == SimdSign::NotApplicable)
sign = GetSimdSign(toType);
// Possibly expand into multiple instructions.
ins = MSimdConvert::AddLegalized(alloc(), current, arg, mirType, sign);
}
return boxSimd(callInfo, ins, templateObj);
}
IonBuilder::InliningStatus
IonBuilder::inlineSimdSelect(CallInfo& callInfo, JSNative native, MIRType mirType)
IonBuilder::inlineSimdSelect(CallInfo& callInfo, JSNative native, SimdType type)
{
InlineTypedObject* templateObj = nullptr;
if (!canInlineSimd(callInfo, native, 3, &templateObj))
return InliningStatus_NotInlined;
// See comment in inlineSimdBinary
MSimdSelect* ins = MSimdSelect::New(alloc(), callInfo.getArg(0), callInfo.getArg(1),
callInfo.getArg(2), mirType);
MDefinition* mask = unboxSimd(callInfo.getArg(0), GetBooleanSimdType(type));
MDefinition* tval = unboxSimd(callInfo.getArg(1), type);
MDefinition* fval = unboxSimd(callInfo.getArg(2), type);
MSimdSelect* ins = MSimdSelect::New(alloc(), mask, tval, fval);
return boxSimd(callInfo, ins, templateObj);
}
IonBuilder::InliningStatus
IonBuilder::inlineSimdShuffle(CallInfo& callInfo, JSNative native, MIRType mirType,
unsigned numVectors, unsigned numLanes)
IonBuilder::inlineSimdShuffle(CallInfo& callInfo, JSNative native, SimdType type,
unsigned numVectors)
{
unsigned numLanes = GetSimdLanes(type);
InlineTypedObject* templateObj = nullptr;
if (!canInlineSimd(callInfo, native, numVectors + numLanes, &templateObj))
return InliningStatus_NotInlined;
MIRType mirType = SimdTypeToMIRType(type);
MSimdGeneralShuffle* ins = MSimdGeneralShuffle::New(alloc(), numVectors, numLanes, mirType);
if (!ins->init(alloc()))
return InliningStatus_Error;
for (unsigned i = 0; i < numVectors; i++)
ins->setVector(i, callInfo.getArg(i));
ins->setVector(i, unboxSimd(callInfo.getArg(i), type));
for (size_t i = 0; i < numLanes; i++)
ins->setLane(i, callInfo.getArg(numVectors + i));
@@ -3582,7 +3627,8 @@ IonBuilder::inlineSimdShuffle(CallInfo& callInfo, JSNative native, MIRType mirTy
}
IonBuilder::InliningStatus
IonBuilder::inlineSimdAnyAllTrue(CallInfo& callInfo, bool IsAllTrue, JSNative native)
IonBuilder::inlineSimdAnyAllTrue(CallInfo& callInfo, bool IsAllTrue, JSNative native,
SimdType type)
{
// anyTrue() / allTrue() return a scalar, so don't use canInlineSimd() which looks
// for a template object.
@@ -3591,11 +3637,13 @@ IonBuilder::inlineSimdAnyAllTrue(CallInfo& callInfo, bool IsAllTrue, JSNative na
return InliningStatus_NotInlined;
}
MDefinition* arg = unboxSimd(callInfo.getArg(0), type);
MUnaryInstruction* ins;
if (IsAllTrue)
ins = MSimdAllTrue::New(alloc(), callInfo.getArg(0), MIRType_Bool32x4);
ins = MSimdAllTrue::New(alloc(), arg, MIRType_Boolean);
else
ins = MSimdAnyTrue::New(alloc(), callInfo.getArg(0), MIRType_Bool32x4);
ins = MSimdAnyTrue::New(alloc(), arg, MIRType_Boolean);
current->add(ins);
current->push(ins);
@@ -3606,11 +3654,12 @@ IonBuilder::inlineSimdAnyAllTrue(CallInfo& callInfo, bool IsAllTrue, JSNative na
// Get the typed array element type corresponding to the lanes in a SIMD vector type.
// This only applies to SIMD types that can be loaded and stored to a typed array.
static Scalar::Type
SimdTypeToArrayElementType(MIRType type)
SimdTypeToArrayElementType(SimdType type)
{
switch (type) {
case MIRType_Float32x4: return Scalar::Float32x4;
case MIRType_Int32x4: return Scalar::Int32x4;
case SimdType::Float32x4: return Scalar::Float32x4;
case SimdType::Int32x4:
case SimdType::Uint32x4: return Scalar::Int32x4;
default: MOZ_CRASH("unexpected simd type");
}
}
@@ -3660,7 +3709,7 @@ IonBuilder::prepareForSimdLoadStore(CallInfo& callInfo, Scalar::Type simdType, M
}
IonBuilder::InliningStatus
IonBuilder::inlineSimdLoad(CallInfo& callInfo, JSNative native, MIRType type, unsigned numElems)
IonBuilder::inlineSimdLoad(CallInfo& callInfo, JSNative native, SimdType type, unsigned numElems)
{
InlineTypedObject* templateObj = nullptr;
if (!canInlineSimd(callInfo, native, 2, &templateObj))
@@ -3675,14 +3724,14 @@ IonBuilder::inlineSimdLoad(CallInfo& callInfo, JSNative native, MIRType type, un
return InliningStatus_NotInlined;
MLoadUnboxedScalar* load = MLoadUnboxedScalar::New(alloc(), elements, index, arrayType);
load->setResultType(type);
load->setResultType(SimdTypeToMIRType(type));
load->setSimdRead(elemType, numElems);
return boxSimd(callInfo, load, templateObj);
}
IonBuilder::InliningStatus
IonBuilder::inlineSimdStore(CallInfo& callInfo, JSNative native, MIRType type, unsigned numElems)
IonBuilder::inlineSimdStore(CallInfo& callInfo, JSNative native, SimdType type, unsigned numElems)
{
InlineTypedObject* templateObj = nullptr;
if (!canInlineSimd(callInfo, native, 3, &templateObj))
@@ -3696,14 +3745,16 @@ IonBuilder::inlineSimdStore(CallInfo& callInfo, JSNative native, MIRType type, u
if (!prepareForSimdLoadStore(callInfo, elemType, &elements, &index, &arrayType))
return InliningStatus_NotInlined;
MDefinition* valueToWrite = callInfo.getArg(2);
MDefinition* valueToWrite = unboxSimd(callInfo.getArg(2), type);
MStoreUnboxedScalar* store = MStoreUnboxedScalar::New(alloc(), elements, index,
valueToWrite, arrayType,
MStoreUnboxedScalar::TruncateInput);
store->setSimdWrite(elemType, numElems);
current->add(store);
current->push(valueToWrite);
// Produce the original boxed value as our return value.
// This is unlikely to be used, so don't bother reboxing valueToWrite.
current->push(callInfo.getArg(2));
callInfo.setImplicitlyUsedUnchecked();
+145 -4
View File
@@ -994,12 +994,14 @@ MSimdUnbox::foldsTo(TempAllocator& alloc)
MDefinition* in = input();
if (in->isSimdBox()) {
MSimdBox* box = in->toSimdBox();
// If the operand is a MSimdBox, then we just reuse the operand of the
// MSimdBox as long as the type corresponds to what we are supposed to
// unbox.
in = in->toSimdBox()->input();
if (in->type() != type())
in = box->input();
if (box->simdType() != simdType())
return this;
MOZ_ASSERT(in->type() == type());
return in;
}
@@ -1031,10 +1033,149 @@ MSimdGeneralShuffle::foldsTo(TempAllocator& alloc)
}
if (numVectors() == 1)
return MSimdSwizzle::New(alloc, vector(0), type(), lanes[0], lanes[1], lanes[2], lanes[3]);
return MSimdSwizzle::New(alloc, vector(0), lanes[0], lanes[1], lanes[2], lanes[3]);
MOZ_ASSERT(numVectors() == 2);
return MSimdShuffle::New(alloc, vector(0), vector(1), type(), lanes[0], lanes[1], lanes[2], lanes[3]);
return MSimdShuffle::New(alloc, vector(0), vector(1), lanes[0], lanes[1], lanes[2], lanes[3]);
}
MInstruction*
MSimdConvert::AddLegalized(TempAllocator& alloc, MBasicBlock* addTo, MDefinition* obj,
MIRType toType, SimdSign sign)
{
MIRType fromType = obj->type();
if (SupportsUint32x4FloatConversions || sign != SimdSign::Unsigned) {
MInstruction* ins = New(alloc, obj, toType, sign);
addTo->add(ins);
return ins;
}
// This architecture can't do Uint32x4 <-> Float32x4 conversions (Hi SSE!)
MOZ_ASSERT(sign == SimdSign::Unsigned);
if (fromType == MIRType_Int32x4 && toType == MIRType_Float32x4) {
// Converting Uint32x4 -> Float32x4. This algorithm is from LLVM.
//
// Split the input number into high and low parts:
//
// uint32_t hi = x >> 16;
// uint32_t lo = x & 0xffff;
//
// Insert these parts as the low mantissa bits in a float32 number with
// the corresponding exponent:
//
// float fhi = (bits-as-float)(hi | 0x53000000); // 0x1.0p39f + hi*2^16
// float flo = (bits-as-float)(lo | 0x4b000000); // 0x1.0p23f + lo
//
// Subtract the bias from the hi part:
//
// fhi -= (0x1.0p39 + 0x1.0p23) // hi*2^16 - 0x1.0p23
//
// And finally combine:
//
// result = flo + fhi // lo + hi*2^16.
// Compute hi = obj >> 16 (lane-wise unsigned shift).
MInstruction* c16 = MConstant::New(alloc, Int32Value(16));
addTo->add(c16);
MInstruction* hi = MSimdShift::New(alloc, obj, c16, MSimdShift::ursh);
addTo->add(hi);
// Compute lo = obj & 0xffff (lane-wise).
MInstruction* m16 =
MSimdConstant::New(alloc, SimdConstant::SplatX4(0xffff), MIRType_Int32x4);
addTo->add(m16);
MInstruction* lo = MSimdBinaryBitwise::New(alloc, obj, m16, MSimdBinaryBitwise::and_);
addTo->add(lo);
// Mix in the exponents.
MInstruction* exphi =
MSimdConstant::New(alloc, SimdConstant::SplatX4(0x53000000), MIRType_Int32x4);
addTo->add(exphi);
MInstruction* mhi = MSimdBinaryBitwise::New(alloc, hi, exphi, MSimdBinaryBitwise::or_);
addTo->add(mhi);
MInstruction* explo =
MSimdConstant::New(alloc, SimdConstant::SplatX4(0x4b000000), MIRType_Int32x4);
addTo->add(explo);
MInstruction* mlo = MSimdBinaryBitwise::New(alloc, lo, explo, MSimdBinaryBitwise::or_);
addTo->add(mlo);
// Bit-cast both to Float32x4.
MInstruction* fhi = MSimdReinterpretCast::New(alloc, mhi, MIRType_Float32x4);
addTo->add(fhi);
MInstruction* flo = MSimdReinterpretCast::New(alloc, mlo, MIRType_Float32x4);
addTo->add(flo);
// Subtract out the bias: 0x1.0p39f + 0x1.0p23f.
// MSVC doesn't support the hexadecimal float syntax.
const float BiasValue = 549755813888.f + 8388608.f;
MInstruction* bias =
MSimdConstant::New(alloc, SimdConstant::SplatX4(BiasValue), MIRType_Float32x4);
addTo->add(bias);
MInstruction* fhi_debiased =
MSimdBinaryArith::New(alloc, fhi, bias, MSimdBinaryArith::Op_sub);
addTo->add(fhi_debiased);
// Compute the final result.
MInstruction* result =
MSimdBinaryArith::New(alloc, fhi_debiased, flo, MSimdBinaryArith::Op_add);
addTo->add(result);
return result;
}
if (fromType == MIRType_Float32x4 && toType == MIRType_Int32x4) {
// The Float32x4 -> Uint32x4 conversion can throw if the input is out of
// range. This is handled by the LFloat32x4ToUint32x4 expansion.
MInstruction* ins = New(alloc, obj, toType, sign);
addTo->add(ins);
return ins;
}
MOZ_CRASH("Unhandled SIMD type conversion");
}
MInstruction*
MSimdBinaryComp::AddLegalized(TempAllocator& alloc, MBasicBlock* addTo, MDefinition* left,
MDefinition* right, Operation op, SimdSign sign)
{
MOZ_ASSERT(left->type() == right->type());
MIRType opType = left->type();
MOZ_ASSERT(IsSimdType(opType));
bool IsEquality = op == equal || op == notEqual;
if (!SupportsUint32x4Compares && sign == SimdSign::Unsigned && !IsEquality) {
MOZ_ASSERT(opType == MIRType_Int32x4);
// This is an order comparison of Uint32x4 vectors which are not supported on this target.
// Simply offset |left| and |right| by INT_MIN, then do a signed comparison.
MInstruction* bias =
MSimdConstant::New(alloc, SimdConstant::SplatX4(int32_t(0x80000000)), opType);
addTo->add(bias);
// Add the bias.
MInstruction* bleft = MSimdBinaryArith::New(alloc, left, bias, MSimdBinaryArith::Op_add);
addTo->add(bleft);
MInstruction* bright = MSimdBinaryArith::New(alloc, right, bias, MSimdBinaryArith::Op_add);
addTo->add(bright);
// Do the equivalent signed comparison.
MInstruction* result = MSimdBinaryComp::New(alloc, bleft, bright, op, SimdSign::Signed);
addTo->add(result);
return result;
}
if (!SupportsUint32x4Compares && sign == SimdSign::Unsigned && opType == MIRType_Int32x4) {
// The sign doesn't matter for equality tests. Flip it to make the
// backend assertions happy.
MOZ_ASSERT(IsEquality);
sign = SimdSign::Signed;
}
// This is a legal operation already. Just create the instruction requested.
MInstruction* result = MSimdBinaryComp::New(alloc, left, right, op, sign);
addTo->add(result);
return result;
}
template <typename T>
+216 -152
View File
@@ -67,6 +67,34 @@ MIRType MIRTypeFromValue(const js::Value& vp)
return MIRTypeFromValueType(vp.extractNonDoubleType());
}
// If simdType is one of the SIMD types suported by Ion, set mirType to the
// corresponding MIRType, and return true.
//
// If simdType is not suported by Ion, return false.
static inline
bool MaybeSimdTypeToMIRType(SimdType type, MIRType* mirType)
{
switch (type) {
case SimdType::Uint32x4:
case SimdType::Int32x4: *mirType = MIRType_Int32x4; return true;
case SimdType::Float32x4: *mirType = MIRType_Float32x4; return true;
case SimdType::Bool32x4: *mirType = MIRType_Bool32x4; return true;
default: return false;
}
}
// Convert a SimdType to the corresponding MIRType, or crash.
//
// Note that this is not an injective mapping: SimdType has signed and unsigned
// integer types that map to the same MIRType.
static inline
MIRType SimdTypeToMIRType(SimdType type)
{
MIRType ret = MIRType_None;
JS_ALWAYS_TRUE(MaybeSimdTypeToMIRType(type, &ret));
return ret;
}
static inline
SimdType MIRTypeToSimdType(MIRType type)
{
@@ -1410,17 +1438,6 @@ class MSimdValueX4
return new(alloc) MSimdValueX4(type, x, y, z, w);
}
static MSimdValueX4* NewAsmJS(TempAllocator& alloc, MIRType type, MDefinition* x,
MDefinition* y, MDefinition* z, MDefinition* w)
{
mozilla::DebugOnly<MIRType> laneType = SimdTypeToLaneArgumentType(type);
MOZ_ASSERT(laneType == x->type());
MOZ_ASSERT(laneType == y->type());
MOZ_ASSERT(laneType == z->type());
MOZ_ASSERT(laneType == w->type());
return MSimdValueX4::New(alloc, type, x, y, z, w);
}
bool canConsumeFloat32(MUse* use) const override {
return SimdTypeToLaneType(type()) == MIRType_Float32;
}
@@ -1455,12 +1472,6 @@ class MSimdSplatX4
public:
INSTRUCTION_HEADER(SimdSplatX4)
static MSimdSplatX4* NewAsmJS(TempAllocator& alloc, MDefinition* v, MIRType type)
{
MOZ_ASSERT(SimdTypeToLaneArgumentType(type) == v->type());
return new(alloc) MSimdSplatX4(type, v);
}
static MSimdSplatX4* New(TempAllocator& alloc, MDefinition* v, MIRType type)
{
return new(alloc) MSimdSplatX4(type, v);
@@ -1527,10 +1538,20 @@ class MSimdConvert
: public MUnaryInstruction,
public SimdPolicy<0>::Data
{
MSimdConvert(MDefinition* obj, MIRType fromType, MIRType toType)
: MUnaryInstruction(obj)
// When either fromType or toType is an integer vector, should it be treated
// as signed or unsigned. Note that we don't support int-int conversions -
// use MSimdReinterpretCast for that.
SimdSign sign_;
MSimdConvert(MDefinition* obj, MIRType toType, SimdSign sign)
: MUnaryInstruction(obj), sign_(sign)
{
MIRType fromType = obj->type();
MOZ_ASSERT(IsSimdType(fromType));
MOZ_ASSERT(IsSimdType(toType));
// All conversions are int <-> float, so signedness is required.
MOZ_ASSERT(sign != SimdSign::NotApplicable);
setResultType(toType);
specialization_ = fromType; // expects fromType as input
@@ -1543,24 +1564,36 @@ class MSimdConvert
public:
INSTRUCTION_HEADER(SimdConvert)
static MSimdConvert* NewAsmJS(TempAllocator& alloc, MDefinition* obj, MIRType fromType,
MIRType toType)
static MSimdConvert* NewAsmJS(TempAllocator& alloc, MDefinition* obj, MIRType toType)
{
MOZ_ASSERT(IsSimdType(obj->type()) && fromType == obj->type());
return new(alloc) MSimdConvert(obj, fromType, toType);
// AsmJS only has signed integer vectors for now.
return new(alloc) MSimdConvert(obj, toType, SimdSign::Signed);
}
static MSimdConvert* New(TempAllocator& alloc, MDefinition* obj, MIRType fromType,
MIRType toType)
static MSimdConvert* New(TempAllocator& alloc, MDefinition* obj, MIRType toType, SimdSign sign)
{
return new(alloc) MSimdConvert(obj, fromType, toType);
return new(alloc) MSimdConvert(obj, toType, sign);
}
// Create a MSimdConvert instruction and add it to the basic block.
// Possibly create and add an equivalent sequence of instructions instead if
// the current target doesn't support the requested conversion directly.
// Return the inserted MInstruction that computes the converted value.
static MInstruction* AddLegalized(TempAllocator& alloc, MBasicBlock* addTo, MDefinition* obj,
MIRType toType, SimdSign sign);
SimdSign signedness() const {
return sign_;
}
AliasSet getAliasSet() const override {
return AliasSet::None();
}
bool congruentTo(const MDefinition* ins) const override {
return congruentIfOperandsEqual(ins);
if (!congruentIfOperandsEqual(ins))
return false;
const MSimdConvert* other = ins->toSimdConvert();
return sign_ == other->sign_;
}
ALLOW_CLONE(MSimdConvert)
};
@@ -1570,9 +1603,11 @@ class MSimdReinterpretCast
: public MUnaryInstruction,
public SimdPolicy<0>::Data
{
MSimdReinterpretCast(MDefinition* obj, MIRType fromType, MIRType toType)
MSimdReinterpretCast(MDefinition* obj, MIRType toType)
: MUnaryInstruction(obj)
{
MIRType fromType = obj->type();
MOZ_ASSERT(IsSimdType(fromType));
MOZ_ASSERT(IsSimdType(toType));
setMovable();
setResultType(toType);
@@ -1581,17 +1616,14 @@ class MSimdReinterpretCast
public:
INSTRUCTION_HEADER(SimdReinterpretCast)
static MSimdReinterpretCast* NewAsmJS(TempAllocator& alloc, MDefinition* obj, MIRType fromType,
MIRType toType)
static MSimdReinterpretCast* NewAsmJS(TempAllocator& alloc, MDefinition* obj, MIRType toType)
{
MOZ_ASSERT(IsSimdType(obj->type()) && fromType == obj->type());
return new(alloc) MSimdReinterpretCast(obj, fromType, toType);
return new(alloc) MSimdReinterpretCast(obj, toType);
}
static MSimdReinterpretCast* New(TempAllocator& alloc, MDefinition* obj, MIRType fromType,
MIRType toType)
static MSimdReinterpretCast* New(TempAllocator& alloc, MDefinition* obj, MIRType toType)
{
return new(alloc) MSimdReinterpretCast(obj, fromType, toType);
return new(alloc) MSimdReinterpretCast(obj, toType);
}
AliasSet getAliasSet() const override {
@@ -1604,23 +1636,38 @@ class MSimdReinterpretCast
};
// Extracts a lane element from a given vector type, given by its lane symbol.
//
// For integer SIMD types, a SimdSign must be provided so the lane value can be
// converted to a scalar correctly.
class MSimdExtractElement
: public MUnaryInstruction,
public SimdPolicy<0>::Data
{
protected:
SimdLane lane_;
SimdSign sign_;
MSimdExtractElement(MDefinition* obj, MIRType vecType, MIRType laneType, SimdLane lane)
: MUnaryInstruction(obj), lane_(lane)
MSimdExtractElement(MDefinition* obj, MIRType laneType, SimdLane lane, SimdSign sign)
: MUnaryInstruction(obj), lane_(lane), sign_(sign)
{
MIRType vecType = obj->type();
MOZ_ASSERT(IsSimdType(vecType));
MOZ_ASSERT(uint32_t(lane) < SimdTypeToLength(vecType));
MOZ_ASSERT(!IsSimdType(laneType));
MOZ_ASSERT((sign != SimdSign::NotApplicable) == IsIntegerSimdType(vecType),
"Signedness must be specified for integer SIMD extractLanes");
// The resulting type should match the lane type.
// Allow extracting boolean lanes directly into an Int32 (for asm.js).
// Allow extracting Uint32 lanes into a double.
//
// We also allow extracting Uint32 lanes into a MIRType_Int32. This is
// equivalent to extracting the Uint32 lane to a double and then
// applying MTruncateToInt32, but it bypasses the conversion to/from
// double.
MOZ_ASSERT(SimdTypeToLaneType(vecType) == laneType ||
(IsBooleanSimdType(vecType) && laneType == MIRType_Int32));
(IsBooleanSimdType(vecType) && laneType == MIRType_Int32) ||
(vecType == MIRType_Int32x4 && laneType == MIRType_Double &&
sign == SimdSign::Unsigned));
setMovable();
specialization_ = vecType;
@@ -1633,19 +1680,26 @@ class MSimdExtractElement
static MSimdExtractElement* NewAsmJS(TempAllocator& alloc, MDefinition* obj, MIRType type,
SimdLane lane)
{
return new(alloc) MSimdExtractElement(obj, obj->type(), type, lane);
// Only signed integer types in AsmJS so far.
SimdSign sign =
IsIntegerSimdType(obj->type()) ? SimdSign::Signed : SimdSign::NotApplicable;
return new (alloc) MSimdExtractElement(obj, type, lane, sign);
}
static MSimdExtractElement* New(TempAllocator& alloc, MDefinition* obj, MIRType vecType,
MIRType scalarType, SimdLane lane)
static MSimdExtractElement* New(TempAllocator& alloc, MDefinition* obj, MIRType scalarType,
SimdLane lane, SimdSign sign)
{
return new(alloc) MSimdExtractElement(obj, vecType, scalarType, lane);
return new(alloc) MSimdExtractElement(obj, scalarType, lane, sign);
}
SimdLane lane() const {
return lane_;
}
SimdSign signedness() const {
return sign_;
}
AliasSet getAliasSet() const override {
return AliasSet::None();
}
@@ -1653,7 +1707,7 @@ class MSimdExtractElement
if (!ins->isSimdExtractElement())
return false;
const MSimdExtractElement* other = ins->toSimdExtractElement();
if (other->lane_ != lane_)
if (other->lane_ != lane_ || other->sign_ != sign_)
return false;
return congruentIfOperandsEqual(other);
}
@@ -1668,9 +1722,10 @@ class MSimdInsertElement
private:
SimdLane lane_;
MSimdInsertElement(MDefinition* vec, MDefinition* val, MIRType type, SimdLane lane)
MSimdInsertElement(MDefinition* vec, MDefinition* val, SimdLane lane)
: MBinaryInstruction(vec, val), lane_(lane)
{
MIRType type = vec->type();
MOZ_ASSERT(IsSimdType(type));
setMovable();
setResultType(type);
@@ -1679,18 +1734,10 @@ class MSimdInsertElement
public:
INSTRUCTION_HEADER(SimdInsertElement)
static MSimdInsertElement* NewAsmJS(TempAllocator& alloc, MDefinition* vec, MDefinition* val,
MIRType type, SimdLane lane)
{
MOZ_ASSERT(vec->type() == type);
MOZ_ASSERT(SimdTypeToLaneArgumentType(type) == val->type());
return new(alloc) MSimdInsertElement(vec, val, type, lane);
}
static MSimdInsertElement* New(TempAllocator& alloc, MDefinition* vec, MDefinition* val,
MIRType type, SimdLane lane)
SimdLane lane)
{
return new(alloc) MSimdInsertElement(vec, val, type, lane);
return new(alloc) MSimdInsertElement(vec, val, lane);
}
MDefinition* vector() {
@@ -1736,9 +1783,11 @@ class MSimdAllTrue
public SimdPolicy<0>::Data
{
protected:
explicit MSimdAllTrue(MDefinition* obj, MIRType simdType, MIRType result)
explicit MSimdAllTrue(MDefinition* obj, MIRType result)
: MUnaryInstruction(obj)
{
MIRType simdType = obj->type();
MOZ_ASSERT(IsBooleanSimdType(simdType));
MOZ_ASSERT(result == MIRType_Boolean || result == MIRType_Int32);
setResultType(result);
specialization_ = simdType;
@@ -1748,15 +1797,9 @@ class MSimdAllTrue
public:
INSTRUCTION_HEADER(SimdAllTrue)
static MSimdAllTrue* NewAsmJS(TempAllocator& alloc, MDefinition* obj)
{
MOZ_ASSERT(IsSimdType(obj->type()));
return new(alloc) MSimdAllTrue(obj, obj->type(), MIRType_Int32);
}
static MSimdAllTrue* New(TempAllocator& alloc, MDefinition* obj, MIRType type)
{
return new(alloc) MSimdAllTrue(obj, type, MIRType_Boolean);
return new(alloc) MSimdAllTrue(obj, type);
}
AliasSet getAliasSet() const override {
@@ -1774,9 +1817,11 @@ class MSimdAnyTrue
public SimdPolicy<0>::Data
{
protected:
explicit MSimdAnyTrue(MDefinition* obj, MIRType simdType, MIRType result)
explicit MSimdAnyTrue(MDefinition* obj, MIRType result)
: MUnaryInstruction(obj)
{
MIRType simdType = obj->type();
MOZ_ASSERT(IsBooleanSimdType(simdType));
MOZ_ASSERT(result == MIRType_Boolean || result == MIRType_Int32);
setResultType(result);
specialization_ = simdType;
@@ -1786,15 +1831,9 @@ class MSimdAnyTrue
public:
INSTRUCTION_HEADER(SimdAnyTrue)
static MSimdAnyTrue* NewAsmJS(TempAllocator& alloc, MDefinition* obj)
{
MOZ_ASSERT(IsSimdType(obj->type()));
return new(alloc) MSimdAnyTrue(obj, obj->type(), MIRType_Int32);
}
static MSimdAnyTrue* New(TempAllocator& alloc, MDefinition* obj, MIRType type)
{
return new(alloc) MSimdAnyTrue(obj, type, MIRType_Boolean);
return new(alloc) MSimdAnyTrue(obj, type);
}
AliasSet getAliasSet() const override {
@@ -1851,25 +1890,22 @@ class MSimdSwizzle
public NoTypePolicy::Data
{
protected:
MSimdSwizzle(MDefinition* obj, MIRType type,
MSimdSwizzle(MDefinition* obj,
uint32_t laneX, uint32_t laneY, uint32_t laneZ, uint32_t laneW)
: MUnaryInstruction(obj), MSimdShuffleBase(laneX, laneY, laneZ, laneW, type)
: MUnaryInstruction(obj), MSimdShuffleBase(laneX, laneY, laneZ, laneW, obj->type())
{
MOZ_ASSERT(laneX < 4 && laneY < 4 && laneZ < 4 && laneW < 4);
MOZ_ASSERT(IsSimdType(obj->type()));
MOZ_ASSERT(IsSimdType(type));
MOZ_ASSERT(obj->type() == type);
setResultType(type);
setResultType(obj->type());
setMovable();
}
public:
INSTRUCTION_HEADER(SimdSwizzle)
static MSimdSwizzle* New(TempAllocator& alloc, MDefinition* obj, MIRType type,
static MSimdSwizzle* New(TempAllocator& alloc, MDefinition* obj,
uint32_t laneX, uint32_t laneY, uint32_t laneZ, uint32_t laneW)
{
return new(alloc) MSimdSwizzle(obj, type, laneX, laneY, laneZ, laneW);
return new(alloc) MSimdSwizzle(obj, laneX, laneY, laneZ, laneW);
}
bool congruentTo(const MDefinition* ins) const override {
@@ -1973,7 +2009,7 @@ class MSimdShuffle
public MSimdShuffleBase,
public NoTypePolicy::Data
{
MSimdShuffle(MDefinition* lhs, MDefinition* rhs, MIRType type,
MSimdShuffle(MDefinition* lhs, MDefinition* rhs,
uint32_t laneX, uint32_t laneY, uint32_t laneZ, uint32_t laneW)
: MBinaryInstruction(lhs, rhs), MSimdShuffleBase(laneX, laneY, laneZ, laneW, lhs->type())
{
@@ -1981,9 +2017,7 @@ class MSimdShuffle
MOZ_ASSERT(IsSimdType(lhs->type()));
MOZ_ASSERT(IsSimdType(rhs->type()));
MOZ_ASSERT(lhs->type() == rhs->type());
MOZ_ASSERT(IsSimdType(type));
MOZ_ASSERT(lhs->type() == type);
setResultType(type);
setResultType(lhs->type());
setMovable();
}
@@ -1991,8 +2025,7 @@ class MSimdShuffle
INSTRUCTION_HEADER(SimdShuffle)
static MInstruction* New(TempAllocator& alloc, MDefinition* lhs, MDefinition* rhs,
MIRType type, uint32_t laneX, uint32_t laneY, uint32_t laneZ,
uint32_t laneW)
uint32_t laneX, uint32_t laneY, uint32_t laneZ, uint32_t laneW)
{
// Swap operands so that new lanes come from LHS in majority.
// In the balanced case, swap operands if needs be, in order to be able
@@ -2008,9 +2041,9 @@ class MSimdShuffle
// If all lanes come from the same vector, just use swizzle instead.
if (laneX < 4 && laneY < 4 && laneZ < 4 && laneW < 4)
return MSimdSwizzle::New(alloc, lhs, type, laneX, laneY, laneZ, laneW);
return MSimdSwizzle::New(alloc, lhs, laneX, laneY, laneZ, laneW);
return new(alloc) MSimdShuffle(lhs, rhs, type, laneX, laneY, laneZ, laneW);
return new(alloc) MSimdShuffle(lhs, rhs, laneX, laneY, laneZ, laneW);
}
bool congruentTo(const MDefinition* ins) const override {
@@ -2055,9 +2088,11 @@ class MSimdUnaryArith
private:
Operation operation_;
MSimdUnaryArith(MDefinition* def, Operation op, MIRType type)
MSimdUnaryArith(MDefinition* def, Operation op)
: MUnaryInstruction(def), operation_(op)
{
MIRType type = def->type();
MOZ_ASSERT(IsSimdType(type));
MOZ_ASSERT_IF(type == MIRType_Int32x4, op == neg || op == not_);
setResultType(type);
setMovable();
@@ -2066,17 +2101,9 @@ class MSimdUnaryArith
public:
INSTRUCTION_HEADER(SimdUnaryArith)
static MSimdUnaryArith* New(TempAllocator& alloc, MDefinition* def, Operation op, MIRType t)
static MSimdUnaryArith* New(TempAllocator& alloc, MDefinition* def, Operation op)
{
return new(alloc) MSimdUnaryArith(def, op, t);
}
static MSimdUnaryArith* NewAsmJS(TempAllocator& alloc, MDefinition* def,
Operation op, MIRType t)
{
MOZ_ASSERT(IsSimdType(t));
MOZ_ASSERT(def->type() == t);
return new(alloc) MSimdUnaryArith(def, op, t);
return new(alloc) MSimdUnaryArith(def, op);
}
Operation operation() const { return operation_; }
@@ -2095,8 +2122,10 @@ class MSimdUnaryArith
};
// Compares each value of a SIMD vector to each corresponding lane's value of
// another SIMD vector, and returns a int32x4 vector containing the results of
// another SIMD vector, and returns a boolean vector containing the results of
// the comparison: all bits are set to 1 if the comparison is true, 0 otherwise.
// When comparing integer vectors, a SimdSign must be provided to request signed
// or unsigned comparison.
class MSimdBinaryComp
: public MBinaryInstruction,
public SimdAllPolicy::Data
@@ -2119,10 +2148,16 @@ class MSimdBinaryComp
private:
Operation operation_;
SimdSign sign_;
MSimdBinaryComp(MDefinition* left, MDefinition* right, Operation op, MIRType opType)
: MBinaryInstruction(left, right), operation_(op)
MSimdBinaryComp(MDefinition* left, MDefinition* right, Operation op, SimdSign sign)
: MBinaryInstruction(left, right), operation_(op), sign_(sign)
{
MOZ_ASSERT(left->type() == right->type());
MIRType opType = left->type();
MOZ_ASSERT(IsSimdType(opType));
MOZ_ASSERT((sign != SimdSign::NotApplicable) == IsIntegerSimdType(opType),
"Signedness must be specified for integer SIMD compares");
setResultType(MIRType_Bool32x4);
specialization_ = opType;
setMovable();
@@ -2135,22 +2170,31 @@ class MSimdBinaryComp
static MSimdBinaryComp* NewAsmJS(TempAllocator& alloc, MDefinition* left, MDefinition* right,
Operation op)
{
MOZ_ASSERT(IsSimdType(left->type()));
MOZ_ASSERT(left->type() == right->type());
return new(alloc) MSimdBinaryComp(left, right, op, left->type());
// AsmJS only has signed vectors for now.
SimdSign sign =
IsIntegerSimdType(left->type()) ? SimdSign::Signed : SimdSign::NotApplicable;
return new (alloc) MSimdBinaryComp(left, right, op, sign);
}
static MSimdBinaryComp* New(TempAllocator& alloc, MDefinition* left, MDefinition* right,
Operation op, MIRType opType)
Operation op, SimdSign sign)
{
return new(alloc) MSimdBinaryComp(left, right, op, opType);
return new(alloc) MSimdBinaryComp(left, right, op, sign);
}
AliasSet getAliasSet() const override {
// Create a MSimdBinaryComp or an equivalent sequence of instructions
// supported by the current target.
// Add all instructions to the basic block |addTo|.
static MInstruction* AddLegalized(TempAllocator& alloc, MBasicBlock* addTo, MDefinition* left,
MDefinition* right, Operation op, SimdSign sign);
AliasSet getAliasSet() const override
{
return AliasSet::None();
}
Operation operation() const { return operation_; }
SimdSign signedness() const { return sign_; }
MIRType specialization() const { return specialization_; }
// Swap the operands and reverse the comparison predicate.
@@ -2173,7 +2217,8 @@ class MSimdBinaryComp
return false;
const MSimdBinaryComp* other = ins->toSimdBinaryComp();
return specialization_ == other->specialization() &&
operation_ == other->operation();
operation_ == other->operation() &&
sign_ == other->signedness();
}
void printOpcode(GenericPrinter& out) const override;
@@ -2206,9 +2251,11 @@ class MSimdBinaryArith
private:
Operation operation_;
MSimdBinaryArith(MDefinition* left, MDefinition* right, Operation op, MIRType type)
MSimdBinaryArith(MDefinition* left, MDefinition* right, Operation op)
: MBinaryInstruction(left, right), operation_(op)
{
MOZ_ASSERT(left->type() == right->type());
MIRType type = left->type();
MOZ_ASSERT_IF(type == MIRType_Int32x4, op == Op_add || op == Op_sub || op == Op_mul);
MOZ_ASSERT(IsSimdType(type));
setResultType(type);
@@ -2220,17 +2267,15 @@ class MSimdBinaryArith
public:
INSTRUCTION_HEADER(SimdBinaryArith)
static MSimdBinaryArith* New(TempAllocator& alloc, MDefinition* left, MDefinition* right,
Operation op, MIRType t)
Operation op)
{
return new(alloc) MSimdBinaryArith(left, right, op, t);
return new(alloc) MSimdBinaryArith(left, right, op);
}
static MSimdBinaryArith* NewAsmJS(TempAllocator& alloc, MDefinition* left, MDefinition* right,
Operation op, MIRType t)
Operation op)
{
MOZ_ASSERT(left->type() == right->type());
MOZ_ASSERT(left->type() == t);
return New(alloc, left, right, op, t);
return New(alloc, left, right, op);
}
AliasSet getAliasSet() const override {
@@ -2273,9 +2318,11 @@ class MSimdBinaryBitwise
private:
Operation operation_;
MSimdBinaryBitwise(MDefinition* left, MDefinition* right, Operation op, MIRType type)
MSimdBinaryBitwise(MDefinition* left, MDefinition* right, Operation op)
: MBinaryInstruction(left, right), operation_(op)
{
MOZ_ASSERT(left->type() == right->type());
MIRType type = left->type();
MOZ_ASSERT(IsSimdType(type));
setResultType(type);
setMovable();
@@ -2285,17 +2332,15 @@ class MSimdBinaryBitwise
public:
INSTRUCTION_HEADER(SimdBinaryBitwise)
static MSimdBinaryBitwise* New(TempAllocator& alloc, MDefinition* left, MDefinition* right,
Operation op, MIRType t)
Operation op)
{
return new(alloc) MSimdBinaryBitwise(left, right, op, t);
return new(alloc) MSimdBinaryBitwise(left, right, op);
}
static MSimdBinaryBitwise* NewAsmJS(TempAllocator& alloc, MDefinition* left,
MDefinition* right, Operation op, MIRType t)
MDefinition* right, Operation op)
{
MOZ_ASSERT(left->type() == right->type());
MOZ_ASSERT(left->type() == t);
return new(alloc) MSimdBinaryBitwise(left, right, op, t);
return new(alloc) MSimdBinaryBitwise(left, right, op);
}
AliasSet getAliasSet() const override {
@@ -2332,23 +2377,24 @@ class MSimdShift
MSimdShift(MDefinition* left, MDefinition* right, Operation op)
: MBinaryInstruction(left, right), operation_(op)
{
setResultType(MIRType_Int32x4);
MIRType type = left->type();
MOZ_ASSERT(IsIntegerSimdType(type));
setResultType(type);
setMovable();
}
public:
INSTRUCTION_HEADER(SimdShift)
static MSimdShift* NewAsmJS(TempAllocator& alloc, MDefinition* left,
MDefinition* right, Operation op)
static MSimdShift* NewAsmJS(TempAllocator& alloc, MDefinition* left, MDefinition* right,
Operation op)
{
MOZ_ASSERT(left->type() == MIRType_Int32x4 && right->type() == MIRType_Int32);
return new(alloc) MSimdShift(left, right, op);
}
static MSimdShift* New(TempAllocator& alloc, MDefinition* left, MDefinition* right,
Operation op, MIRType type)
Operation op)
{
MOZ_ASSERT(type == MIRType_Int32x4);
return new(alloc) MSimdShift(left, right, op);
}
@@ -2367,7 +2413,7 @@ class MSimdShift
switch (op) {
case lsh: return "lsh";
case rsh: return "rsh-arithmetic";
case ursh: return "rhs-logical";
case ursh: return "rsh-logical";
}
MOZ_CRASH("unexpected operation");
}
@@ -2387,9 +2433,12 @@ class MSimdSelect
: public MTernaryInstruction,
public SimdSelectPolicy::Data
{
MSimdSelect(MDefinition* mask, MDefinition* lhs, MDefinition* rhs, MIRType type)
MSimdSelect(MDefinition* mask, MDefinition* lhs, MDefinition* rhs)
: MTernaryInstruction(mask, lhs, rhs)
{
MOZ_ASSERT(IsBooleanSimdType(mask->type()));
MOZ_ASSERT(lhs->type() == lhs->type());
MIRType type = lhs->type();
MOZ_ASSERT(IsSimdType(type));
setResultType(type);
specialization_ = type;
@@ -2398,19 +2447,11 @@ class MSimdSelect
public:
INSTRUCTION_HEADER(SimdSelect)
static MSimdSelect* NewAsmJS(TempAllocator& alloc, MDefinition* mask, MDefinition* lhs,
MDefinition* rhs, MIRType t)
{
MOZ_ASSERT(mask->type() == MIRType_Bool32x4);
MOZ_ASSERT(lhs->type() == rhs->type());
MOZ_ASSERT(lhs->type() == t);
return new(alloc) MSimdSelect(mask, lhs, rhs, t);
}
static MSimdSelect* New(TempAllocator& alloc, MDefinition* mask, MDefinition* lhs,
MDefinition* rhs, MIRType t)
MDefinition* rhs)
{
return new(alloc) MSimdSelect(mask, lhs, rhs, t);
return new(alloc) MSimdSelect(mask, lhs, rhs);
}
MDefinition* mask() const {
@@ -3251,14 +3292,17 @@ class MSimdBox
{
protected:
CompilerGCPointer<InlineTypedObject*> templateObject_;
SimdType simdType_;
gc::InitialHeap initialHeap_;
MSimdBox(CompilerConstraintList* constraints,
MDefinition* op,
InlineTypedObject* templateObject,
SimdType simdType,
gc::InitialHeap initialHeap)
: MUnaryInstruction(op),
templateObject_(templateObject),
simdType_(simdType),
initialHeap_(initialHeap)
{
MOZ_ASSERT(IsSimdType(op->type()));
@@ -3275,26 +3319,32 @@ class MSimdBox
CompilerConstraintList* constraints,
MDefinition* op,
InlineTypedObject* templateObject,
SimdType simdType,
gc::InitialHeap initialHeap)
{
return new(alloc) MSimdBox(constraints, op, templateObject, initialHeap);
return new(alloc) MSimdBox(constraints, op, templateObject, simdType, initialHeap);
}
InlineTypedObject* templateObject() const {
return templateObject_;
}
SimdType simdType() const {
return simdType_;
}
gc::InitialHeap initialHeap() const {
return initialHeap_;
}
bool congruentTo(const MDefinition* ins) const override {
if (congruentIfOperandsEqual(ins)) {
MOZ_ASSERT(ins->toSimdBox()->initialHeap() == initialHeap());
return true;
}
return false;
if (!congruentIfOperandsEqual(ins))
return false;
const MSimdBox* box = ins->toSimdBox();
if (box->simdType() != simdType())
return false;
MOZ_ASSERT(box->initialHeap() == initialHeap());
return true;
}
AliasSet getAliasSet() const override {
@@ -3312,9 +3362,13 @@ class MSimdUnbox
public SingleObjectPolicy::Data
{
protected:
MSimdUnbox(MDefinition* op, MIRType type)
: MUnaryInstruction(op)
SimdType simdType_;
MSimdUnbox(MDefinition* op, SimdType simdType)
: MUnaryInstruction(op),
simdType_(simdType)
{
MIRType type = SimdTypeToMIRType(simdType);
MOZ_ASSERT(IsSimdType(type));
setGuard();
setMovable();
@@ -3325,14 +3379,18 @@ class MSimdUnbox
INSTRUCTION_HEADER(SimdUnbox)
ALLOW_CLONE(MSimdUnbox)
static MSimdUnbox* New(TempAllocator& alloc, MDefinition* op, MIRType type)
static MSimdUnbox* New(TempAllocator& alloc, MDefinition* op, SimdType simdType)
{
return new(alloc) MSimdUnbox(op, type);
return new(alloc) MSimdUnbox(op, simdType);
}
SimdType simdType() const { return simdType_; }
MDefinition* foldsTo(TempAllocator& alloc) override;
bool congruentTo(const MDefinition* ins) const override {
return congruentIfOperandsEqual(ins);
if (!congruentIfOperandsEqual(ins))
return false;
return ins->toSimdUnbox()->simdType() == simdType();
}
AliasSet getAliasSet() const override {
@@ -7522,7 +7580,10 @@ class MRegExp : public MNullaryInstruction
class MRegExpMatcher
: public MAryInstruction<4>,
public NoTypePolicy::Data
public Mix4Policy<ObjectPolicy<0>,
StringPolicy<1>,
IntPolicy<2>,
BooleanPolicy<3> >::Data
{
private:
@@ -7575,7 +7636,10 @@ class MRegExpMatcher
class MRegExpTester
: public MAryInstruction<4>,
public NoTypePolicy::Data
public Mix4Policy<ObjectPolicy<0>,
StringPolicy<1>,
IntPolicy<2>,
BooleanPolicy<3> >::Data
{
private:
+5 -11
View File
@@ -1336,8 +1336,7 @@ MSimdBox::writeRecoverData(CompactBufferWriter& writer) const
MOZ_ASSERT(canRecoverOnBailout());
writer.writeUnsigned(uint32_t(RInstruction::Recover_SimdBox));
static_assert(sizeof(SimdType) == sizeof(uint8_t), "assuming uint8 storage class for SimdType");
SimdType type = templateObject()->typeDescr().as<SimdTypeDescr>().type();
writer.writeByte(uint8_t(type));
writer.writeByte(uint8_t(simdType()));
return true;
}
@@ -1352,21 +1351,19 @@ RSimdBox::recover(JSContext* cx, SnapshotIterator& iter) const
JSObject* resultObject = nullptr;
RValueAllocation a = iter.readAllocation();
MOZ_ASSERT(iter.allocationReadable(a));
MOZ_ASSERT_IF(a.mode() == RValueAllocation::ANY_FLOAT_REG, a.fpuReg().isSimd128());
const FloatRegisters::RegisterContent* raw = iter.floatAllocationPointer(a);
switch (SimdType(type_)) {
case SimdType::Bool32x4:
MOZ_ASSERT_IF(a.mode() == RValueAllocation::ANY_FLOAT_REG,
a.fpuReg().isSimd128());
resultObject = js::CreateSimd<Bool32x4>(cx, (const Bool32x4::Elem*) raw);
break;
case SimdType::Int32x4:
MOZ_ASSERT_IF(a.mode() == RValueAllocation::ANY_FLOAT_REG,
a.fpuReg().isSimd128());
resultObject = js::CreateSimd<Int32x4>(cx, (const Int32x4::Elem*) raw);
break;
case SimdType::Uint32x4:
resultObject = js::CreateSimd<Uint32x4>(cx, (const Uint32x4::Elem*) raw);
break;
case SimdType::Float32x4:
MOZ_ASSERT_IF(a.mode() == RValueAllocation::ANY_FLOAT_REG,
a.fpuReg().isSimd128());
resultObject = js::CreateSimd<Float32x4>(cx, (const Float32x4::Elem*) raw);
break;
case SimdType::Float64x2:
@@ -1384,9 +1381,6 @@ RSimdBox::recover(JSContext* cx, SnapshotIterator& iter) const
case SimdType::Uint16x8:
MOZ_CRASH("NYI, RSimdBox of UInt16x8");
break;
case SimdType::Uint32x4:
MOZ_CRASH("NYI, RSimdBox of UInt32x4");
break;
case SimdType::Bool8x16:
MOZ_CRASH("NYI, RSimdBox of Bool8x16");
break;
+41 -40
View File
@@ -106,6 +106,8 @@ AllDoublePolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins)
if (in->type() == MIRType_Double)
continue;
if (!alloc.ensureBallast())
return false;
MInstruction* replace = MToDouble::New(alloc, in);
ins->block()->insertBefore(ins, replace);
@@ -433,6 +435,23 @@ template bool ConvertToStringPolicy<0>::staticAdjustInputs(TempAllocator& alloc,
template bool ConvertToStringPolicy<1>::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins);
template bool ConvertToStringPolicy<2>::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins);
template <unsigned Op>
bool
BooleanPolicy<Op>::staticAdjustInputs(TempAllocator& alloc, MInstruction* def)
{
MDefinition* in = def->getOperand(Op);
if (in->type() == MIRType_Boolean)
return true;
MUnbox* replace = MUnbox::New(alloc, in, MIRType_Boolean, MUnbox::Fallible);
def->block()->insertBefore(def, replace);
def->replaceOperand(Op, replace);
return replace->typePolicy()->adjustInputs(alloc, replace);
}
template bool BooleanPolicy<3>::staticAdjustInputs(TempAllocator& alloc, MInstruction* def);
template <unsigned Op>
bool
IntPolicy<Op>::staticAdjustInputs(TempAllocator& alloc, MInstruction* def)
@@ -785,26 +804,12 @@ template bool ObjectPolicy<1>::staticAdjustInputs(TempAllocator& alloc, MInstruc
template bool ObjectPolicy<2>::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins);
template bool ObjectPolicy<3>::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins);
static bool
MaybeSimdUnbox(TempAllocator& alloc, MInstruction* ins, MIRType type, unsigned op)
{
MOZ_ASSERT(IsSimdType(type));
MDefinition* in = ins->getOperand(op);
if (in->type() == type)
return true;
MSimdUnbox* replace = MSimdUnbox::New(alloc, in, type);
ins->block()->insertBefore(ins, replace);
ins->replaceOperand(op, replace);
return replace->typePolicy()->adjustInputs(alloc, replace);
}
template <unsigned Op>
bool
SimdSameAsReturnedTypePolicy<Op>::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins)
{
return MaybeSimdUnbox(alloc, ins, ins->type(), Op);
MOZ_ASSERT(ins->type() == ins->getOperand(Op)->type());
return true;
}
template bool
@@ -815,11 +820,8 @@ SimdSameAsReturnedTypePolicy<1>::staticAdjustInputs(TempAllocator& alloc, MInstr
bool
SimdAllPolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins)
{
MIRType specialization = ins->typePolicySpecialization();
for (unsigned i = 0, e = ins->numOperands(); i < e; i++) {
if (!MaybeSimdUnbox(alloc, ins, specialization, i))
return false;
}
for (unsigned i = 0, e = ins->numOperands(); i < e; i++)
MOZ_ASSERT(ins->getOperand(i)->type() == ins->typePolicySpecialization());
return true;
}
@@ -827,7 +829,8 @@ template <unsigned Op>
bool
SimdPolicy<Op>::adjustInputs(TempAllocator& alloc, MInstruction* ins)
{
return MaybeSimdUnbox(alloc, ins, ins->typePolicySpecialization(), Op);
MOZ_ASSERT(ins->typePolicySpecialization() == ins->getOperand(Op)->type());
return true;
}
template bool
@@ -836,14 +839,10 @@ SimdPolicy<0>::adjustInputs(TempAllocator& alloc, MInstruction* ins);
bool
SimdShufflePolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins)
{
MIRType specialization = ins->typePolicySpecialization();
MSimdGeneralShuffle* s = ins->toSimdGeneralShuffle();
for (unsigned i = 0; i < s->numVectors(); i++) {
if (!MaybeSimdUnbox(alloc, ins, specialization, i))
return false;
}
for (unsigned i = 0; i < s->numVectors(); i++)
MOZ_ASSERT(ins->getOperand(i)->type() == ins->typePolicySpecialization());
// Next inputs are the lanes, which need to be int32
for (unsigned i = 0; i < s->numLanes(); i++) {
@@ -864,17 +863,12 @@ SimdShufflePolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins)
bool
SimdSelectPolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins)
{
MIRType specialization = ins->typePolicySpecialization();
// First input is the mask, which has to be a bool32x4.
if (!MaybeSimdUnbox(alloc, ins, MIRType_Bool32x4, 0))
return false;
MOZ_ASSERT(ins->getOperand(0)->type() == MIRType_Bool32x4);
// Next inputs are the two vectors of a particular type.
for (unsigned i = 1; i < 3; i++) {
if (!MaybeSimdUnbox(alloc, ins, specialization, i))
return false;
}
for (unsigned i = 1; i < 3; i++)
MOZ_ASSERT(ins->getOperand(i)->type() == ins->typePolicySpecialization());
return true;
}
@@ -894,8 +888,11 @@ CallPolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins)
return false;
}
for (uint32_t i = 0; i < call->numStackArgs(); i++)
for (uint32_t i = 0; i < call->numStackArgs(); i++) {
if (!alloc.ensureBallast())
return false;
EnsureOperandNotFloat32(alloc, call, MCall::IndexOfStackArg(i));
}
return true;
}
@@ -931,9 +928,12 @@ StoreUnboxedScalarPolicy::adjustValueInput(TempAllocator& alloc, MInstruction* i
Scalar::Type writeType, MDefinition* value,
int valueOperand)
{
// Storing a SIMD value just implies that we might need a SimdUnbox.
if (Scalar::isSimdType(writeType))
return MaybeSimdUnbox(alloc, ins, ScalarTypeToMIRType(writeType), valueOperand);
// Storing a SIMD value requires a valueOperand that has already been
// SimdUnboxed. See IonBuilder::inlineSimdStore(()
if (Scalar::isSimdType(writeType)) {
MOZ_ASSERT(IsSimdType(value->type()));
return true;
}
MDefinition* curValue = value;
// First, ensure the value is int32, boolean, double or Value.
@@ -1227,6 +1227,7 @@ FilterTypeSetPolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins)
_(Mix3Policy<StringPolicy<0>, IntPolicy<1>, IntPolicy<2>>) \
_(Mix3Policy<StringPolicy<0>, ObjectPolicy<1>, StringPolicy<2> >) \
_(Mix3Policy<StringPolicy<0>, StringPolicy<1>, StringPolicy<2> >) \
_(Mix4Policy<ObjectPolicy<0>, StringPolicy<1>, IntPolicy<2>, BooleanPolicy<3>>) \
_(Mix4Policy<ObjectPolicy<0>, IntPolicy<1>, IntPolicy<2>, IntPolicy<3>>) \
_(Mix4Policy<ObjectPolicy<0>, IntPolicy<1>, TruncateToInt32Policy<2>, TruncateToInt32Policy<3> >) \
_(Mix3Policy<ObjectPolicy<0>, CacheIdPolicy<1>, NoFloatPolicy<2>>) \
+12 -8
View File
@@ -168,6 +168,18 @@ class ConvertToStringPolicy final : public TypePolicy
}
};
// Expect an Boolean for operand Op. If the input is a Value, it is unboxed.
template <unsigned Op>
class BooleanPolicy final : private TypePolicy
{
public:
EMPTY_DATA_;
static bool staticAdjustInputs(TempAllocator& alloc, MInstruction* def);
virtual bool adjustInputs(TempAllocator& alloc, MInstruction* def) override {
return staticAdjustInputs(alloc, def);
}
};
// Expect an Int for operand Op. If the input is a Value, it is unboxed.
template <unsigned Op>
class IntPolicy final : private TypePolicy
@@ -513,14 +525,6 @@ class FilterTypeSetPolicy final : public TypePolicy
virtual bool adjustInputs(TempAllocator& alloc, MInstruction* ins) override;
};
static inline bool
CoercesToDouble(MIRType type)
{
if (type == MIRType_Undefined || IsFloatingPointType(type))
return true;
return false;
}
#undef SPECIALIZATION_DATA_
#undef INHERIT_DATA_
#undef EMPTY_DATA_
+6
View File
@@ -220,6 +220,12 @@ static_assert(JitStackAlignment % SimdMemoryAlignment == 0,
static const uint32_t AsmJSStackAlignment = SimdMemoryAlignment;
// Does this architecture support SIMD conversions between Uint32x4 and Float32x4?
static MOZ_CONSTEXPR_VAR bool SupportsUint32x4FloatConversions = false;
// Does this architecture support comparisons of unsigned 32x4 integer vectors?
static MOZ_CONSTEXPR_VAR bool SupportsUint32x4Compares = false;
static const Scale ScalePointer = TimesFour;
class Instruction;
+6
View File
@@ -176,6 +176,12 @@ static_assert(CodeAlignment % SimdMemoryAlignment == 0,
static const uint32_t AsmJSStackAlignment = SimdMemoryAlignment;
static const int32_t AsmJSGlobalRegBias = 1024;
// Does this architecture support SIMD conversions between Uint32x4 and Float32x4?
static MOZ_CONSTEXPR_VAR bool SupportsUint32x4FloatConversions = false;
// Does this architecture support comparisons of unsigned 32x4 integer vectors?
static MOZ_CONSTEXPR_VAR bool SupportsUint32x4Compares = false;
class Assembler : public vixl::Assembler
{
public:
+6
View File
@@ -98,6 +98,12 @@ static_assert(JitStackAlignment % sizeof(Value) == 0 && JitStackValueAlignment >
static MOZ_CONSTEXPR_VAR uint32_t SimdMemoryAlignment = 8;
static MOZ_CONSTEXPR_VAR uint32_t AsmJSStackAlignment = SimdMemoryAlignment;
// Does this architecture support SIMD conversions between Uint32x4 and Float32x4?
static MOZ_CONSTEXPR_VAR bool SupportsUint32x4FloatConversions = false;
// Does this architecture support comparisons of unsigned 32x4 integer vectors?
static MOZ_CONSTEXPR_VAR bool SupportsUint32x4Compares = false;
static MOZ_CONSTEXPR_VAR Scale ScalePointer = TimesFour;
class Assembler : public AssemblerMIPSShared
+18 -18
View File
@@ -281,7 +281,7 @@ SimInstruction::isForbiddenInBranchDelay() const
break;
default:
return false;
};
}
}
bool
@@ -446,7 +446,7 @@ SimInstruction::instructionType() const
return kJumpType;
default:
return kUnsupported;
};
}
return kUnsupported;
}
@@ -2231,7 +2231,7 @@ Simulator::configureTypeRegister(SimInstruction* instr,
break;
default:
MOZ_CRASH();
};
}
break;
case op_cop1x:
break;
@@ -2367,7 +2367,7 @@ Simulator::configureTypeRegister(SimInstruction* instr,
break;
default:
MOZ_CRASH();
};
}
break;
case op_special2:
switch (instr->functionFieldRaw()) {
@@ -2379,7 +2379,7 @@ Simulator::configureTypeRegister(SimInstruction* instr,
break;
default:
MOZ_CRASH();
};
}
break;
case op_special3:
switch (instr->functionFieldRaw()) {
@@ -2405,11 +2405,11 @@ Simulator::configureTypeRegister(SimInstruction* instr,
}
default:
MOZ_CRASH();
};
}
break;
default:
MOZ_CRASH();
};
}
}
void
@@ -2775,7 +2775,7 @@ Simulator::decodeTypeRegister(SimInstruction* instr)
break;
default:
MOZ_CRASH();
};
}
break;
case rs_l:
switch (instr->functionFieldRaw()) {
@@ -2797,7 +2797,7 @@ Simulator::decodeTypeRegister(SimInstruction* instr)
break;
default:
MOZ_CRASH();
};
}
break;
case op_cop1x:
switch (instr->functionFieldRaw()) {
@@ -2817,7 +2817,7 @@ Simulator::decodeTypeRegister(SimInstruction* instr)
break;
default:
MOZ_CRASH();
};
}
break;
case op_special:
switch (instr->functionFieldRaw()) {
@@ -2897,7 +2897,7 @@ Simulator::decodeTypeRegister(SimInstruction* instr)
break;
default: // For other special opcodes we do the default operation.
setRegister(rd_reg, alu_out);
};
}
break;
case op_special2:
switch (instr->functionFieldRaw()) {
@@ -2923,14 +2923,14 @@ Simulator::decodeTypeRegister(SimInstruction* instr)
break;
default:
MOZ_CRASH();
};
}
break;
// Unimplemented opcodes raised an error in the configuration step before,
// so we can use the default here to set the destination register in common
// cases.
default:
setRegister(rd_reg, alu_out);
};
}
}
// Type 2: instructions using a 16 bytes immediate. (e.g. addi, beq).
@@ -2992,7 +2992,7 @@ Simulator::decodeTypeImmediate(SimInstruction* instr)
break;
default:
MOZ_CRASH();
};
}
break;
// ------------- op_regimm class.
case op_regimm:
@@ -3011,7 +3011,7 @@ Simulator::decodeTypeImmediate(SimInstruction* instr)
break;
default:
MOZ_CRASH();
};
}
switch (instr->rtFieldRaw()) {
case rt_bltz:
case rt_bltzal:
@@ -3030,7 +3030,7 @@ Simulator::decodeTypeImmediate(SimInstruction* instr)
}
default:
break;
};
}
break; // case op_regimm.
// ------------- Branch instructions.
// When comparing to zero, the encoding of rt field is always 0, so we don't
@@ -3163,7 +3163,7 @@ Simulator::decodeTypeImmediate(SimInstruction* instr)
break;
default:
MOZ_CRASH();
};
}
// ---------- Raise exceptions triggered.
signalExceptions();
@@ -3239,7 +3239,7 @@ Simulator::decodeTypeImmediate(SimInstruction* instr)
break;
default:
break;
};
}
if (execute_branch_delay_instruction) {
+6
View File
@@ -109,6 +109,12 @@ static MOZ_CONSTEXPR_VAR uint32_t SimdMemoryAlignment = 16;
static MOZ_CONSTEXPR_VAR uint32_t AsmJSStackAlignment = SimdMemoryAlignment;
// Does this architecture support SIMD conversions between Uint32x4 and Float32x4?
static MOZ_CONSTEXPR_VAR bool SupportsUint32x4FloatConversions = false;
// Does this architecture support comparisons of unsigned 32x4 integer vectors?
static MOZ_CONSTEXPR_VAR bool SupportsUint32x4Compares = false;
static MOZ_CONSTEXPR_VAR Scale ScalePointer = TimesEight;
class Assembler : public AssemblerMIPSShared
+6
View File
@@ -18,6 +18,12 @@ static const bool SupportsSimd = false;
static const uint32_t SimdMemoryAlignment = 4; // Make it 4 to avoid a bunch of div-by-zero warnings
static const uint32_t AsmJSStackAlignment = 8;
// Does this architecture support SIMD conversions between Uint32x4 and Float32x4?
static MOZ_CONSTEXPR_VAR bool SupportsUint32x4FloatConversions = false;
// Does this architecture support comparisons of unsigned 32x4 integer vectors?
static MOZ_CONSTEXPR_VAR bool SupportsUint32x4Compares = false;
class Registers
{
public:
+41
View File
@@ -280,6 +280,24 @@ class LSimdExtractElementF : public LSimdExtractElementBase
{}
};
// Extracts an element from an Uint32x4 SIMD vector, converts to double.
class LSimdExtractElementU2D : public LInstructionHelper<1, 1, 1>
{
public:
LIR_HEADER(SimdExtractElementU2D);
explicit LSimdExtractElementU2D(const LAllocation& base, const LDefinition& temp) {
setOperand(0, base);
setTemp(0, temp);
}
SimdLane lane() const {
return mir_->toSimdExtractElement()->lane();
}
const LDefinition* temp() {
return getTemp(0);
}
};
class LSimdInsertElementBase : public LInstructionHelper<1, 2, 0>
{
protected:
@@ -3794,6 +3812,29 @@ class LFloat32x4ToInt32x4 : public LInstructionHelper<1, 1, 1>
}
};
// Float32x4 to Uint32x4 needs one GPR temp and one FloatReg temp.
class LFloat32x4ToUint32x4 : public LInstructionHelper<1, 1, 2>
{
public:
LIR_HEADER(Float32x4ToUint32x4);
explicit LFloat32x4ToUint32x4(const LAllocation& input, const LDefinition& tempR,
const LDefinition& tempF)
{
setOperand(0, input);
setTemp(0, tempR);
setTemp(1, tempF);
}
const LDefinition* tempR() {
return getTemp(0);
}
const LDefinition* tempF() {
return getTemp(1);
}
const MSimdConvert* mir() const {
return mir_->toSimdConvert();
}
};
// Double raised to a half power.
class LPowHalfD : public LInstructionHelper<1, 1, 0>
{
+2
View File
@@ -26,6 +26,7 @@
_(SimdAnyTrue) \
_(SimdReinterpretCast) \
_(SimdExtractElementI) \
_(SimdExtractElementU2D) \
_(SimdExtractElementB) \
_(SimdExtractElementF) \
_(SimdInsertElementI) \
@@ -185,6 +186,7 @@
_(ValueToObjectOrNull) \
_(Int32x4ToFloat32x4) \
_(Float32x4ToInt32x4) \
_(Float32x4ToUint32x4) \
_(Start) \
_(OsrEntry) \
_(OsrValue) \
@@ -20,6 +20,12 @@
namespace js {
namespace jit {
// Does this architecture support SIMD conversions between Uint32x4 and Float32x4?
static MOZ_CONSTEXPR_VAR bool SupportsUint32x4FloatConversions = false;
// Does this architecture support comparisons of unsigned 32x4 integer vectors?
static MOZ_CONSTEXPR_VAR bool SupportsUint32x4Compares = false;
#if defined(JS_CODEGEN_X86)
// In bytes: slots needed for potential memory->memory move spills.
// +8 for cycles
@@ -2361,6 +2361,91 @@ CodeGeneratorX86Shared::visitOutOfLineSimdFloatToIntCheck(OutOfLineSimdFloatToIn
}
}
// Convert Float32x4 to Uint32x4.
//
// If any input lane value is out of range or NaN, bail out.
void
CodeGeneratorX86Shared::visitFloat32x4ToUint32x4(LFloat32x4ToUint32x4* ins)
{
FloatRegister in = ToFloatRegister(ins->input());
FloatRegister out = ToFloatRegister(ins->output());
Register temp = ToRegister(ins->tempR());
FloatRegister tempF = ToFloatRegister(ins->tempF());
// Classify lane values into 4 disjoint classes:
//
// N-lanes: in < -0.0
// A-lanes: -0.0 <= in <= 0x0.ffffffp31
// B-lanes: 0x1.0p31 <= in <= 0x0.ffffffp32
// V-lanes: 0x1.0p32 <= in, or isnan(in)
//
// We need to bail out to throw a RangeError if we see any N-lanes or
// V-lanes.
//
// For A-lanes and B-lanes, we make two float -> int32 conversions:
//
// A = cvttps2dq(in)
// B = cvttps2dq(in - 0x1.0p31f)
//
// Note that the subtraction for the B computation is exact for B-lanes.
// There is no rounding, so B is the low 31 bits of the correctly converted
// result.
//
// The cvttps2dq instruction produces 0x80000000 when the input is NaN or
// out of range for a signed int32_t. This conveniently provides the missing
// high bit for B, so the desired result is A for A-lanes and A|B for
// B-lanes.
ScratchSimd128Scope scratch(masm);
// First we need to filter out N-lanes. We need to use a floating point
// comparison to do that because cvttps2dq maps the negative range
// [-0x0.ffffffp0;-0.0] to 0. We can't simply look at the sign bits of in
// because -0.0 is a valid input.
// TODO: It may be faster to let ool code deal with -0.0 and skip the
// vcmpleps here.
masm.zeroFloat32x4(scratch);
masm.vcmpleps(Operand(in), scratch, scratch);
masm.vmovmskps(scratch, temp);
masm.cmp32(temp, Imm32(15));
bailoutIf(Assembler::NotEqual, ins->snapshot());
// TODO: If the majority of lanes are A-lanes, it could be faster to compute
// A first, use vmovmskps to check for any non-A-lanes and handle them in
// ool code. OTOH, we we're wrong about the lane distribution, that would be
// slower.
// Compute B in |scratch|.
static const float Adjust = 0x80000000; // 0x1.0p31f for the benefit of MSVC.
static const SimdConstant Bias = SimdConstant::SplatX4(-Adjust);
masm.loadConstantFloat32x4(Bias, scratch);
masm.packedAddFloat32(Operand(in), scratch);
masm.convertFloat32x4ToInt32x4(scratch, scratch);
// Compute A in |out|. This is the last time we use |in| and the first time
// we use |out|, so we can tolerate if they are the same register.
masm.convertFloat32x4ToInt32x4(in, out);
// Since we filtered out N-lanes, we can identify A-lanes by the sign bits
// in A: Any A-lanes will be positive in A, and B-lanes and V-lanes will be
// 0x80000000 in A. Compute a mask of non-A-lanes into |tempF|.
masm.zeroFloat32x4(tempF);
masm.packedGreaterThanInt32x4(Operand(out), tempF);
// Clear the A-lanes in B.
masm.bitwiseAndX4(Operand(tempF), scratch);
// Compute the final result: A for A-lanes, A|B for B-lanes.
masm.bitwiseOrX4(Operand(scratch), out);
// We still need to filter out the V-lanes. They would show up as 0x80000000
// in both A and B. Since we cleared the valid A-lanes in B, the V-lanes are
// the remaining negative lanes in B.
masm.vmovmskps(scratch, temp);
masm.cmp32(temp, Imm32(0));
bailoutIf(Assembler::NotEqual, ins->snapshot());
}
void
CodeGeneratorX86Shared::visitSimdValueInt32x4(LSimdValueInt32x4* ins)
{
@@ -2454,13 +2539,10 @@ CodeGeneratorX86Shared::visitSimdReinterpretCast(LSimdReinterpretCast* ins)
}
}
// Extract an integer lane from the vector register |input| and place it in |output|.
void
CodeGeneratorX86Shared::visitSimdExtractElementB(LSimdExtractElementB* ins)
CodeGeneratorX86Shared::emitSimdExtractLane(FloatRegister input, Register output, unsigned lane)
{
FloatRegister input = ToFloatRegister(ins->input());
Register output = ToRegister(ins->output());
SimdLane lane = ins->lane();
if (lane == LaneX) {
// The value we want to extract is in the low double-word
masm.moveLowInt32(input, output);
@@ -2471,6 +2553,15 @@ CodeGeneratorX86Shared::visitSimdExtractElementB(LSimdExtractElementB* ins)
masm.shuffleInt32(mask, input, ScratchSimd128Reg);
masm.moveLowInt32(ScratchSimd128Reg, output);
}
}
void
CodeGeneratorX86Shared::visitSimdExtractElementB(LSimdExtractElementB* ins)
{
FloatRegister input = ToFloatRegister(ins->input());
Register output = ToRegister(ins->output());
emitSimdExtractLane(input, output, ins->lane());
// We need to generate a 0/1 value. We have 0/-1.
masm.and32(Imm32(1), output);
@@ -2482,18 +2573,18 @@ CodeGeneratorX86Shared::visitSimdExtractElementI(LSimdExtractElementI* ins)
FloatRegister input = ToFloatRegister(ins->input());
Register output = ToRegister(ins->output());
SimdLane lane = ins->lane();
if (lane == LaneX) {
// The value we want to extract is in the low double-word
masm.moveLowInt32(input, output);
} else if (AssemblerX86Shared::HasSSE41()) {
masm.vpextrd(lane, input, output);
} else {
uint32_t mask = MacroAssembler::ComputeShuffleMask(lane);
ScratchSimd128Scope scratch(masm);
masm.shuffleInt32(mask, input, scratch);
masm.moveLowInt32(scratch, output);
}
emitSimdExtractLane(input, output, ins->lane());
}
void
CodeGeneratorX86Shared::visitSimdExtractElementU2D(LSimdExtractElementU2D* ins)
{
FloatRegister input = ToFloatRegister(ins->input());
FloatRegister output = ToFloatRegister(ins->output());
Register temp = ToRegister(ins->temp());
emitSimdExtractLane(input, temp, ins->lane());
masm.convertUInt32ToDouble(temp, output);
}
void
@@ -202,6 +202,8 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared
void emitTableSwitchDispatch(MTableSwitch* mir, Register index, Register base);
void emitSimdExtractLane(FloatRegister input, Register output, unsigned lane);
public:
CodeGeneratorX86Shared(MIRGenerator* gen, LIRGraph* graph, MacroAssembler* masm);
@@ -278,9 +280,11 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared
void visitFloat32x4(LFloat32x4* ins);
void visitInt32x4ToFloat32x4(LInt32x4ToFloat32x4* ins);
void visitFloat32x4ToInt32x4(LFloat32x4ToInt32x4* ins);
void visitFloat32x4ToUint32x4(LFloat32x4ToUint32x4* ins);
void visitSimdReinterpretCast(LSimdReinterpretCast* lir);
void visitSimdExtractElementB(LSimdExtractElementB* lir);
void visitSimdExtractElementI(LSimdExtractElementI* lir);
void visitSimdExtractElementU2D(LSimdExtractElementU2D* lir);
void visitSimdExtractElementF(LSimdExtractElementF* lir);
void visitSimdInsertElementI(LSimdInsertElementI* lir);
void visitSimdInsertElementF(LSimdInsertElementF* lir);
+1 -1
View File
@@ -9496,7 +9496,7 @@ CompareTrees(nsPresContext* aFirstPresContext, nsIFrame* aFirstFrame,
const nsFrameList& kids1 = !lists1.IsDone() ? lists1.CurrentList() : nsFrameList();
const nsFrameList& kids2 = !lists2.IsDone() ? lists2.CurrentList() : nsFrameList();
int32_t l1 = kids1.GetLength();
int32_t l2 = kids2.GetLength();;
int32_t l2 = kids2.GetLength();
if (l1 != l2) {
ok = false;
LogVerifyMessage(kids1.FirstChild(), kids2.FirstChild(),
+1 -1
View File
@@ -1428,7 +1428,7 @@ static void GetProfileTimelineSubDocShells(nsDocShell* aRootDocShell,
}
aShells.AppendElement(shell);
};
}
}
static void
+2 -2
View File
@@ -2781,14 +2781,14 @@ nsFrameSelection::AddCellsToSelection(nsIContent *aTableContent,
col ++;
else
col--;
};
}
if (row == aEndRowIndex) break;
if (aStartRowIndex < aEndRowIndex)
row++;
else
row--;
};
}
return result;
}
+1 -1
View File
@@ -7527,7 +7527,7 @@ nsTableFrame::InvalidateTableFrame(nsIFrame* aFrame,
aOrigVisualOverflow.Size() != visualOverflow.Size()){
aFrame->InvalidateFrameWithRect(aOrigVisualOverflow);
aFrame->InvalidateFrame();
parent->InvalidateFrameWithRect(aOrigRect);;
parent->InvalidateFrameWithRect(aOrigRect);
parent->InvalidateFrame();
}
}
+1 -1
View File
@@ -1138,7 +1138,7 @@ nsNSSCertificate::ExportAsCMS(uint32_t chainMode,
break;
default:
return NS_ERROR_INVALID_ARG;
};
}
ScopedNSSCMSMessage cmsg(NSS_CMSMessage_Create(nullptr));
if (!cmsg) {
@@ -55,7 +55,7 @@ void* AllocateNearTo(void* source, size_t size) {
// Try 100 MB higher.
base = reinterpret_cast<char*>(base) + 100 * 0x100000;
};
}
if (attempts == 41)
return NULL;
@@ -662,7 +662,7 @@ PendingLookup::StartLookup()
nsresult rv = DoLookupInternal();
if (NS_FAILED(rv)) {
return OnComplete(false, NS_OK);
};
}
return rv;
}
@@ -480,7 +480,7 @@ NativeFileWatcherIOTask::RunInternal()
}
rawNotificationBuffer += notificationInfo->NextEntryOffset;
};
}
// We need to keep watching for further changes.
nsresult rv = AddDirectoryToWatchList(changedRes);
@@ -0,0 +1,32 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/*
* The temporary directory downloads saves to, should be only readable
* for the current user.
*/
add_task(function test_private_temp() {
let download = yield promiseStartExternalHelperAppServiceDownload(
httpUrl("empty.txt"));
yield promiseDownloadStopped(download);
var targetFile = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
targetFile.initWithPath(download.target.path);
// 488 is the decimal value of 0700.
equal(targetFile.parent.permissions, 448);
});
////////////////////////////////////////////////////////////////////////////////
//// Termination
let tailFile = do_get_file("tail.js");
Services.scriptloader.loadSubScript(NetUtil.newURI(tailFile).spec);
@@ -16,3 +16,5 @@ support-files =
[test_DownloadList.js]
[test_Downloads.js]
[test_DownloadStore.js]
[test_PrivateTemp.js]
skip-if = os != 'linux'
+1 -1
View File
@@ -2335,7 +2335,7 @@ TelemetryImpl::CreateHistogramSnapshots(JSContext *cx,
DebugOnly<nsresult> rv = GetHistogramByEnumId(Telemetry::ID(i), &h);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
};
}
StatisticsRecorder::Histograms hs;
StatisticsRecorder::GetHistograms(&hs);
@@ -127,7 +127,7 @@ CreateSourceEvent(SourceEventType aType)
#include "SourceEventTypeMap.h"
default:
MOZ_CRASH("Unknown SourceEvent.");
};
}
#undef CREATE_SOURCE_EVENT_NAME
// Log a fake dispatch and start for this source event.
@@ -399,9 +399,75 @@ static nsresult GetDownloadDirectory(nsIFile **_directory,
return NS_ERROR_FAILURE;
}
#else
// On all other platforms, we default to the system's temporary directory.
// On all other platforms, we default to the systems temporary directory.
nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(dir));
NS_ENSURE_SUCCESS(rv, rv);
#if defined(XP_UNIX)
// Ensuring that only the current user can read the file names we end up
// creating. Note that Creating directories with specified permission only
// supported on Unix platform right now. That's why above if exists.
uint32_t permissions;
rv = dir->GetPermissions(&permissions);
NS_ENSURE_SUCCESS(rv, rv);
if (permissions != PR_IRWXU) {
const char* userName = PR_GetEnv("USERNAME");
if (!userName || !*userName) {
userName = PR_GetEnv("USER");
if (!userName || !*userName) {
userName = PR_GetEnv("LOGNAME");
}
else {
userName = "mozillaUser";
}
}
nsAutoString userDir;
userDir.AssignLiteral("mozilla_");
userDir.AppendASCII(userName);
userDir.ReplaceChar(FILE_PATH_SEPARATOR FILE_ILLEGAL_CHARACTERS, '_');
int counter = 0;
bool pathExists;
nsCOMPtr<nsIFile> finalPath;
while (true) {
nsAutoString countedUserDir(userDir);
countedUserDir.AppendInt(counter, 10);
dir->Clone(getter_AddRefs(finalPath));
finalPath->Append(countedUserDir);
rv = finalPath->Exists(&pathExists);
NS_ENSURE_SUCCESS(rv, rv);
if (pathExists) {
// If this path has the right permissions, use it.
rv = finalPath->GetPermissions(&permissions);
NS_ENSURE_SUCCESS(rv, rv);
if (permissions == PR_IRWXU) {
dir = finalPath;
break;
}
}
rv = finalPath->Create(nsIFile::DIRECTORY_TYPE, PR_IRWXU);
if (NS_SUCCEEDED(rv)) {
dir = finalPath;
break;
}
else if (rv != NS_ERROR_FILE_ALREADY_EXISTS) {
// Unexpected error.
return rv;
}
counter++;
}
}
#endif
#endif
NS_ASSERTION(dir, "Somehow we didn't get a download directory!");
+1 -1
View File
@@ -155,7 +155,7 @@ GetPrefNameForFeature(int32_t aFeature)
break;
default:
break;
};
}
return name;
}
+1 -1
View File
@@ -392,7 +392,7 @@ GonkDisplayJB::NotifyBootAnimationStopped()
void
GonkDisplayJB::PowerOnDisplay(int aDpy)
{
MOZ_ASSERT(mHwc);;
MOZ_ASSERT(mHwc);
#if ANDROID_VERSION >= 21
if (mHwc->common.version >= HWC_DEVICE_API_VERSION_1_4) {
mHwc->setPowerMode(mHwc, aDpy, HWC_POWER_MODE_NORMAL);
+1 -1
View File
@@ -364,7 +364,7 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor)
#else
case eColorID_threeddarkshadow:
// Hardcode to black
aColor = NS_RGB(0x00,0x00,0x00);;
aColor = NS_RGB(0x00,0x00,0x00);
break;
case eColorID__moz_eventreerow:
+1 -1
View File
@@ -811,7 +811,7 @@ WindowsVersionToOperatingSystem(int32_t aWindowsVersion)
case kWindowsUnknown:
default:
return DRIVER_OS_UNKNOWN;
};
}
}
const nsTArray<GfxDriverInfo>&
+1 -1
View File
@@ -216,7 +216,7 @@ HRESULT InkCollectorEvent::Invoke(DISPID aDispIdMember, REFIID /*aRiid*/,
}
break;
}
};
}
return S_OK;
}
+1 -1
View File
@@ -5976,7 +5976,7 @@ void nsWindow::OnWindowPosChanged(WINDOWPOS* wp)
default:
MOZ_LOG(gWindowsLog, LogLevel::Info, ("*** mSizeMode: ??????\n"));
break;
};
}
#endif
if (mWidgetListener)
+1 -1
View File
@@ -383,7 +383,7 @@ nsConsoleService::GetMessageArray(uint32_t* aCount,
nsCOMPtr<nsIConsoleMessage> m = e->Get();
m.forget(&messageArray[i]);
i++;
};
}
MOZ_ASSERT(i == mCurrentSize);
+1 -1
View File
@@ -324,7 +324,7 @@ NS_DebugBreak(uint32_t aSeverity, const char* aStr, const char* aExpr,
default:
aSeverity = NS_DEBUG_WARNING;
};
}
# define PrintToBuffer(...) PR_sxprintf(StuffFixedBuffer, &buf, __VA_ARGS__)
+2 -2
View File
@@ -522,7 +522,7 @@ nsAString::AppendInt(int aInt, int32_t aRadix)
default:
NS_ERROR("Unrecognized radix");
fmt = "";
};
}
char buf[20];
int len = snprintf(buf, sizeof(buf), fmt, aInt);
@@ -1002,7 +1002,7 @@ nsACString::AppendInt(int aInt, int32_t aRadix)
default:
NS_ERROR("Unrecognized radix");
fmt = "";
};
}
char buf[20];
int len = snprintf(buf, sizeof(buf), fmt, aInt);
+2 -2
View File
@@ -199,7 +199,7 @@ nsStorageStream::Write(const char* aBuffer, uint32_t aCount,
mWriteCursor += count;
LOG(("nsStorageStream [%p] Writing mWriteCursor=%x mSegmentEnd=%x count=%d\n",
this, mWriteCursor, mSegmentEnd, count));
};
}
out:
*aNumWritten = aCount - remaining;
@@ -476,7 +476,7 @@ nsStorageInputStream::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
remainingCapacity -= bytesConsumed;
mReadCursor += bytesConsumed;
mLogicalCursor += bytesConsumed;
};
}
out:
*aNumRead = aCount - remainingCapacity;