Merge inbound to mozilla-central. a=merge

This commit is contained in:
Margareta Eliza Balazs 2018-02-18 18:41:41 +02:00
commit 5536f71c38
41 changed files with 488 additions and 547 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -1459,44 +1459,6 @@ class ICRetSub_Resume : public ICStub
};
};
// UnaryArith
// JSOP_BITNOT
// JSOP_NEG
class ICUnaryArith_Fallback : public ICFallbackStub
{
friend class ICStubSpace;
explicit ICUnaryArith_Fallback(JitCode* stubCode)
: ICFallbackStub(UnaryArith_Fallback, stubCode)
{
extra_ = 0;
}
public:
bool sawDoubleResult() {
return extra_;
}
void setSawDoubleResult() {
extra_ = 1;
}
// Compiler for this stub kind.
class Compiler : public ICStubCompiler {
protected:
MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override;
public:
explicit Compiler(JSContext* cx)
: ICStubCompiler(cx, ICStub::UnaryArith_Fallback, Engine::Baseline)
{}
ICStub* getStub(ICStubSpace* space) override {
return newStub<ICUnaryArith_Fallback>(space, getStubCode());
}
};
};
inline bool
IsCacheableDOMProxy(JSObject* obj)
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -175,16 +175,12 @@ typedef bool (*IonInICFn)(JSContext*, HandleScript, IonInIC*, HandleValue, Handl
static const VMFunction IonInICInfo =
FunctionInfo<IonInICFn>(IonInIC::update, "IonInIC::update");
typedef bool (*IonInstanceOfICFn)(JSContext*, HandleScript, IonInstanceOfIC*,
HandleValue lhs, HandleObject rhs, bool* res);
static const VMFunction IonInstanceOfInfo =
FunctionInfo<IonInstanceOfICFn>(IonInstanceOfIC::update, "IonInstanceOfIC::update");
typedef bool (*IonUnaryArithICFn)(JSContext* cx, HandleScript outerScript, IonUnaryArithIC* stub,
HandleValue val, MutableHandleValue res);
static const VMFunction IonUnaryArithICInfo =
FunctionInfo<IonUnaryArithICFn>(IonUnaryArithIC::update, "IonUnaryArithIC::update");
void
CodeGenerator::visitOutOfLineICFallback(OutOfLineICFallback* ool)
{
@ -361,22 +357,6 @@ CodeGenerator::visitOutOfLineICFallback(OutOfLineICFallback* ool)
masm.jump(ool->rejoin());
return;
}
case CacheKind::UnaryArith: {
IonUnaryArithIC* unaryArithIC = ic->asUnaryArithIC();
saveLive(lir);
pushArg(unaryArithIC->input());
icInfo_[cacheInfoIndex].icOffsetForPush = pushArgWithPatch(ImmWord(-1));
pushArg(ImmGCPtr(gen->info().script()));
callVM(IonUnaryArithICInfo, lir);
StoreValueTo(unaryArithIC->output()).generate(this);
restoreLiveIgnore(lir, StoreValueTo(unaryArithIC->output()).clobbered());
masm.jump(ool->rejoin());
return;
}
case CacheKind::Call:
case CacheKind::Compare:
case CacheKind::TypeOf:
@ -2757,14 +2737,22 @@ CodeGenerator::visitBinarySharedStub(LBinarySharedStub* lir)
}
void
CodeGenerator::visitUnaryCache(LUnaryCache* lir)
CodeGenerator::visitUnarySharedStub(LUnarySharedStub* lir)
{
LiveRegisterSet liveRegs = lir->safepoint()->liveRegs();
TypedOrValueRegister input = TypedOrValueRegister(ToValue(lir, LUnaryCache::Input));
ValueOperand output = GetValueOutput(lir);
IonUnaryArithIC ic(liveRegs, input, output);
addIC(lir, allocateIC(ic));
JSOp jsop = JSOp(*lir->mir()->resumePoint()->pc());
switch (jsop) {
case JSOP_BITNOT:
case JSOP_NEG:
emitSharedStub(ICStub::Kind::UnaryArith_Fallback, lir);
break;
case JSOP_CALLPROP:
case JSOP_GETPROP:
case JSOP_LENGTH:
emitSharedStub(ICStub::Kind::GetProp_Fallback, lir);
break;
default:
MOZ_CRASH("Unsupported jsop in shared stubs.");
}
}
void
@ -9957,6 +9945,11 @@ CodeGenerator::linkSharedStubs(JSContext* cx)
stub = stubCompiler.getStub(&stubSpace_);
break;
}
case ICStub::Kind::UnaryArith_Fallback: {
ICUnaryArith_Fallback::Compiler stubCompiler(cx, ICStubCompiler::Engine::IonSharedIC);
stub = stubCompiler.getStub(&stubSpace_);
break;
}
case ICStub::Kind::Compare_Fallback: {
ICCompare_Fallback::Compiler stubCompiler(cx, ICStubCompiler::Engine::IonSharedIC);
stub = stubCompiler.getStub(&stubSpace_);

View File

@ -136,7 +136,7 @@ class CodeGenerator final : public CodeGeneratorSpecific
void visitStringReplace(LStringReplace* lir);
void emitSharedStub(ICStub::Kind kind, LInstruction* lir);
void visitBinarySharedStub(LBinarySharedStub* lir);
void visitUnaryCache(LUnaryCache* lir);
void visitUnarySharedStub(LUnarySharedStub* lir);
void visitNullarySharedStub(LNullarySharedStub* lir);
void visitClassConstructor(LClassConstructor* lir);
void visitLambda(LLambda* lir);

View File

@ -3546,6 +3546,11 @@ IonBuilder::arithTrySharedStub(bool* emitted, JSOp op,
if (actualOp == JSOP_POS)
return Ok();
// FIXME: The JSOP_BITNOT path doesn't track optimizations yet.
if (actualOp != JSOP_BITNOT) {
trackOptimizationAttempt(TrackedStrategy::BinaryArith_SharedCache);
trackOptimizationSuccess();
}
MInstruction* stub = nullptr;
switch (actualOp) {
@ -3554,7 +3559,8 @@ IonBuilder::arithTrySharedStub(bool* emitted, JSOp op,
MOZ_ASSERT_IF(op == JSOP_MUL,
left->maybeConstantValue() && left->maybeConstantValue()->toInt32() == -1);
MOZ_ASSERT_IF(op != JSOP_MUL, !left);
stub = MUnaryCache::New(alloc(), right);
stub = MUnarySharedStub::New(alloc(), right);
break;
case JSOP_ADD:
case JSOP_SUB:

View File

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

View File

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

View File

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

View File

@ -2531,13 +2531,13 @@ LIRGenerator::visitBinarySharedStub(MBinarySharedStub* ins)
}
void
LIRGenerator::visitUnaryCache(MUnaryCache* ins)
LIRGenerator::visitUnarySharedStub(MUnarySharedStub* ins)
{
MDefinition* input = ins->getOperand(0);
MOZ_ASSERT(ins->type() == MIRType::Value);
LUnaryCache* lir = new(alloc()) LUnaryCache(useBox(input));
defineBox(lir, ins);
LUnarySharedStub* lir = new(alloc()) LUnarySharedStub(useBoxFixedAtStart(input, R0));
defineSharedStubReturn(lir, ins);
assignSafepoint(lir, ins);
}

View File

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

View File

@ -8231,18 +8231,18 @@ class MBinarySharedStub
TRIVIAL_NEW_WRAPPERS
};
class MUnaryCache
class MUnarySharedStub
: public MUnaryInstruction,
public BoxPolicy<0>::Data
{
explicit MUnaryCache(MDefinition* input)
explicit MUnarySharedStub(MDefinition* input)
: MUnaryInstruction(classOpcode, input)
{
setResultType(MIRType::Value);
}
public:
INSTRUCTION_HEADER(UnaryCache)
INSTRUCTION_HEADER(UnarySharedStub)
TRIVIAL_NEW_WRAPPERS
};

View File

@ -54,7 +54,7 @@ namespace jit {
_(OsrArgumentsObject) \
_(ReturnFromCtor) \
_(BinarySharedStub) \
_(UnaryCache) \
_(UnarySharedStub) \
_(NullarySharedStub) \
_(CheckOverRecursed) \
_(DefVar) \

View File

@ -1233,6 +1233,144 @@ ICBinaryArith_DoubleWithInt32::Compiler::generateStubCode(MacroAssembler& masm)
return true;
}
//
// UnaryArith_Fallback
//
static bool
DoUnaryArithFallback(JSContext* cx, void* payload, ICUnaryArith_Fallback* stub_,
HandleValue val, MutableHandleValue res)
{
SharedStubInfo info(cx, payload, stub_->icEntry());
ICStubCompiler::Engine engine = info.engine();
// This fallback stub may trigger debug mode toggling.
DebugModeOSRVolatileStub<ICUnaryArith_Fallback*> stub(engine, info.maybeFrame(), stub_);
jsbytecode* pc = info.pc();
JSOp op = JSOp(*pc);
FallbackICSpew(cx, stub, "UnaryArith(%s)", CodeName[op]);
switch (op) {
case JSOP_BITNOT: {
int32_t result;
if (!BitNot(cx, val, &result))
return false;
res.setInt32(result);
break;
}
case JSOP_NEG:
if (!NegOperation(cx, val, res))
return false;
break;
default:
MOZ_CRASH("Unexpected op");
}
// Check if debug mode toggling made the stub invalid.
if (stub.invalid())
return true;
if (res.isDouble())
stub->setSawDoubleResult();
if (stub->numOptimizedStubs() >= ICUnaryArith_Fallback::MAX_OPTIMIZED_STUBS) {
// TODO: Discard/replace stubs.
return true;
}
if (val.isInt32() && res.isInt32()) {
JitSpew(JitSpew_BaselineIC, " Generating %s(Int32 => Int32) stub", CodeName[op]);
ICUnaryArith_Int32::Compiler compiler(cx, op, engine);
ICStub* int32Stub = compiler.getStub(compiler.getStubSpace(info.outerScript(cx)));
if (!int32Stub)
return false;
stub->addNewStub(int32Stub);
return true;
}
if (val.isNumber() && res.isNumber() && cx->runtime()->jitSupportsFloatingPoint) {
JitSpew(JitSpew_BaselineIC, " Generating %s(Number => Number) stub", CodeName[op]);
// Unlink int32 stubs, the double stub handles both cases and TI specializes for both.
stub->unlinkStubsWithKind(cx, ICStub::UnaryArith_Int32);
ICUnaryArith_Double::Compiler compiler(cx, op, engine);
ICStub* doubleStub = compiler.getStub(compiler.getStubSpace(info.outerScript(cx)));
if (!doubleStub)
return false;
stub->addNewStub(doubleStub);
return true;
}
return true;
}
typedef bool (*DoUnaryArithFallbackFn)(JSContext*, void*, ICUnaryArith_Fallback*,
HandleValue, MutableHandleValue);
static const VMFunction DoUnaryArithFallbackInfo =
FunctionInfo<DoUnaryArithFallbackFn>(DoUnaryArithFallback, "DoUnaryArithFallback", TailCall,
PopValues(1));
bool
ICUnaryArith_Fallback::Compiler::generateStubCode(MacroAssembler& masm)
{
MOZ_ASSERT(R0 == JSReturnOperand);
// Restore the tail call register.
EmitRestoreTailCallReg(masm);
// Ensure stack is fully synced for the expression decompiler.
masm.pushValue(R0);
// Push arguments.
masm.pushValue(R0);
masm.push(ICStubReg);
pushStubPayload(masm, R0.scratchReg());
return tailCallVM(DoUnaryArithFallbackInfo, masm);
}
bool
ICUnaryArith_Double::Compiler::generateStubCode(MacroAssembler& masm)
{
Label failure;
masm.ensureDouble(R0, FloatReg0, &failure);
MOZ_ASSERT(op == JSOP_NEG || op == JSOP_BITNOT);
if (op == JSOP_NEG) {
masm.negateDouble(FloatReg0);
masm.boxDouble(FloatReg0, R0, FloatReg0);
} else {
// Truncate the double to an int32.
Register scratchReg = R1.scratchReg();
Label doneTruncate;
Label truncateABICall;
masm.branchTruncateDoubleMaybeModUint32(FloatReg0, scratchReg, &truncateABICall);
masm.jump(&doneTruncate);
masm.bind(&truncateABICall);
masm.setupUnalignedABICall(scratchReg);
masm.passABIArg(FloatReg0, MoveOp::DOUBLE);
masm.callWithABI(BitwiseCast<void*, int32_t(*)(double)>(JS::ToInt32),
MoveOp::GENERAL, CheckUnsafeCallWithABI::DontCheckOther);
masm.storeCallInt32Result(scratchReg);
masm.bind(&doneTruncate);
masm.not32(scratchReg);
masm.tagValue(JSVAL_TYPE_INT32, scratchReg, R0);
}
EmitReturnFromIC(masm);
// Failure case - jump to next stub
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
//
// Compare_Fallback
//

View File

@ -1914,6 +1914,94 @@ class ICBinaryArith_DoubleWithInt32 : public ICStub
};
};
// UnaryArith
// JSOP_BITNOT
// JSOP_NEG
class ICUnaryArith_Fallback : public ICFallbackStub
{
friend class ICStubSpace;
explicit ICUnaryArith_Fallback(JitCode* stubCode)
: ICFallbackStub(UnaryArith_Fallback, stubCode)
{
extra_ = 0;
}
public:
static const uint32_t MAX_OPTIMIZED_STUBS = 8;
bool sawDoubleResult() {
return extra_;
}
void setSawDoubleResult() {
extra_ = 1;
}
// Compiler for this stub kind.
class Compiler : public ICStubCompiler {
protected:
MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override;
public:
explicit Compiler(JSContext* cx, Engine engine)
: ICStubCompiler(cx, ICStub::UnaryArith_Fallback, engine)
{}
ICStub* getStub(ICStubSpace* space) override {
return newStub<ICUnaryArith_Fallback>(space, getStubCode());
}
};
};
class ICUnaryArith_Int32 : public ICStub
{
friend class ICStubSpace;
explicit ICUnaryArith_Int32(JitCode* stubCode)
: ICStub(UnaryArith_Int32, stubCode)
{}
public:
class Compiler : public ICMultiStubCompiler {
protected:
MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override;
public:
Compiler(JSContext* cx, JSOp op, Engine engine)
: ICMultiStubCompiler(cx, ICStub::UnaryArith_Int32, op, engine)
{}
ICStub* getStub(ICStubSpace* space) override {
return newStub<ICUnaryArith_Int32>(space, getStubCode());
}
};
};
class ICUnaryArith_Double : public ICStub
{
friend class ICStubSpace;
explicit ICUnaryArith_Double(JitCode* stubCode)
: ICStub(UnaryArith_Double, stubCode)
{}
public:
class Compiler : public ICMultiStubCompiler {
protected:
MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override;
public:
Compiler(JSContext* cx, JSOp op, Engine engine)
: ICMultiStubCompiler(cx, ICStub::UnaryArith_Double, op, engine)
{}
ICStub* getStub(ICStubSpace* space) override {
return newStub<ICUnaryArith_Double>(space, getStubCode());
}
};
};
// Compare
// JSOP_LT
// JSOP_LE

View File

@ -20,6 +20,10 @@ namespace jit {
_(BinaryArith_BooleanWithInt32) \
_(BinaryArith_DoubleWithInt32) \
\
_(UnaryArith_Fallback) \
_(UnaryArith_Int32) \
_(UnaryArith_Double) \
\
_(Compare_Fallback) \
_(Compare_Int32) \
_(Compare_Double) \

View File

@ -186,5 +186,33 @@ ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm)
return true;
}
bool
ICUnaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm)
{
Label failure;
masm.branchTestInt32(Assembler::NotEqual, R0, &failure);
switch (op) {
case JSOP_BITNOT:
masm.ma_mvn(R0.payloadReg(), R0.payloadReg());
break;
case JSOP_NEG:
// Guard against 0 and MIN_INT, both result in a double.
masm.branchTest32(Assembler::Zero, R0.payloadReg(), Imm32(0x7fffffff), &failure);
// Compile -x as 0 - x.
masm.as_rsb(R0.payloadReg(), R0.payloadReg(), Imm8(0));
break;
default:
MOZ_CRASH("Unexpected op");
}
EmitReturnFromIC(masm);
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
} // namespace jit
} // namespace js

View File

@ -185,5 +185,36 @@ ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm)
return true;
}
bool
ICUnaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm)
{
Label failure;
masm.branchTestInt32(Assembler::NotEqual, R0, &failure);
switch (op) {
case JSOP_BITNOT:
masm.Mvn(ARMRegister(R1.valueReg(), 32), ARMRegister(R0.valueReg(), 32));
masm.movePayload(R1.valueReg(), R0.valueReg());
break;
case JSOP_NEG:
// Guard against 0 and MIN_INT, both result in a double.
masm.branchTest32(Assembler::Zero, R0.valueReg(), Imm32(0x7fffffff), &failure);
// Compile -x as 0 - x.
masm.Sub(ARMRegister(R1.valueReg(), 32), wzr, ARMRegister(R0.valueReg(), 32));
masm.movePayload(R1.valueReg(), R0.valueReg());
break;
default:
MOZ_CRASH("Unexpected op");
}
EmitReturnFromIC(masm);
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
} // namespace jit
} // namespace js

View File

@ -143,5 +143,34 @@ ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm)
return true;
}
bool
ICUnaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm)
{
Label failure;
masm.branchTestInt32(Assembler::NotEqual, R0, &failure);
switch (op) {
case JSOP_BITNOT:
masm.not32(R0.payloadReg());
break;
case JSOP_NEG:
// Guard against 0 and MIN_INT, both result in a double.
masm.branchTest32(Assembler::Zero, R0.payloadReg(), Imm32(INT32_MAX), &failure);
masm.neg32(R0.payloadReg());
break;
default:
MOZ_CRASH("Unexpected op");
return false;
}
EmitReturnFromIC(masm);
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
} // namespace jit
} // namespace js

