summaryrefslogtreecommitdiffstats
path: root/js/src/jit/CacheIRCompiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/CacheIRCompiler.cpp')
-rw-r--r--js/src/jit/CacheIRCompiler.cpp85
1 files changed, 79 insertions, 6 deletions
diff --git a/js/src/jit/CacheIRCompiler.cpp b/js/src/jit/CacheIRCompiler.cpp
index 9a26b0816c..ceb14f0ecb 100644
--- a/js/src/jit/CacheIRCompiler.cpp
+++ b/js/src/jit/CacheIRCompiler.cpp
@@ -44,6 +44,7 @@
#include "vm/GeneratorObject.h"
#include "vm/GetterSetter.h"
#include "vm/Interpreter.h"
+#include "vm/TypeofEqOperand.h" // TypeofEqOperand
#include "vm/Uint8Clamped.h"
#include "builtin/Boolean-inl.h"
@@ -1055,6 +1056,15 @@ void CacheIRStubInfo::replaceStubRawWord(uint8_t* stubData, uint32_t offset,
*addr = newWord;
}
+void CacheIRStubInfo::replaceStubRawValueBits(uint8_t* stubData,
+ uint32_t offset, uint64_t oldBits,
+ uint64_t newBits) const {
+ MOZ_ASSERT(uint64_t(stubData + offset) % sizeof(uint64_t) == 0);
+ uint64_t* addr = reinterpret_cast<uint64_t*>(stubData + offset);
+ MOZ_ASSERT(*addr == oldBits);
+ *addr = newBits;
+}
+
template <class Stub, StubField::Type type>
typename MapStubFieldToType<type>::WrappedType& CacheIRStubInfo::getStubField(
Stub* stub, uint32_t offset) const {
@@ -2838,7 +2848,7 @@ bool CacheIRCompiler::emitStringToAtom(StringOperandId stringId) {
masm.branchTest32(Assembler::NonZero, Address(str, JSString::offsetOfFlags()),
Imm32(JSString::ATOM_BIT), &done);
- masm.lookupStringInAtomCacheLastLookups(str, scratch, str, &vmCall);
+ masm.tryFastAtomize(str, scratch, str, &vmCall);
masm.jump(&done);
masm.bind(&vmCall);
@@ -4670,8 +4680,7 @@ bool CacheIRCompiler::emitGuardNoAllocationMetadataBuilder(
return true;
}
-bool CacheIRCompiler::emitGuardFunctionHasJitEntry(ObjOperandId funId,
- bool constructing) {
+bool CacheIRCompiler::emitGuardFunctionHasJitEntry(ObjOperandId funId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
Register fun = allocator.useRegister(masm, funId);
@@ -4680,7 +4689,7 @@ bool CacheIRCompiler::emitGuardFunctionHasJitEntry(ObjOperandId funId,
return false;
}
- masm.branchIfFunctionHasNoJitEntry(fun, constructing, failure->label());
+ masm.branchIfFunctionHasNoJitEntry(fun, failure->label());
return true;
}
@@ -4694,8 +4703,7 @@ bool CacheIRCompiler::emitGuardFunctionHasNoJitEntry(ObjOperandId funId) {
return false;
}
- masm.branchIfFunctionHasJitEntry(obj, /*isConstructing =*/false,
- failure->label());
+ masm.branchIfFunctionHasJitEntry(obj, failure->label());
return true;
}
@@ -6565,6 +6573,7 @@ bool CacheIRCompiler::emitStoreTypedArrayElement(ObjOperandId objId,
valInt32.emplace(allocator.useRegister(masm, Int32OperandId(rhsId)));
break;
+ case Scalar::Float16:
case Scalar::Float32:
case Scalar::Float64:
allocator.ensureDoubleRegister(masm, NumberOperandId(rhsId),
@@ -7057,6 +7066,7 @@ bool CacheIRCompiler::emitStoreDataViewValueResult(
valInt32.emplace(allocator.useRegister(masm, Int32OperandId(valueId)));
break;
+ case Scalar::Float16:
case Scalar::Float32:
case Scalar::Float64:
allocator.ensureDoubleRegister(masm, NumberOperandId(valueId),
@@ -7400,6 +7410,69 @@ bool CacheIRCompiler::emitLoadTypeOfObjectResult(ObjOperandId objId) {
return true;
}
+bool CacheIRCompiler::emitLoadTypeOfEqObjectResult(ObjOperandId objId,
+ TypeofEqOperand operand) {
+ JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
+ AutoOutputRegister output(*this);
+ Register obj = allocator.useRegister(masm, objId);
+ AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
+ JSType type = operand.type();
+ JSOp compareOp = operand.compareOp();
+ bool result;
+
+ Label slowCheck, isObject, isCallable, isUndefined, done;
+ masm.typeOfObject(obj, scratch, &slowCheck, &isObject, &isCallable,
+ &isUndefined);
+
+ masm.bind(&isCallable);
+ result = type == JSTYPE_FUNCTION;
+ if (compareOp == JSOp::Ne) {
+ result = !result;
+ }
+ masm.moveValue(BooleanValue(result), output.valueReg());
+ masm.jump(&done);
+
+ masm.bind(&isUndefined);
+ result = type == JSTYPE_UNDEFINED;
+ if (compareOp == JSOp::Ne) {
+ result = !result;
+ }
+ masm.moveValue(BooleanValue(result), output.valueReg());
+ masm.jump(&done);
+
+ masm.bind(&isObject);
+ result = type == JSTYPE_OBJECT;
+ if (compareOp == JSOp::Ne) {
+ result = !result;
+ }
+ masm.moveValue(BooleanValue(result), output.valueReg());
+ masm.jump(&done);
+
+ {
+ masm.bind(&slowCheck);
+ LiveRegisterSet save(GeneralRegisterSet::Volatile(),
+ liveVolatileFloatRegs());
+ save.takeUnchecked(output.valueReg());
+ save.takeUnchecked(scratch);
+ masm.PushRegsInMask(save);
+
+ using Fn = bool (*)(JSObject* obj, TypeofEqOperand operand);
+ masm.setupUnalignedABICall(scratch);
+ masm.passABIArg(obj);
+ masm.move32(Imm32(TypeofEqOperand(type, compareOp).rawValue()), scratch);
+ masm.passABIArg(scratch);
+ masm.callWithABI<Fn, TypeOfEqObject>();
+ masm.storeCallBoolResult(scratch);
+
+ masm.PopRegsInMask(save);
+
+ masm.tagValue(JSVAL_TYPE_BOOLEAN, scratch, output.valueReg());
+ }
+
+ masm.bind(&done);
+ return true;
+}
+
bool CacheIRCompiler::emitLoadInt32TruthyResult(ValOperandId inputId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
AutoOutputRegister output(*this);