Merge inbound to central. a=merge

--HG--
rename : servo/components/style/properties/longhand/box.mako.rs => servo/components/style/properties/longhands/box.mako.rs
This commit is contained in:
Cosmin Sabou 2018-06-21 04:16:40 +03:00
Родитель 7f0f3c70f0 f2b10c6146
Коммит 4c18cd4036
254 изменённых файлов: 3054 добавлений и 995 удалений

Просмотреть файл

@ -8,6 +8,9 @@
(^|/)\.DS_Store$
\.pdb
\.egg-info
\.gcda
\.gcno
\.gcov
# Vim swap files.
^\.sw.$

Просмотреть файл

@ -453,7 +453,8 @@ async function setupHistory() {
let today = new Date();
today.setHours(0);
today.setMinutes(0);
today.setSeconds(1);
today.setSeconds(0);
today.setMilliseconds(1);
addPlace("http://today.com/", "Today", today.getTime() * 1000);
let lastYear = new Date();
@ -564,7 +565,8 @@ async function setupFormHistory() {
let today = new Date();
today.setHours(0);
today.setMinutes(0);
today.setSeconds(1);
today.setSeconds(0);
today.setMilliseconds(1);
timestamp = today.getTime() * 1000;
results = await searchEntries(["guid"], { fieldname: "today" });
await update({ op: "update", firstUsed: timestamp, guid: results[0].guid });
@ -655,7 +657,8 @@ async function setupDownloads() {
let today = new Date();
today.setHours(0);
today.setMinutes(0);
today.setSeconds(1);
today.setSeconds(0);
today.setMilliseconds(1);
download = await Downloads.createDownload({
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",

Просмотреть файл

@ -127,10 +127,10 @@ var Policies = {
addAllowDenyPermissions("cookie", param.Allow, param.Block);
if (param.Block) {
const hosts = param.Block.map(uri => uri.host).sort().join("\n");
const hosts = param.Block.map(url => url.hostname).sort().join("\n");
runOncePerModification("clearCookiesForBlockedHosts", hosts, () => {
for (let blocked of param.Block) {
Services.cookies.removeCookiesWithOriginAttributes("{}", blocked.host);
Services.cookies.removeCookiesWithOriginAttributes("{}", blocked.hostname);
}
});
}
@ -508,9 +508,9 @@ var Policies = {
// |homepages| will be a string containing a pipe-separated ('|') list of
// URLs because that is what the "Home page" section of about:preferences
// (and therefore what the pref |browser.startup.homepage|) accepts.
let homepages = param.URL.spec;
let homepages = param.URL.href;
if (param.Additional && param.Additional.length > 0) {
homepages += "|" + param.Additional.map(url => url.spec).join("|");
homepages += "|" + param.Additional.map(url => url.href).join("|");
}
if (param.Locked) {
setAndLockPref("browser.startup.homepage", homepages);
@ -563,14 +563,14 @@ var Policies = {
"OverrideFirstRunPage": {
onProfileAfterChange(manager, param) {
let url = param ? param.spec : "";
let url = param ? param.href : "";
setAndLockPref("startup.homepage_welcome_url", url);
}
},
"OverridePostUpdatePage": {
onProfileAfterChange(manager, param) {
let url = param ? param.spec : "";
let url = param ? param.href : "";
setAndLockPref("startup.homepage_override_url", url);
// The pref startup.homepage_override_url is only used
// as a fallback when the update.xml file hasn't provided
@ -857,18 +857,18 @@ function addAllowDenyPermissions(permissionName, allowList, blockList) {
for (let origin of allowList) {
try {
Services.perms.add(origin,
Services.perms.add(Services.io.newURI(origin.href),
permissionName,
Ci.nsIPermissionManager.ALLOW_ACTION,
Ci.nsIPermissionManager.EXPIRE_POLICY);
} catch (ex) {
log.error(`Added by default for ${permissionName} permission in the permission
manager - ${origin.spec}`);
manager - ${origin.href}`);
}
}
for (let origin of blockList) {
Services.perms.add(origin,
Services.perms.add(Services.io.newURI(origin.href),
permissionName,
Ci.nsIPermissionManager.DENY_ACTION,
Ci.nsIPermissionManager.EXPIRE_POLICY);

Просмотреть файл

@ -8,7 +8,7 @@
* A Bookmark object received through the policy engine will be an
* object with the following properties:
*
* - URL (nsIURI)
* - URL (URL)
* (required) The URL for this bookmark
*
* - Title (string)
@ -25,7 +25,7 @@
* If missing, the bookmark will be created directly into the
* chosen placement.
*
* - Favicon (nsIURI)
* - Favicon (URL)
* (optional) An http:, https: or data: URL with the favicon.
* If possible, we recommend against using this property, in order
* to keep the json file small.
@ -34,7 +34,7 @@
*
*
* Note: The Policy Engine automatically converts the strings given to
* the URL and favicon properties into a nsIURI object.
* the URL and favicon properties into a URL object.
*
* The schema for this object is defined in policies-schema.json.
*/
@ -109,7 +109,7 @@ async function calculateLists(specifiedBookmarks) {
// MAP of url (string) -> bookmarks objects from the Policy Engine
let specifiedBookmarksMap = new Map();
for (let bookmark of specifiedBookmarks) {
specifiedBookmarksMap.set(bookmark.URL.spec, bookmark);
specifiedBookmarksMap.set(bookmark.URL.href, bookmark);
}
// LIST B
@ -193,7 +193,7 @@ async function insertBookmark(bookmark) {
bookmark.Folder);
await PlacesUtils.bookmarks.insert({
url: bookmark.URL,
url: Services.io.newURI(bookmark.URL.href),
title: bookmark.Title,
guid: generateGuidWithPrefix(BookmarksPolicies.BOOKMARK_GUID_PREFIX),
parentGuid,
@ -209,24 +209,24 @@ async function setFaviconForBookmark(bookmark) {
let faviconURI;
let nullPrincipal = Services.scriptSecurityManager.createNullPrincipal({});
switch (bookmark.Favicon.scheme) {
case "data":
switch (bookmark.Favicon.protocol) {
case "data:":
// data urls must first call replaceFaviconDataFromDataURL, using a
// fake URL. Later, it's needed to call setAndFetchFaviconForPage
// with the same URL.
faviconURI = Services.io.newURI("fake-favicon-uri:" + bookmark.URL.spec);
faviconURI = Services.io.newURI("fake-favicon-uri:" + bookmark.URL.href);
PlacesUtils.favicons.replaceFaviconDataFromDataURL(
faviconURI,
bookmark.Favicon.spec,
bookmark.Favicon.href,
0, /* max expiration length */
nullPrincipal
);
break;
case "http":
case "https":
faviconURI = bookmark.Favicon;
case "http:":
case "https:":
faviconURI = Services.io.newURI(bookmark.Favicon.href);
break;
default:
@ -236,7 +236,7 @@ async function setFaviconForBookmark(bookmark) {
return new Promise(resolve => {
PlacesUtils.favicons.setAndFetchFaviconForPage(
bookmark.URL,
Services.io.newURI(bookmark.URL.href),
faviconURI,
false, /* forceReload */
PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,

Просмотреть файл

@ -40,7 +40,7 @@ var ProxyPolicies = {
}
if (param.AutoConfigURL) {
setPref("network.proxy.autoconfig_url", param.AutoConfigURL.spec);
setPref("network.proxy.autoconfig_url", param.AutoConfigURL.href);
}
if (param.UseProxyForDNS !== undefined) {

Просмотреть файл

@ -15,7 +15,7 @@ let CURRENT_POLICY;
const BASE_POLICY = {
"policies": {
"display_bookmarks_toolbar": true,
"DisplayBookmarksToolbar": true,
"Bookmarks": [
{
"Title": "Bookmark 1",

Просмотреть файл

@ -16,9 +16,9 @@ add_task(async function test_proxy_modes_and_autoconfig() {
});
}
let autoconfigURL = Services.io.newURI("data:text/plain,test");
let autoconfigURL = new URL("data:text/plain,test");
ProxyPolicies.configureProxySettings({AutoConfigURL: autoconfigURL}, (_, value) => {
is(value, autoconfigURL.spec, "AutoconfigURL correctly set");
is(value, autoconfigURL.href, "AutoconfigURL correctly set");
});
});

Просмотреть файл

@ -206,6 +206,7 @@ var Sanitizer = {
d.setHours(0); // zero us back to midnight...
d.setMinutes(0);
d.setSeconds(0);
d.setMilliseconds(0);
startDate = d.valueOf() * 1000; // convert to epoch usec
break;
case Sanitizer.TIMESPAN_24HOURS :

Просмотреть файл

@ -2912,6 +2912,27 @@ exports.CSS_PROPERTIES = {
"caret-color",
"scrollbar-face-color",
"scrollbar-track-color",
"text-anchor",
"color-interpolation",
"color-interpolation-filters",
"fill",
"fill-opacity",
"fill-rule",
"shape-rendering",
"stroke",
"stroke-width",
"stroke-linecap",
"stroke-linejoin",
"stroke-miterlimit",
"stroke-opacity",
"stroke-dasharray",
"stroke-dashoffset",
"clip-rule",
"marker-start",
"marker-mid",
"marker-end",
"paint-order",
"-moz-context-properties",
"list-style-position",
"list-style-type",
"list-style-image",
@ -2981,27 +3002,6 @@ exports.CSS_PROPERTIES = {
"-moz-user-select",
"-moz-window-dragging",
"-moz-force-broken-image-icon",
"text-anchor",
"color-interpolation",
"color-interpolation-filters",
"fill",
"fill-opacity",
"fill-rule",
"shape-rendering",
"stroke",
"stroke-width",
"stroke-linecap",
"stroke-linejoin",
"stroke-miterlimit",
"stroke-opacity",
"stroke-dasharray",
"stroke-dashoffset",
"clip-rule",
"marker-start",
"marker-mid",
"marker-end",
"paint-order",
"-moz-context-properties",
"dominant-baseline",
"vector-effect",
"stop-color",

Просмотреть файл

@ -45,7 +45,8 @@ class MOZ_RAII AutoMemMap
public:
explicit AutoMemMap(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
: fd(nullptr)
: fileInfo()
, fd(nullptr)
, fileMap(nullptr)
, addr(nullptr)
{

Просмотреть файл

@ -1359,7 +1359,9 @@ public:
HeapSnapshotHandler(CoreDumpWriter& writer,
JS::CompartmentSet* compartments)
: writer(writer),
compartments(compartments)
compartments(compartments),
nodeCount(0),
edgeCount(0)
{ }
// JS::ubi::BreadthFirst handler interface.

Просмотреть файл

@ -133,6 +133,15 @@ HasUserPassword(const nsACString& aStringURI)
return false;
}
// Assume that 1 tab is accidental, but more than 1 implies this is
// supposed to be tab-separated content.
static bool
MaybeTabSeparatedContent(const nsCString& aStringURI)
{
auto firstTab = aStringURI.FindChar('\t');
return firstTab != kNotFound && aStringURI.RFindChar('\t') != firstTab;
}
NS_IMETHODIMP
nsDefaultURIFixup::GetFixupURIInfo(const nsACString& aStringURI,
uint32_t aFixupFlags,
@ -147,8 +156,8 @@ nsDefaultURIFixup::GetFixupURIInfo(const nsACString& aStringURI,
// Eliminate embedded newlines, which single-line text fields now allow:
uriString.StripCRLF();
// Cleanup the empty spaces that might be on each end:
uriString.Trim(" ");
// Cleanup the empty spaces and tabs that might be on each end:
uriString.Trim(" \t");
NS_ENSURE_TRUE(!uriString.IsEmpty(), NS_ERROR_FAILURE);
@ -360,12 +369,16 @@ nsDefaultURIFixup::GetFixupURIInfo(const nsACString& aStringURI,
inputHadDuffProtocol = true;
}
// NB: this rv gets returned at the end of this method if we never
// do a keyword fixup after this (because the pref or the flags passed
// might not let us).
rv = FixupURIProtocol(uriString, info, getter_AddRefs(uriWithProtocol));
if (uriWithProtocol) {
info->mFixedURI = uriWithProtocol;
// Note: this rv gets returned at the end of this method if we don't fix up
// the protocol and don't do a keyword fixup after this (because the pref
// or the flags passed might not let us).
rv = NS_OK;
// Avoid fixing up content that looks like tab-separated values
if (!MaybeTabSeparatedContent(uriString)) {
rv = FixupURIProtocol(uriString, info, getter_AddRefs(uriWithProtocol));
if (uriWithProtocol) {
info->mFixedURI = uriWithProtocol;
}
}
// See if it is a keyword

Просмотреть файл

@ -493,6 +493,16 @@ var testcases = [ {
alternateURI: "http://www.xn--lodaehvb5cdik4g.xn--node/",
protocolChange: true,
},
{
input: " \t mozilla.org/\t \t ",
fixedURI: "http://mozilla.org/",
alternateURI: "http://www.mozilla.org/",
protocolChange: true,
},
{
input: " moz\ti\tlla.org ",
keywordLookup: true,
},
];
if (Services.appinfo.OS.toLowerCase().startsWith("win")) {
@ -589,24 +599,25 @@ function do_single_test_run() {
// Both APIs should then also be using the same spec.
Assert.equal(!!fixupURIOnly, !!URIInfo.preferredURI);
if (fixupURIOnly)
Assert.equal(fixupURIOnly.spec, URIInfo.preferredURI.spec);
if (fixupURIOnly) {
Assert.equal(fixupURIOnly.spec, URIInfo.preferredURI.spec, "Fixed and preferred URI should match");
}
let isFileURL = expectedFixedURI && expectedFixedURI.startsWith("file");
// Check the fixedURI:
let makeAlternativeURI = flags & urifixup.FIXUP_FLAGS_MAKE_ALTERNATE_URI;
if (makeAlternativeURI && alternativeURI != null) {
Assert.equal(URIInfo.fixedURI.spec, alternativeURI);
Assert.equal(URIInfo.fixedURI.spec, alternativeURI, "should have gotten alternate URI");
} else {
Assert.equal(URIInfo.fixedURI && URIInfo.fixedURI.spec, expectedFixedURI);
Assert.equal(URIInfo.fixedURI && URIInfo.fixedURI.spec, expectedFixedURI, "should get correct fixed URI");
}
// Check booleans on input:
let couldDoKeywordLookup = flags & urifixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
Assert.equal(!!URIInfo.keywordProviderName, couldDoKeywordLookup && expectKeywordLookup);
Assert.equal(URIInfo.fixupChangedProtocol, expectProtocolChange);
Assert.equal(URIInfo.fixupCreatedAlternateURI, makeAlternativeURI && alternativeURI != null);
Assert.equal(!!URIInfo.keywordProviderName, couldDoKeywordLookup && expectKeywordLookup, "keyword lookup as expected");
Assert.equal(URIInfo.fixupChangedProtocol, expectProtocolChange, "protocol change as expected");
Assert.equal(URIInfo.fixupCreatedAlternateURI, makeAlternativeURI && alternativeURI != null, "alternative URI as expected");
// Check the preferred URI
if (couldDoKeywordLookup) {
@ -620,19 +631,21 @@ function do_single_test_run() {
}
let searchURL = kSearchEngineURL.replace("{searchTerms}", urlparamInput);
let spec = URIInfo.preferredURI.spec.replace(/%27/g, "'");
Assert.equal(spec, searchURL);
Assert.equal(spec, searchURL, "should get correct search URI");
} else {
Assert.equal(URIInfo.preferredURI, null);
Assert.equal(URIInfo.preferredURI, null, "not expecting a preferred URI");
}
} else {
Assert.equal(URIInfo.preferredURI.spec, URIInfo.fixedURI.spec);
Assert.equal(URIInfo.preferredURI.spec, URIInfo.fixedURI.spec, "fixed URI should match");
}
} else {
// In these cases, we should never be doing a keyword lookup and
// the fixed URI should be preferred:
Assert.equal(URIInfo.preferredURI.spec, URIInfo.fixedURI.spec);
let prefURI = URIInfo.preferredURI && URIInfo.preferredURI.spec;
let fixedURI = URIInfo.fixedURI && URIInfo.fixedURI.spec;
Assert.equal(prefURI, fixedURI, "fixed URI should be same as expected");
}
Assert.equal(sanitize(testInput), URIInfo.originalInput);
Assert.equal(sanitize(testInput), URIInfo.originalInput, "should mirror original input");
}
}
}

Просмотреть файл

@ -80,6 +80,8 @@
#include "mozilla/Preferences.h"
#include "mozilla/ResultExtensions.h"
#include "mozilla/dom/Selection.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPrefs.h"
#include "mozilla/TextEvents.h"
#include "nsArrayUtils.h"
#include "nsAString.h"
@ -512,6 +514,41 @@ EventListenerManagerHashClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
lm->~EventListenerManagerMapEntry();
}
static bool
IsThirdPartyWindowOrChannel(nsPIDOMWindowInner* aWindow,
nsIChannel* aChannel,
nsIURI* aURI)
{
MOZ_ASSERT(!aWindow || !aChannel,
"A window and channel should not both be provided.");
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil = services::GetThirdPartyUtil();
if (!thirdPartyUtil) {
return false;
}
// In the absence of a window or channel, we assume that we are first-party.
bool thirdParty = false;
if (aWindow) {
Unused << thirdPartyUtil->IsThirdPartyWindow(aWindow->GetOuterWindow(),
aURI,
&thirdParty);
}
if (aChannel) {
// Note, we must call IsThirdPartyChannel() here and not just try to
// use nsILoadInfo.isThirdPartyContext. That nsILoadInfo property only
// indicates if the parent loading window is third party or not. We
// want to check the channel URI against the loading principal as well.
Unused << thirdPartyUtil->IsThirdPartyChannel(aChannel,
nullptr,
&thirdParty);
}
return thirdParty;
}
class SameOriginCheckerImpl final : public nsIChannelEventSink,
public nsIInterfaceRequestor
{
@ -8815,6 +8852,36 @@ nsContentUtils::GetCookieBehaviorForPrincipal(nsIPrincipal* aPrincipal,
}
}
// static public
bool
nsContentUtils::StorageDisabledByAntiTracking(nsPIDOMWindowInner* aWindow,
nsIChannel* aChannel,
nsIURI* aURI)
{
if (!StaticPrefs::privacy_trackingprotection_storagerestriction_enabled()) {
return false;
}
// Let's check if this is a 3rd party context.
if (!IsThirdPartyWindowOrChannel(aWindow, aChannel, aURI)) {
return false;
}
nsCOMPtr<nsIChannel> channel;
// aChannel and aWindow are mutually exclusive.
channel = aChannel;
if (aWindow) {
nsIDocument* document = aWindow->GetExtantDoc();
if (document) {
channel = document->GetChannel();
}
}
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
return httpChannel && httpChannel->GetIsTrackingResource();
}
// static, private
nsContentUtils::StorageAccess
nsContentUtils::InternalStorageAllowedForPrincipal(nsIPrincipal* aPrincipal,
@ -8832,6 +8899,10 @@ nsContentUtils::InternalStorageAllowedForPrincipal(nsIPrincipal* aPrincipal,
return StorageAccess::eDeny;
}
if (StorageDisabledByAntiTracking(aWindow, aChannel, aURI)) {
return StorageAccess::eDeny;
}
if (aWindow) {
// If the document is sandboxed, then it is not permitted to use storage
nsIDocument* document = aWindow->GetExtantDoc();
@ -8907,47 +8978,15 @@ nsContentUtils::InternalStorageAllowedForPrincipal(nsIPrincipal* aPrincipal,
return StorageAccess::eDeny;
}
if (behavior == nsICookieService::BEHAVIOR_REJECT_FOREIGN ||
behavior == nsICookieService::BEHAVIOR_LIMIT_FOREIGN) {
if ((behavior == nsICookieService::BEHAVIOR_REJECT_FOREIGN ||
behavior == nsICookieService::BEHAVIOR_LIMIT_FOREIGN) &&
IsThirdPartyWindowOrChannel(aWindow, aChannel, aURI)) {
// XXX For non-cookie forms of storage, we handle BEHAVIOR_LIMIT_FOREIGN by
// simply rejecting the request to use the storage. In the future, if we
// change the meaning of BEHAVIOR_LIMIT_FOREIGN to be one which makes sense
// for non-cookie storage types, this may change.
// In the absence of a window or channel, we assume that we are first-party.
bool thirdParty = false;
MOZ_ASSERT(!aWindow || !aChannel,
"A window and channel should not both be provided.");
if (aWindow) {
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
do_GetService(THIRDPARTYUTIL_CONTRACTID);
MOZ_ASSERT(thirdPartyUtil);
Unused << thirdPartyUtil->IsThirdPartyWindow(aWindow->GetOuterWindow(),
aURI,
&thirdParty);
}
if (aChannel) {
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
do_GetService(THIRDPARTYUTIL_CONTRACTID);
MOZ_ASSERT(thirdPartyUtil);
// Note, we must call IsThirdPartyChannel() here and not just try to
// use nsILoadInfo.isThirdPartyContext. That nsILoadInfo property only
// indicates if the parent loading window is third party or not. We
// want to check the channel URI against the loading principal as well.
Unused << thirdPartyUtil->IsThirdPartyChannel(aChannel,
nullptr,
&thirdParty);
}
if (thirdParty) {
// XXX For non-cookie forms of storage, we handle BEHAVIOR_LIMIT_FOREIGN by
// simply rejecting the request to use the storage. In the future, if we
// change the meaning of BEHAVIOR_LIMIT_FOREIGN to be one which makes sense
// for non-cookie storage types, this may change.
return StorageAccess::eDeny;
}
return StorageAccess::eDeny;
}
return access;

Просмотреть файл

@ -2954,6 +2954,14 @@ public:
*/
static StorageAccess StorageAllowedForPrincipal(nsIPrincipal* aPrincipal);
/*
* Returns true if this window/channel should disable storages because of the
* anti-tracking feature.
*/
static bool StorageDisabledByAntiTracking(nsPIDOMWindowInner* aWindow,
nsIChannel* aChannel,
nsIURI* aURI);
/*
* Serializes a HTML nsINode into its markup representation.
*/

Просмотреть файл

@ -941,6 +941,10 @@ nsGlobalWindowInner::nsGlobalWindowInner(nsGlobalWindowOuter *aOuterWindow)
false);
os->AddObserver(mObserver, MEMORY_PRESSURE_OBSERVER_TOPIC, false);
if (aOuterWindow->IsTopLevelWindow()) {
os->AddObserver(mObserver, "clear-site-data-reload-needed", false);
}
}
Preferences::AddStrongObserver(mObserver, "intl.accept_languages");
@ -1268,6 +1272,11 @@ nsGlobalWindowInner::FreeInnerObjects()
if (os) {
os->RemoveObserver(mObserver, NS_IOSERVICE_OFFLINE_STATUS_TOPIC);
os->RemoveObserver(mObserver, MEMORY_PRESSURE_OBSERVER_TOPIC);
if (GetOuterWindowInternal() &&
GetOuterWindowInternal()->IsTopLevelWindow()) {
os->RemoveObserver(mObserver, "clear-site-data-reload-needed");
}
}
RefPtr<StorageNotifierService> sns = StorageNotifierService::GetOrCreate();
@ -5818,6 +5827,13 @@ nsGlobalWindowInner::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK;
}
if (!nsCRT::strcmp(aTopic, "clear-site-data-reload-needed")) {
// The reload is propagated from the top-level window only.
NS_ConvertUTF16toUTF8 otherOrigin(aData);
PropagateClearSiteDataReload(otherOrigin);
return NS_OK;
}
if (!nsCRT::strcmp(aTopic, OBSERVER_TOPIC_IDLE)) {
mCurrentlyIdle = true;
if (IsFrozen()) {
@ -8053,6 +8069,39 @@ nsPIDOMWindowInner::MaybeCreateDoc()
}
}
void
nsGlobalWindowInner::PropagateClearSiteDataReload(const nsACString& aOrigin)
{
nsIPrincipal* principal = GetPrincipal();
if (!principal) {
return;
}
nsAutoCString origin;
nsresult rv = principal->GetOrigin(origin);
NS_ENSURE_SUCCESS_VOID(rv);
// If the URL of this window matches, let's refresh this window only.
// We don't need to traverse the DOM tree.
if (origin.Equals(aOrigin)) {
nsCOMPtr<nsIDocShell> docShell = GetDocShell();
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(docShell));
if (NS_WARN_IF(!webNav)) {
return;
}
// We don't need any special reload flags, because this notification is
// dispatched by Clear-Site-Data header, which should have already cleaned
// up all the needed data.
rv = webNav->Reload(nsIWebNavigation::LOAD_FLAGS_NONE);
NS_ENSURE_SUCCESS_VOID(rv);
return;
}
CallOnChildren(&nsGlobalWindowInner::PropagateClearSiteDataReload, aOrigin);
}
mozilla::dom::DocGroup*
nsPIDOMWindowInner::GetDocGroup() const
{

Просмотреть файл

@ -979,6 +979,8 @@ public:
bool ShouldReportForServiceWorkerScope(const nsAString& aScope);
void PropagateClearSiteDataReload(const nsACString& aOrigin);
already_AddRefed<mozilla::dom::InstallTriggerImpl> GetInstallTrigger();
void UpdateTopInnerWindow();

Просмотреть файл

@ -17,6 +17,7 @@
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/BackgroundUtils.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "mozilla/StaticPrefs.h"
#include "nsContentUtils.h"
#include "nsIBFCacheEntry.h"
@ -299,12 +300,25 @@ BroadcastChannel::Constructor(const GlobalObject& aGlobal,
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
if (StaticPrefs::privacy_trackingprotection_storagerestriction_enabled() &&
nsContentUtils::StorageAllowedForWindow(window) !=
nsContentUtils::StorageAccess::eAllow) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
}
} else {
JSContext* cx = aGlobal.Context();
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
MOZ_ASSERT(workerPrivate);
if (StaticPrefs::privacy_trackingprotection_storagerestriction_enabled() &&
!workerPrivate->IsStorageAllowed()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
}
RefPtr<StrongWorkerRef> workerRef =
StrongWorkerRef::Create(workerPrivate, "BroadcastChannel",
[bc] () { bc->Shutdown(); });

Просмотреть файл

@ -1106,6 +1106,11 @@ nsHTMLDocument::GetCookie(nsAString& aCookie, ErrorResult& rv)
return;
}
if (nsContentUtils::StorageDisabledByAntiTracking(GetInnerWindow(), nullptr,
nullptr)) {
return;
}
// If the document is a cookie-averse Document... return the empty string.
if (IsCookieAverse()) {
return;

Просмотреть файл

@ -2589,6 +2589,18 @@ ContentChild::RecvUpdateRequestedLocales(nsTArray<nsCString>&& aRequestedLocales
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentChild::RecvClearSiteDataReloadNeeded(const nsString& aOrigin)
{
// Rebroadcast "clear-site-data-reload-needed".
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->NotifyObservers(nullptr, "clear-site-data-reload-needed",
aOrigin.get());
}
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentChild::RecvAddPermission(const IPC::Permission& permission)
{

Просмотреть файл

@ -405,6 +405,8 @@ public:
virtual mozilla::ipc::IPCResult RecvUpdateAppLocales(nsTArray<nsCString>&& aAppLocales) override;
virtual mozilla::ipc::IPCResult RecvUpdateRequestedLocales(nsTArray<nsCString>&& aRequestedLocales) override;
virtual mozilla::ipc::IPCResult RecvClearSiteDataReloadNeeded(const nsString& aOrigin) override;
virtual mozilla::ipc::IPCResult RecvAddPermission(const IPC::Permission& permission) override;
virtual mozilla::ipc::IPCResult RecvFlushMemory(const nsString& reason) override;

Просмотреть файл

@ -594,6 +594,7 @@ static const char* sObserverTopics[] = {
"intl:requested-locales-changed",
"cookie-changed",
"private-cookie-changed",
"clear-site-data-reload-needed",
};
// PreallocateProcess is called by the PreallocatedProcessManager.
@ -3012,6 +3013,9 @@ ContentParent::Observe(nsISupports* aSubject,
(!nsCRT::strcmp(aData, u"changed"))) {
cs->AddCookie(xpcCookie);
}
} else if (!strcmp(aTopic, "clear-site-data-reload-needed")) {
// Rebroadcast "clear-site-data-reload-needed".
Unused << SendClearSiteDataReloadNeeded(nsString(aData));
}
return NS_OK;
}

Просмотреть файл

@ -455,6 +455,8 @@ child:
async UpdateAppLocales(nsCString[] appLocales);
async UpdateRequestedLocales(nsCString[] requestedLocales);
async ClearSiteDataReloadNeeded(nsString origin);
// nsIPermissionManager messages
async AddPermission(Permission permission);

Просмотреть файл

@ -94,3 +94,5 @@ BlockSubresourceFTP=Loading FTP subresource within http(s) page not allowed (Blo
# LOCALIZATION NOTE (BrowserUpgradeInsecureDisplayRequest):
# %1$S is the browser name "brandShortName"; %2$S is the URL of the upgraded request; %1$S is the upgraded scheme.
BrowserUpgradeInsecureDisplayRequest = %1$S is upgrading an insecure display request %2$S to use %3$S
RunningClearSiteDataValue=Clear-Site-Data header forces the clean up of “%S” data.
UnknownClearSiteDataValue=Clear-Site-Data header found. Unknown value “%S”.

Просмотреть файл

@ -113,8 +113,8 @@ static NPNetscapeFuncs sBrowserFuncs = {
_memfree,
_memflush,
_reloadplugins,
nullptr, // _getJavaEnv, unimplemented
nullptr, // _getJavaPeer, unimplemented
_getJavaEnv,
_getJavaPeer,
_geturlnotify,
_posturlnotify,
_getvalue,
@ -1703,6 +1703,14 @@ _requestread(NPStream *pstream, NPByteRange *rangeList)
return NPERR_STREAM_NOT_SEEKABLE;
}
// Deprecated, only stubbed out
void* /* OJI type: JRIEnv* */
_getJavaEnv()
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetJavaEnv\n"));
return nullptr;
}
const char *
_useragent(NPP npp)
{
@ -1736,6 +1744,14 @@ _memalloc (uint32_t size)
return moz_xmalloc(size);
}
// Deprecated, only stubbed out
void* /* OJI type: jref */
_getJavaPeer(NPP npp)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetJavaPeer: npp=%p\n", (void*)npp));
return nullptr;
}
void
_pushpopupsenabledstate(NPP npp, NPBool enabled)
{

Просмотреть файл

@ -279,6 +279,13 @@ _useragent(NPP npp);
void*
_memalloc (uint32_t size);
// Deprecated entry points for the old Java plugin.
void* /* OJI type: JRIEnv* */
_getJavaEnv();
void* /* OJI type: jref */
_getJavaPeer(NPP npp);
void
_urlredirectresponse(NPP instance, void* notifyData, NPBool allow);

Просмотреть файл

@ -875,6 +875,14 @@ _useragent(NPP aNPP);
static void*
_memalloc (uint32_t size);
// Deprecated entry points for the old Java plugin.
static void* /* OJI type: JRIEnv* */
_getjavaenv(void);
// Deprecated entry points for the old Java plugin.
static void* /* OJI type: jref */
_getjavapeer(NPP aNPP);
static bool
_invoke(NPP aNPP, NPObject* npobj, NPIdentifier method, const NPVariant *args,
uint32_t argCount, NPVariant *result);
@ -979,8 +987,8 @@ const NPNetscapeFuncs PluginModuleChild::sBrowserFuncs = {
mozilla::plugins::child::_memfree,
mozilla::plugins::child::_memflush,
mozilla::plugins::child::_reloadplugins,
nullptr, // _getjavaenv, unimplemented
nullptr, // _getjavapeer, unimplemented
mozilla::plugins::child::_getjavaenv,
mozilla::plugins::child::_getjavapeer,
mozilla::plugins::child::_geturlnotify,
mozilla::plugins::child::_posturlnotify,
mozilla::plugins::child::_getvalue,
@ -1296,6 +1304,21 @@ _memalloc(uint32_t aSize)
return moz_xmalloc(aSize);
}
// Deprecated entry points for the old Java plugin.
void* /* OJI type: JRIEnv* */
_getjavaenv(void)
{
PLUGIN_LOG_DEBUG_FUNCTION;
return 0;
}
void* /* OJI type: jref */
_getjavapeer(NPP aNPP)
{
PLUGIN_LOG_DEBUG_FUNCTION;
return 0;
}
bool
_invoke(NPP aNPP,
NPObject* aNPObj,

Просмотреть файл

@ -180,6 +180,13 @@ nsContentSecurityManager::CheckFTPSubresourceLoad(nsIChannel* aChannel)
return NS_OK;
}
// Allow the system principal to load everything. This is meant to
// temporarily fix downloads and pdf.js.
nsIPrincipal* triggeringPrincipal = loadInfo->TriggeringPrincipal();
if (nsContentUtils::IsSystemPrincipal(triggeringPrincipal)) {
return NS_OK;
}
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
@ -193,7 +200,6 @@ nsContentSecurityManager::CheckFTPSubresourceLoad(nsIChannel* aChannel)
}
// Allow loading FTP subresources in FTP documents, like XML.
nsIPrincipal* triggeringPrincipal = loadInfo->TriggeringPrincipal();
nsCOMPtr<nsIURI> triggeringURI;
triggeringPrincipal->GetURI(getter_AddRefs(triggeringURI));
if (triggeringURI && nsContentUtils::SchemeIs(triggeringURI, "ftp")) {

Просмотреть файл

@ -308,9 +308,7 @@ LoadContextOptions(const char* aPrefName, void* /* aClosure */)
.setFuzzing(GetWorkerPref<bool>(NS_LITERAL_CSTRING("fuzzing.enabled")))
#endif
.setStreams(GetWorkerPref<bool>(NS_LITERAL_CSTRING("streams")))
.setExtraWarnings(GetWorkerPref<bool>(NS_LITERAL_CSTRING("strict")))
.setArrayProtoValues(GetWorkerPref<bool>(
NS_LITERAL_CSTRING("array_prototype_values")));
.setExtraWarnings(GetWorkerPref<bool>(NS_LITERAL_CSTRING("strict")));
nsCOMPtr<nsIXULRuntime> xr = do_GetService("@mozilla.org/xre/runtime;1");
if (xr) {

Просмотреть файл

@ -91,7 +91,7 @@ ClipManager::PushOverrideForASR(const ActiveScrolledRoot* aASR,
Maybe<wr::WrClipId> scrollId = mBuilder->GetScrollIdForDefinedScrollLayer(viewId);
MOZ_ASSERT(scrollId.isSome());
CLIP_LOG("Pushing override %" PRIu64 " -> %s\n", scrollId->id,
CLIP_LOG("Pushing override %zu -> %s\n", scrollId->id,
aClipId ? Stringify(aClipId->id).c_str() : "(none)");
auto it = mASROverride.insert({ *scrollId, std::stack<Maybe<wr::WrClipId>>() });
it.first->second.push(aClipId);
@ -114,7 +114,7 @@ ClipManager::PopOverrideForASR(const ActiveScrolledRoot* aASR)
auto it = mASROverride.find(*scrollId);
MOZ_ASSERT(it != mASROverride.end());
MOZ_ASSERT(!(it->second.empty()));
CLIP_LOG("Popping override %" PRIu64 " -> %s\n", scrollId->id,
CLIP_LOG("Popping override %zu -> %s\n", scrollId->id,
it->second.top() ? Stringify(it->second.top()->id).c_str() : "(none)");
it->second.pop();
if (it->second.empty()) {
@ -133,7 +133,7 @@ ClipManager::ClipIdAfterOverride(const Maybe<wr::WrClipId>& aClipId)
return aClipId;
}
MOZ_ASSERT(!it->second.empty());
CLIP_LOG("Overriding %" PRIu64 " with %s\n", aClipId->id,
CLIP_LOG("Overriding %zu with %s\n", aClipId->id,
it->second.top() ? Stringify(it->second.top()->id).c_str() : "(none)");
return it->second.top();
}
@ -309,7 +309,7 @@ ClipManager::DefineClipChain(const DisplayItemClipChain* aChain,
if (it != cache.end()) {
// Found it in the currently-active cache, so just use the id we have for
// it.
CLIP_LOG("cache[%p] => %" PRIu64 "\n", chain, it->second.id);
CLIP_LOG("cache[%p] => %zu\n", chain, it->second.id);
clipIds.AppendElement(it->second);
continue;
}
@ -339,7 +339,7 @@ ClipManager::DefineClipChain(const DisplayItemClipChain* aChain,
wr::ToRoundedLayoutRect(clip), &wrRoundedRects);
clipIds.AppendElement(clipId);
cache[chain] = clipId;
CLIP_LOG("cache[%p] <= %" PRIu64 "\n", chain, clipId.id);
CLIP_LOG("cache[%p] <= %zu\n", chain, clipId.id);
}
// Now find the parent display item's clipchain id

Просмотреть файл

@ -514,6 +514,7 @@ static void read_nested_curveType(struct mem_source *src, struct curveType *(*cu
(*curveArray)[i] = read_curveType(src, curve_offset + channel_offset, &tag_len);
if (!(*curveArray)[i]) {
invalid_source(src, "invalid nested curveType curve");
break;
}
channel_offset += tag_len;

Просмотреть файл

@ -16,6 +16,8 @@
#include "nsExpirationTracker.h"
#include "nsClassHashtable.h"
#include "gfxUtils.h"
#include <limits>
#include <cmath>
using namespace mozilla;
using namespace mozilla::gfx;
@ -953,6 +955,16 @@ gfxAlphaBoxBlur::BlurRectangle(gfxContext* aDestinationCtx,
const gfxRect& aDirtyRect,
const gfxRect& aSkipRect)
{
const double maxSize = (double)gfxPlatform::MaxTextureSize();
const double maxPos = (double)std::numeric_limits<std::int16_t>::max();
if (aRect.width > maxSize || aRect.height > maxSize ||
std::abs(aRect.x) > maxPos || std::abs(aRect.y) > maxPos) {
// The rectangle is huge, perhaps due to a very strong perspective or some other
// transform. We won't be able to blur something this big so give up now before
// overflowing or running into texture size limits later.
return;
}
IntSize blurRadius = CalculateBlurRadius(aBlurStdDev);
bool mirrorCorners = !aCornerRadii || aCornerRadii->AreRadiiSame();

Просмотреть файл

@ -7,6 +7,7 @@
#include "mozilla/HashFunctions.h"
#include "mozilla/Move.h"
#include "nsContentUtils.h"
#include "nsLayoutUtils.h"
#include "nsString.h"
#include "mozilla/dom/BlobURLProtocolHandler.h"
@ -42,7 +43,7 @@ ImageCacheKey::ImageCacheKey(nsIURI* aURI,
nsresult& aRv)
: mURI(aURI)
, mOriginAttributes(aAttrs)
, mControlledDocument(GetControlledDocumentToken(aDocument))
, mControlledDocument(GetSpecialCaseDocumentToken(aDocument, aURI))
, mHash(0)
, mIsChrome(false)
{
@ -125,11 +126,10 @@ ImageCacheKey::SchemeIs(const char* aScheme)
}
/* static */ void*
ImageCacheKey::GetControlledDocumentToken(nsIDocument* aDocument)
ImageCacheKey::GetSpecialCaseDocumentToken(nsIDocument* aDocument, nsIURI* aURI)
{
// For non-controlled documents, we just return null. For controlled
// documents, we cast the pointer into a void* to avoid dereferencing
// it (since we only use it for comparisons), and return it.
// For controlled documents, we cast the pointer into a void* to avoid
// dereferencing it (since we only use it for comparisons).
void* pointer = nullptr;
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
if (aDocument && swm) {
@ -138,6 +138,16 @@ ImageCacheKey::GetControlledDocumentToken(nsIDocument* aDocument)
pointer = aDocument;
}
}
// If this document has been marked as tracker, let's use its address to make
// a unique cache key.
if (!pointer && aDocument &&
nsContentUtils::StorageDisabledByAntiTracking(nullptr,
aDocument->GetChannel(),
aURI)) {
pointer = aDocument;
}
return pointer;
}

Просмотреть файл

@ -41,9 +41,11 @@ public:
bool operator==(const ImageCacheKey& aOther) const;
PLDHashNumber Hash() const { return mHash; }
/// A weak pointer to the URI. For logging only.
/// A weak pointer to the URI.
nsIURI* URI() const { return mURI; }
const OriginAttributes& OriginAttributesRef() const { return mOriginAttributes; }
/// Is this cache entry for a chrome image?
bool IsChrome() const { return mIsChrome; }
@ -53,7 +55,11 @@ public:
private:
bool SchemeIs(const char* aScheme);
static void* GetControlledDocumentToken(nsIDocument* aDocument);
// For ServiceWorker and for anti-tracking we need to use the document as
// token for the key. All those exceptions are handled by this method.
static void* GetSpecialCaseDocumentToken(nsIDocument* aDocument,
nsIURI* aURI);
nsCOMPtr<nsIURI> mURI;
Maybe<uint64_t> mBlobSerial;

Просмотреть файл

@ -8,11 +8,20 @@
interface imgIRequest;
interface nsIDocument;
interface nsIPrincipal;
interface nsIProperties;
interface nsIURI;
webidl Document;
%{ C++
namespace mozilla {
class OriginAttributes;
} // mozilla namespace
%}
[ptr] native OriginAttributesPtr(mozilla::OriginAttributes);
/**
* imgICache interface
*
@ -41,6 +50,14 @@ interface imgICache : nsISupports
*/
[noscript] void removeEntry(in nsIURI uri, [optional] in Document doc);
/**
* Evict images from the cache with the same origin and the same
* originAttributes of the passed principal.
*
* @param aPrincipal The principal
*/
void removeEntriesFromPrincipal(in nsIPrincipal aPrincipal);
/**
* Find Properties
* Used to get properties such as 'type' and 'content-disposition'

Просмотреть файл

@ -1469,6 +1469,45 @@ imgLoader::ClearCache(bool chrome)
}
NS_IMETHODIMP
imgLoader::RemoveEntriesFromPrincipal(nsIPrincipal* aPrincipal)
{
nsAutoString origin;
nsresult rv = nsContentUtils::GetUTFOrigin(aPrincipal, origin);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
AutoTArray<RefPtr<imgCacheEntry>, 128> entriesToBeRemoved;
imgCacheTable& cache = GetCache(nsContentUtils::IsSystemPrincipal(aPrincipal));
for (auto iter = cache.Iter(); !iter.Done(); iter.Next()) {
auto& key = iter.Key();
if (key.OriginAttributesRef() != BasePrincipal::Cast(aPrincipal)->OriginAttributesRef()) {
continue;
}
nsAutoString imageOrigin;
nsresult rv = nsContentUtils::GetUTFOrigin(key.URI(), imageOrigin);
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
if (imageOrigin == origin) {
entriesToBeRemoved.AppendElement(iter.Data());
}
}
for (auto& entry : entriesToBeRemoved) {
if (!RemoveFromCache(entry)) {
NS_WARNING("Couldn't remove an entry from the cache in RemoveEntriesFromPrincipal()\n");
}
}
return NS_OK;
}
NS_IMETHODIMP
imgLoader::RemoveEntry(nsIURI* aURI,
nsIDocument* aDoc)

Просмотреть файл

@ -262,11 +262,14 @@ EvalKernel(JSContext* cx, HandleValue v, EvalType evalType, AbstractFramePtr cal
const char* filename;
bool mutedErrors;
uint32_t pcOffset;
DescribeScriptedCallerForCompilation(cx, &maybeScript, &filename, &lineno, &pcOffset,
&mutedErrors,
evalType == DIRECT_EVAL
? CALLED_FROM_JSOP_EVAL
: NOT_CALLED_FROM_JSOP_EVAL);
if (evalType == DIRECT_EVAL) {
DescribeScriptedCallerForDirectEval(cx, callerScript, pc, &filename, &lineno,
&pcOffset, &mutedErrors);
maybeScript = callerScript;
} else {
DescribeScriptedCallerForCompilation(cx, &maybeScript, &filename, &lineno, &pcOffset,
&mutedErrors);
}
const char* introducerFilename = filename;
if (maybeScript && maybeScript->scriptSource()->introducerFilename())
@ -344,17 +347,16 @@ js::DirectEvalStringFromIon(JSContext* cx,
esg.lookupInEvalCache(linearStr, callerScript, pc);
if (!esg.foundScript()) {
RootedScript maybeScript(cx);
const char* filename;
unsigned lineno;
bool mutedErrors;
uint32_t pcOffset;
DescribeScriptedCallerForCompilation(cx, &maybeScript, &filename, &lineno, &pcOffset,
&mutedErrors, CALLED_FROM_JSOP_EVAL);
DescribeScriptedCallerForDirectEval(cx, callerScript, pc, &filename, &lineno, &pcOffset,
&mutedErrors);
const char* introducerFilename = filename;
if (maybeScript && maybeScript->scriptSource()->introducerFilename())
introducerFilename = maybeScript->scriptSource()->introducerFilename();
if (callerScript->scriptSource()->introducerFilename())
introducerFilename = callerScript->scriptSource()->introducerFilename();
RootedScope enclosing(cx, callerScript->innermostScope(pc));
@ -366,7 +368,8 @@ js::DirectEvalStringFromIon(JSContext* cx,
if (introducerFilename) {
options.setFileAndLine(filename, 1);
options.setIntroductionInfo(introducerFilename, "eval", lineno, maybeScript, pcOffset);
options.setIntroductionInfo(introducerFilename, "eval", lineno, callerScript,
pcOffset);
} else {
options.setFileAndLine("eval", 1);
options.setIntroductionType("eval");

Просмотреть файл

@ -1360,7 +1360,7 @@ CaptureFirstSubsumedFrame(JSContext* cx, unsigned argc, JS::Value* vp)
return false;
}
JS::StackCapture capture(JS::FirstSubsumedFrame(cx, obj->realm()->principals()));
JS::StackCapture capture(JS::FirstSubsumedFrame(cx, obj->nonCCWRealm()->principals()));
if (args.length() > 1)
capture.as<JS::FirstSubsumedFrame>().ignoreSelfHosted = JS::ToBoolean(args[1]);

Просмотреть файл

@ -339,13 +339,13 @@ static const uint32_t ReferenceSizes[] = {
uint32_t
ReferenceTypeDescr::size(Type t)
{
return ReferenceSizes[t];
return ReferenceSizes[uint32_t(t)];
}
uint32_t
ReferenceTypeDescr::alignment(Type t)
{
return ReferenceSizes[t];
return ReferenceSizes[uint32_t(t)];
}
/*static*/ const char*
@ -375,11 +375,11 @@ js::ReferenceTypeDescr::call(JSContext* cx, unsigned argc, Value* vp)
}
switch (descr->type()) {
case ReferenceTypeDescr::TYPE_ANY:
case ReferenceType::TYPE_ANY:
args.rval().set(args[0]);
return true;
case ReferenceTypeDescr::TYPE_OBJECT:
case ReferenceType::TYPE_OBJECT:
{
RootedObject obj(cx, ToObject(cx, args[0]));
if (!obj)
@ -388,7 +388,7 @@ js::ReferenceTypeDescr::call(JSContext* cx, unsigned argc, Value* vp)
return true;
}
case ReferenceTypeDescr::TYPE_STRING:
case ReferenceType::TYPE_STRING:
{
RootedString obj(cx, ToString<CanGC>(cx, args[0]));
if (!obj)
@ -766,7 +766,45 @@ const JSFunctionSpec StructMetaTypeDescr::typedObjectMethods[] = {
JS_FS_END
};
JSObject*
CheckedInt32
StructMetaTypeDescr::Layout::addField(int32_t fieldAlignment, int32_t fieldSize)
{
// Alignment of the struct is the max of the alignment of its fields.
structAlignment = js::Max(structAlignment, fieldAlignment);
// Align the pointer.
CheckedInt32 offset = RoundUpToAlignment(sizeSoFar, fieldAlignment);
if (!offset.isValid())
return offset;
// Allocate space.
sizeSoFar = offset + fieldSize;
if (!sizeSoFar.isValid())
return sizeSoFar;
return offset;
}
CheckedInt32
StructMetaTypeDescr::Layout::addScalar(Scalar::Type type) {
return addField(ScalarTypeDescr::alignment(type),
ScalarTypeDescr::size(type));
}
CheckedInt32
StructMetaTypeDescr::Layout::addReference(ReferenceType type) {
return addField(ReferenceTypeDescr::alignment(type),
ReferenceTypeDescr::size(type));
}
CheckedInt32
StructMetaTypeDescr::Layout::close(int32_t *alignment) {
if (alignment)
*alignment = structAlignment;
return RoundUpToAlignment(sizeSoFar, structAlignment);
}
/* static */ JSObject*
StructMetaTypeDescr::create(JSContext* cx,
HandleObject metaTypeDescr,
HandleObject fields)
@ -779,30 +817,13 @@ StructMetaTypeDescr::create(JSContext* cx,
// Iterate through each field. Collect values for the various
// vectors below and also track total size and alignment. Be wary
// of overflow!
StringBuffer stringBuffer(cx); // Canonical string repr
AutoValueVector fieldNames(cx); // Name of each field.
AutoValueVector fieldTypeObjs(cx); // Type descriptor of each field.
AutoValueVector fieldOffsets(cx); // Offset of each field field.
RootedObject userFieldOffsets(cx); // User-exposed {f:offset} object
RootedObject userFieldTypes(cx); // User-exposed {f:descr} object.
CheckedInt32 sizeSoFar(0); // Size of struct thus far.
uint32_t alignment = 1; // Alignment of struct.
bool opaque = false; // Opacity of struct.
userFieldOffsets = NewBuiltinClassInstance<PlainObject>(cx, TenuredObject);
if (!userFieldOffsets)
return nullptr;
userFieldTypes = NewBuiltinClassInstance<PlainObject>(cx, TenuredObject);
if (!userFieldTypes)
return nullptr;
if (!stringBuffer.append("new StructType({"))
return nullptr;
RootedValue fieldTypeVal(cx);
RootedId id(cx);
Rooted<TypeDescr*> fieldType(cx);
for (unsigned int i = 0; i < ids.length(); i++) {
id = ids[i];
@ -824,12 +845,59 @@ StructMetaTypeDescr::create(JSContext* cx,
return nullptr;
}
// Collect field name and type object
// Collect field type object
if (!fieldTypeObjs.append(ObjectValue(*fieldType)))
return nullptr;
// Struct is opaque if any field is opaque
if (fieldType->opaque())
opaque = true;
}
RootedObject structTypePrototype(cx, GetPrototype(cx, metaTypeDescr));
if (!structTypePrototype)
return nullptr;
return createFromArrays(cx, structTypePrototype, opaque, ids, fieldTypeObjs);
}
/* static */ StructTypeDescr*
StructMetaTypeDescr::createFromArrays(JSContext* cx,
HandleObject structTypePrototype,
bool opaque,
AutoIdVector& ids,
AutoValueVector& fieldTypeObjs)
{
StringBuffer stringBuffer(cx); // Canonical string repr
AutoValueVector fieldNames(cx); // Name of each field.
AutoValueVector fieldOffsets(cx); // Offset of each field field.
RootedObject userFieldOffsets(cx); // User-exposed {f:offset} object
RootedObject userFieldTypes(cx); // User-exposed {f:descr} object.
Layout layout; // Field offsetter
userFieldOffsets = NewBuiltinClassInstance<PlainObject>(cx, TenuredObject);
if (!userFieldOffsets)
return nullptr;
userFieldTypes = NewBuiltinClassInstance<PlainObject>(cx, TenuredObject);
if (!userFieldTypes)
return nullptr;
if (!stringBuffer.append("new StructType({"))
return nullptr;
RootedId id(cx);
Rooted<TypeDescr*> fieldType(cx);
for (unsigned int i = 0; i < ids.length(); i++) {
id = ids[i];
// Collect field name
RootedValue fieldName(cx, IdToValue(id));
if (!fieldNames.append(fieldName))
return nullptr;
if (!fieldTypeObjs.append(ObjectValue(*fieldType)))
return nullptr;
fieldType = ToObjectIf<TypeDescr>(fieldTypeObjs[i]);
// userFieldTypes[id] = typeObj
if (!DefineDataProperty(cx, userFieldTypes, id, fieldTypeObjs[i],
@ -848,9 +916,7 @@ StructMetaTypeDescr::create(JSContext* cx,
if (!stringBuffer.append(&fieldType->stringRepr()))
return nullptr;
// Offset of this field is the current total size adjusted for
// the field's alignment.
CheckedInt32 offset = RoundUpToAlignment(sizeSoFar, fieldType->alignment());
CheckedInt32 offset = layout.addField(fieldType->alignment(), fieldType->size());
if (!offset.isValid()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPEDOBJECT_TOO_BIG);
return nullptr;
@ -866,20 +932,6 @@ StructMetaTypeDescr::create(JSContext* cx,
{
return nullptr;
}
// Add space for this field to the total struct size.
sizeSoFar = offset + fieldType->size();
if (!sizeSoFar.isValid()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPEDOBJECT_TOO_BIG);
return nullptr;
}
// Struct is opaque if any field is opaque
if (fieldType->opaque())
opaque = true;
// Alignment of the struct is the max of the alignment of its fields.
alignment = js::Max(alignment, fieldType->alignment());
}
// Complete string representation.
@ -890,17 +942,14 @@ StructMetaTypeDescr::create(JSContext* cx,
if (!stringRepr)
return nullptr;
// Adjust the total size to be a multiple of the final alignment.
CheckedInt32 totalSize = RoundUpToAlignment(sizeSoFar, alignment);
int32_t alignment;
CheckedInt32 totalSize = layout.close(&alignment);
if (!totalSize.isValid()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPEDOBJECT_TOO_BIG);
return nullptr;
}
// Now create the resulting type descriptor.
RootedObject structTypePrototype(cx, GetPrototype(cx, metaTypeDescr));
if (!structTypePrototype)
return nullptr;
Rooted<StructTypeDescr*> descr(cx);
descr = NewObjectWithGivenProto<StructTypeDescr>(cx, structTypePrototype, SingletonObject);
@ -1127,7 +1176,7 @@ DefineSimpleTypeDescr(JSContext* cx,
descr->initReservedSlot(JS_DESCR_SLOT_ALIGNMENT, Int32Value(T::alignment(type)));
descr->initReservedSlot(JS_DESCR_SLOT_SIZE, Int32Value(AssertedCast<int32_t>(T::size(type))));
descr->initReservedSlot(JS_DESCR_SLOT_OPAQUE, BooleanValue(T::Opaque));
descr->initReservedSlot(JS_DESCR_SLOT_TYPE, Int32Value(type));
descr->initReservedSlot(JS_DESCR_SLOT_TYPE, Int32Value(int32_t(type)));
if (!CreateUserSizeAndAlignmentProperties(cx, descr))
return false;
@ -2740,14 +2789,14 @@ void
MemoryInitVisitor::visitReference(ReferenceTypeDescr& descr, uint8_t* mem)
{
switch (descr.type()) {
case ReferenceTypeDescr::TYPE_ANY:
case ReferenceType::TYPE_ANY:
{
js::GCPtrValue* heapValue = reinterpret_cast<js::GCPtrValue*>(mem);
heapValue->init(UndefinedValue());
return;
}
case ReferenceTypeDescr::TYPE_OBJECT:
case ReferenceType::TYPE_OBJECT:
{
js::GCPtrObject* objectPtr =
reinterpret_cast<js::GCPtrObject*>(mem);
@ -2755,7 +2804,7 @@ MemoryInitVisitor::visitReference(ReferenceTypeDescr& descr, uint8_t* mem)
return;
}
case ReferenceTypeDescr::TYPE_STRING:
case ReferenceType::TYPE_STRING:
{
js::GCPtrString* stringPtr =
reinterpret_cast<js::GCPtrString*>(mem);
@ -2810,21 +2859,21 @@ void
MemoryTracingVisitor::visitReference(ReferenceTypeDescr& descr, uint8_t* mem)
{
switch (descr.type()) {
case ReferenceTypeDescr::TYPE_ANY:
case ReferenceType::TYPE_ANY:
{
GCPtrValue* heapValue = reinterpret_cast<js::GCPtrValue*>(mem);
TraceEdge(trace_, heapValue, "reference-val");
return;
}
case ReferenceTypeDescr::TYPE_OBJECT:
case ReferenceType::TYPE_OBJECT:
{
GCPtrObject* objectPtr = reinterpret_cast<js::GCPtrObject*>(mem);
TraceNullableEdge(trace_, objectPtr, "reference-obj");
return;
}
case ReferenceTypeDescr::TYPE_STRING:
case ReferenceType::TYPE_STRING:
{
GCPtrString* stringPtr = reinterpret_cast<js::GCPtrString*>(mem);
TraceNullableEdge(trace_, stringPtr, "reference-str");
@ -2864,9 +2913,9 @@ TraceListVisitor::visitReference(ReferenceTypeDescr& descr, uint8_t* mem)
{
VectorType* offsets;
switch (descr.type()) {
case ReferenceTypeDescr::TYPE_ANY: offsets = &valueOffsets; break;
case ReferenceTypeDescr::TYPE_OBJECT: offsets = &objectOffsets; break;
case ReferenceTypeDescr::TYPE_STRING: offsets = &stringOffsets; break;
case ReferenceType::TYPE_ANY: offsets = &valueOffsets; break;
case ReferenceType::TYPE_OBJECT: offsets = &objectOffsets; break;
case ReferenceType::TYPE_STRING: offsets = &stringOffsets; break;
default: MOZ_CRASH("Invalid kind");
}

Просмотреть файл

@ -7,6 +7,8 @@
#ifndef builtin_TypedObject_h
#define builtin_TypedObject_h
#include "mozilla/CheckedInt.h"
#include "builtin/TypedObjectConstants.h"
#include "gc/WeakMap.h"
#include "js/Conversions.h"
@ -286,6 +288,12 @@ class ScalarTypeDescr : public SimpleTypeDescr
JS_FOR_EACH_UNIQUE_SCALAR_TYPE_REPR_CTYPE(macro_) \
macro_(Scalar::Uint8Clamped, uint8_t, uint8Clamped)
enum class ReferenceType {
TYPE_ANY = JS_REFERENCETYPEREPR_ANY,
TYPE_OBJECT = JS_REFERENCETYPEREPR_OBJECT,
TYPE_STRING = JS_REFERENCETYPEREPR_STRING
};
// Type for reference type constructors like `Any`, `String`, and
// `Object`. All such type constructors share a common js::Class and
// JSFunctionSpec. All these types are opaque.
@ -293,14 +301,10 @@ class ReferenceTypeDescr : public SimpleTypeDescr
{
public:
// Must match order of JS_FOR_EACH_REFERENCE_TYPE_REPR below
enum Type {
TYPE_ANY = JS_REFERENCETYPEREPR_ANY,
TYPE_OBJECT = JS_REFERENCETYPEREPR_OBJECT,
TYPE_STRING = JS_REFERENCETYPEREPR_STRING,
};
static const int32_t TYPE_MAX = TYPE_STRING + 1;
typedef ReferenceType Type;
static const char* typeName(Type type);
static const int32_t TYPE_MAX = int32_t(ReferenceType::TYPE_STRING) + 1;
static const type::Kind Kind = type::Reference;
static const bool Opaque = true;
static const Class class_;
@ -308,8 +312,8 @@ class ReferenceTypeDescr : public SimpleTypeDescr
static uint32_t alignment(Type t);
static const JSFunctionSpec typeObjectMethods[];
ReferenceTypeDescr::Type type() const {
return (ReferenceTypeDescr::Type) getReservedSlot(JS_DESCR_SLOT_TYPE).toInt32();
ReferenceType type() const {
return (ReferenceType) getReservedSlot(JS_DESCR_SLOT_TYPE).toInt32();
}
const char* typeName() const {
@ -320,9 +324,9 @@ class ReferenceTypeDescr : public SimpleTypeDescr
};
#define JS_FOR_EACH_REFERENCE_TYPE_REPR(macro_) \
macro_(ReferenceTypeDescr::TYPE_ANY, GCPtrValue, Any) \
macro_(ReferenceTypeDescr::TYPE_OBJECT, GCPtrObject, Object) \
macro_(ReferenceTypeDescr::TYPE_STRING, GCPtrString, string)
macro_(ReferenceType::TYPE_ANY, GCPtrValue, Any) \
macro_(ReferenceType::TYPE_OBJECT, GCPtrObject, Object) \
macro_(ReferenceType::TYPE_STRING, GCPtrString, string)
// Type descriptors whose instances are objects and hence which have
// an associated `prototype` property.
@ -435,6 +439,15 @@ class StructMetaTypeDescr : public NativeObject
HandleObject fields);
public:
// The prototype cannot be null.
// The names in `ids` must all be non-numeric.
// The type objects in `fieldTypeObjs` must all be TypeDescr objects.
static StructTypeDescr* createFromArrays(JSContext* cx,
HandleObject structTypePrototype,
bool opaque,
AutoIdVector& ids,
AutoValueVector& fieldTypeObjs);
// Properties and methods to be installed on StructType.prototype,
// and hence inherited by all struct type objects:
static const JSPropertySpec typeObjectProperties[];
@ -448,6 +461,27 @@ class StructMetaTypeDescr : public NativeObject
// This is the function that gets called when the user
// does `new StructType(...)`. It produces a struct type object.
static MOZ_MUST_USE bool construct(JSContext* cx, unsigned argc, Value* vp);
class Layout
{
// Can call addField() directly.
friend class StructMetaTypeDescr;
mozilla::CheckedInt32 sizeSoFar = 0;
int32_t structAlignment = 1;
mozilla::CheckedInt32 addField(int32_t fieldAlignment, int32_t fieldSize);
public:
// The field adders return the offset of the the field.
mozilla::CheckedInt32 addScalar(Scalar::Type type);
mozilla::CheckedInt32 addReference(ReferenceType type);
// The close method rounds up the structure size to the appropriate
// alignment and returns that size. If `alignment` is not NULL then
// return the structure alignment through that pointer.
mozilla::CheckedInt32 close(int32_t* alignment = nullptr);
};
};
class StructTypeDescr : public ComplexTypeDescr

Просмотреть файл

@ -8,6 +8,12 @@
#include "mozilla/MathAlgorithms.h"
#include "ds/MemoryProtectionExceptionHandler.h"
#ifdef LIFO_CHUNK_PROTECT
# include "gc/Memory.h"
#endif
using namespace js;
using mozilla::RoundUpPow2;
@ -18,7 +24,7 @@ namespace detail {
/* static */
UniquePtr<BumpChunk>
BumpChunk::newWithCapacity(size_t size)
BumpChunk::newWithCapacity(size_t size, bool protect)
{
MOZ_ASSERT(RoundUpPow2(size) == size);
MOZ_ASSERT(size >= sizeof(BumpChunk));
@ -26,7 +32,7 @@ BumpChunk::newWithCapacity(size_t size)
if (!mem)
return nullptr;
UniquePtr<BumpChunk> result(new (mem) BumpChunk(size));
UniquePtr<BumpChunk> result(new (mem) BumpChunk(size, protect));
// We assume that the alignment of LIFO_ALLOC_ALIGN is less than that of the
// underlying memory allocator -- creating a new BumpChunk should always
@ -44,6 +50,96 @@ BumpChunk::canAlloc(size_t n)
return bump_ <= newBump && newBump <= capacity_;
}
#ifdef LIFO_CHUNK_PROTECT
static const uint8_t*
AlignPtrUp(const uint8_t* ptr, uintptr_t align) {
MOZ_ASSERT(mozilla::IsPowerOfTwo(align));
uintptr_t uptr = uintptr_t(ptr);
uintptr_t diff = uptr & (align - 1);
diff = (align - diff) & (align - 1);
uptr = uptr + diff;
return (uint8_t*) uptr;
}
static const uint8_t*
AlignPtrDown(const uint8_t* ptr, uintptr_t align) {
MOZ_ASSERT(mozilla::IsPowerOfTwo(align));
uintptr_t uptr = uintptr_t(ptr);
uptr = uptr & ~(align - 1);
return (uint8_t*) uptr;
}
void
BumpChunk::setRWUntil(Loc loc) const
{
if (!protect_)
return;
uintptr_t pageSize = gc::SystemPageSize();
// The allocated chunks might not be aligned on page boundaries. This code
// is used to ensure that we are changing the memory protection of pointers
// which are within the range of the BumpChunk, or that the range formed by
// [b .. e] is empty.
const uint8_t* b = base();
const uint8_t* e = capacity_;
b = AlignPtrUp(b, pageSize);
e = AlignPtrDown(e, pageSize);
if (e < b)
e = b;
// The mid-point is aligned to the next page, and clamp to the end-point to
// ensure that it remains in the [b .. e] range.
const uint8_t* m = nullptr;
switch (loc) {
case Loc::Header:
m = b;
break;
case Loc::Allocated:
m = begin();
break;
case Loc::Reserved:
m = end();
break;
case Loc::End:
m = e;
break;
}
m = AlignPtrUp(m, pageSize);
if (e < m)
m = e;
if (b < m)
gc::UnprotectPages(const_cast<uint8_t*>(b), m - b);
// Note: We could use no-access protection for everything after begin(), but
// we need to read capabilities for reading the bump_ / capacity_ fields
// from this function to unprotect the memory later.
if (m < e)
gc::MakePagesReadOnly(const_cast<uint8_t*>(m), e - m);
}
// The memory protection handler is catching memory accesses error on the
// regions registered into it. These method, instead of registering sub-ranges
// of the BumpChunk within setRWUntil, we just register the full BumpChunk
// ranges, and let the MemoryProtectionExceptionHandler catch bad memory
// accesses when it is being protected by setRWUntil.
void
BumpChunk::addMProtectHandler() const
{
if (!protect_)
return;
js::MemoryProtectionExceptionHandler::addRegion(const_cast<uint8_t*>(base()), capacity_ - base());
}
void
BumpChunk::removeMProtectHandler() const
{
if (!protect_)
return;
js::MemoryProtectionExceptionHandler::removeRegion(const_cast<uint8_t*>(base()));
}
#endif
} // namespace detail
} // namespace js
@ -51,10 +147,12 @@ void
LifoAlloc::freeAll()
{
while (!chunks_.empty()) {
chunks_.begin()->setRWUntil(Loc::End);
BumpChunk bc = chunks_.popFirst();
decrementCurSize(bc->computedSizeOfIncludingThis());
}
while (!unused_.empty()) {
unused_.begin()->setRWUntil(Loc::End);
BumpChunk bc = unused_.popFirst();
decrementCurSize(bc->computedSizeOfIncludingThis());
}
@ -90,7 +188,7 @@ LifoAlloc::newChunkWithCapacity(size_t n)
}
// Create a new BumpChunk, and allocate space for it.
BumpChunk result = detail::BumpChunk::newWithCapacity(chunkSize);
BumpChunk result = detail::BumpChunk::newWithCapacity(chunkSize, protect_);
if (!result)
return nullptr;
MOZ_ASSERT(result->computedSizeOfIncludingThis() == chunkSize);
@ -100,12 +198,19 @@ LifoAlloc::newChunkWithCapacity(size_t n)
bool
LifoAlloc::getOrCreateChunk(size_t n)
{
// This function is adding a new BumpChunk in which all upcoming allocation
// would be made. Thus, we protect against out-of-bounds the last chunk in
// which we did our previous allocations.
if (!chunks_.empty())
chunks_.last()->setRWUntil(Loc::Reserved);
// Look for existing unused BumpChunks to satisfy the request, and pick the
// first one which is large enough, and move it into the list of used
// chunks.
if (!unused_.empty()) {
if (unused_.begin()->canAlloc(n)) {
chunks_.append(unused_.popFirst());
chunks_.last()->setRWUntil(Loc::End);
return true;
}
@ -117,6 +222,7 @@ LifoAlloc::getOrCreateChunk(size_t n)
BumpChunkList temp = unused_.splitAfter(i.get());
chunks_.append(temp.popFirst());
unused_.appendAll(std::move(temp));
chunks_.last()->setRWUntil(Loc::End);
return true;
}
}
@ -127,6 +233,9 @@ LifoAlloc::getOrCreateChunk(size_t n)
if (!newChunk)
return false;
size_t size = newChunk->computedSizeOfIncludingThis();
// The last chunk in which allocations are performed should be protected
// with setRWUntil(Loc::End), but this is not necessary here because any new
// allocation should be protected as RW already.
chunks_.append(std::move(newChunk));
incrementCurSize(size);
return true;

Просмотреть файл

@ -216,14 +216,21 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
private:
// Pointer to the last byte allocated in this chunk.
uint8_t* bump_;
// Pointer to the last byte available in this chunk.
const uint8_t* capacity_;
// Pointer to the first byte after this chunk.
uint8_t* const capacity_;
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
// Magic number used to check against poisoned values.
const uintptr_t magic_;
static constexpr uintptr_t magicNumber =
sizeof(uintptr_t) == 4 ? uintptr_t(0x4c69666f) : uintptr_t(0x4c69666f42756d70);
const uintptr_t magic_ : 24;
static constexpr uintptr_t magicNumber = uintptr_t(0x4c6966);
#endif
#if defined(DEBUG) || defined(MOZ_DIAGNOSTIC_ASSERT_ENABLED)
# define LIFO_CHUNK_PROTECT 1
// Constant used to know if the current chunk should be protected. This is
// mainly use to prevent dead-lock in the MemoryProtectionExceptionHandler
// methods.
const uintptr_t protect_ : 1;
#endif
// Poison the memory with memset, in order to catch errors due to
@ -269,11 +276,14 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
BumpChunk& operator=(const BumpChunk&) = delete;
BumpChunk(const BumpChunk&) = delete;
explicit BumpChunk(uintptr_t capacity)
explicit BumpChunk(uintptr_t capacity, bool protect)
: bump_(begin()),
capacity_(base() + capacity)
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
, magic_(magicNumber)
#endif
#ifdef LIFO_CHUNK_PROTECT
, protect_(protect ? 1 : 0)
#endif
{
// We cannot bake this value inside the BumpChunk class, because
@ -292,6 +302,7 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
// no-access, as it has not been allocated within the BumpChunk.
LIFO_MAKE_MEM_NOACCESS(bump_, capacity_ - bump_);
#endif
addMProtectHandler();
}
// Cast |this| into a uint8_t* pointer.
@ -326,6 +337,7 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
public:
~BumpChunk() {
release();
removeMProtectHandler();
}
// Space reserved for the BumpChunk internal data, and the alignment of the
@ -350,7 +362,10 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
// This function is the only way to allocate and construct a chunk. It
// returns a UniquePtr to the newly allocated chunk. The size given as
// argument includes the space needed for the header of the chunk.
static UniquePtr<BumpChunk> newWithCapacity(size_t size);
//
// The protect boolean is used to indicate whether the Bumpchunk memory
// should be reported within the MemoryProtectionExceptionHandler.
static UniquePtr<BumpChunk> newWithCapacity(size_t size, bool protect);
// Report allocation.
size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
@ -443,6 +458,44 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
setBump(newBump);
return aligned;
}
// These locations are approximated locations, with the base rounded up to
// the nearest page boundary.
enum class Loc {
// Refers to the inherited linked list, this includes any allocated any
// reserved bytes, from base() to capacity_.
//
// This is used when freezing a LifoAlloc, such as moving a LifoAlloc to
// another thread.
Header = 0,
// Refers to the set of allocated and reserved bytes, from
// PageRoundup(begin()), to capacity_.
//
// This is used when a BumpChunk is moved to the list of unused chunks,
// as we want the header to remain mutable.
Allocated = 1,
// Refers to the set of reserved bytes, from PageRoundup(end()) to
// capacity_.
//
// This is used when a BumpChunk is no longer used for allocation, while
// containing live data. This should catch out-of-bound accesses within
// the LifoAlloc content.
Reserved = 2,
// Refers to the end of the BumpChunk.
//
// This is used when a BumpChunk is used for doing allocation, as
// re-protecting at each setBump would be too costly.
End = 3
};
#ifdef LIFO_CHUNK_PROTECT
void setRWUntil(Loc loc) const;
void addMProtectHandler() const;
void removeMProtectHandler() const;
#else
void setRWUntil(Loc loc) const {}
void addMProtectHandler() const {}
void removeMProtectHandler() const {}
#endif
};
} // namespace detail
@ -453,6 +506,7 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
// been released to avoid thrashing before a GC.
class LifoAlloc
{
using Loc = detail::BumpChunk::Loc;
using BumpChunk = js::UniquePtr<detail::BumpChunk>;
using BumpChunkList = detail::SingleLinkedList<detail::BumpChunk>;
@ -472,6 +526,9 @@ class LifoAlloc
#if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
bool fallibleScope_;
#endif
#ifdef LIFO_CHUNK_PROTECT
const bool protect_;
#endif
void operator=(const LifoAlloc&) = delete;
LifoAlloc(const LifoAlloc&) = delete;
@ -485,10 +542,14 @@ class LifoAlloc
void reset(size_t defaultChunkSize) {
MOZ_ASSERT(mozilla::RoundUpPow2(defaultChunkSize) == defaultChunkSize);
while (!chunks_.empty())
while (!chunks_.empty()) {
chunks_.begin()->setRWUntil(Loc::End);
chunks_.popFirst();
while (!unused_.empty())
}
while (!unused_.empty()) {
unused_.begin()->setRWUntil(Loc::End);
unused_.popFirst();
}
defaultChunkSize_ = defaultChunkSize;
markCount = 0;
curSize_ = 0;
@ -536,10 +597,13 @@ class LifoAlloc
}
public:
explicit LifoAlloc(size_t defaultChunkSize)
explicit LifoAlloc(size_t defaultChunkSize, bool protect = true)
: peakSize_(0)
#if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
, fallibleScope_(true)
#endif
#ifdef LIFO_CHUNK_PROTECT
, protect_(protect)
#endif
{
reset(defaultChunkSize);
@ -641,6 +705,7 @@ class LifoAlloc
if (!newChunk)
return false;
size_t size = newChunk->computedSizeOfIncludingThis();
newChunk->setRWUntil(Loc::Allocated);
unused_.pushFront(std::move(newChunk));
incrementCurSize(size);
return true;
@ -714,22 +779,49 @@ class LifoAlloc
released = chunks_.splitAfter(mark.markedChunk());
// Release the content of all the blocks which are after the marks.
for (detail::BumpChunk& bc : released)
for (detail::BumpChunk& bc : released) {
bc.release();
bc.setRWUntil(Loc::Allocated);
}
unused_.appendAll(std::move(released));
// Release everything which follows the mark in the last chunk.
if (!chunks_.empty())
if (!chunks_.empty()) {
chunks_.last()->setRWUntil(Loc::End);
chunks_.last()->release(mark);
}
}
void releaseAll() {
MOZ_ASSERT(!markCount);
for (detail::BumpChunk& bc : chunks_)
for (detail::BumpChunk& bc : chunks_) {
bc.release();
bc.setRWUntil(Loc::Allocated);
}
unused_.appendAll(std::move(chunks_));
}
// Protect the content of the LifoAlloc chunks.
void setReadOnly() {
#ifdef LIFO_CHUNK_PROTECT
for (detail::BumpChunk& bc : chunks_)
bc.setRWUntil(Loc::Header);
for (detail::BumpChunk& bc : unused_)
bc.setRWUntil(Loc::Header);
#endif
}
void setReadWrite() {
#ifdef LIFO_CHUNK_PROTECT
BumpChunkList::Iterator e(chunks_.last());
for (BumpChunkList::Iterator i(chunks_.begin()); i != e; ++i)
i->setRWUntil(Loc::Reserved);
if (!chunks_.empty())
chunks_.last()->setRWUntil(Loc::End);
for (detail::BumpChunk& bc : unused_)
bc.setRWUntil(Loc::Allocated);
#endif
}
// Get the total "used" (occupied bytes) count for the arena chunks.
size_t used() const {
size_t accum = 0;

Просмотреть файл

@ -65,7 +65,9 @@ class ProtectedRegionTree
public:
ProtectedRegionTree()
: lock(mutexid::ProtectedRegionTree),
alloc(4096),
// Here "false" is used to not use the memory protection mechanism of
// LifoAlloc in order to prevent dead-locks.
alloc(4096, false),
tree(&alloc)
{
sProtectedRegionsInit = true;

Просмотреть файл

@ -431,8 +431,8 @@ void Zone::releaseAtoms()
keepAtomsCount--;
if (!hasKeptAtoms() && purgeAtomsDeferred) {
atomCache().clearAndShrink();
purgeAtomsDeferred = false;
purgeAtomCache();
}
}
@ -444,7 +444,21 @@ Zone::purgeAtomCacheOrDefer()
return;
}
purgeAtomCache();
}
void
Zone::purgeAtomCache()
{
MOZ_ASSERT(!hasKeptAtoms());
MOZ_ASSERT(!purgeAtomsDeferred);
atomCache().clearAndShrink();
// Also purge the dtoa caches so that subsequent lookups populate atom
// cache too.
for (RealmsInZoneIter r(this); !r.done(); r.next())
r->dtoaCache.purge();
}
void

Просмотреть файл

@ -524,6 +524,7 @@ class Zone : public JS::shadow::Zone,
void traceAtomCache(JSTracer* trc);
void purgeAtomCacheOrDefer();
void purgeAtomCache();
js::ExternalStringCache& externalStringCache() { return externalStringCache_.ref(); };

Просмотреть файл

@ -0,0 +1,18 @@
// |jit-test| error: ReferenceError
loadFile(`
gczeal(2,9);
evaluate(\`
reportCompare(expect, actual, summary);
\`);
`);
function loadFile(lfVarx) {
try {
evaluate(lfVarx);
} catch (lfVare) {}
}
eval("(function(){({6953421313:0})})")();
function f() {
x[6953421313] = "a";
}
f();

Просмотреть файл

@ -1243,7 +1243,7 @@ BaselineCacheIRCompiler::emitStoreTypedObjectReferenceProperty()
ObjOperandId objId = reader.objOperandId();
Address offsetAddr = stubAddress(reader.stubOffset());
TypedThingLayout layout = reader.typedThingLayout();
ReferenceTypeDescr::Type type = reader.referenceTypeDescrType();
ReferenceType type = reader.referenceTypeDescrType();
// Allocate the fixed registers first. These need to be fixed for
// callTypeUpdateIC.
@ -1254,7 +1254,7 @@ BaselineCacheIRCompiler::emitStoreTypedObjectReferenceProperty()
AutoScratchRegister scratch2(allocator, masm);
// We don't need a type update IC if the property is always a string.
if (type != ReferenceTypeDescr::TYPE_STRING) {
if (type != ReferenceType::TYPE_STRING) {
LiveGeneralRegisterSet saveRegs;
saveRegs.add(obj);
saveRegs.add(val);

Просмотреть файл

@ -2218,7 +2218,7 @@ BaselineCompiler::emit_JSOP_MUTATEPROTO()
// Keep values on the stack for the decompiler.
frame.syncStack(0);
masm.extractObject(frame.addressOfStackValue(frame.peek(-2)), R0.scratchReg());
masm.unboxObject(frame.addressOfStackValue(frame.peek(-2)), R0.scratchReg());
masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R1);
prepareVMCall();
@ -2701,7 +2701,7 @@ BaselineCompiler::getEnvironmentCoordinateObject(Register reg)
masm.loadPtr(frame.addressOfEnvironmentChain(), reg);
for (unsigned i = ec.hops(); i; i--)
masm.extractObject(Address(reg, EnvironmentObject::offsetOfEnclosingEnvironment()), reg);
masm.unboxObject(Address(reg, EnvironmentObject::offsetOfEnclosingEnvironment()), reg);
}
Address
@ -3000,8 +3000,8 @@ BaselineCompiler::emitInitPropGetterSetter()
prepareVMCall();
masm.extractObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg());
masm.extractObject(frame.addressOfStackValue(frame.peek(-2)), R1.scratchReg());
masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg());
masm.unboxObject(frame.addressOfStackValue(frame.peek(-2)), R1.scratchReg());
pushArg(R0.scratchReg());
pushArg(ImmGCPtr(script->getName(pc)));
@ -3057,13 +3057,13 @@ BaselineCompiler::emitInitElemGetterSetter()
// decompiler.
frame.syncStack(0);
masm.loadValue(frame.addressOfStackValue(frame.peek(-2)), R0);
masm.extractObject(frame.addressOfStackValue(frame.peek(-1)), R1.scratchReg());
masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), R1.scratchReg());
prepareVMCall();
pushArg(R1.scratchReg());
pushArg(R0);
masm.extractObject(frame.addressOfStackValue(frame.peek(-3)), R0.scratchReg());
masm.unboxObject(frame.addressOfStackValue(frame.peek(-3)), R0.scratchReg());
pushArg(R0.scratchReg());
pushArg(ImmPtr(pc));

Просмотреть файл

@ -65,9 +65,9 @@ class StackValue
};
private:
Kind kind_;
MOZ_INIT_OUTSIDE_CTOR Kind kind_;
union Data {
MOZ_INIT_OUTSIDE_CTOR union Data {
JS::Value constant;
ValueOperand reg;
uint32_t localSlot;
@ -80,7 +80,7 @@ class StackValue
MOZ_POP_DISABLE_NONTRIVIAL_UNION_WARNINGS
} data;
JSValueType knownType_;
MOZ_INIT_OUTSIDE_CTOR JSValueType knownType_;
public:
StackValue() {

Просмотреть файл

@ -306,14 +306,14 @@ DoTypeUpdateFallback(JSContext* cx, BaselineFrame* frame, ICUpdatedStub* stub, H
MOZ_ALWAYS_TRUE(structDescr->fieldIndex(id, &fieldIndex));
TypeDescr* fieldDescr = &structDescr->fieldDescr(fieldIndex);
ReferenceTypeDescr::Type type = fieldDescr->as<ReferenceTypeDescr>().type();
if (type == ReferenceTypeDescr::TYPE_ANY) {
ReferenceType type = fieldDescr->as<ReferenceTypeDescr>().type();
if (type == ReferenceType::TYPE_ANY) {
// Ignore undefined values, which are included implicitly in type
// information for this property.
if (value.isUndefined())
addType = false;
} else {
MOZ_ASSERT(type == ReferenceTypeDescr::TYPE_OBJECT);
MOZ_ASSERT(type == ReferenceType::TYPE_OBJECT);
// Ignore null values being written here. Null is included
// implicitly in type information for this property. Note that
@ -1376,7 +1376,7 @@ DoGetIntrinsicFallback(JSContext* cx, BaselineFrame* frame, ICGetIntrinsic_Fallb
MOZ_ASSERT(op == JSOP_GETINTRINSIC);
if (!GetIntrinsicOperation(cx, pc, res))
if (!GetIntrinsicOperation(cx, script, pc, res))
return false;
// An intrinsic operation will always produce the same result, so only
@ -2730,7 +2730,7 @@ ICCallStubCompiler::pushArrayArguments(MacroAssembler& masm, Address arrayVal,
// no holes.
Register startReg = regs.takeAny();
Register endReg = regs.takeAny();
masm.extractObject(arrayVal, startReg);
masm.unboxObject(arrayVal, startReg);
masm.loadPtr(Address(startReg, NativeObject::offsetOfElements()), startReg);
masm.load32(Address(startReg, ObjectElements::offsetOfInitializedLength()), endReg);
masm.alignJitStackBasedOnNArgs(endReg);
@ -3546,7 +3546,7 @@ ICCall_ScriptedApplyArray::Compiler::generateStubCode(MacroAssembler& masm)
EmitBaselineCreateStubFrameDescriptor(masm, scratch, JitFrameLayout::Size());
// Reload argc from length of array.
masm.extractObject(arrayVal, argcReg);
masm.unboxObject(arrayVal, argcReg);
masm.loadPtr(Address(argcReg, NativeObject::offsetOfElements()), argcReg);
masm.load32(Address(argcReg, ObjectElements::offsetOfInitializedLength()), argcReg);

Просмотреть файл

@ -79,6 +79,16 @@ BaselineScript::BaselineScript(uint32_t prologueOffset, uint32_t epilogueOffset,
#endif
postDebugPrologueOffset_(postDebugPrologueOffset),
flags_(0),
icEntriesOffset_(0),
icEntries_(0),
pcMappingIndexOffset_(0),
pcMappingIndexEntries_(0),
pcMappingOffset_(0),
pcMappingSize_(0),
bytecodeTypeMapOffset_(0),
yieldEntriesOffset_(0),
traceLoggerToggleOffsetsOffset_(0),
numTraceLoggerToggleOffsets_(0),
inlinedBytecodeLength_(0),
maxInliningDepth_(UINT8_MAX),
pendingBuilder_(nullptr),

Просмотреть файл

@ -18,7 +18,8 @@ using namespace js::jit;
BytecodeAnalysis::BytecodeAnalysis(TempAllocator& alloc, JSScript* script)
: script_(script),
infos_(alloc),
usesEnvironmentChain_(false)
usesEnvironmentChain_(false),
hasTryFinally_(false)
{
}

Просмотреть файл

@ -1128,7 +1128,7 @@ GetPropIRGenerator::tryAttachCrossCompartmentWrapper(HandleObject obj, ObjOperan
// so we optimize for that case as well.
isWindowProxy = IsWindowProxy(unwrapped);
if (isWindowProxy) {
MOZ_ASSERT(ToWindowIfWindowProxy(unwrapped) == unwrapped->realm()->maybeGlobal());
MOZ_ASSERT(ToWindowIfWindowProxy(unwrapped) == &unwrapped->nonCCWGlobal());
unwrapped = cx_->global();
MOZ_ASSERT(unwrapped);
}
@ -1641,8 +1641,8 @@ GetPropIRGenerator::tryAttachTypedObject(HandleObject obj, ObjOperandId objId, H
Scalar::Type type = ScalarTypeFromSimpleTypeDescrKey(typeDescr);
monitorLoad = type == Scalar::Uint32;
} else {
ReferenceTypeDescr::Type type = ReferenceTypeFromSimpleTypeDescrKey(typeDescr);
monitorLoad = type != ReferenceTypeDescr::TYPE_STRING;
ReferenceType type = ReferenceTypeFromSimpleTypeDescrKey(typeDescr);
monitorLoad = type != ReferenceType::TYPE_STRING;
}
if (monitorLoad)
@ -3337,14 +3337,14 @@ SetPropIRGenerator::tryAttachTypedObjectProperty(HandleObject obj, ObjOperandId
// For reference types, guard on the RHS type first, so that
// StoreTypedObjectReferenceProperty is infallible.
ReferenceTypeDescr::Type type = fieldDescr->as<ReferenceTypeDescr>().type();
ReferenceType type = fieldDescr->as<ReferenceTypeDescr>().type();
switch (type) {
case ReferenceTypeDescr::TYPE_ANY:
case ReferenceType::TYPE_ANY:
break;
case ReferenceTypeDescr::TYPE_OBJECT:
case ReferenceType::TYPE_OBJECT:
writer.guardIsObjectOrNull(rhsId);
break;
case ReferenceTypeDescr::TYPE_STRING:
case ReferenceType::TYPE_STRING:
writer.guardType(rhsId, JSVAL_TYPE_STRING);
break;
}

Просмотреть файл

@ -873,7 +873,7 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
}
void storeTypedObjectReferenceProperty(ObjOperandId obj, uint32_t offset,
TypedThingLayout layout, ReferenceTypeDescr::Type type,
TypedThingLayout layout, ReferenceType type,
ValOperandId rhs)
{
writeOpWithOperandId(CacheOp::StoreTypedObjectReferenceProperty, obj);
@ -1225,8 +1225,8 @@ class MOZ_RAII CacheIRReader
uint32_t uint32Immediate() { return buffer_.readUnsigned(); }
void* pointer() { return buffer_.readRawPointer(); }
ReferenceTypeDescr::Type referenceTypeDescrType() {
return ReferenceTypeDescr::Type(buffer_.readByte());
ReferenceType referenceTypeDescrType() {
return ReferenceType(buffer_.readByte());
}
uint8_t readByte() {

Просмотреть файл

@ -1727,7 +1727,7 @@ CacheIRCompiler::emitLoadEnclosingEnvironment()
{
Register obj = allocator.useRegister(masm, reader.objOperandId());
Register reg = allocator.defineRegister(masm, reader.objOperandId());
masm.extractObject(Address(obj, EnvironmentObject::offsetOfEnclosingEnvironment()), reg);
masm.unboxObject(Address(obj, EnvironmentObject::offsetOfEnclosingEnvironment()), reg);
return true;
}
@ -2432,13 +2432,13 @@ CacheIRCompiler::emitLoadTypedObjectResultShared(const Address& fieldAddr, Regis
masm.loadFromTypedArray(type, fieldAddr, output.valueReg(),
/* allowDouble = */ true, scratch, nullptr);
} else {
ReferenceTypeDescr::Type type = ReferenceTypeFromSimpleTypeDescrKey(typeDescr);
ReferenceType type = ReferenceTypeFromSimpleTypeDescrKey(typeDescr);
switch (type) {
case ReferenceTypeDescr::TYPE_ANY:
case ReferenceType::TYPE_ANY:
masm.loadValue(fieldAddr, output.valueReg());
break;
case ReferenceTypeDescr::TYPE_OBJECT: {
case ReferenceType::TYPE_OBJECT: {
Label notNull, done;
masm.loadPtr(fieldAddr, scratch);
masm.branchTestPtr(Assembler::NonZero, scratch, scratch, &notNull);
@ -2450,7 +2450,7 @@ CacheIRCompiler::emitLoadTypedObjectResultShared(const Address& fieldAddr, Regis
break;
}
case ReferenceTypeDescr::TYPE_STRING:
case ReferenceType::TYPE_STRING:
masm.loadPtr(fieldAddr, scratch);
masm.tagValue(JSVAL_TYPE_STRING, scratch, output.valueReg());
break;
@ -2666,18 +2666,18 @@ CacheIRCompiler::emitBreakpoint()
}
void
CacheIRCompiler::emitStoreTypedObjectReferenceProp(ValueOperand val, ReferenceTypeDescr::Type type,
CacheIRCompiler::emitStoreTypedObjectReferenceProp(ValueOperand val, ReferenceType type,
const Address& dest, Register scratch)
{
// Callers will post-barrier this store.
switch (type) {
case ReferenceTypeDescr::TYPE_ANY:
case ReferenceType::TYPE_ANY:
EmitPreBarrier(masm, dest, MIRType::Value);
masm.storeValue(val, dest);
break;
case ReferenceTypeDescr::TYPE_OBJECT: {
case ReferenceType::TYPE_OBJECT: {
EmitPreBarrier(masm, dest, MIRType::Object);
Label isNull, done;
masm.branchTestObject(Assembler::NotEqual, val, &isNull);
@ -2690,7 +2690,7 @@ CacheIRCompiler::emitStoreTypedObjectReferenceProp(ValueOperand val, ReferenceTy
break;
}
case ReferenceTypeDescr::TYPE_STRING:
case ReferenceType::TYPE_STRING:
EmitPreBarrier(masm, dest, MIRType::String);
masm.unboxString(val, scratch);
masm.storePtr(scratch, dest);

Просмотреть файл

@ -656,7 +656,7 @@ class MOZ_RAII CacheIRCompiler
uint32_t typeDescr,
const AutoOutputRegister& output);
void emitStoreTypedObjectReferenceProp(ValueOperand val, ReferenceTypeDescr::Type type,
void emitStoreTypedObjectReferenceProp(ValueOperand val, ReferenceType type,
const Address& dest, Register scratch);
void emitRegisterEnumerator(Register enumeratorsList, Register iter, Register scratch);

Просмотреть файл

@ -666,9 +666,7 @@ class OutOfLineTestObject : public OutOfLineCodeBase<CodeGenerator>
public:
OutOfLineTestObject()
#ifdef DEBUG
: ifEmulatesUndefined_(nullptr), ifDoesntEmulateUndefined_(nullptr)
#endif
{ }
void accept(CodeGenerator* codegen) final {
@ -3425,12 +3423,12 @@ CodeGenerator::visitStoreSlotT(LStoreSlotT* lir)
if (valueType == MIRType::ObjectOrNull) {
masm.storeObjectOrNull(ToRegister(lir->value()), dest);
} else {
ConstantOrRegister value;
mozilla::Maybe<ConstantOrRegister> value;
if (lir->value()->isConstant())
value = ConstantOrRegister(lir->value()->toConstant()->toJSValue());
value.emplace(ConstantOrRegister(lir->value()->toConstant()->toJSValue()));
else
value = TypedOrValueRegister(valueType, ToAnyRegister(lir->value()));
masm.storeUnboxedValue(value, valueType, dest, lir->mir()->slotType());
value.emplace(TypedOrValueRegister(valueType, ToAnyRegister(lir->value())));
masm.storeUnboxedValue(value.ref(), valueType, dest, lir->mir()->slotType());
}
}
@ -3628,13 +3626,13 @@ CodeGenerator::visitSetPropertyPolymorphicT(LSetPropertyPolymorphicT* ins)
Register temp1 = ToRegister(ins->temp1());
Register temp2 = ToRegister(ins->temp2());
ConstantOrRegister value;
mozilla::Maybe<ConstantOrRegister> value;
if (ins->mir()->value()->isConstant())
value = ConstantOrRegister(ins->mir()->value()->toConstant()->toJSValue());
value.emplace(ConstantOrRegister(ins->mir()->value()->toConstant()->toJSValue()));
else
value = TypedOrValueRegister(ins->mir()->value()->type(), ToAnyRegister(ins->value()));
value.emplace(TypedOrValueRegister(ins->mir()->value()->type(), ToAnyRegister(ins->value())));
emitSetPropertyPolymorphic(ins, obj, temp1, temp2, value);
emitSetPropertyPolymorphic(ins, obj, temp1, temp2, value.ref());
}
void
@ -9388,7 +9386,7 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool)
LInstruction* ins = ool->ins();
const LAllocation* index;
MIRType valueType;
ConstantOrRegister value;
mozilla::Maybe<ConstantOrRegister> value;
Register spectreTemp;
if (ins->isStoreElementHoleV()) {
@ -9397,7 +9395,7 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool)
elements = ToRegister(store->elements());
index = store->index();
valueType = store->mir()->value()->type();
value = TypedOrValueRegister(ToValue(store, LStoreElementHoleV::Value));
value.emplace(TypedOrValueRegister(ToValue(store, LStoreElementHoleV::Value)));
spectreTemp = ToTempRegisterOrInvalid(store->spectreTemp());
} else if (ins->isFallibleStoreElementV()) {
LFallibleStoreElementV* store = ins->toFallibleStoreElementV();
@ -9405,7 +9403,7 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool)
elements = ToRegister(store->elements());
index = store->index();
valueType = store->mir()->value()->type();
value = TypedOrValueRegister(ToValue(store, LFallibleStoreElementV::Value));
value.emplace(TypedOrValueRegister(ToValue(store, LFallibleStoreElementV::Value)));
spectreTemp = ToTempRegisterOrInvalid(store->spectreTemp());
} else if (ins->isStoreElementHoleT()) {
LStoreElementHoleT* store = ins->toStoreElementHoleT();
@ -9414,9 +9412,9 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool)
index = store->index();
valueType = store->mir()->value()->type();
if (store->value()->isConstant())
value = ConstantOrRegister(store->value()->toConstant()->toJSValue());
value.emplace(ConstantOrRegister(store->value()->toConstant()->toJSValue()));
else
value = TypedOrValueRegister(valueType, ToAnyRegister(store->value()));
value.emplace(TypedOrValueRegister(valueType, ToAnyRegister(store->value())));
spectreTemp = ToTempRegisterOrInvalid(store->spectreTemp());
} else { // ins->isFallibleStoreElementT()
LFallibleStoreElementT* store = ins->toFallibleStoreElementT();
@ -9425,9 +9423,9 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool)
index = store->index();
valueType = store->mir()->value()->type();
if (store->value()->isConstant())
value = ConstantOrRegister(store->value()->toConstant()->toJSValue());
value.emplace(ConstantOrRegister(store->value()->toConstant()->toJSValue()));
else
value = TypedOrValueRegister(valueType, ToAnyRegister(store->value()));
value.emplace(TypedOrValueRegister(valueType, ToAnyRegister(store->value())));
spectreTemp = ToTempRegisterOrInvalid(store->spectreTemp());
}
@ -9488,7 +9486,7 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool)
saveLive(ins);
pushArg(Imm32(ool->strict()));
pushArg(value);
pushArg(value.ref());
if (index->isConstant())
pushArg(Imm32(ToInt32(index)));
else
@ -9737,13 +9735,13 @@ CodeGenerator::visitArrayPushT(LArrayPushT* lir)
Register obj = ToRegister(lir->object());
Register elementsTemp = ToRegister(lir->temp());
Register length = ToRegister(lir->output());
ConstantOrRegister value;
mozilla::Maybe<ConstantOrRegister> value;
if (lir->value()->isConstant())
value = ConstantOrRegister(lir->value()->toConstant()->toJSValue());
value.emplace(ConstantOrRegister(lir->value()->toConstant()->toJSValue()));
else
value = TypedOrValueRegister(lir->mir()->value()->type(), ToAnyRegister(lir->value()));
value.emplace(TypedOrValueRegister(lir->mir()->value()->type(), ToAnyRegister(lir->value())));
Register spectreTemp = ToTempRegisterOrInvalid(lir->spectreTemp());
emitArrayPush(lir, obj, value, elementsTemp, length, spectreTemp);
emitArrayPush(lir, obj, value.ref(), elementsTemp, length, spectreTemp);
}
typedef JSObject* (*ArraySliceDenseFn)(JSContext*, HandleObject, int32_t, int32_t, HandleObject);
@ -11719,30 +11717,30 @@ CodeGenerator::visitLoadElementFromStateV(LLoadElementFromStateV* lir)
// Add inlined code for loading arguments from where they are allocated.
for (size_t i = 0, e = array->numElements(); i < e; i++) {
MDefinition* elem = array->getElement(i);
ConstantOrRegister input;
mozilla::Maybe<ConstantOrRegister> input;
jumpTable->addCodeEntry(masm);
Register typeReg = Register::Invalid();
const LAllocation* a = lir->getOperand(1 + BOX_PIECES * i);
if (a->isBogus()) {
if (elem->type() == MIRType::Null) {
input = NullValue();
input.emplace(NullValue());
} else if (elem->type() == MIRType::Undefined) {
input = UndefinedValue();
input.emplace(UndefinedValue());
} else if (elem->isConstant() && elem->isEmittedAtUses()) {
input = elem->toConstant()->toJSValue();
input.emplace(elem->toConstant()->toJSValue());
} else {
MOZ_CRASH("Unsupported element constant allocation.");
}
} else if (a->isMemory()) {
if (elem->type() == MIRType::Double) {
masm.loadDouble(ToAddress(a), tempD);
input = TypedOrValueRegister(elem->type(), AnyRegister(tempD));
input.emplace(TypedOrValueRegister(elem->type(), AnyRegister(tempD)));
} else if (elem->type() == MIRType::Value) {
typeReg = temp0;
masm.loadPtr(ToAddress(a), temp0);
#ifdef JS_PUNBOX64
input = TypedOrValueRegister(ValueOperand(temp0));
input.emplace(TypedOrValueRegister(ValueOperand(temp0)));
#endif
} else {
typeReg = temp0;
@ -11753,24 +11751,23 @@ CodeGenerator::visitLoadElementFromStateV(LLoadElementFromStateV* lir)
masm.loadPtr(ToAddress(a), temp0);
else
MOZ_CRASH("Unsupported load size");
input = TypedOrValueRegister(elem->type(), AnyRegister(typeReg));
input.emplace(TypedOrValueRegister(elem->type(), AnyRegister(typeReg)));
}
} else if (a->isGeneralReg()) {
typeReg = ToRegister(a);
input = TypedOrValueRegister(elem->type(), AnyRegister(typeReg));
#ifdef JS_PUNBOX64
if (elem->type() != MIRType::Value)
input = TypedOrValueRegister(elem->type(), AnyRegister(typeReg));
input.emplace(TypedOrValueRegister(elem->type(), AnyRegister(typeReg)));
else
input = TypedOrValueRegister(ValueOperand(typeReg));
input.emplace(TypedOrValueRegister(ValueOperand(typeReg)));
#else
if (elem->type() != MIRType::Value)
input = TypedOrValueRegister(elem->type(), AnyRegister(typeReg));
input.emplace(TypedOrValueRegister(elem->type(), AnyRegister(typeReg)));
#endif
} else if (a->isFloatReg()) {
input = TypedOrValueRegister(elem->type(), AnyRegister(ToFloatRegister(a)));
input.emplace(TypedOrValueRegister(elem->type(), AnyRegister(ToFloatRegister(a))));
} else if (a->isConstantValue()) {
input = a->toConstant()->toJSValue();
input.emplace(a->toConstant()->toJSValue());
} else {
MOZ_CRASH("Unsupported element allocation.");
}
@ -11784,9 +11781,9 @@ CodeGenerator::visitLoadElementFromStateV(LLoadElementFromStateV* lir)
MOZ_ASSERT(typeReg != Register::Invalid());
if (a1->isMemory()) {
masm.loadPtr(ToAddress(a1), temp1);
input = TypedOrValueRegister(ValueOperand(typeReg, temp1));
input.emplace(TypedOrValueRegister(ValueOperand(typeReg, temp1)));
} else if (a1->isGeneralReg()) {
input = TypedOrValueRegister(ValueOperand(typeReg, ToRegister(a1)));
input.emplace(TypedOrValueRegister(ValueOperand(typeReg, ToRegister(a1))));
} else {
MOZ_CRASH("Unsupported Value allocation.");
}
@ -11794,7 +11791,7 @@ CodeGenerator::visitLoadElementFromStateV(LLoadElementFromStateV* lir)
MOZ_ASSERT(lir->getOperand(1 + BOX_PIECES * i + 1)->isBogus());
}
#endif
masm.moveValue(input, out);
masm.moveValue(input.ref(), out);
// For the last entry, fall-through.
if (i + 1 < e)

Просмотреть файл

@ -252,7 +252,7 @@ class CompileInfo
explicit CompileInfo(unsigned nlocals)
: script_(nullptr), fun_(nullptr), osrPc_(nullptr),
analysisMode_(Analysis_None), scriptNeedsArgsObj_(false),
analysisMode_(Analysis_None), scriptNeedsArgsObj_(false), hadOverflowBailout_(false),
mayReadFrameArgsDirectly_(false), inlineScriptTree_(nullptr),
needsBodyEnvironmentObject_(false), funNeedsSomeEnvironmentObject_(false)
{

Просмотреть файл

@ -391,7 +391,8 @@ JSContext::freeOsrTempData()
}
JitRealm::JitRealm()
: stubCodes_(nullptr)
: stubCodes_(nullptr),
stringsCanBeInNursery(false)
{
}
@ -844,6 +845,7 @@ IonScript::IonScript(IonCompilationId compilationId)
safepointsStart_(0),
safepointsSize_(0),
frameSlots_(0),
argumentSlots_(0),
frameSize_(0),
bailoutTable_(0),
bailoutEntries_(0),
@ -852,10 +854,15 @@ IonScript::IonScript(IonCompilationId compilationId)
snapshots_(0),
snapshotsListSize_(0),
snapshotsRVATableSize_(0),
recovers_(0),
recoversSize_(0),
constantTable_(0),
constantEntries_(0),
sharedStubList_(0),
sharedStubEntries_(0),
invalidationCount_(0),
compilationId_(compilationId),
optimizationLevel_(OptimizationLevel::Normal),
osrPcMismatchCounter_(0),
fallbackStubSpace_()
{

Просмотреть файл

@ -136,6 +136,7 @@ IonBuilder::IonBuilder(JSContext* analysisContext, CompileRealm* realm,
typeArray(nullptr),
typeArrayHint(0),
bytecodeTypeMap(nullptr),
current(nullptr),
loopDepth_(loopDepth),
blockWorklist(*temp),
cfgCurrent(nullptr),
@ -7958,7 +7959,7 @@ IonBuilder::getElemTryReferenceElemOfTypedObject(bool* emitted,
{
MOZ_ASSERT(objPrediction.ofArrayKind());
ReferenceTypeDescr::Type elemType = elemPrediction.referenceType();
ReferenceType elemType = elemPrediction.referenceType();
uint32_t elemSize = ReferenceTypeDescr::size(elemType);
LinearSum indexAsByteOffset(alloc());
@ -8016,7 +8017,7 @@ IonBuilder::pushScalarLoadFromTypedObject(MDefinition* obj,
AbortReasonOr<Ok>
IonBuilder::pushReferenceLoadFromTypedObject(MDefinition* typedObj,
const LinearSum& byteOffset,
ReferenceTypeDescr::Type type,
ReferenceType type,
PropertyName* name)
{
// Find location within the owner object.
@ -8033,7 +8034,7 @@ IonBuilder::pushReferenceLoadFromTypedObject(MDefinition* typedObj,
typedObj, name, observedTypes);
switch (type) {
case ReferenceTypeDescr::TYPE_ANY: {
case ReferenceType::TYPE_ANY: {
// Make sure the barrier reflects the possibility of reading undefined.
bool bailOnUndefined = barrier == BarrierKind::NoBarrier &&
!observedTypes->hasType(TypeSet::UndefinedType());
@ -8042,7 +8043,7 @@ IonBuilder::pushReferenceLoadFromTypedObject(MDefinition* typedObj,
load = MLoadElement::New(alloc(), elements, scaledOffset, false, false, adjustment);
break;
}
case ReferenceTypeDescr::TYPE_OBJECT: {
case ReferenceType::TYPE_OBJECT: {
// Make sure the barrier reflects the possibility of reading null. When
// there is no other barrier needed we include the null bailout with
// MLoadUnboxedObjectOrNull, which avoids the need to box the result
@ -8056,7 +8057,7 @@ IonBuilder::pushReferenceLoadFromTypedObject(MDefinition* typedObj,
adjustment);
break;
}
case ReferenceTypeDescr::TYPE_STRING: {
case ReferenceType::TYPE_STRING: {
load = MLoadUnboxedString::New(alloc(), elements, scaledOffset, adjustment);
observedTypes->addType(TypeSet::StringType(), alloc().lifoAlloc());
break;
@ -8955,7 +8956,7 @@ IonBuilder::setElemTryReferenceElemOfTypedObject(bool* emitted,
MDefinition* value,
TypedObjectPrediction elemPrediction)
{
ReferenceTypeDescr::Type elemType = elemPrediction.referenceType();
ReferenceType elemType = elemPrediction.referenceType();
uint32_t elemSize = ReferenceTypeDescr::size(elemType);
LinearSum indexAsByteOffset(alloc());
@ -10603,7 +10604,7 @@ IonBuilder::getPropTryReferencePropOfTypedObject(bool* emitted, MDefinition* typ
TypedObjectPrediction fieldPrediction,
PropertyName* name)
{
ReferenceTypeDescr::Type fieldType = fieldPrediction.referenceType();
ReferenceType fieldType = fieldPrediction.referenceType();
TypeSet::ObjectKey* globalKey = TypeSet::ObjectKey::get(&script()->global());
if (globalKey->hasFlags(constraints(), OBJECT_FLAG_TYPED_OBJECT_HAS_DETACHED_BUFFER))
@ -11718,7 +11719,7 @@ IonBuilder::setPropTryReferencePropOfTypedObject(bool* emitted,
TypedObjectPrediction fieldPrediction,
PropertyName* name)
{
ReferenceTypeDescr::Type fieldType = fieldPrediction.referenceType();
ReferenceType fieldType = fieldPrediction.referenceType();
TypeSet::ObjectKey* globalKey = TypeSet::ObjectKey::get(&script()->global());
if (globalKey->hasFlags(constraints(), OBJECT_FLAG_TYPED_OBJECT_HAS_DETACHED_BUFFER))
@ -13563,7 +13564,7 @@ AbortReasonOr<Ok>
IonBuilder::setPropTryReferenceTypedObjectValue(bool* emitted,
MDefinition* typedObj,
const LinearSum& byteOffset,
ReferenceTypeDescr::Type type,
ReferenceType type,
MDefinition* value,
PropertyName* name)
{
@ -13571,11 +13572,11 @@ IonBuilder::setPropTryReferenceTypedObjectValue(bool* emitted,
// Make sure we aren't adding new type information for writes of object and value
// references.
if (type != ReferenceTypeDescr::TYPE_STRING) {
MOZ_ASSERT(type == ReferenceTypeDescr::TYPE_ANY ||
type == ReferenceTypeDescr::TYPE_OBJECT);
if (type != ReferenceType::TYPE_STRING) {
MOZ_ASSERT(type == ReferenceType::TYPE_ANY ||
type == ReferenceType::TYPE_OBJECT);
MIRType implicitType =
(type == ReferenceTypeDescr::TYPE_ANY) ? MIRType::Undefined : MIRType::Null;
(type == ReferenceType::TYPE_ANY) ? MIRType::Undefined : MIRType::Null;
if (PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current, &typedObj, name, &value,
/* canModify = */ true, implicitType))
@ -13595,20 +13596,20 @@ IonBuilder::setPropTryReferenceTypedObjectValue(bool* emitted,
MInstruction* store = nullptr; // initialize to silence GCC warning
switch (type) {
case ReferenceTypeDescr::TYPE_ANY:
case ReferenceType::TYPE_ANY:
if (needsPostBarrier(value))
current->add(MPostWriteBarrier::New(alloc(), typedObj, value));
store = MStoreElement::New(alloc(), elements, scaledOffset, value, false, adjustment);
store->toStoreElement()->setNeedsBarrier();
break;
case ReferenceTypeDescr::TYPE_OBJECT:
case ReferenceType::TYPE_OBJECT:
// Note: We cannot necessarily tell at this point whether a post
// barrier is needed, because the type policy may insert ToObjectOrNull
// instructions later, and those may require a post barrier. Therefore,
// defer the insertion of post barriers to the type policy.
store = MStoreUnboxedObjectOrNull::New(alloc(), elements, scaledOffset, value, typedObj, adjustment);
break;
case ReferenceTypeDescr::TYPE_STRING:
case ReferenceType::TYPE_STRING:
// See previous comment. The StoreUnboxedString type policy may insert
// ToString instructions that require a post barrier.
store = MStoreUnboxedString::New(alloc(), elements, scaledOffset, value, typedObj, adjustment);

Просмотреть файл

@ -288,7 +288,7 @@ class IonBuilder
AbortReasonOr<Ok> setPropTryReferenceTypedObjectValue(bool* emitted,
MDefinition* typedObj,
const LinearSum& byteOffset,
ReferenceTypeDescr::Type type,
ReferenceType type,
MDefinition* value,
PropertyName* name);
AbortReasonOr<Ok> setPropTryScalarPropOfTypedObject(bool* emitted,
@ -385,7 +385,7 @@ class IonBuilder
ScalarTypeDescr::Type type);
AbortReasonOr<Ok> pushReferenceLoadFromTypedObject(MDefinition* typedObj,
const LinearSum& byteOffset,
ReferenceTypeDescr::Type type,
ReferenceType type,
PropertyName* name);
// jsop_setelem() helpers.

Просмотреть файл

@ -1695,7 +1695,7 @@ IonCacheIRCompiler::emitStoreTypedObjectReferenceProperty()
Register obj = allocator.useRegister(masm, reader.objOperandId());
int32_t offset = int32StubField(reader.stubOffset());
TypedThingLayout layout = reader.typedThingLayout();
ReferenceTypeDescr::Type type = reader.referenceTypeDescrType();
ReferenceType type = reader.referenceTypeDescrType();
ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
@ -1704,7 +1704,7 @@ IonCacheIRCompiler::emitStoreTypedObjectReferenceProperty()
// We don't need to check property types if the property is always a
// string.
if (type != ReferenceTypeDescr::TYPE_STRING) {
if (type != ReferenceType::TYPE_STRING) {
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
@ -1718,7 +1718,7 @@ IonCacheIRCompiler::emitStoreTypedObjectReferenceProperty()
emitStoreTypedObjectReferenceProp(val, type, dest, scratch2);
if (needsPostBarrier() && type != ReferenceTypeDescr::TYPE_STRING)
if (needsPostBarrier() && type != ReferenceType::TYPE_STRING)
emitPostBarrierSlot(obj, val, scratch1);
return true;
}

Просмотреть файл

@ -68,10 +68,7 @@ class JitCode : public gc::TenuredCell
bool hasBytecodeMap_ : 1; // Whether the code object has been registered with
// native=>bytecode mapping tables.
JitCode()
: code_(nullptr),
pool_(nullptr)
{ }
JitCode() = delete;
JitCode(uint8_t* code, uint32_t bufferSize, uint32_t headerSize, ExecutablePool* pool,
CodeKind kind)
: code_(code),

Просмотреть файл

@ -15,6 +15,7 @@ using mozilla::DebugOnly;
ControlFlowGenerator::ControlFlowGenerator(TempAllocator& temp, JSScript* script)
: script(script),
current(nullptr),
pc(nullptr),
alloc_(temp),
blocks_(temp),
cfgStack_(temp),

Просмотреть файл

@ -149,7 +149,36 @@ class OptimizationInfo
// as a multiplication of inliningWarmUpThreshold.
uint32_t inliningRecompileThresholdFactor_;
OptimizationInfo()
constexpr OptimizationInfo()
: level_(OptimizationLevel::Normal),
eaa_(false),
ama_(false),
edgeCaseAnalysis_(false),
eliminateRedundantChecks_(false),
inlineInterpreted_(false),
inlineNative_(false),
eagerSimdUnbox_(false),
gvn_(false),
licm_(false),
rangeAnalysis_(false),
loopUnrolling_(false),
reordering_(false),
autoTruncate_(false),
sincos_(false),
sink_(false),
registerAllocator_(RegisterAllocator_Backtracking),
inlineMaxBytecodePerCallSiteHelperThread_(0),
inlineMaxBytecodePerCallSiteMainThread_(0),
inlineMaxCalleeInlinedBytecodeLength_(0),
inlineMaxTotalBytecodeLength_(0),
inliningMaxCallerBytecodeLength_(0),
maxInlineDepth_(0),
scalarReplacement_(false),
smallFunctionMaxInlineDepth_(0),
compilerWarmUpThreshold_(0),
compilerSmallFunctionWarmUpThreshold_(0),
inliningWarmUpThresholdFactor_(0.0),
inliningRecompileThresholdFactor_(0)
{ }
void initNormalOptimizationInfo();

Просмотреть файл

@ -12,6 +12,8 @@
#include "mozilla/OperatorNewExtensions.h"
#include "mozilla/TypeTraits.h"
#include <utility>
#include "ds/LifoAlloc.h"
#include "jit/InlineList.h"
#include "jit/Ion.h"
@ -189,11 +191,13 @@ class TempObjectPool
MOZ_ASSERT(freed_.empty());
alloc_ = &alloc;
}
T* allocate() {
template <typename... Args>
T* allocate(Args&&... args) {
MOZ_ASSERT(alloc_);
if (freed_.empty())
return new(alloc_->fallible()) T();
return freed_.popFront();
return new (alloc_->fallible()) T(std::forward<Args>(args)...);
T* res = freed_.popFront();
return new (res) T(std::forward<Args>(args)...);
}
void free(T* obj) {
freed_.pushFront(obj);

Просмотреть файл

@ -1541,6 +1541,7 @@ SnapshotIterator::SnapshotIterator()
: snapshot_(nullptr, 0, 0, 0),
recover_(snapshot_, nullptr, 0),
fp_(nullptr),
machine_(nullptr),
ionScript_(nullptr),
instructionResults_(nullptr)
{
@ -2054,7 +2055,9 @@ SnapshotIterator::maybeReadAllocByIndex(size_t index)
InlineFrameIterator::InlineFrameIterator(JSContext* cx, const JSJitFrameIter* iter)
: calleeTemplate_(cx),
calleeRVA_(),
script_(cx)
script_(cx),
pc_(nullptr),
numActualArgs_(0)
{
resetOn(iter);
}
@ -2065,7 +2068,9 @@ InlineFrameIterator::InlineFrameIterator(JSContext* cx, const InlineFrameIterato
frameCount_(iter ? iter->frameCount_ : UINT32_MAX),
calleeTemplate_(cx),
calleeRVA_(),
script_(cx)
script_(cx),
pc_(nullptr),
numActualArgs_(0)
{
if (frame_) {
machine_ = iter->machine_;

Просмотреть файл

@ -230,8 +230,7 @@ class FrameSizeClass
{ }
public:
FrameSizeClass()
{ }
FrameSizeClass() = delete;
static FrameSizeClass None() {
return FrameSizeClass(NO_FRAME_SIZE_CLASS_ID);

Просмотреть файл

@ -32,8 +32,16 @@ class FrameSizeClass;
struct EnterJitData
{
explicit EnterJitData(JSContext* cx)
: envChain(cx),
result(cx)
: jitcode(nullptr),
osrFrame(nullptr),
calleeToken(nullptr),
maxArgv(nullptr),
maxArgc(0),
numActualArgs(0),
osrNumStackValues(0),
envChain(cx),
result(cx),
constructing(false)
{}
uint8_t* jitcode;

Просмотреть файл

@ -1464,7 +1464,7 @@ struct SafepointSlotEntry {
// Byte offset of the slot, as in LStackSlot or LArgument.
uint32_t slot:31;
SafepointSlotEntry() { }
SafepointSlotEntry() : stack(0), slot(0) { }
SafepointSlotEntry(bool stack, uint32_t slot)
: stack(stack), slot(slot)
{ }
@ -1478,7 +1478,7 @@ struct SafepointNunboxEntry {
LAllocation type;
LAllocation payload;
SafepointNunboxEntry() { }
SafepointNunboxEntry() : typeVreg(0) { }
SafepointNunboxEntry(uint32_t typeVreg, LAllocation type, LAllocation payload)
: typeVreg(typeVreg), type(type), payload(payload)
{ }

Просмотреть файл

@ -489,6 +489,8 @@ MBasicBlock::MBasicBlock(MIRGraph& graph, const CompileInfo& info, BytecodeSite*
info_(info),
predecessors_(graph.alloc()),
stackPosition_(info_.firstStackSlot()),
id_(0),
domIndex_(0),
numDominated_(0),
pc_(site->pc()),
lir_(nullptr),

Просмотреть файл

@ -2808,6 +2808,7 @@ MacroAssembler::MacroAssembler(JSContext* cx)
#ifdef DEBUG
inCall_(false),
#endif
dynamicAlignment_(false),
emitProfilingInstrumentation_(false)
{
jitContext_.emplace(cx, (js::jit::TempAllocator*)nullptr);
@ -2827,6 +2828,7 @@ MacroAssembler::MacroAssembler()
#ifdef DEBUG
inCall_(false),
#endif
dynamicAlignment_(false),
emitProfilingInstrumentation_(false)
{
JitContext* jcx = GetJitContext();
@ -2853,6 +2855,7 @@ MacroAssembler::MacroAssembler(WasmToken, TempAllocator& alloc)
#ifdef DEBUG
inCall_(false),
#endif
dynamicAlignment_(false),
emitProfilingInstrumentation_(false)
{
moveResolver_.setAllocator(alloc);

Просмотреть файл

@ -2193,7 +2193,7 @@ class MacroAssembler : public MacroAssemblerSpecific
void branchIfNativeIteratorNotReusable(Register ni, Label* notReusable);
using MacroAssemblerSpecific::extractTag;
Register extractTag(const TypedOrValueRegister& reg, Register scratch) {
MOZ_MUST_USE Register extractTag(const TypedOrValueRegister& reg, Register scratch) {
if (reg.hasValue())
return extractTag(reg.valueReg(), scratch);
mov(ImmWord(MIRTypeToTag(reg.type())), scratch);
@ -2201,7 +2201,7 @@ class MacroAssembler : public MacroAssemblerSpecific
}
using MacroAssemblerSpecific::extractObject;
Register extractObject(const TypedOrValueRegister& reg, Register scratch) {
MOZ_MUST_USE Register extractObject(const TypedOrValueRegister& reg, Register scratch) {
if (reg.hasValue())
return extractObject(reg.valueReg(), scratch);
MOZ_ASSERT(reg.type() == MIRType::Object);

Просмотреть файл

@ -16,6 +16,7 @@ using namespace js;
using namespace js::jit;
MoveOperand::MoveOperand(MacroAssembler& masm, const ABIArg& arg)
: disp_(0)
{
switch (arg.kind()) {
case ABIArg::GPR:
@ -64,10 +65,9 @@ MoveResolver::addMove(const MoveOperand& from, const MoveOperand& to, MoveOp::Ty
{
// Assert that we're not doing no-op moves.
MOZ_ASSERT(!(from == to));
PendingMove* pm = movePool_.allocate();
PendingMove* pm = movePool_.allocate(from, to, type);
if (!pm)
return false;
new (pm) PendingMove(from, to, type);
pending_.pushBack(pm);
return true;
}
@ -205,14 +205,14 @@ MoveResolver::resolve()
PendingMove* pm = *iter;
if (isDoubleAliasedAsSingle(pm->from()) || isDoubleAliasedAsSingle(pm->to())) {
PendingMove* lower = movePool_.allocate();
MoveOperand fromLower = SplitIntoLowerHalf(pm->from());
MoveOperand toLower = SplitIntoLowerHalf(pm->to());
PendingMove* lower = movePool_.allocate(fromLower, toLower, MoveOp::FLOAT32);
if (!lower)
return false;
// Insert the new node before the current position to not affect iteration.
MoveOperand fromLower = SplitIntoLowerHalf(pm->from());
MoveOperand toLower = SplitIntoLowerHalf(pm->to());
new (lower) PendingMove(fromLower, toLower, MoveOp::FLOAT32);
pending_.insertBefore(pm, lower);
// Overwrite pm in place for the upper move. Iteration proceeds as normal.

Просмотреть файл

@ -45,11 +45,10 @@ class MoveOperand
int32_t disp_;
public:
MoveOperand()
MoveOperand() = delete;
explicit MoveOperand(Register reg) : kind_(REG), code_(reg.code()), disp_(0)
{ }
explicit MoveOperand(Register reg) : kind_(REG), code_(reg.code())
{ }
explicit MoveOperand(FloatRegister reg) : kind_(FLOAT_REG), code_(reg.code())
explicit MoveOperand(FloatRegister reg) : kind_(FLOAT_REG), code_(reg.code()), disp_(0)
{ }
MoveOperand(Register reg, int32_t disp, Kind kind = MEMORY)
: kind_(kind),
@ -207,8 +206,7 @@ class MoveOp
Type endCycleType_;
public:
MoveOp()
{ }
MoveOp() = delete;
MoveOp(const MoveOperand& from, const MoveOperand& to, Type type)
: from_(from),
to_(to),
@ -270,8 +268,8 @@ class MoveResolver
public TempObject,
public InlineListNode<PendingMove>
{
PendingMove()
{ }
PendingMove() = delete;
PendingMove(const MoveOperand& from, const MoveOperand& to, Type type)
: MoveOp(from, to, type)
{ }

Просмотреть файл

@ -454,7 +454,9 @@ struct IonTrackedTypeWithAddendum
explicit IonTrackedTypeWithAddendum(TypeSet::Type type)
: type(type),
hasAddendum(HasNothing)
hasAddendum(HasNothing),
script(nullptr),
offset(0)
{ }
IonTrackedTypeWithAddendum(TypeSet::Type type, JSScript* script, uint32_t offset)

Просмотреть файл

@ -195,15 +195,15 @@ class Range : public TempObject {
// exponent computation have to be over-estimations of the actual result. On
// the Int32 this over approximation is rectified.
int32_t lower_;
int32_t upper_;
MOZ_INIT_OUTSIDE_CTOR int32_t lower_;
MOZ_INIT_OUTSIDE_CTOR int32_t upper_;
bool hasInt32LowerBound_;
bool hasInt32UpperBound_;
MOZ_INIT_OUTSIDE_CTOR bool hasInt32LowerBound_;
MOZ_INIT_OUTSIDE_CTOR bool hasInt32UpperBound_;
FractionalPartFlag canHaveFractionalPart_ : 1;
NegativeZeroFlag canBeNegativeZero_ : 1;
uint16_t max_exponent_;
MOZ_INIT_OUTSIDE_CTOR FractionalPartFlag canHaveFractionalPart_ : 1;
MOZ_INIT_OUTSIDE_CTOR NegativeZeroFlag canBeNegativeZero_ : 1;
MOZ_INIT_OUTSIDE_CTOR uint16_t max_exponent_;
// Any symbolic lower or upper bound computed for this term.
const SymbolicBound* symbolicLower_;

Просмотреть файл

@ -246,8 +246,7 @@ class ConstantOrRegister
public:
ConstantOrRegister()
{}
ConstantOrRegister() = delete;
MOZ_IMPLICIT ConstantOrRegister(const Value& value)
: constant_(true)

Просмотреть файл

@ -36,13 +36,16 @@ RematerializedFrame::RematerializedFrame(JSContext* cx, uint8_t* top, unsigned n
InlineFrameIterator& iter, MaybeReadFallback& fallback)
: prevUpToDate_(false),
isDebuggee_(iter.script()->isDebuggee()),
hasInitialEnv_(false),
isConstructing_(iter.isConstructing()),
hasCachedSavedFrame_(false),
top_(top),
pc_(iter.pc()),
frameNo_(iter.frameNo()),
numActualArgs_(numActualArgs),
script_(iter.script())
script_(iter.script()),
envChain_(nullptr),
argsObj_(nullptr)
{
if (iter.isFunctionFrame())
callee_ = iter.callee(fallback);

Просмотреть файл

@ -395,7 +395,9 @@ SafepointReader::SafepointReader(IonScript* script, const SafepointIndex* si)
: stream_(script->safepoints() + si->safepointOffset(),
script->safepoints() + script->safepointsSize()),
frameSlots_((script->frameSlots() / sizeof(intptr_t)) + 1), // Stack slot counts are inclusive.
argumentSlots_(script->argumentSlots() / sizeof(intptr_t))
argumentSlots_(script->argumentSlots() / sizeof(intptr_t)),
nunboxSlotsRemaining_(0),
slotsOrElementsSlotsRemaining_(0)
{
osiCallPointOffset_ = stream_.readUnsigned();

Просмотреть файл

@ -374,6 +374,7 @@ const char* ObjectMemoryView::phaseName = "Scalar Replacement of Object";
ObjectMemoryView::ObjectMemoryView(TempAllocator& alloc, MInstruction* obj)
: alloc_(alloc),
undefinedVal_(nullptr),
obj_(obj),
startBlock_(obj->block()),
state_(nullptr),

Просмотреть файл

@ -2308,11 +2308,11 @@ ScalarTypeFromSimpleTypeDescrKey(uint32_t key)
return ScalarTypeDescr::Type(key >> 1);
}
inline ReferenceTypeDescr::Type
inline ReferenceType
ReferenceTypeFromSimpleTypeDescrKey(uint32_t key)
{
MOZ_ASSERT(!SimpleTypeDescrKeyIsScalar(key));
return ReferenceTypeDescr::Type(key >> 1);
return ReferenceType(key >> 1);
}
// JSOP_NEWARRAY

Просмотреть файл

@ -53,7 +53,8 @@ class StupidAllocator : public RegisterAllocator
public:
StupidAllocator(MIRGenerator* mir, LIRGenerator* lir, LIRGraph& graph)
: RegisterAllocator(mir, lir, graph)
: RegisterAllocator(mir, lir, graph),
registerCount(0)
{
}

Просмотреть файл

@ -201,7 +201,7 @@ TypedObjectPrediction::scalarType() const
return extractType<ScalarTypeDescr>();
}
ReferenceTypeDescr::Type
ReferenceType
TypedObjectPrediction::referenceType() const
{
return extractType<ReferenceTypeDescr>();

Просмотреть файл

@ -118,7 +118,8 @@ class TypedObjectPrediction {
// Constructing a prediction. Generally, you start with an empty
// prediction and invoke addDescr() repeatedly.
TypedObjectPrediction() {
TypedObjectPrediction()
: data_() {
kind_ = Empty;
}
@ -166,8 +167,8 @@ class TypedObjectPrediction {
//
// Only valid when |kind()| is Scalar, Reference, or Simd (as appropriate).
ScalarTypeDescr::Type scalarType() const;
ReferenceTypeDescr::Type referenceType() const;
Scalar::Type scalarType() const;
ReferenceType referenceType() const;
SimdType simdType() const;
///////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -2784,8 +2784,8 @@ MacroAssemblerARMCompat::testGCThing(Assembler::Condition cond, const Address& a
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(address, scratch);
ma_cmp(scratch, ImmTag(JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET));
Register tag = extractTag(address, scratch);
ma_cmp(tag, ImmTag(JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET));
return cond == Equal ? AboveOrEqual : Below;
}
@ -2794,8 +2794,8 @@ MacroAssemblerARMCompat::testMagic(Assembler::Condition cond, const Address& add
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(address, scratch);
ma_cmp(scratch, ImmTag(JSVAL_TAG_MAGIC));
Register tag = extractTag(address, scratch);
ma_cmp(tag, ImmTag(JSVAL_TAG_MAGIC));
return cond;
}
@ -2804,8 +2804,8 @@ MacroAssemblerARMCompat::testInt32(Assembler::Condition cond, const Address& add
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(address, scratch);
ma_cmp(scratch, ImmTag(JSVAL_TAG_INT32));
Register tag = extractTag(address, scratch);
ma_cmp(tag, ImmTag(JSVAL_TAG_INT32));
return cond;
}
@ -2814,8 +2814,8 @@ MacroAssemblerARMCompat::testDouble(Condition cond, const Address& address)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(address, scratch);
return testDouble(cond, scratch);
Register tag = extractTag(address, scratch);
return testDouble(cond, tag);
}
Assembler::Condition
@ -2823,8 +2823,8 @@ MacroAssemblerARMCompat::testBoolean(Condition cond, const Address& address)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(address, scratch);
return testBoolean(cond, scratch);
Register tag = extractTag(address, scratch);
return testBoolean(cond, tag);
}
Assembler::Condition
@ -2832,8 +2832,8 @@ MacroAssemblerARMCompat::testNull(Condition cond, const Address& address)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(address, scratch);
return testNull(cond, scratch);
Register tag = extractTag(address, scratch);
return testNull(cond, tag);
}
Assembler::Condition
@ -2841,8 +2841,8 @@ MacroAssemblerARMCompat::testUndefined(Condition cond, const Address& address)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(address, scratch);
return testUndefined(cond, scratch);
Register tag = extractTag(address, scratch);
return testUndefined(cond, tag);
}
Assembler::Condition
@ -2850,8 +2850,8 @@ MacroAssemblerARMCompat::testString(Condition cond, const Address& address)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(address, scratch);
return testString(cond, scratch);
Register tag = extractTag(address, scratch);
return testString(cond, tag);
}
Assembler::Condition
@ -2859,8 +2859,8 @@ MacroAssemblerARMCompat::testSymbol(Condition cond, const Address& address)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(address, scratch);
return testSymbol(cond, scratch);
Register tag = extractTag(address, scratch);
return testSymbol(cond, tag);
}
Assembler::Condition
@ -2868,8 +2868,8 @@ MacroAssemblerARMCompat::testObject(Condition cond, const Address& address)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(address, scratch);
return testObject(cond, scratch);
Register tag = extractTag(address, scratch);
return testObject(cond, tag);
}
Assembler::Condition
@ -2877,8 +2877,8 @@ MacroAssemblerARMCompat::testNumber(Condition cond, const Address& address)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(address, scratch);
return testNumber(cond, scratch);
Register tag = extractTag(address, scratch);
return testNumber(cond, tag);
}
Assembler::Condition
@ -2903,8 +2903,8 @@ MacroAssemblerARMCompat::testUndefined(Condition cond, const BaseIndex& src)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(src, scratch);
ma_cmp(scratch, ImmTag(JSVAL_TAG_UNDEFINED));
Register tag = extractTag(src, scratch);
ma_cmp(tag, ImmTag(JSVAL_TAG_UNDEFINED));
return cond;
}
@ -2913,8 +2913,8 @@ MacroAssemblerARMCompat::testNull(Condition cond, const BaseIndex& src)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(src, scratch);
ma_cmp(scratch, ImmTag(JSVAL_TAG_NULL));
Register tag = extractTag(src, scratch);
ma_cmp(tag, ImmTag(JSVAL_TAG_NULL));
return cond;
}
@ -2923,8 +2923,8 @@ MacroAssemblerARMCompat::testBoolean(Condition cond, const BaseIndex& src)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(src, scratch);
ma_cmp(scratch, ImmTag(JSVAL_TAG_BOOLEAN));
Register tag = extractTag(src, scratch);
ma_cmp(tag, ImmTag(JSVAL_TAG_BOOLEAN));
return cond;
}
@ -2933,8 +2933,8 @@ MacroAssemblerARMCompat::testString(Condition cond, const BaseIndex& src)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(src, scratch);
ma_cmp(scratch, ImmTag(JSVAL_TAG_STRING));
Register tag = extractTag(src, scratch);
ma_cmp(tag, ImmTag(JSVAL_TAG_STRING));
return cond;
}
@ -2943,8 +2943,8 @@ MacroAssemblerARMCompat::testSymbol(Condition cond, const BaseIndex& src)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(src, scratch);
ma_cmp(scratch, ImmTag(JSVAL_TAG_SYMBOL));
Register tag = extractTag(src, scratch);
ma_cmp(tag, ImmTag(JSVAL_TAG_SYMBOL));
return cond;
}
@ -2953,8 +2953,8 @@ MacroAssemblerARMCompat::testInt32(Condition cond, const BaseIndex& src)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(src, scratch);
ma_cmp(scratch, ImmTag(JSVAL_TAG_INT32));
Register tag = extractTag(src, scratch);
ma_cmp(tag, ImmTag(JSVAL_TAG_INT32));
return cond;
}
@ -2963,8 +2963,8 @@ MacroAssemblerARMCompat::testObject(Condition cond, const BaseIndex& src)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(src, scratch);
ma_cmp(scratch, ImmTag(JSVAL_TAG_OBJECT));
Register tag = extractTag(src, scratch);
ma_cmp(tag, ImmTag(JSVAL_TAG_OBJECT));
return cond;
}
@ -2974,8 +2974,8 @@ MacroAssemblerARMCompat::testDouble(Condition cond, const BaseIndex& src)
MOZ_ASSERT(cond == Equal || cond == NotEqual);
Assembler::Condition actual = (cond == Equal) ? Below : AboveOrEqual;
ScratchRegisterScope scratch(asMasm());
extractTag(src, scratch);
ma_cmp(scratch, ImmTag(JSVAL_TAG_CLEAR));
Register tag = extractTag(src, scratch);
ma_cmp(tag, ImmTag(JSVAL_TAG_CLEAR));
return actual;
}
@ -2984,8 +2984,8 @@ MacroAssemblerARMCompat::testMagic(Condition cond, const BaseIndex& address)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(address, scratch);
ma_cmp(scratch, ImmTag(JSVAL_TAG_MAGIC));
Register tag = extractTag(address, scratch);
ma_cmp(tag, ImmTag(JSVAL_TAG_MAGIC));
return cond;
}
@ -2994,8 +2994,8 @@ MacroAssemblerARMCompat::testGCThing(Condition cond, const BaseIndex& address)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
extractTag(address, scratch);
ma_cmp(scratch, ImmTag(JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET));
Register tag = extractTag(address, scratch);
ma_cmp(tag, ImmTag(JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET));
return cond == Equal ? AboveOrEqual : Below;
}
@ -4931,7 +4931,7 @@ MacroAssembler::branchValueIsNurseryCell(Condition cond, const Address& address,
Label done, checkAddress;
Register tag = temp;
extractTag(address, tag);
tag = extractTag(address, tag);
branchTestObject(Assembler::Equal, tag, &checkAddress);
branchTestString(Assembler::NotEqual, tag, cond == Assembler::Equal ? &done : label);

Просмотреть файл

@ -825,24 +825,24 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
// Extended unboxing API. If the payload is already in a register, returns
// that register. Otherwise, provides a move to the given scratch register,
// and returns that.
Register extractObject(const Address& address, Register scratch);
Register extractObject(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractObject(const Address& address, Register scratch);
MOZ_MUST_USE Register extractObject(const ValueOperand& value, Register scratch) {
unboxNonDouble(value, value.payloadReg(), JSVAL_TYPE_OBJECT);
return value.payloadReg();
}
Register extractSymbol(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractSymbol(const ValueOperand& value, Register scratch) {
unboxNonDouble(value, value.payloadReg(), JSVAL_TYPE_SYMBOL);
return value.payloadReg();
}
Register extractInt32(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractInt32(const ValueOperand& value, Register scratch) {
return value.payloadReg();
}
Register extractBoolean(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractBoolean(const ValueOperand& value, Register scratch) {
return value.payloadReg();
}
Register extractTag(const Address& address, Register scratch);
Register extractTag(const BaseIndex& address, Register scratch);
Register extractTag(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractTag(const Address& address, Register scratch);
MOZ_MUST_USE Register extractTag(const BaseIndex& address, Register scratch);
MOZ_MUST_USE Register extractTag(const ValueOperand& value, Register scratch) {
return value.typeReg();
}

Просмотреть файл

@ -799,7 +799,6 @@ JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm, const VMFunct
// Copy any arguments.
for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) {
MoveOperand from;
switch (f.argProperties(explicitArg)) {
case VMFunction::WordByValue:
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL);

Просмотреть файл

@ -994,7 +994,7 @@ MacroAssembler::branchValueIsNurseryObject(Condition cond, ValueOperand value, R
Label done;
branchTestObject(Assembler::NotEqual, value, cond == Assembler::Equal ? &done : label);
extractObject(value, temp);
unboxObject(value, temp);
orPtr(Imm32(gc::ChunkMask), temp);
branch32(cond, Address(temp, gc::ChunkLocationOffsetFromLastByte),
Imm32(int32_t(gc::ChunkLocation::Nursery)), label);

Просмотреть файл

@ -400,33 +400,33 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
void splitTag(Register src, Register dest) {
ubfx(ARMRegister(dest, 64), ARMRegister(src, 64), JSVAL_TAG_SHIFT, (64 - JSVAL_TAG_SHIFT));
}
Register extractTag(const Address& address, Register scratch) {
MOZ_MUST_USE Register extractTag(const Address& address, Register scratch) {
loadPtr(address, scratch);
splitTag(scratch, scratch);
return scratch;
}
Register extractTag(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractTag(const ValueOperand& value, Register scratch) {
splitTag(value.valueReg(), scratch);
return scratch;
}
Register extractObject(const Address& address, Register scratch) {
MOZ_MUST_USE Register extractObject(const Address& address, Register scratch) {
loadPtr(address, scratch);
unboxObject(scratch, scratch);
return scratch;
}
Register extractObject(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractObject(const ValueOperand& value, Register scratch) {
unboxObject(value, scratch);
return scratch;
}
Register extractSymbol(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractSymbol(const ValueOperand& value, Register scratch) {
unboxSymbol(value, scratch);
return scratch;
}
Register extractInt32(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractInt32(const ValueOperand& value, Register scratch) {
unboxInt32(value, scratch);
return scratch;
}
Register extractBoolean(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractBoolean(const ValueOperand& value, Register scratch) {
unboxBoolean(value, scratch);
return scratch;
}

Просмотреть файл

@ -615,7 +615,6 @@ JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm, const VMFunct
// Copy arguments.
for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) {
MoveOperand from;
switch (f.argProperties(explicitArg)) {
case VMFunction::WordByValue:
masm.passABIArg(MoveOperand(argsBase, argDisp),

Просмотреть файл

@ -396,25 +396,25 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
// Extended unboxing API. If the payload is already in a register, returns
// that register. Otherwise, provides a move to the given scratch register,
// and returns that.
Register extractObject(const Address& address, Register scratch);
Register extractObject(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractObject(const Address& address, Register scratch);
MOZ_MUST_USE Register extractObject(const ValueOperand& value, Register scratch) {
return value.payloadReg();
}
Register extractString(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractString(const ValueOperand& value, Register scratch) {
return value.payloadReg();
}
Register extractSymbol(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractSymbol(const ValueOperand& value, Register scratch) {
return value.payloadReg();
}
Register extractInt32(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractInt32(const ValueOperand& value, Register scratch) {
return value.payloadReg();
}
Register extractBoolean(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractBoolean(const ValueOperand& value, Register scratch) {
return value.payloadReg();
}
Register extractTag(const Address& address, Register scratch);
Register extractTag(const BaseIndex& address, Register scratch);
Register extractTag(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractTag(const Address& address, Register scratch);
MOZ_MUST_USE Register extractTag(const BaseIndex& address, Register scratch);
MOZ_MUST_USE Register extractTag(const ValueOperand& value, Register scratch) {
return value.typeReg();
}

Просмотреть файл

@ -2158,7 +2158,7 @@ MacroAssembler::branchValueIsNurseryObject(Condition cond, ValueOperand value,
Label done;
branchTestObject(Assembler::NotEqual, value, cond == Assembler::Equal ? &done : label);
extractObject(value, SecondScratchReg);
unboxObject(value, SecondScratchReg);
orPtr(Imm32(gc::ChunkMask), SecondScratchReg);
branch32(cond, Address(SecondScratchReg, gc::ChunkLocationOffsetFromLastByte),
Imm32(int32_t(gc::ChunkLocation::Nursery)), label);

Просмотреть файл

@ -452,30 +452,30 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
// Extended unboxing API. If the payload is already in a register, returns
// that register. Otherwise, provides a move to the given scratch register,
// and returns that.
Register extractObject(const Address& address, Register scratch);
Register extractObject(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractObject(const Address& address, Register scratch);
MOZ_MUST_USE Register extractObject(const ValueOperand& value, Register scratch) {
unboxObject(value, scratch);
return scratch;
}
Register extractString(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractString(const ValueOperand& value, Register scratch) {
unboxString(value, scratch);
return scratch;
}
Register extractSymbol(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractSymbol(const ValueOperand& value, Register scratch) {
unboxSymbol(value, scratch);
return scratch;
}
Register extractInt32(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractInt32(const ValueOperand& value, Register scratch) {
unboxInt32(value, scratch);
return scratch;
}
Register extractBoolean(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractBoolean(const ValueOperand& value, Register scratch) {
unboxBoolean(value, scratch);
return scratch;
}
Register extractTag(const Address& address, Register scratch);
Register extractTag(const BaseIndex& address, Register scratch);
Register extractTag(const ValueOperand& value, Register scratch) {
MOZ_MUST_USE Register extractTag(const Address& address, Register scratch);
MOZ_MUST_USE Register extractTag(const BaseIndex& address, Register scratch);
MOZ_MUST_USE Register extractTag(const ValueOperand& value, Register scratch) {
MOZ_ASSERT(scratch != ScratchRegister);
splitTag(value, scratch);
return scratch;

Просмотреть файл

@ -332,12 +332,12 @@ class MacroAssemblerNone : public Assembler
void unboxNonDouble(const Address&, Register, JSValueType) { MOZ_CRASH();}
void unboxGCThingForPreBarrierTrampoline(const Address&, Register) { MOZ_CRASH(); }
void notBoolean(ValueOperand) { MOZ_CRASH(); }
Register extractObject(Address, Register) { MOZ_CRASH(); }
Register extractObject(ValueOperand, Register) { MOZ_CRASH(); }
Register extractSymbol(ValueOperand, Register) { MOZ_CRASH(); }
Register extractInt32(ValueOperand, Register) { MOZ_CRASH(); }
Register extractBoolean(ValueOperand, Register) { MOZ_CRASH(); }
template <typename T> Register extractTag(T, Register) { MOZ_CRASH(); }
MOZ_MUST_USE Register extractObject(Address, Register) { MOZ_CRASH(); }
MOZ_MUST_USE Register extractObject(ValueOperand, Register) { MOZ_CRASH(); }
MOZ_MUST_USE Register extractSymbol(ValueOperand, Register) { MOZ_CRASH(); }
MOZ_MUST_USE Register extractInt32(ValueOperand, Register) { MOZ_CRASH(); }
MOZ_MUST_USE Register extractBoolean(ValueOperand, Register) { MOZ_CRASH(); }
template <typename T> MOZ_MUST_USE Register extractTag(T, Register) { MOZ_CRASH(); }
void convertFloat32ToInt32(FloatRegister, Register, Label*, bool v = true) { MOZ_CRASH(); }
void convertDoubleToInt32(FloatRegister, Register, Label*, bool v = true) { MOZ_CRASH(); }

Просмотреть файл

@ -75,7 +75,8 @@ CodeGeneratorShared::CodeGeneratorShared(MIRGenerator* gen, LIRGraph* graph, Mac
checkOsiPointRegisters(JitOptions.checkOsiPointRegisters),
#endif
frameDepth_(graph->paddedLocalSlotsSize() + graph->argumentsSize()),
frameInitialAdjustment_(0)
frameInitialAdjustment_(0),
frameClass_(FrameSizeClass::None())
{
if (gen->isProfilerInstrumentationEnabled())
masm.enableProfilingInstrumentation();
@ -107,7 +108,7 @@ CodeGeneratorShared::CodeGeneratorShared(MIRGenerator* gen, LIRGraph* graph, Mac
// FrameSizeClass is only used for bailing, which cannot happen in
// wasm code.
frameClass_ = FrameSizeClass::None();
MOZ_ASSERT(frameClass_ == FrameSizeClass::None());
} else {
frameClass_ = FrameSizeClass::FromDepth(frameDepth_);
}

Просмотреть файл

@ -243,6 +243,7 @@ class BranchDeadlineSet
public:
explicit BranchDeadlineSet(LifoAlloc& alloc)
: earliestRange_(0)
{
// Manually construct vectors in the uninitialized aligned storage.
// This is because C++ arrays can otherwise only be constructed with

Просмотреть файл

@ -37,6 +37,7 @@ class LIRGeneratorShared
: gen(gen),
graph(graph),
lirGraph_(lirGraph),
current(nullptr),
lastResumePoint_(nullptr),
cachedRecoverInfo_(nullptr),
osiPoint_(nullptr)

Просмотреть файл

@ -262,7 +262,9 @@ class RelocationIterator
public:
explicit RelocationIterator(CompactBufferReader& reader)
: reader_(reader)
: reader_(reader),
offset_(0),
extOffset_(0)
{
tableStart_ = reader_.readFixedUint32_t();
}

Просмотреть файл

@ -47,7 +47,8 @@ class BailoutStack
BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator& activations,
BailoutStack* bailout)
: machine_(bailout->machineState())
: machine_(bailout->machineState()),
activation_(nullptr)
{
uint8_t* sp = bailout->parentStackPointer();
framePointer_ = sp + bailout->frameSize();
@ -62,7 +63,8 @@ BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator& activations,
BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator& activations,
InvalidationBailoutStack* bailout)
: machine_(bailout->machine())
: machine_(bailout->machine()),
activation_(nullptr)
{
framePointer_ = (uint8_t*) bailout->fp();
topFrameSize_ = framePointer_ - bailout->sp();

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше