Merge m-c to b-i

This commit is contained in:
Phil Ringnalda 2015-02-08 17:43:39 -08:00
commit 5f221e9991
97 changed files with 37206 additions and 36777 deletions

View File

@ -296,7 +296,6 @@ skip-if = e10s
[browser_contextSearchTabPosition.js]
skip-if = os == "mac" || e10s # bug 967013; e10s: bug 1094761 - test hits the network in e10s, causing next test to crash
[browser_ctrlTab.js]
[browser_customize_popupNotification.js]
[browser_datareporting_notification.js]
skip-if = !datareporting
[browser_devedition.js]

View File

@ -1,35 +0,0 @@
/*
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
*/
function test() {
waitForExplicitFinish();
let newWin = OpenBrowserWindow();
registerCleanupFunction(() => {
newWin.close()
newWin = null;
});
whenDelayedStartupFinished(newWin, function () {
// Remove the URL bar
newWin.gURLBar.parentNode.removeChild(newWin.gURLBar);
waitForFocus(function () {
let PN = newWin.PopupNotifications;
try {
let panelPromise = promisePopupShown(PN.panel);
let notification = PN.show(newWin.gBrowser.selectedBrowser, "some-notification", "Some message");
panelPromise.then(function() {
ok(notification, "showed the notification");
ok(PN.isPanelOpen, "panel is open");
is(PN.panel.anchorNode, newWin.gBrowser.selectedTab, "notification is correctly anchored to the tab");
PN.panel.hidePopup();
finish();
});
} catch (ex) {
ok(false, "threw exception: " + ex);
finish();
}
}, newWin);
});
}

View File

@ -1535,13 +1535,29 @@ this.MozLoopService = {
let urlStr = this.getLoopPref("gettingStarted.url");
let url = new URL(Services.urlFormatter.formatURL(urlStr));
for (let paramName in aAdditionalParams) {
url.searchParams.append(paramName, aAdditionalParams[paramName]);
url.searchParams.set(paramName, aAdditionalParams[paramName]);
}
if (aSrc) {
url.searchParams.set("utm_source", "firefox-browser");
url.searchParams.set("utm_medium", "firefox-browser");
url.searchParams.set("utm_campaign", aSrc);
}
// Find the most recent pageID that has the Loop prefix.
let mostRecentLoopPageID = {id: null, lastSeen: null};
for (let pageID of UITour.pageIDsForSession) {
if (pageID[0] && pageID[0].startsWith("hello-tour_OpenPanel_") &&
pageID[1] && pageID[1].lastSeen > mostRecentLoopPageID.lastSeen) {
mostRecentLoopPageID.id = pageID[0];
mostRecentLoopPageID.lastSeen = pageID[1].lastSeen;
}
}
const PAGE_ID_EXPIRATION_MS = 60 * 60 * 1000;
if (mostRecentLoopPageID.id &&
mostRecentLoopPageID.lastSeen > Date.now() - PAGE_ID_EXPIRATION_MS) {
url.searchParams.set("utm_content", mostRecentLoopPageID.id);
}
return url;
},

View File