View File

@ -154,5 +154,37 @@ ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm)
return true;
}
bool
ICUnaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm)
{
Label failure;
masm.branchTestInt32(Assembler::NotEqual, R0, &failure);
switch (op) {
case JSOP_BITNOT:
masm.not32(R0.valueReg());
masm.tagValue(JSVAL_TYPE_INT32, R0.valueReg(), R0);
break;
case JSOP_NEG:
masm.unboxInt32(R0, ExtractTemp0);
// Guard against 0 and MIN_INT, both result in a double.
masm.branchTest32(Assembler::Zero, ExtractTemp0, Imm32(INT32_MAX), &failure);
masm.neg32(ExtractTemp0);
masm.tagValue(JSVAL_TYPE_INT32, ExtractTemp0, R0);
break;
default:
MOZ_CRASH("Unexpected op");
return false;
}
EmitReturnFromIC(masm);
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
} // namespace jit
} // namespace js

View File

@ -45,3 +45,4 @@ BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator& iter, Invalidati
bool ICCompare_Int32::Compiler::generateStubCode(MacroAssembler&) { MOZ_CRASH(); }
bool ICCompare_Double::Compiler::generateStubCode(MacroAssembler&) { MOZ_CRASH(); }
bool ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler&) { MOZ_CRASH(); }
bool ICUnaryArith_Int32::Compiler::generateStubCode(MacroAssembler&) { MOZ_CRASH(); }

