Merge mozilla-central to autoland

This commit is contained in:
Dorel Luca 2018-02-17 11:59:56 +02:00
commit e6b2438e24
321 changed files with 2836 additions and 3546 deletions

View File

@ -114,7 +114,7 @@ oddly_ordered_inclnames = set([
'frontend/ReservedWordsGenerated.h', # Included in the body of frontend/TokenStream.h
'gc/StatsPhasesGenerated.h', # Included in the body of gc/Statistics.h
'gc/StatsPhasesGenerated.cpp', # Included in the body of gc/Statistics.cpp
'jswin.h', # Must be #included before <psapi.h>
'util/Windows.h', # Must be #included before <psapi.h>
'machine/endian.h', # Must be included after <sys/types.h> on BSD
'winbase.h', # Must precede other system headers(?)
'windef.h' # Must precede other system headers(?)

View File

@ -101,6 +101,7 @@ support-files =
[browser_dbg-asm.js]
[browser_dbg-async-stepping.js]
[browser_dbg-babel.js]
skip-if = (os == "win" && ccov) # bug 1438797
[browser_dbg-breaking.js]
[browser_dbg-breaking-from-console.js]
[browser_dbg-breakpoints.js]

View File

@ -303,6 +303,7 @@ define(function (require, exports, module) {
dom.a({
id: id ? id + "-tab" : "tab-" + index,
tabIndex: isTabSelected ? 0 : -1,
title,
"aria-controls": id ? id + "-panel" : "panel-" + index,
"aria-selected": isTabSelected,
role: "tab",

View File

@ -908,24 +908,44 @@ let SourceActor = ActorClassWithSpec(sourceSpec, {
}
}
} else {
// Compute columnToOffsetMaps for each script so that we can
// find matching entrypoints for the column breakpoint.
const columnToOffsetMaps = scripts.map(script =>
[
script,
script.getAllColumnOffsets()
.filter(({ lineNumber }) => lineNumber === generatedLine)
]
);
// This is a column breakpoint, so we are interested in all column
// offsets that correspond to the given line *and* column number.
for (let script of scripts) {
let columnToOffsetMap = script.getAllColumnOffsets()
.filter(({ lineNumber }) => {
return lineNumber === generatedLine;
});
for (let [script, columnToOffsetMap] of columnToOffsetMaps) {
for (let { columnNumber: column, offset } of columnToOffsetMap) {
if (column >= generatedColumn && column <= generatedLastColumn) {
entryPoints.push({ script, offsets: [offset] });
}
}
}
// If we don't find any matching entrypoints, then
// we should check to see if the breakpoint is to the left of the first offset.
if (entryPoints.length === 0) {
for (let [script, columnToOffsetMap] of columnToOffsetMaps) {
if (columnToOffsetMap.length > 0) {
let { columnNumber: column, offset } = columnToOffsetMap[0];
if (generatedColumn < column) {
entryPoints.push({ script, offsets: [offset] });
}
}
}
}
}
if (entryPoints.length === 0) {
return false;
}
setBreakpointAtEntryPoints(actor, entryPoints);
return true;
}

View File

@ -0,0 +1,64 @@
"use strict";
var SOURCE_URL = getFileUrl("setBreakpoint-on-column.js");
function run_test() {
return async function () {
do_test_pending();
DebuggerServer.registerModule("xpcshell-test/testactors");
DebuggerServer.init(() => true);
let global = createTestGlobal("test");
DebuggerServer.addTestGlobal(global);
let client = new DebuggerClient(DebuggerServer.connectPipe());
await connect(client);
let { tabs } = await listTabs(client);
let tab = findTab(tabs, "test");
let [, tabClient] = await attachTab(client, tab);
let [, threadClient] = await attachThread(tabClient);
await resume(threadClient);
let promise = waitForNewSource(threadClient, SOURCE_URL);
loadSubScript(SOURCE_URL, global);
let { source } = await promise;
let sourceClient = threadClient.source(source);
let location = { line: 4, column: 2 };
let [packet, breakpointClient] = await setBreakpoint(
sourceClient,
location
);
Assert.ok(!packet.isPending);
Assert.equal(false, "actualLocation" in packet);
packet = await executeOnNextTickAndWaitForPause(function () {
Cu.evalInSandbox("f()", global);
}, client);
Assert.equal(packet.type, "paused");
let why = packet.why;
Assert.equal(why.type, "breakpoint");
Assert.equal(why.actors.length, 1);
Assert.equal(why.actors[0], breakpointClient.actor);
let frame = packet.frame;
let where = frame.where;
Assert.equal(where.source.actor, source.actor);
Assert.equal(where.line, location.line);
Assert.equal(where.column, 6);
let variables = frame.environment.bindings.variables;
Assert.equal(variables.a.value.type, "undefined");
Assert.equal(variables.b.value.type, "undefined");
Assert.equal(variables.c.value.type, "undefined");
await resume(threadClient);
await close(client);
do_test_finished();
};
}

View File

@ -222,6 +222,7 @@ reason = bug 937197
[test_get-executable-lines-source-map.js]
[test_xpcshell_debugging.js]
support-files = xpcshell_debugging_script.js
[test_setBreakpoint-at-the-beginning-of-a-line.js]
[test_setBreakpoint-on-column.js]
[test_setBreakpoint-on-column-in-gcd-script.js]
[test_setBreakpoint-on-column-with-no-offsets-at-end-of-line.js]

View File

@ -9,6 +9,8 @@
#include "mozilla/dom/StyleSheetList.h"
#include "nsDocument.h"
#include "nsFocusManager.h"
#include "nsLayoutUtils.h"
#include "nsSVGUtils.h"
namespace mozilla {
namespace dom {
@ -166,5 +168,120 @@ DocumentOrShadowRoot::GetFullscreenElement()
return nullptr;
}
Element*
DocumentOrShadowRoot::ElementFromPoint(float aX, float aY)
{
return ElementFromPointHelper(aX, aY, false, true);
}
void
DocumentOrShadowRoot::ElementsFromPoint(float aX, float aY,
nsTArray<RefPtr<Element>>& aElements)
{
ElementsFromPointHelper(aX, aY, nsIDocument::FLUSH_LAYOUT, aElements);
}
Element*
DocumentOrShadowRoot::ElementFromPointHelper(float aX, float aY,
bool aIgnoreRootScrollFrame,
bool aFlushLayout)
{
AutoTArray<RefPtr<Element>, 1> elementArray;
ElementsFromPointHelper(aX, aY,
((aIgnoreRootScrollFrame ? nsIDocument::IGNORE_ROOT_SCROLL_FRAME : 0) |
(aFlushLayout ? nsIDocument::FLUSH_LAYOUT : 0) |
nsIDocument::IS_ELEMENT_FROM_POINT),
elementArray);
if (elementArray.IsEmpty()) {
return nullptr;
}
return elementArray[0];
}
void
DocumentOrShadowRoot::ElementsFromPointHelper(float aX, float aY,
uint32_t aFlags,
nsTArray<RefPtr<mozilla::dom::Element>>& aElements)
{
// As per the the spec, we return null if either coord is negative
if (!(aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) && (aX < 0 || aY < 0)) {
return;
}
nscoord x = nsPresContext::CSSPixelsToAppUnits(aX);
nscoord y = nsPresContext::CSSPixelsToAppUnits(aY);
nsPoint pt(x, y);
nsCOMPtr<nsIDocument> doc = AsNode().OwnerDoc();
// Make sure the layout information we get is up-to-date, and
// ensure we get a root frame (for everything but XUL)
if (aFlags & nsIDocument::FLUSH_LAYOUT) {
doc->FlushPendingNotifications(FlushType::Layout);
}
nsIPresShell* ps = doc->GetShell();
if (!ps) {
return;
}
nsIFrame* rootFrame = ps->GetRootFrame();
// XUL docs, unlike HTML, have no frame tree until everything's done loading
if (!rootFrame) {
return; // return null to premature XUL callers as a reminder to wait
}
nsTArray<nsIFrame*> outFrames;
// Emulate what GetFrameAtPoint does, since we want all the frames under our
// point.
nsLayoutUtils::GetFramesForArea(rootFrame, nsRect(pt, nsSize(1, 1)), outFrames,
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC |
((aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) ? nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME : 0));
// Dunno when this would ever happen, as we should at least have a root frame under us?
if (outFrames.IsEmpty()) {
return;
}
// Used to filter out repeated elements in sequence.
nsIContent* lastAdded = nullptr;
for (uint32_t i = 0; i < outFrames.Length(); i++) {
nsIContent* node = doc->GetContentInThisDocument(outFrames[i]);
if (!node || !node->IsElement()) {
// If this helper is called via ElementsFromPoint, we need to make sure
// our frame is an element. Otherwise return whatever the top frame is
// even if it isn't the top-painted element.
// SVG 'text' element's SVGTextFrame doesn't respond to hit-testing, so
// if 'node' is a child of such an element then we need to manually defer
// to the parent here.
if (!(aFlags & nsIDocument::IS_ELEMENT_FROM_POINT) &&
!nsSVGUtils::IsInSVGTextSubtree(outFrames[i])) {
continue;
}
node = node->GetParent();
if (ShadowRoot* shadow = ShadowRoot::FromNodeOrNull(node)) {
node = shadow->Host();
}
}
//XXXsmaug There is plenty of unspec'ed behavior here
// https://github.com/w3c/webcomponents/issues/735
// https://github.com/w3c/webcomponents/issues/736
node = Retarget(node);
if (node && node != lastAdded) {
aElements.AppendElement(node->AsElement());
lastAdded = node;
// If this helper is called via ElementFromPoint, just return the first
// element we find.
if (aFlags & nsIDocument::IS_ELEMENT_FROM_POINT) {
return;
}
}
}
}
}
}

View File

@ -115,6 +115,30 @@ public:
Element* GetPointerLockElement();
Element* GetFullscreenElement();
Element* ElementFromPoint(float aX, float aY);
void ElementsFromPoint(float aX, float aY,
nsTArray<RefPtr<mozilla::dom::Element>>& aElements);
/**
* Helper for nsIDOMDocument::elementFromPoint implementation that allows
* ignoring the scroll frame and/or avoiding layout flushes.
*
* @see nsIDOMWindowUtils::elementFromPoint
*/
Element* ElementFromPointHelper(float aX, float aY,
bool aIgnoreRootScrollFrame,
bool aFlushLayout);
enum ElementsFromPointFlags
{
IGNORE_ROOT_SCROLL_FRAME = 1,
FLUSH_LAYOUT = 2,
IS_ELEMENT_FROM_POINT = 4
};
void ElementsFromPointHelper(float aX, float aY, uint32_t aFlags,
nsTArray<RefPtr<mozilla::dom::Element>>& aElements);
protected:
nsIContent* Retarget(nsIContent* aContent) const;

View File

@ -3726,7 +3726,7 @@ Element::GetTransformToAncestor(Element& aAncestor)
// then the call to GetTransformToAncestor will return the transform
// all the way up through the parent chain.
transform = nsLayoutUtils::GetTransformToAncestor(primaryFrame,
ancestorFrame, nsIFrame::IN_CSS_UNITS);
ancestorFrame, nsIFrame::IN_CSS_UNITS).GetMatrix();
}
DOMMatrixReadOnly* matrix = new DOMMatrix(this, transform, IsStyledByServo());
@ -3743,7 +3743,7 @@ Element::GetTransformToParent()
if (primaryFrame) {
nsIFrame* parentFrame = primaryFrame->GetParent();
transform = nsLayoutUtils::GetTransformToAncestor(primaryFrame,
parentFrame, nsIFrame::IN_CSS_UNITS);
parentFrame, nsIFrame::IN_CSS_UNITS).GetMatrix();
}
DOMMatrixReadOnly* matrix = new DOMMatrix(this, transform, IsStyledByServo());
@ -3758,7 +3758,7 @@ Element::GetTransformToViewport()
Matrix4x4 transform;
if (primaryFrame) {
transform = nsLayoutUtils::GetTransformToAncestor(primaryFrame,
nsLayoutUtils::GetDisplayRootFrame(primaryFrame), nsIFrame::IN_CSS_UNITS);
nsLayoutUtils::GetDisplayRootFrame(primaryFrame), nsIFrame::IN_CSS_UNITS).GetMatrix();
}
DOMMatrixReadOnly* matrix = new DOMMatrix(this, transform, IsStyledByServo());

View File