@ -74,6 +74,9 @@ XPCOMUtils.defineLazyGetter(this, "log", () => {
this.UITour = {
url: null,
seenPageIDs: null,
// This map is not persisted and is used for
// building the content source of a potential tour.
pageIDsForSession: new Map(),
pageIDSourceBrowsers: new WeakMap(),
/* Map from browser chrome windows to a Set of <browser>s in which a tour is open (both visible and hidden) */
tourBrowsersByWindow: new WeakMap(),
@ -375,16 +378,22 @@ this.UITour = {
switch (action) {
case "registerPageID": {
// This is only relevant if Telemtry is enabled.
if (typeof data.pageID != "string") {
log.warn("registerPageID: pageID must be a string");
break;
}
this.pageIDsForSession.set(data.pageID, {lastSeen: Date.now()});
// The rest is only relevant if Telemetry is enabled.
if (!UITelemetry.enabled) {
log.debug("registerPageID: Telemery disabled, not doing anything");
log.debug("registerPageID: Telemetry disabled, not doing anything");
break;
}
// We don't want to allow BrowserUITelemetry.BUCKET_SEPARATOR in the
// pageID, as it could make parsing the telemetry bucket name difficult.
if (typeof data.pageID != "string" ||
data.pageID.contains(BrowserUITelemetry.BUCKET_SEPARATOR)) {
if (data.pageID.contains(BrowserUITelemetry.BUCKET_SEPARATOR)) {
log.warn("registerPageID: Invalid page ID specified");
break;
}

View File

@ -20,7 +20,7 @@ skip-if = e10s # Bug 941428 - UITour.jsm not e10s friendly.
[browser_UITour_heartbeat.js]
skip-if = e10s # Bug 941428 - UITour.jsm not e10s friendly.
[browser_UITour_loop.js]
skip-if = e10s # Bug 941428 - UITour.jsm not e10s friendly.
skip-if = os == "linux" || e10s # Bug 941428 - UITour.jsm not e10s friendly.
[browser_UITour_modalDialog.js]
run-if = os == "mac" # modal dialog disabling only working on OS X
skip-if = e10s # Bug 941428 - UITour.jsm not e10s friendly

View File

@ -172,12 +172,12 @@ let tests = [
info("'Heartbeat:Voted' notification received (timestamp " + aData.timestamp.toString() + ").");
ok(Number.isFinite(aData.timestamp), "Timestamp must be a number.");
is(aData.score, expectedScore, "Should report a score of " + expectedScore);
done();
break;
}
case "Heartbeat:NotificationClosed": {
info("'Heartbeat:NotificationClosed' notification received (timestamp " + aData.timestamp.toString() + ").");
ok(Number.isFinite(aData.timestamp), "Timestamp must be a number.");
done();
break;
}
default:
@ -197,6 +197,7 @@ let tests = [
let flowId = "ui-ratefirefox-" + Math.random();
let originalTabCount = gBrowser.tabs.length;
const expectedTabCount = originalTabCount + 1;
let heartbeatVoteSeen = false;
gContentAPI.observe(function (aEventName, aData) {
switch (aEventName) {
@ -210,9 +211,11 @@ let tests = [
case "Heartbeat:Voted": {
info("'Heartbeat:Voted' notification received (timestamp " + aData.timestamp.toString() + ").");
ok(Number.isFinite(aData.timestamp), "Timestamp must be a number.");
heartbeatVoteSeen = true;
break;
}
case "Heartbeat:NotificationClosed": {
ok(heartbeatVoteSeen, "Heartbeat vote should have been received");
info("'Heartbeat:NotificationClosed' notification received (timestamp " + aData.timestamp.toString() + ").");
ok(Number.isFinite(aData.timestamp), "Timestamp must be a number.");
is(gBrowser.tabs.length, expectedTabCount, "Engagement URL should open in a new tab.");

View File

@ -27,7 +27,84 @@ function runOffline(fun) {
}
let tests = [
taskify(function* test_gettingStartedClicked_linkOpenedWithExpectedParams() {
Services.prefs.setBoolPref("loop.gettingStarted.seen", false);
Services.prefs.setCharPref("loop.gettingStarted.url", "http://example.com");
ise(loopButton.open, false, "Menu should initially be closed");
loopButton.click();
yield waitForConditionPromise(() => {
return loopButton.open;
}, "Menu should be visible after showMenu()");
gContentAPI.registerPageID("hello-tour_OpenPanel_testPage");
yield new Promise(resolve => {
gContentAPI.ping(() => resolve());
});
let loopDoc = document.getElementById("loop-notification-panel").children[0].contentDocument;
let gettingStartedButton = loopDoc.getElementById("fte-button");
ok(gettingStartedButton, "Getting Started button should be found");
let newTabPromise = waitForConditionPromise(() => {
return gBrowser.currentURI.path.contains("utm_source=firefox-browser");
}, "New tab with utm_content=testPageNewID should have opened");
gettingStartedButton.click();
yield newTabPromise;
ok(gBrowser.currentURI.path.contains("utm_content=hello-tour_OpenPanel_testPage"),
"Expected URL opened (" + gBrowser.currentURI.path + ")");
yield gBrowser.removeCurrentTab();
checkLoopPanelIsHidden();
}),
taskify(function* test_gettingStartedClicked_linkOpenedWithExpectedParams2() {
Services.prefs.setBoolPref("loop.gettingStarted.seen", false);
// Force a refresh of the loop panel since going from seen -> unseen doesn't trigger
// automatic re-rendering.
let loopWin = document.getElementById("loop-notification-panel").children[0].contentWindow;
var event = new loopWin.CustomEvent("GettingStartedSeen");
loopWin.dispatchEvent(event);
UITour.pageIDsForSession.clear();
Services.prefs.setCharPref("loop.gettingStarted.url", "http://example.com");
ise(loopButton.open, false, "Menu should initially be closed");
loopButton.click();
yield waitForConditionPromise(() => {
return loopButton.open;
}, "Menu should be visible after showMenu()");
gContentAPI.registerPageID("hello-tour_OpenPanel_testPageOldId");
yield new Promise(resolve => {
gContentAPI.ping(() => resolve());
});
// Set the time of the page ID to 10 hours earlier, so that it is considered "expired".
UITour.pageIDsForSession.set("hello-tour_OpenPanel_testPageOldId",
{lastSeen: Date.now() - (10 * 60 * 60 * 1000)});
let loopDoc = loopWin.document;
let gettingStartedButton = loopDoc.getElementById("fte-button");
ok(gettingStartedButton, "Getting Started button should be found");
let newTabPromise = waitForConditionPromise(() => {
Services.console.logStringMessage(gBrowser.currentURI.path);
return gBrowser.currentURI.path.contains("utm_source=firefox-browser");
}, "New tab with utm_content=testPageNewID should have opened");
gettingStartedButton.click();
yield newTabPromise;
ok(!gBrowser.currentURI.path.contains("utm_content=hello-tour_OpenPanel_testPageOldId"),
"Expected URL opened without the utm_content parameter (" +
gBrowser.currentURI.path + ")");
yield gBrowser.removeCurrentTab();
checkLoopPanelIsHidden();
}),
taskify(function* test_menu_show_hide() {
// The targets to highlight only appear after getting started is launched.
Services.prefs.setBoolPref("loop.gettingStarted.seen", true);
ise(loopButton.open, false, "Menu should initially be closed");
gContentAPI.showMenu("loop");
@ -277,8 +354,6 @@ function setupFakeRoom() {
if (Services.prefs.getBoolPref("loop.enabled")) {
loopButton = window.LoopUI.toolbarButton.node;
// The targets to highlight only appear after getting started is launched.
Services.prefs.setBoolPref("loop.gettingStarted.seen", true);
registerCleanupFunction(() => {
Services.prefs.clearUserPref("loop.gettingStarted.resumeOnFirstJoin");

View File

@ -53,7 +53,8 @@ function getStringPref(pref, def) {
}
function log(str) {
dump(str + '\n');
var msg = 'ShumwayBootstrapUtils.jsm: ' + str;
Services.console.logStringMessage(msg);
}
// Register/unregister a constructor as a factory.
@ -80,6 +81,19 @@ Factory.prototype = {
let converterFactory = new Factory();
let overlayConverterFactory = new Factory();
function allowedPlatformForMedia() {
var oscpu = Cc["@mozilla.org/network/protocol;1?name=http"]
.getService(Ci.nsIHttpProtocolHandler).oscpu;
if (oscpu.indexOf('Windows NT') === 0) {
return oscpu.indexOf('Windows NT 5') < 0; // excluding Windows XP
}
if (oscpu.indexOf('Intel Mac OS X') === 0) {
return true;
}
// Other platforms are not supported yet.
return false;
}
var ShumwayBootstrapUtils = {
register: function () {
// Register the components.
@ -88,7 +102,15 @@ var ShumwayBootstrapUtils = {
if (registerOverlayPreview) {
var ignoreCTP = getBoolPref(PREF_IGNORE_CTP, true);
var whitelist = getStringPref(PREF_WHITELIST);
var whitelist = getStringPref(PREF_WHITELIST);
// Some platforms cannot support video playback, and our whitelist targets
// only video players atm. We need to disable Shumway for those platforms.
if (whitelist && !Services.prefs.prefHasUserValue(PREF_WHITELIST) &&
!allowedPlatformForMedia()) {
log('Default SWF whitelist is used on an unsupported platform -- ' +
'using demo whitelist.');
whitelist = 'http://www.areweflashyet.com/*.swf';
}
Ph.registerPlayPreviewMimeType(SWF_CONTENT_TYPE, ignoreCTP,
undefined, whitelist);
}

View File

@ -220,7 +220,7 @@ function isShumwayEnabledFor(actions) {
function getVersionInfo() {
var deferred = Promise.defer();
var versionInfo = {
version: 'unknown',
geckoVersion: 'unknown',
geckoBuildID: 'unknown',
shumwayVersion: 'unknown'
};
@ -230,18 +230,30 @@ function getVersionInfo() {
versionInfo.geckoVersion = appInfo.version;
versionInfo.geckoBuildID = appInfo.appBuildID;
} catch (e) {
log('Error encountered while getting platform version info:', e);
log('Error encountered while getting platform version info: ' + e);
}
try {
var addonId = "shumway@research.mozilla.org";
AddonManager.getAddonByID(addonId, function(addon) {
versionInfo.shumwayVersion = addon ? addon.version : 'n/a';
deferred.resolve(versionInfo);
});
} catch (e) {
log('Error encountered while getting Shumway version info:', e);
var xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Ci.nsIXMLHttpRequest);
xhr.open('GET', 'resource://shumway/version.txt', true);
xhr.overrideMimeType('text/plain');
xhr.onload = function () {
try {
// Trying to merge version.txt lines into something like:
// "version (sha) details"
var lines = xhr.responseText.split(/\n/g);
lines[1] = '(' + lines[1] + ')';
versionInfo.shumwayVersion = lines.join(' ');
} catch (e) {
log('Error while parsing version info: ' + e);
}
deferred.resolve(versionInfo);
}
};
xhr.onerror = function () {
log('Error while reading version info: ' + xhr.error);
deferred.resolve(versionInfo);
};
xhr.send();
return deferred.promise;
}
@ -754,6 +766,7 @@ function activateShumwayScripts(window, requestListener) {
}
function initExternalCom(wrappedWindow, wrappedObject, targetWindow) {
var traceExternalInterface = getBoolPref('shumway.externalInterface.trace', false);
if (!wrappedWindow.__flash__initialized) {
wrappedWindow.__flash__initialized = true;
wrappedWindow.__flash__toXML = function __flash__toXML(obj) {
@ -786,29 +799,32 @@ function initExternalCom(wrappedWindow, wrappedObject, targetWindow) {
}
};
wrappedWindow.__flash__eval = function (expr) {
this.console.log('__flash__eval: ' + expr);
traceExternalInterface && this.console.log('__flash__eval: ' + expr);
// allowScriptAccess protects page from unwanted swf scripts,
// we can execute script in the page context without restrictions.
return this.eval(expr);
var result = this.eval(expr);
traceExternalInterface && this.console.log('__flash__eval (result): ' + result);
return result;
}.bind(wrappedWindow);
wrappedWindow.__flash__call = function (expr) {
this.console.log('__flash__call (ignored): ' + expr);
traceExternalInterface && this.console.log('__flash__call (ignored): ' + expr);
};
}
wrappedObject.__flash__registerCallback = function (functionName) {
wrappedWindow.console.log('__flash__registerCallback: ' + functionName);
traceExternalInterface && wrappedWindow.console.log('__flash__registerCallback: ' + functionName);
Components.utils.exportFunction(function () {
var args = Array.prototype.slice.call(arguments, 0);
wrappedWindow.console.log('__flash__callIn: ' + functionName);
traceExternalInterface && wrappedWindow.console.log('__flash__callIn: ' + functionName);
var result;
if (targetWindow.wrappedJSObject.onExternalCallback) {
result = targetWindow.wrappedJSObject.onExternalCallback({functionName: functionName, args: args});
traceExternalInterface && wrappedWindow.console.log('__flash__callIn (result): ' + result);
}
return wrappedWindow.eval(result);
}, this, { defineAs: functionName });
};
wrappedObject.__flash__unregisterCallback = function (functionName) {
wrappedWindow.console.log('__flash__unregisterCallback: ' + functionName);
traceExternalInterface && wrappedWindow.console.log('__flash__unregisterCallback: ' + functionName);
delete this[functionName];
};
}
@ -909,7 +925,11 @@ ShumwayStreamConverterBase.prototype = {
throw new Error('Movie url is not specified');
}
baseUrl = objectParams.base || pageUrl;
if (objectParams.base) {
baseUrl = Services.io.newURI(objectParams.base, null, pageUrl).spec;
} else {
baseUrl = pageUrl;
}
var movieParams = {};
if (objectParams.flashvars) {

View File

@ -17,6 +17,7 @@ var EXPORTED_SYMBOLS = ["ShumwayUtils"];
const PREF_PREFIX = 'shumway.';
const PREF_DISABLED = PREF_PREFIX + 'disabled';
const PREF_WHITELIST = PREF_PREFIX + 'swf.whitelist';
let Cc = Components.classes;
let Ci = Components.interfaces;
@ -43,6 +44,7 @@ let ShumwayUtils = {
_registered: false,
init: function init() {
this.migratePreferences();
if (this.enabled)
this._ensureRegistered();
else
@ -56,6 +58,19 @@ let ShumwayUtils = {
Services.prefs.addObserver(PREF_DISABLED, this, false);
},
migratePreferences: function migratePreferences() {
// At one point we had shumway.disabled set to true by default,
// and we are trying to replace it with shumway.swf.whitelist:
// checking if the user already changed it before to reset
// the whitelist to '*'.
if (Services.prefs.prefHasUserValue(PREF_DISABLED) &&
!Services.prefs.prefHasUserValue(PREF_WHITELIST) &&
!getBoolPref(PREF_DISABLED, false)) {
// The user is already using Shumway -- enabling all web sites.
Services.prefs.setCharPref(PREF_WHITELIST, '*');
}
},
// nsIObserver
observe: function observe(aSubject, aTopic, aData) {
if (this.enabled)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +1,2 @@
0.9.3693
217e2e2
0.9.3775
a82ac47

View File

@ -111,7 +111,7 @@ limitations under the License.
<menuitem label="Open in Inspector" id="inspectorMenu"></menuitem>
<menuitem label="Report Problems" id="reportMenu"></menuitem>
<menuitem label="Reload in Adobe Flash Player" id="fallbackMenu" hidden></menuitem>
<menuitem label="About Shumway" id="aboutMenu"></menuitem>
<menuitem label="About Shumway %version%..." id="aboutMenu"></menuitem>
</menu>
</section>

View File

@ -161,6 +161,10 @@ function runViewer() {
document.getElementById('inspectorMenu').addEventListener('click', showInInspector);
document.getElementById('reportMenu').addEventListener('click', reportIssue);
document.getElementById('aboutMenu').addEventListener('click', showAbout);
var version = Shumway.version || '';
document.getElementById('aboutMenu').label =
document.getElementById('aboutMenu').label.replace('%version%', version);
}
function showURL() {

View File

@ -44,7 +44,7 @@ function runSwfPlayer(flashParams) {
Shumway.AVM2.Verifier.enabled.value = compilerSettings.verifier;
Shumway.createAVM2(builtinPath, viewerPlayerglobalInfo, sysMode, appMode, function (avm2) {
function runSWF(file) {
function runSWF(file, buffer, baseUrl) {
var player = new Shumway.Player.Window.WindowPlayer(window, window.parent);
player.defaultStageColor = flashParams.bgcolor;
player.movieParams = flashParams.movieParams;
@ -54,17 +54,18 @@ function runSwfPlayer(flashParams) {
Shumway.ExternalInterfaceService.instance = player.createExternalInterfaceService();
player.load(file);
player.pageUrl = baseUrl;
player.load(file, buffer);
}
Shumway.FileLoadingService.instance.setBaseUrl(baseUrl);
if (asyncLoading) {
runSWF(movieUrl);
runSWF(movieUrl, undefined, baseUrl);
} else {
new Shumway.BinaryFileReader(movieUrl).readAll(null, function(buffer, error) {
if (!buffer) {
throw "Unable to open the file " + movieUrl + ": " + error;
}
runSWF(movieUrl, buffer);
runSWF(movieUrl, buffer, baseUrl);
});
}
});
@ -127,6 +128,11 @@ function setupServices() {
this.onprogress && this.onprogress(args.array, {bytesLoaded: args.loaded, bytesTotal: args.total});
break;
}
},
close: function () {
if (Shumway.FileLoadingService.instance.sessions[sessionId]) {
// TODO send abort
}
}
};
},

View File

@ -1808,25 +1808,33 @@ void
ContentChild::ProcessingError(Result aCode, const char* aReason)
{
switch (aCode) {
case MsgDropped:
NS_WARNING("MsgDropped in ContentChild");
return;
case MsgNotKnown:
NS_RUNTIMEABORT("aborting because of MsgNotKnown");
case MsgNotAllowed:
NS_RUNTIMEABORT("aborting because of MsgNotAllowed");
case MsgPayloadError:
NS_RUNTIMEABORT("aborting because of MsgPayloadError");
case MsgProcessingError:
NS_RUNTIMEABORT("aborting because of MsgProcessingError");
case MsgRouteError:
NS_RUNTIMEABORT("aborting because of MsgRouteError");
case MsgValueError:
NS_RUNTIMEABORT("aborting because of MsgValueError");
case MsgDropped:
NS_WARNING("MsgDropped in ContentChild");
return;
default:
NS_RUNTIMEABORT("not reached");
case MsgNotKnown:
case MsgNotAllowed:
case MsgPayloadError:
case MsgProcessingError:
case MsgRouteError:
case MsgValueError:
break;
default:
NS_RUNTIMEABORT("not reached");
}
#if defined(MOZ_CRASHREPORTER) && !defined(MOZ_B2G)
if (ManagedPCrashReporterChild().Length() > 0) {
CrashReporterChild* crashReporter =
static_cast<CrashReporterChild*>(ManagedPCrashReporterChild()[0]);
nsDependentCString reason(aReason);
crashReporter->SendAnnotateCrashReport(
NS_LITERAL_CSTRING("ipc_channel_error"),
reason);
}
#endif
NS_RUNTIMEABORT("Content child abort due to IPC error");
}
void

View File

@ -497,10 +497,10 @@ SystemMessageInternal.prototype = {
return;
}
// Return the |msg| of each pending message (drop the |msgID|).
// Return the |msg| of each pending message.
let pendingMessages = [];
page.pendingMessages.forEach(function(aMessage) {
pendingMessages.push(aMessage.msg);
pendingMessages.push({ msg: aMessage.msg, msgID: aMessage.msgID });
});
// Clear the pending queue for this page. This is OK since we'll store

View File

@ -267,7 +267,7 @@ SystemMessageManager.prototype = {
}
let messages = (aMessage.name == "SystemMessageManager:Message")
? [msg.msg]
? [{ msg: msg.msg, msgID: msg.msgID }]
: msg.msgQueue;
// We only dispatch messages when a handler is registered.
@ -285,7 +285,7 @@ SystemMessageManager.prototype = {
}
messages.forEach(function(aMsg) {
this._dispatchMessage(msg.type, dispatcher, aMsg, msg.msgID);
this._dispatchMessage(msg.type, dispatcher, aMsg.msg, aMsg.msgID);
}, this);
} else {

View File

@ -535,13 +535,13 @@ TryEnablingJit(JSContext *cx, AsmJSModule &module, HandleFunction fun, uint32_t
// BaselineScript, so if those checks hold now they must hold at least until
// the BaselineScript is discarded and when that happens the FFI exit is
// patched back.
if (!types::TypeScript::ThisTypes(script)->hasType(types::Type::UndefinedType()))
if (!TypeScript::ThisTypes(script)->hasType(TypeSet::UndefinedType()))
return true;
for (uint32_t i = 0; i < fun->nargs(); i++) {
types::StackTypeSet *typeset = types::TypeScript::ArgTypes(script, i);
types::Type type = types::Type::DoubleType();
StackTypeSet *typeset = TypeScript::ArgTypes(script, i);
TypeSet::Type type = TypeSet::DoubleType();
if (!argv[i].isDouble())
type = types::Type::PrimitiveType(argv[i].extractNonDoubleType());
type = TypeSet::PrimitiveType(argv[i].extractNonDoubleType());
if (!typeset->hasType(type))
return true;
}

View File

@ -21,7 +21,6 @@
#include "vm/Shape-inl.h"
using namespace js;
using namespace js::types;
using js::frontend::IsIdentifier;
using mozilla::ArrayLength;

View File

@ -19,7 +19,6 @@
#include "vm/NativeObject-inl.h"
using namespace js;
using namespace js::types;
using mozilla::ArrayLength;
using mozilla::Maybe;

View File

@ -2729,7 +2729,7 @@ js::StoreReference##T::Func(JSContext *cx, unsigned argc, Value *vp) \
int32_t offset = args[1].toInt32(); \
\
jsid id = args[2].isString() \
? types::IdToTypeId(AtomToId(&args[2].toString()->asAtom())) \
? IdToTypeId(AtomToId(&args[2].toString()->asAtom())) \
: JSID_VOID; \
\
/* Should be guaranteed by the typed objects API: */ \
@ -2795,8 +2795,8 @@ StoreReferenceHeapValue::store(JSContext *cx, HeapValue *heap, const Value &v,
// considered to contain undefined.
if (!v.isUndefined()) {
if (cx->isJSContext())
types::AddTypePropertyId(cx->asJSContext(), obj, id, v);
else if (!types::HasTypePropertyId(obj, id, v))
AddTypePropertyId(cx->asJSContext(), obj, id, v);
else if (!HasTypePropertyId(obj, id, v))
return false;
}
@ -2815,8 +2815,8 @@ StoreReferenceHeapPtrObject::store(JSContext *cx, HeapPtrObject *heap, const Val
// considered to contain null.
if (v.isObject()) {
if (cx->isJSContext())
types::AddTypePropertyId(cx->asJSContext(), obj, id, v);
else if (!types::HasTypePropertyId(obj, id, v))
AddTypePropertyId(cx->asJSContext(), obj, id, v);
else if (!HasTypePropertyId(obj, id, v))
return false;
}

View File

@ -1902,7 +1902,7 @@ BindNameToSlotHelper(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
* has no object to stand in the static scope chain, 2. to minimize memory
* bloat where a single live function keeps its whole global script
* alive.), ScopeCoordinateToTypeSet is not able to find the var/let's
* associated types::TypeSet.
* associated TypeSet.
*/
if (skip) {
BytecodeEmitter *bceSkipped = bce;
@ -3704,7 +3704,7 @@ EmitDestructuringOpsObjectHelper(ExclusiveContext *cx, BytecodeEmitter *bce, Par
// used PNK_NUMBER instead, but also watch for ids which TI treats
// as indexes for simplification of downstream analysis.
jsid id = NameToId(name);
if (id != types::IdToTypeId(id)) {
if (id != IdToTypeId(id)) {
if (!EmitTree(cx, bce, key)) // ... OBJ OBJ KEY
return false;
} else {
@ -6622,7 +6622,7 @@ EmitObject(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
// used PNK_NUMBER instead, but also watch for ids which TI treats
// as indexes for simpliciation of downstream analysis.
jsid id = NameToId(key->pn_atom->asPropertyName());
if (id != types::IdToTypeId(id)) {
if (id != IdToTypeId(id)) {
if (!EmitTree(cx, bce, key))
return false;
isIndex = true;

View File

@ -834,7 +834,7 @@ Fold(ExclusiveContext *cx, ParseNode **pnp,
}
}
if (name && NameToId(name) == types::IdToTypeId(NameToId(name))) {
if (name && NameToId(name) == IdToTypeId(NameToId(name))) {
// Optimization 3: We have pn1["foo"] where foo is not an index.
// Convert to a property access (like pn1.foo) which we optimize
// better downstream. Don't bother with this for names which TI

View File

@ -17,7 +17,6 @@
using namespace js;
using namespace js::gc;
using namespace js::types;
JS_STATIC_ASSERT(AllocKinds == FINALIZE_LIMIT);
JS_STATIC_ASSERT(LastObjectAllocKind == FINALIZE_OBJECT_LAST);

View File

@ -787,18 +787,18 @@ gc::MarkValueRoot(JSTracer *trc, Value *v, const char *name)
}
void
gc::MarkTypeRoot(JSTracer *trc, types::Type *v, const char *name)
TypeSet::MarkTypeRoot(JSTracer *trc, TypeSet::Type *v, const char *name)
{
JS_ROOT_MARKING_ASSERT(trc);
trc->setTracingName(name);
if (v->isSingleton()) {
JSObject *obj = v->singleton();
MarkInternal(trc, &obj);
*v = types::Type::ObjectType(obj);
*v = TypeSet::ObjectType(obj);
} else if (v->isGroup()) {
ObjectGroup *group = v->group();
MarkInternal(trc, &group);
*v = types::Type::ObjectType(group);
*v = TypeSet::ObjectType(group);
}
}
@ -1426,7 +1426,7 @@ ScanObjectGroup(GCMarker *gcmarker, ObjectGroup *group)
{
unsigned count = group->getPropertyCount();
for (unsigned i = 0; i < count; i++) {
if (types::Property *prop = group->getProperty(i))
if (ObjectGroup::Property *prop = group->getProperty(i))
MarkId(gcmarker, &prop->id, "ObjectGroup property id");
}
@ -1454,8 +1454,7 @@ gc::MarkChildren(JSTracer *trc, ObjectGroup *group)
{
unsigned count = group->getPropertyCount();
for (unsigned i = 0; i < count; i++) {
types::Property *prop = group->getProperty(i);
if (prop)
if (ObjectGroup::Property *prop = group->getProperty(i))
MarkId(trc, &prop->id, "group_property");
}

View File

@ -37,10 +37,6 @@ struct IonScript;
struct VMFunction;
}
namespace types {
class Type;
}
namespace gc {
/*** Object Marking ***/
@ -213,9 +209,6 @@ MarkValueRootRange(JSTracer *trc, Value *begin, Value *end, const char *name)
MarkValueRootRange(trc, end - begin, begin, name);
}
void
MarkTypeRoot(JSTracer *trc, types::Type *v, const char *name);
bool
IsValueMarked(Value *v);

View File

@ -112,7 +112,7 @@ MarkExactStackRootsAcrossTypes(T context, JSTracer *trc)
MarkExactStackRootList<LazyScript *, MarkLazyScriptRoot>(trc, context, "exact-lazy-script");
MarkExactStackRootList<jsid, MarkIdRoot>(trc, context, "exact-id");
MarkExactStackRootList<Value, MarkValueRoot>(trc, context, "exact-value");
MarkExactStackRootList<types::Type, MarkTypeRoot>(trc, context, "types::Type");
MarkExactStackRootList<TypeSet::Type, TypeSet::MarkTypeRoot>(trc, context, "TypeSet::Type");
MarkExactStackRootList<Bindings, MarkBindingsRoot>(trc, context, "Bindings");
MarkExactStackRootList<JSPropertyDescriptor, MarkPropertyDescriptorRoot>(
trc, context, "JSPropertyDescriptor");

View File

@ -115,7 +115,7 @@ Zone::beginSweepTypes(FreeOp *fop, bool releaseTypes)
if (active)
releaseTypes = false;
types::AutoClearTypeInferenceStateOnOOM oom(this);
AutoClearTypeInferenceStateOnOOM oom(this);
types.beginSweep(fop, releaseTypes, oom);
}

View File

@ -237,7 +237,7 @@ struct Zone : public JS::shadow::Zone,
public:
js::gc::ArenaLists arenas;
js::types::TypeZone types;
js::TypeZone types;
// The set of compartments in this zone.
typedef js::Vector<JSCompartment *, 1, js::SystemAllocPolicy> CompartmentVector;

View File

@ -90,7 +90,7 @@ BaselineCompiler::compile()
return Method_Error;
// Pin analysis info during compilation.
types::AutoEnterAnalysis autoEnterAnalysis(cx);
AutoEnterAnalysis autoEnterAnalysis(cx);
MOZ_ASSERT(!script->hasBaselineScript());
@ -250,7 +250,7 @@ BaselineCompiler::compile()
#endif
uint32_t *bytecodeMap = baselineScript->bytecodeTypeMap();
types::FillBytecodeTypeMap(script, bytecodeMap);
FillBytecodeTypeMap(script, bytecodeMap);
// The last entry in the last index found, and is used to avoid binary
// searches for the sought entry when queries are in linear order.

View File

@ -771,7 +771,7 @@ CloneOldBaselineStub(JSContext *cx, DebugModeOSREntryVector &entries, size_t ent
static bool
InvalidateScriptsInZone(JSContext *cx, Zone *zone, const Vector<DebugModeOSREntry> &entries)
{
types::RecompileInfoVector invalid;
RecompileInfoVector invalid;
for (UniqueScriptOSREntryIter iter(entries); !iter.done(); ++iter) {
JSScript *script = iter.entry().script;
if (script->compartment()->zone() != zone)

View File

@ -1197,12 +1197,12 @@ DoTypeMonitorFallback(JSContext *cx, BaselineFrame *frame, ICTypeMonitor_Fallbac
uint32_t argument;
if (stub->monitorsThis()) {
MOZ_ASSERT(pc == script->code());
types::TypeScript::SetThis(cx, script, value);
TypeScript::SetThis(cx, script, value);
} else if (stub->monitorsArgument(&argument)) {
MOZ_ASSERT(pc == script->code());
types::TypeScript::SetArgument(cx, script, argument, value);
TypeScript::SetArgument(cx, script, argument, value);
} else {
types::TypeScript::Monitor(cx, script, pc, value);
TypeScript::Monitor(cx, script, pc, value);
}
if (!stub->addMonitorStubForValue(cx, script, value))
@ -1324,12 +1324,12 @@ ICUpdatedStub::addUpdateStubForValue(JSContext *cx, HandleScript script, HandleO
return true;
}
types::EnsureTrackPropertyTypes(cx, obj, id);
EnsureTrackPropertyTypes(cx, obj, id);
// Make sure that undefined values are explicitly included in the property
// types for an object if generating a stub to write an undefined value.
if (val.isUndefined() && types::CanHaveEmptyPropertyTypesForOwnProperty(obj))
types::AddTypePropertyId(cx, obj, id, val);
if (val.isUndefined() && CanHaveEmptyPropertyTypesForOwnProperty(obj))
AddTypePropertyId(cx, obj, id, val);
if (val.isPrimitive()) {
JSValueType type = val.isDouble() ? JSVAL_TYPE_DOUBLE : val.extractNonDoubleType();
@ -1423,7 +1423,7 @@ DoTypeUpdateFallback(JSContext *cx, BaselineFrame *frame, ICUpdatedStub *stub, H
case ICStub::SetElem_DenseAdd: {
MOZ_ASSERT(obj->isNative());
id = JSID_VOID;
types::AddTypePropertyId(cx, obj, id, value);
AddTypePropertyId(cx, obj, id, value);
break;
}
case ICStub::SetProp_Native:
@ -1435,7 +1435,7 @@ DoTypeUpdateFallback(JSContext *cx, BaselineFrame *frame, ICUpdatedStub *stub, H
id = NameToId(ScopeCoordinateName(cx->runtime()->scopeCoordinateNameCache, script, pc));
else
id = NameToId(script->getName(pc));
types::AddTypePropertyId(cx, obj, id, value);
AddTypePropertyId(cx, obj, id, value);
break;
}
case ICStub::SetProp_TypedObject: {
@ -1448,12 +1448,12 @@ DoTypeUpdateFallback(JSContext *cx, BaselineFrame *frame, ICUpdatedStub *stub, H
// and non-object non-null values will cause the stub to fail to
// match shortly and we will end up doing the assignment in the VM.
if (value.isObject())
types::AddTypePropertyId(cx, obj, id, value);
AddTypePropertyId(cx, obj, id, value);
} else {
// Ignore undefined values, which are included implicitly in type
// information for this property.
if (!value.isUndefined())
types::AddTypePropertyId(cx, obj, id, value);
AddTypePropertyId(cx, obj, id, value);
}
break;
}
@ -3975,13 +3975,13 @@ DoGetElemFallback(JSContext *cx, BaselineFrame *frame, ICGetElem_Fallback *stub_
if (!GetElemOptimizedArguments(cx, frame, &lhsCopy, rhs, res, &isOptimizedArgs))
return false;
if (isOptimizedArgs)
types::TypeScript::Monitor(cx, frame->script(), pc, res);
TypeScript::Monitor(cx, frame->script(), pc, res);
}
if (!isOptimizedArgs) {
if (!GetElementOperation(cx, op, &lhsCopy, rhs, res))
return false;
types::TypeScript::Monitor(cx, frame->script(), pc, res);
TypeScript::Monitor(cx, frame->script(), pc, res);
}
// Check if debug mode toggling made the stub invalid.
@ -5803,7 +5803,7 @@ TryAttachGlobalNameStub(JSContext *cx, HandleScript script, jsbytecode *pc,
// Instantiate this global property, for use during Ion compilation.
if (IsIonEnabled(cx))
types::EnsureTrackPropertyTypes(cx, current, id);
EnsureTrackPropertyTypes(cx, current, id);
if (shape->hasDefaultGetter() && shape->hasSlot()) {
@ -6006,7 +6006,7 @@ DoGetNameFallback(JSContext *cx, BaselineFrame *frame, ICGetName_Fallback *stub_
return false;
}
types::TypeScript::Monitor(cx, script, pc, res);
TypeScript::Monitor(cx, script, pc, res);
// Check if debug mode toggling made the stub invalid.
if (stub.invalid())
@ -6195,7 +6195,7 @@ DoGetIntrinsicFallback(JSContext *cx, BaselineFrame *frame, ICGetIntrinsic_Fallb
// needs to be monitored once. Attach a stub to load the resulting constant
// directly.
types::TypeScript::Monitor(cx, script, pc, res);
TypeScript::Monitor(cx, script, pc, res);
// Check if debug mode toggling made the stub invalid.
if (stub.invalid())
@ -6383,7 +6383,7 @@ HasUnanalyzedNewScript(JSObject *obj)
if (obj->isSingleton())
return false;
types::TypeNewScript *newScript = obj->group()->newScript();
TypeNewScript *newScript = obj->group()->newScript();
if (newScript && !newScript->analyzed())
return true;
@ -6451,7 +6451,7 @@ TryAttachNativeGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc,
// Instantiate this property for singleton holders, for use during Ion compilation.
if (IsIonEnabled(cx))
types::EnsureTrackPropertyTypes(cx, holder, NameToId(name));
EnsureTrackPropertyTypes(cx, holder, NameToId(name));
ICStub::Kind kind;
if (obj == holder)
@ -6741,7 +6741,7 @@ TryAttachPrimitiveGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc
// Instantiate this property, for use during Ion compilation.
RootedId id(cx, NameToId(name));
if (IsIonEnabled(cx))
types::EnsureTrackPropertyTypes(cx, proto, id);
EnsureTrackPropertyTypes(cx, proto, id);
// For now, only look for properties directly set on the prototype.
RootedShape shape(cx, proto->lookup(cx, id));
@ -6869,7 +6869,7 @@ DoGetPropFallback(JSContext *cx, BaselineFrame *frame, ICGetProp_Fallback *stub_
if (!ComputeGetPropResult(cx, frame, op, name, val, res))
return false;
types::TypeScript::Monitor(cx, frame->script(), pc, res);
TypeScript::Monitor(cx, frame->script(), pc, res);
// Check if debug mode toggling made the stub invalid.
if (stub.invalid())
@ -8054,8 +8054,8 @@ TryAttachSetValuePropStub(JSContext *cx, HandleScript script, jsbytecode *pc, IC
// properties, TI will not mark the property as having been
// overwritten. Don't attach a stub in this case, so that we don't
// execute another write to the property without TI seeing that write.
types::EnsureTrackPropertyTypes(cx, obj, id);
if (!types::PropertyHasBeenMarkedNonConstant(obj, id)) {
EnsureTrackPropertyTypes(cx, obj, id);
if (!PropertyHasBeenMarkedNonConstant(obj, id)) {
*attached = true;
return true;
}
@ -9327,7 +9327,7 @@ TryAttachCallStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script, jsb
// Keep track of the function's |prototype| property in type
// information, for use during Ion compilation.
if (IsIonEnabled(cx))
types::EnsureTrackPropertyTypes(cx, fun, NameToId(cx->names().prototype));
EnsureTrackPropertyTypes(cx, fun, NameToId(cx->names().prototype));
// Remember the template object associated with any script being called
// as a constructor, for later use during Ion compilation.
@ -9345,7 +9345,7 @@ TryAttachCallStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script, jsb
// stub. After the analysis is performed, CreateThisForFunction may
// start returning objects with a different type, and the Ion
// compiler might get confused.
types::TypeNewScript *newScript = templateObject->group()->newScript();
TypeNewScript *newScript = templateObject->group()->newScript();
if (newScript && !newScript->analyzed()) {
// Clear the object just created from the preliminary objects
// on the TypeNewScript, as it will not be used or filled in by
@ -9573,7 +9573,7 @@ DoCallFallback(JSContext *cx, BaselineFrame *frame, ICCall_Fallback *stub_, uint
return false;
}
types::TypeScript::Monitor(cx, script, pc, res);
TypeScript::Monitor(cx, script, pc, res);
// Check if debug mode toggling made the stub invalid.
if (stub.invalid())
@ -11234,7 +11234,7 @@ DoInstanceOfFallback(JSContext *cx, BaselineFrame *frame, ICInstanceOf_Fallback
// For functions, keep track of the |prototype| property in type information,
// for use during Ion compilation.
types::EnsureTrackPropertyTypes(cx, obj, NameToId(cx->names().prototype));
EnsureTrackPropertyTypes(cx, obj, NameToId(cx->names().prototype));
if (stub->numOptimizedStubs() >= ICInstanceOf_Fallback::MAX_OPTIMIZED_STUBS)
return true;

View File

@ -3395,7 +3395,7 @@ CodeGenerator::generateArgumentsChecks(bool bailout)
for (uint32_t i = info.startArgSlot(); i < info.endArgSlot(); i++) {
// All initial parameters are guaranteed to be MParameters.
MParameter *param = rp->getOperand(i)->toParameter();
const types::TypeSet *types = param->resultTypeSet();
const TypeSet *types = param->resultTypeSet();
if (!types || types->unknown())
continue;
@ -7215,11 +7215,11 @@ CodeGenerator::generate()
struct AutoDiscardIonCode
{
JSContext *cx;
types::RecompileInfo *recompileInfo;
RecompileInfo *recompileInfo;
IonScript *ionScript;
bool keep;
AutoDiscardIonCode(JSContext *cx, types::RecompileInfo *recompileInfo)
AutoDiscardIonCode(JSContext *cx, RecompileInfo *recompileInfo)
: cx(cx), recompileInfo(recompileInfo), ionScript(nullptr), keep(false) {}
~AutoDiscardIonCode() {
@ -7240,7 +7240,7 @@ struct AutoDiscardIonCode
};
bool
CodeGenerator::link(JSContext *cx, types::CompilerConstraintList *constraints)
CodeGenerator::link(JSContext *cx, CompilerConstraintList *constraints)
{
RootedScript script(cx, gen->info().script());
OptimizationLevel optimizationLevel = gen->optimizationInfo().level();
@ -7261,8 +7261,8 @@ CodeGenerator::link(JSContext *cx, types::CompilerConstraintList *constraints)
// Check to make sure we didn't have a mid-build invalidation. If so, we
// will trickle to jit::Compile() and return Method_Skipped.
uint32_t warmUpCount = script->getWarmUpCount();
types::RecompileInfo recompileInfo;
if (!types::FinishCompilation(cx, script, constraints, &recompileInfo))
RecompileInfo recompileInfo;
if (!FinishCompilation(cx, script, constraints, &recompileInfo))
return true;
// IonMonkey could have inferred better type information during

View File

@ -56,7 +56,7 @@ class CodeGenerator : public CodeGeneratorSpecific
public:
bool generate();
bool generateAsmJS(AsmJSFunctionLabels *labels);
bool link(JSContext *cx, types::CompilerConstraintList *constraints);
bool link(JSContext *cx, CompilerConstraintList *constraints);
void visitLabel(LLabel *lir);
void visitNop(LNop *lir);

View File

@ -471,7 +471,7 @@ jit::LazyLinkTopActivation(JSContext *cx)
IonBuilder *builder = it.script()->ionScript()->pendingBuilder();
it.script()->setPendingIonBuilder(cx, nullptr);
types::AutoEnterAnalysis enterTypes(cx);
AutoEnterAnalysis enterTypes(cx);
RootedScript script(cx, builder->script());
// Remove from pending.
@ -749,7 +749,7 @@ IonScript::IonScript()
}
IonScript *
IonScript::New(JSContext *cx, types::RecompileInfo recompileInfo,
IonScript::New(JSContext *cx, RecompileInfo recompileInfo,
uint32_t frameSlots, uint32_t argumentSlots, uint32_t frameSize,
size_t snapshotsListSize, size_t snapshotsRVATableSize,
size_t recoversSize, size_t bailoutEntries,
@ -1600,7 +1600,7 @@ AttachFinishedCompilations(JSContext *cx)
if (!ion)
return;
types::AutoEnterAnalysis enterTypes(cx);
AutoEnterAnalysis enterTypes(cx);
AutoLockHelperThreadState lock;
GlobalHelperThreadState::IonBuilderVector &finished = HelperThreadState().ionFinishedList();
@ -1758,7 +1758,7 @@ TrackAllProperties(JSContext *cx, JSObject *obj)
MOZ_ASSERT(obj->isSingleton());
for (Shape::Range<NoGC> range(obj->lastProperty()); !range.empty(); range.popFront())
types::EnsureTrackPropertyTypes(cx, obj, range.front().propid());
EnsureTrackPropertyTypes(cx, obj, range.front().propid());
}
static void
@ -1839,7 +1839,7 @@ IonCompile(JSContext *cx, JSScript *script,
JitContext jctx(cx, temp);
types::AutoEnterAnalysis enter(cx);
AutoEnterAnalysis enter(cx);
if (!cx->compartment()->ensureJitCompartmentExists(cx))
return AbortReason_Alloc;
@ -1872,7 +1872,7 @@ IonCompile(JSContext *cx, JSScript *script,
return AbortReason_Alloc;
}
types::CompilerConstraintList *constraints = types::NewCompilerConstraintList(*temp);
CompilerConstraintList *constraints = NewCompilerConstraintList(*temp);
if (!constraints)
return AbortReason_Alloc;
@ -2645,8 +2645,8 @@ jit::InvalidateAll(FreeOp *fop, Zone *zone)
void
jit::Invalidate(types::TypeZone &types, FreeOp *fop,
const types::RecompileInfoVector &invalid, bool resetUses,
jit::Invalidate(TypeZone &types, FreeOp *fop,
const RecompileInfoVector &invalid, bool resetUses,
bool cancelOffThread)
{
JitSpew(JitSpew_IonInvalidate, "Start invalidation.");
@ -2655,7 +2655,7 @@ jit::Invalidate(types::TypeZone &types, FreeOp *fop,
// to the traversal which frames have been invalidated.
size_t numInvalidations = 0;
for (size_t i = 0; i < invalid.length(); i++) {
const types::CompilerOutput *co = invalid[i].compilerOutput(types);
const CompilerOutput *co = invalid[i].compilerOutput(types);
if (!co)
continue;
MOZ_ASSERT(co->isValid());
@ -2688,7 +2688,7 @@ jit::Invalidate(types::TypeZone &types, FreeOp *fop,
// IonScript will be immediately destroyed. Otherwise, it will be held live
// until its last invalidated frame is destroyed.
for (size_t i = 0; i < invalid.length(); i++) {
types::CompilerOutput *co = invalid[i].compilerOutput(types);
CompilerOutput *co = invalid[i].compilerOutput(types);
if (!co)
continue;
MOZ_ASSERT(co->isValid());
@ -2716,7 +2716,7 @@ jit::Invalidate(types::TypeZone &types, FreeOp *fop,
}
void
jit::Invalidate(JSContext *cx, const types::RecompileInfoVector &invalid, bool resetUses,
jit::Invalidate(JSContext *cx, const RecompileInfoVector &invalid, bool resetUses,
bool cancelOffThread)
{
jit::Invalidate(cx->zone()->types, cx->runtime()->defaultFreeOp(), invalid, resetUses,
@ -2727,7 +2727,7 @@ bool
jit::IonScript::invalidate(JSContext *cx, bool resetUses, const char *reason)
{
JitSpew(JitSpew_IonInvalidate, " Invalidate IonScript %p: %s", this, reason);
types::RecompileInfoVector list;
RecompileInfoVector list;
if (!list.append(recompileInfo()))
return false;
Invalidate(cx, list, resetUses, true);
@ -2760,7 +2760,7 @@ jit::Invalidate(JSContext *cx, JSScript *script, bool resetUses, bool cancelOffT
js_free(buf);
}
types::RecompileInfoVector scripts;
RecompileInfoVector scripts;
MOZ_ASSERT(script->hasIonScript());
if (!scripts.append(script->ionScript()->recompileInfo()))
return false;
@ -2772,11 +2772,11 @@ jit::Invalidate(JSContext *cx, JSScript *script, bool resetUses, bool cancelOffT
static void
FinishInvalidationOf(FreeOp *fop, JSScript *script, IonScript *ionScript)
{
types::TypeZone &types = script->zone()->types;
TypeZone &types = script->zone()->types;
// Note: If the script is about to be swept, the compiler output may have
// already been destroyed.
if (types::CompilerOutput *output = ionScript->recompileInfo().compilerOutput(types))
if (CompilerOutput *output = ionScript->recompileInfo().compilerOutput(types))
output->invalidate();
// If this script has Ion code on the stack, invalidated() will return

View File

@ -122,10 +122,10 @@ JitExecStatus IonCannon(JSContext *cx, RunState &state);
JitExecStatus FastInvoke(JSContext *cx, HandleFunction fun, CallArgs &args);
// Walk the stack and invalidate active Ion frames for the invalid scripts.
void Invalidate(types::TypeZone &types, FreeOp *fop,
const types::RecompileInfoVector &invalid, bool resetUses = true,
void Invalidate(TypeZone &types, FreeOp *fop,
const RecompileInfoVector &invalid, bool resetUses = true,
bool cancelOffThread = true);
void Invalidate(JSContext *cx, const types::RecompileInfoVector &invalid, bool resetUses = true,
void Invalidate(JSContext *cx, const RecompileInfoVector &invalid, bool resetUses = true,
bool cancelOffThread = true);
bool Invalidate(JSContext *cx, JSScript *script, bool resetUses = true,
bool cancelOffThread = true);

View File

@ -2484,8 +2484,8 @@ TryEliminateTypeBarrier(MTypeBarrier *barrier, bool *eliminated)
{
MOZ_ASSERT(!*eliminated);
const types::TemporaryTypeSet *barrierTypes = barrier->resultTypeSet();
const types::TemporaryTypeSet *inputTypes = barrier->input()->resultTypeSet();
const TemporaryTypeSet *barrierTypes = barrier->resultTypeSet();
const TemporaryTypeSet *inputTypes = barrier->input()->resultTypeSet();
// Disregard the possible unbox added before the Typebarrier.
if (barrier->input()->isUnbox() && barrier->input()->toUnbox()->mode() != MUnbox::Fallible)
@ -2494,8 +2494,8 @@ TryEliminateTypeBarrier(MTypeBarrier *barrier, bool *eliminated)
if (!barrierTypes || !inputTypes)
return true;
bool filtersNull = barrierTypes->filtersType(inputTypes, types::Type::NullType());
bool filtersUndefined = barrierTypes->filtersType(inputTypes, types::Type::UndefinedType());
bool filtersNull = barrierTypes->filtersType(inputTypes, TypeSet::NullType());
bool filtersUndefined = barrierTypes->filtersType(inputTypes, TypeSet::UndefinedType());
if (!filtersNull && !filtersUndefined)
return true;
@ -2883,7 +2883,7 @@ static bool
AnalyzePoppedThis(JSContext *cx, ObjectGroup *group,
MDefinition *thisValue, MInstruction *ins, bool definitelyExecuted,
HandlePlainObject baseobj,
Vector<types::TypeNewScript::Initializer> *initializerList,
Vector<TypeNewScript::Initializer> *initializerList,
Vector<PropertyName *> *accessedProperties,
bool *phandled)
{
@ -2926,7 +2926,7 @@ AnalyzePoppedThis(JSContext *cx, ObjectGroup *group,
return true;
RootedId id(cx, NameToId(setprop->name()));
if (!types::AddClearDefiniteGetterSetterForPrototypeChain(cx, group, id)) {
if (!AddClearDefiniteGetterSetterForPrototypeChain(cx, group, id)) {
// The prototype chain already contains a getter/setter for this
// property, or type information is too imprecise.
return true;
@ -2952,15 +2952,15 @@ AnalyzePoppedThis(JSContext *cx, ObjectGroup *group,
for (int i = callerResumePoints.length() - 1; i >= 0; i--) {
MResumePoint *rp = callerResumePoints[i];
JSScript *script = rp->block()->info().script();
types::TypeNewScript::Initializer entry(types::TypeNewScript::Initializer::SETPROP_FRAME,
script->pcToOffset(rp->pc()));
TypeNewScript::Initializer entry(TypeNewScript::Initializer::SETPROP_FRAME,
script->pcToOffset(rp->pc()));
if (!initializerList->append(entry))
return false;
}
JSScript *script = ins->block()->info().script();
types::TypeNewScript::Initializer entry(types::TypeNewScript::Initializer::SETPROP,
script->pcToOffset(setprop->resumePoint()->pc()));
TypeNewScript::Initializer entry(TypeNewScript::Initializer::SETPROP,
script->pcToOffset(setprop->resumePoint()->pc()));
if (!initializerList->append(entry))
return false;
@ -2986,7 +2986,7 @@ AnalyzePoppedThis(JSContext *cx, ObjectGroup *group,
if (!baseobj->lookup(cx, id) && !accessedProperties->append(get->name()))
return false;
if (!types::AddClearDefiniteGetterSetterForPrototypeChain(cx, group, id)) {
if (!AddClearDefiniteGetterSetterForPrototypeChain(cx, group, id)) {
// The |this| value can escape if any property reads it does go
// through a getter.
return true;
@ -3014,7 +3014,7 @@ CmpInstructions(const void *a, const void *b)
bool
jit::AnalyzeNewScriptDefiniteProperties(JSContext *cx, JSFunction *fun,
ObjectGroup *group, HandlePlainObject baseobj,
Vector<types::TypeNewScript::Initializer> *initializerList)
Vector<TypeNewScript::Initializer> *initializerList)
{
MOZ_ASSERT(cx->zone()->types.activeAnalysis);
@ -3050,7 +3050,7 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext *cx, JSFunction *fun,
return true;
}
types::TypeScript::SetThis(cx, script, types::Type::ObjectType(group));
TypeScript::SetThis(cx, script, TypeSet::ObjectType(group));
MIRGraph graph(&temp);
InlineScriptTree *inlineScriptTree = InlineScriptTree::New(&temp, nullptr, nullptr, script);
@ -3065,7 +3065,7 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext *cx, JSFunction *fun,
const OptimizationInfo *optimizationInfo = js_IonOptimizations.get(Optimization_Normal);
types::CompilerConstraintList *constraints = types::NewCompilerConstraintList(temp);
CompilerConstraintList *constraints = NewCompilerConstraintList(temp);
if (!constraints) {
js_ReportOutOfMemory(cx);
return false;
@ -3083,7 +3083,7 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext *cx, JSFunction *fun,
return true;
}
types::FinishDefinitePropertiesAnalysis(cx, constraints);
FinishDefinitePropertiesAnalysis(cx, constraints);
if (!SplitCriticalEdges(graph))
return false;
@ -3183,7 +3183,7 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext *cx, JSFunction *fun,
if (MResumePoint *rp = block->callerResumePoint()) {
if (block->numPredecessors() == 1 && block->getPredecessor(0) == rp->block()) {
JSScript *script = rp->block()->info().script();
if (!types::AddClearDefiniteFunctionUsesInScript(cx, group, script, block->info().script()))
if (!AddClearDefiniteFunctionUsesInScript(cx, group, script, block->info().script()))
return false;
}
}
@ -3234,7 +3234,7 @@ bool
jit::AnalyzeArgumentsUsage(JSContext *cx, JSScript *scriptArg)
{
RootedScript script(cx, scriptArg);
types::AutoEnterAnalysis enter(cx);
AutoEnterAnalysis enter(cx);
MOZ_ASSERT(!script->analyzedArgsUsage());
@ -3293,7 +3293,7 @@ jit::AnalyzeArgumentsUsage(JSContext *cx, JSScript *scriptArg)
const OptimizationInfo *optimizationInfo = js_IonOptimizations.get(Optimization_Normal);
types::CompilerConstraintList *constraints = types::NewCompilerConstraintList(temp);
CompilerConstraintList *constraints = NewCompilerConstraintList(temp);
if (!constraints)
return false;

View File

@ -171,7 +171,7 @@ ConvertLinearInequality(TempAllocator &alloc, MBasicBlock *block, const LinearSu
bool
AnalyzeNewScriptDefiniteProperties(JSContext *cx, JSFunction *fun,
ObjectGroup *group, HandlePlainObject baseobj,
Vector<types::TypeNewScript::Initializer> *initializerList);
Vector<TypeNewScript::Initializer> *initializerList);
bool
AnalyzeArgumentsUsage(JSContext *cx, JSScript *script);

File diff suppressed because it is too large Load Diff

View File

@ -218,7 +218,7 @@ class IonBuilder
public:
IonBuilder(JSContext *analysisContext, CompileCompartment *comp,
const JitCompileOptions &options, TempAllocator *temp,
MIRGraph *graph, types::CompilerConstraintList *constraints,
MIRGraph *graph, CompilerConstraintList *constraints,
BaselineInspector *inspector, CompileInfo *info,
const OptimizationInfo *optimizationInfo, BaselineFrameInspector *baselineFrame,
size_t inliningDepth = 0, uint32_t loopDepth = 0);
@ -240,8 +240,8 @@ class IonBuilder
MInstruction *constantMaybeNursery(JSObject *obj);
JSFunction *getSingleCallTarget(types::TemporaryTypeSet *calleeTypes);
bool getPolyCallTargets(types::TemporaryTypeSet *calleeTypes, bool constructing,
JSFunction *getSingleCallTarget(TemporaryTypeSet *calleeTypes);
bool getPolyCallTargets(TemporaryTypeSet *calleeTypes, bool constructing,
ObjectVector &targets, uint32_t maxTargets);
void popCfgStack();
@ -318,7 +318,7 @@ class IonBuilder
// Incorporates a type/typeSet into an OSR value for a loop, after the loop
// body has been processed.
bool addOsrValueTypeBarrier(uint32_t slot, MInstruction **def,
MIRType type, types::TemporaryTypeSet *typeSet);
MIRType type, TemporaryTypeSet *typeSet);
bool maybeAddOsrTypeBarriers();
// Restarts processing of a loop if the type information at its header was
@ -358,18 +358,18 @@ class IonBuilder
bool improveTypesAtCompare(MCompare *ins, bool trueBranch, MTest *test);
// Used to detect triangular structure at test.
bool detectAndOrStructure(MPhi *ins, bool *branchIsTrue);
bool replaceTypeSet(MDefinition *subject, types::TemporaryTypeSet *type, MTest *test);
bool replaceTypeSet(MDefinition *subject, TemporaryTypeSet *type, MTest *test);
// Add a guard which ensure that the set of type which goes through this
// generated code correspond to the observed types for the bytecode.
MDefinition *addTypeBarrier(MDefinition *def, types::TemporaryTypeSet *observed,
MDefinition *addTypeBarrier(MDefinition *def, TemporaryTypeSet *observed,
BarrierKind kind, MTypeBarrier **pbarrier = nullptr);
bool pushTypeBarrier(MDefinition *def, types::TemporaryTypeSet *observed, BarrierKind kind);
bool pushTypeBarrier(MDefinition *def, TemporaryTypeSet *observed, BarrierKind kind);
// As pushTypeBarrier, but will compute the needBarrier boolean itself based
// on observed and the JSFunction that we're planning to call. The
// JSFunction must be a DOM method or getter.
bool pushDOMTypeBarrier(MInstruction *ins, types::TemporaryTypeSet *observed, JSFunction* func);
bool pushDOMTypeBarrier(MInstruction *ins, TemporaryTypeSet *observed, JSFunction* func);
// If definiteType is not known or def already has the right type, just
// returns def. Otherwise, returns an MInstruction that has that definite
@ -378,7 +378,7 @@ class IonBuilder
MDefinition *ensureDefiniteType(MDefinition* def, MIRType definiteType);
// Creates a MDefinition based on the given def improved with type as TypeSet.
MDefinition *ensureDefiniteTypeSet(MDefinition* def, types::TemporaryTypeSet *types);
MDefinition *ensureDefiniteTypeSet(MDefinition* def, TemporaryTypeSet *types);
JSObject *getSingletonPrototype(JSFunction *target);
@ -404,9 +404,9 @@ class IonBuilder
bool hasStaticScopeObject(ScopeCoordinate sc, JSObject **pcall);
bool loadSlot(MDefinition *obj, size_t slot, size_t nfixed, MIRType rvalType,
BarrierKind barrier, types::TemporaryTypeSet *types);
BarrierKind barrier, TemporaryTypeSet *types);
bool loadSlot(MDefinition *obj, Shape *shape, MIRType rvalType,
BarrierKind barrier, types::TemporaryTypeSet *types);
BarrierKind barrier, TemporaryTypeSet *types);
bool storeSlot(MDefinition *obj, size_t slot, size_t nfixed,
MDefinition *value, bool needsBarrier,
MIRType slotType = MIRType_None);
@ -418,19 +418,19 @@ class IonBuilder
// jsop_getprop() helpers.
bool checkIsDefinitelyOptimizedArguments(MDefinition *obj, bool *isOptimizedArgs);
bool getPropTryInferredConstant(bool *emitted, MDefinition *obj, PropertyName *name,
types::TemporaryTypeSet *types);
TemporaryTypeSet *types);
bool getPropTryArgumentsLength(bool *emitted, MDefinition *obj);
bool getPropTryArgumentsCallee(bool *emitted, MDefinition *obj, PropertyName *name);
bool getPropTryConstant(bool *emitted, MDefinition *obj, PropertyName *name,
types::TemporaryTypeSet *types);
TemporaryTypeSet *types);
bool getPropTryDefiniteSlot(bool *emitted, MDefinition *obj, PropertyName *name,
BarrierKind barrier, types::TemporaryTypeSet *types);
BarrierKind barrier, TemporaryTypeSet *types);
bool getPropTryUnboxed(bool *emitted, MDefinition *obj, PropertyName *name,
BarrierKind barrier, types::TemporaryTypeSet *types);
BarrierKind barrier, TemporaryTypeSet *types);
bool getPropTryCommonGetter(bool *emitted, MDefinition *obj, PropertyName *name,
types::TemporaryTypeSet *types);
TemporaryTypeSet *types);
bool getPropTryInlineAccess(bool *emitted, MDefinition *obj, PropertyName *name,
BarrierKind barrier, types::TemporaryTypeSet *types);
BarrierKind barrier, TemporaryTypeSet *types);
bool getPropTryTypedObject(bool *emitted, MDefinition *obj, PropertyName *name);
bool getPropTryScalarPropOfTypedObject(bool *emitted, MDefinition *typedObj,
int32_t fieldOffset,
@ -444,25 +444,25 @@ class IonBuilder
TypedObjectPrediction fieldTypeReprs,
size_t fieldIndex);
bool getPropTryInnerize(bool *emitted, MDefinition *obj, PropertyName *name,
types::TemporaryTypeSet *types);
TemporaryTypeSet *types);
bool getPropTryCache(bool *emitted, MDefinition *obj, PropertyName *name,
BarrierKind barrier, types::TemporaryTypeSet *types);
BarrierKind barrier, TemporaryTypeSet *types);
// jsop_setprop() helpers.
bool setPropTryCommonSetter(bool *emitted, MDefinition *obj,
PropertyName *name, MDefinition *value);
bool setPropTryCommonDOMSetter(bool *emitted, MDefinition *obj,
MDefinition *value, JSFunction *setter,
types::TemporaryTypeSet *objTypes);
TemporaryTypeSet *objTypes);
bool setPropTryDefiniteSlot(bool *emitted, MDefinition *obj,
PropertyName *name, MDefinition *value,
bool barrier, types::TemporaryTypeSet *objTypes);
bool barrier, TemporaryTypeSet *objTypes);
bool setPropTryUnboxed(bool *emitted, MDefinition *obj,
PropertyName *name, MDefinition *value,
bool barrier, types::TemporaryTypeSet *objTypes);
bool barrier, TemporaryTypeSet *objTypes);
bool setPropTryInlineAccess(bool *emitted, MDefinition *obj,
PropertyName *name, MDefinition *value,
bool barrier, types::TemporaryTypeSet *objTypes);
bool barrier, TemporaryTypeSet *objTypes);
bool setPropTryTypedObject(bool *emitted, MDefinition *obj,
PropertyName *name, MDefinition *value);
bool setPropTryReferencePropOfTypedObject(bool *emitted,
@ -478,11 +478,11 @@ class IonBuilder
TypedObjectPrediction fieldTypeReprs);
bool setPropTryCache(bool *emitted, MDefinition *obj,
PropertyName *name, MDefinition *value,
bool barrier, types::TemporaryTypeSet *objTypes);
bool barrier, TemporaryTypeSet *objTypes);
// binary data lookup helpers.
TypedObjectPrediction typedObjectPrediction(MDefinition *typedObj);
TypedObjectPrediction typedObjectPrediction(types::TemporaryTypeSet *types);
TypedObjectPrediction typedObjectPrediction(TemporaryTypeSet *types);
bool typedObjectHasField(MDefinition *typedObj,
PropertyName *name,
size_t *fieldOffset,
@ -650,7 +650,7 @@ class IonBuilder
bool jsop_getelem_dense(MDefinition *obj, MDefinition *index);
bool jsop_getelem_typed(MDefinition *obj, MDefinition *index, ScalarTypeDescr::Type arrayType);
bool jsop_setelem();
bool jsop_setelem_dense(types::TemporaryTypeSet::DoubleConversion conversion,
bool jsop_setelem_dense(TemporaryTypeSet::DoubleConversion conversion,
SetElemSafety safety,
MDefinition *object, MDefinition *index, MDefinition *value);
bool jsop_setelem_typed(ScalarTypeDescr::Type arrayType,
@ -726,7 +726,7 @@ class IonBuilder
// Native inlining helpers.
// The typeset for the return value of our function. These are
// the types it's been observed returning in the past.
types::TemporaryTypeSet *getInlineReturnTypeSet();
TemporaryTypeSet *getInlineReturnTypeSet();
// The known MIR type of getInlineReturnTypeSet.
MIRType getInlineReturnType();
@ -863,18 +863,18 @@ class IonBuilder
MBasicBlock *bottom);
MDefinition *specializeInlinedReturn(MDefinition *rdef, MBasicBlock *exit);
bool objectsHaveCommonPrototype(types::TemporaryTypeSet *types, PropertyName *name,
bool objectsHaveCommonPrototype(TemporaryTypeSet *types, PropertyName *name,
bool isGetter, JSObject *foundProto, bool *guardGlobal);
void freezePropertiesForCommonPrototype(types::TemporaryTypeSet *types, PropertyName *name,
void freezePropertiesForCommonPrototype(TemporaryTypeSet *types, PropertyName *name,
JSObject *foundProto, bool allowEmptyTypesForGlobal = false);
/*
* Callers must pass a non-null globalGuard if they pass a non-null globalShape.
*/
bool testCommonGetterSetter(types::TemporaryTypeSet *types, PropertyName *name,
bool testCommonGetterSetter(TemporaryTypeSet *types, PropertyName *name,
bool isGetter, JSObject *foundProto, Shape *lastProperty,
MDefinition **guard, Shape *globalShape = nullptr,
MDefinition **globalGuard = nullptr);
bool testShouldDOMCall(types::TypeSet *inTypes,
bool testShouldDOMCall(TypeSet *inTypes,
JSFunction *func, JSJitInfo::OpType opType);
MDefinition *addShapeGuardsForGetterSetter(MDefinition *obj, JSObject *holder, Shape *holderShape,
@ -882,27 +882,27 @@ class IonBuilder
bool isOwnProperty);
bool annotateGetPropertyCache(MDefinition *obj, MGetPropertyCache *getPropCache,
types::TemporaryTypeSet *objTypes,
types::TemporaryTypeSet *pushedTypes);
TemporaryTypeSet *objTypes,
TemporaryTypeSet *pushedTypes);
MGetPropertyCache *getInlineableGetPropertyCache(CallInfo &callInfo);
JSObject *testSingletonProperty(JSObject *obj, PropertyName *name);
bool testSingletonPropertyTypes(MDefinition *obj, JSObject *singleton, PropertyName *name,
bool *testObject, bool *testString);
uint32_t getDefiniteSlot(types::TemporaryTypeSet *types, PropertyName *name);
uint32_t getUnboxedOffset(types::TemporaryTypeSet *types, PropertyName *name,
uint32_t getDefiniteSlot(TemporaryTypeSet *types, PropertyName *name);
uint32_t getUnboxedOffset(TemporaryTypeSet *types, PropertyName *name,
JSValueType *punboxedType);
MInstruction *loadUnboxedProperty(MDefinition *obj, size_t offset, JSValueType unboxedType,
BarrierKind barrier, types::TemporaryTypeSet *types);
BarrierKind barrier, TemporaryTypeSet *types);
MInstruction *storeUnboxedProperty(MDefinition *obj, size_t offset, JSValueType unboxedType,
MDefinition *value);
bool freezePropTypeSets(types::TemporaryTypeSet *types,
bool freezePropTypeSets(TemporaryTypeSet *types,
JSObject *foundProto, PropertyName *name);
bool canInlinePropertyOpShapes(const BaselineInspector::ShapeVector &nativeShapes,
const BaselineInspector::ObjectGroupVector &unboxedGroups);
types::TemporaryTypeSet *bytecodeTypes(jsbytecode *pc);
TemporaryTypeSet *bytecodeTypes(jsbytecode *pc);
// Use one of the below methods for updating the current block, rather than
// updating |current| directly. setCurrent() should only be used in cases
@ -946,7 +946,7 @@ class IonBuilder
CodeGenerator *backgroundCodegen() const { return backgroundCodegen_; }
void setBackgroundCodegen(CodeGenerator *codegen) { backgroundCodegen_ = codegen; }
types::CompilerConstraintList *constraints() {
CompilerConstraintList *constraints() {
return constraints_;
}
@ -978,7 +978,7 @@ class IonBuilder
BaselineFrameInspector *baselineFrame_;
// Constraints for recording dependencies on type information.
types::CompilerConstraintList *constraints_;
CompilerConstraintList *constraints_;
// Basic analysis information about the script.
BytecodeAnalysis analysis_;
@ -986,7 +986,7 @@ class IonBuilder
return analysis_;
}
types::TemporaryTypeSet *thisTypes, *argTypes, *typeArray;
TemporaryTypeSet *thisTypes, *argTypes, *typeArray;
uint32_t typeArrayHint;
uint32_t *bytecodeTypeMap;
@ -1119,7 +1119,7 @@ class IonBuilder
// unchecked variants, despite the unchecked variants having no other
// callers.
void trackTypeInfo(JS::TrackedTypeSite site, MIRType mirType,
types::TemporaryTypeSet *typeSet)
TemporaryTypeSet *typeSet)
{
if (MOZ_UNLIKELY(current->trackedSite()->hasOptimizations()))
trackTypeInfoUnchecked(site, mirType, typeSet);
@ -1156,7 +1156,7 @@ class IonBuilder
// Out-of-line variants that don't check if optimization tracking is
// enabled.
void trackTypeInfoUnchecked(JS::TrackedTypeSite site, MIRType mirType,
types::TemporaryTypeSet *typeSet);
TemporaryTypeSet *typeSet);
void trackTypeInfoUnchecked(JS::TrackedTypeSite site, JSObject *obj);
void trackTypeInfoUnchecked(CallInfo &callInfo);
void trackOptimizationAttemptUnchecked(JS::TrackedStrategy strategy);
@ -1292,7 +1292,7 @@ class CallInfo
}
};
bool TypeSetIncludes(types::TypeSet *types, MIRType input, types::TypeSet *inputTypes);
bool TypeSetIncludes(TypeSet *types, MIRType input, TypeSet *inputTypes);
bool NeedsPostBarrier(CompileInfo &info, MDefinition *value);

View File

@ -1268,10 +1268,9 @@ GetPropertyIC::allowArrayLength(Context cx, HandleObject obj) const
CacheLocation *locs = ion->getCacheLocs(locationIndex);
for (size_t i = 0; i < numLocations; i++) {
CacheLocation &curLoc = locs[i];
types::StackTypeSet *bcTypes =
types::TypeScript::BytecodeTypes(curLoc.script, curLoc.pc);
StackTypeSet *bcTypes = TypeScript::BytecodeTypes(curLoc.script, curLoc.pc);
if (!bcTypes->hasType(types::Type::Int32Type()))
if (!bcTypes->hasType(TypeSet::Int32Type()))
return false;
}
@ -1855,7 +1854,7 @@ GetPropertyIC::update(JSContext *cx, size_t cacheIndex,
// Monitor changes to cache entry.
if (!cache.monitoredResult())
types::TypeScript::Monitor(cx, script, pc, vp);
TypeScript::Monitor(cx, script, pc, vp);
}
return true;
@ -1900,11 +1899,11 @@ CheckTypeSetForWrite(MacroAssembler &masm, JSObject *obj, jsid id,
ObjectGroup *group = obj->group();
if (group->unknownProperties())
return;
types::HeapTypeSet *propTypes = group->maybeGetProperty(id);
HeapTypeSet *propTypes = group->maybeGetProperty(id);
MOZ_ASSERT(propTypes);
// guardTypeSet can read from type sets without triggering read barriers.
types::TypeSet::readBarrier(propTypes);
TypeSet::readBarrier(propTypes);
Register scratch = object;
masm.guardTypeSet(valReg, propTypes, BarrierKind::TypeSet, scratch, failure);
@ -2581,7 +2580,7 @@ CanInlineSetPropTypeCheck(JSObject *obj, jsid id, ConstantOrRegister val, bool *
bool shouldCheck = false;
ObjectGroup *group = obj->group();
if (!group->unknownProperties()) {
types::HeapTypeSet *propTypes = group->maybeGetProperty(id);
HeapTypeSet *propTypes = group->maybeGetProperty(id);
if (!propTypes)
return false;
if (!propTypes->unknown()) {
@ -2590,7 +2589,7 @@ CanInlineSetPropTypeCheck(JSObject *obj, jsid id, ConstantOrRegister val, bool *
shouldCheck = true;
if (val.constant()) {
// If the input is a constant, then don't bother if the barrier will always fail.
if (!propTypes->hasType(types::GetValueType(val.value())))
if (!propTypes->hasType(TypeSet::GetValueType(val.value())))
return false;
shouldCheck = false;
} else {
@ -2601,7 +2600,7 @@ CanInlineSetPropTypeCheck(JSObject *obj, jsid id, ConstantOrRegister val, bool *
// contains the specific object, but doesn't have ANYOBJECT set.
if (reg.hasTyped() && reg.type() != MIRType_Object) {
JSValueType valType = ValueTypeFromMIRType(reg.type());
if (!propTypes->hasType(types::Type::PrimitiveType(valType)))
if (!propTypes->hasType(TypeSet::PrimitiveType(valType)))
return false;
shouldCheck = false;
}
@ -3409,7 +3408,7 @@ GetElementIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
if (!GetObjectElementOperation(cx, JSOp(*pc), obj, idval, res))
return false;
if (!cache.monitoredResult())
types::TypeScript::Monitor(cx, script, pc, res);
TypeScript::Monitor(cx, script, pc, res);
return true;
}
@ -3463,7 +3462,7 @@ GetElementIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
}
if (!cache.monitoredResult())
types::TypeScript::Monitor(cx, script, pc, res);
TypeScript::Monitor(cx, script, pc, res);
return true;
}
@ -4143,7 +4142,7 @@ NameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain,
}
// Monitor changes to cache entry.
types::TypeScript::Monitor(cx, script, pc, vp);
TypeScript::Monitor(cx, script, pc, vp);
return true;
}

View File

@ -265,7 +265,7 @@ struct IonScript
uint32_t invalidationCount_;
// Identifier of the compilation which produced this code.
types::RecompileInfo recompileInfo_;
RecompileInfo recompileInfo_;
// The optimization level this script was compiled in.
OptimizationLevel optimizationLevel_;
@ -332,7 +332,7 @@ struct IonScript
// Do not call directly, use IonScript::New. This is public for cx->new_.
IonScript();
static IonScript *New(JSContext *cx, types::RecompileInfo recompileInfo,
static IonScript *New(JSContext *cx, RecompileInfo recompileInfo,
uint32_t frameSlots, uint32_t argumentSlots, uint32_t frameSize,
size_t snapshotsListSize, size_t snapshotsRVATableSize,
size_t recoversSize, size_t bailoutEntries,
@ -541,10 +541,10 @@ struct IonScript
if (!invalidationCount_)
Destroy(fop, this);
}
const types::RecompileInfo& recompileInfo() const {
const RecompileInfo& recompileInfo() const {
return recompileInfo_;
}
types::RecompileInfo& recompileInfoRef() {
RecompileInfo& recompileInfoRef() {
return recompileInfo_;
}
OptimizationLevel optimizationLevel() const {

View File

@ -2115,7 +2115,7 @@ SnapshotIterator::computeInstructionResults(JSContext *cx, RInstructionResults *
// Use AutoEnterAnalysis to avoid invoking the object metadata callback,
// which could try to walk the stack while bailing out.
types::AutoEnterAnalysis enter(cx);
AutoEnterAnalysis enter(cx);
// Fill with the results of recover instructions.
SnapshotIterator s(*this);

View File

@ -2295,7 +2295,7 @@ LIRGenerator::visitTypeBarrier(MTypeBarrier *ins)
// Requesting a non-GC pointer is safe here since we never re-enter C++
// from inside a type barrier test.
const types::TemporaryTypeSet *types = ins->resultTypeSet();
const TemporaryTypeSet *types = ins->resultTypeSet();
bool needTemp = !types->unknownObject() && types->getObjectCount() > 0;
MIRType inputType = ins->getOperand(0)->type();
@ -2325,7 +2325,7 @@ LIRGenerator::visitTypeBarrier(MTypeBarrier *ins)
}
// Handle typebarrier with specific ObjectGroup/SingleObjects.
if (inputType == MIRType_Object && !types->hasType(types::Type::AnyObjectType()) &&
if (inputType == MIRType_Object && !types->hasType(TypeSet::AnyObjectType()) &&
ins->barrierKind() != BarrierKind::TypeTagOnly)
{
LDefinition tmp = needTemp ? temp() : LDefinition::BogusTemp();
@ -2346,7 +2346,7 @@ LIRGenerator::visitMonitorTypes(MMonitorTypes *ins)
// Requesting a non-GC pointer is safe here since we never re-enter C++
// from inside a type check.
const types::TemporaryTypeSet *types = ins->typeSet();
const TemporaryTypeSet *types = ins->typeSet();
bool needTemp = !types->unknownObject() && types->getObjectCount() > 0;
LDefinition tmp = needTemp ? temp() : tempToUnbox();

View File

@ -274,7 +274,7 @@ IonBuilder::inlineNativeGetter(CallInfo &callInfo, JSFunction *target)
if (!optimizationInfo().inlineNative())
return InliningStatus_NotInlined;
types::TemporaryTypeSet *thisTypes = callInfo.thisArg()->resultTypeSet();
TemporaryTypeSet *thisTypes = callInfo.thisArg()->resultTypeSet();
MOZ_ASSERT(callInfo.argc() == 0);
// Try to optimize typed array lengths. There is one getter on
@ -321,7 +321,7 @@ IonBuilder::inlineNonFunctionCall(CallInfo &callInfo, JSObject *target)
return InliningStatus_NotInlined;
}
types::TemporaryTypeSet *
TemporaryTypeSet *
IonBuilder::getInlineReturnTypeSet()
{
return bytecodeTypes(pc);
@ -330,7 +330,7 @@ IonBuilder::getInlineReturnTypeSet()
MIRType
IonBuilder::getInlineReturnType()
{
types::TemporaryTypeSet *returnTypes = getInlineReturnTypeSet();
TemporaryTypeSet *returnTypes = getInlineReturnTypeSet();
return returnTypes->getKnownMIRType();
}
@ -377,9 +377,9 @@ IonBuilder::inlineArray(CallInfo &callInfo)
initLength = callInfo.argc();
allocating = NewArray_FullyAllocating;
types::TypeSetObjectKey *key = types::TypeSetObjectKey::get(templateArray);
TypeSet::ObjectKey *key = TypeSet::ObjectKey::get(templateArray);
if (!key->unknownProperties()) {
types::HeapTypeSetKey elemTypes = key->property(JSID_VOID);
HeapTypeSetKey elemTypes = key->property(JSID_VOID);
for (uint32_t i = 0; i < initLength; i++) {
MDefinition *value = callInfo.getArg(i);
@ -391,9 +391,9 @@ IonBuilder::inlineArray(CallInfo &callInfo)
}
}
types::TemporaryTypeSet::DoubleConversion conversion =
TemporaryTypeSet::DoubleConversion conversion =
getInlineReturnTypeSet()->convertDoubleElements(constraints());
if (conversion == types::TemporaryTypeSet::AlwaysConvertToDoubles)
if (conversion == TemporaryTypeSet::AlwaysConvertToDoubles)
templateArray->setShouldConvertDoubleElements();
else
templateArray->clearShouldConvertDoubleElements();
@ -461,7 +461,7 @@ IonBuilder::inlineArray(CallInfo &callInfo)
current->add(id);
MDefinition *value = callInfo.getArg(i);
if (conversion == types::TemporaryTypeSet::AlwaysConvertToDoubles) {
if (conversion == TemporaryTypeSet::AlwaysConvertToDoubles) {
MInstruction *valueDouble = MToDouble::New(alloc(), value);
current->add(valueDouble);
value = valueDouble;
@ -512,7 +512,7 @@ IonBuilder::inlineArrayPopShift(CallInfo &callInfo, MArrayPopShift::Mode mode)
OBJECT_FLAG_ITERATED;
MDefinition *obj = callInfo.thisArg();
types::TemporaryTypeSet *thisTypes = obj->resultTypeSet();
TemporaryTypeSet *thisTypes = obj->resultTypeSet();
if (!thisTypes || thisTypes->getKnownClass(constraints()) != &ArrayObject::class_)
return InliningStatus_NotInlined;
if (thisTypes->hasObjectFlags(constraints(), unhandledFlags)) {
@ -520,7 +520,7 @@ IonBuilder::inlineArrayPopShift(CallInfo &callInfo, MArrayPopShift::Mode mode)
return InliningStatus_NotInlined;
}
if (types::ArrayPrototypeHasIndexedProperty(constraints(), script())) {
if (ArrayPrototypeHasIndexedProperty(constraints(), script())) {
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
return InliningStatus_NotInlined;
}
@ -529,9 +529,9 @@ IonBuilder::inlineArrayPopShift(CallInfo &callInfo, MArrayPopShift::Mode mode)
obj = addMaybeCopyElementsForWrite(obj);
types::TemporaryTypeSet *returnTypes = getInlineReturnTypeSet();
TemporaryTypeSet *returnTypes = getInlineReturnTypeSet();
bool needsHoleCheck = thisTypes->hasObjectFlags(constraints(), OBJECT_FLAG_NON_PACKED);
bool maybeUndefined = returnTypes->hasType(types::Type::UndefinedType());
bool maybeUndefined = returnTypes->hasType(TypeSet::UndefinedType());
BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(),
obj, nullptr, returnTypes);
@ -640,7 +640,7 @@ IonBuilder::inlineArrayPush(CallInfo &callInfo)
if (callInfo.thisArg()->type() != MIRType_Object)
return InliningStatus_NotInlined;
types::TemporaryTypeSet *thisTypes = callInfo.thisArg()->resultTypeSet();
TemporaryTypeSet *thisTypes = callInfo.thisArg()->resultTypeSet();
if (!thisTypes || thisTypes->getKnownClass(constraints()) != &ArrayObject::class_)
return InliningStatus_NotInlined;
if (thisTypes->hasObjectFlags(constraints(), OBJECT_FLAG_SPARSE_INDEXES |
@ -650,14 +650,14 @@ IonBuilder::inlineArrayPush(CallInfo &callInfo)
return InliningStatus_NotInlined;
}
if (types::ArrayPrototypeHasIndexedProperty(constraints(), script())) {
if (ArrayPrototypeHasIndexedProperty(constraints(), script())) {
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
return InliningStatus_NotInlined;
}
types::TemporaryTypeSet::DoubleConversion conversion =
TemporaryTypeSet::DoubleConversion conversion =
thisTypes->convertDoubleElements(constraints());
if (conversion == types::TemporaryTypeSet::AmbiguousDoubleConversion) {
if (conversion == TemporaryTypeSet::AmbiguousDoubleConversion) {
trackOptimizationOutcome(TrackedOutcome::ArrayDoubleConversion);
return InliningStatus_NotInlined;
}
@ -665,8 +665,8 @@ IonBuilder::inlineArrayPush(CallInfo &callInfo)
callInfo.setImplicitlyUsedUnchecked();
value = callInfo.getArg(0);
if (conversion == types::TemporaryTypeSet::AlwaysConvertToDoubles ||
conversion == types::TemporaryTypeSet::MaybeConvertToDoubles)
if (conversion == TemporaryTypeSet::AlwaysConvertToDoubles ||
conversion == TemporaryTypeSet::MaybeConvertToDoubles)
{
MInstruction *valueDouble = MToDouble::New(alloc(), value);
current->add(valueDouble);
@ -704,8 +704,8 @@ IonBuilder::inlineArrayConcat(CallInfo &callInfo)
return InliningStatus_NotInlined;
// |this| and the argument must be dense arrays.
types::TemporaryTypeSet *thisTypes = callInfo.thisArg()->resultTypeSet();
types::TemporaryTypeSet *argTypes = callInfo.getArg(0)->resultTypeSet();
TemporaryTypeSet *thisTypes = callInfo.thisArg()->resultTypeSet();
TemporaryTypeSet *argTypes = callInfo.getArg(0)->resultTypeSet();
if (!thisTypes || !argTypes)
return InliningStatus_NotInlined;
@ -728,7 +728,7 @@ IonBuilder::inlineArrayConcat(CallInfo &callInfo)
}
// Watch out for indexed properties on the prototype.
if (types::ArrayPrototypeHasIndexedProperty(constraints(), script())) {
if (ArrayPrototypeHasIndexedProperty(constraints(), script())) {
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
return InliningStatus_NotInlined;
}
@ -741,7 +741,7 @@ IonBuilder::inlineArrayConcat(CallInfo &callInfo)
ObjectGroup *thisGroup = thisTypes->getGroup(0);
if (!thisGroup)
return InliningStatus_NotInlined;
types::TypeSetObjectKey *thisKey = types::TypeSetObjectKey::get(thisGroup);
TypeSet::ObjectKey *thisKey = TypeSet::ObjectKey::get(thisGroup);
if (thisKey->unknownProperties())
return InliningStatus_NotInlined;
@ -757,21 +757,21 @@ IonBuilder::inlineArrayConcat(CallInfo &callInfo)
// Constraints modeling this concat have not been generated by inference,
// so check that type information already reflects possible side effects of
// this call.
types::HeapTypeSetKey thisElemTypes = thisKey->property(JSID_VOID);
HeapTypeSetKey thisElemTypes = thisKey->property(JSID_VOID);
types::TemporaryTypeSet *resTypes = getInlineReturnTypeSet();
if (!resTypes->hasType(types::Type::ObjectType(thisKey)))
TemporaryTypeSet *resTypes = getInlineReturnTypeSet();
if (!resTypes->hasType(TypeSet::ObjectType(thisKey)))
return InliningStatus_NotInlined;
for (unsigned i = 0; i < argTypes->getObjectCount(); i++) {
types::TypeSetObjectKey *key = argTypes->getObject(i);
TypeSet::ObjectKey *key = argTypes->getObject(i);
if (!key)
continue;
if (key->unknownProperties())
return InliningStatus_NotInlined;
types::HeapTypeSetKey elemTypes = key->property(JSID_VOID);
HeapTypeSetKey elemTypes = key->property(JSID_VOID);
if (!elemTypes.knownSubset(constraints(), thisElemTypes))
return InliningStatus_NotInlined;
}
@ -1236,11 +1236,11 @@ IonBuilder::inlineMathFRound(CallInfo &callInfo)
// MIRType can't be Float32, as this point, as getInlineReturnType uses JSVal types
// to infer the returned MIR type.
types::TemporaryTypeSet *returned = getInlineReturnTypeSet();
TemporaryTypeSet *returned = getInlineReturnTypeSet();
if (returned->empty()) {
// As there's only one possible returned type, just add it to the observed
// returned typeset
returned->addType(types::Type::DoubleType(), alloc_->lifoAlloc());
returned->addType(TypeSet::DoubleType(), alloc_->lifoAlloc());
} else {
MIRType returnType = getInlineReturnType();
if (!IsNumberType(returnType))
@ -1377,15 +1377,15 @@ IonBuilder::inlineStringSplit(CallInfo &callInfo)
return InliningStatus_NotInlined;
MOZ_ASSERT(templateObject->is<ArrayObject>());
types::TypeSetObjectKey *retKey = types::TypeSetObjectKey::get(templateObject);
TypeSet::ObjectKey *retKey = TypeSet::ObjectKey::get(templateObject);
if (retKey->unknownProperties())
return InliningStatus_NotInlined;
types::HeapTypeSetKey key = retKey->property(JSID_VOID);
HeapTypeSetKey key = retKey->property(JSID_VOID);
if (!key.maybeTypes())
return InliningStatus_NotInlined;
if (!key.maybeTypes()->hasType(types::Type::StringType())) {
if (!key.maybeTypes()->hasType(TypeSet::StringType())) {
key.freeze(constraints());
return InliningStatus_NotInlined;
}
@ -1547,7 +1547,7 @@ IonBuilder::inlineRegExpExec(CallInfo &callInfo)
if (callInfo.thisArg()->type() != MIRType_Object)
return InliningStatus_NotInlined;
types::TemporaryTypeSet *thisTypes = callInfo.thisArg()->resultTypeSet();
TemporaryTypeSet *thisTypes = callInfo.thisArg()->resultTypeSet();
const Class *clasp = thisTypes ? thisTypes->getKnownClass(constraints()) : nullptr;
if (clasp != &RegExpObject::class_)
return InliningStatus_NotInlined;
@ -1588,7 +1588,7 @@ IonBuilder::inlineRegExpTest(CallInfo &callInfo)
if (callInfo.thisArg()->type() != MIRType_Object)
return InliningStatus_NotInlined;
types::TemporaryTypeSet *thisTypes = callInfo.thisArg()->resultTypeSet();
TemporaryTypeSet *thisTypes = callInfo.thisArg()->resultTypeSet();
const Class *clasp = thisTypes ? thisTypes->getKnownClass(constraints()) : nullptr;
if (clasp != &RegExpObject::class_)
return InliningStatus_NotInlined;
@ -1627,7 +1627,7 @@ IonBuilder::inlineStrReplace(CallInfo &callInfo)
return InliningStatus_NotInlined;
// Arg 0: RegExp.
types::TemporaryTypeSet *arg0Type = callInfo.getArg(0)->resultTypeSet();
TemporaryTypeSet *arg0Type = callInfo.getArg(0)->resultTypeSet();
const Class *clasp = arg0Type ? arg0Type->getKnownClass(constraints()) : nullptr;
if (clasp != &RegExpObject::class_ && callInfo.getArg(0)->type() != MIRType_String)
return InliningStatus_NotInlined;
@ -1704,7 +1704,7 @@ IonBuilder::inlineObjectCreate(CallInfo &callInfo)
if (IsInsideNursery(proto))
return InliningStatus_NotInlined;
types::TemporaryTypeSet *types = arg->resultTypeSet();
TemporaryTypeSet *types = arg->resultTypeSet();
if (!types || types->maybeSingleton() != proto)
return InliningStatus_NotInlined;
@ -1851,7 +1851,7 @@ IonBuilder::inlineUnsafeSetDenseArrayElement(CallInfo &callInfo, uint32_t base)
MDefinition *id = callInfo.getArg(base + 1);
MDefinition *elem = callInfo.getArg(base + 2);
types::TemporaryTypeSet::DoubleConversion conversion =
TemporaryTypeSet::DoubleConversion conversion =
obj->resultTypeSet()->convertDoubleElements(constraints());
if (!jsop_setelem_dense(conversion, SetElem_Unsafe, obj, id, elem))
return false;
@ -1913,7 +1913,7 @@ IonBuilder::inlineHasClass(CallInfo &callInfo,
if (getInlineReturnType() != MIRType_Boolean)
return InliningStatus_NotInlined;
types::TemporaryTypeSet *types = callInfo.getArg(0)->resultTypeSet();
TemporaryTypeSet *types = callInfo.getArg(0)->resultTypeSet();
const Class *knownClass = types ? types->getKnownClass(constraints()) : nullptr;
if (knownClass) {
pushConstant(BooleanValue(knownClass == clasp1 ||
@ -1966,20 +1966,20 @@ IonBuilder::inlineIsTypedArray(CallInfo &callInfo)
// The test is elaborate: in-line only if there is exact
// information.
types::TemporaryTypeSet *types = callInfo.getArg(0)->resultTypeSet();
TemporaryTypeSet *types = callInfo.getArg(0)->resultTypeSet();
if (!types)
return InliningStatus_NotInlined;
bool result = false;
switch (types->forAllClasses(constraints(), IsTypedArrayClass)) {
case types::TemporaryTypeSet::ForAllResult::ALL_FALSE:
case types::TemporaryTypeSet::ForAllResult::EMPTY:
case TemporaryTypeSet::ForAllResult::ALL_FALSE:
case TemporaryTypeSet::ForAllResult::EMPTY:
result = false;
break;
case types::TemporaryTypeSet::ForAllResult::ALL_TRUE:
case TemporaryTypeSet::ForAllResult::ALL_TRUE:
result = true;
break;
case types::TemporaryTypeSet::ForAllResult::MIXED:
case TemporaryTypeSet::ForAllResult::MIXED:
return InliningStatus_NotInlined;
}
@ -2026,20 +2026,20 @@ IonBuilder::inlineObjectIsTypeDescr(CallInfo &callInfo)
// The test is elaborate: in-line only if there is exact
// information.
types::TemporaryTypeSet *types = callInfo.getArg(0)->resultTypeSet();
TemporaryTypeSet *types = callInfo.getArg(0)->resultTypeSet();
if (!types)
return InliningStatus_NotInlined;
bool result = false;
switch (types->forAllClasses(constraints(), IsTypeDescrClass)) {
case types::TemporaryTypeSet::ForAllResult::ALL_FALSE:
case types::TemporaryTypeSet::ForAllResult::EMPTY:
case TemporaryTypeSet::ForAllResult::ALL_FALSE:
case TemporaryTypeSet::ForAllResult::EMPTY:
result = false;
break;
case types::TemporaryTypeSet::ForAllResult::ALL_TRUE:
case TemporaryTypeSet::ForAllResult::ALL_TRUE:
result = true;
break;
case types::TemporaryTypeSet::ForAllResult::MIXED:
case TemporaryTypeSet::ForAllResult::MIXED:
return InliningStatus_NotInlined;
}
@ -2070,15 +2070,15 @@ IonBuilder::inlineSetTypedObjectOffset(CallInfo &callInfo)
// with TI or because of something else -- but we'll just let it
// fall through to the SetTypedObjectOffset intrinsic in such
// cases.
types::TemporaryTypeSet *types = typedObj->resultTypeSet();
TemporaryTypeSet *types = typedObj->resultTypeSet();
if (typedObj->type() != MIRType_Object || !types)
return InliningStatus_NotInlined;
switch (types->forAllClasses(constraints(), IsTypedObjectClass)) {
case types::TemporaryTypeSet::ForAllResult::ALL_FALSE:
case types::TemporaryTypeSet::ForAllResult::EMPTY:
case types::TemporaryTypeSet::ForAllResult::MIXED:
case TemporaryTypeSet::ForAllResult::ALL_FALSE:
case TemporaryTypeSet::ForAllResult::EMPTY:
case TemporaryTypeSet::ForAllResult::MIXED:
return InliningStatus_NotInlined;
case types::TemporaryTypeSet::ForAllResult::ALL_TRUE:
case TemporaryTypeSet::ForAllResult::ALL_TRUE:
break;
}
@ -2188,7 +2188,7 @@ IonBuilder::inlineIsCallable(CallInfo &callInfo)
isCallableKnown = true;
isCallableConstant = false;
} else {
types::TemporaryTypeSet *types = callInfo.getArg(0)->resultTypeSet();
TemporaryTypeSet *types = callInfo.getArg(0)->resultTypeSet();
const Class *clasp = types ? types->getKnownClass(constraints()) : nullptr;
if (clasp && !clasp->isProxy()) {
isCallableKnown = true;
@ -2588,7 +2588,7 @@ IonBuilder::atomicsMeetsPreconditions(CallInfo &callInfo, Scalar::Type *arrayTyp
// optimize and that the return type is suitable for that element
// type.
types::TemporaryTypeSet *arg0Types = callInfo.getArg(0)->resultTypeSet();
TemporaryTypeSet *arg0Types = callInfo.getArg(0)->resultTypeSet();
if (!arg0Types)
return false;

View File

@ -270,7 +270,7 @@ MDefinition::mightBeMagicType() const
if (MIRType_Value != type())
return false;
return !resultTypeSet() || resultTypeSet()->hasType(types::Type::MagicArgType());
return !resultTypeSet() || resultTypeSet()->hasType(TypeSet::MagicArgType());
}
MDefinition *
@ -339,12 +339,12 @@ MInstruction::clearResumePoint()
}
static bool
MaybeEmulatesUndefined(types::CompilerConstraintList *constraints, MDefinition *op)
MaybeEmulatesUndefined(CompilerConstraintList *constraints, MDefinition *op)
{
if (!op->mightBeType(MIRType_Object))
return false;
types::TemporaryTypeSet *types = op->resultTypeSet();
TemporaryTypeSet *types = op->resultTypeSet();
if (!types)
return true;
@ -352,12 +352,12 @@ MaybeEmulatesUndefined(types::CompilerConstraintList *constraints, MDefinition *
}
static bool
MaybeCallable(types::CompilerConstraintList *constraints, MDefinition *op)
MaybeCallable(CompilerConstraintList *constraints, MDefinition *op)
{
if (!op->mightBeType(MIRType_Object))
return false;
types::TemporaryTypeSet *types = op->resultTypeSet();
TemporaryTypeSet *types = op->resultTypeSet();
if (!types)
return true;
@ -371,7 +371,7 @@ MTest::New(TempAllocator &alloc, MDefinition *ins, MBasicBlock *ifTrue, MBasicBl
}
void
MTest::cacheOperandMightEmulateUndefined(types::CompilerConstraintList *constraints)
MTest::cacheOperandMightEmulateUndefined(CompilerConstraintList *constraints)
{
MOZ_ASSERT(operandMightEmulateUndefined());
@ -621,13 +621,13 @@ MDefinition::emptyResultTypeSet() const
}
MConstant *
MConstant::New(TempAllocator &alloc, const Value &v, types::CompilerConstraintList *constraints)
MConstant::New(TempAllocator &alloc, const Value &v, CompilerConstraintList *constraints)
{
return new(alloc) MConstant(v, constraints);
}
MConstant *
MConstant::NewTypedValue(TempAllocator &alloc, const Value &v, MIRType type, types::CompilerConstraintList *constraints)
MConstant::NewTypedValue(TempAllocator &alloc, const Value &v, MIRType type, CompilerConstraintList *constraints)
{
MOZ_ASSERT(!IsSimdType(type));
MConstant *constant = new(alloc) MConstant(v, constraints);
@ -647,29 +647,29 @@ MConstant::NewConstraintlessObject(TempAllocator &alloc, JSObject *v)
return new(alloc) MConstant(v);
}
types::TemporaryTypeSet *
jit::MakeSingletonTypeSet(types::CompilerConstraintList *constraints, JSObject *obj)
TemporaryTypeSet *
jit::MakeSingletonTypeSet(CompilerConstraintList *constraints, JSObject *obj)
{
// Invalidate when this object's ObjectGroup gets unknown properties. This
// happens for instance when we mutate an object's __proto__, in this case
// we want to invalidate and mark this TypeSet as containing AnyObject
// (because mutating __proto__ will change an object's ObjectGroup).
MOZ_ASSERT(constraints);
types::TypeSetObjectKey *key = types::TypeSetObjectKey::get(obj);
TypeSet::ObjectKey *key = TypeSet::ObjectKey::get(obj);
key->hasStableClassAndProto(constraints);
LifoAlloc *alloc = GetJitContext()->temp->lifoAlloc();
return alloc->new_<types::TemporaryTypeSet>(alloc, types::Type::ObjectType(obj));
return alloc->new_<TemporaryTypeSet>(alloc, TypeSet::ObjectType(obj));
}
static types::TemporaryTypeSet *
static TemporaryTypeSet *
MakeUnknownTypeSet()
{
LifoAlloc *alloc = GetJitContext()->temp->lifoAlloc();
return alloc->new_<types::TemporaryTypeSet>(alloc, types::Type::UnknownType());
return alloc->new_<TemporaryTypeSet>(alloc, TypeSet::UnknownType());
}
MConstant::MConstant(const js::Value &vp, types::CompilerConstraintList *constraints)
MConstant::MConstant(const js::Value &vp, CompilerConstraintList *constraints)
: value_(vp)
{
setResultType(MIRTypeFromValue(vp));
@ -806,7 +806,7 @@ MConstant::canProduceFloat32() const
return true;
}
MNurseryObject::MNurseryObject(JSObject *obj, uint32_t index, types::CompilerConstraintList *constraints)
MNurseryObject::MNurseryObject(JSObject *obj, uint32_t index, CompilerConstraintList *constraints)
: index_(index)
{
setResultType(MIRType_Object);
@ -820,7 +820,7 @@ MNurseryObject::MNurseryObject(JSObject *obj, uint32_t index, types::CompilerCon
MNurseryObject *
MNurseryObject::New(TempAllocator &alloc, JSObject *obj, uint32_t index,
types::CompilerConstraintList *constraints)
CompilerConstraintList *constraints)
{
return new(alloc) MNurseryObject(obj, index, constraints);
}
@ -1107,7 +1107,7 @@ MMathFunction::foldsTo(TempAllocator &alloc)
}
MParameter *
MParameter::New(TempAllocator &alloc, int32_t index, types::TemporaryTypeSet *types)
MParameter::New(TempAllocator &alloc, int32_t index, TemporaryTypeSet *types)
{
return new(alloc) MParameter(index, types);
}
@ -1624,20 +1624,20 @@ MPhi::congruentTo(const MDefinition *ins) const
return congruentIfOperandsEqual(ins);
}
static inline types::TemporaryTypeSet *
static inline TemporaryTypeSet *
MakeMIRTypeSet(MIRType type)
{
MOZ_ASSERT(type != MIRType_Value);
types::Type ntype = type == MIRType_Object
? types::Type::AnyObjectType()
: types::Type::PrimitiveType(ValueTypeFromMIRType(type));
TypeSet::Type ntype = type == MIRType_Object
? TypeSet::AnyObjectType()
: TypeSet::PrimitiveType(ValueTypeFromMIRType(type));
LifoAlloc *alloc = GetJitContext()->temp->lifoAlloc();
return alloc->new_<types::TemporaryTypeSet>(alloc, ntype);
return alloc->new_<TemporaryTypeSet>(alloc, ntype);
}
bool
jit::MergeTypes(MIRType *ptype, types::TemporaryTypeSet **ptypeSet,
MIRType newType, types::TemporaryTypeSet *newTypeSet)
jit::MergeTypes(MIRType *ptype, TemporaryTypeSet **ptypeSet,
MIRType newType, TemporaryTypeSet *newTypeSet)
{
if (newTypeSet && newTypeSet->empty())
return true;
@ -1664,7 +1664,7 @@ jit::MergeTypes(MIRType *ptype, types::TemporaryTypeSet **ptypeSet,
}
if (newTypeSet) {
if (!newTypeSet->isSubset(*ptypeSet))
*ptypeSet = types::TypeSet::unionSets(*ptypeSet, newTypeSet, alloc);
*ptypeSet = TypeSet::unionSets(*ptypeSet, newTypeSet, alloc);
} else {
*ptypeSet = nullptr;
}
@ -1694,7 +1694,7 @@ MPhi::specializeType()
}
MIRType resultType = this->type();
types::TemporaryTypeSet *resultTypeSet = this->resultTypeSet();
TemporaryTypeSet *resultTypeSet = this->resultTypeSet();
for (size_t i = start; i < inputs_.length(); i++) {
MDefinition *def = getOperand(i);
@ -1708,13 +1708,13 @@ MPhi::specializeType()
}
bool
MPhi::addBackedgeType(MIRType type, types::TemporaryTypeSet *typeSet)
MPhi::addBackedgeType(MIRType type, TemporaryTypeSet *typeSet)
{
MOZ_ASSERT(!specialized_);
if (hasBackedgeType_) {
MIRType resultType = this->type();
types::TemporaryTypeSet *resultTypeSet = this->resultTypeSet();
TemporaryTypeSet *resultTypeSet = this->resultTypeSet();
if (!MergeTypes(&resultType, &resultTypeSet, type, typeSet))
return false;
@ -1735,7 +1735,7 @@ MPhi::typeIncludes(MDefinition *def)
if (def->type() == MIRType_Int32 && this->type() == MIRType_Double)
return true;
if (types::TemporaryTypeSet *types = def->resultTypeSet()) {
if (TemporaryTypeSet *types = def->resultTypeSet()) {
if (this->resultTypeSet())
return types->isSubset(this->resultTypeSet());
if (this->type() == MIRType_Value || types->empty())
@ -1756,7 +1756,7 @@ bool
MPhi::checkForTypeChange(MDefinition *ins, bool *ptypeChange)
{
MIRType resultType = this->type();
types::TemporaryTypeSet *resultTypeSet = this->resultTypeSet();
TemporaryTypeSet *resultTypeSet = this->resultTypeSet();
if (!MergeTypes(&resultType, &resultTypeSet, ins->type(), ins->resultTypeSet()))
return false;
@ -2468,7 +2468,7 @@ MBinaryArithInstruction::inferFallback(BaselineInspector *inspector,
// either to avoid degrading subsequent analysis.
if (getOperand(0)->emptyResultTypeSet() || getOperand(1)->emptyResultTypeSet()) {
LifoAlloc *alloc = GetJitContext()->temp->lifoAlloc();
types::TemporaryTypeSet *types = alloc->new_<types::TemporaryTypeSet>();
TemporaryTypeSet *types = alloc->new_<TemporaryTypeSet>();
if (types)
setResultTypeSet(types);
}
@ -2496,7 +2496,7 @@ ObjectOrSimplePrimitive(MDefinition *op)
}
static bool
CanDoValueBitwiseCmp(types::CompilerConstraintList *constraints,
CanDoValueBitwiseCmp(CompilerConstraintList *constraints,
MDefinition *lhs, MDefinition *rhs, bool looseEq)
{
// Only primitive (not double/string) or objects are supported.
@ -2619,7 +2619,7 @@ MBinaryInstruction::tryUseUnsignedOperands()
}
void
MCompare::infer(types::CompilerConstraintList *constraints, BaselineInspector *inspector, jsbytecode *pc)
MCompare::infer(CompilerConstraintList *constraints, BaselineInspector *inspector, jsbytecode *pc)
{
MOZ_ASSERT(operandMightEmulateUndefined());
@ -2827,7 +2827,7 @@ MTypeOf::foldsTo(TempAllocator &alloc)
}
void
MTypeOf::cacheInputMaybeCallableOrEmulatesUndefined(types::CompilerConstraintList *constraints)
MTypeOf::cacheInputMaybeCallableOrEmulatesUndefined(CompilerConstraintList *constraints)
{
MOZ_ASSERT(inputMaybeCallableOrEmulatesUndefined());
@ -3568,7 +3568,7 @@ MCompare::filtersUndefinedOrNull(bool trueBranch, MDefinition **subject, bool *f
}
void
MNot::cacheOperandMightEmulateUndefined(types::CompilerConstraintList *constraints)
MNot::cacheOperandMightEmulateUndefined(CompilerConstraintList *constraints)
{
MOZ_ASSERT(operandMightEmulateUndefined());
@ -4030,16 +4030,16 @@ InlinePropertyTable::hasFunction(JSFunction *func) const
return false;
}
types::TemporaryTypeSet *
TemporaryTypeSet *
InlinePropertyTable::buildTypeSetForFunction(JSFunction *func) const
{
LifoAlloc *alloc = GetJitContext()->temp->lifoAlloc();
types::TemporaryTypeSet *types = alloc->new_<types::TemporaryTypeSet>();
TemporaryTypeSet *types = alloc->new_<TemporaryTypeSet>();
if (!types)
return nullptr;
for (size_t i = 0; i < numEntries(); i++) {
if (entries_[i]->func == func)
types->addType(types::Type::ObjectType(entries_[i]->group), alloc);
types->addType(TypeSet::ObjectType(entries_[i]->group), alloc);
}
return types;
}
@ -4085,7 +4085,7 @@ MGetElementCache::allowDoubleResult() const
if (!resultTypeSet())
return true;
return resultTypeSet()->hasType(types::Type::DoubleType());
return resultTypeSet()->hasType(TypeSet::DoubleType());
}
size_t
@ -4277,7 +4277,7 @@ MArrayJoin::foldsTo(TempAllocator &alloc) {
}
bool
jit::ElementAccessIsDenseNative(types::CompilerConstraintList *constraints,
jit::ElementAccessIsDenseNative(CompilerConstraintList *constraints,
MDefinition *obj, MDefinition *id)
{
if (obj->mightBeType(MIRType_String))
@ -4286,7 +4286,7 @@ jit::ElementAccessIsDenseNative(types::CompilerConstraintList *constraints,
if (id->type() != MIRType_Int32 && id->type() != MIRType_Double)
return false;
types::TemporaryTypeSet *types = obj->resultTypeSet();
TemporaryTypeSet *types = obj->resultTypeSet();
if (!types)
return false;
@ -4296,7 +4296,7 @@ jit::ElementAccessIsDenseNative(types::CompilerConstraintList *constraints,
}
bool
jit::ElementAccessIsAnyTypedArray(types::CompilerConstraintList *constraints,
jit::ElementAccessIsAnyTypedArray(CompilerConstraintList *constraints,
MDefinition *obj, MDefinition *id,
Scalar::Type *arrayType)
{
@ -4306,7 +4306,7 @@ jit::ElementAccessIsAnyTypedArray(types::CompilerConstraintList *constraints,
if (id->type() != MIRType_Int32 && id->type() != MIRType_Double)
return false;
types::TemporaryTypeSet *types = obj->resultTypeSet();
TemporaryTypeSet *types = obj->resultTypeSet();
if (!types)
return false;
@ -4318,47 +4318,47 @@ jit::ElementAccessIsAnyTypedArray(types::CompilerConstraintList *constraints,
}
bool
jit::ElementAccessIsPacked(types::CompilerConstraintList *constraints, MDefinition *obj)
jit::ElementAccessIsPacked(CompilerConstraintList *constraints, MDefinition *obj)
{
types::TemporaryTypeSet *types = obj->resultTypeSet();
TemporaryTypeSet *types = obj->resultTypeSet();
return types && !types->hasObjectFlags(constraints, OBJECT_FLAG_NON_PACKED);
}
bool
jit::ElementAccessMightBeCopyOnWrite(types::CompilerConstraintList *constraints, MDefinition *obj)
jit::ElementAccessMightBeCopyOnWrite(CompilerConstraintList *constraints, MDefinition *obj)
{
types::TemporaryTypeSet *types = obj->resultTypeSet();
TemporaryTypeSet *types = obj->resultTypeSet();
return !types || types->hasObjectFlags(constraints, OBJECT_FLAG_COPY_ON_WRITE);
}
bool
jit::ElementAccessHasExtraIndexedProperty(types::CompilerConstraintList *constraints,
jit::ElementAccessHasExtraIndexedProperty(CompilerConstraintList *constraints,
MDefinition *obj)
{
types::TemporaryTypeSet *types = obj->resultTypeSet();
TemporaryTypeSet *types = obj->resultTypeSet();
if (!types || types->hasObjectFlags(constraints, OBJECT_FLAG_LENGTH_OVERFLOW))
return true;
return types::TypeCanHaveExtraIndexedProperties(constraints, types);
return TypeCanHaveExtraIndexedProperties(constraints, types);
}
MIRType
jit::DenseNativeElementType(types::CompilerConstraintList *constraints, MDefinition *obj)
jit::DenseNativeElementType(CompilerConstraintList *constraints, MDefinition *obj)
{
types::TemporaryTypeSet *types = obj->resultTypeSet();
TemporaryTypeSet *types = obj->resultTypeSet();
MIRType elementType = MIRType_None;
unsigned count = types->getObjectCount();
for (unsigned i = 0; i < count; i++) {
types::TypeSetObjectKey *key = types->getObject(i);
TypeSet::ObjectKey *key = types->getObject(i);
if (!key)
continue;
if (key->unknownProperties())
return MIRType_None;
types::HeapTypeSetKey elementTypes = key->property(JSID_VOID);
HeapTypeSetKey elementTypes = key->property(JSID_VOID);
MIRType type = elementTypes.knownMIRType(constraints);
if (type == MIRType_None)
@ -4374,9 +4374,9 @@ jit::DenseNativeElementType(types::CompilerConstraintList *constraints, MDefinit
}
static BarrierKind
PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints,
types::TypeSetObjectKey *key, PropertyName *name,
types::TypeSet *observed)
PropertyReadNeedsTypeBarrier(CompilerConstraintList *constraints,
TypeSet::ObjectKey *key, PropertyName *name,
TypeSet *observed)
{
// If the object being read from has types for the property which haven't
// been observed at this access site, the read could produce a new type and
@ -4393,7 +4393,7 @@ PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints,
}
jsid id = name ? NameToId(name) : JSID_VOID;
types::HeapTypeSetKey property = key->property(id);
HeapTypeSetKey property = key->property(id);
if (property.maybeTypes()) {
if (!TypeSetIncludes(observed, MIRType_Value, property.maybeTypes())) {
// If all possible objects have been observed, we don't have to
@ -4412,7 +4412,7 @@ PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints,
// other than undefined, a barrier is required.
if (key->isSingleton()) {
JSObject *obj = key->singleton();
if (name && types::CanHaveEmptyPropertyTypesForOwnProperty(obj) &&
if (name && CanHaveEmptyPropertyTypesForOwnProperty(obj) &&
(!property.maybeTypes() || property.maybeTypes()->empty()))
{
return BarrierKind::TypeSet;
@ -4425,9 +4425,9 @@ PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints,
BarrierKind
jit::PropertyReadNeedsTypeBarrier(JSContext *propertycx,
types::CompilerConstraintList *constraints,
types::TypeSetObjectKey *key, PropertyName *name,
types::TemporaryTypeSet *observed, bool updateObserved)
CompilerConstraintList *constraints,
TypeSet::ObjectKey *key, PropertyName *name,
TemporaryTypeSet *observed, bool updateObserved)
{
// If this access has never executed, try to add types to the observed set
// according to any property which exists on the object or its prototype.
@ -4442,14 +4442,14 @@ jit::PropertyReadNeedsTypeBarrier(JSContext *propertycx,
if (!obj->getClass()->isNative())
break;
types::TypeSetObjectKey *key = types::TypeSetObjectKey::get(obj);
TypeSet::ObjectKey *key = TypeSet::ObjectKey::get(obj);
if (propertycx)
key->ensureTrackedProperty(propertycx, NameToId(name));
if (!key->unknownProperties()) {
types::HeapTypeSetKey property = key->property(NameToId(name));
HeapTypeSetKey property = key->property(NameToId(name));
if (property.maybeTypes()) {
types::TypeSet::TypeList types;
TypeSet::TypeList types;
if (!property.maybeTypes()->enumerateTypes(&types))
break;
if (types.length()) {
@ -4469,14 +4469,14 @@ jit::PropertyReadNeedsTypeBarrier(JSContext *propertycx,
BarrierKind
jit::PropertyReadNeedsTypeBarrier(JSContext *propertycx,
types::CompilerConstraintList *constraints,
CompilerConstraintList *constraints,
MDefinition *obj, PropertyName *name,
types::TemporaryTypeSet *observed)
TemporaryTypeSet *observed)
{
if (observed->unknown())
return BarrierKind::NoBarrier;
types::TypeSet *types = obj->resultTypeSet();
TypeSet *types = obj->resultTypeSet();
if (!types || types->unknownObject())
return BarrierKind::TypeSet;
@ -4484,8 +4484,7 @@ jit::PropertyReadNeedsTypeBarrier(JSContext *propertycx,
bool updateObserved = types->getObjectCount() == 1;
for (size_t i = 0; i < types->getObjectCount(); i++) {
types::TypeSetObjectKey *key = types->getObject(i);
if (key) {
if (TypeSet::ObjectKey *key = types->getObject(i)) {
BarrierKind kind = PropertyReadNeedsTypeBarrier(propertycx, constraints, key, name,
observed, updateObserved);
if (kind == BarrierKind::TypeSet)
@ -4504,21 +4503,21 @@ jit::PropertyReadNeedsTypeBarrier(JSContext *propertycx,
}
BarrierKind
jit::PropertyReadOnPrototypeNeedsTypeBarrier(types::CompilerConstraintList *constraints,
jit::PropertyReadOnPrototypeNeedsTypeBarrier(CompilerConstraintList *constraints,
MDefinition *obj, PropertyName *name,
types::TemporaryTypeSet *observed)
TemporaryTypeSet *observed)
{
if (observed->unknown())
return BarrierKind::NoBarrier;
types::TypeSet *types = obj->resultTypeSet();
TypeSet *types = obj->resultTypeSet();
if (!types || types->unknownObject())
return BarrierKind::TypeSet;
BarrierKind res = BarrierKind::NoBarrier;
for (size_t i = 0; i < types->getObjectCount(); i++) {
types::TypeSetObjectKey *key = types->getObject(i);
TypeSet::ObjectKey *key = types->getObject(i);
if (!key)
continue;
while (true) {
@ -4526,7 +4525,7 @@ jit::PropertyReadOnPrototypeNeedsTypeBarrier(types::CompilerConstraintList *cons
return BarrierKind::TypeSet;
if (!key->proto().isObject())
break;
key = types::TypeSetObjectKey::get(key->proto().toObject());
key = TypeSet::ObjectKey::get(key->proto().toObject());
BarrierKind kind = PropertyReadNeedsTypeBarrier(constraints, key, name, observed);
if (kind == BarrierKind::TypeSet)
return BarrierKind::TypeSet;
@ -4544,23 +4543,22 @@ jit::PropertyReadOnPrototypeNeedsTypeBarrier(types::CompilerConstraintList *cons
}
bool
jit::PropertyReadIsIdempotent(types::CompilerConstraintList *constraints,
jit::PropertyReadIsIdempotent(CompilerConstraintList *constraints,
MDefinition *obj, PropertyName *name)
{
// Determine if reading a property from obj is likely to be idempotent.
types::TypeSet *types = obj->resultTypeSet();
TypeSet *types = obj->resultTypeSet();
if (!types || types->unknownObject())
return false;
for (size_t i = 0; i < types->getObjectCount(); i++) {
types::TypeSetObjectKey *key = types->getObject(i);
if (key) {
if (TypeSet::ObjectKey *key = types->getObject(i)) {
if (key->unknownProperties())
return false;
// Check if the property has been reconfigured or is a getter.
types::HeapTypeSetKey property = key->property(NameToId(name));
HeapTypeSetKey property = key->property(NameToId(name));
if (property.nonData(constraints))
return false;
}
@ -4571,62 +4569,61 @@ jit::PropertyReadIsIdempotent(types::CompilerConstraintList *constraints,
void
jit::AddObjectsForPropertyRead(MDefinition *obj, PropertyName *name,
types::TemporaryTypeSet *observed)
TemporaryTypeSet *observed)
{
// Add objects to observed which *could* be observed by reading name from obj,
// to hopefully avoid unnecessary type barriers and code invalidations.
LifoAlloc *alloc = GetJitContext()->temp->lifoAlloc();
types::TemporaryTypeSet *types = obj->resultTypeSet();
TemporaryTypeSet *types = obj->resultTypeSet();
if (!types || types->unknownObject()) {
observed->addType(types::Type::AnyObjectType(), alloc);
observed->addType(TypeSet::AnyObjectType(), alloc);
return;
}
for (size_t i = 0; i < types->getObjectCount(); i++) {
types::TypeSetObjectKey *key = types->getObject(i);
TypeSet::ObjectKey *key = types->getObject(i);
if (!key)
continue;
if (key->unknownProperties()) {
observed->addType(types::Type::AnyObjectType(), alloc);
observed->addType(TypeSet::AnyObjectType(), alloc);
return;
}
jsid id = name ? NameToId(name) : JSID_VOID;
types::HeapTypeSetKey property = key->property(id);
types::HeapTypeSet *types = property.maybeTypes();
HeapTypeSetKey property = key->property(id);
HeapTypeSet *types = property.maybeTypes();
if (!types)
continue;
if (types->unknownObject()) {
observed->addType(types::Type::AnyObjectType(), alloc);
observed->addType(TypeSet::AnyObjectType(), alloc);
return;
}
for (size_t i = 0; i < types->getObjectCount(); i++) {
types::TypeSetObjectKey *key = types->getObject(i);
if (key)
observed->addType(types::Type::ObjectType(key), alloc);
if (TypeSet::ObjectKey *key = types->getObject(i))
observed->addType(TypeSet::ObjectType(key), alloc);
}
}
}
static bool
PropertyTypeIncludes(TempAllocator &alloc, types::HeapTypeSetKey property,
PropertyTypeIncludes(TempAllocator &alloc, HeapTypeSetKey property,
MDefinition *value, MIRType implicitType)
{
// If implicitType is not MIRType_None, it is an additional type which the
// property implicitly includes. In this case, make a new type set which
// explicitly contains the type.
types::TypeSet *types = property.maybeTypes();
TypeSet *types = property.maybeTypes();
if (implicitType != MIRType_None) {
types::Type newType = types::Type::PrimitiveType(ValueTypeFromMIRType(implicitType));
TypeSet::Type newType = TypeSet::PrimitiveType(ValueTypeFromMIRType(implicitType));
if (types)
types = types->clone(alloc.lifoAlloc());
else
types = alloc.lifoAlloc()->new_<types::TemporaryTypeSet>();
types = alloc.lifoAlloc()->new_<TemporaryTypeSet>();
types->addType(newType, alloc.lifoAlloc());
}
@ -4634,8 +4631,8 @@ PropertyTypeIncludes(TempAllocator &alloc, types::HeapTypeSetKey property,
}
static bool
TryAddTypeBarrierForWrite(TempAllocator &alloc, types::CompilerConstraintList *constraints,
MBasicBlock *current, types::TemporaryTypeSet *objTypes,
TryAddTypeBarrierForWrite(TempAllocator &alloc, CompilerConstraintList *constraints,
MBasicBlock *current, TemporaryTypeSet *objTypes,
PropertyName *name, MDefinition **pvalue, MIRType implicitType)
{
// Return whether pvalue was modified to include a type barrier ensuring
@ -4645,10 +4642,10 @@ TryAddTypeBarrierForWrite(TempAllocator &alloc, types::CompilerConstraintList *c
// All objects in the set must have the same types for name. Otherwise, we
// could bail out without subsequently triggering a type change that
// invalidates the compiled code.
Maybe<types::HeapTypeSetKey> aggregateProperty;
Maybe<HeapTypeSetKey> aggregateProperty;
for (size_t i = 0; i < objTypes->getObjectCount(); i++) {
types::TypeSetObjectKey *key = objTypes->getObject(i);
TypeSet::ObjectKey *key = objTypes->getObject(i);
if (!key)
continue;
@ -4656,7 +4653,7 @@ TryAddTypeBarrierForWrite(TempAllocator &alloc, types::CompilerConstraintList *c
return false;
jsid id = name ? NameToId(name) : JSID_VOID;
types::HeapTypeSetKey property = key->property(id);
HeapTypeSetKey property = key->property(id);
if (!property.maybeTypes() || property.couldBeConstant(constraints))
return false;
@ -4704,7 +4701,7 @@ TryAddTypeBarrierForWrite(TempAllocator &alloc, types::CompilerConstraintList *c
if ((*pvalue)->type() != MIRType_Value)
return false;
types::TemporaryTypeSet *types = aggregateProperty->maybeTypes()->clone(alloc.lifoAlloc());
TemporaryTypeSet *types = aggregateProperty->maybeTypes()->clone(alloc.lifoAlloc());
if (!types)
return false;
@ -4721,7 +4718,7 @@ TryAddTypeBarrierForWrite(TempAllocator &alloc, types::CompilerConstraintList *c
static MInstruction *
AddGroupGuard(TempAllocator &alloc, MBasicBlock *current, MDefinition *obj,
types::TypeSetObjectKey *key, bool bailOnEquality)
TypeSet::ObjectKey *key, bool bailOnEquality)
{
MInstruction *guard;
@ -4742,8 +4739,8 @@ AddGroupGuard(TempAllocator &alloc, MBasicBlock *current, MDefinition *obj,
// Whether value can be written to property without changing type information.
bool
jit::CanWriteProperty(TempAllocator &alloc, types::CompilerConstraintList *constraints,
types::HeapTypeSetKey property, MDefinition *value,
jit::CanWriteProperty(TempAllocator &alloc, CompilerConstraintList *constraints,
HeapTypeSetKey property, MDefinition *value,
MIRType implicitType /* = MIRType_None */)
{
if (property.couldBeConstant(constraints))
@ -4752,7 +4749,7 @@ jit::CanWriteProperty(TempAllocator &alloc, types::CompilerConstraintList *const
}
bool
jit::PropertyWriteNeedsTypeBarrier(TempAllocator &alloc, types::CompilerConstraintList *constraints,
jit::PropertyWriteNeedsTypeBarrier(TempAllocator &alloc, CompilerConstraintList *constraints,
MBasicBlock *current, MDefinition **pobj,
PropertyName *name, MDefinition **pvalue,
bool canModify, MIRType implicitType)
@ -4763,7 +4760,7 @@ jit::PropertyWriteNeedsTypeBarrier(TempAllocator &alloc, types::CompilerConstrai
// properties that are accounted for by type information, i.e. normal data
// properties and elements.
types::TemporaryTypeSet *types = (*pobj)->resultTypeSet();
TemporaryTypeSet *types = (*pobj)->resultTypeSet();
if (!types || types->unknownObject())
return true;
@ -4774,7 +4771,7 @@ jit::PropertyWriteNeedsTypeBarrier(TempAllocator &alloc, types::CompilerConstrai
bool success = true;
for (size_t i = 0; i < types->getObjectCount(); i++) {
types::TypeSetObjectKey *key = types->getObject(i);
TypeSet::ObjectKey *key = types->getObject(i);
if (!key || key->unknownProperties())
continue;
@ -4784,7 +4781,7 @@ jit::PropertyWriteNeedsTypeBarrier(TempAllocator &alloc, types::CompilerConstrai
continue;
jsid id = name ? NameToId(name) : JSID_VOID;
types::HeapTypeSetKey property = key->property(id);
HeapTypeSetKey property = key->property(id);
if (!CanWriteProperty(alloc, constraints, property, *pvalue, implicitType)) {
// Either pobj or pvalue needs to be modified to filter out the
// types which the value could have but are not in the property,
@ -4808,16 +4805,16 @@ jit::PropertyWriteNeedsTypeBarrier(TempAllocator &alloc, types::CompilerConstrai
if (types->getObjectCount() <= 1)
return true;
types::TypeSetObjectKey *excluded = nullptr;
TypeSet::ObjectKey *excluded = nullptr;
for (size_t i = 0; i < types->getObjectCount(); i++) {
types::TypeSetObjectKey *key = types->getObject(i);
TypeSet::ObjectKey *key = types->getObject(i);
if (!key || key->unknownProperties())
continue;
if (!name && IsAnyTypedArrayClass(key->clasp()))
continue;
jsid id = name ? NameToId(name) : JSID_VOID;
types::HeapTypeSetKey property = key->property(id);
HeapTypeSetKey property = key->property(id);
if (CanWriteProperty(alloc, constraints, property, *pvalue, implicitType))
continue;

View File

@ -363,7 +363,7 @@ class MDefinition : public MNode
uint32_t flags_; // Bit flags.
Range *range_; // Any computed range for this def.
MIRType resultType_; // Representation of result type.
types::TemporaryTypeSet *resultTypeSet_; // Optional refinement of the result type.
TemporaryTypeSet *resultTypeSet_; // Optional refinement of the result type.
union {
MInstruction *dependency_; // Implicit dependency (store, call, etc.) of this instruction.
// Used by alias analysis, GVN and LICM.
@ -608,7 +608,7 @@ class MDefinition : public MNode
return resultType_;
}
types::TemporaryTypeSet *resultTypeSet() const {
TemporaryTypeSet *resultTypeSet() const {
return resultTypeSet_;
}
bool emptyResultTypeSet() const;
@ -781,7 +781,7 @@ class MDefinition : public MNode
void setResultType(MIRType type) {
resultType_ = type;
}
void setResultTypeSet(types::TemporaryTypeSet *types) {
void setResultTypeSet(TemporaryTypeSet *types) {
resultTypeSet_ = types;
}
@ -1277,15 +1277,15 @@ class MConstant : public MNullaryInstruction
Value value_;
protected:
MConstant(const Value &v, types::CompilerConstraintList *constraints);
MConstant(const Value &v, CompilerConstraintList *constraints);
explicit MConstant(JSObject *obj);
public:
INSTRUCTION_HEADER(Constant)
static MConstant *New(TempAllocator &alloc, const Value &v,
types::CompilerConstraintList *constraints = nullptr);
CompilerConstraintList *constraints = nullptr);
static MConstant *NewTypedValue(TempAllocator &alloc, const Value &v, MIRType type,
types::CompilerConstraintList *constraints = nullptr);
CompilerConstraintList *constraints = nullptr);
static MConstant *NewAsmJS(TempAllocator &alloc, const Value &v, MIRType type);
static MConstant *NewConstraintlessObject(TempAllocator &alloc, JSObject *v);
@ -1335,12 +1335,12 @@ class MNurseryObject : public MNullaryInstruction
uint32_t index_;
protected:
MNurseryObject(JSObject *obj, uint32_t index, types::CompilerConstraintList *constraints);
MNurseryObject(JSObject *obj, uint32_t index, CompilerConstraintList *constraints);
public:
INSTRUCTION_HEADER(NurseryObject)
static MNurseryObject *New(TempAllocator &alloc, JSObject *obj, uint32_t index,
types::CompilerConstraintList *constraints = nullptr);
CompilerConstraintList *constraints = nullptr);
HashNumber valueHash() const MOZ_OVERRIDE;
bool congruentTo(const MDefinition *ins) const MOZ_OVERRIDE;
@ -2197,7 +2197,7 @@ class MParameter : public MNullaryInstruction
public:
static const int32_t THIS_SLOT = -1;
MParameter(int32_t index, types::TemporaryTypeSet *types)
MParameter(int32_t index, TemporaryTypeSet *types)
: index_(index)
{
setResultType(MIRType_Value);
@ -2206,7 +2206,7 @@ class MParameter : public MNullaryInstruction
public:
INSTRUCTION_HEADER(Parameter)
static MParameter *New(TempAllocator &alloc, int32_t index, types::TemporaryTypeSet *types);
static MParameter *New(TempAllocator &alloc, int32_t index, TemporaryTypeSet *types);
int32_t index() const {
return index_;
@ -2540,7 +2540,7 @@ class MTest
// background threads. So make callers explicitly call it if they want us
// to check whether the operand might do this. If this method is never
// called, we'll assume our operand can emulate undefined.
void cacheOperandMightEmulateUndefined(types::CompilerConstraintList *constraints);
void cacheOperandMightEmulateUndefined(CompilerConstraintList *constraints);
MDefinition *foldsTo(TempAllocator &alloc) MOZ_OVERRIDE;
void filtersUndefinedOrNull(bool trueBranch, MDefinition **subject, bool *filtersUndefined,
bool *filtersNull);
@ -2632,12 +2632,12 @@ class MThrow
};
// Fabricate a type set containing only the type of the specified object.
types::TemporaryTypeSet *
MakeSingletonTypeSet(types::CompilerConstraintList *constraints, JSObject *obj);
TemporaryTypeSet *
MakeSingletonTypeSet(CompilerConstraintList *constraints, JSObject *obj);
bool
MergeTypes(MIRType *ptype, types::TemporaryTypeSet **ptypeSet,
MIRType newType, types::TemporaryTypeSet *newTypeSet);
MergeTypes(MIRType *ptype, TemporaryTypeSet **ptypeSet,
MIRType newType, TemporaryTypeSet *newTypeSet);
// Helper class to assert all GC pointers embedded in MIR instructions are
// tenured. Off-thread Ion compilation and nursery GCs can happen in parallel,
@ -2689,7 +2689,7 @@ class MNewArray
// Allocate space at initialization or not
AllocatingBehaviour allocating_;
MNewArray(types::CompilerConstraintList *constraints, uint32_t count, MConstant *templateConst,
MNewArray(CompilerConstraintList *constraints, uint32_t count, MConstant *templateConst,
gc::InitialHeap initialHeap, AllocatingBehaviour allocating)
: MUnaryInstruction(templateConst),
count_(count),
@ -2705,7 +2705,7 @@ class MNewArray
public:
INSTRUCTION_HEADER(NewArray)
static MNewArray *New(TempAllocator &alloc, types::CompilerConstraintList *constraints,
static MNewArray *New(TempAllocator &alloc, CompilerConstraintList *constraints,
uint32_t count, MConstant *templateConst,
gc::InitialHeap initialHeap, AllocatingBehaviour allocating)
{
@ -2755,7 +2755,7 @@ class MNewArrayCopyOnWrite : public MNullaryInstruction
AlwaysTenured<ArrayObject*> templateObject_;
gc::InitialHeap initialHeap_;
MNewArrayCopyOnWrite(types::CompilerConstraintList *constraints, ArrayObject *templateObject,
MNewArrayCopyOnWrite(CompilerConstraintList *constraints, ArrayObject *templateObject,
gc::InitialHeap initialHeap)
: templateObject_(templateObject),
initialHeap_(initialHeap)
@ -2769,7 +2769,7 @@ class MNewArrayCopyOnWrite : public MNullaryInstruction
INSTRUCTION_HEADER(NewArrayCopyOnWrite)
static MNewArrayCopyOnWrite *New(TempAllocator &alloc,
types::CompilerConstraintList *constraints,
CompilerConstraintList *constraints,
ArrayObject *templateObject,
gc::InitialHeap initialHeap)
{
@ -2796,7 +2796,7 @@ class MNewArrayDynamicLength
AlwaysTenured<ArrayObject*> templateObject_;
gc::InitialHeap initialHeap_;
MNewArrayDynamicLength(types::CompilerConstraintList *constraints, ArrayObject *templateObject,
MNewArrayDynamicLength(CompilerConstraintList *constraints, ArrayObject *templateObject,
gc::InitialHeap initialHeap, MDefinition *length)
: MUnaryInstruction(length),
templateObject_(templateObject),
@ -2811,7 +2811,7 @@ class MNewArrayDynamicLength
public:
INSTRUCTION_HEADER(NewArrayDynamicLength)
static MNewArrayDynamicLength *New(TempAllocator &alloc, types::CompilerConstraintList *constraints,
static MNewArrayDynamicLength *New(TempAllocator &alloc, CompilerConstraintList *constraints,
ArrayObject *templateObject, gc::InitialHeap initialHeap,
MDefinition *length)
{
@ -2844,7 +2844,7 @@ class MNewObject
gc::InitialHeap initialHeap_;
Mode mode_;
MNewObject(types::CompilerConstraintList *constraints, MConstant *templateConst,
MNewObject(CompilerConstraintList *constraints, MConstant *templateConst,
gc::InitialHeap initialHeap, Mode mode)
: MUnaryInstruction(templateConst),
initialHeap_(initialHeap),
@ -2867,7 +2867,7 @@ class MNewObject
public:
INSTRUCTION_HEADER(NewObject)
static MNewObject *New(TempAllocator &alloc, types::CompilerConstraintList *constraints,
static MNewObject *New(TempAllocator &alloc, CompilerConstraintList *constraints,
MConstant *templateConst, gc::InitialHeap initialHeap,
Mode mode)
{
@ -2903,7 +2903,7 @@ class MNewTypedObject : public MNullaryInstruction
AlwaysTenured<InlineTypedObject *> templateObject_;
gc::InitialHeap initialHeap_;
MNewTypedObject(types::CompilerConstraintList *constraints,
MNewTypedObject(CompilerConstraintList *constraints,
InlineTypedObject *templateObject,
gc::InitialHeap initialHeap)
: templateObject_(templateObject),
@ -2917,7 +2917,7 @@ class MNewTypedObject : public MNullaryInstruction
INSTRUCTION_HEADER(NewTypedObject)
static MNewTypedObject *New(TempAllocator &alloc,
types::CompilerConstraintList *constraints,
CompilerConstraintList *constraints,
InlineTypedObject *templateObject,
gc::InitialHeap initialHeap)
{
@ -2978,7 +2978,7 @@ class MSimdBox
AlwaysTenured<InlineTypedObject *> templateObject_;
gc::InitialHeap initialHeap_;
MSimdBox(types::CompilerConstraintList *constraints,
MSimdBox(CompilerConstraintList *constraints,
MDefinition *op,
InlineTypedObject *templateObject,
gc::InitialHeap initialHeap)
@ -2996,7 +2996,7 @@ class MSimdBox
INSTRUCTION_HEADER(SimdBox)
static MSimdBox *New(TempAllocator &alloc,
types::CompilerConstraintList *constraints,
CompilerConstraintList *constraints,
MDefinition *op,
InlineTypedObject *templateObject,
gc::InitialHeap initialHeap)
@ -3910,7 +3910,7 @@ class MCompare
void filtersUndefinedOrNull(bool trueBranch, MDefinition **subject, bool *filtersUndefined,
bool *filtersNull);
void infer(types::CompilerConstraintList *constraints,
void infer(CompilerConstraintList *constraints,
BaselineInspector *inspector, jsbytecode *pc);
CompareType compareType() const {
return compareType_;
@ -4002,10 +4002,10 @@ class MBox
if (ins->resultTypeSet()) {
setResultTypeSet(ins->resultTypeSet());
} else if (ins->type() != MIRType_Value) {
types::Type ntype = ins->type() == MIRType_Object
? types::Type::AnyObjectType()
: types::Type::PrimitiveType(ValueTypeFromMIRType(ins->type()));
setResultTypeSet(alloc.lifoAlloc()->new_<types::TemporaryTypeSet>(alloc.lifoAlloc(), ntype));
TypeSet::Type ntype = ins->type() == MIRType_Object
? TypeSet::AnyObjectType()
: TypeSet::PrimitiveType(ValueTypeFromMIRType(ins->type()));
setResultTypeSet(alloc.lifoAlloc()->new_<TemporaryTypeSet>(alloc.lifoAlloc(), ntype));
}
setMovable();
}
@ -4261,7 +4261,7 @@ class MCreateThisWithTemplate
{
gc::InitialHeap initialHeap_;
MCreateThisWithTemplate(types::CompilerConstraintList *constraints, MConstant *templateConst,
MCreateThisWithTemplate(CompilerConstraintList *constraints, MConstant *templateConst,
gc::InitialHeap initialHeap)
: MUnaryInstruction(templateConst),
initialHeap_(initialHeap)
@ -4272,7 +4272,7 @@ class MCreateThisWithTemplate
public:
INSTRUCTION_HEADER(CreateThisWithTemplate)
static MCreateThisWithTemplate *New(TempAllocator &alloc, types::CompilerConstraintList *constraints,
static MCreateThisWithTemplate *New(TempAllocator &alloc, CompilerConstraintList *constraints,
MConstant *templateConst, gc::InitialHeap initialHeap)
{
return new(alloc) MCreateThisWithTemplate(constraints, templateConst, initialHeap);
@ -4971,7 +4971,7 @@ class MTypeOf
}
MDefinition *foldsTo(TempAllocator &alloc) MOZ_OVERRIDE;
void cacheInputMaybeCallableOrEmulatesUndefined(types::CompilerConstraintList *constraints);
void cacheInputMaybeCallableOrEmulatesUndefined(CompilerConstraintList *constraints);
bool inputMaybeCallableOrEmulatesUndefined() const {
return inputMaybeCallableOrEmulatesUndefined_;
@ -6293,7 +6293,7 @@ class MStringSplit
: public MTernaryInstruction,
public MixPolicy<StringPolicy<0>, StringPolicy<1> >::Data
{
MStringSplit(types::CompilerConstraintList *constraints, MDefinition *string, MDefinition *sep,
MStringSplit(CompilerConstraintList *constraints, MDefinition *string, MDefinition *sep,
MConstant *templateObject)
: MTernaryInstruction(string, sep, templateObject)
{
@ -6304,7 +6304,7 @@ class MStringSplit
public:
INSTRUCTION_HEADER(StringSplit)
static MStringSplit *New(TempAllocator &alloc, types::CompilerConstraintList *constraints,
static MStringSplit *New(TempAllocator &alloc, CompilerConstraintList *constraints,
MDefinition *string, MDefinition *sep,
MConstant *templateObject)
{
@ -6504,7 +6504,7 @@ class MPhi MOZ_FINAL
// Add types for this phi which speculate about new inputs that may come in
// via a loop backedge.
bool addBackedgeType(MIRType type, types::TemporaryTypeSet *typeSet);
bool addBackedgeType(MIRType type, TemporaryTypeSet *typeSet);
// Initializes the operands vector to the given capacity,
// permitting use of addInput() instead of addInputSlow().
@ -6904,7 +6904,7 @@ class MRegExp : public MNullaryInstruction
AlwaysTenured<RegExpObject *> source_;
bool mustClone_;
MRegExp(types::CompilerConstraintList *constraints, RegExpObject *source, bool mustClone)
MRegExp(CompilerConstraintList *constraints, RegExpObject *source, bool mustClone)
: source_(source),
mustClone_(mustClone)
{
@ -6915,7 +6915,7 @@ class MRegExp : public MNullaryInstruction
public:
INSTRUCTION_HEADER(RegExp)
static MRegExp *New(TempAllocator &alloc, types::CompilerConstraintList *constraints,
static MRegExp *New(TempAllocator &alloc, CompilerConstraintList *constraints,
RegExpObject *source, bool mustClone)
{
return new(alloc) MRegExp(constraints, source, mustClone);
@ -7183,7 +7183,7 @@ class MLambda
{
LambdaFunctionInfo info_;
MLambda(types::CompilerConstraintList *constraints, MDefinition *scopeChain, MConstant *cst)
MLambda(CompilerConstraintList *constraints, MDefinition *scopeChain, MConstant *cst)
: MBinaryInstruction(scopeChain, cst), info_(&cst->value().toObject().as<JSFunction>())
{
setResultType(MIRType_Object);
@ -7194,7 +7194,7 @@ class MLambda
public:
INSTRUCTION_HEADER(Lambda)
static MLambda *New(TempAllocator &alloc, types::CompilerConstraintList *constraints,
static MLambda *New(TempAllocator &alloc, CompilerConstraintList *constraints,
MDefinition *scopeChain, MConstant *fun)
{
return new(alloc) MLambda(constraints, scopeChain, fun);
@ -7220,7 +7220,7 @@ class MLambdaArrow
{
LambdaFunctionInfo info_;
MLambdaArrow(types::CompilerConstraintList *constraints, MDefinition *scopeChain,
MLambdaArrow(CompilerConstraintList *constraints, MDefinition *scopeChain,
MDefinition *this_, JSFunction *fun)
: MBinaryInstruction(scopeChain, this_), info_(fun)
{
@ -7233,7 +7233,7 @@ class MLambdaArrow
public:
INSTRUCTION_HEADER(LambdaArrow)
static MLambdaArrow *New(TempAllocator &alloc, types::CompilerConstraintList *constraints,
static MLambdaArrow *New(TempAllocator &alloc, CompilerConstraintList *constraints,
MDefinition *scopeChain, MDefinition *this_, JSFunction *fun)
{
return new(alloc) MLambdaArrow(constraints, scopeChain, this_, fun);
@ -7773,7 +7773,7 @@ class MNot
INSTRUCTION_HEADER(Not)
void cacheOperandMightEmulateUndefined(types::CompilerConstraintList *constraints);
void cacheOperandMightEmulateUndefined(CompilerConstraintList *constraints);
MDefinition *foldsTo(TempAllocator &alloc) MOZ_OVERRIDE;
void markOperandCantEmulateUndefined() {
@ -8514,7 +8514,7 @@ class MArrayConcat
AlwaysTenured<ArrayObject*> templateObj_;
gc::InitialHeap initialHeap_;
MArrayConcat(types::CompilerConstraintList *constraints, MDefinition *lhs, MDefinition *rhs,
MArrayConcat(CompilerConstraintList *constraints, MDefinition *lhs, MDefinition *rhs,
ArrayObject *templateObj, gc::InitialHeap initialHeap)
: MBinaryInstruction(lhs, rhs),
templateObj_(templateObj),
@ -8527,7 +8527,7 @@ class MArrayConcat
public:
INSTRUCTION_HEADER(ArrayConcat)
static MArrayConcat *New(TempAllocator &alloc, types::CompilerConstraintList *constraints,
static MArrayConcat *New(TempAllocator &alloc, CompilerConstraintList *constraints,
MDefinition *lhs, MDefinition *rhs,
ArrayObject *templateObj, gc::InitialHeap initialHeap)
{
@ -9251,7 +9251,7 @@ class InlinePropertyTable : public TempObject
}
bool hasFunction(JSFunction *func) const;
types::TemporaryTypeSet *buildTypeSetForFunction(JSFunction *func) const;
TemporaryTypeSet *buildTypeSetForFunction(JSFunction *func) const;
// Remove targets that vetoed inlining from the InlinePropertyTable.
void trimTo(ObjectVector &targets, BoolVector &choiceSet);
@ -11319,7 +11319,7 @@ class MRest
public MRestCommon,
public IntPolicy<0>::Data
{
MRest(types::CompilerConstraintList *constraints, MDefinition *numActuals, unsigned numFormals,
MRest(CompilerConstraintList *constraints, MDefinition *numActuals, unsigned numFormals,
ArrayObject *templateObject)
: MUnaryInstruction(numActuals),
MRestCommon(numFormals, templateObject)
@ -11331,7 +11331,7 @@ class MRest
public:
INSTRUCTION_HEADER(Rest)
static MRest *New(TempAllocator &alloc, types::CompilerConstraintList *constraints,
static MRest *New(TempAllocator &alloc, CompilerConstraintList *constraints,
MDefinition *numActuals, unsigned numFormals,
ArrayObject *templateObject)
{
@ -11354,7 +11354,7 @@ class MFilterTypeSet
: public MUnaryInstruction,
public FilterTypeSetPolicy::Data
{
MFilterTypeSet(MDefinition *def, types::TemporaryTypeSet *types)
MFilterTypeSet(MDefinition *def, TemporaryTypeSet *types)
: MUnaryInstruction(def)
{
MOZ_ASSERT(!types->unknown());
@ -11365,7 +11365,7 @@ class MFilterTypeSet
public:
INSTRUCTION_HEADER(FilterTypeSet)
static MFilterTypeSet *New(TempAllocator &alloc, MDefinition *def, types::TemporaryTypeSet *types) {
static MFilterTypeSet *New(TempAllocator &alloc, MDefinition *def, TemporaryTypeSet *types) {
return new(alloc) MFilterTypeSet(def, types);
}
@ -11388,7 +11388,7 @@ class MTypeBarrier
{
BarrierKind barrierKind_;
MTypeBarrier(MDefinition *def, types::TemporaryTypeSet *types, BarrierKind kind)
MTypeBarrier(MDefinition *def, TemporaryTypeSet *types, BarrierKind kind)
: MUnaryInstruction(def),
barrierKind_(kind)
{
@ -11405,7 +11405,7 @@ class MTypeBarrier
public:
INSTRUCTION_HEADER(TypeBarrier)
static MTypeBarrier *New(TempAllocator &alloc, MDefinition *def, types::TemporaryTypeSet *types,
static MTypeBarrier *New(TempAllocator &alloc, MDefinition *def, TemporaryTypeSet *types,
BarrierKind kind = BarrierKind::TypeSet) {
return new(alloc) MTypeBarrier(def, types, kind);
}
@ -11444,10 +11444,10 @@ class MMonitorTypes
: public MUnaryInstruction,
public BoxInputsPolicy::Data
{
const types::TemporaryTypeSet *typeSet_;
const TemporaryTypeSet *typeSet_;
BarrierKind barrierKind_;
MMonitorTypes(MDefinition *def, const types::TemporaryTypeSet *types, BarrierKind kind)
MMonitorTypes(MDefinition *def, const TemporaryTypeSet *types, BarrierKind kind)
: MUnaryInstruction(def),
typeSet_(types),
barrierKind_(kind)
@ -11461,12 +11461,12 @@ class MMonitorTypes
public:
INSTRUCTION_HEADER(MonitorTypes)
static MMonitorTypes *New(TempAllocator &alloc, MDefinition *def, const types::TemporaryTypeSet *types,
static MMonitorTypes *New(TempAllocator &alloc, MDefinition *def, const TemporaryTypeSet *types,
BarrierKind kind) {
return new(alloc) MMonitorTypes(def, types, kind);
}
const types::TemporaryTypeSet *typeSet() const {
const TemporaryTypeSet *typeSet() const {
return typeSet_;
}
BarrierKind barrierKind() const {
@ -12701,35 +12701,35 @@ MControlInstruction *MDefinition::toControlInstruction() {
// Helper functions used to decide how to build MIR.
bool ElementAccessIsDenseNative(types::CompilerConstraintList *constraints,
bool ElementAccessIsDenseNative(CompilerConstraintList *constraints,
MDefinition *obj, MDefinition *id);
bool ElementAccessIsAnyTypedArray(types::CompilerConstraintList *constraints,
bool ElementAccessIsAnyTypedArray(CompilerConstraintList *constraints,
MDefinition *obj, MDefinition *id,
Scalar::Type *arrayType);
bool ElementAccessIsPacked(types::CompilerConstraintList *constraints, MDefinition *obj);
bool ElementAccessMightBeCopyOnWrite(types::CompilerConstraintList *constraints, MDefinition *obj);
bool ElementAccessHasExtraIndexedProperty(types::CompilerConstraintList *constraints,
bool ElementAccessIsPacked(CompilerConstraintList *constraints, MDefinition *obj);
bool ElementAccessMightBeCopyOnWrite(CompilerConstraintList *constraints, MDefinition *obj);
bool ElementAccessHasExtraIndexedProperty(CompilerConstraintList *constraints,
MDefinition *obj);
MIRType DenseNativeElementType(types::CompilerConstraintList *constraints, MDefinition *obj);
MIRType DenseNativeElementType(CompilerConstraintList *constraints, MDefinition *obj);
BarrierKind PropertyReadNeedsTypeBarrier(JSContext *propertycx,
types::CompilerConstraintList *constraints,
types::TypeSetObjectKey *key, PropertyName *name,
types::TemporaryTypeSet *observed, bool updateObserved);
CompilerConstraintList *constraints,
TypeSet::ObjectKey *key, PropertyName *name,
TemporaryTypeSet *observed, bool updateObserved);
BarrierKind PropertyReadNeedsTypeBarrier(JSContext *propertycx,
types::CompilerConstraintList *constraints,
CompilerConstraintList *constraints,
MDefinition *obj, PropertyName *name,
types::TemporaryTypeSet *observed);
BarrierKind PropertyReadOnPrototypeNeedsTypeBarrier(types::CompilerConstraintList *constraints,
TemporaryTypeSet *observed);
BarrierKind PropertyReadOnPrototypeNeedsTypeBarrier(CompilerConstraintList *constraints,
MDefinition *obj, PropertyName *name,
types::TemporaryTypeSet *observed);
bool PropertyReadIsIdempotent(types::CompilerConstraintList *constraints,
TemporaryTypeSet *observed);
bool PropertyReadIsIdempotent(CompilerConstraintList *constraints,
MDefinition *obj, PropertyName *name);
void AddObjectsForPropertyRead(MDefinition *obj, PropertyName *name,
types::TemporaryTypeSet *observed);
bool CanWriteProperty(TempAllocator &alloc, types::CompilerConstraintList *constraints,
types::HeapTypeSetKey property, MDefinition *value,
TemporaryTypeSet *observed);
bool CanWriteProperty(TempAllocator &alloc, CompilerConstraintList *constraints,
HeapTypeSetKey property, MDefinition *value,
MIRType implicitType = MIRType_None);
bool PropertyWriteNeedsTypeBarrier(TempAllocator &alloc, types::CompilerConstraintList *constraints,
bool PropertyWriteNeedsTypeBarrier(TempAllocator &alloc, CompilerConstraintList *constraints,
MBasicBlock *current, MDefinition **pobj,
PropertyName *name, MDefinition **pvalue,
bool canModify, MIRType implicitType = MIRType_None);

View File

@ -37,17 +37,17 @@ namespace {
// Emulate a TypeSet logic from a Type object to avoid duplicating the guard
// logic.
class TypeWrapper {
types::Type t_;
TypeSet::Type t_;
public:
explicit TypeWrapper(types::Type t) : t_(t) {}
explicit TypeWrapper(TypeSet::Type t) : t_(t) {}
inline bool unknown() const {
return t_.isUnknown();
}
inline bool hasType(types::Type t) const {
if (t == types::Type::Int32Type())
return t == t_ || t_ == types::Type::DoubleType();
inline bool hasType(TypeSet::Type t) const {
if (t == TypeSet::Int32Type())
return t == t_ || t_ == TypeSet::DoubleType();
return t == t_;
}
inline unsigned getObjectCount() const {
@ -69,30 +69,30 @@ class TypeWrapper {
} /* anonymous namespace */
template <typename Source, typename TypeSet> void
MacroAssembler::guardTypeSet(const Source &address, const TypeSet *types, BarrierKind kind,
template <typename Source, typename Set> void
MacroAssembler::guardTypeSet(const Source &address, const Set *types, BarrierKind kind,
Register scratch, Label *miss)
{
MOZ_ASSERT(kind == BarrierKind::TypeTagOnly || kind == BarrierKind::TypeSet);
MOZ_ASSERT(!types->unknown());
Label matched;
types::Type tests[8] = {
types::Type::Int32Type(),
types::Type::UndefinedType(),
types::Type::BooleanType(),
types::Type::StringType(),
types::Type::SymbolType(),
types::Type::NullType(),
types::Type::MagicArgType(),
types::Type::AnyObjectType()
TypeSet::Type tests[8] = {
TypeSet::Int32Type(),
TypeSet::UndefinedType(),
TypeSet::BooleanType(),
TypeSet::StringType(),
TypeSet::SymbolType(),
TypeSet::NullType(),
TypeSet::MagicArgType(),
TypeSet::AnyObjectType()
};
// The double type also implies Int32.
// So replace the int32 test with the double one.
if (types->hasType(types::Type::DoubleType())) {
MOZ_ASSERT(types->hasType(types::Type::Int32Type()));
tests[0] = types::Type::DoubleType();
if (types->hasType(TypeSet::DoubleType())) {
MOZ_ASSERT(types->hasType(TypeSet::Int32Type()));
tests[0] = TypeSet::DoubleType();
}
Register tag = extractTag(address, scratch);
@ -109,7 +109,7 @@ MacroAssembler::guardTypeSet(const Source &address, const TypeSet *types, Barrie
}
// If this is the last check, invert the last branch.
if (types->hasType(types::Type::AnyObjectType()) || !types->getObjectCount()) {
if (types->hasType(TypeSet::AnyObjectType()) || !types->getObjectCount()) {
if (!lastBranch.isInitialized()) {
jump(miss);
return;
@ -156,12 +156,12 @@ MacroAssembler::guardTypeSet(const Source &address, const TypeSet *types, Barrie
bind(&matched);
}
template <typename TypeSet> void
MacroAssembler::guardObjectType(Register obj, const TypeSet *types,
template <typename Set> void
MacroAssembler::guardObjectType(Register obj, const Set *types,
Register scratch, Label *miss)
{
MOZ_ASSERT(!types->unknown());
MOZ_ASSERT(!types->hasType(types::Type::AnyObjectType()));
MOZ_ASSERT(!types->hasType(TypeSet::AnyObjectType()));
MOZ_ASSERT(types->getObjectCount());
MOZ_ASSERT(scratch != InvalidReg);
@ -229,28 +229,28 @@ MacroAssembler::guardObjectType(Register obj, const TypeSet *types,
}
template <typename Source> void
MacroAssembler::guardType(const Source &address, types::Type type,
MacroAssembler::guardType(const Source &address, TypeSet::Type type,
Register scratch, Label *miss)
{
TypeWrapper wrapper(type);
guardTypeSet(address, &wrapper, BarrierKind::TypeSet, scratch, miss);
}
template void MacroAssembler::guardTypeSet(const Address &address, const types::TemporaryTypeSet *types,
template void MacroAssembler::guardTypeSet(const Address &address, const TemporaryTypeSet *types,
BarrierKind kind, Register scratch, Label *miss);
template void MacroAssembler::guardTypeSet(const ValueOperand &value, const types::TemporaryTypeSet *types,
template void MacroAssembler::guardTypeSet(const ValueOperand &value, const TemporaryTypeSet *types,
BarrierKind kind, Register scratch, Label *miss);
template void MacroAssembler::guardTypeSet(const Address &address, const types::HeapTypeSet *types,
template void MacroAssembler::guardTypeSet(const Address &address, const HeapTypeSet *types,
BarrierKind kind, Register scratch, Label *miss);
template void MacroAssembler::guardTypeSet(const ValueOperand &value, const types::HeapTypeSet *types,
template void MacroAssembler::guardTypeSet(const ValueOperand &value, const HeapTypeSet *types,
BarrierKind kind, Register scratch, Label *miss);
template void MacroAssembler::guardTypeSet(const TypedOrValueRegister &reg, const types::HeapTypeSet *types,
template void MacroAssembler::guardTypeSet(const TypedOrValueRegister &reg, const HeapTypeSet *types,
BarrierKind kind, Register scratch, Label *miss);
template void MacroAssembler::guardTypeSet(const Address &address, const types::TypeSet *types,
template void MacroAssembler::guardTypeSet(const Address &address, const TypeSet *types,
BarrierKind kind, Register scratch, Label *miss);
template void MacroAssembler::guardTypeSet(const ValueOperand &value, const types::TypeSet *types,
template void MacroAssembler::guardTypeSet(const ValueOperand &value, const TypeSet *types,
BarrierKind kind, Register scratch, Label *miss);
template void MacroAssembler::guardTypeSet(const Address &address, const TypeWrapper *types,
@ -258,16 +258,16 @@ template void MacroAssembler::guardTypeSet(const Address &address, const TypeWra
template void MacroAssembler::guardTypeSet(const ValueOperand &value, const TypeWrapper *types,
BarrierKind kind, Register scratch, Label *miss);
template void MacroAssembler::guardObjectType(Register obj, const types::TemporaryTypeSet *types,
template void MacroAssembler::guardObjectType(Register obj, const TemporaryTypeSet *types,
Register scratch, Label *miss);
template void MacroAssembler::guardObjectType(Register obj, const types::TypeSet *types,
template void MacroAssembler::guardObjectType(Register obj, const TypeSet *types,
Register scratch, Label *miss);
template void MacroAssembler::guardObjectType(Register obj, const TypeWrapper *types,
Register scratch, Label *miss);
template void MacroAssembler::guardType(const Address &address, types::Type type,
template void MacroAssembler::guardType(const Address &address, TypeSet::Type type,
Register scratch, Label *miss);
template void MacroAssembler::guardType(const ValueOperand &value, types::Type type,
template void MacroAssembler::guardType(const ValueOperand &value, TypeSet::Type type,
Register scratch, Label *miss);
template<typename S, typename T>

View File

@ -118,20 +118,20 @@ class MacroAssembler : public MacroAssemblerSpecific
};
/*
* Creates a branch based on a specific types::Type.
* Note: emits number test (int/double) for types::Type::DoubleType()
* Creates a branch based on a specific TypeSet::Type.
* Note: emits number test (int/double) for TypeSet::DoubleType()
*/
class BranchType : public Branch
{
types::Type type_;
TypeSet::Type type_;
public:
BranchType()
: Branch(),
type_(types::Type::UnknownType())
type_(TypeSet::UnknownType())
{ }
BranchType(Condition cond, Register reg, types::Type type, Label *jump)
BranchType(Condition cond, Register reg, TypeSet::Type type, Label *jump)
: Branch(cond, reg, jump),
type_(type)
{ }
@ -278,7 +278,7 @@ class MacroAssembler : public MacroAssemblerSpecific
template <typename TypeSet>
void guardObjectType(Register obj, const TypeSet *types, Register scratch, Label *miss);
template <typename Source>
void guardType(const Source &address, types::Type type, Register scratch, Label *miss);
void guardType(const Source &address, TypeSet::Type type, Register scratch, Label *miss);
void loadObjShape(Register objReg, Register dest) {
loadPtr(Address(objReg, JSObject::offsetOfShape()), dest);

View File

@ -138,7 +138,7 @@ SpewTempOptimizationTypeInfoVector(const TempOptimizationTypeInfoVector *types,
indent ? indent : "",
TrackedTypeSiteString(t->site()), StringFromMIRType(t->mirType()));
for (uint32_t i = 0; i < t->types().length(); i++)
JitSpewCont(JitSpew_OptimizationTracking, " %s", types::TypeString(t->types()[i]));
JitSpewCont(JitSpew_OptimizationTracking, " %s", TypeSet::TypeString(t->types()[i]));
JitSpewFin(JitSpew_OptimizationTracking);
}
#endif
@ -166,7 +166,7 @@ TrackedOptimizations::spew() const
}
bool
OptimizationTypeInfo::trackTypeSet(types::TemporaryTypeSet *typeSet)
OptimizationTypeInfo::trackTypeSet(TemporaryTypeSet *typeSet)
{
if (!typeSet)
return true;
@ -174,7 +174,7 @@ OptimizationTypeInfo::trackTypeSet(types::TemporaryTypeSet *typeSet)
}
bool
OptimizationTypeInfo::trackType(types::Type type)
OptimizationTypeInfo::trackType(TypeSet::Type type)
{
return types_.append(type);
}
@ -202,15 +202,15 @@ CombineHash(HashNumber h, HashNumber n)
}
static inline HashNumber
HashType(types::Type ty)
HashType(TypeSet::Type ty)
{
if (ty.isObjectUnchecked())
return PointerHasher<types::TypeSetObjectKey *, 3>::hash(ty.objectKey());
return PointerHasher<TypeSet::ObjectKey *, 3>::hash(ty.objectKey());
return HashNumber(ty.raw());
}
static HashNumber
HashTypeList(const types::TypeSet::TypeList &types)
HashTypeList(const TypeSet::TypeList &types)
{
HashNumber h = 0;
for (uint32_t i = 0; i < types.length(); i++)
@ -348,18 +348,18 @@ class jit::UniqueTrackedTypes
public:
struct TypeHasher
{
typedef types::Type Lookup;
typedef TypeSet::Type Lookup;
static HashNumber hash(const Lookup &ty) { return HashType(ty); }
static bool match(const types::Type &ty1, const types::Type &ty2) { return ty1 == ty2; }
static bool match(const TypeSet::Type &ty1, const TypeSet::Type &ty2) { return ty1 == ty2; }
};
private:
// Map of unique types::Types to indices.
typedef HashMap<types::Type, uint8_t, TypeHasher> TypesMap;
// Map of unique TypeSet::Types to indices.
typedef HashMap<TypeSet::Type, uint8_t, TypeHasher> TypesMap;
TypesMap map_;
Vector<types::Type, 1> list_;
Vector<TypeSet::Type, 1> list_;
public:
explicit UniqueTrackedTypes(JSContext *cx)
@ -368,14 +368,14 @@ class jit::UniqueTrackedTypes
{ }
bool init() { return map_.init(); }
bool getIndexOf(types::Type ty, uint8_t *indexp);
bool getIndexOf(TypeSet::Type ty, uint8_t *indexp);
uint32_t count() const { MOZ_ASSERT(map_.count() == list_.length()); return list_.length(); }
bool enumerate(types::TypeSet::TypeList *types) const;
bool enumerate(TypeSet::TypeList *types) const;
};
bool
UniqueTrackedTypes::getIndexOf(types::Type ty, uint8_t *indexp)
UniqueTrackedTypes::getIndexOf(TypeSet::Type ty, uint8_t *indexp)
{
TypesMap::AddPtr p = map_.lookupForAdd(ty);
if (p) {
@ -398,7 +398,7 @@ UniqueTrackedTypes::getIndexOf(types::Type ty, uint8_t *indexp)
}
bool
UniqueTrackedTypes::enumerate(types::TypeSet::TypeList *types) const
UniqueTrackedTypes::enumerate(TypeSet::TypeList *types) const
{
return types->append(list_.begin(), list_.end());
}
@ -814,19 +814,19 @@ WriteOffsetsTable(CompactBufferWriter &writer, const Vector<uint32_t, 16> &offse
}
static JSFunction *
MaybeConstructorFromType(types::Type ty)
MaybeConstructorFromType(TypeSet::Type ty)
{
if (ty.isUnknown() || ty.isAnyObject() || !ty.isGroup())
return nullptr;
ObjectGroup *obj = ty.group();
types::TypeNewScript *newScript = obj->newScript();
TypeNewScript *newScript = obj->newScript();
if (!newScript && obj->maybeUnboxedLayout())
newScript = obj->unboxedLayout().newScript();
return newScript ? newScript->function() : nullptr;
}
static void
SpewConstructor(types::Type ty, JSFunction *constructor)
SpewConstructor(TypeSet::Type ty, JSFunction *constructor)
{
#ifdef DEBUG
char buf[512];
@ -843,16 +843,16 @@ SpewConstructor(types::Type ty, JSFunction *constructor)
}
JitSpew(JitSpew_OptimizationTracking, " Unique type %s has constructor %s (%s:%u)",
types::TypeString(ty), buf, filename, lineno);
TypeSet::TypeString(ty), buf, filename, lineno);
#endif
}
static void
SpewAllocationSite(types::Type ty, JSScript *script, uint32_t offset)
SpewAllocationSite(TypeSet::Type ty, JSScript *script, uint32_t offset)
{
#ifdef DEBUG
JitSpew(JitSpew_OptimizationTracking, " Unique type %s has alloc site %s:%u",
types::TypeString(ty), script->filename(),
TypeSet::TypeString(ty), script->filename(),
PCToLineNumber(script, script->offsetToPC(offset)));
#endif
}
@ -942,11 +942,11 @@ jit::WriteIonTrackedOptimizationsTable(JSContext *cx, CompactBufferWriter &write
// instead of during profiling to avoid touching compartment tables during
// profiling. Additionally, TypeNewScript is subject to GC in the
// meantime.
types::TypeSet::TypeList uniqueTypeList;
TypeSet::TypeList uniqueTypeList;
if (!uniqueTypes.enumerate(&uniqueTypeList))
return false;
for (uint32_t i = 0; i < uniqueTypeList.length(); i++) {
types::Type ty = uniqueTypeList[i];
TypeSet::Type ty = uniqueTypeList[i];
if (JSFunction *constructor = MaybeConstructorFromType(ty)) {
if (!allTypes->append(IonTrackedTypeWithAddendum(ty, constructor)))
return false;
@ -954,7 +954,9 @@ jit::WriteIonTrackedOptimizationsTable(JSContext *cx, CompactBufferWriter &write
} else {
JSScript *script;
uint32_t offset;
if (ObjectGroup::findAllocationSiteForType(cx, ty, &script, &offset)) {
if (!ty.isUnknown() && !ty.isAnyObject() && ty.isGroup() &&
ObjectGroup::findAllocationSite(cx, ty.group(), &script, &offset))
{
if (!allTypes->append(IonTrackedTypeWithAddendum(ty, script, offset)))
return false;
SpewAllocationSite(ty, script, offset);
@ -1032,7 +1034,7 @@ IonBuilder::startTrackingOptimizations()
void
IonBuilder::trackTypeInfoUnchecked(TrackedTypeSite kind, MIRType mirType,
types::TemporaryTypeSet *typeSet)
TemporaryTypeSet *typeSet)
{
BytecodeSite *site = current->trackedSite();
// OOMs are handled as if optimization tracking were turned off.
@ -1051,7 +1053,7 @@ IonBuilder::trackTypeInfoUnchecked(TrackedTypeSite kind, JSObject *obj)
BytecodeSite *site = current->trackedSite();
// OOMs are handled as if optimization tracking were turned off.
OptimizationTypeInfo typeInfo(kind, MIRType_Object);
if (!typeInfo.trackType(types::Type::ObjectType(obj)))
if (!typeInfo.trackType(TypeSet::ObjectType(obj)))
return;
if (!site->optimizations()->trackTypeInfo(mozilla::Move(typeInfo)))
site->setOptimizations(nullptr);
@ -1068,7 +1070,7 @@ IonBuilder::trackTypeInfoUnchecked(CallInfo &callInfo)
trackTypeInfoUnchecked(TrackedTypeSite::Call_Arg, arg->type(), arg->resultTypeSet());
}
types::TemporaryTypeSet *returnTypes = getInlineReturnTypeSet();
TemporaryTypeSet *returnTypes = getInlineReturnTypeSet();
trackTypeInfoUnchecked(TrackedTypeSite::Call_Return, returnTypes->getKnownMIRType(),
returnTypes);
}
@ -1140,7 +1142,7 @@ InterpretedFunctionFromTrackedType(const IonTrackedTypeWithAddendum &tracked)
if (tracked.hasConstructor())
return tracked.constructor;
types::Type ty = tracked.type;
TypeSet::Type ty = tracked.type;
if (ty.isSingleton()) {
JSObject *obj = ty.singleton();
@ -1162,10 +1164,10 @@ class ForEachTypeInfoAdapter : public IonTrackedOptimizationsTypeInfo::ForEachOp
{ }
void readType(const IonTrackedTypeWithAddendum &tracked) MOZ_OVERRIDE {
types::Type ty = tracked.type;
TypeSet::Type ty = tracked.type;
if (ty.isPrimitive() || ty.isUnknown() || ty.isAnyObject()) {
op_.readType("primitive", types::NonObjectTypeString(ty), nullptr, 0);
op_.readType("primitive", TypeSet::NonObjectTypeString(ty), nullptr, 0);
return;
}

View File

@ -59,7 +59,7 @@ class OptimizationTypeInfo
{
JS::TrackedTypeSite site_;
MIRType mirType_;
types::TypeSet::TypeList types_;
TypeSet::TypeList types_;
public:
OptimizationTypeInfo(OptimizationTypeInfo &&other)
@ -73,12 +73,12 @@ class OptimizationTypeInfo
mirType_(mirType)
{ }
bool trackTypeSet(types::TemporaryTypeSet *typeSet);
bool trackType(types::Type type);
bool trackTypeSet(TemporaryTypeSet *typeSet);
bool trackType(TypeSet::Type type);
JS::TrackedTypeSite site() const { return site_; }
MIRType mirType() const { return mirType_; }
const types::TypeSet::TypeList &types() const { return types_; }
const TypeSet::TypeList &types() const { return types_; }
bool operator ==(const OptimizationTypeInfo &other) const;
bool operator !=(const OptimizationTypeInfo &other) const;
@ -421,7 +421,7 @@ class IonTrackedOptimizationsAttempts
struct IonTrackedTypeWithAddendum
{
types::Type type;
TypeSet::Type type;
enum HasAddendum {
HasNothing,
@ -441,19 +441,19 @@ struct IonTrackedTypeWithAddendum
JSFunction *constructor;
};
explicit IonTrackedTypeWithAddendum(types::Type type)
explicit IonTrackedTypeWithAddendum(TypeSet::Type type)
: type(type),
hasAddendum(HasNothing)
{ }
IonTrackedTypeWithAddendum(types::Type type, JSScript *script, uint32_t offset)
IonTrackedTypeWithAddendum(TypeSet::Type type, JSScript *script, uint32_t offset)
: type(type),
hasAddendum(HasAllocationSite),
script(script),
offset(offset)
{ }
IonTrackedTypeWithAddendum(types::Type type, JSFunction *constructor)
IonTrackedTypeWithAddendum(TypeSet::Type type, JSFunction *constructor)
: type(type),
hasAddendum(HasConstructor),
constructor(constructor)
@ -482,7 +482,7 @@ class IonTrackedOptimizationsTypeInfo
// Unlike IonTrackedOptimizationAttempts,
// JS::ForEachTrackedOptimizaitonTypeInfoOp cannot be used directly. The
// internal API needs to deal with engine-internal data structures (e.g.,
// types::Type) directly.
// TypeSet::Type) directly.
struct ForEachOp
{
virtual void readType(const IonTrackedTypeWithAddendum &tracked) = 0;

View File

@ -99,7 +99,7 @@ InvokeFunction(JSContext *cx, HandleObject obj0, uint32_t argc, Value *argv, Val
if (obj->is<JSFunction>()) {
jsbytecode *pc;
RootedScript script(cx, cx->currentScript(&pc));
types::TypeScript::Monitor(cx, script, pc, rv.get());
TypeScript::Monitor(cx, script, pc, rv.get());
}
*rval = rv;
@ -330,7 +330,7 @@ ArrayPopDense(JSContext *cx, HandleObject obj, MutableHandleValue rval)
// have to monitor the return value.
rval.set(argv[0]);
if (rval.isUndefined())
types::TypeScript::Monitor(cx, rval);
TypeScript::Monitor(cx, rval);
return true;
}
@ -380,7 +380,7 @@ ArrayShiftDense(JSContext *cx, HandleObject obj, MutableHandleValue rval)
// have to monitor the return value.
rval.set(argv[0]);
if (rval.isUndefined())
types::TypeScript::Monitor(cx, rval);
TypeScript::Monitor(cx, rval);
return true;
}
@ -583,7 +583,7 @@ GetIntrinsicValue(JSContext *cx, HandlePropertyName name, MutableHandleValue rva
// purposes, as its side effect is not observable from JS. We are
// guaranteed to bail out after this function, but because of its AliasSet,
// type info will not be reflowed. Manually monitor here.
types::TypeScript::Monitor(cx, rval);
TypeScript::Monitor(cx, rval);
return true;
}

View File

@ -874,7 +874,7 @@ class ReadTempAttemptsVectorOp : public JS::ForEachTrackedOptimizationAttemptOp
struct ReadTempTypeInfoVectorOp : public IonTrackedOptimizationsTypeInfo::ForEachOp
{
TempOptimizationTypeInfoVector *types_;
types::TypeSet::TypeList accTypes_;
TypeSet::TypeList accTypes_;
public:
explicit ReadTempTypeInfoVectorOp(TempOptimizationTypeInfoVector *types)

View File

@ -97,7 +97,6 @@
using namespace js;
using namespace js::gc;
using namespace js::types;
using mozilla::Maybe;
using mozilla::PodCopy;

View File

@ -44,7 +44,6 @@
using namespace js;
using namespace js::gc;
using namespace js::types;
using mozilla::Abs;
using mozilla::ArrayLength;
@ -1225,8 +1224,7 @@ InitArrayTypes(JSContext *cx, ObjectGroup *group, const Value *vector, unsigned
for (unsigned i = 0; i < count; i++) {
if (vector[i].isMagic(JS_ELEMENTS_HOLE))
continue;
Type valtype = GetValueType(vector[i]);
types->addType(cx, valtype);
types->addType(cx, TypeSet::GetValueType(vector[i]));
}
}
return true;

View File

@ -23,7 +23,6 @@
#include "vm/BooleanObject-inl.h"
using namespace js;
using namespace js::types;
const Class BooleanObject::class_ = {
"Boolean",

View File

@ -253,7 +253,7 @@ js::DestroyContext(JSContext *cx, DestroyContextMode mode)
* This printing depends on atoms still existing.
*/
for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next())
types::PrintTypes(cx, c, false);
PrintTypes(cx, c, false);
}
if (mode == DCM_FORCE_GC) {
MOZ_ASSERT(!rt->isHeapBusy());

View File

@ -46,7 +46,6 @@
#include "jsobjinlines.h"
using namespace js;
using namespace js::types;
using mozilla::ArrayLength;
using mozilla::IsFinite;

View File

@ -37,7 +37,6 @@
using namespace js;
using namespace js::gc;
using namespace js::types;
using mozilla::ArrayLength;
using mozilla::PodArrayZero;

View File

@ -49,7 +49,6 @@
using namespace js;
using namespace js::gc;
using namespace js::types;
using namespace js::frontend;
using mozilla::ArrayLength;

View File

@ -2218,7 +2218,7 @@ GCRuntime::sweepTypesAfterCompacting(Zone *zone)
FreeOp *fop = rt->defaultFreeOp();
zone->beginSweepTypes(fop, rt->gc.releaseObservedTypes && !zone->isPreservingCode());
types::AutoClearTypeInferenceStateOnOOM oom(zone);
AutoClearTypeInferenceStateOnOOM oom(zone);
for (ZoneCellIterUnderGC i(zone, FINALIZE_SCRIPT); !i.done(); i.next()) {
JSScript *script = i.get<JSScript>();
@ -5191,13 +5191,13 @@ SweepThing(Shape *shape)
}
static void
SweepThing(JSScript *script, types::AutoClearTypeInferenceStateOnOOM *oom)
SweepThing(JSScript *script, AutoClearTypeInferenceStateOnOOM *oom)
{
script->maybeSweepTypes(oom);
}
static void
SweepThing(ObjectGroup *group, types::AutoClearTypeInferenceStateOnOOM *oom)
SweepThing(ObjectGroup *group, AutoClearTypeInferenceStateOnOOM *oom)
{
group->maybeSweep(oom);
}
@ -5245,7 +5245,7 @@ GCRuntime::sweepPhase(SliceBudget &sliceBudget)
for (; sweepZone; sweepZone = sweepZone->nextNodeInGroup()) {
ArenaLists &al = sweepZone->arenas;
types::AutoClearTypeInferenceStateOnOOM oom(sweepZone);
AutoClearTypeInferenceStateOnOOM oom(sweepZone);
if (!SweepArenaList<JSScript>(&al.gcScriptArenasToUpdate, sliceBudget, &oom))
return NotFinished;

View File

@ -41,7 +41,6 @@
using namespace js;
using namespace js::gc;
using namespace js::types;
using mozilla::DebugOnly;
using mozilla::Maybe;
@ -76,7 +75,7 @@ id_caller(JSContext *cx)
}
const char *
types::TypeIdStringImpl(jsid id)
js::TypeIdStringImpl(jsid id)
{
if (JSID_IS_VOID(id))
return "(index)";
@ -97,8 +96,8 @@ types::TypeIdStringImpl(jsid id)
// Logging
/////////////////////////////////////////////////////////////////////
const char *
types::NonObjectTypeString(Type type)
/* static */ const char *
TypeSet::NonObjectTypeString(TypeSet::Type type)
{
if (type.isPrimitive()) {
switch (type.primitive()) {
@ -170,7 +169,7 @@ static bool InferSpewColorable()
}
const char *
types::InferSpewColorReset()
js::InferSpewColorReset()
{
if (!InferSpewColorable())
return "";
@ -178,7 +177,7 @@ types::InferSpewColorReset()
}
const char *
types::InferSpewColor(TypeConstraint *constraint)
js::InferSpewColor(TypeConstraint *constraint)
{
/* Type constraints are printed out using foreground colors. */
static const char * const colors[] = { "\x1b[31m", "\x1b[32m", "\x1b[33m",
@ -190,7 +189,7 @@ types::InferSpewColor(TypeConstraint *constraint)
}
const char *
types::InferSpewColor(TypeSet *types)
js::InferSpewColor(TypeSet *types)
{
/* Type sets are printed out using bold colors. */
static const char * const colors[] = { "\x1b[1;31m", "\x1b[1;32m", "\x1b[1;33m",
@ -201,8 +200,8 @@ types::InferSpewColor(TypeSet *types)
return colors[DefaultHasher<TypeSet *>::hash(types) % 7];
}
const char *
types::TypeString(Type type)
/* static */ const char *
TypeSet::TypeString(TypeSet::Type type)
{
if (type.isPrimitive() || type.isUnknown() || type.isAnyObject())
return NonObjectTypeString(type);
@ -219,14 +218,14 @@ types::TypeString(Type type)
return bufs[which];
}
const char *
types::ObjectGroupString(ObjectGroup *group)
/* static */ const char *
TypeSet::ObjectGroupString(ObjectGroup *group)
{
return TypeString(Type::ObjectType(group));
return TypeString(TypeSet::ObjectType(group));
}
void
types::InferSpew(SpewChannel channel, const char *fmt, ...)
js::InferSpew(SpewChannel channel, const char *fmt, ...)
{
if (!InferSpewActive(channel))
return;
@ -240,7 +239,7 @@ types::InferSpew(SpewChannel channel, const char *fmt, ...)
}
bool
types::TypeHasProperty(JSContext *cx, ObjectGroup *group, jsid id, const Value &value)
js::ObjectGroupHasProperty(JSContext *cx, ObjectGroup *group, jsid id, const Value &value)
{
/*
* Check the correctness of the type information in the object's property
@ -253,7 +252,7 @@ types::TypeHasProperty(JSContext *cx, ObjectGroup *group, jsid id, const Value &
if (id == id___proto__(cx) || id == id_constructor(cx) || id == id_caller(cx))
return true;
Type type = GetValueType(value);
TypeSet::Type type = TypeSet::GetValueType(value);
// Type set guards might miss when an object's group changes and its
// properties become unknown.
@ -277,7 +276,8 @@ types::TypeHasProperty(JSContext *cx, ObjectGroup *group, jsid id, const Value &
if (!types->hasType(type)) {
TypeFailure(cx, "Missing type in object %s %s: %s",
ObjectGroupString(group), TypeIdString(id), TypeString(type));
TypeSet::ObjectGroupString(group), TypeIdString(id),
TypeSet::TypeString(type));
}
}
return true;
@ -286,7 +286,7 @@ types::TypeHasProperty(JSContext *cx, ObjectGroup *group, jsid id, const Value &
#endif
void
types::TypeFailure(JSContext *cx, const char *fmt, ...)
js::TypeFailure(JSContext *cx, const char *fmt, ...)
{
char msgbuf[1024]; /* Larger error messages will be truncated */
char errbuf[1024];
@ -323,12 +323,12 @@ TemporaryTypeSet::TemporaryTypeSet(LifoAlloc *alloc, Type type)
flags |= TYPE_FLAG_ANYOBJECT;
} else {
setBaseObjectCount(1);
objectSet = reinterpret_cast<TypeSetObjectKey**>(type.objectKey());
objectSet = reinterpret_cast<ObjectKey**>(type.objectKey());
if (type.isGroup()) {
ObjectGroup *ngroup = type.group();
if (ngroup->newScript() && ngroup->newScript()->initializedGroup())
addType(Type::ObjectType(ngroup->newScript()->initializedGroup()), alloc);
addType(ObjectType(ngroup->newScript()->initializedGroup()), alloc);
}
}
}
@ -387,10 +387,10 @@ TypeSet::objectsAreSubset(TypeSet *other)
return false;
for (unsigned i = 0; i < getObjectCount(); i++) {
TypeSetObjectKey *key = getObject(i);
ObjectKey *key = getObject(i);
if (!key)
continue;
if (!other->hasType(Type::ObjectType(key)))
if (!other->hasType(ObjectType(key)))
return false;
}
@ -407,10 +407,10 @@ TypeSet::isSubset(const TypeSet *other) const
MOZ_ASSERT(other->unknownObject());
} else {
for (unsigned i = 0; i < getObjectCount(); i++) {
TypeSetObjectKey *key = getObject(i);
ObjectKey *key = getObject(i);
if (!key)
continue;
if (!other->hasType(Type::ObjectType(key)))
if (!other->hasType(ObjectType(key)))
return false;
}
}
@ -423,12 +423,12 @@ TypeSet::enumerateTypes(TypeList *list) const
{
/* If any type is possible, there's no need to worry about specifics. */
if (flags & TYPE_FLAG_UNKNOWN)
return list->append(Type::UnknownType());
return list->append(UnknownType());
/* Enqueue type set members stored as bits. */
for (TypeFlags flag = 1; flag < TYPE_FLAG_ANYOBJECT; flag <<= 1) {
if (flags & flag) {
Type type = Type::PrimitiveType(TypeFlagPrimitive(flag));
Type type = PrimitiveType(TypeFlagPrimitive(flag));
if (!list->append(type))
return false;
}
@ -436,14 +436,14 @@ TypeSet::enumerateTypes(TypeList *list) const
/* If any object is possible, skip specifics. */
if (flags & TYPE_FLAG_ANYOBJECT)
return list->append(Type::AnyObjectType());
return list->append(AnyObjectType());
/* Enqueue specific object types. */
unsigned count = getObjectCount();
for (unsigned i = 0; i < count; i++) {
TypeSetObjectKey *key = getObject(i);
ObjectKey *key = getObject(i);
if (key) {
if (!list->append(Type::ObjectType(key)))
if (!list->append(ObjectType(key)))
return false;
}
}
@ -532,9 +532,9 @@ TypeSet::addType(Type type, LifoAlloc *alloc)
{
uint32_t objectCount = baseObjectCount();
TypeSetObjectKey *key = type.objectKey();
TypeSetObjectKey **pentry = HashSetInsert<TypeSetObjectKey *,TypeSetObjectKey,TypeSetObjectKey>
(*alloc, objectSet, objectCount, key);
ObjectKey *key = type.objectKey();
ObjectKey **pentry = TypeHashSet::Insert<ObjectKey *, ObjectKey, ObjectKey>
(*alloc, objectSet, objectCount, key);
if (!pentry)
goto unknownObject;
if (*pentry)
@ -579,7 +579,7 @@ TypeSet::addType(Type type, LifoAlloc *alloc)
// corresponding fully initialized group, as an object's group may change
// from the former to the latter via the acquired properties analysis.
if (ngroup->newScript() && ngroup->newScript()->initializedGroup())
addType(Type::ObjectType(ngroup->newScript()->initializedGroup()), alloc);
addType(ObjectType(ngroup->newScript()->initializedGroup()), alloc);
}
if (false) {
@ -600,7 +600,7 @@ ConstraintTypeSet::addType(ExclusiveContext *cxArg, Type type)
TypeSet::addType(type, &cxArg->typeLifoAlloc());
if (type.isObjectUnchecked() && unknownObject())
type = Type::AnyObjectType();
type = AnyObjectType();
InferSpew(ISpewOps, "addType: %sT%p%s %s",
InferSpewColor(this), this, InferSpewColorReset(),
@ -663,9 +663,9 @@ TypeSet::print()
unsigned count = getObjectCount();
for (unsigned i = 0; i < count; i++) {
TypeSetObjectKey *key = getObject(i);
ObjectKey *key = getObject(i);
if (key)
fprintf(stderr, " %s", TypeString(Type::ObjectType(key)));
fprintf(stderr, " %s", TypeString(ObjectType(key)));
}
}
}
@ -677,7 +677,7 @@ TypeSet::readBarrier(const TypeSet *types)
return;
for (unsigned i = 0; i < types->getObjectCount(); i++) {
if (TypeSetObjectKey *key = types->getObject(i)) {
if (ObjectKey *key = types->getObject(i)) {
if (key->isSingleton())
(void) key->singleton();
else
@ -692,11 +692,11 @@ TypeSet::clone(LifoAlloc *alloc, TemporaryTypeSet *result) const
MOZ_ASSERT(result->empty());
unsigned objectCount = baseObjectCount();
unsigned capacity = (objectCount >= 2) ? HashSetCapacity(objectCount) : 0;
unsigned capacity = (objectCount >= 2) ? TypeHashSet::Capacity(objectCount) : 0;
TypeSetObjectKey **newSet;
ObjectKey **newSet;
if (capacity) {
newSet = alloc->newArray<TypeSetObjectKey*>(capacity);
newSet = alloc->newArray<ObjectKey*>(capacity);
if (!newSet)
return false;
PodCopy(newSet, objectSet, capacity);
@ -759,18 +759,18 @@ TypeSet::cloneWithoutObjects(LifoAlloc *alloc)
TypeSet::unionSets(TypeSet *a, TypeSet *b, LifoAlloc *alloc)
{
TemporaryTypeSet *res = alloc->new_<TemporaryTypeSet>(a->baseFlags() | b->baseFlags(),
static_cast<TypeSetObjectKey**>(nullptr));
static_cast<ObjectKey**>(nullptr));
if (!res)
return nullptr;
if (!res->unknownObject()) {
for (size_t i = 0; i < a->getObjectCount() && !res->unknownObject(); i++) {
if (TypeSetObjectKey *key = a->getObject(i))
res->addType(Type::ObjectType(key), alloc);
if (ObjectKey *key = a->getObject(i))
res->addType(ObjectType(key), alloc);
}
for (size_t i = 0; i < b->getObjectCount() && !res->unknownObject(); i++) {
if (TypeSetObjectKey *key = b->getObject(i))
res->addType(Type::ObjectType(key), alloc);
if (ObjectKey *key = b->getObject(i))
res->addType(ObjectType(key), alloc);
}
}
@ -782,7 +782,7 @@ TypeSet::intersectSets(TemporaryTypeSet *a, TemporaryTypeSet *b, LifoAlloc *allo
{
TemporaryTypeSet *res;
res = alloc->new_<TemporaryTypeSet>(a->baseFlags() & b->baseFlags(),
static_cast<TypeSetObjectKey**>(nullptr));
static_cast<ObjectKey**>(nullptr));
if (!res)
return nullptr;
@ -795,7 +795,7 @@ TypeSet::intersectSets(TemporaryTypeSet *a, TemporaryTypeSet *b, LifoAlloc *allo
if (a->unknownObject()) {
for (size_t i = 0; i < b->getObjectCount(); i++) {
if (b->getObject(i))
res->addType(Type::ObjectType(b->getObject(i)), alloc);
res->addType(ObjectType(b->getObject(i)), alloc);
}
return res;
}
@ -803,7 +803,7 @@ TypeSet::intersectSets(TemporaryTypeSet *a, TemporaryTypeSet *b, LifoAlloc *allo
if (b->unknownObject()) {
for (size_t i = 0; i < a->getObjectCount(); i++) {
if (b->getObject(i))
res->addType(Type::ObjectType(a->getObject(i)), alloc);
res->addType(ObjectType(a->getObject(i)), alloc);
}
return res;
}
@ -816,7 +816,7 @@ TypeSet::intersectSets(TemporaryTypeSet *a, TemporaryTypeSet *b, LifoAlloc *allo
continue;
if (!b->getObject(j))
continue;
res->addType(Type::ObjectType(b->getObject(j)), alloc);
res->addType(ObjectType(b->getObject(j)), alloc);
break;
}
}
@ -869,7 +869,7 @@ class CompilerConstraint
virtual bool generateTypeConstraint(JSContext *cx, RecompileInfo recompileInfo) = 0;
};
class types::CompilerConstraintList
class js::CompilerConstraintList
{
public:
struct FrozenScript
@ -949,7 +949,7 @@ class types::CompilerConstraintList
};
CompilerConstraintList *
types::NewCompilerConstraintList(jit::TempAllocator &alloc)
js::NewCompilerConstraintList(jit::TempAllocator &alloc)
{
return alloc.lifoAlloc()->new_<CompilerConstraintList>(alloc);
}
@ -1015,7 +1015,7 @@ class TypeCompilerConstraint : public TypeConstraint
const char *kind() { return data.kind(); }
void newType(JSContext *cx, TypeSet *source, Type type) {
void newType(JSContext *cx, TypeSet *source, TypeSet::Type type) {
if (data.invalidateOnNewType(type))
cx->zone()->types.addPendingRecompile(cx, compilation);
}
@ -1061,19 +1061,19 @@ CompilerConstraintInstance<T>::generateTypeConstraint(JSContext *cx, RecompileIn
} /* anonymous namespace */
const Class *
TypeSetObjectKey::clasp()
TypeSet::ObjectKey::clasp()
{
return isGroup() ? group()->clasp() : singleton()->getClass();
}
TaggedProto
TypeSetObjectKey::proto()
TypeSet::ObjectKey::proto()
{
return isGroup() ? group()->proto() : singleton()->getTaggedProto();
}
TypeNewScript *
TypeSetObjectKey::newScript()
TypeSet::ObjectKey::newScript()
{
if (isGroup() && group()->newScript())
return group()->newScript();
@ -1081,7 +1081,7 @@ TypeSetObjectKey::newScript()
}
ObjectGroup *
TypeSetObjectKey::maybeGroup()
TypeSet::ObjectKey::maybeGroup()
{
if (isGroup())
return group();
@ -1091,7 +1091,7 @@ TypeSetObjectKey::maybeGroup()
}
bool
TypeSetObjectKey::unknownProperties()
TypeSet::ObjectKey::unknownProperties()
{
if (ObjectGroup *group = maybeGroup())
return group->unknownProperties();
@ -1099,7 +1099,7 @@ TypeSetObjectKey::unknownProperties()
}
HeapTypeSetKey
TypeSetObjectKey::property(jsid id)
TypeSet::ObjectKey::property(jsid id)
{
MOZ_ASSERT(!unknownProperties());
@ -1113,7 +1113,7 @@ TypeSetObjectKey::property(jsid id)
}
void
TypeSetObjectKey::ensureTrackedProperty(JSContext *cx, jsid id)
TypeSet::ObjectKey::ensureTrackedProperty(JSContext *cx, jsid id)
{
// If we are accessing a lazily defined property which actually exists in
// the VM and has not been instantiated yet, instantiate it now if we are
@ -1182,7 +1182,7 @@ class TypeConstraintFreezeStack : public TypeConstraint
const char *kind() { return "freezeStack"; }
void newType(JSContext *cx, TypeSet *source, Type type) {
void newType(JSContext *cx, TypeSet *source, TypeSet::Type type) {
/*
* Unlike TypeConstraintFreeze, triggering this constraint once does
* not disable it on future changes to the type set.
@ -1201,7 +1201,7 @@ class TypeConstraintFreezeStack : public TypeConstraint
} /* anonymous namespace */
bool
types::FinishCompilation(JSContext *cx, HandleScript script, CompilerConstraintList *constraints,
js::FinishCompilation(JSContext *cx, HandleScript script, CompilerConstraintList *constraints,
RecompileInfo *precompileInfo)
{
if (constraints->failed())
@ -1254,13 +1254,13 @@ types::FinishCompilation(JSContext *cx, HandleScript script, CompilerConstraintL
break;
}
if (!CheckFrozenTypeSet(cx, entry.thisTypes, types::TypeScript::ThisTypes(entry.script)))
if (!CheckFrozenTypeSet(cx, entry.thisTypes, TypeScript::ThisTypes(entry.script)))
succeeded = false;
unsigned nargs = entry.script->functionNonDelazifying()
? entry.script->functionNonDelazifying()->nargs()
: 0;
for (size_t i = 0; i < nargs; i++) {
if (!CheckFrozenTypeSet(cx, &entry.argTypes[i], types::TypeScript::ArgTypes(entry.script, i)))
if (!CheckFrozenTypeSet(cx, &entry.argTypes[i], TypeScript::ArgTypes(entry.script, i)))
succeeded = false;
}
for (size_t i = 0; i < entry.script->nTypeSets(); i++) {
@ -1310,7 +1310,7 @@ CheckDefinitePropertiesTypeSet(JSContext *cx, TemporaryTypeSet *frozen, StackTyp
}
void
types::FinishDefinitePropertiesAnalysis(JSContext *cx, CompilerConstraintList *constraints)
js::FinishDefinitePropertiesAnalysis(JSContext *cx, CompilerConstraintList *constraints)
{
#ifdef DEBUG
// Assert no new types have been added to the StackTypeSets. Do this before
@ -1364,7 +1364,7 @@ class ConstraintDataFreeze
const char *kind() { return "freeze"; }
bool invalidateOnNewType(Type type) { return true; }
bool invalidateOnNewType(TypeSet::Type type) { return true; }
bool invalidateOnNewPropertyState(TypeSet *property) { return true; }
bool invalidateOnNewObjectState(ObjectGroup *group) { return false; }
@ -1559,7 +1559,7 @@ class ConstraintDataFreezeObjectFlags
const char *kind() { return "freezeObjectFlags"; }
bool invalidateOnNewType(Type type) { return false; }
bool invalidateOnNewType(TypeSet::Type type) { return false; }
bool invalidateOnNewPropertyState(TypeSet *property) { return false; }
bool invalidateOnNewObjectState(ObjectGroup *group) {
return group->hasAnyFlags(flags);
@ -1577,7 +1577,7 @@ class ConstraintDataFreezeObjectFlags
} /* anonymous namespace */
bool
TypeSetObjectKey::hasFlags(CompilerConstraintList *constraints, ObjectGroupFlags flags)
TypeSet::ObjectKey::hasFlags(CompilerConstraintList *constraints, ObjectGroupFlags flags)
{
MOZ_ASSERT(flags);
@ -1595,7 +1595,7 @@ TypeSetObjectKey::hasFlags(CompilerConstraintList *constraints, ObjectGroupFlags
}
bool
TypeSetObjectKey::hasStableClassAndProto(CompilerConstraintList *constraints)
TypeSet::ObjectKey::hasStableClassAndProto(CompilerConstraintList *constraints)
{
return !hasFlags(constraints, OBJECT_FLAG_UNKNOWN_PROPERTIES);
}
@ -1615,7 +1615,7 @@ TemporaryTypeSet::hasObjectFlags(CompilerConstraintList *constraints, ObjectGrou
unsigned count = getObjectCount();
for (unsigned i = 0; i < count; i++) {
TypeSetObjectKey *key = getObject(i);
ObjectKey *key = getObject(i);
if (key && key->hasFlags(constraints, flags))
return true;
}
@ -1636,7 +1636,7 @@ ObjectGroup::initialHeap(CompilerConstraintList *constraints)
if (!canPreTenure())
return gc::DefaultHeap;
HeapTypeSetKey objectProperty = TypeSetObjectKey::get(this)->property(JSID_EMPTY);
HeapTypeSetKey objectProperty = TypeSet::ObjectKey::get(this)->property(JSID_EMPTY);
LifoAlloc *alloc = constraints->alloc();
typedef CompilerConstraintInstance<ConstraintDataFreezeObjectFlags> T;
@ -1659,7 +1659,7 @@ class ConstraintDataFreezeObjectForInlinedCall
const char *kind() { return "freezeObjectForInlinedCall"; }
bool invalidateOnNewType(Type type) { return false; }
bool invalidateOnNewType(TypeSet::Type type) { return false; }
bool invalidateOnNewPropertyState(TypeSet *property) { return false; }
bool invalidateOnNewObjectState(ObjectGroup *group) {
// We don't keep track of the exact dependencies the caller has on its
@ -1691,7 +1691,7 @@ class ConstraintDataFreezeObjectForTypedArrayData
const char *kind() { return "freezeObjectForTypedArrayData"; }
bool invalidateOnNewType(Type type) { return false; }
bool invalidateOnNewType(TypeSet::Type type) { return false; }
bool invalidateOnNewPropertyState(TypeSet *property) { return false; }
bool invalidateOnNewObjectState(ObjectGroup *group) {
TypedArrayObject &tarray = group->singleton()->as<TypedArrayObject>();
@ -1713,7 +1713,7 @@ class ConstraintDataFreezeObjectForTypedArrayData
} /* anonymous namespace */
void
TypeSetObjectKey::watchStateChangeForInlinedCall(CompilerConstraintList *constraints)
TypeSet::ObjectKey::watchStateChangeForInlinedCall(CompilerConstraintList *constraints)
{
HeapTypeSetKey objectProperty = property(JSID_EMPTY);
LifoAlloc *alloc = constraints->alloc();
@ -1723,7 +1723,7 @@ TypeSetObjectKey::watchStateChangeForInlinedCall(CompilerConstraintList *constra
}
void
TypeSetObjectKey::watchStateChangeForTypedArrayData(CompilerConstraintList *constraints)
TypeSet::ObjectKey::watchStateChangeForTypedArrayData(CompilerConstraintList *constraints)
{
TypedArrayObject &tarray = singleton()->as<TypedArrayObject>();
HeapTypeSetKey objectProperty = property(JSID_EMPTY);
@ -1776,7 +1776,7 @@ class ConstraintDataFreezePropertyState
const char *kind() { return (which == NON_DATA) ? "freezeNonDataProperty" : "freezeNonWritableProperty"; }
bool invalidateOnNewType(Type type) { return false; }
bool invalidateOnNewType(TypeSet::Type type) { return false; }
bool invalidateOnNewPropertyState(TypeSet *property) {
return (which == NON_DATA)
? property->nonDataProperty()
@ -1832,7 +1832,7 @@ class ConstraintDataConstantProperty
const char *kind() { return "constantProperty"; }
bool invalidateOnNewType(Type type) { return false; }
bool invalidateOnNewType(TypeSet::Type type) { return false; }
bool invalidateOnNewPropertyState(TypeSet *property) {
return property->nonConstantProperty();
}
@ -1894,7 +1894,7 @@ class ConstraintDataInert
const char *kind() { return "inert"; }
bool invalidateOnNewType(Type type) { return false; }
bool invalidateOnNewType(TypeSet::Type type) { return false; }
bool invalidateOnNewPropertyState(TypeSet *property) { return false; }
bool invalidateOnNewObjectState(ObjectGroup *group) { return false; }
@ -1937,7 +1937,7 @@ TemporaryTypeSet::filtersType(const TemporaryTypeSet *other, Type filteredType)
return unknown();
for (TypeFlags flag = 1; flag < TYPE_FLAG_ANYOBJECT; flag <<= 1) {
Type type = Type::PrimitiveType(TypeFlagPrimitive(flag));
Type type = PrimitiveType(TypeFlagPrimitive(flag));
if (type != filteredType && other->hasType(type) && !hasType(type))
return false;
}
@ -1946,9 +1946,9 @@ TemporaryTypeSet::filtersType(const TemporaryTypeSet *other, Type filteredType)
return unknownObject();
for (size_t i = 0; i < other->getObjectCount(); i++) {
TypeSetObjectKey *key = other->getObject(i);
ObjectKey *key = other->getObject(i);
if (key) {
Type type = Type::ObjectType(key);
Type type = ObjectType(key);
if (type != filteredType && !hasType(type))
return false;
}
@ -1968,7 +1968,7 @@ TemporaryTypeSet::convertDoubleElements(CompilerConstraintList *constraints)
bool dontConvert = false;
for (unsigned i = 0; i < getObjectCount(); i++) {
TypeSetObjectKey *key = getObject(i);
ObjectKey *key = getObject(i);
if (!key)
continue;
@ -1985,7 +1985,7 @@ TemporaryTypeSet::convertDoubleElements(CompilerConstraintList *constraints)
// information incorrect), nor for non-array objects (as their elements
// may point to emptyObjectElements, which cannot be converted).
if (!property.maybeTypes() ||
!property.maybeTypes()->hasType(Type::DoubleType()) ||
!property.maybeTypes()->hasType(DoubleType()) ||
key->clasp() != &ArrayObject::class_)
{
dontConvert = true;
@ -2040,7 +2040,7 @@ TemporaryTypeSet::getKnownClass(CompilerConstraintList *constraints)
if (clasp) {
for (unsigned i = 0; i < count; i++) {
TypeSetObjectKey *key = getObject(i);
ObjectKey *key = getObject(i);
if (key && !key->hasStableClassAndProto(constraints))
return nullptr;
}
@ -2182,7 +2182,7 @@ TemporaryTypeSet::getCommonPrototype(CompilerConstraintList *constraints)
unsigned count = getObjectCount();
for (unsigned i = 0; i < count; i++) {
TypeSetObjectKey *key = getObject(i);
ObjectKey *key = getObject(i);
if (!key)
continue;
@ -2202,7 +2202,7 @@ TemporaryTypeSet::getCommonPrototype(CompilerConstraintList *constraints)
// Guard against mutating __proto__.
for (unsigned i = 0; i < count; i++) {
TypeSetObjectKey *key = getObject(i);
ObjectKey *key = getObject(i);
if (key)
JS_ALWAYS_TRUE(key->hasStableClassAndProto(constraints));
}
@ -2217,7 +2217,7 @@ TemporaryTypeSet::propertyNeedsBarrier(CompilerConstraintList *constraints, jsid
return true;
for (unsigned i = 0; i < getObjectCount(); i++) {
TypeSetObjectKey *key = getObject(i);
ObjectKey *key = getObject(i);
if (!key)
continue;
@ -2241,11 +2241,11 @@ ClassCanHaveExtraProperties(const Class *clasp)
|| IsAnyTypedArrayClass(clasp);
}
static inline bool
static bool
PrototypeHasIndexedProperty(CompilerConstraintList *constraints, JSObject *obj)
{
do {
TypeSetObjectKey *key = TypeSetObjectKey::get(obj);
TypeSet::ObjectKey *key = TypeSet::ObjectKey::get(obj);
if (ClassCanHaveExtraProperties(key->clasp()))
return true;
if (key->unknownProperties())
@ -2260,7 +2260,7 @@ PrototypeHasIndexedProperty(CompilerConstraintList *constraints, JSObject *obj)
}
bool
types::ArrayPrototypeHasIndexedProperty(CompilerConstraintList *constraints, JSScript *script)
js::ArrayPrototypeHasIndexedProperty(CompilerConstraintList *constraints, JSScript *script)
{
if (JSObject *proto = script->global().maybeGetArrayPrototype())
return PrototypeHasIndexedProperty(constraints, proto);
@ -2268,8 +2268,8 @@ types::ArrayPrototypeHasIndexedProperty(CompilerConstraintList *constraints, JSS
}
bool
types::TypeCanHaveExtraIndexedProperties(CompilerConstraintList *constraints,
TemporaryTypeSet *types)
js::TypeCanHaveExtraIndexedProperties(CompilerConstraintList *constraints,
TemporaryTypeSet *types)
{
const Class *clasp = types->getKnownClass(constraints);
@ -2348,7 +2348,7 @@ TypeZone::addPendingRecompile(JSContext *cx, JSScript *script)
}
void
types::PrintTypes(JSContext *cx, JSCompartment *comp, bool force)
js::PrintTypes(JSContext *cx, JSCompartment *comp, bool force)
{
#ifdef DEBUG
gc::AutoSuppressGC suppressGC(cx);
@ -2388,7 +2388,7 @@ UpdatePropertyType(ExclusiveContext *cx, HeapTypeSet *types, NativeObject *obj,
if (shape->hasGetterValue() || shape->hasSetterValue()) {
types->setNonDataProperty(cx);
types->TypeSet::addType(Type::UnknownType(), &cx->typeLifoAlloc());
types->TypeSet::addType(TypeSet::UnknownType(), &cx->typeLifoAlloc());
} else if (shape->hasDefaultGetter() && shape->hasSlot()) {
if (!indexed && types->canSetDefinite(shape->slot()))
types->setDefinite(shape->slot());
@ -2403,11 +2403,11 @@ UpdatePropertyType(ExclusiveContext *cx, HeapTypeSet *types, NativeObject *obj,
* Also don't add untracked values (initial uninitialized lexical
* magic values and optimized out values) as appearing in CallObjects.
*/
MOZ_ASSERT_IF(IsUntrackedValue(value), obj->is<CallObject>());
MOZ_ASSERT_IF(TypeSet::IsUntrackedValue(value), obj->is<CallObject>());
if ((indexed || !value.isUndefined() || !CanHaveEmptyPropertyTypesForOwnProperty(obj)) &&
!IsUntrackedValue(value))
!TypeSet::IsUntrackedValue(value))
{
Type type = GetValueType(value);
TypeSet::Type type = TypeSet::GetValueType(value);
types->TypeSet::addType(type, &cx->typeLifoAlloc());
}
@ -2416,7 +2416,7 @@ UpdatePropertyType(ExclusiveContext *cx, HeapTypeSet *types, NativeObject *obj,
} else {
InferSpew(ISpewOps, "typeSet: %sT%p%s property %s %s - setConstant",
InferSpewColor(types), types, InferSpewColorReset(),
ObjectGroupString(obj->group()), TypeIdString(shape->propid()));
TypeSet::ObjectGroupString(obj->group()), TypeIdString(shape->propid()));
}
}
}
@ -2426,7 +2426,7 @@ ObjectGroup::updateNewPropertyTypes(ExclusiveContext *cx, jsid id, HeapTypeSet *
{
InferSpew(ISpewOps, "typeSet: %sT%p%s property %s %s",
InferSpewColor(types), types, InferSpewColorReset(),
ObjectGroupString(this), TypeIdString(id));
TypeSet::ObjectGroupString(this), TypeIdString(id));
if (!singleton() || !singleton()->isNative()) {
types->setNonConstantProperty(cx);
@ -2455,7 +2455,7 @@ ObjectGroup::updateNewPropertyTypes(ExclusiveContext *cx, jsid id, HeapTypeSet *
for (size_t i = 0; i < obj->getDenseInitializedLength(); i++) {
const Value &value = obj->getDenseElement(i);
if (!value.isMagic(JS_ELEMENTS_HOLE)) {
Type type = GetValueType(value);
TypeSet::Type type = TypeSet::GetValueType(value);
types->TypeSet::addType(type, &cx->typeLifoAlloc());
}
}
@ -2531,7 +2531,7 @@ ObjectGroup::matchDefiniteProperties(HandleObject obj)
}
void
types::AddTypePropertyId(ExclusiveContext *cx, ObjectGroup *group, jsid id, Type type)
js::AddTypePropertyId(ExclusiveContext *cx, ObjectGroup *group, jsid id, TypeSet::Type type)
{
MOZ_ASSERT(id == IdToTypeId(id));
@ -2547,7 +2547,7 @@ types::AddTypePropertyId(ExclusiveContext *cx, ObjectGroup *group, jsid id, Type
// Clear any constant flag if it exists.
if (!types->empty() && !types->nonConstantProperty()) {
InferSpew(ISpewOps, "constantMutated: %sT%p%s %s",
InferSpewColor(types), types, InferSpewColorReset(), TypeString(type));
InferSpewColor(types), types, InferSpewColorReset(), TypeSet::TypeString(type));
types->setNonConstantProperty(cx);
}
@ -2555,7 +2555,7 @@ types::AddTypePropertyId(ExclusiveContext *cx, ObjectGroup *group, jsid id, Type
return;
InferSpew(ISpewOps, "externalType: property %s %s: %s",
ObjectGroupString(group), TypeIdString(id), TypeString(type));
TypeSet::ObjectGroupString(group), TypeIdString(id), TypeSet::TypeString(type));
types->addType(cx, type);
// Propagate new types from partially initialized groups to fully
@ -2565,15 +2565,15 @@ types::AddTypePropertyId(ExclusiveContext *cx, ObjectGroup *group, jsid id, Type
// from acquiring the fully initialized group.
if (group->newScript() && group->newScript()->initializedGroup()) {
if (type.isObjectUnchecked() && types->unknownObject())
type = Type::AnyObjectType();
type = TypeSet::AnyObjectType();
AddTypePropertyId(cx, group->newScript()->initializedGroup(), id, type);
}
}
void
types::AddTypePropertyId(ExclusiveContext *cx, ObjectGroup *group, jsid id, const Value &value)
js::AddTypePropertyId(ExclusiveContext *cx, ObjectGroup *group, jsid id, const Value &value)
{
AddTypePropertyId(cx, group, id, GetValueType(value));
AddTypePropertyId(cx, group, id, TypeSet::GetValueType(value));
}
void
@ -2655,7 +2655,7 @@ ObjectGroup::setFlags(ExclusiveContext *cx, ObjectGroupFlags flags)
addFlags(flags);
InferSpew(ISpewOps, "%s: setFlags 0x%x", ObjectGroupString(this), flags);
InferSpew(ISpewOps, "%s: setFlags 0x%x", TypeSet::ObjectGroupString(this), flags);
ObjectStateChange(cx, this, false);
@ -2673,7 +2673,7 @@ ObjectGroup::markUnknown(ExclusiveContext *cx)
MOZ_ASSERT(cx->zone()->types.activeAnalysis);
MOZ_ASSERT(!unknownProperties());
InferSpew(ISpewOps, "UnknownProperties: %s", ObjectGroupString(this));
InferSpew(ISpewOps, "UnknownProperties: %s", TypeSet::ObjectGroupString(this));
clearNewScript(cx);
ObjectStateChange(cx, this, true);
@ -2691,7 +2691,7 @@ ObjectGroup::markUnknown(ExclusiveContext *cx)
for (unsigned i = 0; i < count; i++) {
Property *prop = getProperty(i);
if (prop) {
prop->types.addType(cx, Type::UnknownType());
prop->types.addType(cx, TypeSet::UnknownType());
prop->types.setNonDataProperty(cx);
}
}
@ -2800,8 +2800,8 @@ ObjectGroup::print()
{
TaggedProto tagged(proto());
fprintf(stderr, "%s : %s",
ObjectGroupString(this),
tagged.isObject() ? TypeString(Type::ObjectType(tagged.toObject()))
TypeSet::ObjectGroupString(this),
tagged.isObject() ? TypeSet::TypeString(TypeSet::ObjectType(tagged.toObject()))
: (tagged.isLazy() ? "(lazy)" : "(null)"));
if (unknownProperties()) {
@ -2881,7 +2881,7 @@ class TypeConstraintClearDefiniteGetterSetter : public TypeConstraint
group->clearNewScript(cx);
}
void newType(JSContext *cx, TypeSet *source, Type type) {}
void newType(JSContext *cx, TypeSet *source, TypeSet::Type type) {}
bool sweep(TypeZone &zone, TypeConstraint **res) {
if (IsObjectGroupAboutToBeFinalized(&group))
@ -2892,7 +2892,7 @@ class TypeConstraintClearDefiniteGetterSetter : public TypeConstraint
};
bool
types::AddClearDefiniteGetterSetterForPrototypeChain(JSContext *cx, ObjectGroup *group, HandleId id)
js::AddClearDefiniteGetterSetterForPrototypeChain(JSContext *cx, ObjectGroup *group, HandleId id)
{
/*
* Ensure that if the properties named here could have a getter, setter or
@ -2929,7 +2929,7 @@ class TypeConstraintClearDefiniteSingle : public TypeConstraint
const char *kind() { return "clearDefiniteSingle"; }
void newType(JSContext *cx, TypeSet *source, Type type) {
void newType(JSContext *cx, TypeSet *source, TypeSet::Type type) {
if (source->baseFlags() || source->getObjectCount() > 1)
group->clearNewScript(cx);
}
@ -2943,7 +2943,7 @@ class TypeConstraintClearDefiniteSingle : public TypeConstraint
};
bool
types::AddClearDefiniteFunctionUsesInScript(JSContext *cx, ObjectGroup *group,
js::AddClearDefiniteFunctionUsesInScript(JSContext *cx, ObjectGroup *group,
JSScript *script, JSScript *calleeScript)
{
// Look for any uses of the specified calleeScript in type sets for
@ -2954,7 +2954,8 @@ types::AddClearDefiniteFunctionUsesInScript(JSContext *cx, ObjectGroup *group,
// contain a single object, as IonBuilder does not inline polymorphic sites
// during the definite properties analysis.
TypeSetObjectKey *calleeKey = Type::ObjectType(calleeScript->functionNonDelazifying()).objectKey();
TypeSet::ObjectKey *calleeKey =
TypeSet::ObjectType(calleeScript->functionNonDelazifying()).objectKey();
unsigned count = TypeScript::NumTypeSets(script);
StackTypeSet *typeArray = script->types()->typeArray();
@ -2990,8 +2991,7 @@ types::AddClearDefiniteFunctionUsesInScript(JSContext *cx, ObjectGroup *group,
/////////////////////////////////////////////////////////////////////
void
types::TypeMonitorCallSlow(JSContext *cx, JSObject *callee, const CallArgs &args,
bool constructing)
js::TypeMonitorCallSlow(JSContext *cx, JSObject *callee, const CallArgs &args, bool constructing)
{
unsigned nargs = callee->as<JSFunction>().nargs();
JSScript *script = callee->as<JSFunction>().nonLazyScript();
@ -3014,18 +3014,18 @@ types::TypeMonitorCallSlow(JSContext *cx, JSObject *callee, const CallArgs &args
}
static inline bool
IsAboutToBeFinalized(TypeSetObjectKey **keyp)
IsAboutToBeFinalized(TypeSet::ObjectKey **keyp)
{
// Mask out the low bit indicating whether this is a group or JS object.
uintptr_t flagBit = uintptr_t(*keyp) & 1;
gc::Cell *tmp = reinterpret_cast<gc::Cell *>(uintptr_t(*keyp) & ~1);
bool isAboutToBeFinalized = IsCellAboutToBeFinalized(&tmp);
*keyp = reinterpret_cast<TypeSetObjectKey *>(uintptr_t(tmp) | flagBit);
*keyp = reinterpret_cast<TypeSet::ObjectKey *>(uintptr_t(tmp) | flagBit);
return isAboutToBeFinalized;
}
void
types::FillBytecodeTypeMap(JSScript *script, uint32_t *bytecodeMap)
js::FillBytecodeTypeMap(JSScript *script, uint32_t *bytecodeMap)
{
uint32_t added = 0;
for (jsbytecode *pc = script->code(); pc < script->codeEnd(); pc += GetBytecodeLength(pc)) {
@ -3040,7 +3040,7 @@ types::FillBytecodeTypeMap(JSScript *script, uint32_t *bytecodeMap)
}
void
types::TypeMonitorResult(JSContext *cx, JSScript *script, jsbytecode *pc, const js::Value &rval)
js::TypeMonitorResult(JSContext *cx, JSScript *script, jsbytecode *pc, const js::Value &rval)
{
/* Allow the non-TYPESET scenario to simplify stubs used in compound opcodes. */
if (!(js_CodeSpec[*pc].format & JOF_TYPESET))
@ -3051,13 +3051,13 @@ types::TypeMonitorResult(JSContext *cx, JSScript *script, jsbytecode *pc, const
AutoEnterAnalysis enter(cx);
Type type = GetValueType(rval);
TypeSet::Type type = TypeSet::GetValueType(rval);
StackTypeSet *types = TypeScript::BytecodeTypes(script, pc);
if (types->hasType(type))
return;
InferSpew(ISpewOps, "bytecodeType: %p %05u: %s",
script, script->pcToOffset(pc), TypeString(type));
script, script->pcToOffset(pc), TypeSet::TypeString(type));
types->addType(cx, type);
}
@ -3688,18 +3688,18 @@ ConstraintTypeSet::sweep(Zone *zone, AutoClearTypeInferenceStateOnOOM &oom)
*/
unsigned objectCount = baseObjectCount();
if (objectCount >= 2) {
unsigned oldCapacity = HashSetCapacity(objectCount);
TypeSetObjectKey **oldArray = objectSet;
unsigned oldCapacity = TypeHashSet::Capacity(objectCount);
ObjectKey **oldArray = objectSet;
clearObjects();
objectCount = 0;
for (unsigned i = 0; i < oldCapacity; i++) {
TypeSetObjectKey *key = oldArray[i];
ObjectKey *key = oldArray[i];
if (!key)
continue;
if (!IsAboutToBeFinalized(&key)) {
TypeSetObjectKey **pentry =
HashSetInsert<TypeSetObjectKey *,TypeSetObjectKey,TypeSetObjectKey>
ObjectKey **pentry =
TypeHashSet::Insert<ObjectKey *, ObjectKey, ObjectKey>
(zone->types.typeLifoAlloc, objectSet, objectCount, key);
if (pentry) {
*pentry = key;
@ -3722,9 +3722,9 @@ ConstraintTypeSet::sweep(Zone *zone, AutoClearTypeInferenceStateOnOOM &oom)
}
setBaseObjectCount(objectCount);
} else if (objectCount == 1) {
TypeSetObjectKey *key = (TypeSetObjectKey *) objectSet;
ObjectKey *key = (ObjectKey *) objectSet;
if (!IsAboutToBeFinalized(&key)) {
objectSet = reinterpret_cast<TypeSetObjectKey **>(key);
objectSet = reinterpret_cast<ObjectKey **>(key);
} else {
// As above, mark type sets containing objects with unknown
// properties as unknown.
@ -3823,7 +3823,7 @@ ObjectGroup::maybeSweep(AutoClearTypeInferenceStateOnOOM *oom)
*/
unsigned propertyCount = basePropertyCount();
if (propertyCount >= 2) {
unsigned oldCapacity = HashSetCapacity(propertyCount);
unsigned oldCapacity = TypeHashSet::Capacity(propertyCount);
Property **oldArray = propertySet;
clearProperties();
@ -3843,9 +3843,8 @@ ObjectGroup::maybeSweep(AutoClearTypeInferenceStateOnOOM *oom)
Property *newProp = typeLifoAlloc.new_<Property>(*prop);
if (newProp) {
Property **pentry =
HashSetInsert<jsid,Property,Property>
(typeLifoAlloc, propertySet, propertyCount, prop->id);
Property **pentry = TypeHashSet::Insert<jsid, Property, Property>
(typeLifoAlloc, propertySet, propertyCount, prop->id);
if (pentry) {
*pentry = newProp;
newProp->types.sweep(zone(), *oom);

View File

@ -23,7 +23,6 @@
#include "js/UbiNode.h"
#include "js/Utility.h"
#include "js/Vector.h"
#include "vm/ObjectGroup.h"
namespace js {
@ -33,122 +32,12 @@ namespace jit {
class TempAllocator;
}
namespace types {
class TaggedProto;
struct TypeZone;
class TypeSet;
struct TypeSetObjectKey;
/*
* Information about a single concrete type. We pack this into a single word,
* where small values are particular primitive or other singleton types, and
* larger values are either specific JS objects or object groups.
*/
class Type
{
uintptr_t data;
explicit Type(uintptr_t data) : data(data) {}
public:
uintptr_t raw() const { return data; }
bool isPrimitive() const {
return data < JSVAL_TYPE_OBJECT;
}
bool isPrimitive(JSValueType type) const {
MOZ_ASSERT(type < JSVAL_TYPE_OBJECT);
return (uintptr_t) type == data;
}
JSValueType primitive() const {
MOZ_ASSERT(isPrimitive());
return (JSValueType) data;
}
bool isMagicArguments() const {
return primitive() == JSVAL_TYPE_MAGIC;
}
bool isSomeObject() const {
return data == JSVAL_TYPE_OBJECT || data > JSVAL_TYPE_UNKNOWN;
}
bool isAnyObject() const {
return data == JSVAL_TYPE_OBJECT;
}
bool isUnknown() const {
return data == JSVAL_TYPE_UNKNOWN;
}
/* Accessors for types that are either JSObject or ObjectGroup. */
bool isObject() const {
MOZ_ASSERT(!isAnyObject() && !isUnknown());
return data > JSVAL_TYPE_UNKNOWN;
}
bool isObjectUnchecked() const {
return data > JSVAL_TYPE_UNKNOWN;
}
inline TypeSetObjectKey *objectKey() const;
/* Accessors for JSObject types */
bool isSingleton() const {
return isObject() && !!(data & 1);
}
inline JSObject *singleton() const;
inline JSObject *singletonNoBarrier() const;
/* Accessors for ObjectGroup types */
bool isGroup() const {
return isObject() && !(data & 1);
}
inline ObjectGroup *group() const;
inline ObjectGroup *groupNoBarrier() const;
bool operator == (Type o) const { return data == o.data; }
bool operator != (Type o) const { return data != o.data; }
static inline Type UndefinedType() { return Type(JSVAL_TYPE_UNDEFINED); }
static inline Type NullType() { return Type(JSVAL_TYPE_NULL); }
static inline Type BooleanType() { return Type(JSVAL_TYPE_BOOLEAN); }
static inline Type Int32Type() { return Type(JSVAL_TYPE_INT32); }
static inline Type DoubleType() { return Type(JSVAL_TYPE_DOUBLE); }
static inline Type StringType() { return Type(JSVAL_TYPE_STRING); }
static inline Type SymbolType() { return Type(JSVAL_TYPE_SYMBOL); }
static inline Type MagicArgType() { return Type(JSVAL_TYPE_MAGIC); }
static inline Type AnyObjectType() { return Type(JSVAL_TYPE_OBJECT); }
static inline Type UnknownType() { return Type(JSVAL_TYPE_UNKNOWN); }
static inline Type PrimitiveType(JSValueType type) {
MOZ_ASSERT(type < JSVAL_TYPE_UNKNOWN);
return Type(type);
}
static inline Type ObjectType(JSObject *obj);
static inline Type ObjectType(ObjectGroup *group);
static inline Type ObjectType(TypeSetObjectKey *key);
static js::ThingRootKind rootKind() { return js::THING_ROOT_TYPE; }
};
/* Get the type of a jsval, or zero for an unknown special value. */
inline Type GetValueType(const Value &val);
/*
* Get the type of a possibly optimized out or uninitialized let value. This
* generally only happens on unconditional type monitors on bailing out of
* Ion, such as for argument and local types.
*/
inline Type GetMaybeUntrackedValueType(const Value &val);
class TypeConstraint;
class TypeNewScript;
class CompilerConstraintList;
class HeapTypeSetKey;
/*
* Type inference memory management overview.
@ -162,46 +51,6 @@ inline Type GetMaybeUntrackedValueType(const Value &val);
* Thus, type set and constraints only hold weak references.
*/
/*
* A constraint which listens to additions to a type set and propagates those
* changes to other type sets.
*/
class TypeConstraint
{
public:
/* Next constraint listening to the same type set. */
TypeConstraint *next;
TypeConstraint()
: next(nullptr)
{}
/* Debugging name for this kind of constraint. */
virtual const char *kind() = 0;
/* Register a new type for the set this constraint is listening to. */
virtual void newType(JSContext *cx, TypeSet *source, Type type) = 0;
/*
* For constraints attached to an object property's type set, mark the
* property as having changed somehow.
*/
virtual void newPropertyState(JSContext *cx, TypeSet *source) {}
/*
* For constraints attached to the JSID_EMPTY type set on an object,
* indicate a change in one of the object's dynamic property flags or other
* state.
*/
virtual void newObjectState(JSContext *cx, ObjectGroup *group) {}
/*
* If the data this constraint refers to is still live, copy it into the
* zone's new allocator. Type constraints only hold weak references.
*/
virtual bool sweep(TypeZone &zone, TypeConstraint **res) = 0;
};
/* Flags and other state stored in TypeSet::flags */
enum : uint32_t {
TYPE_FLAG_UNDEFINED = 0x1,
@ -261,6 +110,81 @@ enum : uint32_t {
};
typedef uint32_t TypeFlags;
/* Flags and other state stored in ObjectGroup::Flags */
enum : uint32_t {
/* Whether this group is associated with some allocation site. */
OBJECT_FLAG_FROM_ALLOCATION_SITE = 0x1,
/* (0x2 and 0x4 are unused) */
/* Mask/shift for the number of properties in propertySet */
OBJECT_FLAG_PROPERTY_COUNT_MASK = 0xfff8,
OBJECT_FLAG_PROPERTY_COUNT_SHIFT = 3,
OBJECT_FLAG_PROPERTY_COUNT_LIMIT =
OBJECT_FLAG_PROPERTY_COUNT_MASK >> OBJECT_FLAG_PROPERTY_COUNT_SHIFT,
/* Whether any objects this represents may have sparse indexes. */
OBJECT_FLAG_SPARSE_INDEXES = 0x00010000,
/* Whether any objects this represents may not have packed dense elements. */
OBJECT_FLAG_NON_PACKED = 0x00020000,
/*
* Whether any objects this represents may be arrays whose length does not
* fit in an int32.
*/
OBJECT_FLAG_LENGTH_OVERFLOW = 0x00040000,
/* Whether any objects have been iterated over. */
OBJECT_FLAG_ITERATED = 0x00080000,
/* For a global object, whether flags were set on the RegExpStatics. */
OBJECT_FLAG_REGEXP_FLAGS_SET = 0x00100000,
/*
* For the function on a run-once script, whether the function has actually
* run multiple times.
*/
OBJECT_FLAG_RUNONCE_INVALIDATED = 0x00200000,
/*
* For a global object, whether any array buffers in this compartment with
* typed object views have been neutered.
*/
OBJECT_FLAG_TYPED_OBJECT_NEUTERED = 0x00400000,
/*
* Whether objects with this type should be allocated directly in the
* tenured heap.
*/
OBJECT_FLAG_PRE_TENURE = 0x00800000,
/* Whether objects with this type might have copy on write elements. */
OBJECT_FLAG_COPY_ON_WRITE = 0x01000000,
/* Whether this type has had its 'new' script cleared in the past. */
OBJECT_FLAG_NEW_SCRIPT_CLEARED = 0x02000000,
/*
* Whether all properties of this object are considered unknown.
* If set, all other flags in DYNAMIC_MASK will also be set.
*/
OBJECT_FLAG_UNKNOWN_PROPERTIES = 0x04000000,
/* Flags which indicate dynamic properties of represented objects. */
OBJECT_FLAG_DYNAMIC_MASK = 0x07ff0000,
// Mask/shift for the kind of addendum attached to this group.
OBJECT_FLAG_ADDENDUM_MASK = 0x38000000,
OBJECT_FLAG_ADDENDUM_SHIFT = 27,
// Mask/shift for this group's generation. If out of sync with the
// TypeZone's generation, this group hasn't been swept yet.
OBJECT_FLAG_GENERATION_MASK = 0x40000000,
OBJECT_FLAG_GENERATION_SHIFT = 30,
};
typedef uint32_t ObjectGroupFlags;
class StackTypeSet;
class HeapTypeSet;
class TemporaryTypeSet;
@ -271,11 +195,12 @@ class TemporaryTypeSet;
*
* - StackTypeSet are associated with TypeScripts, for arguments and values
* observed at property reads. These are implicitly frozen on compilation
* and do not have constraints attached to them.
* and only have constraints added to them which can trigger invalidation of
* TypeNewScript information.
*
* - HeapTypeSet are associated with the properties of ObjectGroups. These
* may have constraints added to them to trigger invalidation of compiled
* code.
* may have constraints added to them to trigger invalidation of either
* compiled code or TypeNewScript information.
*
* - TemporaryTypeSet are created during compilation and do not outlive
* that compilation.
@ -289,12 +214,162 @@ class TemporaryTypeSet;
*/
class TypeSet
{
public:
// Type set entry for either a JSObject with singleton type or a
// non-singleton ObjectGroup.
class ObjectKey {
public:
static intptr_t keyBits(ObjectKey *obj) { return (intptr_t) obj; }
static ObjectKey *getKey(ObjectKey *obj) { return obj; }
static inline ObjectKey *get(JSObject *obj);
static inline ObjectKey *get(ObjectGroup *group);
bool isGroup() {
return (uintptr_t(this) & 1) == 0;
}
bool isSingleton() {
return (uintptr_t(this) & 1) != 0;
}
inline ObjectGroup *group();
inline JSObject *singleton();
inline ObjectGroup *groupNoBarrier();
inline JSObject *singletonNoBarrier();
const Class *clasp();
TaggedProto proto();
TypeNewScript *newScript();
bool unknownProperties();
bool hasFlags(CompilerConstraintList *constraints, ObjectGroupFlags flags);
bool hasStableClassAndProto(CompilerConstraintList *constraints);
void watchStateChangeForInlinedCall(CompilerConstraintList *constraints);
void watchStateChangeForTypedArrayData(CompilerConstraintList *constraints);
HeapTypeSetKey property(jsid id);
void ensureTrackedProperty(JSContext *cx, jsid id);
ObjectGroup *maybeGroup();
};
// Information about a single concrete type. We pack this into one word,
// where small values are particular primitive or other singleton types and
// larger values are either specific JS objects or object groups.
class Type
{
friend class TypeSet;
uintptr_t data;
explicit Type(uintptr_t data) : data(data) {}
public:
uintptr_t raw() const { return data; }
bool isPrimitive() const {
return data < JSVAL_TYPE_OBJECT;
}
bool isPrimitive(JSValueType type) const {
MOZ_ASSERT(type < JSVAL_TYPE_OBJECT);
return (uintptr_t) type == data;
}
JSValueType primitive() const {
MOZ_ASSERT(isPrimitive());
return (JSValueType) data;
}
bool isMagicArguments() const {
return primitive() == JSVAL_TYPE_MAGIC;
}
bool isSomeObject() const {
return data == JSVAL_TYPE_OBJECT || data > JSVAL_TYPE_UNKNOWN;
}
bool isAnyObject() const {
return data == JSVAL_TYPE_OBJECT;
}
bool isUnknown() const {
return data == JSVAL_TYPE_UNKNOWN;
}
/* Accessors for types that are either JSObject or ObjectGroup. */
bool isObject() const {
MOZ_ASSERT(!isAnyObject() && !isUnknown());
return data > JSVAL_TYPE_UNKNOWN;
}
bool isObjectUnchecked() const {
return data > JSVAL_TYPE_UNKNOWN;
}
inline ObjectKey *objectKey() const;
/* Accessors for JSObject types */
bool isSingleton() const {
return isObject() && !!(data & 1);
}
inline JSObject *singleton() const;
inline JSObject *singletonNoBarrier() const;
/* Accessors for ObjectGroup types */
bool isGroup() const {
return isObject() && !(data & 1);
}
inline ObjectGroup *group() const;
inline ObjectGroup *groupNoBarrier() const;
bool operator == (Type o) const { return data == o.data; }
bool operator != (Type o) const { return data != o.data; }
static ThingRootKind rootKind() { return THING_ROOT_TYPE; }
};
static inline Type UndefinedType() { return Type(JSVAL_TYPE_UNDEFINED); }
static inline Type NullType() { return Type(JSVAL_TYPE_NULL); }
static inline Type BooleanType() { return Type(JSVAL_TYPE_BOOLEAN); }
static inline Type Int32Type() { return Type(JSVAL_TYPE_INT32); }
static inline Type DoubleType() { return Type(JSVAL_TYPE_DOUBLE); }
static inline Type StringType() { return Type(JSVAL_TYPE_STRING); }
static inline Type SymbolType() { return Type(JSVAL_TYPE_SYMBOL); }
static inline Type MagicArgType() { return Type(JSVAL_TYPE_MAGIC); }
static inline Type AnyObjectType() { return Type(JSVAL_TYPE_OBJECT); }
static inline Type UnknownType() { return Type(JSVAL_TYPE_UNKNOWN); }
static inline Type PrimitiveType(JSValueType type) {
MOZ_ASSERT(type < JSVAL_TYPE_UNKNOWN);
return Type(type);
}
static inline Type ObjectType(JSObject *obj);
static inline Type ObjectType(ObjectGroup *group);
static inline Type ObjectType(ObjectKey *key);
static const char *NonObjectTypeString(Type type);
#ifdef DEBUG
static const char *TypeString(Type type);
static const char *ObjectGroupString(ObjectGroup *group);
#else
static const char *TypeString(Type type) { return nullptr; }
static const char *ObjectGroupString(ObjectGroup *group) { return nullptr; }
#endif
protected:
/* Flags for this type set. */
TypeFlags flags;
/* Possible objects this type set can represent. */
TypeSetObjectKey **objectSet;
ObjectKey **objectSet;
public:
@ -350,7 +425,7 @@ class TypeSet
* may return nullptr.
*/
inline unsigned getObjectCount() const;
inline TypeSetObjectKey *getObject(unsigned i) const;
inline ObjectKey *getObject(unsigned i) const;
inline JSObject *getSingleton(unsigned i) const;
inline ObjectGroup *getGroup(unsigned i) const;
inline JSObject *getSingletonNoBarrier(unsigned i) const;
@ -412,6 +487,58 @@ class TypeSet
inline void setBaseObjectCount(uint32_t count);
void clearObjects();
public:
static inline Type GetValueType(const Value &val);
static inline bool IsUntrackedValue(const Value &val);
// Get the type of a possibly optimized out or uninitialized let value.
// This generally only happens on unconditional type monitors on bailing
// out of Ion, such as for argument and local types.
static inline Type GetMaybeUntrackedValueType(const Value &val);
static void MarkTypeRoot(JSTracer *trc, Type *v, const char *name);
};
/*
* A constraint which listens to additions to a type set and propagates those
* changes to other type sets.
*/
class TypeConstraint
{
public:
/* Next constraint listening to the same type set. */
TypeConstraint *next;
TypeConstraint()
: next(nullptr)
{}
/* Debugging name for this kind of constraint. */
virtual const char *kind() = 0;
/* Register a new type for the set this constraint is listening to. */
virtual void newType(JSContext *cx, TypeSet *source, TypeSet::Type type) = 0;
/*
* For constraints attached to an object property's type set, mark the
* property as having changed somehow.
*/
virtual void newPropertyState(JSContext *cx, TypeSet *source) {}
/*
* For constraints attached to the JSID_EMPTY type set on an object,
* indicate a change in one of the object's dynamic property flags or other
* state.
*/
virtual void newObjectState(JSContext *cx, ObjectGroup *group) {}
/*
* If the data this constraint refers to is still live, copy it into the
* zone's new allocator. Type constraints only hold weak references.
*/
virtual bool sweep(TypeZone &zone, TypeConstraint **res) = 0;
};
// If there is an OOM while sweeping types, the type information is deoptimized
@ -487,7 +614,7 @@ class TemporaryTypeSet : public TypeSet
TemporaryTypeSet() {}
TemporaryTypeSet(LifoAlloc *alloc, Type type);
TemporaryTypeSet(uint32_t flags, TypeSetObjectKey **objectSet) {
TemporaryTypeSet(uint32_t flags, ObjectKey **objectSet) {
this->flags = flags;
this->objectSet = objectSet;
}
@ -772,66 +899,6 @@ class TypeNewScript
/* Is this a reasonable PC to be doing inlining on? */
inline bool isInlinableCall(jsbytecode *pc);
/*
* Type information about a property.
*
* The type sets in the properties of a group describe the possible values
* that can be read out of that property in actual JS objects. In native
* objects, property types account for plain data properties (those with a
* slot and no getter or setter hook) and dense elements. In typed objects
* and unboxed objects, property types account for object and value
* properties and elements in the object.
*
* For accesses on these properties, the correspondence is as follows:
*
* 1. If the group has unknownProperties(), the possible properties and
* value types for associated JSObjects are unknown.
*
* 2. Otherwise, for any |obj| in |group|, and any |id| which is a property
* in |obj|, before obj->getProperty(id) the property in |group| for
* |id| must reflect the result of the getProperty.
*
* There are several exceptions to this:
*
* 1. For properties of global JS objects which are undefined at the point
* where the property was (lazily) generated, the property type set will
* remain empty, and the 'undefined' type will only be added after a
* subsequent assignment or deletion. After these properties have been
* assigned a defined value, the only way they can become undefined
* again is after such an assign or deletion.
*
* 2. Array lengths are special cased by the compiler and VM and are not
* reflected in property types.
*
* 3. In typed objects (but not unboxed objects), the initial values of
* properties (null pointers and undefined values) are not reflected in
* the property types. These values are always possible when reading the
* property.
*
* We establish these by using write barriers on calls to setProperty and
* defineProperty which are on native properties, and on any jitcode which
* might update the property with a new type.
*/
struct Property
{
/* Identifier for this property, JSID_VOID for the aggregate integer index property. */
HeapId id;
/* Possible types for this property, including types inherited from prototypes. */
HeapTypeSet types;
explicit Property(jsid id)
: id(id)
{}
Property(const Property &o)
: id(o.id.get()), types(o.types)
{}
static uint32_t keyBits(jsid id) { return uint32_t(JSID_BITS(id)); }
static jsid getKey(Property *p) { return p->id; }
};
/*
* Whether Array.prototype, or an object on its proto chain, has an
* indexed property.
@ -894,9 +961,10 @@ class TypeScript
static inline void MonitorAssign(JSContext *cx, HandleObject obj, jsid id);
/* Add a type for a variable in a script. */
static inline void SetThis(JSContext *cx, JSScript *script, Type type);
static inline void SetThis(JSContext *cx, JSScript *script, TypeSet::Type type);
static inline void SetThis(JSContext *cx, JSScript *script, const js::Value &value);
static inline void SetArgument(JSContext *cx, JSScript *script, unsigned arg, Type type);
static inline void SetArgument(JSContext *cx, JSScript *script, unsigned arg,
TypeSet::Type type);
static inline void SetArgument(JSContext *cx, JSScript *script, unsigned arg,
const js::Value &value);
@ -940,45 +1008,6 @@ FinishCompilation(JSContext *cx, HandleScript script, CompilerConstraintList *co
void
FinishDefinitePropertiesAnalysis(JSContext *cx, CompilerConstraintList *constraints);
class HeapTypeSetKey;
// Type set entry for either a JSObject with singleton type or a non-singleton ObjectGroup.
struct TypeSetObjectKey
{
static intptr_t keyBits(TypeSetObjectKey *obj) { return (intptr_t) obj; }
static TypeSetObjectKey *getKey(TypeSetObjectKey *obj) { return obj; }
static inline TypeSetObjectKey *get(JSObject *obj);
static inline TypeSetObjectKey *get(ObjectGroup *group);
bool isGroup() {
return (uintptr_t(this) & 1) == 0;
}
bool isSingleton() {
return (uintptr_t(this) & 1) != 0;
}
inline ObjectGroup *group();
inline JSObject *singleton();
inline ObjectGroup *groupNoBarrier();
inline JSObject *singletonNoBarrier();
const Class *clasp();
TaggedProto proto();
TypeNewScript *newScript();
bool unknownProperties();
bool hasFlags(CompilerConstraintList *constraints, ObjectGroupFlags flags);
bool hasStableClassAndProto(CompilerConstraintList *constraints);
void watchStateChangeForInlinedCall(CompilerConstraintList *constraints);
void watchStateChangeForTypedArrayData(CompilerConstraintList *constraints);
HeapTypeSetKey property(jsid id);
void ensureTrackedProperty(JSContext *cx, jsid id);
ObjectGroup *maybeGroup();
};
// Representation of a heap type property which may or may not be instantiated.
// Heap properties for singleton types are instantiated lazily as they are used
// by the compiler, but this is only done on the main thread. If we are
@ -989,10 +1018,10 @@ struct TypeSetObjectKey
// during generation of baseline caches.
class HeapTypeSetKey
{
friend struct TypeSetObjectKey;
friend class TypeSet::ObjectKey;
// Object and property being accessed.
TypeSetObjectKey *object_;
TypeSet::ObjectKey *object_;
jsid id_;
// If instantiated, the underlying heap type set.
@ -1003,7 +1032,7 @@ class HeapTypeSetKey
: object_(nullptr), id_(JSID_EMPTY), maybeTypes_(nullptr)
{}
TypeSetObjectKey *object() const { return object_; }
TypeSet::ObjectKey *object() const { return object_; }
jsid id() const { return id_; }
HeapTypeSet *maybeTypes() const { return maybeTypes_; }
@ -1166,8 +1195,6 @@ enum SpewChannel {
SPEW_COUNT
};
const char *NonObjectTypeString(Type type);
#ifdef DEBUG
const char * InferSpewColorReset();
@ -1175,11 +1202,9 @@ const char * InferSpewColor(TypeConstraint *constraint);
const char * InferSpewColor(TypeSet *types);
void InferSpew(SpewChannel which, const char *fmt, ...);
const char * TypeString(Type type);
const char * ObjectGroupString(ObjectGroup *group);
/* Check that the type property for id in group contains value. */
bool TypeHasProperty(JSContext *cx, ObjectGroup *group, jsid id, const Value &value);
bool ObjectGroupHasProperty(JSContext *cx, ObjectGroup *group, jsid id, const Value &value);
#else
@ -1187,8 +1212,6 @@ inline const char * InferSpewColorReset() { return nullptr; }
inline const char * InferSpewColor(TypeConstraint *constraint) { return nullptr; }
inline const char * InferSpewColor(TypeSet *types) { return nullptr; }
inline void InferSpew(SpewChannel which, const char *fmt, ...) {}
inline const char * TypeString(Type type) { return nullptr; }
inline const char * ObjectGroupString(ObjectGroup *group) { return nullptr; }
#endif
@ -1199,7 +1222,6 @@ MOZ_NORETURN MOZ_COLD void TypeFailure(JSContext *cx, const char *fmt, ...);
void
PrintTypes(JSContext *cx, JSCompartment *comp, bool force);
} /* namespace types */
} /* namespace js */
// JS::ubi::Nodes can point to object groups; they're js::gc::Cell instances

View File

@ -27,7 +27,6 @@
#include "jscntxtinlines.h"
namespace js {
namespace types {
/////////////////////////////////////////////////////////////////////
// CompilerOutput & RecompileInfo
@ -92,40 +91,40 @@ RecompileInfo::shouldSweep(TypeZone &types)
// Types
/////////////////////////////////////////////////////////////////////
/* static */ inline TypeSetObjectKey *
TypeSetObjectKey::get(JSObject *obj)
/* static */ inline TypeSet::ObjectKey *
TypeSet::ObjectKey::get(JSObject *obj)
{
MOZ_ASSERT(obj);
if (obj->isSingleton())
return (TypeSetObjectKey *) (uintptr_t(obj) | 1);
return (TypeSetObjectKey *) obj->group();
return (ObjectKey *) (uintptr_t(obj) | 1);
return (ObjectKey *) obj->group();
}
/* static */ inline TypeSetObjectKey *
TypeSetObjectKey::get(ObjectGroup *group)
/* static */ inline TypeSet::ObjectKey *
TypeSet::ObjectKey::get(ObjectGroup *group)
{
MOZ_ASSERT(group);
if (group->singleton())
return (TypeSetObjectKey *) (uintptr_t(group->singleton()) | 1);
return (TypeSetObjectKey *) group;
return (ObjectKey *) (uintptr_t(group->singleton()) | 1);
return (ObjectKey *) group;
}
inline ObjectGroup *
TypeSetObjectKey::groupNoBarrier()
TypeSet::ObjectKey::groupNoBarrier()
{
MOZ_ASSERT(isGroup());
return (ObjectGroup *) this;
}
inline JSObject *
TypeSetObjectKey::singletonNoBarrier()
TypeSet::ObjectKey::singletonNoBarrier()
{
MOZ_ASSERT(isSingleton());
return (JSObject *) (uintptr_t(this) & ~1);
}
inline ObjectGroup *
TypeSetObjectKey::group()
TypeSet::ObjectKey::group()
{
ObjectGroup *res = groupNoBarrier();
ObjectGroup::readBarrier(res);
@ -133,56 +132,56 @@ TypeSetObjectKey::group()
}
inline JSObject *
TypeSetObjectKey::singleton()
TypeSet::ObjectKey::singleton()
{
JSObject *res = singletonNoBarrier();
JSObject::readBarrier(res);
return res;
}
/* static */ inline Type
Type::ObjectType(JSObject *obj)
/* static */ inline TypeSet::Type
TypeSet::ObjectType(JSObject *obj)
{
if (obj->isSingleton())
return Type(uintptr_t(obj) | 1);
return Type(uintptr_t(obj->group()));
}
/* static */ inline Type
Type::ObjectType(ObjectGroup *group)
/* static */ inline TypeSet::Type
TypeSet::ObjectType(ObjectGroup *group)
{
if (group->singleton())
return Type(uintptr_t(group->singleton()) | 1);
return Type(uintptr_t(group));
}
/* static */ inline Type
Type::ObjectType(TypeSetObjectKey *obj)
/* static */ inline TypeSet::Type
TypeSet::ObjectType(ObjectKey *obj)
{
return Type(uintptr_t(obj));
}
inline Type
GetValueType(const Value &val)
inline TypeSet::Type
TypeSet::GetValueType(const Value &val)
{
if (val.isDouble())
return Type::DoubleType();
return TypeSet::DoubleType();
if (val.isObject())
return Type::ObjectType(&val.toObject());
return Type::PrimitiveType(val.extractNonDoubleType());
return TypeSet::ObjectType(&val.toObject());
return TypeSet::PrimitiveType(val.extractNonDoubleType());
}
inline bool
IsUntrackedValue(const Value &val)
TypeSet::IsUntrackedValue(const Value &val)
{
return val.isMagic() && (val.whyMagic() == JS_OPTIMIZED_OUT ||
val.whyMagic() == JS_UNINITIALIZED_LEXICAL);
}
inline Type
GetMaybeUntrackedValueType(const Value &val)
inline TypeSet::Type
TypeSet::GetMaybeUntrackedValueType(const Value &val)
{
return IsUntrackedValue(val) ? Type::UnknownType() : GetValueType(val);
return IsUntrackedValue(val) ? UnknownType() : GetValueType(val);
}
inline TypeFlags
@ -398,7 +397,7 @@ PropertyHasBeenMarkedNonConstant(JSObject *obj, jsid id)
}
inline bool
HasTypePropertyId(JSObject *obj, jsid id, Type type)
HasTypePropertyId(JSObject *obj, jsid id, TypeSet::Type type)
{
if (obj->hasLazyGroup())
return true;
@ -415,15 +414,15 @@ HasTypePropertyId(JSObject *obj, jsid id, Type type)
inline bool
HasTypePropertyId(JSObject *obj, jsid id, const Value &value)
{
return HasTypePropertyId(obj, id, GetValueType(value));
return HasTypePropertyId(obj, id, TypeSet::GetValueType(value));
}
void AddTypePropertyId(ExclusiveContext *cx, ObjectGroup *group, jsid id, Type type);
void AddTypePropertyId(ExclusiveContext *cx, ObjectGroup *group, jsid id, TypeSet::Type type);
void AddTypePropertyId(ExclusiveContext *cx, ObjectGroup *group, jsid id, const Value &value);
/* Add a possible type for a property of obj. */
inline void
AddTypePropertyId(ExclusiveContext *cx, JSObject *obj, jsid id, Type type)
AddTypePropertyId(ExclusiveContext *cx, JSObject *obj, jsid id, TypeSet::Type type)
{
id = IdToTypeId(id);
if (TrackPropertyTypes(cx, obj, id))
@ -489,10 +488,8 @@ MarkObjectStateChange(ExclusiveContext *cx, JSObject *obj)
}
/* Interface helpers for JSScript*. */
extern void TypeMonitorResult(JSContext *cx, JSScript *script, jsbytecode *pc,
const js::Value &rval);
extern void TypeDynamicResult(JSContext *cx, JSScript *script, jsbytecode *pc,
js::types::Type type);
extern void TypeMonitorResult(JSContext *cx, JSScript *script, jsbytecode *pc, const Value &rval);
extern void TypeDynamicResult(JSContext *cx, JSScript *script, jsbytecode *pc, TypeSet::Type type);
/////////////////////////////////////////////////////////////////////
// Script interface functions
@ -622,7 +619,7 @@ TypeScript::MonitorAssign(JSContext *cx, HandleObject obj, jsid id)
}
/* static */ inline void
TypeScript::SetThis(JSContext *cx, JSScript *script, Type type)
TypeScript::SetThis(JSContext *cx, JSScript *script, TypeSet::Type type)
{
StackTypeSet *types = ThisTypes(script);
if (!types)
@ -632,7 +629,7 @@ TypeScript::SetThis(JSContext *cx, JSScript *script, Type type)
AutoEnterAnalysis enter(cx);
InferSpew(ISpewOps, "externalType: setThis %p: %s",
script, TypeString(type));
script, TypeSet::TypeString(type));
types->addType(cx, type);
}
}
@ -640,11 +637,11 @@ TypeScript::SetThis(JSContext *cx, JSScript *script, Type type)
/* static */ inline void
TypeScript::SetThis(JSContext *cx, JSScript *script, const js::Value &value)
{
SetThis(cx, script, GetValueType(value));
SetThis(cx, script, TypeSet::GetValueType(value));
}
/* static */ inline void
TypeScript::SetArgument(JSContext *cx, JSScript *script, unsigned arg, Type type)
TypeScript::SetArgument(JSContext *cx, JSScript *script, unsigned arg, TypeSet::Type type)
{
StackTypeSet *types = ArgTypes(script, arg);
if (!types)
@ -654,7 +651,7 @@ TypeScript::SetArgument(JSContext *cx, JSScript *script, unsigned arg, Type type
AutoEnterAnalysis enter(cx);
InferSpew(ISpewOps, "externalType: setArg %p %u: %s",
script, arg, TypeString(type));
script, arg, TypeSet::TypeString(type));
types->addType(cx, type);
}
}
@ -662,210 +659,211 @@ TypeScript::SetArgument(JSContext *cx, JSScript *script, unsigned arg, Type type
/* static */ inline void
TypeScript::SetArgument(JSContext *cx, JSScript *script, unsigned arg, const js::Value &value)
{
Type type = GetValueType(value);
SetArgument(cx, script, arg, type);
SetArgument(cx, script, arg, TypeSet::GetValueType(value));
}
/////////////////////////////////////////////////////////////////////
// TypeHashSet
/////////////////////////////////////////////////////////////////////
// Hashing code shared by objects in TypeSets and properties in ObjectGroups.
struct TypeHashSet
{
// The sets of objects in a type set grow monotonically, are usually empty,
// almost always small, and sometimes big. For empty or singleton sets, the
// the pointer refers directly to the value. For sets fitting into
// SET_ARRAY_SIZE, an array of this length is used to store the elements.
// For larger sets, a hash table filled to 25%-50% of capacity is used,
// with collisions resolved by linear probing.
static const unsigned SET_ARRAY_SIZE = 8;
static const unsigned SET_CAPACITY_OVERFLOW = 1u << 30;
// Get the capacity of a set with the given element count.
static inline unsigned
Capacity(unsigned count)
{
MOZ_ASSERT(count >= 2);
MOZ_ASSERT(count < SET_CAPACITY_OVERFLOW);
if (count <= SET_ARRAY_SIZE)
return SET_ARRAY_SIZE;
return 1u << (mozilla::FloorLog2(count) + 2);
}
// Compute the FNV hash for the low 32 bits of v.
template <class T, class KEY>
static inline uint32_t
HashKey(T v)
{
uint32_t nv = KEY::keyBits(v);
uint32_t hash = 84696351 ^ (nv & 0xff);
hash = (hash * 16777619) ^ ((nv >> 8) & 0xff);
hash = (hash * 16777619) ^ ((nv >> 16) & 0xff);
return (hash * 16777619) ^ ((nv >> 24) & 0xff);
}
// Insert space for an element into the specified set and grow its capacity
// if needed. returned value is an existing or new entry (nullptr if new).
template <class T, class U, class KEY>
static U **
InsertTry(LifoAlloc &alloc, U **&values, unsigned &count, T key)
{
unsigned capacity = Capacity(count);
unsigned insertpos = HashKey<T,KEY>(key) & (capacity - 1);
// Whether we are converting from a fixed array to hashtable.
bool converting = (count == SET_ARRAY_SIZE);
if (!converting) {
while (values[insertpos] != nullptr) {
if (KEY::getKey(values[insertpos]) == key)
return &values[insertpos];
insertpos = (insertpos + 1) & (capacity - 1);
}
}
if (count >= SET_CAPACITY_OVERFLOW)
return nullptr;
count++;
unsigned newCapacity = Capacity(count);
if (newCapacity == capacity) {
MOZ_ASSERT(!converting);
return &values[insertpos];
}
U **newValues = alloc.newArray<U*>(newCapacity);
if (!newValues)
return nullptr;
mozilla::PodZero(newValues, newCapacity);
for (unsigned i = 0; i < capacity; i++) {
if (values[i]) {
unsigned pos = HashKey<T,KEY>(KEY::getKey(values[i])) & (newCapacity - 1);
while (newValues[pos] != nullptr)
pos = (pos + 1) & (newCapacity - 1);
newValues[pos] = values[i];
}
}
values = newValues;
insertpos = HashKey<T,KEY>(key) & (newCapacity - 1);
while (values[insertpos] != nullptr)
insertpos = (insertpos + 1) & (newCapacity - 1);
return &values[insertpos];
}
// Insert an element into the specified set if it is not already there,
// returning an entry which is nullptr if the element was not there.
template <class T, class U, class KEY>
static inline U **
Insert(LifoAlloc &alloc, U **&values, unsigned &count, T key)
{
if (count == 0) {
MOZ_ASSERT(values == nullptr);
count++;
return (U **) &values;
}
if (count == 1) {
U *oldData = (U*) values;
if (KEY::getKey(oldData) == key)
return (U **) &values;
values = alloc.newArray<U*>(SET_ARRAY_SIZE);
if (!values) {
values = (U **) oldData;
return nullptr;
}
mozilla::PodZero(values, SET_ARRAY_SIZE);
count++;
values[0] = oldData;
return &values[1];
}
if (count <= SET_ARRAY_SIZE) {
for (unsigned i = 0; i < count; i++) {
if (KEY::getKey(values[i]) == key)
return &values[i];
}
if (count < SET_ARRAY_SIZE) {
count++;
return &values[count - 1];
}
}
return InsertTry<T,U,KEY>(alloc, values, count, key);
}
// Lookup an entry in a hash set, return nullptr if it does not exist.
template <class T, class U, class KEY>
static inline U *
Lookup(U **values, unsigned count, T key)
{
if (count == 0)
return nullptr;
if (count == 1)
return (KEY::getKey((U *) values) == key) ? (U *) values : nullptr;
if (count <= SET_ARRAY_SIZE) {
for (unsigned i = 0; i < count; i++) {
if (KEY::getKey(values[i]) == key)
return values[i];
}
return nullptr;
}
unsigned capacity = Capacity(count);
unsigned pos = HashKey<T,KEY>(key) & (capacity - 1);
while (values[pos] != nullptr) {
if (KEY::getKey(values[pos]) == key)
return values[pos];
pos = (pos + 1) & (capacity - 1);
}
return nullptr;
}
};
/////////////////////////////////////////////////////////////////////
// TypeSet
/////////////////////////////////////////////////////////////////////
/*
* The sets of objects and scripts in a type set grow monotonically, are usually
* empty, almost always small, and sometimes big. For empty or singleton sets,
* the pointer refers directly to the value. For sets fitting into SET_ARRAY_SIZE,
* an array of this length is used to store the elements. For larger sets, a hash
* table filled to 25%-50% of capacity is used, with collisions resolved by linear
* probing. TODO: replace these with jshashtables.
*/
const unsigned SET_ARRAY_SIZE = 8;
const unsigned SET_CAPACITY_OVERFLOW = 1u << 30;
/* Get the capacity of a set with the given element count. */
static inline unsigned
HashSetCapacity(unsigned count)
{
MOZ_ASSERT(count >= 2);
MOZ_ASSERT(count < SET_CAPACITY_OVERFLOW);
if (count <= SET_ARRAY_SIZE)
return SET_ARRAY_SIZE;
return 1u << (mozilla::FloorLog2(count) + 2);
}
/* Compute the FNV hash for the low 32 bits of v. */
template <class T, class KEY>
static inline uint32_t
HashKey(T v)
{
uint32_t nv = KEY::keyBits(v);
uint32_t hash = 84696351 ^ (nv & 0xff);
hash = (hash * 16777619) ^ ((nv >> 8) & 0xff);
hash = (hash * 16777619) ^ ((nv >> 16) & 0xff);
return (hash * 16777619) ^ ((nv >> 24) & 0xff);
}
/*
* Insert space for an element into the specified set and grow its capacity if needed.
* returned value is an existing or new entry (nullptr if new).
*/
template <class T, class U, class KEY>
static U **
HashSetInsertTry(LifoAlloc &alloc, U **&values, unsigned &count, T key)
{
unsigned capacity = HashSetCapacity(count);
unsigned insertpos = HashKey<T,KEY>(key) & (capacity - 1);
/* Whether we are converting from a fixed array to hashtable. */
bool converting = (count == SET_ARRAY_SIZE);
if (!converting) {
while (values[insertpos] != nullptr) {
if (KEY::getKey(values[insertpos]) == key)
return &values[insertpos];
insertpos = (insertpos + 1) & (capacity - 1);
}
}
if (count >= SET_CAPACITY_OVERFLOW)
return nullptr;
count++;
unsigned newCapacity = HashSetCapacity(count);
if (newCapacity == capacity) {
MOZ_ASSERT(!converting);
return &values[insertpos];
}
U **newValues = alloc.newArray<U*>(newCapacity);
if (!newValues)
return nullptr;
mozilla::PodZero(newValues, newCapacity);
for (unsigned i = 0; i < capacity; i++) {
if (values[i]) {
unsigned pos = HashKey<T,KEY>(KEY::getKey(values[i])) & (newCapacity - 1);
while (newValues[pos] != nullptr)
pos = (pos + 1) & (newCapacity - 1);
newValues[pos] = values[i];
}
}
values = newValues;
insertpos = HashKey<T,KEY>(key) & (newCapacity - 1);
while (values[insertpos] != nullptr)
insertpos = (insertpos + 1) & (newCapacity - 1);
return &values[insertpos];
}
/*
* Insert an element into the specified set if it is not already there, returning
* an entry which is nullptr if the element was not there.
*/
template <class T, class U, class KEY>
static inline U **
HashSetInsert(LifoAlloc &alloc, U **&values, unsigned &count, T key)
{
if (count == 0) {
MOZ_ASSERT(values == nullptr);
count++;
return (U **) &values;
}
if (count == 1) {
U *oldData = (U*) values;
if (KEY::getKey(oldData) == key)
return (U **) &values;
values = alloc.newArray<U*>(SET_ARRAY_SIZE);
if (!values) {
values = (U **) oldData;
return nullptr;
}
mozilla::PodZero(values, SET_ARRAY_SIZE);
count++;
values[0] = oldData;
return &values[1];
}
if (count <= SET_ARRAY_SIZE) {
for (unsigned i = 0; i < count; i++) {
if (KEY::getKey(values[i]) == key)
return &values[i];
}
if (count < SET_ARRAY_SIZE) {
count++;
return &values[count - 1];
}
}
return HashSetInsertTry<T,U,KEY>(alloc, values, count, key);
}
/* Lookup an entry in a hash set, return nullptr if it does not exist. */
template <class T, class U, class KEY>
static inline U *
HashSetLookup(U **values, unsigned count, T key)
{
if (count == 0)
return nullptr;
if (count == 1)
return (KEY::getKey((U *) values) == key) ? (U *) values : nullptr;
if (count <= SET_ARRAY_SIZE) {
for (unsigned i = 0; i < count; i++) {
if (KEY::getKey(values[i]) == key)
return values[i];
}
return nullptr;
}
unsigned capacity = HashSetCapacity(count);
unsigned pos = HashKey<T,KEY>(key) & (capacity - 1);
while (values[pos] != nullptr) {
if (KEY::getKey(values[pos]) == key)
return values[pos];
pos = (pos + 1) & (capacity - 1);
}
return nullptr;
}
inline TypeSetObjectKey *
Type::objectKey() const
inline TypeSet::ObjectKey *
TypeSet::Type::objectKey() const
{
MOZ_ASSERT(isObject());
return (TypeSetObjectKey *) data;
return (ObjectKey *) data;
}
inline JSObject *
Type::singleton() const
TypeSet::Type::singleton() const
{
return objectKey()->singleton();
}
inline ObjectGroup *
Type::group() const
TypeSet::Type::group() const
{
return objectKey()->group();
}
inline JSObject *
Type::singletonNoBarrier() const
TypeSet::Type::singletonNoBarrier() const
{
return objectKey()->singletonNoBarrier();
}
inline ObjectGroup *
Type::groupNoBarrier() const
TypeSet::Type::groupNoBarrier() const
{
return objectKey()->groupNoBarrier();
}
@ -884,8 +882,8 @@ TypeSet::hasType(Type type) const
return !!(flags & TYPE_FLAG_ANYOBJECT);
} else {
return !!(flags & TYPE_FLAG_ANYOBJECT) ||
HashSetLookup<TypeSetObjectKey*,TypeSetObjectKey,TypeSetObjectKey>
(objectSet, baseObjectCount(), type.objectKey()) != nullptr;
TypeHashSet::Lookup<ObjectKey*, ObjectKey, ObjectKey>
(objectSet, baseObjectCount(), type.objectKey()) != nullptr;
}
}
@ -947,18 +945,18 @@ TypeSet::getObjectCount() const
{
MOZ_ASSERT(!unknownObject());
uint32_t count = baseObjectCount();
if (count > SET_ARRAY_SIZE)
return HashSetCapacity(count);
if (count > TypeHashSet::SET_ARRAY_SIZE)
return TypeHashSet::Capacity(count);
return count;
}
inline TypeSetObjectKey *
inline TypeSet::ObjectKey *
TypeSet::getObject(unsigned i) const
{
MOZ_ASSERT(i < getObjectCount());
if (baseObjectCount() == 1) {
MOZ_ASSERT(i == 0);
return (TypeSetObjectKey *) objectSet;
return (ObjectKey *) objectSet;
}
return objectSet[i];
}
@ -966,28 +964,28 @@ TypeSet::getObject(unsigned i) const
inline JSObject *
TypeSet::getSingleton(unsigned i) const
{
TypeSetObjectKey *key = getObject(i);
ObjectKey *key = getObject(i);
return (key && key->isSingleton()) ? key->singleton() : nullptr;
}
inline ObjectGroup *
TypeSet::getGroup(unsigned i) const
{
TypeSetObjectKey *key = getObject(i);
ObjectKey *key = getObject(i);
return (key && key->isGroup()) ? key->group() : nullptr;
}
inline JSObject *
TypeSet::getSingletonNoBarrier(unsigned i) const
{
TypeSetObjectKey *key = getObject(i);
ObjectKey *key = getObject(i);
return (key && key->isSingleton()) ? key->singletonNoBarrier() : nullptr;
}
inline ObjectGroup *
TypeSet::getGroupNoBarrier(unsigned i) const
{
TypeSetObjectKey *key = getObject(i);
ObjectKey *key = getObject(i);
return (key && key->isGroup()) ? key->groupNoBarrier() : nullptr;
}
@ -1016,8 +1014,6 @@ TypeNewScript::writeBarrierPre(TypeNewScript *newScript)
newScript->trace(zone->barrierTracer());
}
} // namespace types
/////////////////////////////////////////////////////////////////////
// ObjectGroup
/////////////////////////////////////////////////////////////////////
@ -1037,25 +1033,25 @@ ObjectGroup::setBasePropertyCount(uint32_t count)
| (count << OBJECT_FLAG_PROPERTY_COUNT_SHIFT);
}
inline types::HeapTypeSet *
inline HeapTypeSet *
ObjectGroup::getProperty(ExclusiveContext *cx, jsid id)
{
MOZ_ASSERT(JSID_IS_VOID(id) || JSID_IS_EMPTY(id) || JSID_IS_STRING(id) || JSID_IS_SYMBOL(id));
MOZ_ASSERT_IF(!JSID_IS_EMPTY(id), id == types::IdToTypeId(id));
MOZ_ASSERT_IF(!JSID_IS_EMPTY(id), id == IdToTypeId(id));
MOZ_ASSERT(!unknownProperties());
if (types::HeapTypeSet *types = maybeGetProperty(id))
if (HeapTypeSet *types = maybeGetProperty(id))
return types;
types::Property *base = cx->typeLifoAlloc().new_<types::Property>(id);
Property *base = cx->typeLifoAlloc().new_<Property>(id);
if (!base) {
markUnknown(cx);
return nullptr;
}
uint32_t propertyCount = basePropertyCount();
types::Property **pprop = types::HashSetInsert<jsid,types::Property,types::Property>
(cx->typeLifoAlloc(), propertySet, propertyCount, id);
Property **pprop = TypeHashSet::Insert<jsid, Property, Property>
(cx->typeLifoAlloc(), propertySet, propertyCount, id);
if (!pprop) {
markUnknown(cx);
return nullptr;
@ -1078,15 +1074,15 @@ ObjectGroup::getProperty(ExclusiveContext *cx, jsid id)
return &base->types;
}
inline types::HeapTypeSet *
inline HeapTypeSet *
ObjectGroup::maybeGetProperty(jsid id)
{
MOZ_ASSERT(JSID_IS_VOID(id) || JSID_IS_EMPTY(id) || JSID_IS_STRING(id) || JSID_IS_SYMBOL(id));
MOZ_ASSERT_IF(!JSID_IS_EMPTY(id), id == types::IdToTypeId(id));
MOZ_ASSERT_IF(!JSID_IS_EMPTY(id), id == IdToTypeId(id));
MOZ_ASSERT(!unknownProperties());
types::Property *prop = types::HashSetLookup<jsid,types::Property,types::Property>
(propertySet, basePropertyCount(), id);
Property *prop = TypeHashSet::Lookup<jsid, Property, Property>
(propertySet, basePropertyCount(), id);
return prop ? &prop->types : nullptr;
}
@ -1095,37 +1091,37 @@ inline unsigned
ObjectGroup::getPropertyCount()
{
uint32_t count = basePropertyCount();
if (count > types::SET_ARRAY_SIZE)
return types::HashSetCapacity(count);
if (count > TypeHashSet::SET_ARRAY_SIZE)
return TypeHashSet::Capacity(count);
return count;
}
inline types::Property *
inline ObjectGroup::Property *
ObjectGroup::getProperty(unsigned i)
{
MOZ_ASSERT(i < getPropertyCount());
if (basePropertyCount() == 1) {
MOZ_ASSERT(i == 0);
return (types::Property *) propertySet;
return (Property *) propertySet;
}
return propertySet[i];
}
template <>
struct GCMethods<const types::Type>
struct GCMethods<const TypeSet::Type>
{
static types::Type initial() { return types::Type::UnknownType(); }
static bool poisoned(const types::Type &v) {
static TypeSet::Type initial() { return TypeSet::UnknownType(); }
static bool poisoned(TypeSet::Type v) {
return (v.isGroup() && IsPoisonedPtr(v.group()))
|| (v.isSingleton() && IsPoisonedPtr(v.singleton()));
}
};
template <>
struct GCMethods<types::Type>
struct GCMethods<TypeSet::Type>
{
static types::Type initial() { return types::Type::UnknownType(); }
static bool poisoned(const types::Type &v) {
static TypeSet::Type initial() { return TypeSet::UnknownType(); }
static bool poisoned(TypeSet::Type v) {
return (v.isGroup() && IsPoisonedPtr(v.group()))
|| (v.isSingleton() && IsPoisonedPtr(v.singleton()));
}
@ -1133,7 +1129,7 @@ struct GCMethods<types::Type>
} // namespace js
inline js::types::TypeScript *
inline js::TypeScript *
JSScript::types()
{
maybeSweepTypes(nullptr);

View File

@ -580,7 +580,7 @@ VectorToKeyIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVecto
if (obj->isSingleton() && !obj->setIteratedSingleton(cx))
return false;
types::MarkObjectGroupFlags(cx, obj, OBJECT_FLAG_ITERATED);
MarkObjectGroupFlags(cx, obj, OBJECT_FLAG_ITERATED);
Rooted<PropertyIteratorObject *> iterobj(cx, NewPropertyIteratorObject(cx, flags));
if (!iterobj)
@ -623,7 +623,7 @@ VectorToValueIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVec
if (obj->isSingleton() && !obj->setIteratedSingleton(cx))
return false;
types::MarkObjectGroupFlags(cx, obj, OBJECT_FLAG_ITERATED);
MarkObjectGroupFlags(cx, obj, OBJECT_FLAG_ITERATED);
Rooted<PropertyIteratorObject*> iterobj(cx, NewPropertyIteratorObject(cx, flags));
if (!iterobj)

View File

@ -39,7 +39,6 @@
#include "vm/String-inl.h"
using namespace js;
using namespace js::types;
using mozilla::Abs;
using mozilla::ArrayLength;

View File

@ -67,7 +67,6 @@
using namespace js;
using namespace js::gc;
using namespace js::types;
using mozilla::DebugOnly;
using mozilla::Maybe;
@ -1605,7 +1604,7 @@ CreateThisForFunctionWithGroup(JSContext *cx, HandleObjectGroup group, JSObject
if (group->maybeUnboxedLayout() && newKind != SingletonObject)
return UnboxedPlainObject::create(cx, group, newKind);
if (types::TypeNewScript *newScript = group->newScript()) {
if (TypeNewScript *newScript = group->newScript()) {
if (newScript->analyzed()) {
// The definite properties analysis has been performed for this
// group, so get the shape and finalize kind to use from the
@ -1685,7 +1684,7 @@ js::CreateThisForFunctionWithProto(JSContext *cx, HandleObject callee, JSObject
JSScript *script = callee->as<JSFunction>().getOrCreateScript(cx);
if (!script)
return nullptr;
TypeScript::SetThis(cx, script, types::Type::ObjectType(res));
TypeScript::SetThis(cx, script, TypeSet::ObjectType(res));
}
return res;
@ -1711,7 +1710,7 @@ js::CreateThisForFunction(JSContext *cx, HandleObject callee, NewObjectKind newK
NativeObject::clear(cx, nobj);
JSScript *calleeScript = callee->as<JSFunction>().nonLazyScript();
TypeScript::SetThis(cx, calleeScript, types::Type::ObjectType(nobj));
TypeScript::SetThis(cx, calleeScript, TypeSet::ObjectType(nobj));
return nobj;
}
@ -3335,7 +3334,7 @@ js::WatchGuts(JSContext *cx, JS::HandleObject origObj, JS::HandleId id, JS::Hand
if (!NativeObject::sparsifyDenseElements(cx, obj.as<NativeObject>()))
return false;
types::MarkTypePropertyNonData(cx, obj, id);
MarkTypePropertyNonData(cx, obj, id);
}
WatchpointMap *wpmap = cx->compartment()->watchpointMap;

View File

@ -177,7 +177,7 @@ js::GetElementNoGC(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t in
inline bool
js::DeleteProperty(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
{
types::MarkTypePropertyNonData(cx, obj, id);
MarkTypePropertyNonData(cx, obj, id);
if (DeletePropertyOp op = obj->getOps()->deleteProperty)
return op(cx, obj, id, succeeded);
return NativeDeleteProperty(cx, obj.as<NativeObject>(), id, succeeded);
@ -198,7 +198,7 @@ js::DeleteElement(JSContext *cx, HandleObject obj, uint32_t index, bool *succeed
inline bool
js::SetPropertyAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
{
types::MarkTypePropertyNonData(cx, obj, id);
MarkTypePropertyNonData(cx, obj, id);
SetAttributesOp op = obj->getOps()->setAttributes;
if (op)
return op(cx, obj, id, attrsp);
@ -758,7 +758,7 @@ NewObjectMetadata(ExclusiveContext *cxArg, JSObject **pmetadata)
{
// Use AutoEnterAnalysis to prohibit both any GC activity under the
// callback, and any reentering of JS via Invoke() etc.
types::AutoEnterAnalysis enter(cx);
AutoEnterAnalysis enter(cx);
if (!cx->compartment()->callObjectMetadataCallback(cx, pmetadata))
return false;

View File

@ -29,7 +29,6 @@
using namespace js;
using namespace js::gc;
using namespace js::types;
using mozilla::IsFinite;
using mozilla::Maybe;

View File

@ -823,7 +823,7 @@ class JSScript : public js::gc::TenuredCell
private:
/* Persistent type information retained across GCs. */
js::types::TypeScript *types_;
js::TypeScript *types_;
// This script's ScriptSourceObject, or a CCW thereof.
//
@ -1455,9 +1455,9 @@ class JSScript : public js::gc::TenuredCell
/* Ensure the script has a TypeScript. */
inline bool ensureHasTypes(JSContext *cx);
inline js::types::TypeScript *types();
inline js::TypeScript *types();
void maybeSweepTypes(js::types::AutoClearTypeInferenceStateOnOOM *oom);
void maybeSweepTypes(js::AutoClearTypeInferenceStateOnOOM *oom);
inline js::GlobalObject &global() const;
js::GlobalObject &uninlinedGlobal() const;

View File

@ -52,7 +52,6 @@
using namespace js;
using namespace js::gc;
using namespace js::types;
using namespace js::unicode;
using JS::Symbol;
@ -3788,7 +3787,7 @@ js::str_split(JSContext *cx, unsigned argc, Value *vp)
RootedObjectGroup group(cx, ObjectGroup::callingAllocationSiteGroup(cx, JSProto_Array));
if (!group)
return false;
AddTypePropertyId(cx, group, JSID_VOID, Type::StringType());
AddTypePropertyId(cx, group, JSID_VOID, TypeSet::StringType());
/* Step 5: Use the second argument as the split limit, if given. */
uint32_t limit;

View File

@ -340,7 +340,7 @@ ArgSetter(JSContext *cx, HandleObject obj, HandleId id, bool strict, MutableHand
if (arg < argsobj->initialLength() && !argsobj->isElementDeleted(arg)) {
argsobj->setElement(cx, arg, vp);
if (arg < script->functionNonDelazifying()->nargs())
types::TypeScript::SetArgument(cx, script, arg, vp);
TypeScript::SetArgument(cx, script, arg, vp);
return true;
}
} else {

View File

@ -58,7 +58,6 @@ using mozilla::UniquePtr;
using namespace js;
using namespace js::gc;
using namespace js::types;
/*
* Convert |v| to an array index for an array of length |length| per
@ -523,7 +522,7 @@ ArrayBufferObject::neuter(JSContext *cx, Handle<ArrayBufferObject*> buffer,
// flag change will be observed.
if (!cx->global()->getGroup(cx))
CrashAtUnhandlableOOM("ArrayBufferObject::neuter");
types::MarkObjectGroupFlags(cx, cx->global(), OBJECT_FLAG_TYPED_OBJECT_NEUTERED);
MarkObjectGroupFlags(cx, cx->global(), OBJECT_FLAG_TYPED_OBJECT_NEUTERED);
cx->compartment()->neuteredTypedObjects = 1;
}

View File

@ -22,7 +22,7 @@ ArrayObject::setLength(ExclusiveContext *cx, uint32_t length)
if (length > INT32_MAX) {
/* Track objects with overflowing lengths in type information. */
types::MarkObjectGroupFlags(cx, this, OBJECT_FLAG_LENGTH_OVERFLOW);
MarkObjectGroupFlags(cx, this, OBJECT_FLAG_LENGTH_OVERFLOW);
}
getElementsHeader()->length = length;

View File

@ -1910,7 +1910,7 @@ UpdateExecutionObservabilityOfScriptsInZone(JSContext *cx, Zone *zone,
// Iterate through observable scripts, invalidating their Ion scripts and
// appending them to a vector for discarding their baseline scripts later.
{
types::AutoEnterAnalysis enter(fop, zone);
AutoEnterAnalysis enter(fop, zone);
if (JSScript *script = obs.singleScriptForZoneInvalidation()) {
if (obs.shouldRecompileOrInvalidate(script)) {
if (!AppendAndInvalidateScript(cx, zone, script, scripts))

View File

@ -13,7 +13,6 @@
#include "vm/Stack-inl.h"
using namespace js;
using namespace js::types;
JSObject *
GeneratorObject::create(JSContext *cx, AbstractFramePtr frame)

View File

@ -199,7 +199,7 @@ GlobalObject::resolveConstructor(JSContext *cx, Handle<GlobalObject*> global, JS
if (clasp->spec.shouldDefineConstructor()) {
// Stash type information, so that what we do here is equivalent to
// initBuiltinConstructor.
types::AddTypePropertyId(cx, global, id, ObjectValue(*ctor));
AddTypePropertyId(cx, global, id, ObjectValue(*ctor));
}
return true;
@ -224,7 +224,7 @@ GlobalObject::initBuiltinConstructor(JSContext *cx, Handle<GlobalObject*> global
global->setPrototype(key, ObjectValue(*proto));
global->setConstructorPropertySlot(key, ObjectValue(*ctor));
types::AddTypePropertyId(cx, global, id, ObjectValue(*ctor));
AddTypePropertyId(cx, global, id, ObjectValue(*ctor));
return true;
}

View File

@ -55,7 +55,6 @@
using namespace js;
using namespace js::gc;
using namespace js::types;
using mozilla::DebugOnly;
using mozilla::NumberEqualsInt32;
@ -1322,7 +1321,7 @@ static MOZ_ALWAYS_INLINE bool
SetObjectElementOperation(JSContext *cx, Handle<JSObject*> obj, HandleId id, const Value &value,
bool strict, JSScript *script = nullptr, jsbytecode *pc = nullptr)
{
types::TypeScript::MonitorAssign(cx, obj, id);
TypeScript::MonitorAssign(cx, obj, id);
if (obj->isNative() && JSID_IS_INT(id)) {
uint32_t length = obj->as<NativeObject>().getDenseInitializedLength();
@ -3963,8 +3962,7 @@ js::RunOnceScriptPrologue(JSContext *cx, HandleScript script)
if (!script->functionNonDelazifying()->getGroup(cx))
return false;
types::MarkObjectGroupFlags(cx, script->functionNonDelazifying(),
OBJECT_FLAG_RUNONCE_INVALIDATED);
MarkObjectGroupFlags(cx, script->functionNonDelazifying(), OBJECT_FLAG_RUNONCE_INVALIDATED);
return true;
}

View File

@ -81,9 +81,9 @@ NativeObject::setDenseElementWithType(ExclusiveContext *cx, uint32_t index,
{
// Avoid a slow AddTypePropertyId call if the type is the same as the type
// of the previous element.
types::Type thisType = types::GetValueType(val);
if (index == 0 || types::GetValueType(elements_[index - 1]) != thisType)
types::AddTypePropertyId(cx, this, JSID_VOID, thisType);
TypeSet::Type thisType = TypeSet::GetValueType(val);
if (index == 0 || TypeSet::GetValueType(elements_[index - 1]) != thisType)
AddTypePropertyId(cx, this, JSID_VOID, thisType);
setDenseElementMaybeConvertDouble(index, val);
}
@ -92,14 +92,14 @@ NativeObject::initDenseElementWithType(ExclusiveContext *cx, uint32_t index,
const Value &val)
{
MOZ_ASSERT(!shouldConvertDoubleElements());
types::AddTypePropertyId(cx, this, JSID_VOID, val);
AddTypePropertyId(cx, this, JSID_VOID, val);
initDenseElement(index, val);
}
inline void
NativeObject::setDenseElementHole(ExclusiveContext *cx, uint32_t index)
{
types::MarkObjectGroupFlags(cx, this, OBJECT_FLAG_NON_PACKED);
MarkObjectGroupFlags(cx, this, OBJECT_FLAG_NON_PACKED);
setDenseElement(index, MagicValue(JS_ELEMENTS_HOLE));
}
@ -107,9 +107,7 @@ NativeObject::setDenseElementHole(ExclusiveContext *cx, uint32_t index)
NativeObject::removeDenseElementForSparseIndex(ExclusiveContext *cx,
HandleNativeObject obj, uint32_t index)
{
types::MarkObjectGroupFlags(cx, obj,
OBJECT_FLAG_NON_PACKED |
OBJECT_FLAG_SPARSE_INDEXES);
MarkObjectGroupFlags(cx, obj, OBJECT_FLAG_NON_PACKED | OBJECT_FLAG_SPARSE_INDEXES);
if (obj->containsDenseElement(index))
obj->setDenseElement(index, MagicValue(JS_ELEMENTS_HOLE));
}
@ -124,7 +122,7 @@ inline void
NativeObject::markDenseElementsNotPacked(ExclusiveContext *cx)
{
MOZ_ASSERT(isNative());
types::MarkObjectGroupFlags(cx, this, OBJECT_FLAG_NON_PACKED);
MarkObjectGroupFlags(cx, this, OBJECT_FLAG_NON_PACKED);
}
inline void
@ -320,7 +318,7 @@ NativeObject::setSlotWithType(ExclusiveContext *cx, Shape *shape,
if (overwriting)
shape->setOverwritten();
types::AddTypePropertyId(cx, this, shape->propid(), value);
AddTypePropertyId(cx, this, shape->propid(), value);
}
/* Make an object with pregenerated shape from a NEWOBJECT bytecode. */

View File

@ -1118,15 +1118,15 @@ UpdateShapeTypeAndValue(ExclusiveContext *cx, NativeObject *obj, Shape *shape, c
// Per the acquired properties analysis, when the shape of a partially
// initialized object is changed to its fully initialized shape, its
// group can be updated as well.
if (types::TypeNewScript *newScript = obj->groupRaw()->newScript()) {
if (TypeNewScript *newScript = obj->groupRaw()->newScript()) {
if (newScript->initializedShape() == shape)
obj->setGroup(newScript->initializedGroup());
}
}
if (!shape->hasSlot() || !shape->hasDefaultGetter() || !shape->hasDefaultSetter())
types::MarkTypePropertyNonData(cx, obj, id);
MarkTypePropertyNonData(cx, obj, id);
if (!shape->writable())
types::MarkTypePropertyNonWritable(cx, obj, id);
MarkTypePropertyNonWritable(cx, obj, id);
return true;
}
@ -1596,7 +1596,7 @@ GetExistingProperty(JSContext *cx,
!obj->isSingleton() &&
!obj->template is<ScopeObject>() &&
shape->hasDefaultGetter(),
js::types::TypeHasProperty(cx, obj->group(), shape->propid(), vp));
ObjectGroupHasProperty(cx, obj->group(), shape->propid(), vp));
} else {
vp.setUndefined();
}
@ -2294,7 +2294,7 @@ js::NativeSetPropertyAttributes(JSContext *cx, HandleNativeObject obj, HandleId
if (!NativeObject::changePropertyAttributes(cx, nobj.as<NativeObject>(), shape, *attrsp))
return false;
if (*attrsp & JSPROP_READONLY)
types::MarkTypePropertyNonWritable(cx, nobj, id);
MarkTypePropertyNonWritable(cx, nobj, id);
return true;
} else {
return SetPropertyAttributes(cx, nobj, id, attrsp);

View File

@ -19,7 +19,6 @@
#include "jsobjinlines.h"
using namespace js;
using namespace js::types;
using mozilla::PodZero;
@ -549,22 +548,22 @@ ObjectGroup::defaultNewGroup(ExclusiveContext *cx, const Class *clasp,
const JSAtomState &names = cx->names();
if (obj->is<RegExpObject>()) {
AddTypePropertyId(cx, group, NameToId(names.source), Type::StringType());
AddTypePropertyId(cx, group, NameToId(names.global), Type::BooleanType());
AddTypePropertyId(cx, group, NameToId(names.ignoreCase), Type::BooleanType());
AddTypePropertyId(cx, group, NameToId(names.multiline), Type::BooleanType());
AddTypePropertyId(cx, group, NameToId(names.sticky), Type::BooleanType());
AddTypePropertyId(cx, group, NameToId(names.lastIndex), Type::Int32Type());
AddTypePropertyId(cx, group, NameToId(names.source), TypeSet::StringType());
AddTypePropertyId(cx, group, NameToId(names.global), TypeSet::BooleanType());
AddTypePropertyId(cx, group, NameToId(names.ignoreCase), TypeSet::BooleanType());
AddTypePropertyId(cx, group, NameToId(names.multiline), TypeSet::BooleanType());
AddTypePropertyId(cx, group, NameToId(names.sticky), TypeSet::BooleanType());
AddTypePropertyId(cx, group, NameToId(names.lastIndex), TypeSet::Int32Type());
}
if (obj->is<StringObject>())
AddTypePropertyId(cx, group, NameToId(names.length), Type::Int32Type());
AddTypePropertyId(cx, group, NameToId(names.length), TypeSet::Int32Type());
if (obj->is<ErrorObject>()) {
AddTypePropertyId(cx, group, NameToId(names.fileName), Type::StringType());
AddTypePropertyId(cx, group, NameToId(names.lineNumber), Type::Int32Type());
AddTypePropertyId(cx, group, NameToId(names.columnNumber), Type::Int32Type());
AddTypePropertyId(cx, group, NameToId(names.stack), Type::StringType());
AddTypePropertyId(cx, group, NameToId(names.fileName), TypeSet::StringType());
AddTypePropertyId(cx, group, NameToId(names.lineNumber), TypeSet::Int32Type());
AddTypePropertyId(cx, group, NameToId(names.columnNumber), TypeSet::Int32Type());
AddTypePropertyId(cx, group, NameToId(names.stack), TypeSet::StringType());
}
}
@ -715,14 +714,14 @@ ObjectGroup::defaultNewGroup(JSContext *cx, JSProtoKey key)
struct ObjectGroupCompartment::ArrayObjectKey : public DefaultHasher<ArrayObjectKey>
{
Type type;
TypeSet::Type type;
JSObject *proto;
ArrayObjectKey()
: type(Type::UndefinedType()), proto(nullptr)
: type(TypeSet::UndefinedType()), proto(nullptr)
{}
ArrayObjectKey(Type type, JSObject *proto)
ArrayObjectKey(TypeSet::Type type, JSObject *proto)
: type(type), proto(proto)
{}
@ -744,7 +743,7 @@ struct ObjectGroupCompartment::ArrayObjectKey : public DefaultHasher<ArrayObject
};
static inline bool
NumberTypes(Type a, Type b)
NumberTypes(TypeSet::Type a, TypeSet::Type b)
{
return (a.isPrimitive(JSVAL_TYPE_INT32) || a.isPrimitive(JSVAL_TYPE_DOUBLE))
&& (b.isPrimitive(JSVAL_TYPE_INT32) || b.isPrimitive(JSVAL_TYPE_DOUBLE));
@ -755,10 +754,10 @@ NumberTypes(Type a, Type b)
* their default prototype. These are the only values that should appear in
* arrays and objects whose type can be fixed.
*/
static inline Type
static inline TypeSet::Type
GetValueTypeForTable(const Value &v)
{
Type type = GetValueType(v);
TypeSet::Type type = TypeSet::GetValueType(v);
MOZ_ASSERT(!type.isSingleton());
return type;
}
@ -779,13 +778,13 @@ ObjectGroup::fixArrayGroup(ExclusiveContext *cx, ArrayObject *obj)
if (len == 0)
return;
Type type = GetValueTypeForTable(obj->getDenseElement(0));
TypeSet::Type type = GetValueTypeForTable(obj->getDenseElement(0));
for (unsigned i = 1; i < len; i++) {
Type ntype = GetValueTypeForTable(obj->getDenseElement(i));
TypeSet::Type ntype = GetValueTypeForTable(obj->getDenseElement(i));
if (ntype != type) {
if (NumberTypes(type, ntype))
type = Type::DoubleType();
type = TypeSet::DoubleType();
else
return;
}
@ -801,11 +800,12 @@ ObjectGroup::fixRestArgumentsGroup(ExclusiveContext *cx, ArrayObject *obj)
// Tracking element types for rest argument arrays is not worth it, but we
// still want it to be known that it's a dense array.
setGroupToHomogenousArray(cx, obj, Type::UnknownType());
setGroupToHomogenousArray(cx, obj, TypeSet::UnknownType());
}
/* static */ void
ObjectGroup::setGroupToHomogenousArray(ExclusiveContext *cx, JSObject *obj, Type elementType)
ObjectGroup::setGroupToHomogenousArray(ExclusiveContext *cx, JSObject *obj,
TypeSet::Type elementType)
{
MOZ_ASSERT(cx->zone()->types.activeAnalysis);
@ -888,7 +888,7 @@ struct ObjectGroupCompartment::PlainObjectEntry
{
ReadBarrieredObjectGroup group;
ReadBarrieredShape shape;
Type *types;
TypeSet::Type *types;
};
/* static */ void
@ -898,8 +898,8 @@ ObjectGroupCompartment::updatePlainObjectEntryTypes(ExclusiveContext *cx, PlainO
if (entry.group->unknownProperties())
return;
for (size_t i = 0; i < nproperties; i++) {
Type type = entry.types[i];
Type ntype = GetValueTypeForTable(properties[i].value);
TypeSet::Type type = entry.types[i];
TypeSet::Type ntype = GetValueTypeForTable(properties[i].value);
if (ntype == type)
continue;
if (ntype.isPrimitive(JSVAL_TYPE_INT32) &&
@ -911,7 +911,7 @@ ObjectGroupCompartment::updatePlainObjectEntryTypes(ExclusiveContext *cx, PlainO
type.isPrimitive(JSVAL_TYPE_INT32))
{
/* Include 'double' in the property types to avoid the update below later. */
entry.types[i] = Type::DoubleType();
entry.types[i] = TypeSet::DoubleType();
}
AddTypePropertyId(cx, entry.group, IdToTypeId(properties[i].id), ntype);
}
@ -986,7 +986,8 @@ ObjectGroup::fixPlainObjectGroup(ExclusiveContext *cx, PlainObject *obj)
if (!ids)
return;
ScopedJSFreePtr<Type> types(group->zone()->pod_calloc<Type>(properties.length()));
ScopedJSFreePtr<TypeSet::Type> types(
group->zone()->pod_calloc<TypeSet::Type>(properties.length()));
if (!types)
return;
@ -1240,16 +1241,12 @@ ObjectGroup::getCopyOnWriteObject(JSScript *script, jsbytecode *pc)
}
/* static */ bool
ObjectGroup::findAllocationSiteForType(JSContext *cx, Type type,
JSScript **script, uint32_t *offset)
ObjectGroup::findAllocationSite(JSContext *cx, ObjectGroup *group,
JSScript **script, uint32_t *offset)
{
*script = nullptr;
*offset = 0;
if (type.isUnknown() || type.isAnyObject() || !type.isGroup())
return false;
ObjectGroup *obj = type.group();
const ObjectGroupCompartment::AllocationSiteTable *table =
cx->compartment()->objectGroups.allocationSiteTable;
@ -1260,7 +1257,7 @@ ObjectGroup::findAllocationSiteForType(JSContext *cx, Type type,
!r.empty();
r.popFront())
{
if (obj == r.front().value()) {
if (group == r.front().value()) {
*script = r.front().key().script;
*offset = r.front().key().offset;
return true;
@ -1395,7 +1392,7 @@ ObjectGroupCompartment::sweep(FreeOp *fop)
if (IsObjectGroupAboutToBeFinalizedFromAnyThread(&group))
remove = true;
else
key.type = Type::ObjectType(group);
key.type = TypeSet::ObjectType(group);
}
if (key.proto && key.proto != TaggedProto::LazyProto &&
IsObjectAboutToBeFinalizedFromAnyThread(&key.proto))
@ -1441,7 +1438,7 @@ ObjectGroupCompartment::sweep(FreeOp *fop)
if (IsObjectGroupAboutToBeFinalizedFromAnyThread(&group))
remove = true;
else if (group != entry.types[i].groupNoBarrier())
entry.types[i] = Type::ObjectType(group);
entry.types[i] = TypeSet::ObjectType(group);
}
}

View File

@ -9,6 +9,7 @@
#include "jsbytecode.h"
#include "jsfriendapi.h"
#include "jsinfer.h"
#include "ds/IdValuePair.h"
#include "gc/Barrier.h"
@ -18,17 +19,11 @@ namespace js {
class TypeDescr;
class UnboxedLayout;
namespace types {
class Type;
class TypeNewScript;
class HeapTypeSet;
struct Property;
class AutoClearTypeInferenceStateOnOOM;
class CompilerConstraintList;
} // namespace types
// Information about an object prototype, which can be either a particular
// object, null, or a lazily generated object. The latter is only used by
// certain kinds of proxies.
@ -118,81 +113,6 @@ class RootedBase<TaggedProto> : public TaggedProtoOperations<Rooted<TaggedProto>
}
};
/* Flags and other state stored in ObjectGroupFlags */
enum : uint32_t {
/* Whether this group is associated with some allocation site. */
OBJECT_FLAG_FROM_ALLOCATION_SITE = 0x1,
/* (0x2 and 0x4 are unused) */
/* Mask/shift for the number of properties in propertySet */
OBJECT_FLAG_PROPERTY_COUNT_MASK = 0xfff8,
OBJECT_FLAG_PROPERTY_COUNT_SHIFT = 3,
OBJECT_FLAG_PROPERTY_COUNT_LIMIT =
OBJECT_FLAG_PROPERTY_COUNT_MASK >> OBJECT_FLAG_PROPERTY_COUNT_SHIFT,
/* Whether any objects this represents may have sparse indexes. */
OBJECT_FLAG_SPARSE_INDEXES = 0x00010000,
/* Whether any objects this represents may not have packed dense elements. */
OBJECT_FLAG_NON_PACKED = 0x00020000,
/*
* Whether any objects this represents may be arrays whose length does not
* fit in an int32.
*/
OBJECT_FLAG_LENGTH_OVERFLOW = 0x00040000,
/* Whether any objects have been iterated over. */
OBJECT_FLAG_ITERATED = 0x00080000,
/* For a global object, whether flags were set on the RegExpStatics. */
OBJECT_FLAG_REGEXP_FLAGS_SET = 0x00100000,
/*
* For the function on a run-once script, whether the function has actually
* run multiple times.
*/
OBJECT_FLAG_RUNONCE_INVALIDATED = 0x00200000,
/*
* For a global object, whether any array buffers in this compartment with
* typed object views have been neutered.
*/
OBJECT_FLAG_TYPED_OBJECT_NEUTERED = 0x00400000,
/*
* Whether objects with this type should be allocated directly in the
* tenured heap.
*/
OBJECT_FLAG_PRE_TENURE = 0x00800000,
/* Whether objects with this type might have copy on write elements. */
OBJECT_FLAG_COPY_ON_WRITE = 0x01000000,
/* Whether this type has had its 'new' script cleared in the past. */
OBJECT_FLAG_NEW_SCRIPT_CLEARED = 0x02000000,
/*
* Whether all properties of this object are considered unknown.
* If set, all other flags in DYNAMIC_MASK will also be set.
*/
OBJECT_FLAG_UNKNOWN_PROPERTIES = 0x04000000,
/* Flags which indicate dynamic properties of represented objects. */
OBJECT_FLAG_DYNAMIC_MASK = 0x07ff0000,
// Mask/shift for the kind of addendum attached to this group.
OBJECT_FLAG_ADDENDUM_MASK = 0x38000000,
OBJECT_FLAG_ADDENDUM_SHIFT = 27,
// Mask/shift for this group's generation. If out of sync with the
// TypeZone's generation, this group hasn't been swept yet.
OBJECT_FLAG_GENERATION_MASK = 0x40000000,
OBJECT_FLAG_GENERATION_SHIFT = 30,
};
typedef uint32_t ObjectGroupFlags;
/*
* Lazy object groups overview.
*
@ -301,9 +221,9 @@ class ObjectGroup : public gc::TenuredCell
((flags_ & OBJECT_FLAG_ADDENDUM_MASK) >> OBJECT_FLAG_ADDENDUM_SHIFT);
}
types::TypeNewScript *newScriptDontCheckGeneration() const {
TypeNewScript *newScriptDontCheckGeneration() const {
if (addendumKind() == Addendum_NewScript)
return reinterpret_cast<types::TypeNewScript *>(addendum_);
return reinterpret_cast<TypeNewScript *>(addendum_);
return nullptr;
}
@ -313,7 +233,7 @@ class ObjectGroup : public gc::TenuredCell
return nullptr;
}
types::TypeNewScript *anyNewScript();
TypeNewScript *anyNewScript();
void detachNewScript(bool writeBarrier);
public:
@ -333,12 +253,12 @@ class ObjectGroup : public gc::TenuredCell
flags_ &= ~flags;
}
types::TypeNewScript *newScript() {
TypeNewScript *newScript() {
maybeSweep(nullptr);
return newScriptDontCheckGeneration();
}
void setNewScript(types::TypeNewScript *newScript) {
void setNewScript(TypeNewScript *newScript) {
setAddendum(Addendum_NewScript, newScript);
}
@ -385,13 +305,71 @@ class ObjectGroup : public gc::TenuredCell
setAddendum(Addendum_InterpretedFunction, fun);
}
class Property
{
public:
// Identifier for this property, JSID_VOID for the aggregate integer
// index property, or JSID_EMPTY for properties holding constraints
// listening to changes in the group's state.
HeapId id;
// Possible own types for this property.
HeapTypeSet types;
explicit Property(jsid id)
: id(id)
{}
Property(const Property &o)
: id(o.id.get()), types(o.types)
{}
static uint32_t keyBits(jsid id) { return uint32_t(JSID_BITS(id)); }
static jsid getKey(Property *p) { return p->id; }
};
private:
// Properties of this object. This may contain JSID_VOID, representing the
// types of all integer indexes of the object, and/or JSID_EMPTY, holding
// constraints listening to changes to the object's state.
//
// See types::Property for more detail about the types represented here.
types::Property **propertySet;
/*
* Properties of this object.
*
* The type sets in the properties of a group describe the possible values
* that can be read out of that property in actual JS objects. In native
* objects, property types account for plain data properties (those with a
* slot and no getter or setter hook) and dense elements. In typed objects
* and unboxed objects, property types account for object and value
* properties and elements in the object.
*
* For accesses on these properties, the correspondence is as follows:
*
* 1. If the group has unknownProperties(), the possible properties and
* value types for associated JSObjects are unknown.
*
* 2. Otherwise, for any |obj| in |group|, and any |id| which is a property
* in |obj|, before obj->getProperty(id) the property in |group| for
* |id| must reflect the result of the getProperty.
*
* There are several exceptions to this:
*
* 1. For properties of global JS objects which are undefined at the point
* where the property was (lazily) generated, the property type set will
* remain empty, and the 'undefined' type will only be added after a
* subsequent assignment or deletion. After these properties have been
* assigned a defined value, the only way they can become undefined
* again is after such an assign or deletion.
*
* 2. Array lengths are special cased by the compiler and VM and are not
* reflected in property types.
*
* 3. In typed objects (but not unboxed objects), the initial values of
* properties (null pointers and undefined values) are not reflected in
* the property types. These values are always possible when reading the
* property.
*
* We establish these by using write barriers on calls to setProperty and
* defineProperty which are on native properties, and on any jitcode which
* might update the property with a new type.
*/
Property **propertySet;
public:
inline ObjectGroup(const Class *clasp, TaggedProto proto, ObjectGroupFlags initialFlags);
@ -415,7 +393,7 @@ class ObjectGroup : public gc::TenuredCell
return hasAnyFlags(OBJECT_FLAG_PRE_TENURE) && !unknownProperties();
}
gc::InitialHeap initialHeap(types::CompilerConstraintList *constraints);
gc::InitialHeap initialHeap(CompilerConstraintList *constraints);
bool canPreTenure() {
return !unknownProperties();
@ -434,17 +412,17 @@ class ObjectGroup : public gc::TenuredCell
* Get or create a property of this object. Only call this for properties which
* a script accesses explicitly.
*/
inline types::HeapTypeSet *getProperty(ExclusiveContext *cx, jsid id);
inline HeapTypeSet *getProperty(ExclusiveContext *cx, jsid id);
/* Get a property only if it already exists. */
inline types::HeapTypeSet *maybeGetProperty(jsid id);
inline HeapTypeSet *maybeGetProperty(jsid id);
inline unsigned getPropertyCount();
inline types::Property *getProperty(unsigned i);
inline Property *getProperty(unsigned i);
/* Helpers */
void updateNewPropertyTypes(ExclusiveContext *cx, jsid id, types::HeapTypeSet *types);
void updateNewPropertyTypes(ExclusiveContext *cx, jsid id, HeapTypeSet *types);
bool addDefiniteProperties(ExclusiveContext *cx, Shape *shape);
bool matchDefiniteProperties(HandleObject obj);
void markPropertyNonData(ExclusiveContext *cx, jsid id);
@ -460,7 +438,7 @@ class ObjectGroup : public gc::TenuredCell
void print();
inline void clearProperties();
void maybeSweep(types::AutoClearTypeInferenceStateOnOOM *oom);
void maybeSweep(AutoClearTypeInferenceStateOnOOM *oom);
private:
#ifdef DEBUG
@ -568,12 +546,13 @@ class ObjectGroup : public gc::TenuredCell
static ArrayObject *getCopyOnWriteObject(JSScript *script, jsbytecode *pc);
// Returns false if not found.
static bool findAllocationSiteForType(JSContext *cx, types::Type type,
JSScript **script, uint32_t *offset);
static bool findAllocationSite(JSContext *cx, ObjectGroup *group,
JSScript **script, uint32_t *offset);
private:
static ObjectGroup *defaultNewGroup(JSContext *cx, JSProtoKey key);
static void setGroupToHomogenousArray(ExclusiveContext *cx, JSObject *obj, types::Type type);
static void setGroupToHomogenousArray(ExclusiveContext *cx, JSObject *obj,
TypeSet::Type type);
};
// Structure used to manage the groups in a compartment.

View File

@ -66,7 +66,7 @@ ProxyObject::New(JSContext *cx, const BaseProxyHandler *handler, HandleValue pri
/* Don't track types of properties of non-DOM and non-singleton proxies. */
if (newKind != SingletonObject && !clasp->isDOMClass())
types::MarkObjectGroupUnknownProperties(cx, proxy->group());
MarkObjectGroupUnknownProperties(cx, proxy->group());
return proxy;
}

View File

@ -738,8 +738,8 @@ RegExpCompartment::createMatchResultTemplateObject(JSContext *cx)
// Make sure type information reflects the indexed properties which might
// be added.
types::AddTypePropertyId(cx, templateObject, JSID_VOID, types::Type::StringType());
types::AddTypePropertyId(cx, templateObject, JSID_VOID, types::Type::UndefinedType());
AddTypePropertyId(cx, templateObject, JSID_VOID, TypeSet::StringType());
AddTypePropertyId(cx, templateObject, JSID_VOID, TypeSet::UndefinedType());
matchResultTemplateObject_.set(templateObject);

View File

@ -76,7 +76,7 @@ RegExpStatics::markFlagsSet(JSContext *cx)
// always be performed).
MOZ_ASSERT_IF(cx->global()->hasRegExpStatics(), this == cx->global()->getRegExpStatics(cx));
types::MarkObjectGroupFlags(cx, cx->global(), OBJECT_FLAG_REGEXP_FLAGS_SET);
MarkObjectGroupFlags(cx, cx->global(), OBJECT_FLAG_REGEXP_FLAGS_SET);
}
bool

View File

@ -24,7 +24,7 @@ ScopeObject::setAliasedVar(JSContext *cx, ScopeCoordinate sc, PropertyName *name
if (isSingleton()) {
MOZ_ASSERT(name);
types::AddTypePropertyId(cx, this, NameToId(name), v);
AddTypePropertyId(cx, this, NameToId(name), v);
// Keep track of properties which have ever been overwritten.
if (!getSlot(sc.slot()).isUndefined()) {
@ -42,7 +42,7 @@ CallObject::setAliasedVar(JSContext *cx, AliasedFormalIter fi, PropertyName *nam
MOZ_ASSERT(name == fi->name());
setSlot(fi.scopeSlot(), v);
if (isSingleton())
types::AddTypePropertyId(cx, this, NameToId(name), v);
AddTypePropertyId(cx, this, NameToId(name), v);
}
inline void
@ -50,7 +50,7 @@ CallObject::setAliasedVarFromArguments(JSContext *cx, const Value &argsValue, js
{
setSlot(ArgumentsObject::SlotFromMagicScopeSlotValue(argsValue), v);
if (isSingleton())
types::AddTypePropertyId(cx, this, id, v);
AddTypePropertyId(cx, this, id, v);
}
inline void

View File

@ -25,7 +25,6 @@
using namespace js;
using namespace js::gc;
using namespace js::types;
using mozilla::PodZero;

View File

@ -893,7 +893,7 @@ NativeObject::changeProperty(ExclusiveContext *cx, HandleNativeObject obj,
MOZ_ASSERT(!((attrs ^ shape->attrs) & JSPROP_SHARED) ||
!(attrs & JSPROP_SHARED));
types::MarkTypePropertyNonData(cx, obj, shape->propid());
MarkTypePropertyNonData(cx, obj, shape->propid());
if (!CheckCanChangeAttrs(cx, obj, shape, &attrs))
return nullptr;

View File

@ -47,7 +47,6 @@
using namespace js;
using namespace js::gc;
using namespace js::types;
using mozilla::IsNaN;
using mozilla::NegativeInfinity;

View File

@ -47,7 +47,6 @@
using namespace js;
using namespace js::gc;
using namespace js::types;
using mozilla::IsNaN;
using mozilla::NegativeInfinity;

View File

@ -42,10 +42,10 @@ UnboxedLayout::sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf)
}
void
UnboxedLayout::setNewScript(types::TypeNewScript *newScript, bool writeBarrier /* = true */)
UnboxedLayout::setNewScript(TypeNewScript *newScript, bool writeBarrier /* = true */)
{
if (newScript_ && writeBarrier)
types::TypeNewScript::writeBarrierPre(newScript_);
TypeNewScript::writeBarrierPre(newScript_);
newScript_ = newScript;
}
@ -92,7 +92,7 @@ UnboxedPlainObject::setValue(JSContext *cx, const UnboxedLayout::Property &prope
// Update property types when writing object properties. Types for
// other properties were captured when the unboxed layout was
// created.
types::AddTypePropertyId(cx, this, NameToId(property.name), v);
AddTypePropertyId(cx, this, NameToId(property.name), v);
*reinterpret_cast<HeapPtrObject*>(p) = v.toObjectOrNull();
return true;
@ -440,7 +440,7 @@ PropertiesAreSuperset(const UnboxedLayout::PropertyVector &properties, UnboxedLa
bool
js::TryConvertToUnboxedLayout(JSContext *cx, Shape *templateShape,
ObjectGroup *group, types::PreliminaryObjectArray *objects)
ObjectGroup *group, PreliminaryObjectArray *objects)
{
if (!cx->runtime()->options().unboxedObjects())
return true;
@ -453,7 +453,7 @@ js::TryConvertToUnboxedLayout(JSContext *cx, Shape *templateShape,
return false;
size_t objectCount = 0;
for (size_t i = 0; i < types::PreliminaryObjectArray::COUNT; i++) {
for (size_t i = 0; i < PreliminaryObjectArray::COUNT; i++) {
JSObject *obj = objects->get(i);
if (!obj)
continue;
@ -625,7 +625,7 @@ js::TryConvertToUnboxedLayout(JSContext *cx, Shape *templateShape,
Vector<Value, 0, SystemAllocPolicy> values;
if (!values.reserve(objectCount * templateShape->slotSpan()))
return false;
for (size_t i = 0; i < types::PreliminaryObjectArray::COUNT; i++) {
for (size_t i = 0; i < PreliminaryObjectArray::COUNT; i++) {
if (!objects->get(i))
continue;
@ -639,14 +639,14 @@ js::TryConvertToUnboxedLayout(JSContext *cx, Shape *templateShape,
obj->setLastPropertyMakeNonNative(newShape);
}
if (types::TypeNewScript *newScript = group->newScript())
if (TypeNewScript *newScript = group->newScript())
layout->setNewScript(newScript);
group->setClasp(&UnboxedPlainObject::class_);
group->setUnboxedLayout(layout.get());
size_t valueCursor = 0;
for (size_t i = 0; i < types::PreliminaryObjectArray::COUNT; i++) {
for (size_t i = 0; i < PreliminaryObjectArray::COUNT; i++) {
if (!objects->get(i))
continue;
UnboxedPlainObject *obj = &objects->get(i)->as<UnboxedPlainObject>();

View File

@ -58,7 +58,7 @@ class UnboxedLayout : public mozilla::LinkedListElement<UnboxedLayout>
size_t size_;
// Any 'new' script information associated with this layout.
types::TypeNewScript *newScript_;
TypeNewScript *newScript_;
// List for use in tracing objects with this layout. This has the same
// structure as the trace list on a TypeDescr.
@ -80,11 +80,11 @@ class UnboxedLayout : public mozilla::LinkedListElement<UnboxedLayout>
return properties_;
}
types::TypeNewScript *newScript() const {
TypeNewScript *newScript() const {
return newScript_;
}
void setNewScript(types::TypeNewScript *newScript, bool writeBarrier = true);
void setNewScript(TypeNewScript *newScript, bool writeBarrier = true);
const int32_t *traceList() const {
return traceList_;
@ -182,7 +182,7 @@ class UnboxedPlainObject : public JSObject
// preliminary objects and their group to the new unboxed representation.
bool
TryConvertToUnboxedLayout(JSContext *cx, Shape *templateShape,
ObjectGroup *group, types::PreliminaryObjectArray *objects);
ObjectGroup *group, PreliminaryObjectArray *objects);
inline gc::AllocKind
UnboxedLayout::getAllocKind() const

View File

@ -1,4 +1,4 @@
#filter substitution;
#filter substitution
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -63,13 +63,6 @@ let AppConstants = Object.freeze({
false,
#endif
MOZ_DEVICES:
#ifdef MOZ_DEVICES
true,
#else
false,
#endif
MOZ_SAFE_BROWSING:
#ifdef MOZ_SAFE_BROWSING
true,