Bug 1644472 part 1 - Optimize IsRegExpObject intrinsic in CacheIR and Warp. r=evilpie

I tried to keep this generic in case we add a similar function for another Class
in the future.

Differential Revision: https://phabricator.services.mozilla.com/D79040
This commit is contained in:
Jan de Mooij 2020-06-11 16:51:02 +00:00
parent 0469ed0adb
commit 9f2f76ec99
7 changed files with 71 additions and 0 deletions

View File

@ -1552,6 +1552,21 @@ bool BaselineCacheIRCompiler::emitMathRandomResult(uint32_t rngOffset) {
return true;
}
bool BaselineCacheIRCompiler::emitHasClassResult(ObjOperandId objId,
uint32_t claspOffset) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
AutoOutputRegister output(*this);
Register obj = allocator.useRegister(masm, objId);
AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
Address claspAddr(stubAddress(claspOffset));
masm.loadObjClassUnsafe(obj, scratch);
masm.cmpPtrSet(Assembler::Equal, claspAddr, scratch.get(), scratch);
masm.tagValue(JSVAL_TYPE_BOOLEAN, scratch, output.valueReg());
return true;
}
bool BaselineCacheIRCompiler::emitCallNativeSetter(ObjOperandId objId,
uint32_t setterOffset,
ValOperandId rhsId) {

View File

@ -5314,6 +5314,32 @@ AttachDecision CallIRGenerator::tryAttachGuardToClass(HandleFunction callee,
return AttachDecision::Attach;
}
AttachDecision CallIRGenerator::tryAttachHasClass(HandleFunction callee,
const JSClass* clasp) {
// Need a single object argument.
if (argc_ != 1 || !args_[0].isObject()) {
return AttachDecision::NoAction;
}
// Initialize the input operand.
Int32OperandId argcId(writer.setInputOperandId(0));
// Guard callee is the 'IsXXXObject' native function.
emitNativeCalleeGuard(callee);
// Perform the Class check.
ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_);
ObjOperandId objId = writer.guardToObject(argId);
writer.hasClassResult(objId, clasp);
// Return without type monitoring, because this always returns a boolean.
writer.returnFromIC();
cacheIRStubKind_ = BaselineCacheIRStubKind::Regular;
trackAttached("HasClass");
return AttachDecision::Attach;
}
AttachDecision CallIRGenerator::tryAttachStringChar(HandleFunction callee,
StringChar kind) {
// Need one argument.
@ -5981,6 +6007,10 @@ AttachDecision CallIRGenerator::tryAttachInlinableNative(
case InlinableNative::IntrinsicGuardToWrapForValidIterator:
return tryAttachGuardToClass(callee, native);
// RegExp natives.
case InlinableNative::IsRegExpObject:
return tryAttachHasClass(callee, &RegExpObject::class_);
// String natives.
case InlinableNative::String:
return tryAttachToString(callee, native);

View File

@ -1545,6 +1545,7 @@ class MOZ_RAII CallIRGenerator : public IRGenerator {
AttachDecision tryAttachIsConstructor(HandleFunction callee);
AttachDecision tryAttachGuardToClass(HandleFunction callee,
InlinableNative native);
AttachDecision tryAttachHasClass(HandleFunction callee, const JSClass* clasp);
AttachDecision tryAttachStringChar(HandleFunction callee, StringChar kind);
AttachDecision tryAttachStringCharCodeAt(HandleFunction callee);
AttachDecision tryAttachStringCharAt(HandleFunction callee);

View File

@ -985,6 +985,7 @@ class MOZ_RAII AutoScratchRegisterMaybeOutput {
}
}
Register get() const { return scratchReg_; }
operator Register() const { return scratchReg_; }
};

View File

@ -196,6 +196,13 @@
obj: ObjId
clasp: RawPointerField
- name: HasClassResult
shared: false
transpile: true
args:
obj: ObjId
clasp: RawPointerField
# Add a reference to a global in the compartment to keep it alive.
- name: GuardCompartment
shared: false

View File

@ -2450,3 +2450,8 @@ bool IonCacheIRCompiler::emitStringFromCharCodeResult(Int32OperandId codeId) {
bool IonCacheIRCompiler::emitMathRandomResult(uint32_t rngOffset) {
MOZ_CRASH("Call ICs not used in ion");
}
bool IonCacheIRCompiler::emitHasClassResult(ObjOperandId objId,
uint32_t claspOffset) {
MOZ_CRASH("Call ICs not used in ion");
}

View File

@ -1285,6 +1285,18 @@ bool WarpCacheIRTranspiler::emitArrayPush(ObjOperandId objId,
return resumeAfter(ins);
}
bool WarpCacheIRTranspiler::emitHasClassResult(ObjOperandId objId,
uint32_t claspOffset) {
MDefinition* obj = getOperand(objId);
const JSClass* clasp = classStubField(claspOffset);
auto* hasClass = MHasClass::New(alloc(), obj, clasp);
add(hasClass);
pushResult(hasClass);
return true;
}
bool WarpCacheIRTranspiler::emitIsArrayResult(ValOperandId inputId) {
MDefinition* value = getOperand(inputId);