View File

@ -5114,21 +5114,17 @@ class LBinarySharedStub : public LCallInstructionHelper<BOX_PIECES, 2 * BOX_PIEC
static const size_t RhsInput = BOX_PIECES;
};
class LUnaryCache : public LInstructionHelper<BOX_PIECES, BOX_PIECES, 0>
class LUnarySharedStub : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES, 0>
{
public:
LIR_HEADER(UnaryCache)
LIR_HEADER(UnarySharedStub)
explicit LUnaryCache(const LBoxAllocation& input) {
explicit LUnarySharedStub(const LBoxAllocation& input) {
setBoxOperand(Input, input);
}
const MUnaryCache* mir() const {
return mir_->toUnaryCache();
}
const LAllocation* input() {
return getOperand(Input);
const MUnarySharedStub* mir() const {
return mir_->toUnarySharedStub();
}
static const size_t Input = 0;

View File

@ -244,7 +244,7 @@
_(StringReplace) \
_(Substr) \
_(BinarySharedStub) \
_(UnaryCache) \
_(UnarySharedStub) \
_(NullarySharedStub) \
_(ClassConstructor) \
_(Lambda) \

View File

@ -210,7 +210,7 @@ LIRGeneratorShared::defineSharedStubReturn(LInstruction* lir, MDefinition* mir)
{
lir->setMir(mir);
MOZ_ASSERT(lir->isBinarySharedStub() || lir->isNullarySharedStub());
MOZ_ASSERT(lir->isBinarySharedStub() || lir->isUnarySharedStub() || lir->isNullarySharedStub());
MOZ_ASSERT(mir->type() == MIRType::Value);
uint32_t vreg = getVirtualRegister();

View File

@ -202,5 +202,33 @@ ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm)
return true;
}
bool
ICUnaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm)
{
Label failure;
masm.branchTestInt32(Assembler::NotEqual, R0, &failure);
switch (op) {
case JSOP_BITNOT:
masm.notl(R0.valueReg());
break;
case JSOP_NEG:
// Guard against 0 and MIN_INT, both result in a double.
masm.branchTest32(Assembler::Zero, R0.valueReg(), Imm32(0x7fffffff), &failure);
masm.negl(R0.valueReg());
break;
default:
MOZ_CRASH("Unexpected op");
}
masm.tagValue(JSVAL_TYPE_INT32, R0.valueReg(), R0);
EmitReturnFromIC(masm);
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
} // namespace jit
} // namespace js