@ -3544,110 +3544,6 @@ nsIDocument::GetCurrentScript()
return el;
}
Element*
nsIDocument::ElementFromPoint(float aX, float aY)
{
return ElementFromPointHelper(aX, aY, false, true);
}
void
nsIDocument::ElementsFromPoint(float aX, float aY,
nsTArray<RefPtr<Element>>& aElements)
{
ElementsFromPointHelper(aX, aY, nsIDocument::FLUSH_LAYOUT, aElements);
}
Element*
nsDocument::ElementFromPointHelper(float aX, float aY,
bool aIgnoreRootScrollFrame,
bool aFlushLayout)
{
AutoTArray<RefPtr<Element>, 1> elementArray;
ElementsFromPointHelper(aX, aY,
((aIgnoreRootScrollFrame ? nsIDocument::IGNORE_ROOT_SCROLL_FRAME : 0) |
(aFlushLayout ? nsIDocument::FLUSH_LAYOUT : 0) |
nsIDocument::IS_ELEMENT_FROM_POINT),
elementArray);
if (elementArray.IsEmpty()) {
return nullptr;
}
return elementArray[0];
}
void
nsDocument::ElementsFromPointHelper(float aX, float aY,
uint32_t aFlags,
nsTArray<RefPtr<mozilla::dom::Element>>& aElements)
{
// As per the the spec, we return null if either coord is negative
if (!(aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) && (aX < 0 || aY < 0)) {
return;
}
nscoord x = nsPresContext::CSSPixelsToAppUnits(aX);
nscoord y = nsPresContext::CSSPixelsToAppUnits(aY);
nsPoint pt(x, y);
// Make sure the layout information we get is up-to-date, and
// ensure we get a root frame (for everything but XUL)
if (aFlags & nsIDocument::FLUSH_LAYOUT) {
FlushPendingNotifications(FlushType::Layout);
}
nsIPresShell *ps = GetShell();
if (!ps) {
return;
}
nsIFrame *rootFrame = ps->GetRootFrame();
// XUL docs, unlike HTML, have no frame tree until everything's done loading
if (!rootFrame) {
return; // return null to premature XUL callers as a reminder to wait
}
nsTArray<nsIFrame*> outFrames;
// Emulate what GetFrameAtPoint does, since we want all the frames under our
// point.
nsLayoutUtils::GetFramesForArea(rootFrame, nsRect(pt, nsSize(1, 1)), outFrames,
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC |
((aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) ? nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME : 0));
// Dunno when this would ever happen, as we should at least have a root frame under us?
if (outFrames.IsEmpty()) {
return;
}
// Used to filter out repeated elements in sequence.
nsIContent* lastAdded = nullptr;
for (uint32_t i = 0; i < outFrames.Length(); i++) {
nsIContent* node = GetContentInThisDocument(outFrames[i]);
if (!node || !node->IsElement()) {
// If this helper is called via ElementsFromPoint, we need to make sure
// our frame is an element. Otherwise return whatever the top frame is
// even if it isn't the top-painted element.
// SVG 'text' element's SVGTextFrame doesn't respond to hit-testing, so
// if 'node' is a child of such an element then we need to manually defer
// to the parent here.
if (!(aFlags & nsIDocument::IS_ELEMENT_FROM_POINT) &&
!nsSVGUtils::IsInSVGTextSubtree(outFrames[i])) {
continue;
}
node = node->GetParent();
}
if (node && node != lastAdded) {
aElements.AppendElement(node->AsElement());
lastAdded = node;
// If this helper is called via ElementFromPoint, just return the first
// element we find.
if (aFlags & nsIDocument::IS_ELEMENT_FROM_POINT) {
return;
}
}
}
}
nsresult
nsDocument::NodesFromRectHelper(float aX, float aY,
float aTopSize, float aRightSize,
@ -8539,7 +8435,7 @@ nsDocument::DoUnblockOnload()
}
nsIContent*
nsDocument::GetContentInThisDocument(nsIFrame* aFrame) const
nsIDocument::GetContentInThisDocument(nsIFrame* aFrame) const
{
for (nsIFrame* f = aFrame; f;
f = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(f)) {

View File

@ -690,14 +690,6 @@ public:
nsAtom* aAttrName,
const nsAString& aAttrValue) const override;
virtual Element* ElementFromPointHelper(float aX, float aY,
bool aIgnoreRootScrollFrame,
bool aFlushLayout) override;
virtual void ElementsFromPointHelper(float aX, float aY,
uint32_t aFlags,
nsTArray<RefPtr<mozilla::dom::Element>>& aElements) override;
virtual nsresult NodesFromRectHelper(float aX, float aY,
float aTopSize, float aRightSize,
float aBottomSize, float aLeftSize,
@ -1225,16 +1217,6 @@ private:
nsresult InitCSP(nsIChannel* aChannel);
/**
* Find the (non-anonymous) content in this document for aFrame. It will
* be aFrame's content node if that content is in this document and not
* anonymous. Otherwise, when aFrame is in a subdocument, we use the frame
* element containing the subdocument containing aFrame, and/or find the
* nearest non-anonymous ancestor in this document.
* Returns null if there is no such element.
*/
nsIContent* GetContentInThisDocument(nsIFrame* aFrame) const;
// Just like EnableStyleSheetsForSet, but doesn't check whether
// aSheetSet is null and allows the caller to control whether to set
// aSheetSet as the preferred set in the CSSLoader.

View File

@ -2096,26 +2096,6 @@ public:
nsAtom* aAttrName,
const nsAString& aAttrValue) const = 0;
/**
* Helper for nsIDOMDocument::elementFromPoint implementation that allows
* ignoring the scroll frame and/or avoiding layout flushes.
*
* @see nsIDOMWindowUtils::elementFromPoint
*/
virtual Element* ElementFromPointHelper(float aX, float aY,
bool aIgnoreRootScrollFrame,
bool aFlushLayout) = 0;
enum ElementsFromPointFlags {
IGNORE_ROOT_SCROLL_FRAME = 1,
FLUSH_LAYOUT = 2,
IS_ELEMENT_FROM_POINT = 4
};
virtual void ElementsFromPointHelper(float aX, float aY,
uint32_t aFlags,
nsTArray<RefPtr<mozilla::dom::Element>>& aElements) = 0;
virtual nsresult NodesFromRectHelper(float aX, float aY,
float aTopSize, float aRightSize,
float aBottomSize, float aLeftSize,
@ -2955,10 +2935,6 @@ public:
void GetPreferredStyleSheetSet(nsAString& aSheetSet);
virtual mozilla::dom::DOMStringList* StyleSheetSets() = 0;
virtual void EnableStyleSheetsForSet(const nsAString& aSheetSet) = 0;
Element* ElementFromPoint(float aX, float aY);
void ElementsFromPoint(float aX,
float aY,
nsTArray<RefPtr<mozilla::dom::Element>>& aElements);
/**
* Retrieve the location of the caret position (DOM node and character
@ -3210,6 +3186,16 @@ public:
bool ModuleScriptsEnabled();
/**
* Find the (non-anonymous) content in this document for aFrame. It will
* be aFrame's content node if that content is in this document and not
* anonymous. Otherwise, when aFrame is in a subdocument, we use the frame
* element containing the subdocument containing aFrame, and/or find the
* nearest non-anonymous ancestor in this document.
* Returns null if there is no such element.
*/
nsIContent* GetContentInThisDocument(nsIFrame* aFrame) const;
protected:
bool GetUseCounter(mozilla::UseCounter aUseCounter)
{

View File

@ -285,8 +285,6 @@ partial interface Document {
// http://dev.w3.org/csswg/cssom-view/#extensions-to-the-document-interface
partial interface Document {
Element? elementFromPoint (float x, float y);
sequence<Element> elementsFromPoint (float x, float y);
CaretPosition? caretPositionFromPoint (float x, float y);
readonly attribute Element? scrollingElement;

View File

@ -12,10 +12,8 @@
interface DocumentOrShadowRoot {
// Not implemented yet: bug 1430308.
// Selection? getSelection();
// Not implemented yet: bug 1430301.
// Element? elementFromPoint (float x, float y);
// Not implemented yet: bug 1430301.
// sequence<Element> elementsFromPoint (float x, float y);
Element? elementFromPoint (float x, float y);
sequence<Element> elementsFromPoint (float x, float y);
// Not implemented yet: bug 1430307.
// CaretPosition? caretPositionFromPoint (float x, float y);

View File

@ -1851,6 +1851,416 @@ public:
};
};
/* This Matrix class will carry one additional type field in order to
* track what type of 4x4 matrix we're dealing with, it can then execute
* simplified versions of certain operations when applicable.
* This does not allow access to the parent class directly, as a caller
* could then mutate the parent class without updating the type.
*/
template <typename SourceUnits, typename TargetUnits>
class Matrix4x4TypedFlagged : protected Matrix4x4Typed<SourceUnits, TargetUnits>
{
public:
using Parent = Matrix4x4Typed<SourceUnits, TargetUnits>;
using TargetPoint = PointTyped<TargetUnits>;
using Parent::_11; using Parent::_12; using Parent::_13; using Parent::_14;
using Parent::_21; using Parent::_22; using Parent::_23; using Parent::_24;
using Parent::_31; using Parent::_32; using Parent::_33; using Parent::_34;
using Parent::_41; using Parent::_42; using Parent::_43; using Parent::_44;
Matrix4x4TypedFlagged()
: mType(MatrixType::Identity)
{}
Matrix4x4TypedFlagged(Float a11, Float a12, Float a13, Float a14,
Float a21, Float a22, Float a23, Float a24,
Float a31, Float a32, Float a33, Float a34,
Float a41, Float a42, Float a43, Float a44)
: Parent(a11, a12, a13, a14, a21, a22, a23, a24,
a31, a32, a33, a34, a41, a42, a43, a44)
{
Analyze();
}
MOZ_IMPLICIT Matrix4x4TypedFlagged(const Parent& aOther)
: Parent(aOther)
{
Analyze();
}
template<class F>
PointTyped<TargetUnits, F> TransformPoint(const PointTyped<SourceUnits, F> &aPoint) const
{
if (mType == MatrixType::Identity) {
return aPoint;
}
if (mType == MatrixType::Simple) {
return TransformPointSimple(aPoint);
}
return Parent::TransformPoint(aPoint);
}
template<class F>
RectTyped<TargetUnits, F> TransformAndClipBounds(const RectTyped<SourceUnits, F>& aRect,
const RectTyped<TargetUnits, F>& aClip) const
{
if (mType == MatrixType::Identity) {
return aRect;
}
if (mType == MatrixType::Simple) {
PointTyped<UnknownUnits, F> p1 = TransformPointSimple(aRect.TopLeft());
PointTyped<UnknownUnits, F> p2 = TransformPointSimple(aRect.TopRight());
PointTyped<UnknownUnits, F> p3 = TransformPointSimple(aRect.BottomLeft());
PointTyped<UnknownUnits, F> p4 = TransformPointSimple(aRect.BottomRight());
F min_x = std::min(std::min(std::min(p1.x, p2.x), p3.x), p4.x);
F max_x = std::max(std::max(std::max(p1.x, p2.x), p3.x), p4.x);
F min_y = std::min(std::min(std::min(p1.y, p2.y), p3.y), p4.y);
F max_y = std::max(std::max(std::max(p1.y, p2.y), p3.y), p4.y);
TargetPoint topLeft(std::max(min_x, aClip.x), std::max(min_y, aClip.y));
F xMost = std::min(max_x, aClip.XMost()) - topLeft.x;
F yMost = std::min(max_y, aClip.YMost()) - topLeft.y;
return RectTyped<TargetUnits, F>(topLeft.x, topLeft.y, xMost, yMost);
}
return Parent::TransformAndClipBounds(aRect, aClip);
}
bool FuzzyEqual(const Parent& o) const
{
return Parent::FuzzyEqual(o);
}
bool FuzzyEqual(const Matrix4x4TypedFlagged& o) const
{
if (mType == MatrixType::Identity && o.mType == MatrixType::Identity) {
return true;
}
return Parent::FuzzyEqual(o);
}
Matrix4x4TypedFlagged &PreTranslate(Float aX, Float aY, Float aZ)
{
if (mType == MatrixType::Identity) {
_41 = aX;
_42 = aY;
_43 = aZ;
if (!aZ) {
mType = MatrixType::Simple;
return *this;
}
mType = MatrixType::Full;
return *this;
}
Parent::PreTranslate(aX, aY, aZ);
if (aZ != 0) {
mType = MatrixType::Full;
}
return *this;
}
Matrix4x4TypedFlagged &PostTranslate(Float aX, Float aY, Float aZ)
{
if (mType == MatrixType::Identity) {
_41 = aX;
_42 = aY;
_43 = aZ;
if (!aZ) {
mType = MatrixType::Simple;
return *this;
}
mType = MatrixType::Full;
return *this;
}
Parent::PostTranslate(aX, aY, aZ);
if (aZ != 0) {
mType = MatrixType::Full;
}
return *this;
}
Matrix4x4TypedFlagged &ChangeBasis(Float aX, Float aY, Float aZ)
{
// Translate to the origin before applying this matrix
PreTranslate(-aX, -aY, -aZ);
// Translate back into position after applying this matrix
PostTranslate(aX, aY, aZ);
return *this;
}
bool IsIdentity() const
{
return mType == MatrixType::Identity;
}
template<class F>
Point4DTyped<TargetUnits, F>
ProjectPoint(const PointTyped<SourceUnits, F>& aPoint) const {
if (mType == MatrixType::Identity) {
return Point4DTyped<TargetUnits, F>(aPoint.x, aPoint.y, 0, 1);
}
if (mType == MatrixType::Simple) {
TargetPoint point = TransformPointSimple(aPoint);
return Point4DTyped<TargetUnits, F>(point.x, point.y, 0, 1);
}
return Parent::ProjectPoint(aPoint);
}
Matrix4x4TypedFlagged& ProjectTo2D() {
if (mType == MatrixType::Full) {
Parent::ProjectTo2D();
}
return *this;
}
bool IsSingular() const
{
if (mType == MatrixType::Identity) {
return false;
}
return Parent::Determinant() == 0.0;
}
bool Invert()
{
if (mType == MatrixType::Identity) {
return true;
}
return Parent::Invert();
}
Matrix4x4TypedFlagged<TargetUnits, SourceUnits> Inverse() const
{
typedef Matrix4x4TypedFlagged<TargetUnits, SourceUnits> InvertedMatrix;
InvertedMatrix clone = InvertedMatrix::FromUnknownMatrix(ToUnknownMatrix());
if (mType == MatrixType::Identity) {
return clone;
}
DebugOnly<bool> inverted = clone.Invert();
MOZ_ASSERT(inverted, "Attempted to get the inverse of a non-invertible matrix");
// Inverting a 2D Matrix should result in a 2D matrix, ergo mType doesn't change.
return clone;
}
template <typename NewTargetUnits>
Matrix4x4TypedFlagged<SourceUnits, NewTargetUnits> operator*(const Matrix4x4Typed<TargetUnits, NewTargetUnits> &aMatrix) const
{
if (mType == MatrixType::Identity) {
return aMatrix;
}
if (mType == MatrixType::Simple) {
Matrix4x4TypedFlagged<SourceUnits, NewTargetUnits> matrix;
matrix._11 = _11 * aMatrix._11 + _12 * aMatrix._21;
matrix._21 = _21 * aMatrix._11 + _22 * aMatrix._21;
matrix._31 = aMatrix._31;
matrix._41 = _41 * aMatrix._11 + _42 * aMatrix._21;
matrix._12 = _11 * aMatrix._12 + _12 * aMatrix._22;
matrix._22 = _21 * aMatrix._12 + _22 * aMatrix._22;
matrix._32 = aMatrix._32;
matrix._42 = _41 * aMatrix._12 + _42 * aMatrix._22;
matrix._13 = _11 * aMatrix._13 + _12 * aMatrix._23;
matrix._23 = _21 * aMatrix._13 + _22 * aMatrix._23;
matrix._33 = aMatrix._33;
matrix._43 = _41 * aMatrix._13 + _42 * aMatrix._23;
matrix._14 = _11 * aMatrix._14 + _12 * aMatrix._24;
matrix._24 = _21 * aMatrix._14 + _22 * aMatrix._24;
matrix._34 = aMatrix._34;
matrix._44 = _41 * aMatrix._14 + _42 * aMatrix._24;
matrix.Analyze();
return matrix;
}
return Parent::operator*(aMatrix);
}
template <typename NewTargetUnits>
Matrix4x4TypedFlagged<SourceUnits, NewTargetUnits> operator*(const Matrix4x4TypedFlagged<TargetUnits, NewTargetUnits> &aMatrix) const
{
if (mType == MatrixType::Identity) {
return aMatrix;
}
if (aMatrix.mType == MatrixType::Identity) {
return Matrix4x4TypedFlagged<SourceUnits, NewTargetUnits>::FromUnknownMatrix(this->ToUnknownMatrix());
}
if (mType == MatrixType::Simple && aMatrix.mType == MatrixType::Simple) {
Matrix4x4TypedFlagged<SourceUnits, NewTargetUnits> matrix;
matrix._11 = _11 * aMatrix._11 + _12 * aMatrix._21;
matrix._21 = _21 * aMatrix._11 + _22 * aMatrix._21;
matrix._41 = _41 * aMatrix._11 + _42 * aMatrix._21 + aMatrix._41;
matrix._12 = _11 * aMatrix._12 + _12 * aMatrix._22;
matrix._22 = _21 * aMatrix._12 + _22 * aMatrix._22;
matrix._42 = _41 * aMatrix._12 + _42 * aMatrix._22 + aMatrix._42;
matrix.mType = MatrixType::Simple;
return matrix;
} else if (mType == MatrixType::Simple) {
Matrix4x4TypedFlagged<SourceUnits, NewTargetUnits> matrix;
matrix._11 = _11 * aMatrix._11 + _12 * aMatrix._21;
matrix._21 = _21 * aMatrix._11 + _22 * aMatrix._21;
matrix._31 = aMatrix._31;
matrix._41 = _41 * aMatrix._11 + _42 * aMatrix._21 + aMatrix._41;
matrix._12 = _11 * aMatrix._12 + _12 * aMatrix._22;
matrix._22 = _21 * aMatrix._12 + _22 * aMatrix._22;
matrix._32 = aMatrix._32;
matrix._42 = _41 * aMatrix._12 + _42 * aMatrix._22 + aMatrix._42;
matrix._13 = _11 * aMatrix._13 + _12 * aMatrix._23;
matrix._23 = _21 * aMatrix._13 + _22 * aMatrix._23;
matrix._33 = aMatrix._33;
matrix._43 = _41 * aMatrix._13 + _42 * aMatrix._23 + aMatrix._43;
matrix._14 = _11 * aMatrix._14 + _12 * aMatrix._24;
matrix._24 = _21 * aMatrix._14 + _22 * aMatrix._24;
matrix._34 = aMatrix._34;
matrix._44 = _41 * aMatrix._14 + _42 * aMatrix._24 + aMatrix._44;
matrix.mType = MatrixType::Full;
return matrix;
} else if (aMatrix.mType == MatrixType::Simple) {
Matrix4x4TypedFlagged<SourceUnits, NewTargetUnits> matrix;
matrix._11 = _11 * aMatrix._11 + _12 * aMatrix._21 + _14 * aMatrix._41;
matrix._21 = _21 * aMatrix._11 + _22 * aMatrix._21 + _24 * aMatrix._41;
matrix._31 = _31 * aMatrix._11 + _32 * aMatrix._21 + _34 * aMatrix._41;
matrix._41 = _41 * aMatrix._11 + _42 * aMatrix._21 + _44 * aMatrix._41;
matrix._12 = _11 * aMatrix._12 + _12 * aMatrix._22 + _14 * aMatrix._42;
matrix._22 = _21 * aMatrix._12 + _22 * aMatrix._22 + _24 * aMatrix._42;
matrix._32 = _31 * aMatrix._12 + _32 * aMatrix._22 + _34 * aMatrix._42;
matrix._42 = _41 * aMatrix._12 + _42 * aMatrix._22 + _44 * aMatrix._42;
matrix._13 = _13;
matrix._23 = _23;
matrix._33 = _33;
matrix._43 = _43;
matrix._14 = _14;
matrix._24 = _24;
matrix._34 = _34;
matrix._44 = _44;
matrix.mType = MatrixType::Full;
return matrix;
}
return Parent::operator*(aMatrix);
}
bool Is2D() const
{
return mType != MatrixType::Full;
}
bool CanDraw2D(Matrix* aMatrix = nullptr) const
{
if (mType != MatrixType::Full) {
if (aMatrix) {
aMatrix->_11 = _11;
aMatrix->_12 = _12;
aMatrix->_21 = _21;
aMatrix->_22 = _22;
aMatrix->_31 = _41;
aMatrix->_32 = _42;
}
return true;
}
return Parent::CanDraw2D(aMatrix);
}
bool Is2D(Matrix* aMatrix) const {
if (!Is2D()) {
return false;
}
if (aMatrix) {
aMatrix->_11 = _11;
aMatrix->_12 = _12;
aMatrix->_21 = _21;
aMatrix->_22 = _22;
aMatrix->_31 = _41;
aMatrix->_32 = _42;
}
return true;
}
template<class F>
RectTyped<TargetUnits, F>
ProjectRectBounds(const RectTyped<SourceUnits, F>& aRect, const RectTyped<TargetUnits, F>& aClip) const
{
return Parent::ProjectRectBounds(aRect, aClip);
}
const Parent &GetMatrix() const { return *this; }
private:
enum class MatrixType : uint8_t
{
Identity,
Simple, // 2x3 Matrix
Full // 4x4 Matrix
};
Matrix4x4TypedFlagged(Float a11, Float a12, Float a13, Float a14,
Float a21, Float a22, Float a23, Float a24,
Float a31, Float a32, Float a33, Float a34,
Float a41, Float a42, Float a43, Float a44,
typename Matrix4x4TypedFlagged::MatrixType aType)
: Parent(a11, a12, a13, a14, a21, a22, a23, a24,
a31, a32, a33, a34, a41, a42, a43, a44)
{
mType = aType;
}
static Matrix4x4TypedFlagged FromUnknownMatrix(const Matrix4x4Flagged& aUnknown) {
return Matrix4x4TypedFlagged{ aUnknown._11, aUnknown._12, aUnknown._13, aUnknown._14,
aUnknown._21, aUnknown._22, aUnknown._23, aUnknown._24,
aUnknown._31, aUnknown._32, aUnknown._33, aUnknown._34,
aUnknown._41, aUnknown._42, aUnknown._43, aUnknown._44, aUnknown.mType };
}
Matrix4x4Flagged ToUnknownMatrix() const {
return Matrix4x4Flagged{ _11, _12, _13, _14,
_21, _22, _23, _24,
_31, _32, _33, _34,
_41, _42, _43, _44, mType };
}
template<class F>
PointTyped<TargetUnits, F> TransformPointSimple(const PointTyped<SourceUnits, F> &aPoint) const
{
PointTyped<SourceUnits, F> temp;
temp.x = aPoint.x * _11 + aPoint.y * +_21 + _41;
temp.y = aPoint.x * _12 + aPoint.y * +_22 + _42;
return temp;
}
void Analyze() {
if (Parent::IsIdentity()) {
mType = MatrixType::Identity;
return;
}
if (Parent::Is2D()) {
mType = MatrixType::Simple;
return;
}
mType = MatrixType::Full;
}
MatrixType mType;
};
using Matrix4x4Flagged = Matrix4x4TypedFlagged<UnknownUnits, UnknownUnits>;
} // namespace gfx
} // namespace mozilla

View File

@ -27,8 +27,11 @@ struct UnknownUnits;
template<class SourceUnits, class TargetUnits>
class Matrix4x4Typed;
template<class SourceUnits, class TargetUnits>
class Matrix4x4TypedFlagged;
typedef Matrix4x4Typed<UnknownUnits, UnknownUnits> Matrix4x4;
typedef Matrix4x4TypedFlagged<UnknownUnits, UnknownUnits> Matrix4x4Flagged;
} // namespace gfx
} // namespace mozilla

View File

@ -259,6 +259,7 @@ public:
POPLAYER,
UNSCALEDFONTCREATION,
UNSCALEDFONTDESTRUCTION,
INTOLUMINANCE,
};
static const uint32_t kTotalEventTypes = RecordedEvent::FILTERNODESETINPUT + 1;

View File

