зеркало из https://github.com/mozilla/gecko-dev.git
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
Коммит
0cbb58ed4f
|
@ -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, ¬Object);
|
||||
Register rhsObject = masm.extractObject(R1, ExtractTemp0);
|
||||
masm.storePtr(rhsObject, dest);
|
||||
EmitReturnFromIC(masm);
|
||||
masm.bind(¬Object);
|
||||
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());
|
||||
|
|
Загрузка…
Ссылка в новой задаче