View File

@ -212,5 +212,31 @@ ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm)
return true;
}
bool
ICUnaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm)
{
Label failure;
masm.branchTestInt32(Assembler::NotEqual, R0, &failure);
switch (op) {
case JSOP_BITNOT:
masm.notl(R0.payloadReg());
break;
case JSOP_NEG:
// Guard against 0 and MIN_INT, both result in a double.
masm.branchTest32(Assembler::Zero, R0.payloadReg(), Imm32(0x7fffffff), &failure);
masm.negl(R0.payloadReg());
break;
default:
MOZ_CRASH("Unexpected op");
}
EmitReturnFromIC(masm);
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
} // namespace jit
} // namespace js

View File

@ -5231,15 +5231,21 @@ AddCanvasBackgroundColor(const nsDisplayList& aList, nsIFrame* aCanvasFrame,
nscolor aColor, bool aCSSBackgroundColor)
{
for (nsDisplayItem* i = aList.GetBottom(); i; i = i->GetAbove()) {
const DisplayItemType type = i->GetType();
if (i->Frame() == aCanvasFrame &&
i->GetType() == DisplayItemType::TYPE_CANVAS_BACKGROUND_COLOR) {
type == DisplayItemType::TYPE_CANVAS_BACKGROUND_COLOR) {
nsDisplayCanvasBackgroundColor* bg = static_cast<nsDisplayCanvasBackgroundColor*>(i);
bg->SetExtraBackgroundColor(aColor);
return true;
}
const bool isBlendContainer =
type == DisplayItemType::TYPE_BLEND_CONTAINER ||
type == DisplayItemType::TYPE_TABLE_BLEND_CONTAINER;
nsDisplayList* sublist = i->GetSameCoordinateSystemChildren();
if (sublist &&
!(i->GetType() == DisplayItemType::TYPE_BLEND_CONTAINER && !aCSSBackgroundColor) &&
if (sublist && !(isBlendContainer && !aCSSBackgroundColor) &&
AddCanvasBackgroundColor(*sublist, aCanvasFrame, aColor, aCSSBackgroundColor))
return true;
}

View File

@ -9,7 +9,9 @@ DECLARE_DISPLAY_ITEM_TYPE(BACKGROUND, 0)
DECLARE_DISPLAY_ITEM_TYPE(THEMED_BACKGROUND, TYPE_RENDERS_NO_IMAGES)
DECLARE_DISPLAY_ITEM_TYPE(BACKGROUND_COLOR, TYPE_RENDERS_NO_IMAGES)
DECLARE_DISPLAY_ITEM_TYPE(BLEND_CONTAINER, TYPE_RENDERS_NO_IMAGES)
DECLARE_DISPLAY_ITEM_TYPE(TABLE_BLEND_CONTAINER, TYPE_RENDERS_NO_IMAGES)
DECLARE_DISPLAY_ITEM_TYPE(BLEND_MODE, TYPE_RENDERS_NO_IMAGES)
DECLARE_DISPLAY_ITEM_TYPE(TABLE_BLEND_MODE, TYPE_RENDERS_NO_IMAGES)
DECLARE_DISPLAY_ITEM_TYPE(BORDER, 0)
DECLARE_DISPLAY_ITEM_TYPE(BOX_SHADOW_OUTER, TYPE_RENDERS_NO_IMAGES)
DECLARE_DISPLAY_ITEM_TYPE(BOX_SHADOW_INNER, TYPE_RENDERS_NO_IMAGES)
@ -59,12 +61,14 @@ DECLARE_DISPLAY_ITEM_TYPE(FILTER, TYPE_RENDERS_NO_IMAGES)
DECLARE_DISPLAY_ITEM_TYPE(SVG_OUTER_SVG, TYPE_RENDERS_NO_IMAGES)
DECLARE_DISPLAY_ITEM_TYPE(SVG_GEOMETRY, 0)
DECLARE_DISPLAY_ITEM_TYPE(SVG_TEXT, 0)
DECLARE_DISPLAY_ITEM_TYPE(SVG_CHAR_CLIP, TYPE_RENDERS_NO_IMAGES)
DECLARE_DISPLAY_ITEM_TYPE(SVG_WRAPPER, TYPE_RENDERS_NO_IMAGES)
DECLARE_DISPLAY_ITEM_TYPE(TABLE_CELL_BACKGROUND, 0)
DECLARE_DISPLAY_ITEM_TYPE(TABLE_CELL_SELECTION, TYPE_RENDERS_NO_IMAGES)
DECLARE_DISPLAY_ITEM_TYPE(TABLE_BORDER_COLLAPSE, 0)
DECLARE_DISPLAY_ITEM_TYPE(TABLE_BACKGROUND_COLOR, TYPE_RENDERS_NO_IMAGES)
DECLARE_DISPLAY_ITEM_TYPE(TABLE_BACKGROUND_IMAGE, 0)
DECLARE_DISPLAY_ITEM_TYPE(TABLE_THEMED_BACKGROUND_IMAGE, 0)
DECLARE_DISPLAY_ITEM_TYPE(TABLE_FIXED_POSITION, TYPE_RENDERS_NO_IMAGES)
DECLARE_DISPLAY_ITEM_TYPE(TEXT, TYPE_RENDERS_NO_IMAGES)
DECLARE_DISPLAY_ITEM_TYPE(TEXT_OVERFLOW, TYPE_RENDERS_NO_IMAGES)

View File

@ -1572,8 +1572,8 @@ nsDisplayListBuilder::Allocate(size_t aSize, DisplayItemType aType)
size_t roundedUpSize = RoundUpPow2(aSize);
uint_fast8_t type = FloorLog2Size(roundedUpSize);
MOZ_ASSERT(gDisplayItemSizes[static_cast<uint32_t>(aType)] == type ||
gDisplayItemSizes[static_cast<uint32_t>(aType)] == 0);
MOZ_RELEASE_ASSERT(gDisplayItemSizes[static_cast<uint32_t>(aType)] == type ||
gDisplayItemSizes[static_cast<uint32_t>(aType)] == 0);
gDisplayItemSizes[static_cast<uint32_t>(aType)] = type;
return mPool.AllocateByCustomID(type, roundedUpSize);
}
@ -6368,7 +6368,9 @@ RequiredLayerStateForChildren(nsDisplayListBuilder* aBuilder,
}
LayerState state = i->GetLayerState(aBuilder, aManager, aParameters);
if (state == LAYER_ACTIVE && i->GetType() == DisplayItemType::TYPE_BLEND_MODE) {
if (state == LAYER_ACTIVE &&
(i->GetType() == DisplayItemType::TYPE_BLEND_MODE ||
i->GetType() == DisplayItemType::TYPE_TABLE_BLEND_MODE)) {
// nsDisplayBlendMode always returns LAYER_ACTIVE to ensure that the
// blending operation happens in the intermediate surface of its parent
// display item (usually an nsDisplayBlendContainer). But this does not

View File

@ -4136,7 +4136,7 @@ public:
virtual nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
NS_DISPLAY_DECL_NAME("TableThemedBackground", TYPE_TABLE_BACKGROUND_IMAGE)
NS_DISPLAY_DECL_NAME("TableThemedBackground", TYPE_TABLE_THEMED_BACKGROUND_IMAGE)
protected:
virtual nsIFrame* StyleFrame() const override { return mAncestorFrame; }
nsIFrame* mAncestorFrame;
@ -5259,7 +5259,7 @@ public:
nsDisplayItem::GetPerFrameKey();
}
NS_DISPLAY_DECL_NAME("BlendMode", TYPE_BLEND_MODE)
NS_DISPLAY_DECL_NAME("TableBlendMode", TYPE_TABLE_BLEND_MODE)
protected:
nsIFrame* mAncestorFrame;
@ -5354,7 +5354,7 @@ public:
nsDisplayItem::GetPerFrameKey();
}
NS_DISPLAY_DECL_NAME("BlendContainer", TYPE_BLEND_CONTAINER)
NS_DISPLAY_DECL_NAME("TableBlendContainer", TYPE_TABLE_BLEND_CONTAINER)
protected:
nsDisplayTableBlendContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
@ -6680,7 +6680,8 @@ public:
static nsCharClipDisplayItem* CheckCast(nsDisplayItem* aItem) {
DisplayItemType t = aItem->GetType();
return (t == DisplayItemType::TYPE_TEXT)
return (t == DisplayItemType::TYPE_TEXT ||
t == DisplayItemType::TYPE_SVG_CHAR_CLIP)
? static_cast<nsCharClipDisplayItem*>(aItem) : nullptr;
}

View File

@ -2733,7 +2733,7 @@ public:
aRun.GetClipEdges(mVisIStartEdge, mVisIEndEdge);
}
NS_DISPLAY_DECL_NAME("SVGText", TYPE_TEXT)
NS_DISPLAY_DECL_NAME("SVGCharClip", TYPE_SVG_CHAR_CLIP)
};
// -----------------------------------------------------------------------------