@ -905,7 +905,7 @@ class RecordedIntoLuminanceSource : public RecordedEventDerived<RecordedIntoLumi
public:
RecordedIntoLuminanceSource(ReferencePtr aRefPtr, DrawTarget *aDT,
LuminanceType aLuminanceType, float aOpacity)
: RecordedEventDerived(SNAPSHOT), mRefPtr(aRefPtr), mDT(aDT),
: RecordedEventDerived(INTOLUMINANCE), mRefPtr(aRefPtr), mDT(aDT),
mLuminanceType(aLuminanceType), mOpacity(aOpacity)
{
}
@ -2800,7 +2800,7 @@ RecordedIntoLuminanceSource::Record(S &aStream) const
template<class S>
RecordedIntoLuminanceSource::RecordedIntoLuminanceSource(S &aStream)
: RecordedEventDerived(SNAPSHOT)
: RecordedEventDerived(INTOLUMINANCE)
{
ReadElement(aStream, mRefPtr);
ReadElement(aStream, mDT);
@ -3413,7 +3413,8 @@ RecordedFilterNodeSetInput::OutputSimpleEventInfo(std::stringstream &aStringStre
f(PUSHLAYER, RecordedPushLayer); \
f(POPLAYER, RecordedPopLayer); \
f(UNSCALEDFONTCREATION, RecordedUnscaledFontCreation); \
f(UNSCALEDFONTDESTRUCTION, RecordedUnscaledFontDestruction);
f(UNSCALEDFONTDESTRUCTION, RecordedUnscaledFontDestruction); \
f(INTOLUMINANCE, RecordedIntoLuminanceSource);
template<class S>
RecordedEvent *

View File

@ -71,14 +71,14 @@ GetTransformIn3DContext(Layer* aLayer) {
* @return local transform for layers not participating 3D rendering
* context, or the accmulated transform in the context for else.
*/
static Matrix4x4
static Matrix4x4Flagged
GetTransformForInvalidation(Layer* aLayer) {
return (!aLayer->Is3DContextLeaf() && !aLayer->Extend3DContext() ?
aLayer->GetLocalTransform() : GetTransformIn3DContext(aLayer));
}
static IntRect
TransformRect(const IntRect& aRect, const Matrix4x4& aTransform)
TransformRect(const IntRect& aRect, const Matrix4x4Flagged& aTransform)
{
if (aRect.IsEmpty()) {
return IntRect();
@ -97,7 +97,7 @@ TransformRect(const IntRect& aRect, const Matrix4x4& aTransform)
}
static void
AddTransformedRegion(nsIntRegion& aDest, const nsIntRegion& aSource, const Matrix4x4& aTransform)
AddTransformedRegion(nsIntRegion& aDest, const nsIntRegion& aSource, const Matrix4x4Flagged& aTransform)
{
for (auto iter = aSource.RectIter(); !iter.Done(); iter.Next()) {
aDest.Or(aDest, TransformRect(iter.Get(), aTransform));
@ -328,7 +328,7 @@ public:
UniquePtr<LayerPropertiesBase> mMaskLayer;
nsTArray<UniquePtr<LayerPropertiesBase>> mAncestorMaskLayers;
nsIntRegion mVisibleRegion;
Matrix4x4 mTransform;
Matrix4x4Flagged mTransform;
float mPostXScale;
float mPostYScale;
float mOpacity;
@ -507,7 +507,7 @@ public:
if (!mLayer->Extend3DContext()) {
// |result| contains invalid regions only of children.
result.Transform(GetTransformForInvalidation(mLayer));
result.Transform(GetTransformForInvalidation(mLayer).GetMatrix());
}
// else, effective transforms have applied on children.

View File

@ -55,6 +55,7 @@ gfxHarfBuzzShaper::gfxHarfBuzzShaper(gfxFont *aFont)
mUVSTableOffset(0),
mNumLongHMetrics(0),
mNumLongVMetrics(0),
mDefaultVOrg(-1.0),
mUseFontGetGlyph(aFont->ProvidesGetGlyph()),
mUseFontGlyphWidths(false),
mInitialized(false),
@ -422,15 +423,17 @@ gfxHarfBuzzShaper::HBGetGlyphVOrigin(hb_font_t *font, void *font_data,
{
const gfxHarfBuzzShaper::FontCallbackData *fcd =
static_cast<const gfxHarfBuzzShaper::FontCallbackData*>(font_data);
fcd->mShaper->GetGlyphVOrigin(glyph, x, y);
fcd->mShaper->GetGlyphVOrigin(*fcd->mDrawTarget, glyph, x, y);
return true;
}
void
gfxHarfBuzzShaper::GetGlyphVOrigin(hb_codepoint_t aGlyph,
gfxHarfBuzzShaper::GetGlyphVOrigin(DrawTarget& aDT, hb_codepoint_t aGlyph,
hb_position_t *aX, hb_position_t *aY) const
{
*aX = 0.5 * GetGlyphHAdvance(aGlyph);
*aX = 0.5 * (mUseFontGlyphWidths
? mFont->GetGlyphWidth(aDT, aGlyph)
: GetGlyphHAdvance(aGlyph));
if (mVORGTable) {
// We checked in Initialize() that the VORG table is safely readable,
@ -493,27 +496,42 @@ gfxHarfBuzzShaper::GetGlyphVOrigin(hb_codepoint_t aGlyph,
}
}
// XXX should we consider using OS/2 sTypo* metrics if available?
if (mDefaultVOrg < 0.0) {
// XXX should we consider using OS/2 sTypo* metrics if available?
gfxFontEntry::AutoTable hheaTable(GetFont()->GetFontEntry(),
TRUETYPE_TAG('h','h','e','a'));
if (hheaTable) {
uint32_t len;
const MetricsHeader* hhea =
reinterpret_cast<const MetricsHeader*>(hb_blob_get_data(hheaTable,
&len));
if (len >= sizeof(MetricsHeader)) {
// divide up the default advance we're using (1em) in proportion
// to ascender:descender from the hhea table
int16_t a = int16_t(hhea->ascender);
int16_t d = int16_t(hhea->descender);
*aY = FloatToFixed(GetFont()->GetAdjustedSize() * a / (a - d));
return;
gfxFontEntry::AutoTable hheaTable(GetFont()->GetFontEntry(),
TRUETYPE_TAG('h','h','e','a'));
if (hheaTable) {
uint32_t len;
const MetricsHeader* hhea =
reinterpret_cast<const MetricsHeader*>(hb_blob_get_data(hheaTable,
&len));
if (len >= sizeof(MetricsHeader)) {
// divide up the default advance we're using (1em) in proportion
// to ascender:descender from the hhea table
int16_t a = int16_t(hhea->ascender);
int16_t d = int16_t(hhea->descender);
mDefaultVOrg =
FloatToFixed(GetFont()->GetAdjustedSize() * a / (a - d));
}
}
if (mDefaultVOrg < 0.0) {
// Last resort, for non-sfnt fonts: get the horizontal metrics and
// compute a default VOrg from their ascent and descent.
const gfxFont::Metrics& mtx = mFont->GetHorizontalMetrics();
gfxFloat advance = mFont->GetMetrics(gfxFont::eVertical).aveCharWidth;
gfxFloat ascent = mtx.emAscent;
gfxFloat height = ascent + mtx.emDescent;
// vOrigin that will place the glyph so that its origin is shifted
// down most of the way within overall (vertical) advance, in
// proportion to the font ascent as a part of the overall font
// height.
mDefaultVOrg = FloatToFixed(advance * ascent / height);
}
}
NS_NOTREACHED("we shouldn't be here!");
*aY = FloatToFixed(GetFont()->GetAdjustedSize() / 2);
*aY = mDefaultVOrg;
}
static hb_bool_t
@ -1331,19 +1349,19 @@ gfxHarfBuzzShaper::LoadHmtxTable()
return true;
}
bool
void
gfxHarfBuzzShaper::InitializeVertical()
{
// We only try this once. If we don't have a mHmtxTable after that,
// this font can't handle vertical shaping, so return false.
// We only do this once. If we don't have a mHmtxTable after that,
// we'll be making up fallback metrics.
if (mVerticalInitialized) {
return mHmtxTable != nullptr;
return;
}
mVerticalInitialized = true;
if (!mHmtxTable) {
if (!LoadHmtxTable()) {
return false;
return;
}
}
@ -1404,8 +1422,6 @@ gfxHarfBuzzShaper::InitializeVertical()
}
}
}
return true;
}
bool
@ -1431,9 +1447,7 @@ gfxHarfBuzzShaper::ShapeText(DrawTarget *aDrawTarget,
}
if (aVertical) {
if (!InitializeVertical()) {
return false;
}
InitializeVertical();
if (!mFont->GetFontEntry()->
SupportsOpenTypeFeature(aScript, HB_TAG('v','e','r','t'))) {
mUseVerticalPresentationForms = true;

View File

@ -52,7 +52,8 @@ public:
hb_position_t GetGlyphVAdvance(hb_codepoint_t glyph) const;
void GetGlyphVOrigin(hb_codepoint_t aGlyph,
void GetGlyphVOrigin(mozilla::gfx::DrawTarget& aDT,
hb_codepoint_t aGlyph,
hb_position_t *aX, hb_position_t *aY) const;
// get harfbuzz horizontal advance in 16.16 fixed point format.
@ -114,7 +115,7 @@ protected:
nsTArray<nsPoint>& aPositions,
uint32_t aAppUnitsPerDevUnit);
bool InitializeVertical();
void InitializeVertical();
bool LoadHmtxTable();
struct Glyf { // we only need the bounding-box at the beginning
@ -176,6 +177,10 @@ protected:
// Similarly for vhea if it's a vertical font.
mutable int32_t mNumLongVMetrics;
// Default y-coordinate for glyph vertical origin, used if the font
// does not actually have vertical-layout metrics.
mutable gfxFloat mDefaultVOrg;
// Whether the font implements GetGlyph, or we should read tables
// directly
bool mUseFontGetGlyph;

View File

@ -16,9 +16,9 @@ namespace JS {
// A wrapper around the internal C++ representation of SpiderMonkey WeakMaps,
// usable outside the engine.
//
// The supported template specializations are enumerated in WeakMapPtr.cpp. If
// you want to use this class for a different key/value combination, add it to
// the list and the compiler will generate the relevant machinery.
// The supported template specializations are enumerated in gc/WeakMapPtr.cpp.
// If you want to use this class for a different key/value combination, add it
// to the list and the compiler will generate the relevant machinery.
template <typename K, typename V>
class JS_PUBLIC_API(WeakMapPtr)
{

View File

@ -14,13 +14,11 @@
#include "jsapi.h"
#include "jsarray.h"
#include "jsnum.h"
#ifdef XP_WIN
# include "jswin.h"
#endif
#include "jswrapper.h"
#include "jit/AtomicOperations.h"
#include "js/Conversions.h"
#include "util/Windows.h"
#include "vm/ArrayBufferObject.h"
#include "vm/GlobalObject.h"
#include "vm/Interpreter.h"

View File

@ -9,9 +9,8 @@
#include "mozilla/HashFunctions.h"
#include "mozilla/Range.h"
#include "jshashutil.h"
#include "frontend/BytecodeCompiler.h"
#include "gc/HashUtil.h"
#include "vm/Debugger.h"
#include "vm/GlobalObject.h"
#include "vm/JSContext.h"

View File

@ -4,7 +4,7 @@
* 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/. */
#include "json.h"
#include "builtin/JSON.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/Range.h"

View File

@ -4,8 +4,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef json_h
#define json_h
#ifndef builtin_JSON_h
#define builtin_JSON_h
#include "mozilla/Range.h"
@ -40,4 +40,4 @@ ParseJSONWithReviver(JSContext* cx, const mozilla::Range<const CharT> chars,
} // namespace js
#endif /* json_h */
#endif /* builtin_JSON_h */

View File

@ -6,13 +6,12 @@
#include "builtin/MapObject.h"
#include "jsiter.h"
#include "ds/OrderedHashTable.h"
#include "gc/FreeOp.h"
#include "js/Utility.h"
#include "vm/GlobalObject.h"
#include "vm/Interpreter.h"
#include "vm/Iteration.h"
#include "vm/JSContext.h"
#include "vm/JSObject.h"
#include "vm/SelfHosting.h"

View File

@ -12,13 +12,13 @@
#include "jsexn.h"
#include "jsfriendapi.h"
#include "jsiter.h"
#include "gc/Heap.h"
#include "js/Debug.h"
#include "vm/AsyncFunction.h"
#include "vm/AsyncIteration.h"
#include "vm/Debugger.h"
#include "vm/Iteration.h"
#include "vm/JSContext.h"
#include "vm/Debugger-inl.h"

View File

@ -2278,14 +2278,16 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
case ParseNodeKind::ExportFrom:
return exportDeclaration(pn, dst);
case ParseNodeKind::Semi:
if (pn->pn_kid) {
RootedValue expr(cx);
return expression(pn->pn_kid, &expr) &&
builder.expressionStatement(expr, &pn->pn_pos, dst);
}
case ParseNodeKind::EmptyStatement:
return builder.emptyStatement(&pn->pn_pos, dst);
case ParseNodeKind::ExpressionStatement:
{
RootedValue expr(cx);
return expression(pn->pn_kid, &expr) &&
builder.expressionStatement(expr, &pn->pn_pos, dst);
}
case ParseNodeKind::LexicalScope:
pn = pn->pn_expr;
if (!pn->isKind(ParseNodeKind::StatementList))
@ -2456,9 +2458,6 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
return builder.classMethods(methods, dst);
}
case ParseNodeKind::Nop:
return builder.emptyStatement(&pn->pn_pos, dst);
default:
LOCAL_NOT_REACHED("unexpected statement type");
}

View File

@ -18,7 +18,6 @@
#include "jsapi.h"
#include "jsfriendapi.h"
#include "jsiter.h"
#include "jsprf.h"
#include "jswrapper.h"
@ -42,6 +41,7 @@
#include "vm/Debugger.h"
#include "vm/GlobalObject.h"
#include "vm/Interpreter.h"
#include "vm/Iteration.h"
#include "vm/JSContext.h"
#include "vm/JSObject.h"
#include "vm/ProxyObject.h"

View File

@ -7,9 +7,8 @@
#ifndef builtin_TypedObject_h
#define builtin_TypedObject_h
#include "jsweakmap.h"
#include "builtin/TypedObjectConstants.h"
#include "gc/WeakMap.h"
#include "js/Conversions.h"
#include "vm/ArrayBufferObject.h"
#include "vm/JSObject.h"

View File

@ -7,8 +7,7 @@
#ifndef builtin_WeakMapObject_h
#define builtin_WeakMapObject_h
#include "jsweakmap.h"
#include "gc/WeakMap.h"
#include "vm/JSObject.h"
namespace js {

View File

@ -7,10 +7,10 @@
#include "builtin/WeakSetObject.h"
#include "jsapi.h"
#include "jsiter.h"
#include "builtin/MapObject.h"
#include "vm/GlobalObject.h"
#include "vm/Iteration.h"
#include "vm/JSContext.h"
#include "vm/SelfHosting.h"

View File

@ -14,27 +14,22 @@
#include <limits>
#include <math.h>
#include <stdint.h>
#if defined(XP_WIN)
#include <float.h>
# include <float.h>
#endif
#if defined(SOLARIS)
#include <ieeefp.h>
# include <ieeefp.h>
#endif
#ifdef HAVE_SSIZE_T
#include <sys/types.h>
# include <sys/types.h>
#endif
#if defined(XP_UNIX)
#include <errno.h>
# include <errno.h>
#endif
#include "jsexn.h"
#include "jsnum.h"
#include "jsprf.h"
#include "jswin.h"
#include "builtin/TypedObject.h"
#include "ctypes/Library.h"
@ -43,6 +38,7 @@
#include "gc/Zone.h"
#include "jit/AtomicOperations.h"
#include "js/Vector.h"
#include "util/Windows.h"
#include "vm/JSContext.h"
#include "vm/JSFunction.h"

View File

@ -9,11 +9,11 @@
// in the same process.
#ifdef WIN32
#include "jswin.h"
# include "util/Windows.h"
#else
#define __cdecl
#include <stdarg.h>
#include <string.h>
# define __cdecl
# include <stdarg.h>
# include <string.h>
#endif
#include "vprof.h"

View File

@ -10,7 +10,7 @@
#include "mozilla/Atomics.h"
#if defined(XP_WIN)
# include "jswin.h"
# include "util/Windows.h"
#elif defined(XP_UNIX) && !defined(XP_DARWIN)
# include <signal.h>
# include <sys/types.h>

View File

@ -1217,8 +1217,6 @@ BinASTParser::parseVariableDeclarationAux(const BinKind kind, const BinFields& f
return raiseMissingField("VariableDeclaration", BinField::Declarations);
result->setKind(pnk);
MOZ_ASSERT(!result->isKind(ParseNodeKind::Nop));
}
return result;

View File

@ -20,13 +20,13 @@
#include "jsapi.h"
#include "jsnum.h"
#include "jsopcode.h"
#include "jstypes.h"
#include "jsutil.h"
#include "ds/Nestable.h"
#include "frontend/Parser.h"
#include "frontend/TokenStream.h"
#include "vm/BytecodeUtil.h"
#include "vm/Debugger.h"
#include "vm/GeneratorObject.h"
#include "vm/JSAtom.h"
@ -3067,7 +3067,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
switch (pn->getKind()) {
// Trivial cases with no side effects.
case ParseNodeKind::Nop:
case ParseNodeKind::EmptyStatement:
case ParseNodeKind::String:
case ParseNodeKind::TemplateString:
case ParseNodeKind::RegExp:
@ -3199,12 +3199,9 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
return checkSideEffects(expr, answer);
}
case ParseNodeKind::Semi:
case ParseNodeKind::ExpressionStatement:
MOZ_ASSERT(pn->isArity(PN_UNARY));
if (ParseNode* expr = pn->pn_kid)
return checkSideEffects(expr, answer);
*answer = false;
return true;
return checkSideEffects(pn->pn_kid, answer);
// Binary cases with obvious side effects.
case ParseNodeKind::Assign:
@ -8714,13 +8711,9 @@ BytecodeEmitter::emitStatementList(ParseNode* pn)
}
bool
BytecodeEmitter::emitStatement(ParseNode* pn)
BytecodeEmitter::emitExpressionStatement(ParseNode* pn)
{
MOZ_ASSERT(pn->isKind(ParseNodeKind::Semi));
ParseNode* pn2 = pn->pn_kid;
if (!pn2)
return true;
MOZ_ASSERT(pn->isKind(ParseNodeKind::ExpressionStatement));
if (!updateSourceCoordNotes(pn->pn_pos.begin))
return false;
@ -8742,8 +8735,9 @@ BytecodeEmitter::emitStatement(ParseNode* pn)
useful = wantval = !script->noScriptRval();
/* Don't eliminate expressions with side effects. */
ParseNode* expr = pn->pn_kid;
if (!useful) {
if (!checkSideEffects(pn2, &useful))
if (!checkSideEffects(expr, &useful))
return false;
/*
@ -8762,8 +8756,8 @@ BytecodeEmitter::emitStatement(ParseNode* pn)
if (useful) {
JSOp op = wantval ? JSOP_SETRVAL : JSOP_POP;
ValueUsage valueUsage = wantval ? ValueUsage::WantValue : ValueUsage::IgnoreValue;
MOZ_ASSERT_IF(pn2->isKind(ParseNodeKind::Assign), pn2->isOp(JSOP_NOP));
if (!emitTree(pn2, valueUsage))
MOZ_ASSERT_IF(expr->isKind(ParseNodeKind::Assign), expr->isOp(JSOP_NOP));
if (!emitTree(expr, valueUsage))
return false;
if (!emit1(op))
return false;
@ -8789,11 +8783,11 @@ BytecodeEmitter::emitStatement(ParseNode* pn)
}
if (directive) {
if (!reportExtraWarning(pn2, JSMSG_CONTRARY_NONDIRECTIVE, directive))
if (!reportExtraWarning(expr, JSMSG_CONTRARY_NONDIRECTIVE, directive))
return false;
}
} else {
if (!reportExtraWarning(pn2, JSMSG_USELESS_EXPR))
if (!reportExtraWarning(expr, JSMSG_USELESS_EXPR))
return false;
}
}
@ -10742,8 +10736,11 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
return false;
break;
case ParseNodeKind::Semi:
if (!emitStatement(pn))
case ParseNodeKind::EmptyStatement:
break;
case ParseNodeKind::ExpressionStatement:
if (!emitExpressionStatement(pn))
return false;
break;
@ -10990,10 +10987,6 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
return false;
break;
case ParseNodeKind::Nop:
MOZ_ASSERT(pn->getArity() == PN_NULLARY);
break;
case ParseNodeKind::Class:
if (!emitClass(pn))
return false;

View File

@ -11,14 +11,13 @@
#include "mozilla/Attributes.h"
#include "jsiter.h"
#include "jsopcode.h"
#include "ds/InlineTable.h"
#include "frontend/EitherParser.h"
#include "frontend/SharedContext.h"
#include "frontend/SourceNotes.h"
#include "vm/BytecodeUtil.h"
#include "vm/Interpreter.h"
#include "vm/Iteration.h"
#include "vm/JSContext.h"
#include "vm/JSScript.h"
@ -767,7 +766,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
MOZ_MUST_USE bool emitAssignment(ParseNode* lhs, ParseNodeKind pnk, ParseNode* rhs);
MOZ_MUST_USE bool emitReturn(ParseNode* pn);
MOZ_MUST_USE bool emitStatement(ParseNode* pn);
MOZ_MUST_USE bool emitExpressionStatement(ParseNode* pn);
MOZ_MUST_USE bool emitStatementList(ParseNode* pn);
MOZ_MUST_USE bool emitDeleteName(ParseNode* pn);

View File

@ -102,14 +102,14 @@ ContainsHoistedDeclaration(JSContext* cx, ParseNode* node, bool* result)
return true;
// Statements with no sub-components at all.
case ParseNodeKind::Nop: // induced by function f() {} function f() {}
case ParseNodeKind::EmptyStatement:
case ParseNodeKind::Debugger:
MOZ_ASSERT(node->isArity(PN_NULLARY));
*result = false;
return true;
// Statements containing only an expression have no declarations.
case ParseNodeKind::Semi:
case ParseNodeKind::ExpressionStatement:
case ParseNodeKind::Throw:
case ParseNodeKind::Return:
MOZ_ASSERT(node->isArity(PN_UNARY));
@ -1590,7 +1590,7 @@ Fold(JSContext* cx, ParseNode** pnp, PerHandlerParser<FullParseHandler>& parser)
ParseNode* pn = *pnp;
switch (pn->getKind()) {
case ParseNodeKind::Nop:
case ParseNodeKind::EmptyStatement:
case ParseNodeKind::RegExp:
case ParseNodeKind::String:
case ParseNodeKind::True:
@ -1655,6 +1655,7 @@ Fold(JSContext* cx, ParseNode** pnp, PerHandlerParser<FullParseHandler>& parser)
case ParseNodeKind::PostDecrement:
return FoldIncrementDecrement(cx, pn, parser);
case ParseNodeKind::ExpressionStatement:
case ParseNodeKind::Throw:
case ParseNodeKind::MutateProto:
case ParseNodeKind::ComputedName:
@ -1668,7 +1669,6 @@ Fold(JSContext* cx, ParseNode** pnp, PerHandlerParser<FullParseHandler>& parser)
MOZ_ASSERT(pn->isArity(PN_BINARY));
return Fold(cx, &pn->pn_left, parser);
case ParseNodeKind::Semi:
case ParseNodeKind::This:
MOZ_ASSERT(pn->isArity(PN_UNARY));
if (ParseNode*& expr = pn->pn_kid)

View File

@ -494,7 +494,7 @@ class FullParseHandler
}
ParseNode* newEmptyStatement(const TokenPos& pos) {
return new_<UnaryNode>(ParseNodeKind::Semi, pos, nullptr);
return new_<NullaryNode>(ParseNodeKind::EmptyStatement, pos);
}
ParseNode* newImportDeclaration(ParseNode* importSpecSet,
@ -541,7 +541,8 @@ class FullParseHandler
ParseNode* newExprStatement(ParseNode* expr, uint32_t end) {
MOZ_ASSERT(expr->pn_pos.end <= end);
return new_<UnaryNode>(ParseNodeKind::Semi, TokenPos(expr->pn_pos.begin, end), expr);
return new_<UnaryNode>(ParseNodeKind::ExpressionStatement,
TokenPos(expr->pn_pos.begin, end), expr);
}
ParseNode* newIfStatement(uint32_t begin, ParseNode* cond, ParseNode* thenBranch,
@ -777,7 +778,7 @@ class FullParseHandler
kind == ParseNodeKind::Var ||
kind == ParseNodeKind::Break ||
kind == ParseNodeKind::Throw ||
(kind == ParseNodeKind::Semi && !node->pn_kid);
kind == ParseNodeKind::EmptyStatement;
}
bool isSuperBase(ParseNode* node) {

View File

@ -4,11 +4,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef frontend_NameAnalysis_h
#define frontend_NameAnalysis_h
#include "jsopcode.h"
#ifndef frontend_NameAnalysisTypes_h
#define frontend_NameAnalysisTypes_h
#include "vm/BytecodeUtil.h"
#include "vm/Scope.h"
namespace js {
@ -377,4 +376,4 @@ struct IsPod<js::frontend::NameLocation> : TrueType {};
} // namespace mozilla
#endif // frontend_NameAnalysis_h
#endif // frontend_NameAnalysisTypes_h

View File

@ -388,7 +388,7 @@ class NameResolver
switch (cur->getKind()) {
// Nodes with no children that might require name resolution need no
// further work.
case ParseNodeKind::Nop:
case ParseNodeKind::EmptyStatement:
case ParseNodeKind::String:
case ParseNodeKind::TemplateString:
case ParseNodeKind::RegExp:
@ -422,6 +422,7 @@ class NameResolver
break;
// Nodes with a single non-null child requiring name resolution.
case ParseNodeKind::ExpressionStatement:
case ParseNodeKind::TypeOfExpr:
case ParseNodeKind::Void:
case ParseNodeKind::Not:
@ -447,7 +448,6 @@ class NameResolver
break;
// Nodes with a single nullable child.
case ParseNodeKind::Semi:
case ParseNodeKind::This:
MOZ_ASSERT(cur->isArity(PN_UNARY));
if (ParseNode* expr = cur->pn_kid) {

View File

@ -183,7 +183,7 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
switch (pn->getKind()) {
// Trivial nodes that refer to no nodes, are referred to by nothing
// but their parents, are never used, and are never a definition.
case ParseNodeKind::Nop:
case ParseNodeKind::EmptyStatement:
case ParseNodeKind::String:
case ParseNodeKind::TemplateString:
case ParseNodeKind::RegExp:
@ -204,6 +204,7 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
return PushResult::Recyclable;
// Nodes with a single non-null child.
case ParseNodeKind::ExpressionStatement:
case ParseNodeKind::TypeOfName:
case ParseNodeKind::TypeOfExpr:
case ParseNodeKind::Void:
@ -228,8 +229,7 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
return PushUnaryNodeChild(pn, stack);
// Nodes with a single nullable child.
case ParseNodeKind::This:
case ParseNodeKind::Semi: {
case ParseNodeKind::This: {
MOZ_ASSERT(pn->isArity(PN_UNARY));
if (pn->pn_kid)
stack->push(pn->pn_kid);

View File

@ -43,8 +43,8 @@ class FunctionBox;
class ObjectBox;
#define FOR_EACH_PARSE_NODE_KIND(F) \
F(Nop) \
F(Semi) \
F(EmptyStatement) \
F(ExpressionStatement) \
F(Comma) \
F(Conditional) \
F(Colon) \
@ -305,10 +305,11 @@ IsTypeofKind(ParseNodeKind kind)
* pn_lexdef (NOT pn_expr) set
* pn_right: initializer
* Return unary pn_kid: return expr or null
* Semi unary pn_kid: expr or null statement
* pn_prologue: true if Directive Prologue member
* in original source, not introduced via
* constant folding or other tree rewriting
* ExpressionStatement unary pn_kid: expr
* pn_prologue: true if Directive Prologue member
* in original source, not introduced via
* constant folding or other tree rewriting
* EmptyStatement nullary (no fields)
* Label name pn_atom: label, pn_expr: labeled statement
* Import binary pn_left: ImportSpecList import specifiers
* pn_right: String module specifier
@ -683,10 +684,10 @@ class ParseNode
* nodes; we use it to determine the extent of the prologue.
*/
JSAtom* isStringExprStatement() const {
if (getKind() == ParseNodeKind::Semi) {
if (getKind() == ParseNodeKind::ExpressionStatement) {
MOZ_ASSERT(pn_arity == PN_UNARY);
ParseNode* kid = pn_kid;
if (kid && kid->getKind() == ParseNodeKind::String && !kid->pn_parens)
if (kid->getKind() == ParseNodeKind::String && !kid->pn_parens)
return kid->pn_atom;
}
return nullptr;

View File

@ -24,7 +24,6 @@
#include "mozilla/TypeTraits.h"
#include "jsapi.h"
#include "jsopcode.h"
#include "jstypes.h"
#include "builtin/ModuleObject.h"
@ -33,6 +32,7 @@
#include "frontend/FoldConstants.h"
#include "frontend/TokenStream.h"
#include "irregexp/RegExpParser.h"
#include "vm/BytecodeUtil.h"
#include "vm/JSAtom.h"
#include "vm/JSContext.h"
#include "vm/JSFunction.h"

View File

@ -168,7 +168,6 @@
#include "mozilla/Maybe.h"
#include "mozilla/TypeTraits.h"
#include "jsiter.h"
#include "jspubtd.h"
#include "ds/Nestable.h"
@ -181,6 +180,7 @@
#include "frontend/SharedContext.h"
#include "frontend/SyntaxParseHandler.h"
#include "frontend/TokenStream.h"
#include "vm/Iteration.h"
namespace js {

View File

@ -7,7 +7,6 @@
#ifndef frontend_SharedContext_h
#define frontend_SharedContext_h
#include "jsopcode.h"
#include "jspubtd.h"
#include "jstypes.h"
@ -15,6 +14,7 @@
#include "ds/InlineTable.h"
#include "frontend/ParseNode.h"
#include "frontend/TokenStream.h"
#include "vm/BytecodeUtil.h"
#include "vm/EnvironmentObject.h"
#include "vm/JSAtom.h"
#include "vm/JSScript.h"

View File

@ -6,10 +6,10 @@
#include "gc/AtomMarking-inl.h"
#include "gc/Iteration.h"
#include "gc/PublicIterators.h"
#include "vm/JSCompartment.h"
#include "jsgcinlines.h"
#include "gc/GC-inl.h"
#include "gc/Heap-inl.h"
namespace js {

View File

@ -4,10 +4,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef jsgcinlines_h
#define jsgcinlines_h
#ifndef gc_GC_inl_h
#define gc_GC_inl_h
#include "jsgc.h"
#include "gc/GC.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Maybe.h"
@ -348,4 +348,4 @@ class ZoneCellIter : public ZoneCellIter<TenuredCell> {
} /* namespace gc */
} /* namespace js */
#endif /* jsgcinlines_h */
#endif /* gc_GC_inl_h */

View File

@ -185,7 +185,7 @@
* this bitmap is managed.
*/
#include "jsgcinlines.h"
#include "gc/GC-inl.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/DebugOnly.h"
@ -204,15 +204,12 @@
# include <sys/mman.h>
# include <unistd.h>
#endif
#include "jsapi.h"
#include "jsfriendapi.h"
#include "jsprf.h"
#include "jstypes.h"
#include "jsutil.h"
#include "jsweakmap.h"
#ifdef XP_WIN
# include "jswin.h"
#endif
#include "gc/FindSCCs.h"
#include "gc/FreeOp.h"
@ -220,11 +217,13 @@
#include "gc/GCTrace.h"
#include "gc/Memory.h"
#include "gc/Policy.h"
#include "gc/WeakMap.h"
#include "jit/BaselineJIT.h"
#include "jit/IonCode.h"
#include "jit/JitcodeMap.h"
#include "js/SliceBudget.h"
#include "proxy/DeadObjectProxy.h"
#include "util/Windows.h"
#include "vm/Debugger.h"
#include "vm/GeckoProfiler.h"
#include "vm/JSAtom.h"
@ -241,10 +240,10 @@
#include "vm/TraceLogging.h"
#include "vm/WrapperObject.h"
#include "gc/GCIteration-inl.h"
#include "gc/Heap-inl.h"
#include "gc/Marking-inl.h"
#include "gc/Nursery-inl.h"
#include "gc/PrivateIterators-inl.h"
#include "vm/GeckoProfiler-inl.h"
#include "vm/JSObject-inl.h"
#include "vm/JSScript-inl.h"

View File

@ -8,8 +8,8 @@
* JS engine garbage collector API.
*/
#ifndef jsgc_h
#define jsgc_h
#ifndef gc_GC_h
#define gc_GC_h
#include "jsapi.h"
@ -144,7 +144,7 @@ enum VerifierType {
extern const char* ZealModeHelpText;
/* Check that write barriers have been used correctly. See jsgc.cpp. */
/* Check that write barriers have been used correctly. See gc/Verifier.cpp. */
void
VerifyBarriers(JSRuntime* rt, VerifierType type);
@ -214,4 +214,4 @@ UninlinedIsInsideNursery(const gc::Cell* cell);
} /* namespace js */
#endif /* jsgc_h */
#endif /* gc_GC_h */

View File

@ -897,7 +897,7 @@ class GCRuntime
* mainly useful to embedders.
*
* We use zeal_ == 4 to enable write barrier verification. See the comment
* in jsgc.cpp for more information about this.
* in gc/Verifier.cpp for more information about this.
*
* zeal_ values from 8 to 10 periodically run different types of
* incremental GC.

View File

@ -4,8 +4,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef jshashutil_h
#define jshashutil_h
#ifndef gc_HashUtil_h
#define gc_HashUtil_h
#include "gc/Zone.h"
#include "vm/JSContext.h"

View File

@ -33,10 +33,9 @@
#include "vm/UnboxedObject.h"
#include "wasm/WasmJS.h"
#include "jsgcinlines.h"
#include "gc/GCIteration-inl.h"
#include "gc/GC-inl.h"
#include "gc/Nursery-inl.h"
#include "gc/PrivateIterators-inl.h"
#include "vm/JSCompartment-inl.h"
#include "vm/NativeObject-inl.h"
#include "vm/String-inl.h"
@ -3398,7 +3397,7 @@ IsAboutToBeFinalizedInternal(T** thingp)
}
template <typename S>
struct IsAboutToBeFinalizedFunctor : public IdentityDefaultAdaptor<S> {
struct IsAboutToBeFinalizedInternalFunctor : public IdentityDefaultAdaptor<S> {
template <typename T> S operator()(T* t, bool* rv) {
*rv = IsAboutToBeFinalizedInternal(&t);
return js::gc::RewrapTaggedPointer<S, T>::wrap(t);
@ -3410,7 +3409,7 @@ static bool
IsAboutToBeFinalizedInternal(T* thingp)
{
bool rv = false;
*thingp = DispatchTyped(IsAboutToBeFinalizedFunctor<T>(), *thingp, &rv);
*thingp = DispatchTyped(IsAboutToBeFinalizedInternalFunctor<T>(), *thingp, &rv);
return rv;
}

View File

@ -14,24 +14,24 @@
#if defined(XP_WIN)
#include "mozilla/Sprintf.h"
#include "jswin.h"
#include <psapi.h>
# include "mozilla/Sprintf.h"
# include "util/Windows.h"
# include <psapi.h>
#elif defined(SOLARIS)
#include <sys/mman.h>
#include <unistd.h>
# include <sys/mman.h>
# include <unistd.h>
#elif defined(XP_UNIX)
#include <algorithm>
#include <errno.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
# include <algorithm>
# include <errno.h>
# include <sys/mman.h>
# include <sys/resource.h>
# include <sys/stat.h>
# include <sys/types.h>
# include <unistd.h>
#endif

View File

@ -16,8 +16,8 @@
#include "gc/FreeOp.h"
#include "gc/GCInternals.h"
#include "gc/Iteration.h"
#include "gc/Memory.h"
#include "gc/PublicIterators.h"
#include "jit/JitFrames.h"
#include "vm/ArrayObject.h"
#include "vm/Debugger.h"

View File

@ -8,12 +8,12 @@
* GC-internal iterators for various data structures.
*/
#ifndef gc_GCIteration_h
#define gc_GCIteration_h
#ifndef gc_PrivateIterators_inl_h
#define gc_PrivateIterators_inl_h
#include "gc/Iteration.h"
#include "gc/PublicIterators.h"
#include "jsgcinlines.h"
#include "gc/GC-inl.h"
namespace js {
namespace gc {
@ -122,4 +122,4 @@ typedef CompartmentsIterT<SweepGroupZonesIter> SweepGroupCompartmentsIter;
} // namespace gc
} // namespace js
#endif // gc_GCIteration_h
#endif // gc_PrivateIterators_inl_h

View File

@ -11,7 +11,7 @@
#include "vm/JSCompartment.h"
#include "vm/Runtime.h"
#include "gc/GCIteration-inl.h"
#include "gc/PrivateIterators-inl.h"
#include "vm/JSContext-inl.h"
using namespace js;

View File

@ -8,8 +8,8 @@
* Iterators for various data structures.
*/
#ifndef gc_Iteration_h
#define gc_Iteration_h
#ifndef gc_PublicIterators_h
#define gc_PublicIterators_h
#include "gc/Zone.h"
@ -224,4 +224,4 @@ typedef CompartmentsIterT<ZonesIter> CompartmentsIter;
} // namespace js
#endif // gc_Iteration_h
#endif // gc_PublicIterators_h

View File

@ -23,8 +23,8 @@
#include "vm/JSContext.h"
#include "vm/JSONParser.h"
#include "gc/GCIteration-inl.h"
#include "gc/Nursery-inl.h"
#include "gc/PrivateIterators-inl.h"
#include "vm/JSObject-inl.h"
using namespace js;

View File

@ -17,10 +17,10 @@
#include <stdarg.h>
#include <stdio.h>
#include "jsgc.h"
#include "jsprf.h"
#include "jsutil.h"
#include "gc/GC.h"
#include "gc/Memory.h"
#include "vm/Debugger.h"
#include "vm/HelperThreads.h"

View File

@ -12,7 +12,7 @@
#include "vm/ArgumentsObject.h"
#include "vm/Runtime.h"
#include "jsgcinlines.h"
#include "gc/GC-inl.h"
using namespace js;
using namespace js::gc;

View File

@ -13,16 +13,15 @@
#include "NamespaceImports.h"
#include "gc/GCInternals.h"
#include "gc/Iteration.h"
#include "gc/Marking.h"
#include "gc/PublicIterators.h"
#include "gc/Zone.h"
#include "vm/JSFunction.h"
#include "vm/JSScript.h"
#include "vm/Shape.h"
#include "vm/Symbol.h"
#include "jsgcinlines.h"
#include "gc/GC-inl.h"
#include "vm/JSCompartment-inl.h"
#include "vm/ObjectGroup-inl.h"

View File

@ -15,13 +15,12 @@
#include "jsprf.h"
#include "gc/GCInternals.h"
#include "gc/Iteration.h"
#include "gc/PublicIterators.h"
#include "gc/Zone.h"
#include "js/HashTable.h"
#include "vm/JSContext.h"
#include "jsgcinlines.h"
#include "gc/GC-inl.h"
#include "gc/Marking-inl.h"
#include "vm/JSContext-inl.h"

View File

@ -4,7 +4,7 @@
* 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/. */
#include "jsweakmap.h"
#include "gc/WeakMap.h"
#include <string.h>
@ -12,7 +12,7 @@
#include "jsfriendapi.h"
#include "jswrapper.h"
#include "gc/Iteration.h"
#include "gc/PublicIterators.h"
#include "vm/GlobalObject.h"
#include "vm/JSContext.h"
#include "vm/JSObject.h"

View File

@ -4,8 +4,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef jsweakmap_h
#define jsweakmap_h
#ifndef gc_WeakMap_h
#define gc_WeakMap_h
#include "mozilla/LinkedList.h"
#include "mozilla/Move.h"
@ -414,4 +414,4 @@ struct DeletePolicy<js::ObjectValueMap> : public js::GCManagedDeletePolicy<js::O
} /* namespace JS */
#endif /* jsweakmap_h */
#endif /* gc_WeakMap_h */

View File

@ -6,7 +6,7 @@
#include "js/WeakMapPtr.h"
#include "jsweakmap.h"
#include "gc/WeakMap.h"
//
// Machinery for the externally-linkable JS::WeakMapPtr, which wraps js::WeakMap

View File

@ -6,16 +6,15 @@
#include "gc/Zone.h"
#include "gc/Iteration.h"
#include "gc/Policy.h"
#include "gc/PublicIterators.h"
#include "jit/BaselineJIT.h"
#include "jit/Ion.h"
#include "jit/JitCompartment.h"
#include "vm/Debugger.h"
#include "vm/Runtime.h"
#include "jsgcinlines.h"
#include "gc/GC-inl.h"
#include "gc/Marking-inl.h"
#include "vm/JSCompartment-inl.h"

View File

@ -178,7 +178,7 @@ struct Zone : public JS::shadow::Zone,
size_t* atomsMarkBitmaps);
// Iterate over all cells in the zone. See the definition of ZoneCellIter
// in jsgcinlines.h for the possible arguments and documentation.
// in gc/GC-inl.h for the possible arguments and documentation.
template <typename T, typename... Args>
js::gc::ZoneCellIter<T> cellIter(Args&&... args) {
return js::gc::ZoneCellIter<T>(const_cast<Zone*>(this), mozilla::Forward<Args>(args)...);

View File

@ -6,7 +6,7 @@
#include "gc/ZoneGroup.h"
#include "gc/Iteration.h"
#include "gc/PublicIterators.h"
#include "jit/IonBuilder.h"
#include "jit/JitCompartment.h"
#include "vm/JSContext.h"

View File

@ -33,9 +33,8 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/Move.h"
#include "jsgc.h"
#include "frontend/TokenStream.h"
#include "gc/GC.h"
#include "irregexp/RegExpCharacters.h"
#include "vm/ErrorReporting.h"
#include "vm/StringBuffer.h"

View File

@ -0,0 +1,29 @@
setJitCompilerOption('ion.forceinlineCaches', 1);
function warmup(fun, input_array, output_array) {
assertEq(output_array.length, input_array.length);
for (var index = 0; index < input_array.length; index++) {
input = input_array[index];
output = output_array[index];
for (var i = 0; i < 30; i++) {
var y = fun(input);
assertEq(y, output)
}
}
}
var fun1 = (x) => { return -x; }
var fun2 = (x) => { return -x; }
var fun3 = (x) => { return ~x; }
var fun4 = (x) => { return ~x; }
warmup(fun1, [1, 2], [-1, -2]);
warmup(fun2, [0], [-0]);
warmup(fun2, [3, 4], [-3, -4]);
warmup(fun1, [1.2, 1.4], [-1.2, -1.4]);
warmup(fun3, [-1, 0], [0, -1]);
warmup(fun4, [-1.0, 0.0, 1.2, 3], [0, -1, -2, -4]);

View File

@ -2105,6 +2105,7 @@ BaselineCacheIRCompiler::init(CacheKind kind)
case CacheKind::TypeOf:
case CacheKind::GetIterator:
case CacheKind::ToBool:
case CacheKind::UnaryArith:
MOZ_ASSERT(numInputs == 1);
allocator.initInputLocation(0, R0);
break;

View File

@ -1930,7 +1930,7 @@ BaselineCompiler::emitUnaryArith()
frame.popRegsAndSync(1);
// Call IC
ICUnaryArith_Fallback::Compiler stubCompiler(cx, ICStubCompiler::Engine::Baseline);
ICUnaryArith_Fallback::Compiler stubCompiler(cx);
if (!emitOpIC(stubCompiler.getStub(&stubSpace_)))
return false;

View File

@ -44,8 +44,8 @@ class BaselineFrame
// Frame has execution observed by a Debugger.
//
// See comment above 'isDebuggee' in jscompartment.h for explanation of
// invariants of debuggee compartments, scripts, and frames.
// See comment above 'isDebuggee' in vm/JSCompartment.h for explanation
// of invariants of debuggee compartments, scripts, and frames.
DEBUGGEE = 1 << 6,
// (1 << 7 and 1 << 8 are unused)

View File

@ -4533,5 +4533,89 @@ ICRest_Fallback::Compiler::generateStubCode(MacroAssembler& masm)
return tailCallVM(DoRestFallbackInfo, masm);
}
//
// UnaryArith_Fallback
//
static bool
DoUnaryArithFallback(JSContext* cx, BaselineFrame* frame, ICUnaryArith_Fallback* stub,
HandleValue val, MutableHandleValue res)
{
// This fallback stub may trigger debug mode toggling.
DebugModeOSRVolatileStub<ICUnaryArith_Fallback*> debug_stub(ICStubEngine::Baseline, frame, stub);
RootedScript script(cx, frame->script());
jsbytecode* pc = stub->icEntry()->pc(script);
JSOp op = JSOp(*pc);
FallbackICSpew(cx, stub, "UnaryArith(%s)", CodeName[op]);
switch (op) {
case JSOP_BITNOT: {
int32_t result;
if (!BitNot(cx, val, &result))
return false;
res.setInt32(result);
break;
}
case JSOP_NEG:
if (!NegOperation(cx, val, res))
return false;
break;
default:
MOZ_CRASH("Unexpected op");
}
// Check if debug mode toggling made the stub invalid.
if (debug_stub.invalid())
return true;
if (res.isDouble())
stub->setSawDoubleResult();
if (stub->state().maybeTransition())
stub->discardStubs(cx);
if (stub->state().canAttachStub()) {
UnaryArithIRGenerator gen(cx, script, pc, stub->state().mode(),
op, val, res);
if (gen.tryAttachStub()) {
bool attached = false;
ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(),
BaselineCacheIRStubKind::Regular,
ICStubEngine::Baseline, script, stub, &attached);
if (newStub) {
JitSpew(JitSpew_BaselineIC, " Attached (shared) CacheIR stub for %s", CodeName[op]);
}
}
}
return true;
}
typedef bool (*DoUnaryArithFallbackFn)(JSContext*, BaselineFrame*, ICUnaryArith_Fallback*,
HandleValue, MutableHandleValue);
static const VMFunction DoUnaryArithFallbackInfo =
FunctionInfo<DoUnaryArithFallbackFn>(DoUnaryArithFallback, "DoUnaryArithFallback", TailCall,
PopValues(1));
bool
ICUnaryArith_Fallback::Compiler::generateStubCode(MacroAssembler& masm)
{
MOZ_ASSERT(R0 == JSReturnOperand);
// Restore the tail call register.
EmitRestoreTailCallReg(masm);
// Ensure stack is fully synced for the expression decompiler.
masm.pushValue(R0);
// Push arguments.
masm.pushValue(R0);
masm.push(ICStubReg);
pushStubPayload(masm, R0.scratchReg());
return tailCallVM(DoUnaryArithFallbackInfo, masm);
}
} // namespace jit
} // namespace js

View File

@ -9,8 +9,6 @@
#include "mozilla/Assertions.h"
#include "jsopcode.h"
#include "builtin/TypedObject.h"
#include "gc/Barrier.h"
#include "jit/BaselineICList.h"
@ -19,6 +17,7 @@
#include "jit/SharedICRegisters.h"
#include "js/GCVector.h"
#include "vm/ArrayObject.h"
#include "vm/BytecodeUtil.h"
#include "vm/JSCompartment.h"
#include "vm/JSContext.h"
#include "vm/UnboxedObject.h"
@ -1460,6 +1459,44 @@ class ICRetSub_Resume : public ICStub
};
};
// UnaryArith
// JSOP_BITNOT
// JSOP_NEG
class ICUnaryArith_Fallback : public ICFallbackStub
{
friend class ICStubSpace;
explicit ICUnaryArith_Fallback(JitCode* stubCode)
: ICFallbackStub(UnaryArith_Fallback, stubCode)
{
extra_ = 0;
}
public:
bool sawDoubleResult() {
return extra_;
}
void setSawDoubleResult() {
extra_ = 1;
}
// Compiler for this stub kind.
class Compiler : public ICStubCompiler {
protected:
MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override;
public:
explicit Compiler(JSContext* cx)
: ICStubCompiler(cx, ICStub::UnaryArith_Fallback, Engine::Baseline)
{}
ICStub* getStub(ICStubSpace* space) override {
return newStub<ICUnaryArith_Fallback>(space, getStubCode());
}
};
};
inline bool
IsCacheableDOMProxy(JSObject* obj)
{

View File

@ -34,6 +34,8 @@ namespace jit {
\
_(ToNumber_Fallback) \
\
_(UnaryArith_Fallback) \
\
_(Call_Fallback) \
_(Call_Scripted) \
_(Call_AnyScripted) \

View File

@ -334,11 +334,9 @@ BaselineInspector::expectedResultType(jsbytecode* pc)
return MIRType::Double;
return MIRType::Int32;
case ICStub::BinaryArith_BooleanWithInt32:
case ICStub::UnaryArith_Int32:
case ICStub::BinaryArith_DoubleWithInt32:
return MIRType::Int32;
case ICStub::BinaryArith_Double:
case ICStub::UnaryArith_Double:
return MIRType::Double;
case ICStub::BinaryArith_StringConcat:
case ICStub::BinaryArith_StringObjectConcat:

View File

@ -22,11 +22,10 @@
#include "vm/TraceLogging.h"
#include "wasm/WasmInstance.h"
#include "jsopcodeinlines.h"
#include "gc/GCIteration-inl.h"
#include "gc/PrivateIterators-inl.h"
#include "jit/JitFrames-inl.h"
#include "jit/MacroAssembler-inl.h"
#include "vm/BytecodeUtil-inl.h"
#include "vm/JSObject-inl.h"
#include "vm/JSScript-inl.h"
#include "vm/Stack-inl.h"

View File

@ -6,12 +6,10 @@
#include "jit/BytecodeAnalysis.h"
#include "jsopcode.h"
#include "jit/JitSpewer.h"
#include "vm/BytecodeUtil.h"
#include "jsopcodeinlines.h"
#include "vm/BytecodeUtil-inl.h"
#include "vm/JSScript-inl.h"
using namespace js;

View File

@ -4683,4 +4683,86 @@ GetIntrinsicIRGenerator::tryAttachStub()
writer.returnFromIC();
trackAttached("GetIntrinsic");
return true;
}
UnaryArithIRGenerator::UnaryArithIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, ICState::Mode mode,
JSOp op, HandleValue val, HandleValue res)
: IRGenerator(cx, script, pc, CacheKind::UnaryArith, mode),
op_(op),
val_(val),
res_(res)
{ }
void
UnaryArithIRGenerator::trackAttached(const char* name)
{
#ifdef JS_CACHEIR_SPEW
if (const CacheIRSpewer::Guard& sp = CacheIRSpewer::Guard(*this, name)) {
sp.valueProperty("val", val_);
}
#endif
}
bool
UnaryArithIRGenerator::tryAttachStub()
{
if (tryAttachInt32())
return true;
if (tryAttachNumber())
return true;
trackAttached(IRGenerator::NotAttached);
return false;
}
bool
UnaryArithIRGenerator::tryAttachInt32()
{
if (!val_.isInt32() || !res_.isInt32())
return false;
ValOperandId valId(writer.setInputOperandId(0));
Int32OperandId intId = writer.guardIsInt32(valId);
switch (op_) {
case JSOP_BITNOT:
writer.int32NotResult(intId);
trackAttached("UnaryArith.Int32Not");
break;
case JSOP_NEG:
writer.int32NegationResult(intId);
trackAttached("UnaryArith.Int32Neg");
break;
default:
MOZ_CRASH("Unexected OP");
}
writer.returnFromIC();
return true;
}
bool
UnaryArithIRGenerator::tryAttachNumber()
{
if (!val_.isNumber() || !res_.isNumber() || !cx_->runtime()->jitSupportsFloatingPoint)
return false;
ValOperandId valId(writer.setInputOperandId(0));
writer.guardType(valId, JSVAL_TYPE_DOUBLE);
Int32OperandId truncatedId;
switch (op_) {
case JSOP_BITNOT:
truncatedId = writer.truncateDoubleToUInt32(valId);
writer.int32NotResult(truncatedId);
trackAttached("UnaryArith.DoubleNot");
break;
case JSOP_NEG:
writer.doubleNegationResult(valId);
trackAttached("UnaryArith.DoubleNeg");
break;
default:
MOZ_CRASH("Unexpected OP");
}
writer.returnFromIC();
return true;
}

View File

@ -153,7 +153,8 @@ class TypedOperandId : public OperandId
_(GetIterator) \
_(Compare) \
_(ToBool) \
_(Call)
_(Call) \
_(UnaryArith)
enum class CacheKind : uint8_t
{
@ -171,6 +172,7 @@ extern const char* CacheKindNames[];
_(GuardIsString) \
_(GuardIsSymbol) \
_(GuardIsNumber) \
_(GuardIsInt32) \
_(GuardIsInt32Index) \
_(GuardType) \
_(GuardShape) \
@ -207,6 +209,8 @@ extern const char* CacheKindNames[];
_(LoadEnclosingEnvironment) \
_(LoadWrapperTarget) \
\
_(TruncateDoubleToUInt32) \
\
_(MegamorphicLoadSlotResult) \
_(MegamorphicLoadSlotByValueResult) \
_(MegamorphicStoreSlot) \
@ -272,6 +276,9 @@ extern const char* CacheKindNames[];
_(LoadStringResult) \
_(LoadInstanceOfObjectResult) \
_(LoadTypeOfObjectResult) \
_(Int32NotResult) \
_(Int32NegationResult) \
_(DoubleNegationResult) \
_(LoadInt32TruthyResult) \
_(LoadDoubleTruthyResult) \
_(LoadStringTruthyResult) \
@ -523,6 +530,12 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
writeOpWithOperandId(CacheOp::GuardIsSymbol, val);
return SymbolOperandId(val.id());
}
Int32OperandId guardIsInt32(ValOperandId val) {
Int32OperandId res(nextOperandId_++);
writeOpWithOperandId(CacheOp::GuardIsInt32, val);
writeOperandId(res);
return res;
}
Int32OperandId guardIsInt32Index(ValOperandId val) {
Int32OperandId res(nextOperandId_++);
writeOpWithOperandId(CacheOp::GuardIsInt32Index, val);
@ -715,6 +728,13 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
return res;
}
Int32OperandId truncateDoubleToUInt32(ValOperandId val) {
Int32OperandId res(nextOperandId_++);
writeOpWithOperandId(CacheOp::TruncateDoubleToUInt32, val);
writeOperandId(res);
return res;
}
ValOperandId loadDOMExpandoValue(ObjOperandId obj) {
ValOperandId res(nextOperandId_++);
writeOpWithOperandId(CacheOp::LoadDOMExpandoValue, obj);
@ -899,6 +919,15 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
buffer_.writeByte(uint32_t(hasOwn));
}
void int32NotResult(Int32OperandId id) {
writeOpWithOperandId(CacheOp::Int32NotResult, id);
}
void int32NegationResult(Int32OperandId id) {
writeOpWithOperandId(CacheOp::Int32NegationResult, id);
}
void doubleNegationResult(ValOperandId val) {
writeOpWithOperandId(CacheOp::DoubleNegationResult, val);
}
void loadBooleanResult(bool val) {
writeOp(CacheOp::LoadBooleanResult);
buffer_.writeByte(uint32_t(val));
@ -1653,6 +1682,24 @@ class MOZ_RAII GetIntrinsicIRGenerator : public IRGenerator
bool tryAttachStub();
};
class MOZ_RAII UnaryArithIRGenerator : public IRGenerator
{
JSOp op_;
HandleValue val_;
HandleValue res_;
bool tryAttachInt32();
bool tryAttachNumber();
void trackAttached(const char* name);
public:
UnaryArithIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, ICState::Mode mode,
JSOp op, HandleValue val, HandleValue res);
bool tryAttachStub();
};
} // namespace jit
} // namespace js

View File

@ -18,6 +18,7 @@ using namespace js;
using namespace js::jit;
using mozilla::Maybe;
using mozilla::BitwiseCast;
ValueOperand
CacheRegisterAllocator::useValueRegister(MacroAssembler& masm, ValOperandId op)
@ -1311,6 +1312,29 @@ CacheIRCompiler::emitGuardIsSymbol()
return true;
}
bool
CacheIRCompiler::emitGuardIsInt32()
{
ValOperandId inputId = reader.valOperandId();
Register output = allocator.defineRegister(masm, reader.int32OperandId());
if (allocator.knownType(inputId) == JSVAL_TYPE_INT32) {
Register input = allocator.useRegister(masm, Int32OperandId(inputId.id()));
masm.move32(input, output);
return true;
}
ValueOperand input = allocator.useValueRegister(masm, inputId);
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
Label notInt32, done;
masm.branchTestInt32(Assembler::NotEqual, input, failure->label());
masm.unboxInt32(input, output);
return true;
}
bool
CacheIRCompiler::emitGuardIsInt32Index()
{
@ -1779,6 +1803,92 @@ CacheIRCompiler::emitLoadInt32ArrayLengthResult()
return true;
}
bool
CacheIRCompiler::emitInt32NegationResult()
{
AutoOutputRegister output(*this);
Register val = allocator.useRegister(masm, reader.int32OperandId());
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
// Guard against 0 and MIN_INT, both result in a double.
masm.branchTest32(Assembler::Zero, val, Imm32(0x7fffffff), failure->label());
masm.neg32(val);
masm.tagValue(JSVAL_TYPE_INT32, val, output.valueReg());
return true;
}
bool
CacheIRCompiler::emitInt32NotResult()
{
AutoOutputRegister output(*this);
Register val = allocator.useRegister(masm, reader.int32OperandId());
masm.not32(val);
masm.tagValue(JSVAL_TYPE_INT32, val, output.valueReg());
return true;
}
bool
CacheIRCompiler::emitDoubleNegationResult()
{
AutoOutputRegister output(*this);
ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
// If we're compiling a Baseline IC, FloatReg0 is always available.
Label failurePopReg, done;
if (mode_ != Mode::Baseline)
masm.push(FloatReg0);
masm.ensureDouble(val, FloatReg0, (mode_ != Mode::Baseline) ? &failurePopReg : failure->label());
masm.negateDouble(FloatReg0);
masm.boxDouble(FloatReg0, output.valueReg(), FloatReg0);
if (mode_ != Mode::Baseline) {
masm.pop(FloatReg0);
masm.jump(&done);
masm.bind(&failurePopReg);
masm.pop(FloatReg0);
masm.jump(failure->label());
}
masm.bind(&done);
return true;
}
bool
CacheIRCompiler::emitTruncateDoubleToUInt32()
{
ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
Register res = allocator.defineRegister(masm, reader.int32OperandId());
Label doneTruncate, truncateABICall;
if (mode_ != Mode::Baseline)
masm.push(FloatReg0);
masm.unboxDouble(val, FloatReg0);
masm.branchTruncateDoubleMaybeModUint32(FloatReg0, res, &truncateABICall);
masm.jump(&doneTruncate);
masm.bind(&truncateABICall);
masm.setupUnalignedABICall(res);
masm.passABIArg(FloatReg0, MoveOp::DOUBLE);
masm.callWithABI(BitwiseCast<void*, int32_t(*)(double)>(JS::ToInt32),
MoveOp::GENERAL, CheckUnsafeCallWithABI::DontCheckOther);
masm.storeCallInt32Result(res);
masm.bind(&doneTruncate);
if (mode_ != Mode::Baseline)
masm.pop(FloatReg0);
return true;
}
bool
CacheIRCompiler::emitLoadArgumentsObjectLengthResult()
{

View File

@ -21,6 +21,7 @@ namespace jit {
_(GuardIsString) \
_(GuardIsSymbol) \
_(GuardIsNumber) \
_(GuardIsInt32) \
_(GuardIsInt32Index) \
_(GuardType) \
_(GuardClass) \
@ -44,6 +45,10 @@ namespace jit {
_(LoadUndefinedResult) \
_(LoadBooleanResult) \
_(LoadInt32ArrayLengthResult) \
_(Int32NegationResult) \
_(Int32NotResult) \
_(DoubleNegationResult) \
_(TruncateDoubleToUInt32) \
_(LoadArgumentsObjectLengthResult) \
_(LoadFunctionLengthResult) \
_(LoadStringLengthResult) \

View File

@ -15,6 +15,8 @@
#include "mozilla/MathAlgorithms.h"
#include "mozilla/ScopeExit.h"
#include <type_traits>
#include "jslibmath.h"
#include "jsmath.h"
#include "jsnum.h"
@ -173,12 +175,16 @@ typedef bool (*IonInICFn)(JSContext*, HandleScript, IonInIC*, HandleValue, Handl
static const VMFunction IonInICInfo =
FunctionInfo<IonInICFn>(IonInIC::update, "IonInIC::update");
typedef bool (*IonInstanceOfICFn)(JSContext*, HandleScript, IonInstanceOfIC*,
HandleValue lhs, HandleObject rhs, bool* res);
static const VMFunction IonInstanceOfInfo =
FunctionInfo<IonInstanceOfICFn>(IonInstanceOfIC::update, "IonInstanceOfIC::update");
typedef bool (*IonUnaryArithICFn)(JSContext* cx, HandleScript outerScript, IonUnaryArithIC* stub,
HandleValue val, MutableHandleValue res);
static const VMFunction IonUnaryArithICInfo =
FunctionInfo<IonUnaryArithICFn>(IonUnaryArithIC::update, "IonUnaryArithIC::update");
void
CodeGenerator::visitOutOfLineICFallback(OutOfLineICFallback* ool)
{
@ -355,6 +361,22 @@ CodeGenerator::visitOutOfLineICFallback(OutOfLineICFallback* ool)
masm.jump(ool->rejoin());
return;
}
case CacheKind::UnaryArith: {
IonUnaryArithIC* unaryArithIC = ic->asUnaryArithIC();
saveLive(lir);
pushArg(unaryArithIC->input());
icInfo_[cacheInfoIndex].icOffsetForPush = pushArgWithPatch(ImmWord(-1));
pushArg(ImmGCPtr(gen->info().script()));
callVM(IonUnaryArithICInfo, lir);
StoreValueTo(unaryArithIC->output()).generate(this);
restoreLiveIgnore(lir, StoreValueTo(unaryArithIC->output()).clobbered());
masm.jump(ool->rejoin());
return;
}
case CacheKind::Call:
case CacheKind::Compare:
case CacheKind::TypeOf:
@ -2735,22 +2757,14 @@ CodeGenerator::visitBinarySharedStub(LBinarySharedStub* lir)
}
void
CodeGenerator::visitUnarySharedStub(LUnarySharedStub* lir)
CodeGenerator::visitUnaryCache(LUnaryCache* lir)
{
JSOp jsop = JSOp(*lir->mir()->resumePoint()->pc());
switch (jsop) {
case JSOP_BITNOT:
case JSOP_NEG:
emitSharedStub(ICStub::Kind::UnaryArith_Fallback, lir);
break;
case JSOP_CALLPROP:
case JSOP_GETPROP:
case JSOP_LENGTH:
emitSharedStub(ICStub::Kind::GetProp_Fallback, lir);
break;
default:
MOZ_CRASH("Unsupported jsop in shared stubs.");
}
LiveRegisterSet liveRegs = lir->safepoint()->liveRegs();
TypedOrValueRegister input = TypedOrValueRegister(ToValue(lir, LUnaryCache::Input));
ValueOperand output = GetValueOutput(lir);
IonUnaryArithIC ic(liveRegs, input, output);
addIC(lir, allocateIC(ic));
}
void
@ -5346,7 +5360,7 @@ struct ScriptCountBlockState
{
// Prefix stream of assembly instructions with their LIR instruction
// name and any associated high level info.
if (const char* extra = ins->extraName())
if (const char* extra = ins->getExtraName())
printer.printf("[%s:%s]\n", ins->opName(), extra);
else
printer.printf("[%s]\n", ins->opName());
@ -5681,7 +5695,7 @@ CodeGenerator::generateBody()
#ifdef JS_JITSPEW
JitSpewStart(JitSpew_Codegen, "instruction %s", iter->opName());
if (const char* extra = iter->extraName())
if (const char* extra = iter->getExtraName())
JitSpewCont(JitSpew_Codegen, ":%s", extra);
JitSpewFin(JitSpew_Codegen);
#endif
@ -5713,12 +5727,20 @@ CodeGenerator::generateBody()
}
}
#ifdef DEBUG
setElement(*iter); // needed to encode correct snapshot location.
#ifdef DEBUG
emitDebugForceBailing(*iter);
#endif
iter->accept(this);
switch (iter->op()) {
#define LIROP(op) case LNode::LOp_##op: visit##op(iter->to##op()); break;
LIR_OPCODE_LIST(LIROP)
#undef LIROP
case LNode::LOp_Invalid:
default:
MOZ_CRASH("Invalid LIR op");
}
// Track the end native offset of optimizations.
if (iter->mirRaw() && iter->mirRaw()->trackedOptimizations())
@ -9935,11 +9957,6 @@ CodeGenerator::linkSharedStubs(JSContext* cx)
stub = stubCompiler.getStub(&stubSpace_);
break;
}
case ICStub::Kind::UnaryArith_Fallback: {
ICUnaryArith_Fallback::Compiler stubCompiler(cx, ICStubCompiler::Engine::IonSharedIC);
stub = stubCompiler.getStub(&stubSpace_);
break;
}
case ICStub::Kind::Compare_Fallback: {
ICCompare_Fallback::Compiler stubCompiler(cx, ICStubCompiler::Engine::IonSharedIC);
stub = stubCompiler.getStub(&stubSpace_);
@ -13234,5 +13251,8 @@ CodeGenerator::visitGetPrototypeOf(LGetPrototypeOf* lir)
masm.bind(ool->rejoin());
}
static_assert(!std::is_polymorphic<CodeGenerator>::value,
"CodeGenerator should not have any virtual methods");
} // namespace jit
} // namespace js

View File

@ -79,89 +79,89 @@ class CodeGenerator final : public CodeGeneratorSpecific
MOZ_MUST_USE bool link(JSContext* cx, CompilerConstraintList* constraints);
MOZ_MUST_USE bool linkSharedStubs(JSContext* cx);
void visitOsiPoint(LOsiPoint* lir) override;
void visitGoto(LGoto* lir) override;
void visitTableSwitch(LTableSwitch* ins) override;
void visitTableSwitchV(LTableSwitchV* ins) override;
void visitCloneLiteral(LCloneLiteral* lir) override;
void visitParameter(LParameter* lir) override;
void visitCallee(LCallee* lir) override;
void visitIsConstructing(LIsConstructing* lir) override;
void visitStart(LStart* lir) override;
void visitReturn(LReturn* ret) override;
void visitDefVar(LDefVar* lir) override;
void visitDefLexical(LDefLexical* lir) override;
void visitDefFun(LDefFun* lir) override;
void visitOsrEntry(LOsrEntry* lir) override;
void visitOsrEnvironmentChain(LOsrEnvironmentChain* lir) override;
void visitOsrValue(LOsrValue* lir) override;
void visitOsrReturnValue(LOsrReturnValue* lir) override;
void visitOsrArgumentsObject(LOsrArgumentsObject* lir) override;
void visitStackArgT(LStackArgT* lir) override;
void visitStackArgV(LStackArgV* lir) override;
void visitMoveGroup(LMoveGroup* group) override;
void visitValueToInt32(LValueToInt32* lir) override;
void visitValueToDouble(LValueToDouble* lir) override;
void visitValueToFloat32(LValueToFloat32* lir) override;
void visitFloat32ToDouble(LFloat32ToDouble* lir) override;
void visitDoubleToFloat32(LDoubleToFloat32* lir) override;
void visitInt32ToFloat32(LInt32ToFloat32* lir) override;
void visitInt32ToDouble(LInt32ToDouble* lir) override;
void visitOsiPoint(LOsiPoint* lir);
void visitGoto(LGoto* lir);
void visitTableSwitch(LTableSwitch* ins);
void visitTableSwitchV(LTableSwitchV* ins);
void visitCloneLiteral(LCloneLiteral* lir);
void visitParameter(LParameter* lir);
void visitCallee(LCallee* lir);
void visitIsConstructing(LIsConstructing* lir);
void visitStart(LStart* lir);
void visitReturn(LReturn* ret);
void visitDefVar(LDefVar* lir);
void visitDefLexical(LDefLexical* lir);
void visitDefFun(LDefFun* lir);
void visitOsrEntry(LOsrEntry* lir);
void visitOsrEnvironmentChain(LOsrEnvironmentChain* lir);
void visitOsrValue(LOsrValue* lir);
void visitOsrReturnValue(LOsrReturnValue* lir);
void visitOsrArgumentsObject(LOsrArgumentsObject* lir);
void visitStackArgT(LStackArgT* lir);
void visitStackArgV(LStackArgV* lir);
void visitMoveGroup(LMoveGroup* group);
void visitValueToInt32(LValueToInt32* lir);
void visitValueToDouble(LValueToDouble* lir);
void visitValueToFloat32(LValueToFloat32* lir);
void visitFloat32ToDouble(LFloat32ToDouble* lir);
void visitDoubleToFloat32(LDoubleToFloat32* lir);
void visitInt32ToFloat32(LInt32ToFloat32* lir);
void visitInt32ToDouble(LInt32ToDouble* lir);
void emitOOLTestObject(Register objreg, Label* ifTruthy, Label* ifFalsy, Register scratch);
void visitTestOAndBranch(LTestOAndBranch* lir) override;
void visitTestVAndBranch(LTestVAndBranch* lir) override;
void visitFunctionDispatch(LFunctionDispatch* lir) override;
void visitObjectGroupDispatch(LObjectGroupDispatch* lir) override;
void visitBooleanToString(LBooleanToString* lir) override;
void visitTestOAndBranch(LTestOAndBranch* lir);
void visitTestVAndBranch(LTestVAndBranch* lir);
void visitFunctionDispatch(LFunctionDispatch* lir);
void visitObjectGroupDispatch(LObjectGroupDispatch* lir);
void visitBooleanToString(LBooleanToString* lir);
void emitIntToString(Register input, Register output, Label* ool);
void visitIntToString(LIntToString* lir) override;
void visitDoubleToString(LDoubleToString* lir) override;
void visitValueToString(LValueToString* lir) override;
void visitValueToObject(LValueToObject* lir) override;
void visitValueToObjectOrNull(LValueToObjectOrNull* lir) override;
void visitInteger(LInteger* lir) override;
void visitInteger64(LInteger64* lir) override;
void visitRegExp(LRegExp* lir) override;
void visitRegExpMatcher(LRegExpMatcher* lir) override;
void visitIntToString(LIntToString* lir);
void visitDoubleToString(LDoubleToString* lir);
void visitValueToString(LValueToString* lir);
void visitValueToObject(LValueToObject* lir);
void visitValueToObjectOrNull(LValueToObjectOrNull* lir);
void visitInteger(LInteger* lir);
void visitInteger64(LInteger64* lir);
void visitRegExp(LRegExp* lir);
void visitRegExpMatcher(LRegExpMatcher* lir);
void visitOutOfLineRegExpMatcher(OutOfLineRegExpMatcher* ool);
void visitRegExpSearcher(LRegExpSearcher* lir) override;
void visitRegExpSearcher(LRegExpSearcher* lir);
void visitOutOfLineRegExpSearcher(OutOfLineRegExpSearcher* ool);
void visitRegExpTester(LRegExpTester* lir) override;
void visitRegExpTester(LRegExpTester* lir);
void visitOutOfLineRegExpTester(OutOfLineRegExpTester* ool);
void visitRegExpPrototypeOptimizable(LRegExpPrototypeOptimizable* lir) override;
void visitRegExpPrototypeOptimizable(LRegExpPrototypeOptimizable* lir);
void visitOutOfLineRegExpPrototypeOptimizable(OutOfLineRegExpPrototypeOptimizable* ool);
void visitRegExpInstanceOptimizable(LRegExpInstanceOptimizable* lir) override;
void visitRegExpInstanceOptimizable(LRegExpInstanceOptimizable* lir);
void visitOutOfLineRegExpInstanceOptimizable(OutOfLineRegExpInstanceOptimizable* ool);
void visitGetFirstDollarIndex(LGetFirstDollarIndex* lir) override;
void visitStringReplace(LStringReplace* lir) override;
void visitGetFirstDollarIndex(LGetFirstDollarIndex* lir);
void visitStringReplace(LStringReplace* lir);
void emitSharedStub(ICStub::Kind kind, LInstruction* lir);
void visitBinarySharedStub(LBinarySharedStub* lir) override;
void visitUnarySharedStub(LUnarySharedStub* lir) override;
void visitNullarySharedStub(LNullarySharedStub* lir) override;
void visitClassConstructor(LClassConstructor* lir) override;
void visitLambda(LLambda* lir) override;
void visitBinarySharedStub(LBinarySharedStub* lir);
void visitUnaryCache(LUnaryCache* lir);
void visitNullarySharedStub(LNullarySharedStub* lir);
void visitClassConstructor(LClassConstructor* lir);
void visitLambda(LLambda* lir);
void visitOutOfLineLambdaArrow(OutOfLineLambdaArrow* ool);
void visitLambdaArrow(LLambdaArrow* lir) override;
void visitLambdaForSingleton(LLambdaForSingleton* lir) override;
void visitSetFunName(LSetFunName* lir) override;
void visitPointer(LPointer* lir) override;
void visitKeepAliveObject(LKeepAliveObject* lir) override;
void visitSlots(LSlots* lir) override;
void visitLoadSlotT(LLoadSlotT* lir) override;
void visitLoadSlotV(LLoadSlotV* lir) override;
void visitStoreSlotT(LStoreSlotT* lir) override;
void visitStoreSlotV(LStoreSlotV* lir) override;
void visitElements(LElements* lir) override;
void visitConvertElementsToDoubles(LConvertElementsToDoubles* lir) override;
void visitMaybeToDoubleElement(LMaybeToDoubleElement* lir) override;
void visitMaybeCopyElementsForWrite(LMaybeCopyElementsForWrite* lir) override;
void visitGuardObjectIdentity(LGuardObjectIdentity* guard) override;
void visitGuardReceiverPolymorphic(LGuardReceiverPolymorphic* lir) override;
void visitGuardUnboxedExpando(LGuardUnboxedExpando* lir) override;
void visitLoadUnboxedExpando(LLoadUnboxedExpando* lir) override;
void visitTypeBarrierV(LTypeBarrierV* lir) override;
void visitTypeBarrierO(LTypeBarrierO* lir) override;
void visitMonitorTypes(LMonitorTypes* lir) override;
void visitLambdaArrow(LLambdaArrow* lir);
void visitLambdaForSingleton(LLambdaForSingleton* lir);
void visitSetFunName(LSetFunName* lir);
void visitPointer(LPointer* lir);
void visitKeepAliveObject(LKeepAliveObject* lir);
void visitSlots(LSlots* lir);
void visitLoadSlotT(LLoadSlotT* lir);
void visitLoadSlotV(LLoadSlotV* lir);
void visitStoreSlotT(LStoreSlotT* lir);
void visitStoreSlotV(LStoreSlotV* lir);
void visitElements(LElements* lir);
void visitConvertElementsToDoubles(LConvertElementsToDoubles* lir);
void visitMaybeToDoubleElement(LMaybeToDoubleElement* lir);
void visitMaybeCopyElementsForWrite(LMaybeCopyElementsForWrite* lir);
void visitGuardObjectIdentity(LGuardObjectIdentity* guard);
void visitGuardReceiverPolymorphic(LGuardReceiverPolymorphic* lir);
void visitGuardUnboxedExpando(LGuardUnboxedExpando* lir);
void visitLoadUnboxedExpando(LLoadUnboxedExpando* lir);
void visitTypeBarrierV(LTypeBarrierV* lir);
void visitTypeBarrierO(LTypeBarrierO* lir);
void visitMonitorTypes(LMonitorTypes* lir);
void emitPostWriteBarrier(const LAllocation* obj);
void emitPostWriteBarrier(Register objreg);
void emitPostWriteBarrierS(Address address, Register prev, Register next);
@ -169,24 +169,24 @@ class CodeGenerator final : public CodeGeneratorSpecific
void visitPostWriteBarrierCommon(LPostBarrierType* lir, OutOfLineCode* ool);
template <class LPostBarrierType>
void visitPostWriteBarrierCommonV(LPostBarrierType* lir, OutOfLineCode* ool);
void visitPostWriteBarrierO(LPostWriteBarrierO* lir) override;
void visitPostWriteElementBarrierO(LPostWriteElementBarrierO* lir) override;
void visitPostWriteBarrierV(LPostWriteBarrierV* lir) override;
void visitPostWriteElementBarrierV(LPostWriteElementBarrierV* lir) override;
void visitPostWriteBarrierS(LPostWriteBarrierS* lir) override;
void visitPostWriteElementBarrierS(LPostWriteElementBarrierS* lir) override;
void visitPostWriteBarrierO(LPostWriteBarrierO* lir);
void visitPostWriteElementBarrierO(LPostWriteElementBarrierO* lir);
void visitPostWriteBarrierV(LPostWriteBarrierV* lir);
void visitPostWriteElementBarrierV(LPostWriteElementBarrierV* lir);
void visitPostWriteBarrierS(LPostWriteBarrierS* lir);
void visitPostWriteElementBarrierS(LPostWriteElementBarrierS* lir);
void visitOutOfLineCallPostWriteBarrier(OutOfLineCallPostWriteBarrier* ool);
void visitOutOfLineCallPostWriteElementBarrier(OutOfLineCallPostWriteElementBarrier* ool);
void visitCallNative(LCallNative* call) override;
void visitCallNative(LCallNative* call);
void emitCallInvokeFunction(LInstruction* call, Register callereg,
bool isConstructing, bool ignoresReturnValue,
uint32_t argc, uint32_t unusedStack);
void visitCallGeneric(LCallGeneric* call) override;
void visitCallGeneric(LCallGeneric* call);
void emitCallInvokeFunctionShuffleNewTarget(LCallKnown *call,
Register calleeReg,
uint32_t numFormals,
uint32_t unusedStack);
void visitCallKnown(LCallKnown* call) override;
void visitCallKnown(LCallKnown* call);
template<typename T> void emitApplyGeneric(T* apply);
template<typename T> void emitCallInvokeFunction(T* apply, Register extraStackSize);
void emitAllocateSpaceForApply(Register argcreg, Register extraStackSpace, Label* end);
@ -194,243 +194,243 @@ class CodeGenerator final : public CodeGeneratorSpecific
size_t argvSrcOffset, size_t argvDstOffset);
void emitPopArguments(Register extraStackSize);
void emitPushArguments(LApplyArgsGeneric* apply, Register extraStackSpace);
void visitApplyArgsGeneric(LApplyArgsGeneric* apply) override;
void visitApplyArgsGeneric(LApplyArgsGeneric* apply);
void emitPushArguments(LApplyArrayGeneric* apply, Register extraStackSpace);
void visitApplyArrayGeneric(LApplyArrayGeneric* apply) override;
void visitBail(LBail* lir) override;
void visitUnreachable(LUnreachable* unreachable) override;
void visitEncodeSnapshot(LEncodeSnapshot* lir) override;
void visitGetDynamicName(LGetDynamicName* lir) override;
void visitCallDirectEval(LCallDirectEval* lir) override;
void visitDoubleToInt32(LDoubleToInt32* lir) override;
void visitFloat32ToInt32(LFloat32ToInt32* lir) override;
void visitApplyArrayGeneric(LApplyArrayGeneric* apply);
void visitBail(LBail* lir);
void visitUnreachable(LUnreachable* unreachable);
void visitEncodeSnapshot(LEncodeSnapshot* lir);
void visitGetDynamicName(LGetDynamicName* lir);
void visitCallDirectEval(LCallDirectEval* lir);
void visitDoubleToInt32(LDoubleToInt32* lir);
void visitFloat32ToInt32(LFloat32ToInt32* lir);
void visitNewArrayCallVM(LNewArray* lir);
void visitNewArray(LNewArray* lir) override;
void visitNewArray(LNewArray* lir);
void visitOutOfLineNewArray(OutOfLineNewArray* ool);
void visitNewArrayCopyOnWrite(LNewArrayCopyOnWrite* lir) override;
void visitNewArrayDynamicLength(LNewArrayDynamicLength* lir) override;
void visitNewIterator(LNewIterator* lir) override;
void visitNewTypedArray(LNewTypedArray* lir) override;
void visitNewTypedArrayDynamicLength(LNewTypedArrayDynamicLength* lir) override;
void visitNewArrayCopyOnWrite(LNewArrayCopyOnWrite* lir);
void visitNewArrayDynamicLength(LNewArrayDynamicLength* lir);
void visitNewIterator(LNewIterator* lir);
void visitNewTypedArray(LNewTypedArray* lir);
void visitNewTypedArrayDynamicLength(LNewTypedArrayDynamicLength* lir);
void visitNewObjectVMCall(LNewObject* lir);
void visitNewObject(LNewObject* lir) override;
void visitNewObject(LNewObject* lir);
void visitOutOfLineNewObject(OutOfLineNewObject* ool);
void visitNewTypedObject(LNewTypedObject* lir) override;
void visitSimdBox(LSimdBox* lir) override;
void visitSimdUnbox(LSimdUnbox* lir) override;
void visitNewNamedLambdaObject(LNewNamedLambdaObject* lir) override;
void visitNewCallObject(LNewCallObject* lir) override;
void visitNewSingletonCallObject(LNewSingletonCallObject* lir) override;
void visitNewStringObject(LNewStringObject* lir) override;
void visitNewDerivedTypedObject(LNewDerivedTypedObject* lir) override;
void visitInitElem(LInitElem* lir) override;
void visitInitElemGetterSetter(LInitElemGetterSetter* lir) override;
void visitMutateProto(LMutateProto* lir) override;
void visitInitPropGetterSetter(LInitPropGetterSetter* lir) override;
void visitCreateThis(LCreateThis* lir) override;
void visitCreateThisWithProto(LCreateThisWithProto* lir) override;
void visitCreateThisWithTemplate(LCreateThisWithTemplate* lir) override;
void visitCreateArgumentsObject(LCreateArgumentsObject* lir) override;
void visitGetArgumentsObjectArg(LGetArgumentsObjectArg* lir) override;
void visitSetArgumentsObjectArg(LSetArgumentsObjectArg* lir) override;
void visitReturnFromCtor(LReturnFromCtor* lir) override;
void visitComputeThis(LComputeThis* lir) override;
void visitImplicitThis(LImplicitThis* lir) override;
void visitArrayLength(LArrayLength* lir) override;
void visitSetArrayLength(LSetArrayLength* lir) override;
void visitGetNextEntryForIterator(LGetNextEntryForIterator* lir) override;
void visitTypedArrayLength(LTypedArrayLength* lir) override;
void visitTypedArrayElements(LTypedArrayElements* lir) override;
void visitSetDisjointTypedElements(LSetDisjointTypedElements* lir) override;
void visitTypedObjectElements(LTypedObjectElements* lir) override;
void visitSetTypedObjectOffset(LSetTypedObjectOffset* lir) override;
void visitTypedObjectDescr(LTypedObjectDescr* ins) override;
void visitStringLength(LStringLength* lir) override;
void visitSubstr(LSubstr* lir) override;
void visitInitializedLength(LInitializedLength* lir) override;
void visitSetInitializedLength(LSetInitializedLength* lir) override;
void visitNotO(LNotO* ins) override;
void visitNotV(LNotV* ins) override;
void visitBoundsCheck(LBoundsCheck* lir) override;
void visitBoundsCheckRange(LBoundsCheckRange* lir) override;
void visitBoundsCheckLower(LBoundsCheckLower* lir) override;
void visitSpectreMaskIndex(LSpectreMaskIndex* lir) override;
void visitLoadFixedSlotV(LLoadFixedSlotV* ins) override;
void visitLoadFixedSlotAndUnbox(LLoadFixedSlotAndUnbox* lir) override;
void visitLoadFixedSlotT(LLoadFixedSlotT* ins) override;
void visitStoreFixedSlotV(LStoreFixedSlotV* ins) override;
void visitStoreFixedSlotT(LStoreFixedSlotT* ins) override;
void visitNewTypedObject(LNewTypedObject* lir);
void visitSimdBox(LSimdBox* lir);
void visitSimdUnbox(LSimdUnbox* lir);
void visitNewNamedLambdaObject(LNewNamedLambdaObject* lir);
void visitNewCallObject(LNewCallObject* lir);
void visitNewSingletonCallObject(LNewSingletonCallObject* lir);
void visitNewStringObject(LNewStringObject* lir);
void visitNewDerivedTypedObject(LNewDerivedTypedObject* lir);
void visitInitElem(LInitElem* lir);
void visitInitElemGetterSetter(LInitElemGetterSetter* lir);
void visitMutateProto(LMutateProto* lir);
void visitInitPropGetterSetter(LInitPropGetterSetter* lir);
void visitCreateThis(LCreateThis* lir);
void visitCreateThisWithProto(LCreateThisWithProto* lir);
void visitCreateThisWithTemplate(LCreateThisWithTemplate* lir);
void visitCreateArgumentsObject(LCreateArgumentsObject* lir);
void visitGetArgumentsObjectArg(LGetArgumentsObjectArg* lir);
void visitSetArgumentsObjectArg(LSetArgumentsObjectArg* lir);
void visitReturnFromCtor(LReturnFromCtor* lir);
void visitComputeThis(LComputeThis* lir);
void visitImplicitThis(LImplicitThis* lir);
void visitArrayLength(LArrayLength* lir);
void visitSetArrayLength(LSetArrayLength* lir);
void visitGetNextEntryForIterator(LGetNextEntryForIterator* lir);
void visitTypedArrayLength(LTypedArrayLength* lir);
void visitTypedArrayElements(LTypedArrayElements* lir);
void visitSetDisjointTypedElements(LSetDisjointTypedElements* lir);
void visitTypedObjectElements(LTypedObjectElements* lir);
void visitSetTypedObjectOffset(LSetTypedObjectOffset* lir);
void visitTypedObjectDescr(LTypedObjectDescr* ins);
void visitStringLength(LStringLength* lir);
void visitSubstr(LSubstr* lir);
void visitInitializedLength(LInitializedLength* lir);
void visitSetInitializedLength(LSetInitializedLength* lir);
void visitNotO(LNotO* ins);
void visitNotV(LNotV* ins);
void visitBoundsCheck(LBoundsCheck* lir);
void visitBoundsCheckRange(LBoundsCheckRange* lir);
void visitBoundsCheckLower(LBoundsCheckLower* lir);
void visitSpectreMaskIndex(LSpectreMaskIndex* lir);
void visitLoadFixedSlotV(LLoadFixedSlotV* ins);
void visitLoadFixedSlotAndUnbox(LLoadFixedSlotAndUnbox* lir);
void visitLoadFixedSlotT(LLoadFixedSlotT* ins);
void visitStoreFixedSlotV(LStoreFixedSlotV* ins);
void visitStoreFixedSlotT(LStoreFixedSlotT* ins);
void emitGetPropertyPolymorphic(LInstruction* lir, Register obj,
Register scratch, const TypedOrValueRegister& output);
void visitGetPropertyPolymorphicV(LGetPropertyPolymorphicV* ins) override;
void visitGetPropertyPolymorphicT(LGetPropertyPolymorphicT* ins) override;
void visitGetPropertyPolymorphicV(LGetPropertyPolymorphicV* ins);
void visitGetPropertyPolymorphicT(LGetPropertyPolymorphicT* ins);
void emitSetPropertyPolymorphic(LInstruction* lir, Register obj,
Register scratch, const ConstantOrRegister& value);
void visitSetPropertyPolymorphicV(LSetPropertyPolymorphicV* ins) override;
void visitSetPropertyPolymorphicT(LSetPropertyPolymorphicT* ins) override;
void visitAbsI(LAbsI* lir) override;
void visitAtan2D(LAtan2D* lir) override;
void visitHypot(LHypot* lir) override;
void visitPowI(LPowI* lir) override;
void visitPowD(LPowD* lir) override;
void visitPowV(LPowV* lir) override;
void visitMathFunctionD(LMathFunctionD* ins) override;
void visitMathFunctionF(LMathFunctionF* ins) override;
void visitModD(LModD* ins) override;
void visitMinMaxI(LMinMaxI* lir) override;
void visitBinaryV(LBinaryV* lir) override;
void visitSetPropertyPolymorphicV(LSetPropertyPolymorphicV* ins);
void visitSetPropertyPolymorphicT(LSetPropertyPolymorphicT* ins);
void visitAbsI(LAbsI* lir);
void visitAtan2D(LAtan2D* lir);
void visitHypot(LHypot* lir);
void visitPowI(LPowI* lir);
void visitPowD(LPowD* lir);
void visitPowV(LPowV* lir);
void visitMathFunctionD(LMathFunctionD* ins);
void visitMathFunctionF(LMathFunctionF* ins);
void visitModD(LModD* ins);
void visitMinMaxI(LMinMaxI* lir);
void visitBinaryV(LBinaryV* lir);
void emitCompareS(LInstruction* lir, JSOp op, Register left, Register right, Register output);
void visitCompareS(LCompareS* lir) override;
void visitCompareStrictS(LCompareStrictS* lir) override;
void visitCompareVM(LCompareVM* lir) override;
void visitIsNullOrLikeUndefinedV(LIsNullOrLikeUndefinedV* lir) override;
void visitIsNullOrLikeUndefinedT(LIsNullOrLikeUndefinedT* lir) override;
void visitIsNullOrLikeUndefinedAndBranchV(LIsNullOrLikeUndefinedAndBranchV* lir) override;
void visitIsNullOrLikeUndefinedAndBranchT(LIsNullOrLikeUndefinedAndBranchT* lir) override;
void visitCompareS(LCompareS* lir);
void visitCompareStrictS(LCompareStrictS* lir);
void visitCompareVM(LCompareVM* lir);
void visitIsNullOrLikeUndefinedV(LIsNullOrLikeUndefinedV* lir);
void visitIsNullOrLikeUndefinedT(LIsNullOrLikeUndefinedT* lir);
void visitIsNullOrLikeUndefinedAndBranchV(LIsNullOrLikeUndefinedAndBranchV* lir);
void visitIsNullOrLikeUndefinedAndBranchT(LIsNullOrLikeUndefinedAndBranchT* lir);
void emitSameValue(FloatRegister left, FloatRegister right, FloatRegister temp,
Register output);
void visitSameValueD(LSameValueD* lir) override;
void visitSameValueV(LSameValueV* lir) override;
void visitSameValueVM(LSameValueVM* lir) override;
void visitSameValueD(LSameValueD* lir);
void visitSameValueV(LSameValueV* lir);
void visitSameValueVM(LSameValueVM* lir);
void emitConcat(LInstruction* lir, Register lhs, Register rhs, Register output);
void visitConcat(LConcat* lir) override;
void visitCharCodeAt(LCharCodeAt* lir) override;
void visitFromCharCode(LFromCharCode* lir) override;
void visitFromCodePoint(LFromCodePoint* lir) override;
void visitStringConvertCase(LStringConvertCase* lir) override;
void visitSinCos(LSinCos *lir) override;
void visitStringSplit(LStringSplit* lir) override;
void visitFunctionEnvironment(LFunctionEnvironment* lir) override;
void visitHomeObject(LHomeObject* lir) override;
void visitHomeObjectSuperBase(LHomeObjectSuperBase* lir) override;
void visitNewLexicalEnvironmentObject(LNewLexicalEnvironmentObject* lir) override;
void visitCopyLexicalEnvironmentObject(LCopyLexicalEnvironmentObject* lir) override;
void visitCallGetProperty(LCallGetProperty* lir) override;
void visitCallGetElement(LCallGetElement* lir) override;
void visitCallSetElement(LCallSetElement* lir) override;
void visitCallInitElementArray(LCallInitElementArray* lir) override;
void visitThrow(LThrow* lir) override;
void visitTypeOfV(LTypeOfV* lir) override;
void visitConcat(LConcat* lir);
void visitCharCodeAt(LCharCodeAt* lir);
void visitFromCharCode(LFromCharCode* lir);
void visitFromCodePoint(LFromCodePoint* lir);
void visitStringConvertCase(LStringConvertCase* lir);
void visitSinCos(LSinCos *lir);
void visitStringSplit(LStringSplit* lir);
void visitFunctionEnvironment(LFunctionEnvironment* lir);
void visitHomeObject(LHomeObject* lir);
void visitHomeObjectSuperBase(LHomeObjectSuperBase* lir);
void visitNewLexicalEnvironmentObject(LNewLexicalEnvironmentObject* lir);
void visitCopyLexicalEnvironmentObject(LCopyLexicalEnvironmentObject* lir);
void visitCallGetProperty(LCallGetProperty* lir);
void visitCallGetElement(LCallGetElement* lir);
void visitCallSetElement(LCallSetElement* lir);
void visitCallInitElementArray(LCallInitElementArray* lir);
void visitThrow(LThrow* lir);
void visitTypeOfV(LTypeOfV* lir);
void visitOutOfLineTypeOfV(OutOfLineTypeOfV* ool);
void visitToAsync(LToAsync* lir) override;
void visitToAsyncGen(LToAsyncGen* lir) override;
void visitToAsyncIter(LToAsyncIter* lir) override;
void visitToIdV(LToIdV* lir) override;
void visitToAsync(LToAsync* lir);
void visitToAsyncGen(LToAsyncGen* lir);
void visitToAsyncIter(LToAsyncIter* lir);
void visitToIdV(LToIdV* lir);
template<typename T> void emitLoadElementT(LLoadElementT* lir, const T& source);
void visitLoadElementT(LLoadElementT* lir) override;
void visitLoadElementV(LLoadElementV* load) override;
void visitLoadElementHole(LLoadElementHole* lir) override;
void visitLoadUnboxedPointerV(LLoadUnboxedPointerV* lir) override;
void visitLoadUnboxedPointerT(LLoadUnboxedPointerT* lir) override;
void visitUnboxObjectOrNull(LUnboxObjectOrNull* lir) override;
void visitLoadElementT(LLoadElementT* lir);
void visitLoadElementV(LLoadElementV* load);
void visitLoadElementHole(LLoadElementHole* lir);
void visitLoadUnboxedPointerV(LLoadUnboxedPointerV* lir);
void visitLoadUnboxedPointerT(LLoadUnboxedPointerT* lir);
void visitUnboxObjectOrNull(LUnboxObjectOrNull* lir);
template <SwitchTableType tableType>
void visitOutOfLineSwitch(OutOfLineSwitch<tableType>* ool);
void visitLoadElementFromStateV(LLoadElementFromStateV* lir) override;
void visitStoreElementT(LStoreElementT* lir) override;
void visitStoreElementV(LStoreElementV* lir) override;
void visitLoadElementFromStateV(LLoadElementFromStateV* lir);
void visitStoreElementT(LStoreElementT* lir);
void visitStoreElementV(LStoreElementV* lir);
template <typename T> void emitStoreElementHoleT(T* lir);
template <typename T> void emitStoreElementHoleV(T* lir);
void visitStoreElementHoleT(LStoreElementHoleT* lir) override;
void visitStoreElementHoleV(LStoreElementHoleV* lir) override;
void visitFallibleStoreElementV(LFallibleStoreElementV* lir) override;
void visitFallibleStoreElementT(LFallibleStoreElementT* lir) override;
void visitStoreUnboxedPointer(LStoreUnboxedPointer* lir) override;
void visitConvertUnboxedObjectToNative(LConvertUnboxedObjectToNative* lir) override;
void visitStoreElementHoleT(LStoreElementHoleT* lir);
void visitStoreElementHoleV(LStoreElementHoleV* lir);
void visitFallibleStoreElementV(LFallibleStoreElementV* lir);
void visitFallibleStoreElementT(LFallibleStoreElementT* lir);
void visitStoreUnboxedPointer(LStoreUnboxedPointer* lir);
void visitConvertUnboxedObjectToNative(LConvertUnboxedObjectToNative* lir);
void emitArrayPopShift(LInstruction* lir, const MArrayPopShift* mir, Register obj,
Register elementsTemp, Register lengthTemp, TypedOrValueRegister out);
void visitArrayPopShiftV(LArrayPopShiftV* lir) override;
void visitArrayPopShiftT(LArrayPopShiftT* lir) override;
void visitArrayPopShiftV(LArrayPopShiftV* lir);
void visitArrayPopShiftT(LArrayPopShiftT* lir);
void emitArrayPush(LInstruction* lir, const MArrayPush* mir, Register obj,
const ConstantOrRegister& value, Register elementsTemp, Register length);
void visitArrayPushV(LArrayPushV* lir) override;
void visitArrayPushT(LArrayPushT* lir) override;
void visitArraySlice(LArraySlice* lir) override;
void visitArrayJoin(LArrayJoin* lir) override;
void visitLoadUnboxedScalar(LLoadUnboxedScalar* lir) override;
void visitLoadTypedArrayElementHole(LLoadTypedArrayElementHole* lir) override;
void visitStoreUnboxedScalar(LStoreUnboxedScalar* lir) override;
void visitStoreTypedArrayElementHole(LStoreTypedArrayElementHole* lir) override;
void visitAtomicIsLockFree(LAtomicIsLockFree* lir) override;
void visitGuardSharedTypedArray(LGuardSharedTypedArray* lir) override;
void visitClampIToUint8(LClampIToUint8* lir) override;
void visitClampDToUint8(LClampDToUint8* lir) override;
void visitClampVToUint8(LClampVToUint8* lir) override;
void visitGetIteratorCache(LGetIteratorCache* lir) override;
void visitIteratorMore(LIteratorMore* lir) override;
void visitIsNoIterAndBranch(LIsNoIterAndBranch* lir) override;
void visitIteratorEnd(LIteratorEnd* lir) override;
void visitArgumentsLength(LArgumentsLength* lir) override;
void visitGetFrameArgument(LGetFrameArgument* lir) override;
void visitSetFrameArgumentT(LSetFrameArgumentT* lir) override;
void visitSetFrameArgumentC(LSetFrameArgumentC* lir) override;
void visitSetFrameArgumentV(LSetFrameArgumentV* lir) override;
void visitRunOncePrologue(LRunOncePrologue* lir) override;
void visitArrayPushV(LArrayPushV* lir);
void visitArrayPushT(LArrayPushT* lir);
void visitArraySlice(LArraySlice* lir);
void visitArrayJoin(LArrayJoin* lir);
void visitLoadUnboxedScalar(LLoadUnboxedScalar* lir);
void visitLoadTypedArrayElementHole(LLoadTypedArrayElementHole* lir);
void visitStoreUnboxedScalar(LStoreUnboxedScalar* lir);
void visitStoreTypedArrayElementHole(LStoreTypedArrayElementHole* lir);
void visitAtomicIsLockFree(LAtomicIsLockFree* lir);
void visitGuardSharedTypedArray(LGuardSharedTypedArray* lir);
void visitClampIToUint8(LClampIToUint8* lir);
void visitClampDToUint8(LClampDToUint8* lir);
void visitClampVToUint8(LClampVToUint8* lir);
void visitGetIteratorCache(LGetIteratorCache* lir);
void visitIteratorMore(LIteratorMore* lir);
void visitIsNoIterAndBranch(LIsNoIterAndBranch* lir);
void visitIteratorEnd(LIteratorEnd* lir);
void visitArgumentsLength(LArgumentsLength* lir);
void visitGetFrameArgument(LGetFrameArgument* lir);
void visitSetFrameArgumentT(LSetFrameArgumentT* lir);
void visitSetFrameArgumentC(LSetFrameArgumentC* lir);
void visitSetFrameArgumentV(LSetFrameArgumentV* lir);
void visitRunOncePrologue(LRunOncePrologue* lir);
void emitRest(LInstruction* lir, Register array, Register numActuals,
Register temp0, Register temp1, unsigned numFormals,
JSObject* templateObject, bool saveAndRestore, Register resultreg);
void visitRest(LRest* lir) override;
void visitCallSetProperty(LCallSetProperty* ins) override;
void visitCallDeleteProperty(LCallDeleteProperty* lir) override;
void visitCallDeleteElement(LCallDeleteElement* lir) override;
void visitBitNotV(LBitNotV* lir) override;
void visitBitOpV(LBitOpV* lir) override;
void visitRest(LRest* lir);
void visitCallSetProperty(LCallSetProperty* ins);
void visitCallDeleteProperty(LCallDeleteProperty* lir);
void visitCallDeleteElement(LCallDeleteElement* lir);
void visitBitNotV(LBitNotV* lir);
void visitBitOpV(LBitOpV* lir);
void emitInstanceOf(LInstruction* ins, JSObject* prototypeObject);
void visitInCache(LInCache* ins) override;
void visitInArray(LInArray* ins) override;
void visitInstanceOfO(LInstanceOfO* ins) override;
void visitInstanceOfV(LInstanceOfV* ins) override;
void visitInstanceOfCache(LInstanceOfCache* ins) override;
void visitGetDOMProperty(LGetDOMProperty* lir) override;
void visitGetDOMMemberV(LGetDOMMemberV* lir) override;
void visitGetDOMMemberT(LGetDOMMemberT* lir) override;
void visitSetDOMProperty(LSetDOMProperty* lir) override;
void visitCallDOMNative(LCallDOMNative* lir) override;
void visitCallGetIntrinsicValue(LCallGetIntrinsicValue* lir) override;
void visitCallBindVar(LCallBindVar* lir) override;
void visitInCache(LInCache* ins);
void visitInArray(LInArray* ins);
void visitInstanceOfO(LInstanceOfO* ins);
void visitInstanceOfV(LInstanceOfV* ins);
void visitInstanceOfCache(LInstanceOfCache* ins);
void visitGetDOMProperty(LGetDOMProperty* lir);
void visitGetDOMMemberV(LGetDOMMemberV* lir);
void visitGetDOMMemberT(LGetDOMMemberT* lir);
void visitSetDOMProperty(LSetDOMProperty* lir);
void visitCallDOMNative(LCallDOMNative* lir);
void visitCallGetIntrinsicValue(LCallGetIntrinsicValue* lir);
void visitCallBindVar(LCallBindVar* lir);
enum CallableOrConstructor {
Callable,
Constructor
};
template <CallableOrConstructor mode>
void emitIsCallableOrConstructor(Register object, Register output, Label* failure);
void visitIsCallableO(LIsCallableO* lir) override;
void visitIsCallableV(LIsCallableV* lir) override;
void visitIsCallableO(LIsCallableO* lir);
void visitIsCallableV(LIsCallableV* lir);
void visitOutOfLineIsCallable(OutOfLineIsCallable* ool);
void visitIsConstructor(LIsConstructor* lir) override;
void visitIsConstructor(LIsConstructor* lir);
void visitOutOfLineIsConstructor(OutOfLineIsConstructor* ool);
void visitIsArrayO(LIsArrayO* lir) override;
void visitIsArrayV(LIsArrayV* lir) override;
void visitIsTypedArray(LIsTypedArray* lir) override;
void visitIsObject(LIsObject* lir) override;
void visitIsObjectAndBranch(LIsObjectAndBranch* lir) override;
void visitHasClass(LHasClass* lir) override;
void visitObjectClassToString(LObjectClassToString* lir) override;
void visitWasmParameter(LWasmParameter* lir) override;
void visitWasmParameterI64(LWasmParameterI64* lir) override;
void visitWasmReturn(LWasmReturn* ret) override;
void visitWasmReturnI64(LWasmReturnI64* ret) override;
void visitWasmReturnVoid(LWasmReturnVoid* ret) override;
void visitLexicalCheck(LLexicalCheck* ins) override;
void visitThrowRuntimeLexicalError(LThrowRuntimeLexicalError* ins) override;
void visitGlobalNameConflictsCheck(LGlobalNameConflictsCheck* ins) override;
void visitDebugger(LDebugger* ins) override;
void visitNewTarget(LNewTarget* ins) override;
void visitArrowNewTarget(LArrowNewTarget* ins) override;
void visitCheckReturn(LCheckReturn* ins) override;
void visitCheckIsObj(LCheckIsObj* ins) override;
void visitCheckIsCallable(LCheckIsCallable* ins) override;
void visitCheckObjCoercible(LCheckObjCoercible* ins) override;
void visitDebugCheckSelfHosted(LDebugCheckSelfHosted* ins) override;
void visitNaNToZero(LNaNToZero* ins) override;
void visitIsArrayO(LIsArrayO* lir);
void visitIsArrayV(LIsArrayV* lir);
void visitIsTypedArray(LIsTypedArray* lir);
void visitIsObject(LIsObject* lir);
void visitIsObjectAndBranch(LIsObjectAndBranch* lir);
void visitHasClass(LHasClass* lir);
void visitObjectClassToString(LObjectClassToString* lir);
void visitWasmParameter(LWasmParameter* lir);
void visitWasmParameterI64(LWasmParameterI64* lir);
void visitWasmReturn(LWasmReturn* ret);
void visitWasmReturnI64(LWasmReturnI64* ret);
void visitWasmReturnVoid(LWasmReturnVoid* ret);
void visitLexicalCheck(LLexicalCheck* ins);
void visitThrowRuntimeLexicalError(LThrowRuntimeLexicalError* ins);
void visitGlobalNameConflictsCheck(LGlobalNameConflictsCheck* ins);
void visitDebugger(LDebugger* ins);
void visitNewTarget(LNewTarget* ins);
void visitArrowNewTarget(LArrowNewTarget* ins);
void visitCheckReturn(LCheckReturn* ins);
void visitCheckIsObj(LCheckIsObj* ins);
void visitCheckIsCallable(LCheckIsCallable* ins);
void visitCheckObjCoercible(LCheckObjCoercible* ins);
void visitDebugCheckSelfHosted(LDebugCheckSelfHosted* ins);
void visitNaNToZero(LNaNToZero* ins);
void visitOutOfLineNaNToZero(OutOfLineNaNToZero* ool);
void visitFinishBoundFunctionInit(LFinishBoundFunctionInit* lir) override;
void visitIsPackedArray(LIsPackedArray* lir) override;
void visitGetPrototypeOf(LGetPrototypeOf* lir) override;
void visitFinishBoundFunctionInit(LFinishBoundFunctionInit* lir);
void visitIsPackedArray(LIsPackedArray* lir);
void visitGetPrototypeOf(LGetPrototypeOf* lir);
void visitCheckOverRecursed(LCheckOverRecursed* lir) override;
void visitCheckOverRecursed(LCheckOverRecursed* lir);
void visitCheckOverRecursedFailure(CheckOverRecursedFailure* ool);
void visitUnboxFloatingPoint(LUnboxFloatingPoint* lir) override;
void visitUnboxFloatingPoint(LUnboxFloatingPoint* lir);
void visitOutOfLineUnboxFloatingPoint(OutOfLineUnboxFloatingPoint* ool);
void visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool);
@ -439,36 +439,36 @@ class CodeGenerator final : public CodeGeneratorSpecific
void visitOutOfLineICFallback(OutOfLineICFallback* ool);
void visitGetPropertyCacheV(LGetPropertyCacheV* ins) override;
void visitGetPropertyCacheT(LGetPropertyCacheT* ins) override;
void visitGetPropSuperCacheV(LGetPropSuperCacheV* ins) override;
void visitBindNameCache(LBindNameCache* ins) override;
void visitGetPropertyCacheV(LGetPropertyCacheV* ins);
void visitGetPropertyCacheT(LGetPropertyCacheT* ins);
void visitGetPropSuperCacheV(LGetPropSuperCacheV* ins);
void visitBindNameCache(LBindNameCache* ins);
void visitCallSetProperty(LInstruction* ins);
void visitSetPropertyCache(LSetPropertyCache* ins) override;
void visitGetNameCache(LGetNameCache* ins) override;
void visitHasOwnCache(LHasOwnCache* ins) override;
void visitSetPropertyCache(LSetPropertyCache* ins);
void visitGetNameCache(LGetNameCache* ins);
void visitHasOwnCache(LHasOwnCache* ins);
void visitAssertRangeI(LAssertRangeI* ins) override;
void visitAssertRangeD(LAssertRangeD* ins) override;
void visitAssertRangeF(LAssertRangeF* ins) override;
void visitAssertRangeV(LAssertRangeV* ins) override;
void visitAssertRangeI(LAssertRangeI* ins);
void visitAssertRangeD(LAssertRangeD* ins);
void visitAssertRangeF(LAssertRangeF* ins);
void visitAssertRangeV(LAssertRangeV* ins);
void visitAssertResultV(LAssertResultV* ins) override;
void visitAssertResultT(LAssertResultT* ins) override;
void visitAssertResultV(LAssertResultV* ins);
void visitAssertResultT(LAssertResultT* ins);
void emitAssertResultV(const ValueOperand output, const TemporaryTypeSet* typeset);
void emitAssertObjectOrStringResult(Register input, MIRType type, const TemporaryTypeSet* typeset);
void visitInterruptCheck(LInterruptCheck* lir) override;
void visitInterruptCheck(LInterruptCheck* lir);
void visitOutOfLineInterruptCheckImplicit(OutOfLineInterruptCheckImplicit* ins);
void visitWasmTrap(LWasmTrap* lir) override;
void visitWasmLoadTls(LWasmLoadTls* ins) override;
void visitWasmBoundsCheck(LWasmBoundsCheck* ins) override;
void visitWasmAlignmentCheck(LWasmAlignmentCheck* ins) override;
void visitRecompileCheck(LRecompileCheck* ins) override;
void visitRotate(LRotate* ins) override;
void visitWasmTrap(LWasmTrap* lir);
void visitWasmLoadTls(LWasmLoadTls* ins);
void visitWasmBoundsCheck(LWasmBoundsCheck* ins);
void visitWasmAlignmentCheck(LWasmAlignmentCheck* ins);
void visitRecompileCheck(LRecompileCheck* ins);
void visitRotate(LRotate* ins);
void visitRandom(LRandom* ins) override;
void visitSignExtendInt32(LSignExtendInt32* ins) override;
void visitRandom(LRandom* ins);
void visitSignExtendInt32(LSignExtendInt32* ins);
#ifdef DEBUG
void emitDebugForceBailing(LInstruction* lir);

View File

@ -4,8 +4,9 @@
* 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/. */
#include "jsgc.h"
#include "jit/CompileWrappers.h"
#include "gc/GC.h"
#include "jit/Ion.h"
#include "jit/JitCompartment.h"

View File

@ -54,7 +54,7 @@
#include "vm/TraceLogging.h"
#include "vtune/VTuneWrapper.h"
#include "gc/GCIteration-inl.h"
#include "gc/PrivateIterators-inl.h"
#include "jit/JitFrames-inl.h"
#include "jit/MacroAssembler-inl.h"
#include "jit/shared/Lowering-shared-inl.h"

View File

@ -19,9 +19,8 @@
#include "vm/RegExpObject.h"
#include "vm/SelfHosting.h"
#include "jsopcodeinlines.h"
#include "jit/shared/Lowering-shared-inl.h"
#include "vm/BytecodeUtil-inl.h"
#include "vm/JSObject-inl.h"
#include "vm/JSScript-inl.h"

View File

@ -25,11 +25,10 @@
#include "vm/RegExpStatics.h"
#include "vm/TraceLogging.h"
#include "jsopcodeinlines.h"
#include "gc/Nursery-inl.h"
#include "jit/CompileInfo-inl.h"
#include "jit/shared/Lowering-shared-inl.h"
#include "vm/BytecodeUtil-inl.h"
#include "vm/EnvironmentObject-inl.h"
#include "vm/JSScript-inl.h"
#include "vm/NativeObject-inl.h"
@ -3547,11 +3546,6 @@ IonBuilder::arithTrySharedStub(bool* emitted, JSOp op,
if (actualOp == JSOP_POS)
return Ok();
// FIXME: The JSOP_BITNOT path doesn't track optimizations yet.
if (actualOp != JSOP_BITNOT) {
trackOptimizationAttempt(TrackedStrategy::BinaryArith_SharedCache);
trackOptimizationSuccess();
}
MInstruction* stub = nullptr;
switch (actualOp) {
@ -3560,8 +3554,7 @@ IonBuilder::arithTrySharedStub(bool* emitted, JSOp op,
MOZ_ASSERT_IF(op == JSOP_MUL,
left->maybeConstantValue() && left->maybeConstantValue()->toInt32() == -1);
MOZ_ASSERT_IF(op != JSOP_MUL, !left);
stub = MUnarySharedStub::New(alloc(), right);
stub = MUnaryCache::New(alloc(), right);
break;
case JSOP_ADD:
case JSOP_SUB:

View File

@ -542,6 +542,19 @@ IonCacheIRCompiler::init()
AnyRegister(ic->rhs())));
break;
}
case CacheKind::UnaryArith: {
IonUnaryArithIC *ic = ic_->asUnaryArithIC();
ValueOperand output = ic->output();
available.add(output);
liveRegs_.emplace(ic->liveRegs());
outputUnchecked_.emplace(TypedOrValueRegister(output));
MOZ_ASSERT(numInputs == 1);
allocator.initInputLocation(0, ic->input());
break;
}
case CacheKind::Call:
case CacheKind::Compare:
case CacheKind::TypeOf:

View File

@ -60,6 +60,8 @@ IonIC::scratchRegisterForEntryJump()
return asGetIteratorIC()->temp1();
case CacheKind::InstanceOf:
return asInstanceOfIC()->output();
case CacheKind::UnaryArith:
return asUnaryArithIC()->output().scratchReg();
case CacheKind::Call:
case CacheKind::Compare:
case CacheKind::TypeOf:
@ -505,6 +507,48 @@ IonInstanceOfIC::update(JSContext* cx, HandleScript outerScript, IonInstanceOfIC
return HasInstance(cx, rhs, lhs, res);
}
/* static */ bool
IonUnaryArithIC::update(JSContext* cx, HandleScript outerScript, IonUnaryArithIC* ic,
HandleValue val, MutableHandleValue res)
{
IonScript* ionScript = outerScript->ionScript();
RootedScript script(cx, ic->script());
jsbytecode* pc = ic->pc();
JSOp op = JSOp(*pc);
switch (op) {
case JSOP_BITNOT: {
int32_t result;
if (!BitNot(cx, val, &result))
return false;
res.setInt32(result);
break;
}
case JSOP_NEG:
if (!NegOperation(cx, val, res))
return false;
break;
default:
MOZ_CRASH("Unexpected op");
}
if (ic->state().maybeTransition())
ic->discardStubs(cx->zone());
if (ic->state().canAttachStub()) {
bool attached = false;
UnaryArithIRGenerator gen(cx, script, pc, ic->state().mode(), op, val, res);
if (gen.tryAttachStub())
ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), ionScript, &attached);
if (!attached)
ic->state().trackNotAttached();
}
return true;
}
uint8_t*
IonICStub::stubDataStart()
{

View File

@ -65,6 +65,7 @@ class IonGetIteratorIC;
class IonHasOwnIC;
class IonInIC;
class IonInstanceOfIC;
class IonUnaryArithIC;
class IonIC
{
@ -172,6 +173,10 @@ class IonIC
MOZ_ASSERT(kind_ == CacheKind::InstanceOf);
return (IonInstanceOfIC*)this;
}
IonUnaryArithIC* asUnaryArithIC() {
MOZ_ASSERT(kind_ == CacheKind::UnaryArith);
return (IonUnaryArithIC*)this;
}
void updateBaseAddress(JitCode* code, MacroAssembler& masm);
@ -475,6 +480,30 @@ class IonInstanceOfIC : public IonIC
HandleValue lhs, HandleObject rhs, bool* attached);
};
class IonUnaryArithIC : public IonIC
{
LiveRegisterSet liveRegs_;
TypedOrValueRegister input_;
ValueOperand output_;
public:
IonUnaryArithIC(LiveRegisterSet liveRegs, TypedOrValueRegister input, ValueOperand output)
: IonIC(CacheKind::UnaryArith),
liveRegs_(liveRegs),
input_(input),
output_(output)
{ }
LiveRegisterSet liveRegs() const { return liveRegs_; }
TypedOrValueRegister input() const { return input_; }
ValueOperand output() const { return output_; }
static MOZ_MUST_USE bool update(JSContext* cx, HandleScript outerScript, IonUnaryArithIC* stub,
HandleValue val, MutableHandleValue res);
};
} // namespace jit
} // namespace js

