CacheIR nursery changes.

CacheIR nursery changes.
This commit is contained in:
win7-7 2026-01-11 00:19:59 +02:00 committed by wuggy
commit d8d6e3aa8a
3 changed files with 166 additions and 7 deletions

View file

@ -1175,8 +1175,7 @@ BaselineCacheIRCompiler::emitStoreTypedObjectReferenceProperty()
emitStoreTypedObjectReferenceProp(val, type, dest, scratch2);
if (type != ReferenceTypeDescr::TYPE_STRING)
emitPostBarrierSlot(obj, val, scratch1);
emitPostBarrierSlot(obj, val, scratch1);
return true;
}

View file

@ -4738,6 +4738,163 @@ BaselineCompiler::emit_JSOP_JUMPTARGET()
return true;
}
typedef bool (*CheckClassHeritageOperationFn)(JSContext*, HandleValue);
static const VMFunction CheckClassHeritageOperationInfo =
FunctionInfo<CheckClassHeritageOperationFn>(js::CheckClassHeritageOperation,
"CheckClassHeritageOperation");
bool
BaselineCompiler::emit_JSOP_CHECKCLASSHERITAGE()
{
frame.syncStack(0);
// Leave the heritage value on the stack.
masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0);
prepareVMCall();
pushArg(R0);
return callVM(CheckClassHeritageOperationInfo);
}
bool
BaselineCompiler::emit_JSOP_INITHOMEOBJECT()
{
frame.syncStack(0);
// Load HomeObject off stack
unsigned skipOver = GET_UINT8(pc);
MOZ_ASSERT(frame.stackDepth() >= skipOver + 2);
masm.loadValue(frame.addressOfStackValue(frame.peek(-2 - skipOver)), R0);
// Load function off stack
Register func = R2.scratchReg();
masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), func);
// Set HOMEOBJECT_SLOT
Address addr(func, FunctionExtended::offsetOfMethodHomeObjectSlot());
#ifdef DEBUG
Label isUndefined;
masm.branchTestUndefined(Assembler::Equal, addr, &isUndefined);
masm.assumeUnreachable("INITHOMEOBJECT expects undefined slot");
masm.bind(&isUndefined);
#endif
masm.storeValue(R0, addr);
Register temp = R1.scratchReg();
Label skipBarrier;
masm.branchPtrInNurseryChunk(Assembler::Equal, func, temp, &skipBarrier);
masm.branchValueIsNurseryCell(Assembler::NotEqual, R0, temp, &skipBarrier);
masm.call(&postBarrierSlot_);
masm.bind(&skipBarrier);
return true;
}
bool
BaselineCompiler::emit_JSOP_BUILTINPROTO()
{
// The builtin prototype is a constant for a given global.
RootedObject builtin(cx);
JSProtoKey key = static_cast<JSProtoKey>(GET_UINT8(pc));
MOZ_ASSERT(key < JSProto_LIMIT);
if (!GetBuiltinPrototype(cx, key, &builtin))
return false;
frame.push(ObjectValue(*builtin));
return true;
}
typedef JSObject* (*ObjectWithProtoOperationFn)(JSContext*, HandleValue);
static const VMFunction ObjectWithProtoOperationInfo =
FunctionInfo<ObjectWithProtoOperationFn>(js::ObjectWithProtoOperation,
"ObjectWithProtoOperationInfo");
bool
BaselineCompiler::emit_JSOP_OBJWITHPROTO()
{
frame.syncStack(0);
// Leave the proto value on the stack for the decompiler
masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0);
prepareVMCall();
pushArg(R0);
if (!callVM(ObjectWithProtoOperationInfo))
return false;
masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
frame.pop();
frame.push(R0);
return true;
}
typedef JSObject* (*FunWithProtoFn)(JSContext*, HandleFunction, HandleObject, HandleObject);
static const VMFunction FunWithProtoInfo =
FunctionInfo<FunWithProtoFn>(js::FunWithProtoOperation, "FunWithProtoOperation");
bool
BaselineCompiler::emit_JSOP_FUNWITHPROTO()
{
frame.popRegsAndSync(1);
masm.unboxObject(R0, R0.scratchReg());
masm.loadPtr(frame.addressOfEnvironmentChain(), R1.scratchReg());
prepareVMCall();
pushArg(R0.scratchReg());
pushArg(R1.scratchReg());
pushArg(ImmGCPtr(script->getFunction(GET_UINT32_INDEX(pc))));
if (!callVM(FunWithProtoInfo))
return false;
masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
frame.push(R0);
return true;
}
typedef JSFunction* (*MakeDefaultConstructorFn)(JSContext*, HandleScript,
jsbytecode*, HandleObject);
static const VMFunction MakeDefaultConstructorInfo =
FunctionInfo<MakeDefaultConstructorFn>(js::MakeDefaultConstructor,
"MakeDefaultConstructor");
bool
BaselineCompiler::emit_JSOP_CLASSCONSTRUCTOR()
{
frame.syncStack(0);
// Pass nullptr as prototype to MakeDefaultConstructor
prepareVMCall();
pushArg(ImmPtr(nullptr));
pushArg(ImmPtr(pc));
pushArg(ImmGCPtr(script));
if (!callVM(MakeDefaultConstructorInfo))
return false;
masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
frame.push(R0);
return true;
}
bool
BaselineCompiler::emit_JSOP_DERIVEDCONSTRUCTOR()
{
frame.popRegsAndSync(1);
masm.unboxObject(R0, R0.scratchReg());
prepareVMCall();
pushArg(R0.scratchReg());
pushArg(ImmPtr(pc));
pushArg(ImmGCPtr(script));
if (!callVM(MakeDefaultConstructorInfo))
return false;
masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
frame.push(R0);
return true;
}
typedef JSObject* (*GetOrCreateModuleMetaObjectFn)(JSContext*, HandleObject);
static const VMFunction GetOrCreateModuleMetaObjectInfo =
FunctionInfo<GetOrCreateModuleMetaObjectFn>(js::GetOrCreateModuleMetaObject,

View file

@ -2238,6 +2238,8 @@ void
CacheIRCompiler::emitStoreTypedObjectReferenceProp(ValueOperand val, ReferenceTypeDescr::Type type,
const Address& dest, Register scratch)
{
// Callers will post-barrier this store.
switch (type) {
case ReferenceTypeDescr::TYPE_ANY:
EmitPreBarrier(masm, dest, MIRType::Value);
@ -2273,18 +2275,19 @@ CacheIRCompiler::emitPostBarrierShared(Register obj, const ConstantOrRegister& v
return;
if (val.constant()) {
MOZ_ASSERT_IF(val.value().isObject(), !IsInsideNursery(&val.value().toObject()));
MOZ_ASSERT_IF(val.value().isGCThing(), !IsInsideNursery(val.value().toGCThing()));
return;
}
TypedOrValueRegister reg = val.reg();
if (reg.hasTyped() && reg.type() != MIRType::Object)
return;
if (reg.hasTyped()) {
if (reg.type() != MIRType::Object && reg.type() != MIRType::String)
return;
}
Label skipBarrier;
if (reg.hasValue()) {
masm.branchValueIsNurseryObject(Assembler::NotEqual, reg.valueReg(), scratch,
&skipBarrier);
masm.branchValueIsNurseryCell(Assembler::NotEqual, reg.valueReg(), scratch, &skipBarrier);
} else {
masm.branchPtrInNurseryChunk(Assembler::NotEqual, reg.typedReg().gpr(), scratch,
&skipBarrier);