View File

@ -249,6 +249,9 @@ void
nsHttpConnection::Start0RTTSpdy(uint8_t spdyVersion)
{
LOG(("nsHttpConnection::Start0RTTSpdy [this=%p]", this));
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
mDid0RTTSpdy = true;
mUsingSpdyVersion = spdyVersion;
mSpdySession = ASpdySession::NewSpdySession(spdyVersion, mSocketTransport,
@ -277,6 +280,7 @@ nsHttpConnection::StartSpdy(uint8_t spdyVersion)
{
LOG(("nsHttpConnection::StartSpdy [this=%p, mDid0RTTSpdy=%d]\n", this, mDid0RTTSpdy));
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
MOZ_ASSERT(!mSpdySession || mDid0RTTSpdy);
mUsingSpdyVersion = spdyVersion;
@ -2444,6 +2448,7 @@ nsAHttpTransaction *
nsHttpConnection::CloseConnectionFastOpenTakesTooLongOrError(bool aCloseSocketTransport)
{
MOZ_ASSERT(!mCurrentBytesRead);
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
mFastOpenStatus = TFO_FAILED;
RefPtr<nsAHttpTransaction> trans;

View File

@ -4703,10 +4703,15 @@ void
nsHttpConnectionMgr::
nsHalfOpenSocket::SetFastOpenStatus(uint8_t tfoStatus)
{
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
MOZ_ASSERT(mFastOpenInProgress);
mFastOpenStatus = tfoStatus;
mConnectionNegotiatingFastOpen->SetFastOpenStatus(tfoStatus);
mConnectionNegotiatingFastOpen->Transaction()->SetFastOpenStatus(tfoStatus);
if (mConnectionNegotiatingFastOpen->Transaction()) {
// The transaction could already be canceled in the meantime, hence nullified.
mConnectionNegotiatingFastOpen->Transaction()->SetFastOpenStatus(tfoStatus);
}
}
void