merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2017-01-20 15:25:25 +01:00
Родитель 3ec1815acd 4eca59f4cb
Коммит 0cbb58ed4f
41 изменённых файлов: 477 добавлений и 416 удалений

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

@ -259,21 +259,16 @@ richlistitem[type="download"]:last-child {
padding: 0;
}
@itemFinished@[exists]:hover > .downloadMainArea,
@item@:not([verdict]):hover > .downloadButtonArea {
background-color: var(--arrowpanel-dimmed);
}
@itemFinished@[exists] .downloadMainArea:hover,
@item@:not([verdict]) > .downloadButtonArea:hover,
@item@[verdict]:hover {
background-color: var(--arrowpanel-dimmed-further);
background-color: var(--arrowpanel-dimmed);
}
@itemFinished@[exists] > .downloadMainArea:hover:active,
@item@:not([verdict]) > .downloadButtonArea:hover:active,
@item@[verdict]:hover:active {
background-color: var(--arrowpanel-dimmed-even-further);
background-color: var(--arrowpanel-dimmed-further);
}
@item@[showingsubview] {

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

@ -9096,9 +9096,15 @@ nsDocShell::CreateContentViewer(const nsACString& aContentType,
// Make sure we have a URI to set currentURI.
nsCOMPtr<nsIURI> failedURI;
nsCOMPtr<nsIPrincipal> triggeringPrincipal;
if (failedChannel) {
NS_GetFinalChannelURI(failedChannel, getter_AddRefs(failedURI));
}
else {
// if there is no failed channel we have to explicitly provide
// a triggeringPrincipal for the history entry.
triggeringPrincipal = nsContentUtils::GetSystemPrincipal();
}
if (!failedURI) {
failedURI = mFailedURI;
@ -9118,7 +9124,8 @@ nsDocShell::CreateContentViewer(const nsACString& aContentType,
// Create an shistory entry for the old load.
if (failedURI) {
bool errorOnLocationChangeNeeded = OnNewURI(
failedURI, failedChannel, nullptr, nullptr, mLoadType, false, false, false);
failedURI, failedChannel, triggeringPrincipal,
nullptr, mLoadType, false, false, false);
if (errorOnLocationChangeNeeded) {
FireOnLocationChange(this, failedChannel, failedURI,
@ -11996,7 +12003,9 @@ nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
// Since we're not changing which page we have loaded, pass
// true for aCloneChildren.
rv = AddToSessionHistory(newURI, nullptr, nullptr, nullptr, true,
rv = AddToSessionHistory(newURI, nullptr,
document->NodePrincipal(), // triggeringPrincipal
nullptr, true,
getter_AddRefs(newSHEntry));
NS_ENSURE_SUCCESS(rv, rv);

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

@ -3467,7 +3467,7 @@ nsDOMWindowUtils::AddSheet(nsIPreloadedStyleSheet* aSheet, uint32_t aSheetType)
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE);
if (sheet->GetOwningDocument()) {
if (sheet->GetAssociatedDocument()) {
return NS_ERROR_INVALID_ARG;
}

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

@ -1485,7 +1485,7 @@ nsDocument::~nsDocument()
// Let the stylesheets know we're going away
for (StyleSheet* sheet : mStyleSheets) {
sheet->SetOwningDocument(nullptr);
sheet->ClearAssociatedDocument();
}
if (mAttrStyleSheet) {
mAttrStyleSheet->SetOwningDocument(nullptr);
@ -2126,7 +2126,7 @@ nsDocument::RemoveDocStyleSheetsFromStyleSets()
{
// The stylesheets should forget us
for (StyleSheet* sheet : Reversed(mStyleSheets)) {
sheet->SetOwningDocument(nullptr);
sheet->ClearAssociatedDocument();
if (sheet->IsApplicable()) {
nsCOMPtr<nsIPresShell> shell = GetShell();
@ -2145,7 +2145,7 @@ nsDocument::RemoveStyleSheetsFromStyleSets(
{
// The stylesheets should forget us
for (StyleSheet* sheet : Reversed(aSheets)) {
sheet->SetOwningDocument(nullptr);
sheet->ClearAssociatedDocument();
if (sheet->IsApplicable()) {
nsCOMPtr<nsIPresShell> shell = GetShell();
@ -4082,7 +4082,7 @@ nsDocument::AddStyleSheet(StyleSheet* aSheet)
{
NS_PRECONDITION(aSheet, "null arg");
mStyleSheets.AppendElement(aSheet);
aSheet->SetOwningDocument(this);
aSheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument);
if (aSheet->IsApplicable()) {
AddStyleSheetToStyleSets(aSheet);
@ -4119,7 +4119,7 @@ nsDocument::RemoveStyleSheet(StyleSheet* aSheet)
NotifyStyleSheetRemoved(aSheet, true);
}
aSheet->SetOwningDocument(nullptr);
aSheet->ClearAssociatedDocument();
}
void
@ -4147,7 +4147,7 @@ nsDocument::UpdateStyleSheets(nsTArray<RefPtr<StyleSheet>>& aOldSheets,
StyleSheet* newSheet = aNewSheets[i];
if (newSheet) {
mStyleSheets.InsertElementAt(oldIndex, newSheet);
newSheet->SetOwningDocument(this);
newSheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument);
if (newSheet->IsApplicable()) {
AddStyleSheetToStyleSets(newSheet);
}
@ -4166,7 +4166,7 @@ nsDocument::InsertStyleSheetAt(StyleSheet* aSheet, int32_t aIndex)
mStyleSheets.InsertElementAt(aIndex, aSheet);
aSheet->SetOwningDocument(this);
aSheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument);
if (aSheet->IsApplicable()) {
AddStyleSheetToStyleSets(aSheet);
@ -4294,7 +4294,7 @@ nsDocument::LoadAdditionalStyleSheet(additionalSheetType aType,
nsresult rv = loader->LoadSheetSync(aSheetURI, parsingMode, true, &sheet);
NS_ENSURE_SUCCESS(rv, rv);
sheet->SetOwningDocument(this);
sheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument);
MOZ_ASSERT(sheet->IsApplicable());
return AddAdditionalStyleSheet(aType, sheet);
@ -4352,7 +4352,7 @@ nsDocument::RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheet
NotifyStyleSheetRemoved(sheetRef, false);
EndUpdate(UPDATE_STYLE);
sheetRef->SetOwningDocument(nullptr);
sheetRef->ClearAssociatedDocument();
}
}
@ -12022,7 +12022,7 @@ SizeOfOwnedSheetArrayExcludingThis(const nsTArray<RefPtr<StyleSheet>>& aSheets,
size_t n = 0;
n += aSheets.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (StyleSheet* sheet : aSheets) {
if (!sheet->GetOwningDocument()) {
if (!sheet->GetAssociatedDocument()) {
// Avoid over-reporting shared sheets.
continue;
}

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

@ -47,6 +47,7 @@ var ecmaGlobals =
[
"Array",
"ArrayBuffer",
"Atomics",
"Boolean",
"DataView",
"Date",
@ -78,9 +79,8 @@ var ecmaGlobals =
"Reflect",
"RegExp",
"Set",
{name: "SharedArrayBuffer", release: false},
"SharedArrayBuffer",
{name: "SIMD", nightly: true},
{name: "Atomics", release: false},
"StopIteration",
"String",
"Symbol",

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

@ -25,6 +25,7 @@ var ecmaGlobals =
[
"Array",
"ArrayBuffer",
"Atomics",
"Boolean",
"DataView",
"Date",
@ -53,9 +54,8 @@ var ecmaGlobals =
"Reflect",
"RegExp",
"Set",
{name: "SharedArrayBuffer", release: false},
"SharedArrayBuffer",
{name: "SIMD", nightly: true},
{name: "Atomics", release: false},
"StopIteration",
"String",
"Symbol",

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

@ -25,6 +25,7 @@ var ecmaGlobals =
[
"Array",
"ArrayBuffer",
"Atomics",
"Boolean",
"DataView",
"Date",
@ -53,9 +54,8 @@ var ecmaGlobals =
"Reflect",
"RegExp",
"Set",
{name: "SharedArrayBuffer", release: false},
"SharedArrayBuffer",
{name: "SIMD", nightly: true},
{name: "Atomics", release: false},
"StopIteration",
"String",
"Symbol",

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

@ -2952,7 +2952,7 @@ HTMLEditor::EnableStyleSheet(const nsAString& aURL,
// Ensure the style sheet is owned by our document.
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocWeak);
sheet->SetOwningDocument(doc);
sheet->SetAssociatedDocument(doc, StyleSheet::NotOwnedByDocument);
if (sheet->IsServo()) {
// XXXheycam ServoStyleSheets don't support being enabled/disabled yet.
@ -2974,7 +2974,7 @@ HTMLEditor::EnableExistingStyleSheet(const nsAString& aURL)
// Ensure the style sheet is owned by our document.
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocWeak);
sheet->SetOwningDocument(doc);
sheet->SetAssociatedDocument(doc, StyleSheet::NotOwnedByDocument);
if (sheet->IsServo()) {
// XXXheycam ServoStyleSheets don't support being enabled/disabled yet.

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

@ -510,6 +510,52 @@ public:
IntRect mBounds;
};
struct BorderLayerProperties : public LayerPropertiesBase
{
explicit BorderLayerProperties(BorderLayer *aLayer)
: LayerPropertiesBase(aLayer)
, mColors(aLayer->GetColors())
, mRect(aLayer->GetRect())
, mCorners(aLayer->GetCorners())
, mWidths(aLayer->GetWidths())
{ }
protected:
BorderLayerProperties(const BorderLayerProperties& a) = delete;
BorderLayerProperties& operator=(const BorderLayerProperties& a) = delete;
public:
nsIntRegion ComputeChangeInternal(const char* aPrefix,
NotifySubDocInvalidationFunc aCallback,
bool& aGeometryChanged) override
{
BorderLayer* border = static_cast<BorderLayer*>(mLayer.get());
if (!border->GetLocalVisibleRegion().ToUnknownRegion().IsEqual(mVisibleRegion)) {
aGeometryChanged = true;
IntRect result = NewTransformedBounds();
result = result.Union(OldTransformedBounds());
return result;
}
if (!PodEqual(&mColors[0], &border->GetColors()[0], 4) ||
!PodEqual(&mWidths[0], &border->GetWidths()[0], 4) ||
!PodEqual(&mCorners[0], &border->GetCorners()[0], 4) ||
!mRect.IsEqualEdges(border->GetRect())) {
aGeometryChanged = true;
LTI_DUMP(NewTransformedBounds(), "bounds");
return NewTransformedBounds();
}
return nsIntRegion();
}
BorderColors mColors;
LayerRect mRect;
BorderCorners mCorners;
BorderWidths mWidths;
};
static ImageHost* GetImageHost(Layer* aLayer)
{
HostLayer* compositor = aLayer->AsHostLayer();
@ -644,11 +690,12 @@ CloneLayerTreePropertiesInternal(Layer* aRoot, bool aIsMask /* = false */)
return MakeUnique<ImageLayerProperties>(static_cast<ImageLayer*>(aRoot), aIsMask);
case Layer::TYPE_CANVAS:
return MakeUnique<CanvasLayerProperties>(static_cast<CanvasLayer*>(aRoot));
case Layer::TYPE_BORDER:
return MakeUnique<BorderLayerProperties>(static_cast<BorderLayer*>(aRoot));
case Layer::TYPE_READBACK:
case Layer::TYPE_SHADOW:
case Layer::TYPE_PAINTED:
case Layer::TYPE_TEXT:
case Layer::TYPE_BORDER:
return MakeUnique<LayerPropertiesBase>(aRoot);
}

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

@ -2510,6 +2510,11 @@ public:
ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
}
const BorderColors& GetColors() { return mColors; }
const LayerRect& GetRect() { return mRect; }
const BorderCorners& GetCorners() { return mCorners; }
const BorderWidths& GetWidths() { return mWidths; }
protected:
BorderLayer(LayerManager* aManager, void* aImplData)
: Layer(aManager, aImplData)

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

@ -369,6 +369,13 @@ CompositorBridgeChild::RecvCompositorUpdated(const uint64_t& aLayersId,
if (sLastSeqNo != aSeqNo) {
gfxPlatform::GetPlatform()->CompositorUpdated();
sLastSeqNo = aSeqNo;
// If we still get device reset here, something must wrong when creating
// d3d11 devices.
if (gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
gfxCriticalError() << "Unexpected reset device processing when \
updating compositor.";
}
}
if (dom::TabChild* child = dom::TabChild::GetFrom(aLayersId)) {

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

@ -1516,6 +1516,14 @@ gfxWindowsPlatform::InitializeD3D11()
}
dm->CreateContentDevices();
// Content process failed to create the d3d11 device while parent process
// succeed.
if (XRE_IsContentProcess() &&
!gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
gfxCriticalError() << "[D3D11] Failed to create the D3D11 device in content \
process.";
}
}
void

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

@ -16,6 +16,8 @@ skip-if = toolkit != "cocoa"
[test_bug1086527.js]
[test_intl_on_workers.js]
skip-if = toolkit == "android" # bug 1309447
[test_pluralForm.js]
[test_pluralForm_english.js]
[test_pluralForm_makeGetter.js]

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

@ -804,6 +804,98 @@ BaselineCacheIRCompiler::emitStoreUnboxedProperty()
return true;
}
bool
BaselineCacheIRCompiler::emitStoreTypedObjectReferenceProperty()
{
ObjOperandId objId = reader.objOperandId();
Address offsetAddr = stubAddress(reader.stubOffset());
TypedThingLayout layout = reader.typedThingLayout();
ReferenceTypeDescr::Type type = reader.referenceTypeDescrType();
// Allocate the fixed registers first. These need to be fixed for
// callTypeUpdateIC.
AutoStubFrame stubFrame(*this);
AutoScratchRegister scratch1(allocator, masm, R1.scratchReg());
ValueOperand val = allocator.useFixedValueRegister(masm, reader.valOperandId(), R0);
Register obj = allocator.useRegister(masm, objId);
// We don't need a type update IC if the property is always a string.
if (type != ReferenceTypeDescr::TYPE_STRING) {
LiveGeneralRegisterSet saveRegs;
saveRegs.add(obj);
saveRegs.add(val);
if (!callTypeUpdateIC(stubFrame, obj, val, scratch1, saveRegs))
return false;
}
// Compute the address being written to.
LoadTypedThingData(masm, layout, obj, scratch1);
masm.addPtr(offsetAddr, scratch1);
Address dest(scratch1, 0);
// To avoid running out of registers on x86, use ICStubReg as second
// scratch. It won't be used after this.
Register scratch2 = ICStubReg;
switch (type) {
case ReferenceTypeDescr::TYPE_ANY:
EmitPreBarrier(masm, dest, MIRType::Value);
masm.storeValue(val, dest);
break;
case ReferenceTypeDescr::TYPE_OBJECT: {
EmitPreBarrier(masm, dest, MIRType::Object);
Label isNull, done;
masm.branchTestObject(Assembler::NotEqual, val, &isNull);
masm.unboxObject(val, scratch2);
masm.storePtr(scratch2, dest);
masm.jump(&done);
masm.bind(&isNull);
masm.storePtr(ImmWord(0), dest);
masm.bind(&done);
break;
}
case ReferenceTypeDescr::TYPE_STRING:
EmitPreBarrier(masm, dest, MIRType::String);
masm.unboxString(val, scratch2);
masm.storePtr(scratch2, dest);
break;
}
if (type != ReferenceTypeDescr::TYPE_STRING)
BaselineEmitPostWriteBarrierSlot(masm, obj, val, scratch1, LiveGeneralRegisterSet(), cx_);
return true;
}
bool
BaselineCacheIRCompiler::emitStoreTypedObjectScalarProperty()
{
Register obj = allocator.useRegister(masm, reader.objOperandId());
Address offsetAddr = stubAddress(reader.stubOffset());
TypedThingLayout layout = reader.typedThingLayout();
Scalar::Type type = reader.scalarType();
ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
AutoScratchRegister scratch1(allocator, masm);
AutoScratchRegister scratch2(allocator, masm);
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
// Compute the address being written to.
LoadTypedThingData(masm, layout, obj, scratch1);
masm.addPtr(offsetAddr, scratch1);
Address dest(scratch1, 0);
BaselineStoreToTypedArray(cx_, masm, type, val, dest, scratch2,
failure->label(), failure->label());
return true;
}
bool
BaselineCacheIRCompiler::emitTypeMonitorResult()
{

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

@ -284,6 +284,33 @@ DoTypeUpdateFallback(JSContext* cx, BaselineFrame* frame, ICUpdatedStub* stub, H
case ICStub::CacheIR_Updated:
id = stub->toCacheIR_Updated()->updateStubId();
MOZ_ASSERT(id != JSID_EMPTY);
// If we're storing null/undefined to a typed object property, check if
// we want to include it in this property's type information.
if (MOZ_UNLIKELY(obj->is<TypedObject>()) && value.isNullOrUndefined()) {
StructTypeDescr* structDescr = &obj->as<TypedObject>().typeDescr().as<StructTypeDescr>();
size_t fieldIndex;
MOZ_ALWAYS_TRUE(structDescr->fieldIndex(id, &fieldIndex));
TypeDescr* fieldDescr = &structDescr->fieldDescr(fieldIndex);
ReferenceTypeDescr::Type type = fieldDescr->as<ReferenceTypeDescr>().type();
if (type == ReferenceTypeDescr::TYPE_ANY) {
// Ignore undefined values, which are included implicitly in type
// information for this property.
if (value.isUndefined())
break;
} else {
MOZ_ASSERT(type == ReferenceTypeDescr::TYPE_OBJECT);
// Ignore null values being written here. Null is included
// implicitly in type information for this property. Note that
// non-object, non-null values are not possible here, these
// should have been filtered out by the IR emitter.
if (value.isNull())
break;
}
}
AddTypePropertyId(cx, obj, id, value);
break;
case ICStub::SetElem_DenseOrUnboxedArray:
@ -302,25 +329,6 @@ DoTypeUpdateFallback(JSContext* cx, BaselineFrame* frame, ICUpdatedStub* stub, H
AddTypePropertyId(cx, obj, id, value);
break;
}
case ICStub::SetProp_TypedObject: {
MOZ_ASSERT(obj->is<TypedObject>());
jsbytecode* pc = stub->getChainFallback()->icEntry()->pc(script);
id = NameToId(script->getName(pc));
if (stub->toSetProp_TypedObject()->isObjectReference()) {
// Ignore all values being written except plain objects. Null
// is included implicitly in type information for this property,
// and non-object non-null values will cause the stub to fail to
// match shortly and we will end up doing the assignment in the VM.
if (value.isObject())
AddTypePropertyId(cx, obj, id, value);
} else {
// Ignore undefined values, which are included implicitly in type
// information for this property.
if (!value.isUndefined())
AddTypePropertyId(cx, obj, id, value);
}
break;
}
default:
MOZ_CRASH("Invalid stub");
}
@ -1856,13 +1864,11 @@ ICSetElemDenseOrUnboxedArrayAddCompiler::generateStubCode(MacroAssembler& masm)
// SetElem_TypedArray
//
// Write an arbitrary value to a typed array or typed object address at dest.
// If the value could not be converted to the appropriate format, jump to
// failure or failureModifiedScratch.
template <typename T>
static void
StoreToTypedArray(JSContext* cx, MacroAssembler& masm, Scalar::Type type, Address value, T dest,
Register scratch, Label* failure, Label* failureModifiedScratch)
template <typename S, typename T>
void
BaselineStoreToTypedArray(JSContext* cx, MacroAssembler& masm, Scalar::Type type, const S& value,
const T& dest, Register scratch, Label* failure,
Label* failureModifiedScratch)
{
Label done;
@ -1922,6 +1928,16 @@ StoreToTypedArray(JSContext* cx, MacroAssembler& masm, Scalar::Type type, Addres
masm.bind(&done);
}
template void
BaselineStoreToTypedArray(JSContext* cx, MacroAssembler& masm, Scalar::Type type,
const ValueOperand& value, const Address& dest, Register scratch,
Label* failure, Label* failureModifiedScratch);
template void
BaselineStoreToTypedArray(JSContext* cx, MacroAssembler& masm, Scalar::Type type,
const Address& value, const BaseIndex& dest, Register scratch,
Label* failure, Label* failureModifiedScratch);
bool
ICSetElem_TypedArray::Compiler::generateStubCode(MacroAssembler& masm)
{
@ -1984,8 +2000,8 @@ ICSetElem_TypedArray::Compiler::generateStubCode(MacroAssembler& masm)
Register secondScratch = regs.takeAny();
Label failureModifiedSecondScratch;
StoreToTypedArray(cx, masm, type_, value, dest,
secondScratch, &failure, &failureModifiedSecondScratch);
BaselineStoreToTypedArray(cx, masm, type_, value, dest,
secondScratch, &failure, &failureModifiedSecondScratch);
EmitReturnFromIC(masm);
if (failureModifiedSecondScratch.used()) {
@ -2748,48 +2764,6 @@ TryAttachSetAccessorPropStub(JSContext* cx, HandleScript script, jsbytecode* pc,
return true;
}
static bool
TryAttachTypedObjectSetPropStub(JSContext* cx, HandleScript script,
ICSetProp_Fallback* stub, HandleId id,
HandleObject obj, HandleValue rhs, bool* attached)
{
MOZ_ASSERT(!*attached);
if (!cx->runtime()->jitSupportsFloatingPoint)
return true;
if (!obj->is<TypedObject>())
return true;
if (!obj->as<TypedObject>().typeDescr().is<StructTypeDescr>())
return true;
Rooted<StructTypeDescr*> structDescr(cx);
structDescr = &obj->as<TypedObject>().typeDescr().as<StructTypeDescr>();
size_t fieldIndex;
if (!structDescr->fieldIndex(id, &fieldIndex))
return true;
Rooted<TypeDescr*> fieldDescr(cx, &structDescr->fieldDescr(fieldIndex));
if (!fieldDescr->is<SimpleTypeDescr>())
return true;
uint32_t fieldOffset = structDescr->fieldOffset(fieldIndex);
ICSetProp_TypedObject::Compiler compiler(cx, obj->maybeShape(), obj->group(), fieldOffset,
&fieldDescr->as<SimpleTypeDescr>());
ICUpdatedStub* newStub = compiler.getStub(compiler.getStubSpace(script));
if (!newStub)
return false;
if (compiler.needsUpdateStubs() && !newStub->addUpdateStubForValue(cx, script, obj, id, rhs))
return false;
stub->addNewStub(newStub);
*attached = true;
return true;
}
static bool
DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_, Value* stack,
HandleValue lhs, HandleValue rhs)
@ -2932,15 +2906,6 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_
if (attached)
return true;
if (!attached &&
lhs.isObject() &&
!TryAttachTypedObjectSetPropStub(cx, script, stub, id, obj, rhs, &attached))
{
return false;
}
if (attached)
return true;
MOZ_ASSERT(!attached);
if (!isTemporarilyUnoptimizable)
stub->noteUnoptimizableAccess();
@ -3197,128 +3162,6 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler& masm)
return true;
}
bool
ICSetProp_TypedObject::Compiler::generateStubCode(MacroAssembler& masm)
{
MOZ_ASSERT(engine_ == Engine::Baseline);
Label failure;
CheckForTypedObjectWithDetachedStorage(cx, masm, &failure);
// Guard input is an object.
masm.branchTestObject(Assembler::NotEqual, R0, &failure);
AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
Register scratch = regs.takeAny();
// Unbox and shape guard.
Register object = masm.extractObject(R0, ExtractTemp0);
masm.loadPtr(Address(ICStubReg, ICSetProp_TypedObject::offsetOfShape()), scratch);
masm.branchTestObjShape(Assembler::NotEqual, object, scratch, &failure);
// Guard that the object group matches.
masm.loadPtr(Address(ICStubReg, ICSetProp_TypedObject::offsetOfGroup()), scratch);
masm.branchPtr(Assembler::NotEqual, Address(object, JSObject::offsetOfGroup()), scratch,
&failure);
if (needsUpdateStubs()) {
// Stow both R0 and R1 (object and value).
EmitStowICValues(masm, 2);
// Move RHS into R0 for TypeUpdate check.
masm.moveValue(R1, R0);
// Call the type update stub.
if (!callTypeUpdateIC(masm, sizeof(Value)))
return false;
// Unstow R0 and R1 (object and key)
EmitUnstowICValues(masm, 2);
// We may have clobbered object in the TypeUpdate IC. Rederive it.
masm.unboxObject(R0, object);
// Trigger post barriers here on the values being written. Descriptors
// which can write objects also need update stubs.
LiveGeneralRegisterSet saveRegs;
saveRegs.add(R0);
saveRegs.add(R1);
saveRegs.addUnchecked(object);
saveRegs.add(ICStubReg);
BaselineEmitPostWriteBarrierSlot(masm, object, R1, scratch, saveRegs, cx);
}
// Save the rhs on the stack so we can get a second scratch register.
Label failurePopRHS;
masm.pushValue(R1);
regs = availableGeneralRegs(1);
regs.takeUnchecked(object);
regs.take(scratch);
Register secondScratch = regs.takeAny();
// Get the object's data pointer.
LoadTypedThingData(masm, layout_, object, scratch);
// Compute the address being written to.
masm.load32(Address(ICStubReg, ICSetProp_TypedObject::offsetOfFieldOffset()), secondScratch);
masm.addPtr(secondScratch, scratch);
Address dest(scratch, 0);
Address value(masm.getStackPointer(), 0);
if (fieldDescr_->is<ScalarTypeDescr>()) {
Scalar::Type type = fieldDescr_->as<ScalarTypeDescr>().type();
StoreToTypedArray(cx, masm, type, value, dest,
secondScratch, &failurePopRHS, &failurePopRHS);
masm.popValue(R1);
} else {
ReferenceTypeDescr::Type type = fieldDescr_->as<ReferenceTypeDescr>().type();
masm.popValue(R1);
switch (type) {
case ReferenceTypeDescr::TYPE_ANY:
EmitPreBarrier(masm, dest, MIRType::Value);
masm.storeValue(R1, dest);
break;
case ReferenceTypeDescr::TYPE_OBJECT: {
EmitPreBarrier(masm, dest, MIRType::Object);
Label notObject;
masm.branchTestObject(Assembler::NotEqual, R1, &notObject);
Register rhsObject = masm.extractObject(R1, ExtractTemp0);
masm.storePtr(rhsObject, dest);
EmitReturnFromIC(masm);
masm.bind(&notObject);
masm.branchTestNull(Assembler::NotEqual, R1, &failure);
masm.storePtr(ImmWord(0), dest);
break;
}
case ReferenceTypeDescr::TYPE_STRING: {
EmitPreBarrier(masm, dest, MIRType::String);
masm.branchTestString(Assembler::NotEqual, R1, &failure);
Register rhsString = masm.extractString(R1, ExtractTemp0);
masm.storePtr(rhsString, dest);
break;
}
default:
MOZ_CRASH();
}
}
EmitReturnFromIC(masm);
masm.bind(&failurePopRHS);
masm.popValue(R1);
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
bool
ICSetProp_CallScripted::Compiler::generateStubCode(MacroAssembler& masm)
{

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

@ -1235,94 +1235,6 @@ class ICSetPropNativeAddCompiler : public ICStubCompiler
ICUpdatedStub* getStub(ICStubSpace* space);
};
class ICSetProp_TypedObject : public ICUpdatedStub
{
friend class ICStubSpace;
GCPtrShape shape_;
GCPtrObjectGroup group_;
uint32_t fieldOffset_;
bool isObjectReference_;
ICSetProp_TypedObject(JitCode* stubCode, Shape* shape, ObjectGroup* group,
uint32_t fieldOffset, bool isObjectReference)
: ICUpdatedStub(ICStub::SetProp_TypedObject, stubCode),
shape_(shape),
group_(group),
fieldOffset_(fieldOffset),
isObjectReference_(isObjectReference)
{
(void) fieldOffset_; // Silence clang warning
}
public:
GCPtrShape& shape() {
return shape_;
}
GCPtrObjectGroup& group() {
return group_;
}
bool isObjectReference() {
return isObjectReference_;
}
static size_t offsetOfShape() {
return offsetof(ICSetProp_TypedObject, shape_);
}
static size_t offsetOfGroup() {
return offsetof(ICSetProp_TypedObject, group_);
}
static size_t offsetOfFieldOffset() {
return offsetof(ICSetProp_TypedObject, fieldOffset_);
}
class Compiler : public ICStubCompiler {
protected:
RootedShape shape_;
RootedObjectGroup group_;
uint32_t fieldOffset_;
TypedThingLayout layout_;
Rooted<SimpleTypeDescr*> fieldDescr_;
MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm);
virtual int32_t getKey() const {
return static_cast<int32_t>(engine_) |
(static_cast<int32_t>(kind) << 1) |
(static_cast<int32_t>(SimpleTypeDescrKey(fieldDescr_)) << 17) |
(static_cast<int32_t>(layout_) << 25);
}
public:
Compiler(JSContext* cx, Shape* shape, ObjectGroup* group, uint32_t fieldOffset,
SimpleTypeDescr* fieldDescr)
: ICStubCompiler(cx, ICStub::SetProp_TypedObject, Engine::Baseline),
shape_(cx, shape),
group_(cx, group),
fieldOffset_(fieldOffset),
layout_(GetTypedThingLayout(shape->getObjectClass())),
fieldDescr_(cx, fieldDescr)
{}
ICUpdatedStub* getStub(ICStubSpace* space) {
bool isObjectReference =
fieldDescr_->is<ReferenceTypeDescr>() &&
fieldDescr_->as<ReferenceTypeDescr>().type() == ReferenceTypeDescr::TYPE_OBJECT;
ICUpdatedStub* stub = newStub<ICSetProp_TypedObject>(space, getStubCode(), shape_,
group_, fieldOffset_,
isObjectReference);
if (!stub || !stub->initUpdatingChain(cx, space))
return nullptr;
return stub;
}
bool needsUpdateStubs() {
return fieldDescr_->is<ReferenceTypeDescr>() &&
fieldDescr_->as<ReferenceTypeDescr>().type() != ReferenceTypeDescr::TYPE_STRING;
}
};
};
// Base stub for calling a setters on a native or unboxed object.
class ICSetPropCallSetter : public ICStub
{
@ -2534,6 +2446,15 @@ struct IonOsrTempData;
void EmitUnboxedPreBarrierForBaseline(MacroAssembler &masm, const BaseIndex& address,
JSValueType type);
// Write an arbitrary value to a typed array or typed object address at dest.
// If the value could not be converted to the appropriate format, jump to
// failure or failureModifiedScratch.
template <typename S, typename T>
void
BaselineStoreToTypedArray(JSContext* cx, MacroAssembler& masm, Scalar::Type type, const S& value,
const T& dest, Register scratch, Label* failure,
Label* failureModifiedScratch);
} // namespace jit
} // namespace js

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

@ -70,7 +70,6 @@ namespace jit {
\
_(SetProp_Fallback) \
_(SetProp_NativeAdd) \
_(SetProp_TypedObject) \
_(SetProp_CallScripted) \
_(SetProp_CallNative) \
\

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

@ -1567,6 +1567,8 @@ SetPropIRGenerator::tryAttachStub()
return true;
if (tryAttachUnboxedProperty(obj, objId, id, rhsValId))
return true;
if (tryAttachTypedObjectProperty(obj, objId, id, rhsValId))
return true;
}
return false;
}
@ -1699,3 +1701,61 @@ SetPropIRGenerator::tryAttachUnboxedProperty(HandleObject obj, ObjOperandId objI
preliminaryObjectAction_ = PreliminaryObjectAction::Unlink;
return true;
}
bool
SetPropIRGenerator::tryAttachTypedObjectProperty(HandleObject obj, ObjOperandId objId, HandleId id,
ValOperandId rhsId)
{
if (!obj->is<TypedObject>() || !cx_->runtime()->jitSupportsFloatingPoint)
return false;
if (cx_->compartment()->detachedTypedObjects)
return false;
if (!obj->as<TypedObject>().typeDescr().is<StructTypeDescr>())
return false;
StructTypeDescr* structDescr = &obj->as<TypedObject>().typeDescr().as<StructTypeDescr>();
size_t fieldIndex;
if (!structDescr->fieldIndex(id, &fieldIndex))
return false;
TypeDescr* fieldDescr = &structDescr->fieldDescr(fieldIndex);
if (!fieldDescr->is<SimpleTypeDescr>())
return false;
uint32_t fieldOffset = structDescr->fieldOffset(fieldIndex);
TypedThingLayout layout = GetTypedThingLayout(obj->getClass());
writer.guardNoDetachedTypedObjects();
writer.guardShape(objId, obj->as<TypedObject>().shape());
writer.guardGroup(objId, obj->group());
setUpdateStubInfo(id);
// Scalar types can always be stored without a type update stub.
if (fieldDescr->is<ScalarTypeDescr>()) {
Scalar::Type type = fieldDescr->as<ScalarTypeDescr>().type();
writer.storeTypedObjectScalarProperty(objId, fieldOffset, layout, type, rhsId);
writer.returnFromIC();
return true;
}
// For reference types, guard on the RHS type first, so that
// StoreTypedObjectReferenceProperty is infallible.
ReferenceTypeDescr::Type type = fieldDescr->as<ReferenceTypeDescr>().type();
switch (type) {
case ReferenceTypeDescr::TYPE_ANY:
break;
case ReferenceTypeDescr::TYPE_OBJECT:
writer.guardIsObjectOrNull(rhsId);
break;
case ReferenceTypeDescr::TYPE_STRING:
writer.guardType(rhsId, JSVAL_TYPE_STRING);
break;
}
writer.storeTypedObjectReferenceProperty(objId, fieldOffset, layout, type, rhsId);
writer.returnFromIC();
return true;
}

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

@ -172,6 +172,8 @@ enum class CacheKind : uint8_t
\
_(StoreFixedSlot) \
_(StoreDynamicSlot) \
_(StoreTypedObjectReferenceProperty) \
_(StoreTypedObjectScalarProperty) \
_(StoreUnboxedProperty) \
\
/* The *Result ops load a value into the cache's result register. */ \
@ -567,6 +569,25 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
addStubField(offset, StubField::Type::RawWord);
writeOperandId(rhs);
}
void storeTypedObjectReferenceProperty(ObjOperandId obj, uint32_t offset,
TypedThingLayout layout, ReferenceTypeDescr::Type type,
ValOperandId rhs)
{
writeOpWithOperandId(CacheOp::StoreTypedObjectReferenceProperty, obj);
addStubField(offset, StubField::Type::RawWord);
buffer_.writeByte(uint32_t(layout));
buffer_.writeByte(uint32_t(type));
writeOperandId(rhs);
}
void storeTypedObjectScalarProperty(ObjOperandId obj, uint32_t offset, TypedThingLayout layout,
Scalar::Type type, ValOperandId rhs)
{
writeOpWithOperandId(CacheOp::StoreTypedObjectScalarProperty, obj);
addStubField(offset, StubField::Type::RawWord);
buffer_.writeByte(uint32_t(layout));
buffer_.writeByte(uint32_t(type));
writeOperandId(rhs);
}
void storeUnboxedProperty(ObjOperandId obj, JSValueType type, size_t offset,
ValOperandId rhs)
{
@ -713,6 +734,10 @@ class MOZ_RAII CacheIRReader
uint32_t typeDescrKey() { return buffer_.readByte(); }
JSWhyMagic whyMagic() { return JSWhyMagic(buffer_.readByte()); }
ReferenceTypeDescr::Type referenceTypeDescrType() {
return ReferenceTypeDescr::Type(buffer_.readByte());
}
bool matchOp(CacheOp op) {
const uint8_t* pos = buffer_.currentPosition();
if (readOp() == op)
@ -880,6 +905,8 @@ class MOZ_RAII SetPropIRGenerator : public IRGenerator
ValOperandId rhsId);
bool tryAttachUnboxedProperty(HandleObject obj, ObjOperandId objId, HandleId id,
ValOperandId rhsId);
bool tryAttachTypedObjectProperty(HandleObject obj, ObjOperandId objId, HandleId id,
ValOperandId rhsId);
public:
SetPropIRGenerator(JSContext* cx, jsbytecode* pc, CacheKind cacheKind,

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

@ -815,7 +815,7 @@ FlowAliasAnalysis::saveStoreDependency(MDefinition* ins, BlockStoreInfo& prevSto
// To form a store dependency chain, we store the previous last dependencies
// in the current store.
StoreDependency* dependency = new(alloc()) StoreDependency(alloc());
StoreDependency* dependency = new(alloc().fallible()) StoreDependency(alloc());
if (!dependency)
return false;
if (!dependency->init(prevStores))

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

@ -855,6 +855,18 @@ IonCacheIRCompiler::emitStoreUnboxedProperty()
MOZ_CRASH("Baseline-specific op");
}
bool
IonCacheIRCompiler::emitStoreTypedObjectReferenceProperty()
{
MOZ_CRASH("Baseline-specific op");
}
bool
IonCacheIRCompiler::emitStoreTypedObjectScalarProperty()
{
MOZ_CRASH("Baseline-specific op");
}
bool
IonCacheIRCompiler::emitLoadTypedObjectResult()
{

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

@ -372,12 +372,6 @@ ICStub::trace(JSTracer* trc)
}
break;
}
case ICStub::SetProp_TypedObject: {
ICSetProp_TypedObject* propStub = toSetProp_TypedObject();
TraceEdge(trc, &propStub->shape(), "baseline-setprop-typedobject-stub-shape");
TraceEdge(trc, &propStub->group(), "baseline-setprop-typedobject-stub-group");
break;
}
case ICStub::SetProp_CallScripted: {
ICSetProp_CallScripted* callStub = toSetProp_CallScripted();
callStub->receiverGuard().trace(trc);

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

@ -2383,7 +2383,7 @@ class ICGetProp_Generic : public ICMonitoredStub
};
};
static uint32_t
static inline uint32_t
SimpleTypeDescrKey(SimpleTypeDescr* descr)
{
if (descr->is<ScalarTypeDescr>())

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

@ -146,11 +146,8 @@ static const size_t gMaxStackSize = 128 * sizeof(size_t) * 1024;
*/
static const TimeDuration MAX_TIMEOUT_INTERVAL = TimeDuration::FromSeconds(1800.0);
#ifdef RELEASE_OR_BETA
# define SHARED_MEMORY_DEFAULT 0
#else
# define SHARED_MEMORY_DEFAULT 1
#endif
// SharedArrayBuffer and Atomics are enabled by default (tracking Firefox).
#define SHARED_MEMORY_DEFAULT 1
using JobQueue = GCVector<JSObject*, 0, SystemAllocPolicy>;

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

@ -256,12 +256,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
gConstructorProperties['ArrayBuffer'] =
constructorProps(["isView", Symbol.species]);
if (!isReleaseOrBeta) {
gPrototypeProperties['SharedArrayBuffer'] = ["constructor", "slice", "byteLength", Symbol.toStringTag];
gConstructorProperties['SharedArrayBuffer'] = constructorProps([Symbol.species]);
} else {
is(typeof SharedArrayBuffer, "undefined", "Enable tests!");
}
gPrototypeProperties['SharedArrayBuffer'] = ["constructor", "slice", "byteLength", Symbol.toStringTag];
gConstructorProperties['SharedArrayBuffer'] = constructorProps([Symbol.species]);
gPrototypeProperties['Map'] =
["constructor", "size", Symbol.toStringTag, "get", "has", "set", "delete",
@ -912,11 +908,7 @@ for (var prop of props) {
}
function testArrayBuffer() {
let constructors = ['ArrayBuffer'];
if (!isReleaseOrBeta) {
constructors.push('SharedArrayBuffer');
}
let constructors = ['ArrayBuffer', 'SharedArrayBuffer'];
for (const c of constructors) {
testXray(c, new iwin[c](0), new iwin[c](12));

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

@ -151,7 +151,8 @@ struct ChildSheetListBuilder {
void SetParentLinks(CSSStyleSheet* aSheet) {
aSheet->mParent = parent;
aSheet->SetOwningDocument(parent->mDocument);
aSheet->SetAssociatedDocument(parent->mDocument,
parent->mDocumentAssociationMode);
}
static void ReparentChildList(CSSStyleSheet* aPrimarySheet,
@ -159,7 +160,8 @@ struct ChildSheetListBuilder {
{
for (CSSStyleSheet *child = aFirstChild; child; child = child->mNext) {
child->mParent = aPrimarySheet;
child->SetOwningDocument(aPrimarySheet->mDocument);
child->SetAssociatedDocument(aPrimarySheet->mDocument,
aPrimarySheet->mDocumentAssociationMode);
}
}
};
@ -612,16 +614,22 @@ CSSStyleSheet::GetParentSheet() const
}
void
CSSStyleSheet::SetOwningDocument(nsIDocument* aDocument)
{ // not ref counted
CSSStyleSheet::SetAssociatedDocument(nsIDocument* aDocument,
DocumentAssociationMode aAssociationMode)
{
MOZ_ASSERT_IF(!aDocument, aAssociationMode == NotOwnedByDocument);
// not ref counted
mDocument = aDocument;
mDocumentAssociationMode = aAssociationMode;
// Now set the same document on all our child sheets....
// XXXbz this is a little bogus; see the XXX comment where we
// declare mFirstChild.
for (CSSStyleSheet* child = mInner->mFirstChild;
child; child = child->mNext) {
if (child->mParent == this) {
child->SetOwningDocument(aDocument);
child->SetAssociatedDocument(aDocument, aAssociationMode);
}
}
}

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

@ -117,7 +117,8 @@ public:
// style sheet owner info
CSSStyleSheet* GetParentSheet() const; // may be null
void SetOwningDocument(nsIDocument* aDocument);
void SetAssociatedDocument(nsIDocument* aDocument,
DocumentAssociationMode aAssociationMode);
// Find the ID of the owner inner window.
uint64_t FindOwningWindowInnerID() const;

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

@ -2218,13 +2218,13 @@ Loader::LoadChildSheet(StyleSheet* aParentSheet,
nsCOMPtr<nsINode> owningNode;
// check for an owning document: if none, don't bother walking up the parent
// sheets
// check for an associated document: if none, don't bother walking up the
// parent sheets
//
// FIXME(emilio): Figure out whether this walk up is necessary (try seems
// green without it), and fix the parenting of stylesheets in the servo case
// if that's the case.
if (aParentSheet->GetOwningDocument() && aParentSheet->IsGecko()) {
if (aParentSheet->GetAssociatedDocument() && aParentSheet->IsGecko()) {
StyleSheet* topSheet = aParentSheet;
while (StyleSheet* parent = topSheet->GetParentSheet()) {
topSheet = parent;

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

@ -70,15 +70,15 @@ ServoStyleRuleDeclaration::SetCSSDeclaration(DeclarationBlock* aDecl)
{
ServoStyleRule* rule = Rule();
if (RefPtr<ServoStyleSheet> sheet = rule->GetStyleSheet()->AsServo()) {
nsCOMPtr<nsIDocument> owningDoc = sheet->GetOwningDocument();
mozAutoDocUpdate updateBatch(owningDoc, UPDATE_STYLE, true);
nsCOMPtr<nsIDocument> doc = sheet->GetAssociatedDocument();
mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);
if (aDecl != mDecls) {
RefPtr<ServoDeclarationBlock> decls = aDecl->AsServo();
Servo_StyleRule_SetStyle(rule->Raw(), decls->Raw());
mDecls = decls.forget();
}
if (owningDoc) {
owningDoc->StyleRuleChanged(sheet, rule);
if (doc) {
doc->StyleRuleChanged(sheet, rule);
}
}
return NS_OK;

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

@ -55,19 +55,23 @@ ServoStyleSheet::HasRules() const
}
void
ServoStyleSheet::SetOwningDocument(nsIDocument* aDocument)
ServoStyleSheet::SetAssociatedDocument(nsIDocument* aDocument,
DocumentAssociationMode aAssociationMode)
{
MOZ_ASSERT_IF(!aDocument, aAssociationMode == NotOwnedByDocument);
// XXXheycam: Traverse to child ServoStyleSheets to set this, like
// CSSStyleSheet::SetOwningDocument does.
// CSSStyleSheet::SetAssociatedDocument does.
mDocument = aDocument;
mDocumentAssociationMode = aAssociationMode;
}
ServoStyleSheet*
ServoStyleSheet::GetParentSheet() const
{
// XXXheycam: When we implement support for child sheets, we'll have
// to fix SetOwningDocument to propagate the owning document down
// to fix SetAssociatedDocument to propagate the associated document down
// to the children.
MOZ_CRASH("stylo: not implemented");
}

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

@ -38,7 +38,8 @@ public:
bool HasRules() const;
void SetOwningDocument(nsIDocument* aDocument);
void SetAssociatedDocument(nsIDocument* aDocument,
DocumentAssociationMode aAssociationMode);
ServoStyleSheet* GetParentSheet() const;
void AppendStyleSheet(ServoStyleSheet* aSheet);

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

@ -1206,13 +1206,13 @@ DOMCSSDeclarationImpl::SetCSSDeclaration(DeclarationBlock* aDecl)
NS_PRECONDITION(mRule,
"can only be called when |GetCSSDeclaration| returned a declaration");
nsCOMPtr<nsIDocument> owningDoc;
nsCOMPtr<nsIDocument> doc;
RefPtr<CSSStyleSheet> sheet = mRule->GetStyleSheet();
if (sheet) {
owningDoc = sheet->GetOwningDocument();
doc = sheet->GetAssociatedDocument();
}
mozAutoDocUpdate updateBatch(owningDoc, UPDATE_STYLE, true);
mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);
mRule->SetDeclaration(aDecl->AsGecko());
@ -1220,8 +1220,8 @@ DOMCSSDeclarationImpl::SetCSSDeclaration(DeclarationBlock* aDecl)
sheet->DidDirty();
}
if (owningDoc) {
owningDoc->StyleRuleChanged(sheet, mRule);
if (doc) {
doc->StyleRuleChanged(sheet, mRule);
}
return NS_OK;
}

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

@ -24,6 +24,7 @@ StyleSheet::StyleSheet(StyleBackendType aType, css::SheetParsingMode aParsingMod
, mParsingMode(aParsingMode)
, mType(aType)
, mDisabled(false)
, mDocumentAssociationMode(NotOwnedByDocument)
{
}
@ -36,6 +37,9 @@ StyleSheet::StyleSheet(const StyleSheet& aCopy,
, mParsingMode(aCopy.mParsingMode)
, mType(aCopy.mType)
, mDisabled(aCopy.mDisabled)
// We only use this constructor during cloning. It's the cloner's
// responsibility to notify us if we end up being owned by a document.
, mDocumentAssociationMode(NotOwnedByDocument)
{
if (aCopy.mMedia) {
// XXX This is wrong; we should be keeping @import rules and

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

@ -106,8 +106,22 @@ public:
inline bool HasRules() const;
// style sheet owner info
nsIDocument* GetOwningDocument() const { return mDocument; }
inline void SetOwningDocument(nsIDocument* aDocument);
enum DocumentAssociationMode {
// OwnedByDocument means mDocument owns us (possibly via a chain of other
// stylesheets).
OwnedByDocument,
// NotOwnedByDocument means we're owned by something that might have a
// different lifetime than mDocument.
NotOwnedByDocument
};
nsIDocument* GetAssociatedDocument() const { return mDocument; }
bool IsOwnedByDocument() const {
return mDocumentAssociationMode == OwnedByDocument;
}
// aDocument must not be null.
inline void SetAssociatedDocument(nsIDocument* aDocument,
DocumentAssociationMode aMode);
inline void ClearAssociatedDocument();
nsINode* GetOwnerNode() const { return mOwningNode; }
inline StyleSheet* GetParentSheet() const;
@ -225,6 +239,11 @@ protected:
const StyleBackendType mType;
bool mDisabled;
// mDocumentAssociationMode determines whether mDocument directly owns us (in
// the sense that if it's known-live then we're known-live). Always
// NotOwnedByDocument when mDocument is null.
DocumentAssociationMode mDocumentAssociationMode;
};
} // namespace mozilla

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

@ -83,9 +83,17 @@ StyleSheet::HasRules() const
}
void
StyleSheet::SetOwningDocument(nsIDocument* aDocument)
StyleSheet::SetAssociatedDocument(nsIDocument* aDocument,
DocumentAssociationMode aAssociationMode)
{
MOZ_STYLO_FORWARD(SetOwningDocument, (aDocument))
MOZ_ASSERT(aDocument);
MOZ_STYLO_FORWARD(SetAssociatedDocument, (aDocument, aAssociationMode))
}
void
StyleSheet::ClearAssociatedDocument()
{
MOZ_STYLO_FORWARD(SetAssociatedDocument, (nullptr, NotOwnedByDocument));
}
StyleSheet*

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

@ -267,7 +267,7 @@ nsDOMCSSDeclaration::GetCSSParsingEnvironmentForRule(css::Rule* aRule,
return;
}
nsIDocument* document = sheet->GetOwningDocument();
nsIDocument* document = sheet->GetAssociatedDocument();
aCSSParseEnv.mSheetURI = sheet->GetSheetURI();
aCSSParseEnv.mBaseURI = sheet->GetBaseURI();
aCSSParseEnv.mPrincipal = sheet->Principal();

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

@ -583,7 +583,7 @@ nsMediaList::GetMediaText(nsAString& aMediaText)
// nsCOMPtr<nsIDocument>
#define BEGIN_MEDIA_CHANGE(sheet, doc) \
if (sheet) { \
doc = sheet->GetOwningDocument(); \
doc = sheet->GetAssociatedDocument(); \
} \
mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true); \
if (sheet) { \

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

@ -446,12 +446,12 @@ WebrtcVideoConduit::CreateRecvStream()
return kMediaConduitNoError;
}
static bool CompatibleH264Config(const webrtc::VideoCodecH264 &aEncoderSpecificH264,
const VideoCodecConfig* aCodecConfig)
static bool CompatibleH264Config(const webrtc::VideoCodecH264& aEncoderSpecificH264,
const VideoCodecConfig& aCodecConfig)
{
if (aEncoderSpecificH264.profile_byte != aCodecConfig->mProfile ||
aEncoderSpecificH264.constraints != aCodecConfig->mConstraints ||
aEncoderSpecificH264.packetizationMode != aCodecConfig->mPacketizationMode) {
if (aEncoderSpecificH264.profile_byte != aCodecConfig.mProfile ||
aEncoderSpecificH264.constraints != aCodecConfig.mConstraints ||
aEncoderSpecificH264.packetizationMode != aCodecConfig.mPacketizationMode) {
return false;
}
return true;
@ -481,27 +481,6 @@ WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig)
return condError;
}
// StopTransmitting may be moot if mSendStream is null, but the code seems to
// allow for it.
// Recreating on PayloadType change may be overkill, but is safe.
if (!mSendStream ||
mSendStreamConfig.encoder_settings.payload_type != codecConfig->mType ||
mSendStreamConfig.encoder_settings.payload_name != codecConfig->mName ||
(codecConfig->mName == "H264" &&
!CompatibleH264Config(mEncoderSpecificH264, codecConfig))) {
condError = StopTransmitting();
if (condError != kMediaConduitNoError) {
return condError;
}
DeleteSendStream(); // safe if mSendStream is null
} // we are already using this codec - mSendStream tells us we're reconfiguring
mSendStreamConfig.encoder_settings.payload_name = codecConfig->mName;
mSendStreamConfig.encoder_settings.payload_type = codecConfig->mType;
mSendStreamConfig.rtp.rtcp_mode = webrtc::RtcpMode::kCompound;
mSendStreamConfig.rtp.max_packet_size = kVideoMtu;
mSendStreamConfig.overuse_callback = mLoadManager.get();
size_t streamCount = std::min(codecConfig->mSimulcastEncodings.size(),
(size_t)webrtc::kMaxSimulcastStreams);
CSFLogDebug(logTag, "%s for VideoConduit:%p stream count:%d", __FUNCTION__,
@ -642,6 +621,35 @@ WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig)
// for the GMP H.264 encoder/decoder!!
mEncoderConfig.SetMinTransmitBitrateBps(0);
// If only encoder stream attibutes have been changed, there is no need to stop,
// create a new webrtc::VideoSendStream, and restart.
// Recreating on PayloadType change may be overkill, but is safe.
if (mSendStream) {
if (!RequiresNewSendStream(*codecConfig)) {
if (!mSendStream->ReconfigureVideoEncoder(mEncoderConfig.GenerateConfig())) {
CSFLogError(logTag, "%s: ReconfigureVideoEncoder failed", __FUNCTION__);
// Don't return here; let it try to destroy the encoder and rebuild it
// on StartTransmitting()
} else {
return kMediaConduitNoError;
}
}
condError = StopTransmitting();
if (condError != kMediaConduitNoError) {
return condError;
}
// This will cause a new encoder to be created by StartTransmitting()
DeleteSendStream();
}
mSendStreamConfig.encoder_settings.payload_name = codecConfig->mName;
mSendStreamConfig.encoder_settings.payload_type = codecConfig->mType;
mSendStreamConfig.rtp.rtcp_mode = webrtc::RtcpMode::kCompound;
mSendStreamConfig.rtp.max_packet_size = kVideoMtu;
mSendStreamConfig.overuse_callback = mLoadManager.get();
// See Bug 1297058, enabling FEC when basic NACK is to be enabled in H.264 is problematic
if (codecConfig->RtcpFbFECIsSet() &&
!(codecConfig->mName == "H264" && codecConfig->RtcpFbNackIsSet(""))) {
@ -659,18 +667,6 @@ WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig)
mCurSendCodecConfig = new VideoCodecConfig(*codecConfig);
}
// Is this a reconfigure of a running codec?
if (mSendStream &&
!mSendStream->ReconfigureVideoEncoder(mEncoderConfig.GenerateConfig())) {
CSFLogError(logTag, "%s: ReconfigureVideoEncoder failed", __FUNCTION__);
// This will cause a new encoder to be created by StartTransmitting()
condError = StopTransmitting();
if (condError != kMediaConduitNoError) {
return condError;
}
DeleteSendStream();
}
return condError;
}
@ -2004,6 +2000,18 @@ WebrtcVideoConduit::CodecPluginID()
return 0;
}
bool
WebrtcVideoConduit::RequiresNewSendStream(const VideoCodecConfig& newConfig) const
{
return !mCurSendCodecConfig
|| mCurSendCodecConfig->mName != newConfig.mName
|| mCurSendCodecConfig->mType != newConfig.mType
|| mCurSendCodecConfig->RtcpFbNackIsSet("") != newConfig.RtcpFbNackIsSet("")
|| mCurSendCodecConfig->RtcpFbFECIsSet() != newConfig.RtcpFbFECIsSet()
|| (newConfig.mName == "H264" &&
!CompatibleH264Config(mEncoderSpecificH264, newConfig));
}
void
WebrtcVideoConduit::VideoEncoderConfigBuilder::SetEncoderSpecificSettings(
void* aSettingsObj)

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

@ -437,14 +437,16 @@ private:
MediaConduitErrorCode DeliverPacket(const void *data, int len);
bool RequiresNewSendStream(const VideoCodecConfig& newConfig) const;
mozilla::ReentrantMonitor mTransportMonitor;
RefPtr<TransportInterface> mTransmitterTransport;
RefPtr<TransportInterface> mReceiverTransport;
RefPtr<mozilla::VideoRenderer> mRenderer;
// Engine state we are concerned with.
mozilla::Atomic<bool> mEngineTransmitting; //If true ==> Transmit Sub-system is up and running
mozilla::Atomic<bool> mEngineReceiving; // if true ==> Receive Sus-sysmtem up and running
mozilla::Atomic<bool> mEngineTransmitting; // If true ==> Transmit Subsystem is up and running
mozilla::Atomic<bool> mEngineReceiving; // if true ==> Receive Subsystem up and running
int mCapId; // Capturer for this conduit
//Local database of currently applied receive codecs

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

@ -1296,12 +1296,7 @@ pref("javascript.options.mem.gc_max_empty_chunk_count", 30);
pref("javascript.options.showInConsole", false);
#ifdef RELEASE_OR_BETA
// Disabled in Beta and Release for now, see bug 1225406
pref("javascript.options.shared_memory", false);
#else
pref("javascript.options.shared_memory", true);
#endif
pref("javascript.options.throw_on_debuggee_would_run", false);
pref("javascript.options.dump_stack_on_debuggee_would_run", false);

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

@ -6721,6 +6721,7 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
// fetch the data from the server, the time includes loading of the old
// cache entry which would skew the network load time.
if (request == mTransactionPump && mCacheEntry && !mDidReval &&
!mCustomConditionalRequest &&
!mAsyncOpenTime.IsNull() && !mOnStartRequestTimestamp.IsNull()) {
nsAutoCString onStartTime;
onStartTime.AppendInt( (uint64_t) (mOnStartRequestTimestamp - mAsyncOpenTime).ToMilliseconds());