View File

@ -484,6 +484,11 @@ LDefinition::dump() const
void
LNode::printOperands(GenericPrinter& out)
{
if (isMoveGroup()) {
toMoveGroup()->printOperands(out);
return;
}
size_t numOperands = isPhi() ? toPhi()->numOperands() : toInstruction()->numOperands();
for (size_t i = 0; i < numOperands; i++) {
@ -596,6 +601,17 @@ LNode::dump()
out.finish();
}
const char*
LNode::getExtraName() const
{
switch (op()) {
default: MOZ_CRASH("Unexpected LIR op");
# define LIROP(x) case LNode::LOp_##x: return to##x()->extraName();
LIR_OPCODE_LIST(LIROP)
# undef LIROP
}
}
void
LInstruction::initSafepoint(TempAllocator& alloc)
{

View File

@ -710,10 +710,14 @@ class LNode
// Hook for opcodes to add extra high level detail about what code will be
// emitted for the op.
virtual const char* extraName() const {
private:
const char* extraName() const {
return nullptr;
}
public:
const char* getExtraName() const;
virtual Opcode op() const = 0;
bool isInstruction() const {
@ -766,11 +770,11 @@ class LNode
// output register will be restored to its original value when bailing out.
inline bool recoversInput() const;
virtual void dump(GenericPrinter& out);
void dump(GenericPrinter& out);
void dump();
static void printName(GenericPrinter& out, Opcode op);
virtual void printName(GenericPrinter& out);
virtual void printOperands(GenericPrinter& out);
void printName(GenericPrinter& out);
void printOperands(GenericPrinter& out);
public:
// Opcode testing and casts.
@ -783,15 +787,9 @@ class LNode
LIR_OPCODE_LIST(LIROP)
# undef LIROP
virtual void accept(LElementVisitor* visitor) = 0;
#define LIR_HEADER(opcode) \
Opcode op() const override { \
return LInstruction::LOp_##opcode; \
} \
void accept(LElementVisitor* visitor) override { \
visitor->setElement(this); \
visitor->visit##opcode(this); \
}
};
@ -910,7 +908,6 @@ class LElementVisitor
return ins_;
}
public:
void setElement(LNode* ins) {
ins_ = ins;
if (ins->mirRaw()) {
@ -926,8 +923,7 @@ class LElementVisitor
lastNotInlinedPC_(nullptr)
{}
public:
#define VISIT_INS(op) virtual void visit##op(L##op*) { MOZ_CRASH("NYI: " #op); }
#define VISIT_INS(op) void visit##op(L##op*) { MOZ_CRASH("NYI: " #op); }
LIR_OPCODE_LIST(VISIT_INS)
#undef VISIT_INS
};

View File

@ -6,7 +6,7 @@
#include "jit/Linker.h"
#include "jsgc.h"
#include "gc/GC.h"
#include "gc/StoreBuffer-inl.h"

View File

@ -14,9 +14,8 @@
#include "jit/MIRGraph.h"
#include "wasm/WasmSignalHandlers.h"
#include "jsopcodeinlines.h"
#include "jit/shared/Lowering-shared-inl.h"
#include "vm/BytecodeUtil-inl.h"
#include "vm/JSObject-inl.h"
using namespace js;
@ -2532,13 +2531,13 @@ LIRGenerator::visitBinarySharedStub(MBinarySharedStub* ins)
}
void
LIRGenerator::visitUnarySharedStub(MUnarySharedStub* ins)
LIRGenerator::visitUnaryCache(MUnaryCache* ins)
{
MDefinition* input = ins->getOperand(0);
MOZ_ASSERT(ins->type() == MIRType::Value);
LUnarySharedStub* lir = new(alloc()) LUnarySharedStub(useBoxFixedAtStart(input, R0));
defineSharedStubReturn(lir, ins);
LUnaryCache* lir = new(alloc()) LUnaryCache(useBox(input));
defineBox(lir, ins);
assignSafepoint(lir, ins);
}

View File

@ -187,7 +187,7 @@ class LIRGenerator : public LIRGeneratorSpecific
void visitGetFirstDollarIndex(MGetFirstDollarIndex* ins) override;
void visitStringReplace(MStringReplace* ins) override;
void visitBinarySharedStub(MBinarySharedStub* ins) override;
void visitUnarySharedStub(MUnarySharedStub* ins) override;
void visitUnaryCache(MUnaryCache* ins) override;
void visitNullarySharedStub(MNullarySharedStub* ins) override;
void visitClassConstructor(MClassConstructor* ins) override;
void visitLambda(MLambda* ins) override;

Some files were not shown because too many files have changed in this diff Show More