Merge mozilla-central to autoland. a=merge CLOSED TREE

This commit is contained in:
Gurzau Raul 2019-05-28 00:57:10 +03:00
commit d568f187db
18 changed files with 169 additions and 77 deletions

View File

@ -13,6 +13,7 @@
#include "mozilla/layers/SourceSurfaceSharedData.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "mozilla/layers/RenderRootStateManager.h"
#include "mozilla/StaticPrefs.h" // for StaticPrefs
#include "mozilla/SystemGroup.h" // for SystemGroup
namespace mozilla {
@ -480,18 +481,15 @@ nsresult SharedSurfacesChild::UpdateAnimation(ImageContainer* aContainer,
AnimationImageKeyData::AnimationImageKeyData(RenderRootStateManager* aManager,
const wr::ImageKey& aImageKey)
: SharedSurfacesChild::ImageKeyData(aManager, aImageKey),
mRecycling(false) {}
: SharedSurfacesChild::ImageKeyData(aManager, aImageKey) {}
AnimationImageKeyData::AnimationImageKeyData(AnimationImageKeyData&& aOther)
: SharedSurfacesChild::ImageKeyData(std::move(aOther)),
mPendingRelease(std::move(aOther.mPendingRelease)),
mRecycling(aOther.mRecycling) {}
mPendingRelease(std::move(aOther.mPendingRelease)) {}
AnimationImageKeyData& AnimationImageKeyData::operator=(
AnimationImageKeyData&& aOther) {
mPendingRelease = std::move(aOther.mPendingRelease);
mRecycling = aOther.mRecycling;
SharedSurfacesChild::ImageKeyData::operator=(std::move(aOther));
return *this;
}
@ -517,7 +515,7 @@ void SharedSurfacesAnimation::Destroy() {
for (const auto& entry : mKeys) {
MOZ_ASSERT(!entry.mManager->IsDestroyed());
if (entry.mRecycling) {
if (StaticPrefs::ImageAnimatedDecodeOnDemandRecycle()) {
entry.mManager->DeregisterAsyncAnimation(entry.mImageKey);
}
entry.mManager->AddImageKeyForDiscard(entry.mImageKey);
@ -533,11 +531,7 @@ void SharedSurfacesAnimation::HoldSurfaceForRecycling(
return;
}
if (!aEntry.mRecycling) {
aEntry.mManager->RegisterAsyncAnimation(aEntry.mImageKey, this);
aEntry.mRecycling = true;
}
MOZ_ASSERT(StaticPrefs::ImageAnimatedDecodeOnDemandRecycle());
aEntry.mPendingRelease.AppendElement(aParentSurface);
}
@ -626,6 +620,10 @@ nsresult SharedSurfacesAnimation::UpdateKey(
if (!found) {
aKey = aManager->WrBridge()->GetNextImageKey();
if (StaticPrefs::ImageAnimatedDecodeOnDemandRecycle()) {
aManager->RegisterAsyncAnimation(aKey, this);
}
AnimationImageKeyData data(aManager, aKey);
HoldSurfaceForRecycling(data, aParentSurface, aSurface);
mKeys.AppendElement(std::move(data));

View File

@ -200,7 +200,6 @@ class AnimationImageKeyData final : public SharedSurfacesChild::ImageKeyData {
AnimationImageKeyData& operator=(AnimationImageKeyData&& aOther);
AutoTArray<RefPtr<gfx::SourceSurface>, 2> mPendingRelease;
bool mRecycling;
};
/**

View File

@ -2638,14 +2638,29 @@ void js::gc::StoreBuffer::MonoTypeBuffer<T>::trace(TenuringTracer& mover) {
}
}
template <typename T>
template <typename CellType>
void js::gc::StoreBuffer::MonoTypeBuffer<T>::traceTyped(TenuringTracer& mover) {
mozilla::ReentrancyGuard g(*owner_);
MOZ_ASSERT(owner_->isEnabled());
if (last_) {
last_.template traceTyped<CellType>(mover);
}
for (typename StoreSet::Range r = stores_.all(); !r.empty(); r.popFront()) {
r.front().template traceTyped<CellType>(mover);
}
}
namespace js {
namespace gc {
template void StoreBuffer::MonoTypeBuffer<StoreBuffer::ValueEdge>::trace(
TenuringTracer&);
template void StoreBuffer::MonoTypeBuffer<StoreBuffer::SlotsEdge>::trace(
TenuringTracer&);
template void StoreBuffer::MonoTypeBuffer<StoreBuffer::CellPtrEdge>::trace(
TenuringTracer&);
template void StoreBuffer::MonoTypeBuffer<StoreBuffer::CellPtrEdge>::traceTyped<
JSString>(TenuringTracer&);
template void StoreBuffer::MonoTypeBuffer<StoreBuffer::CellPtrEdge>::traceTyped<
JSObject>(TenuringTracer&);
} // namespace gc
} // namespace js
@ -2742,7 +2757,8 @@ void js::gc::StoreBuffer::WholeCellBuffer::trace(TenuringTracer& mover) {
head_ = nullptr;
}
void js::gc::StoreBuffer::CellPtrEdge::trace(TenuringTracer& mover) const {
template <typename CellType>
void js::gc::StoreBuffer::CellPtrEdge::traceTyped(TenuringTracer& mover) const {
if (!*edge) {
return;
}
@ -2753,20 +2769,11 @@ void js::gc::StoreBuffer::CellPtrEdge::trace(TenuringTracer& mover) const {
auto traceKind = (*edge)->getTraceKind();
MOZ_ASSERT(traceKind == JS::TraceKind::Object ||
traceKind == JS::TraceKind::String);
MOZ_ASSERT(traceKind == JS::MapTypeToTraceKind<CellType>::kind,
"traceKind mismatch.");
#endif
// Bug 1376646: Make separate store buffers for strings and objects, and
// only check IsInsideNursery once.
if (!IsInsideNursery(*edge)) {
return;
}
if ((*edge)->nurseryCellIsString()) {
mover.traverse(reinterpret_cast<JSString**>(edge));
} else {
mover.traverse(reinterpret_cast<JSObject**>(edge));
}
mover.traverse(reinterpret_cast<CellType**>(edge));
}
void js::gc::StoreBuffer::ValueEdge::trace(TenuringTracer& mover) const {

View File

@ -56,7 +56,8 @@ void StoreBuffer::GenericBuffer::trace(JSTracer* trc) {
StoreBuffer::StoreBuffer(JSRuntime* rt, const Nursery& nursery)
: bufferVal(this),
bufferCell(this),
bufStrCell(this),
bufObjCell(this),
bufferSlot(this),
bufferWholeCell(this),
bufferGeneric(this),
@ -74,7 +75,8 @@ StoreBuffer::StoreBuffer(JSRuntime* rt, const Nursery& nursery)
void StoreBuffer::checkEmpty() const {
MOZ_ASSERT(bufferVal.isEmpty());
MOZ_ASSERT(bufferCell.isEmpty());
MOZ_ASSERT(bufStrCell.isEmpty());
MOZ_ASSERT(bufObjCell.isEmpty());
MOZ_ASSERT(bufferSlot.isEmpty());
MOZ_ASSERT(bufferWholeCell.isEmpty());
MOZ_ASSERT(bufferGeneric.isEmpty());
@ -116,7 +118,8 @@ void StoreBuffer::clear() {
cancelIonCompilations_ = false;
bufferVal.clear();
bufferCell.clear();
bufStrCell.clear();
bufObjCell.clear();
bufferSlot.clear();
bufferWholeCell.clear();
bufferGeneric.clear();
@ -133,7 +136,8 @@ void StoreBuffer::setAboutToOverflow(JS::GCReason reason) {
void StoreBuffer::addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf,
JS::GCSizes* sizes) {
sizes->storeBufferVals += bufferVal.sizeOfExcludingThis(mallocSizeOf);
sizes->storeBufferCells += bufferCell.sizeOfExcludingThis(mallocSizeOf);
sizes->storeBufferCells += bufStrCell.sizeOfExcludingThis(mallocSizeOf) +
bufObjCell.sizeOfExcludingThis(mallocSizeOf);
sizes->storeBufferSlots += bufferSlot.sizeOfExcludingThis(mallocSizeOf);
sizes->storeBufferWholeCells +=
bufferWholeCell.sizeOfExcludingThis(mallocSizeOf);

View File

@ -124,6 +124,9 @@ class StoreBuffer {
/* Trace the source of all edges in the store buffer. */
void trace(TenuringTracer& mover);
template <typename CellType>
void traceTyped(TenuringTracer& mover);
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) {
return stores_.shallowSizeOfExcludingThis(mallocSizeOf);
}
@ -245,6 +248,8 @@ class StoreBuffer {
CellPtrEdge() : edge(nullptr) {}
explicit CellPtrEdge(Cell** v) : edge(v) {}
explicit CellPtrEdge(JSString** v) : edge(reinterpret_cast<Cell**>(v)) {}
explicit CellPtrEdge(JSObject** v) : edge(reinterpret_cast<Cell**>(v)) {}
bool operator==(const CellPtrEdge& other) const {
return edge == other.edge;
}
@ -257,7 +262,8 @@ class StoreBuffer {
return !nursery.isInside(edge);
}
void trace(TenuringTracer& mover) const;
template <typename CellType>
void traceTyped(TenuringTracer& mover) const;
CellPtrEdge tagged() const {
return CellPtrEdge((Cell**)(uintptr_t(edge) | 1));
@ -417,7 +423,8 @@ class StoreBuffer {
}
MonoTypeBuffer<ValueEdge> bufferVal;
MonoTypeBuffer<CellPtrEdge> bufferCell;
MonoTypeBuffer<CellPtrEdge> bufStrCell;
MonoTypeBuffer<CellPtrEdge> bufObjCell;
MonoTypeBuffer<SlotsEdge> bufferSlot;
WholeCellBuffer bufferWholeCell;
GenericBuffer bufferGeneric;
@ -451,8 +458,13 @@ class StoreBuffer {
/* Insert a single edge into the buffer/remembered set. */
void putValue(JS::Value* vp) { put(bufferVal, ValueEdge(vp)); }
void unputValue(JS::Value* vp) { unput(bufferVal, ValueEdge(vp)); }
void putCell(Cell** cellp) { put(bufferCell, CellPtrEdge(cellp)); }
void unputCell(Cell** cellp) { unput(bufferCell, CellPtrEdge(cellp)); }
void putCell(JSString** strp) { put(bufStrCell, CellPtrEdge(strp)); }
void unputCell(JSString** strp) { unput(bufStrCell, CellPtrEdge(strp)); }
void putCell(JSObject** strp) { put(bufObjCell, CellPtrEdge(strp)); }
void unputCell(JSObject** strp) { unput(bufObjCell, CellPtrEdge(strp)); }
void putSlot(NativeObject* obj, int kind, uint32_t start, uint32_t count) {
SlotsEdge edge(obj, kind, start, count);
if (bufferSlot.last_.overlaps(edge)) {
@ -474,7 +486,10 @@ class StoreBuffer {
/* Methods to trace the source of all edges in the store buffer. */
void traceValues(TenuringTracer& mover) { bufferVal.trace(mover); }
void traceCells(TenuringTracer& mover) { bufferCell.trace(mover); }
void traceCells(TenuringTracer& mover) {
bufStrCell.traceTyped<JSString>(mover);
bufObjCell.traceTyped<JSObject>(mover);
}
void traceSlots(TenuringTracer& mover) { bufferSlot.trace(mover); }
void traceWholeCells(TenuringTracer& mover) { bufferWholeCell.trace(mover); }
void traceGenericEntries(JSTracer* trc) { bufferGeneric.trace(trc); }

View File

@ -742,14 +742,14 @@ struct JSObject_Slots16 : JSObject {
if (prev && prev->storeBuffer()) {
return;
}
buffer->putCell(static_cast<js::gc::Cell**>(cellp));
buffer->putCell(static_cast<JSObject**>(cellp));
return;
}
// Remove the prev entry if the new value does not need it. There will only
// be a prev entry if the prev value was in the nursery.
if (prev && (buffer = prev->storeBuffer())) {
buffer->unputCell(static_cast<js::gc::Cell**>(cellp));
buffer->unputCell(static_cast<JSObject**>(cellp));
}
}

View File

@ -1429,7 +1429,7 @@ class NativeObject : public JSObject {
MOZ_ASSERT(*cellp);
gc::StoreBuffer* storeBuffer = (*cellp)->storeBuffer();
if (storeBuffer) {
storeBuffer->putCell(cellp);
storeBuffer->putCell(reinterpret_cast<JSObject**>(cellp));
}
}

View File

@ -721,12 +721,12 @@ class JSString : public js::gc::Cell {
static void addCellAddressToStoreBuffer(js::gc::StoreBuffer* buffer,
js::gc::Cell** cellp) {
buffer->putCell(cellp);
buffer->putCell(reinterpret_cast<JSString**>(cellp));
}
static void removeCellAddressFromStoreBuffer(js::gc::StoreBuffer* buffer,
js::gc::Cell** cellp) {
buffer->unputCell(cellp);
buffer->unputCell(reinterpret_cast<JSString**>(cellp));
}
static void writeBarrierPost(void* cellp, JSString* prev, JSString* next) {
@ -738,12 +738,12 @@ class JSString : public js::gc::Cell {
if (prev && prev->storeBuffer()) {
return;
}
buffer->putCell(static_cast<js::gc::Cell**>(cellp));
buffer->putCell(static_cast<JSString**>(cellp));
return;
}
if (prev && (buffer = prev->storeBuffer())) {
buffer->unputCell(static_cast<js::gc::Cell**>(cellp));
buffer->unputCell(static_cast<JSString**>(cellp));
}
}

View File

@ -985,7 +985,8 @@ void Instance::initElems(uint32_t tableIndex, const ElemSegment& seg,
gc::Cell** location) {
MOZ_ASSERT(SASigPostBarrier.failureMode == FailureMode::Infallible);
MOZ_ASSERT(location);
TlsContext.get()->runtime()->gc.storeBuffer().putCell(location);
TlsContext.get()->runtime()->gc.storeBuffer().putCell(
reinterpret_cast<JSObject**>(location));
}
/* static */ void Instance::postBarrierFiltering(Instance* instance,
@ -995,7 +996,8 @@ void Instance::initElems(uint32_t tableIndex, const ElemSegment& seg,
if (*location == nullptr || !gc::IsInsideNursery(*location)) {
return;
}
TlsContext.get()->runtime()->gc.storeBuffer().putCell(location);
TlsContext.get()->runtime()->gc.storeBuffer().putCell(
reinterpret_cast<JSObject**>(location));
}
// The typeIndex is an index into the structTypeDescrs_ table in the instance.

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
ol {
list-style-position: inside;
column-width: calc(0px);
}
li {
float: left;
}
li:last-child {
padding-block-end: calc(50%);
float: none;
}
</style>
<script>
function boom(){
document.getElementById("tgt").style.display = "block";
}
</script>
</head>
<body onload=boom()>
<ol>
<li id=tgt></li>
<li></li>
<li></li>
</ol>
</body>
</html>

View File

@ -0,0 +1,12 @@
<style>
#x { float: left; }
dir {
list-style-position: inside;
column-width: 3px;
}
</style>
<dir>
<div>
<li>
<li id=x>
<li>

View File

@ -732,3 +732,5 @@ load 1544060-1.html
load 1544060-2.html
load 1542441.html
pref(layout.css.grid-template-subgrid-value.enabled,true) load 1553824.html
load 1346454-1.html
load 1346454-2.html

View File

@ -2859,10 +2859,10 @@ VARCACHE_PREF(
)
VARCACHE_PREF(
Live,
Once,
"image.animated.decode-on-demand.recycle",
ImageAnimatedDecodeOnDemandRecycle,
RelaxedAtomicBool, false
bool, false
)
VARCACHE_PREF(

View File

@ -53,9 +53,10 @@ Communication
The mailing list for Firefox remote debugging discussion is
`dev-remote@lists.mozilla.org`_ (`subscribe`_, `archive`_).
If you prefer real-time chat, there is often someone in the *#remote* channel
on the <a href=https://devtools-html.slack.com/>DevTools Slack</a> instance.
If you prefer real-time chat, there is often someone in
the *#remote* channel on the `DevTools Slack`_ instance.
.. _dev-remote@lists.mozilla.org: mailto:dev-remote@lists.mozilla.org
.. _subscribe: https://lists.mozilla.org/listinfo/dev-remote
.. _archive: https://lists.mozilla.org/pipermail/dev-remote/
.. _DevTools Slack: https://devtools-html.slack.com/

View File

@ -1,27 +1,38 @@
=================
Marionette server
=================
==========
Marionette
==========
Marionette is the remote protocol that lets out-of-process programs
Marionette is a remote protocol that lets out-of-process programs
communicate with, instrument, and control Gecko-based browsers.
It provides interfaces for interacting with both the internal
JavaScript runtime and UI elements of Gecko-based browsers, such
as Firefox and Fennec. It can control both the chrome- and content
documents, giving a high level of control and ability to replicate,
or emulate, user interaction.
It provides interfaces for interacting with both the internal JavaScript
runtime and UI elements of Gecko-based browsers, such as Firefox
and Fennec. It can control both the chrome- and content documents,
giving a high level of control and ability to emulate user interaction.
Marionette can be activated by passing the `-marionette` flag. To
start Firefox with the remote protocol turned on::
Within the central tree, Marionette is used in most TaskCluster
test jobs to instrument Gecko. It can additionally be used to
write different kinds of functional tests:
% firefox -marionette
1491228343089 Marionette INFO Listening on port 2828
* The `Marionette Python client`_ is used in the `Mn` job, which
is generally what you want to use for interacting with web documents
This binds to a TCP socket, over which clients can communicate with
Marionette using the `protocol`_.
* `Firefox Puppeteer`_ is a convenience library for Firefox
frontend UI automation based on the `Marionette Python client`_
Outside the tree, Marionette is used by `geckodriver`_ to implement
`WebDriver`_.
Marionette supports to various degrees all the Gecko based applications,
including Firefox, Thunderbird, Fennec, and Fenix.
.. _protocol: Protocol.html
.. _Marionette Python client: /python/marionette_driver.html
.. _Firefox Puppeteer: http://firefox-puppeteer.readthedocs.io
.. _geckodriver: /testing/geckodriver/
.. _WebDriver: https://w3c.github.io/webdriver/
Some further documentation can be found here:
.. toctree::
:maxdepth: 1
@ -39,16 +50,6 @@ Marionette using the `protocol`_.
Prefs.md
internals/index
See also:
* Documentation for `Marionette Python client`_, which is used
in-tree to write many kinds of Marionette-based tests.
* Documentation for `Firefox Puppeteer`_, which is used to in-tree
to write Firefox UI tests.
.. _Marionette Python client: ../../../python/marionette_driver.html
.. _Firefox Puppeteer: http://firefox-puppeteer.readthedocs.io
Bugs
====

View File

@ -414,6 +414,7 @@ const nsAString& GfxDriverInfo::GetDriverVendor(DriverVendor id) {
DECLARE_DRIVER_VENDOR_ID(DriverMesaSoftPipe, "mesa/softpipe");
DECLARE_DRIVER_VENDOR_ID(DriverMesaSWRast, "mesa/swrast");
DECLARE_DRIVER_VENDOR_ID(DriverMesaUnknown, "mesa/unknown");
DECLARE_DRIVER_VENDOR_ID(DriverNonMesaAll, "non-mesa/all");
// Suppress a warning.
DECLARE_DRIVER_VENDOR_ID(DriverVendorMax, "");
}

View File

@ -145,6 +145,8 @@ enum DriverVendor {
DriverMesaSWRast,
// A generic ID to be provided when we can't determine the DRI driver on Mesa.
DriverMesaUnknown,
// Wildcard for all non-Mesa drivers.
DriverNonMesaAll,
DriverVendorMax
};

View File

@ -341,11 +341,20 @@ const nsTArray<GfxDriverInfo>& GfxInfo::GetGfxDriverInfo() {
nsIGfxInfo::FEATURE_BLOCKED_DEVICE, DRIVER_COMPARISON_IGNORED,
V(0, 0, 0, 0), "FEATURE_FAILURE_WEBRENDER_NO_LINUX_NVIDIA", "");
// Disable on all ATI devices for now.
// ATI Mesa baseline, chosen arbitrarily.
APPEND_TO_DRIVER_BLOCKLIST(
OperatingSystem::Linux,
(nsAString&)GfxDriverInfo::GetDeviceVendor(VendorATI),
(nsAString&)GfxDriverInfo::GetDriverVendor(DriverVendorAll),
(nsAString&)GfxDriverInfo::GetDriverVendor(DriverMesaAll),
GfxDriverInfo::allDevices, nsIGfxInfo::FEATURE_WEBRENDER,
nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, DRIVER_LESS_THAN,
V(18, 0, 0, 0), "FEATURE_FAILURE_WEBRENDER_OLD_MESA", "Mesa 18.0.0.0");
// Disable on all ATI devices not using Mesa for now.
APPEND_TO_DRIVER_BLOCKLIST(
OperatingSystem::Linux,
(nsAString&)GfxDriverInfo::GetDeviceVendor(VendorATI),
(nsAString&)GfxDriverInfo::GetDriverVendor(DriverNonMesaAll),
GfxDriverInfo::allDevices, nsIGfxInfo::FEATURE_WEBRENDER,
nsIGfxInfo::FEATURE_BLOCKED_DEVICE, DRIVER_COMPARISON_IGNORED,
V(0, 0, 0, 0), "FEATURE_FAILURE_WEBRENDER_NO_LINUX_ATI", "");
@ -360,6 +369,11 @@ bool GfxInfo::DoesDriverVendorMatch(const nsAString& aBlocklistVendor,
nsCaseInsensitiveStringComparator())) {
return true;
}
if (!mIsMesa &&
aBlocklistVendor.Equals(GfxDriverInfo::GetDriverVendor(DriverNonMesaAll),
nsCaseInsensitiveStringComparator())) {
return true;
}
return GfxInfoBase::DoesDriverVendorMatch(aBlocklistVendor, aDriverVendor);
}