Bug 1629791 part 12 - Auto-generate boilerplate for more ops. r=evilpie

Differential Revision: https://phabricator.services.mozilla.com/D71320
This commit is contained in:
Jan de Mooij 2020-04-18 00:23:47 +00:00
Родитель da23affa12
Коммит d24b36ece1
7 изменённых файлов: 113 добавлений и 147 удалений

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

@ -1303,10 +1303,9 @@ bool BaselineCacheIRCompiler::emitStoreDenseElementHole(ObjOperandId objId,
return true;
}
bool BaselineCacheIRCompiler::emitArrayPush() {
bool BaselineCacheIRCompiler::emitArrayPush(ObjOperandId objId,
ValOperandId rhsId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
ObjOperandId objId = reader.objOperandId();
ValOperandId rhsId = reader.valOperandId();
// Allocate the fixed registers first. These need to be fixed for
// callTypeUpdateIC.
@ -1417,11 +1416,13 @@ bool BaselineCacheIRCompiler::emitArrayPush() {
return true;
}
bool BaselineCacheIRCompiler::emitCallNativeSetter() {
bool BaselineCacheIRCompiler::emitCallNativeSetter(ObjOperandId objId,
uint32_t setterOffset,
ValOperandId rhsId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
Register obj = allocator.useRegister(masm, reader.objOperandId());
Address setterAddr(stubAddress(reader.stubOffset()));
ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
Register obj = allocator.useRegister(masm, objId);
Address setterAddr(stubAddress(setterOffset));
ValueOperand val = allocator.useValueRegister(masm, rhsId);
AutoScratchRegister scratch(allocator, masm);
@ -1444,15 +1445,17 @@ bool BaselineCacheIRCompiler::emitCallNativeSetter() {
return true;
}
bool BaselineCacheIRCompiler::emitCallScriptedSetter() {
bool BaselineCacheIRCompiler::emitCallScriptedSetter(ObjOperandId objId,
uint32_t setterOffset,
ValOperandId rhsId,
bool sameRealm) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
AutoScratchRegister scratch1(allocator, masm);
AutoScratchRegister scratch2(allocator, masm);
Register obj = allocator.useRegister(masm, reader.objOperandId());
Address setterAddr(stubAddress(reader.stubOffset()));
ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
bool isSameRealm = reader.readBool();
Register obj = allocator.useRegister(masm, objId);
Address setterAddr(stubAddress(setterOffset));
ValueOperand val = allocator.useValueRegister(masm, rhsId);
// First, load the callee in scratch1.
masm.loadPtr(setterAddr, scratch1);
@ -1462,7 +1465,7 @@ bool BaselineCacheIRCompiler::emitCallScriptedSetter() {
AutoStubFrame stubFrame(*this);
stubFrame.enter(masm, scratch2);
if (!isSameRealm) {
if (!sameRealm) {
masm.switchToObjectRealm(scratch1, scratch2);
}
@ -1506,18 +1509,19 @@ bool BaselineCacheIRCompiler::emitCallScriptedSetter() {
stubFrame.leave(masm, true);
if (!isSameRealm) {
if (!sameRealm) {
masm.switchToBaselineFrameRealm(R1.scratchReg());
}
return true;
}
bool BaselineCacheIRCompiler::emitCallSetArrayLength() {
bool BaselineCacheIRCompiler::emitCallSetArrayLength(ObjOperandId objId,
bool strict,
ValOperandId rhsId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
Register obj = allocator.useRegister(masm, reader.objOperandId());
bool strict = reader.readBool();
ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
Register obj = allocator.useRegister(masm, objId);
ValueOperand val = allocator.useValueRegister(masm, rhsId);
AutoScratchRegister scratch(allocator, masm);
@ -1537,12 +1541,14 @@ bool BaselineCacheIRCompiler::emitCallSetArrayLength() {
return true;
}
bool BaselineCacheIRCompiler::emitCallProxySet() {
bool BaselineCacheIRCompiler::emitCallProxySet(ObjOperandId objId,
uint32_t idOffset,
ValOperandId rhsId,
bool strict) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
Register obj = allocator.useRegister(masm, reader.objOperandId());
ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
Address idAddr(stubAddress(reader.stubOffset()));
bool strict = reader.readBool();
Register obj = allocator.useRegister(masm, objId);
ValueOperand val = allocator.useValueRegister(masm, rhsId);
Address idAddr(stubAddress(idOffset));
AutoScratchRegister scratch(allocator, masm);
@ -1566,12 +1572,14 @@ bool BaselineCacheIRCompiler::emitCallProxySet() {
return true;
}
bool BaselineCacheIRCompiler::emitCallProxySetByValue() {
bool BaselineCacheIRCompiler::emitCallProxySetByValue(ObjOperandId objId,
ValOperandId idId,
ValOperandId rhsId,
bool strict) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
Register obj = allocator.useRegister(masm, reader.objOperandId());
ValueOperand idVal = allocator.useValueRegister(masm, reader.valOperandId());
ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
bool strict = reader.readBool();
Register obj = allocator.useRegister(masm, objId);
ValueOperand idVal = allocator.useValueRegister(masm, idId);
ValueOperand val = allocator.useValueRegister(masm, rhsId);
allocator.discardStack(masm);
@ -1600,12 +1608,12 @@ bool BaselineCacheIRCompiler::emitCallProxySetByValue() {
return true;
}
bool BaselineCacheIRCompiler::emitCallAddOrUpdateSparseElementHelper() {
bool BaselineCacheIRCompiler::emitCallAddOrUpdateSparseElementHelper(
ObjOperandId objId, Int32OperandId idId, ValOperandId rhsId, bool strict) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
Register obj = allocator.useRegister(masm, reader.objOperandId());
Register id = allocator.useRegister(masm, reader.int32OperandId());
ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
bool strict = reader.readBool();
Register obj = allocator.useRegister(masm, objId);
Register id = allocator.useRegister(masm, idId);
ValueOperand val = allocator.useValueRegister(masm, rhsId);
AutoScratchRegister scratch(allocator, masm);
allocator.discardStack(masm);
@ -2770,16 +2778,17 @@ void BaselineCacheIRCompiler::updateReturnValue() {
masm.bind(&skipThisReplace);
}
bool BaselineCacheIRCompiler::emitCallScriptedFunction() {
bool BaselineCacheIRCompiler::emitCallScriptedFunction(ObjOperandId calleeId,
Int32OperandId argcId,
CallFlags flags) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
AutoOutputRegister output(*this);
AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
AutoScratchRegister scratch2(allocator, masm);
Register calleeReg = allocator.useRegister(masm, reader.objOperandId());
Register argcReg = allocator.useRegister(masm, reader.int32OperandId());
Register calleeReg = allocator.useRegister(masm, calleeId);
Register argcReg = allocator.useRegister(masm, argcId);
CallFlags flags = reader.callFlags();
bool isConstructing = flags.isConstructing();
bool isSameRealm = flags.isSameRealm();

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

@ -3619,9 +3619,10 @@ static bool CanAttachSetter(JSContext* cx, jsbytecode* pc, HandleObject obj,
return true;
}
static void EmitCallSetterNoGuards(CacheIRWriter& writer, JSObject* obj,
JSObject* holder, Shape* shape,
ObjOperandId objId, ValOperandId rhsId) {
static void EmitCallSetterNoGuards(JSContext* cx, CacheIRWriter& writer,
JSObject* obj, JSObject* holder,
Shape* shape, ObjOperandId objId,
ValOperandId rhsId) {
if (IsCacheableSetPropCallNative(obj, holder, shape)) {
JSFunction* target = &shape->setterValue().toObject().as<JSFunction>();
MOZ_ASSERT(target->isBuiltinNative());
@ -3634,7 +3635,8 @@ static void EmitCallSetterNoGuards(CacheIRWriter& writer, JSObject* obj,
JSFunction* target = &shape->setterValue().toObject().as<JSFunction>();
MOZ_ASSERT(target->hasJitEntry());
writer.callScriptedSetter(objId, target, rhsId);
bool sameRealm = cx->realm() == target->realm();
writer.callScriptedSetter(objId, target, rhsId, sameRealm);
writer.returnFromIC();
}
@ -3670,7 +3672,7 @@ AttachDecision SetPropIRGenerator::tryAttachSetter(HandleObject obj,
writer.guardHasGetterSetter(objId, propShape);
}
EmitCallSetterNoGuards(writer, obj, holder, propShape, objId, rhsId);
EmitCallSetterNoGuards(cx_, writer, obj, holder, propShape, objId, rhsId);
trackAttached("Setter");
return AttachDecision::Attach;
@ -4119,7 +4121,7 @@ AttachDecision SetPropIRGenerator::tryAttachDOMProxyUnshadowed(
// EmitCallSetterNoGuards expects |obj| to be the object the property is
// on to do some checks. Since we actually looked at proto, and no extra
// guards will be generated, we can just pass that instead.
EmitCallSetterNoGuards(writer, proto, holder, propShape, objId, rhsId);
EmitCallSetterNoGuards(cx_, writer, proto, holder, propShape, objId, rhsId);
trackAttached("DOMProxyUnshadowed");
return AttachDecision::Attach;
@ -4171,8 +4173,8 @@ AttachDecision SetPropIRGenerator::tryAttachDOMProxyExpando(
guardDOMProxyExpandoObjectAndShape(obj, objId, expandoVal, expandoObj);
MOZ_ASSERT(holder == expandoObj);
EmitCallSetterNoGuards(writer, expandoObj, expandoObj, propShape, objId,
rhsId);
EmitCallSetterNoGuards(cx_, writer, expandoObj, expandoObj, propShape,
objId, rhsId);
trackAttached("DOMProxyExpandoSetter");
return AttachDecision::Attach;
}

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

@ -568,6 +568,9 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter {
void writeRawPointerField(const void* ptr) {
addStubField(uintptr_t(ptr), StubField::Type::RawWord);
}
void writeIdField(jsid id) {
addStubField(uintptr_t(JSID_BITS(id)), StubField::Type::Id);
}
void writeJSOpImm(JSOp op) {
static_assert(sizeof(JSOp) == sizeof(uint8_t), "JSOp must fit in a byte");
@ -1011,59 +1014,6 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter {
buffer_.writeByte(uint32_t(handleOOB));
}
void arrayPush(ObjOperandId obj, ValOperandId rhs) {
writeOpWithOperandId(CacheOp::ArrayPush, obj);
writeOperandId(rhs);
}
void arrayJoinResult(ObjOperandId obj) {
writeOpWithOperandId(CacheOp::ArrayJoinResult, obj);
}
void callScriptedSetter(ObjOperandId obj, JSFunction* setter,
ValOperandId rhs) {
writeOpWithOperandId(CacheOp::CallScriptedSetter, obj);
addStubField(uintptr_t(setter), StubField::Type::JSObject);
writeOperandId(rhs);
buffer_.writeByte(cx_->realm() == setter->realm());
}
void callNativeSetter(ObjOperandId obj, JSFunction* setter,
ValOperandId rhs) {
writeOpWithOperandId(CacheOp::CallNativeSetter, obj);
addStubField(uintptr_t(setter), StubField::Type::JSObject);
writeOperandId(rhs);
}
void callSetArrayLength(ObjOperandId obj, bool strict, ValOperandId rhs) {
writeOpWithOperandId(CacheOp::CallSetArrayLength, obj);
buffer_.writeByte(uint32_t(strict));
writeOperandId(rhs);
}
void callProxySet(ObjOperandId obj, jsid id, ValOperandId rhs, bool strict) {
writeOpWithOperandId(CacheOp::CallProxySet, obj);
writeOperandId(rhs);
addStubField(uintptr_t(JSID_BITS(id)), StubField::Type::Id);
buffer_.writeByte(uint32_t(strict));
}
void callProxySetByValue(ObjOperandId obj, ValOperandId id, ValOperandId rhs,
bool strict) {
writeOpWithOperandId(CacheOp::CallProxySetByValue, obj);
writeOperandId(id);
writeOperandId(rhs);
buffer_.writeByte(uint32_t(strict));
}
void callAddOrUpdateSparseElementHelper(ObjOperandId obj, Int32OperandId id,
ValOperandId rhs, bool strict) {
writeOpWithOperandId(CacheOp::CallAddOrUpdateSparseElementHelper, obj);
writeOperandId(id);
writeOperandId(rhs);
buffer_.writeByte(uint32_t(strict));
}
StringOperandId callInt32ToString(Int32OperandId id) {
StringOperandId res(nextOperandId_++);
writeOpWithOperandId(CacheOp::CallInt32ToString, id);
@ -1085,13 +1035,6 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter {
return res;
}
void callScriptedFunction(ObjOperandId calleeId, Int32OperandId argc,
CallFlags flags) {
writeOpWithOperandId(CacheOp::CallScriptedFunction, calleeId);
writeOperandId(argc);
writeCallFlagsImm(flags);
}
void callNativeFunction(ObjOperandId calleeId, Int32OperandId argc, JSOp op,
HandleFunction calleeFunc, CallFlags flags) {
writeOpWithOperandId(CacheOp::CallNativeFunction, calleeId);

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

@ -3607,9 +3607,8 @@ bool CacheIRCompiler::emitLoadDenseElementHoleExistsResult() {
return true;
}
bool CacheIRCompiler::emitArrayJoinResult() {
bool CacheIRCompiler::emitArrayJoinResult(ObjOperandId objId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
ObjOperandId objId = reader.objOperandId();
AutoOutputRegister output(*this);
Register obj = allocator.useRegister(masm, objId);

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

@ -603,12 +603,14 @@
- name: ArrayPush
shared: false
gen_boilerplate: true
operands:
obj: ObjId
rhs: ValId
- name: ArrayJoinResult
shared: true
gen_boilerplate: true
operands:
obj: ObjId
@ -624,6 +626,7 @@
- name: CallNativeSetter
shared: false
gen_boilerplate: true
operands:
obj: ObjId
setter: ObjectField
@ -631,6 +634,7 @@
- name: CallScriptedSetter
shared: false
gen_boilerplate: true
operands:
obj: ObjId
setter: ObjectField
@ -639,6 +643,7 @@
- name: CallSetArrayLength
shared: false
gen_boilerplate: true
operands:
obj: ObjId
strict: BoolImm
@ -646,14 +651,16 @@
- name: CallProxySet
shared: false
gen_boilerplate: true
operands:
obj: ObjId
rhs: ValId
id: IdField
rhs: ValId
strict: BoolImm
- name: CallProxySetByValue
shared: false
gen_boilerplate: true
operands:
obj: ObjId
id: ValId
@ -662,6 +669,7 @@
- name: CallAddOrUpdateSparseElementHelper
shared: false
gen_boilerplate: true
operands:
obj: ObjId
id: Int32Id
@ -688,6 +696,7 @@
- name: CallScriptedFunction
shared: false
gen_boilerplate: true
operands:
callee: ObjId
argc: Int32Id

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

@ -74,6 +74,7 @@ operand_writer_info = {
'SymbolField': ('JS::Symbol*', 'writeSymbolField'),
'RawWordField': ('uintptr_t', 'writeRawWordField'),
'RawPointerField': ('const void*', 'writeRawPointerField'),
'IdField': ('jsid', 'writeIdField'),
'JSOpImm': ('JSOp', 'writeJSOpImm'),
'BoolImm': ('bool', 'writeBoolImm'),
@ -136,6 +137,7 @@ operand_compiler_info = {
'SymbolField': ('uint32_t', 'Offset', 'reader.stubOffset()'),
'RawWordField': ('uint32_t', 'Offset', 'reader.stubOffset()'),
'RawPointerField': ('uint32_t', 'Offset', 'reader.stubOffset()'),
'IdField': ('uint32_t', 'Offset', 'reader.stubOffset()'),
'JSOpImm': ('JSOp', '', 'reader.jsop()'),
'BoolImm': ('bool', '', 'reader.readBool()'),

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

@ -1803,20 +1803,21 @@ bool IonCacheIRCompiler::emitStoreDenseElementHole(ObjOperandId objId,
return true;
}
bool IonCacheIRCompiler::emitArrayPush() {
bool IonCacheIRCompiler::emitArrayPush(ObjOperandId objId, ValOperandId rhsId) {
MOZ_ASSERT_UNREACHABLE("emitArrayPush not supported for IonCaches.");
return false;
}
bool IonCacheIRCompiler::emitCallNativeSetter() {
bool IonCacheIRCompiler::emitCallNativeSetter(ObjOperandId objId,
uint32_t setterOffset,
ValOperandId rhsId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
AutoSaveLiveRegisters save(*this);
Register obj = allocator.useRegister(masm, reader.objOperandId());
JSFunction* target = &objectStubField(reader.stubOffset())->as<JSFunction>();
Register obj = allocator.useRegister(masm, objId);
JSFunction* target = &objectStubField(setterOffset)->as<JSFunction>();
MOZ_ASSERT(target->isNative());
ConstantOrRegister val =
allocator.useConstantOrRegister(masm, reader.valOperandId());
ConstantOrRegister val = allocator.useConstantOrRegister(masm, rhsId);
AutoScratchRegister argJSContext(allocator, masm);
AutoScratchRegister argVp(allocator, masm);
@ -1874,17 +1875,18 @@ bool IonCacheIRCompiler::emitCallNativeSetter() {
return true;
}
bool IonCacheIRCompiler::emitCallScriptedSetter() {
bool IonCacheIRCompiler::emitCallScriptedSetter(ObjOperandId objId,
uint32_t setterOffset,
ValOperandId rhsId,
bool sameRealm) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
AutoSaveLiveRegisters save(*this);
Register obj = allocator.useRegister(masm, reader.objOperandId());
JSFunction* target = &objectStubField(reader.stubOffset())->as<JSFunction>();
ConstantOrRegister val =
allocator.useConstantOrRegister(masm, reader.valOperandId());
Register obj = allocator.useRegister(masm, objId);
JSFunction* target = &objectStubField(setterOffset)->as<JSFunction>();
ConstantOrRegister val = allocator.useConstantOrRegister(masm, rhsId);
bool isSameRealm = reader.readBool();
MOZ_ASSERT(isSameRealm == (cx_->realm() == target->realm()));
MOZ_ASSERT(sameRealm == (cx_->realm() == target->realm()));
AutoScratchRegister scratch(allocator, masm);
@ -1916,7 +1918,7 @@ bool IonCacheIRCompiler::emitCallScriptedSetter() {
masm.Push(val);
masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(obj)));
if (!isSameRealm) {
if (!sameRealm) {
masm.switchToRealm(target->realm(), scratch);
}
@ -1936,7 +1938,7 @@ bool IonCacheIRCompiler::emitCallScriptedSetter() {
masm.loadJitCodeRaw(scratch, scratch);
masm.callJit(scratch);
if (!isSameRealm) {
if (!sameRealm) {
masm.switchToRealm(cx_->realm(), ReturnReg);
}
@ -1944,14 +1946,13 @@ bool IonCacheIRCompiler::emitCallScriptedSetter() {
return true;
}
bool IonCacheIRCompiler::emitCallSetArrayLength() {
bool IonCacheIRCompiler::emitCallSetArrayLength(ObjOperandId objId, bool strict,
ValOperandId rhsId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
AutoSaveLiveRegisters save(*this);
Register obj = allocator.useRegister(masm, reader.objOperandId());
bool strict = reader.readBool();
ConstantOrRegister val =
allocator.useConstantOrRegister(masm, reader.valOperandId());
Register obj = allocator.useRegister(masm, objId);
ConstantOrRegister val = allocator.useConstantOrRegister(masm, rhsId);
allocator.discardStack(masm);
prepareVMCall(masm, save);
@ -1965,15 +1966,14 @@ bool IonCacheIRCompiler::emitCallSetArrayLength() {
return true;
}
bool IonCacheIRCompiler::emitCallProxySet() {
bool IonCacheIRCompiler::emitCallProxySet(ObjOperandId objId, uint32_t idOffset,
ValOperandId rhsId, bool strict) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
AutoSaveLiveRegisters save(*this);
Register obj = allocator.useRegister(masm, reader.objOperandId());
ConstantOrRegister val =
allocator.useConstantOrRegister(masm, reader.valOperandId());
jsid id = idStubField(reader.stubOffset());
bool strict = reader.readBool();
Register obj = allocator.useRegister(masm, objId);
ConstantOrRegister val = allocator.useConstantOrRegister(masm, rhsId);
jsid id = idStubField(idOffset);
AutoScratchRegister scratch(allocator, masm);
@ -1990,16 +1990,16 @@ bool IonCacheIRCompiler::emitCallProxySet() {
return true;
}
bool IonCacheIRCompiler::emitCallProxySetByValue() {
bool IonCacheIRCompiler::emitCallProxySetByValue(ObjOperandId objId,
ValOperandId idId,
ValOperandId rhsId,
bool strict) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
AutoSaveLiveRegisters save(*this);
Register obj = allocator.useRegister(masm, reader.objOperandId());
ConstantOrRegister idVal =
allocator.useConstantOrRegister(masm, reader.valOperandId());
ConstantOrRegister val =
allocator.useConstantOrRegister(masm, reader.valOperandId());
bool strict = reader.readBool();
Register obj = allocator.useRegister(masm, objId);
ConstantOrRegister idVal = allocator.useConstantOrRegister(masm, idId);
ConstantOrRegister val = allocator.useConstantOrRegister(masm, rhsId);
allocator.discardStack(masm);
prepareVMCall(masm, save);
@ -2014,14 +2014,14 @@ bool IonCacheIRCompiler::emitCallProxySetByValue() {
return true;
}
bool IonCacheIRCompiler::emitCallAddOrUpdateSparseElementHelper() {
bool IonCacheIRCompiler::emitCallAddOrUpdateSparseElementHelper(
ObjOperandId objId, Int32OperandId idId, ValOperandId rhsId, bool strict) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
AutoSaveLiveRegisters save(*this);
Register obj = allocator.useRegister(masm, reader.objOperandId());
Register id = allocator.useRegister(masm, reader.int32OperandId());
ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
bool strict = reader.readBool();
Register obj = allocator.useRegister(masm, objId);
Register id = allocator.useRegister(masm, idId);
ValueOperand val = allocator.useValueRegister(masm, rhsId);
allocator.discardStack(masm);
prepareVMCall(masm, save);
@ -2320,7 +2320,9 @@ bool IonCacheIRCompiler::emitCallStringObjectConcatResult() {
return true;
}
bool IonCacheIRCompiler::emitCallScriptedFunction() {
bool IonCacheIRCompiler::emitCallScriptedFunction(ObjOperandId calleeId,
Int32OperandId argcId,
CallFlags flags) {
MOZ_CRASH("Call ICs not used in ion");
}