diff options
Diffstat (limited to 'js/src/jit/CacheIR.cpp')
-rw-r--r-- | js/src/jit/CacheIR.cpp | 93 |
1 files changed, 89 insertions, 4 deletions
diff --git a/js/src/jit/CacheIR.cpp b/js/src/jit/CacheIR.cpp index 03eae14140..4de24905b8 100644 --- a/js/src/jit/CacheIR.cpp +++ b/js/src/jit/CacheIR.cpp @@ -49,7 +49,8 @@ #include "vm/ProxyObject.h" #include "vm/RegExpObject.h" #include "vm/SelfHosting.h" -#include "vm/ThrowMsgKind.h" // ThrowCondition +#include "vm/ThrowMsgKind.h" // ThrowCondition +#include "vm/TypeofEqOperand.h" // TypeofEqOperand #include "vm/Watchtower.h" #include "wasm/WasmInstance.h" @@ -109,6 +110,7 @@ size_t js::jit::NumInputsForCacheKind(CacheKind kind) { return 0; case CacheKind::GetProp: case CacheKind::TypeOf: + case CacheKind::TypeOfEq: case CacheKind::ToPropertyKey: case CacheKind::GetIterator: case CacheKind::ToBool: @@ -3170,6 +3172,11 @@ AttachDecision GetPropIRGenerator::tryAttachTypedArrayElement( auto* tarr = &obj->as<TypedArrayObject>(); + if (tarr->type() == Scalar::Float16) { + // TODO: See Bug 1835034 for JIT support for Float16Array. + return AttachDecision::NoAction; + } + bool handleOOB = false; int64_t indexInt64; if (!ValueIsInt64Index(idVal_, &indexInt64) || indexInt64 < 0 || @@ -4530,6 +4537,7 @@ OperandId IRGenerator::emitNumericGuard(ValOperandId valId, const Value& v, return writer.truncateDoubleToUInt32(numId); } + case Scalar::Float16: case Scalar::Float32: case Scalar::Float64: { if (v.isNumber()) { @@ -5061,6 +5069,11 @@ AttachDecision SetPropIRGenerator::tryAttachSetTypedArrayElement( auto* tarr = &obj->as<TypedArrayObject>(); Scalar::Type elementType = tarr->type(); + if (elementType == Scalar::Float16) { + // TODO: See Bug 1835034 for JIT support for Float16Array. + return AttachDecision::NoAction; + } + // Don't attach if the input type doesn't match the guard added below. if (!ValueCanConvertToNumeric(elementType, rhsVal_)) { return AttachDecision::NoAction; @@ -5800,6 +5813,77 @@ AttachDecision TypeOfIRGenerator::tryAttachObject(ValOperandId valId) { return AttachDecision::Attach; } +TypeOfEqIRGenerator::TypeOfEqIRGenerator(JSContext* cx, HandleScript script, + jsbytecode* pc, ICState state, + HandleValue value, JSType type, + JSOp compareOp) + : IRGenerator(cx, script, pc, CacheKind::TypeOfEq, state), + val_(value), + type_(type), + compareOp_(compareOp) {} + +void TypeOfEqIRGenerator::trackAttached(const char* name) { + stubName_ = name ? name : "NotAttached"; +#ifdef JS_CACHEIR_SPEW + if (const CacheIRSpewer::Guard& sp = CacheIRSpewer::Guard(*this, name)) { + sp.valueProperty("val", val_); + sp.jstypeProperty("type", type_); + sp.opcodeProperty("compareOp", compareOp_); + } +#endif +} + +AttachDecision TypeOfEqIRGenerator::tryAttachStub() { + MOZ_ASSERT(cacheKind_ == CacheKind::TypeOfEq); + + AutoAssertNoPendingException aanpe(cx_); + + ValOperandId valId(writer.setInputOperandId(0)); + + TRY_ATTACH(tryAttachPrimitive(valId)); + TRY_ATTACH(tryAttachObject(valId)); + + MOZ_ASSERT_UNREACHABLE("Failed to attach TypeOfEq"); + return AttachDecision::NoAction; +} + +AttachDecision TypeOfEqIRGenerator::tryAttachPrimitive(ValOperandId valId) { + if (!val_.isPrimitive()) { + return AttachDecision::NoAction; + } + + // Note: we don't use GuardIsNumber for int32 values because it's less + // efficient in Warp (unboxing to double instead of int32). + if (val_.isDouble()) { + writer.guardIsNumber(valId); + } else { + writer.guardNonDoubleType(valId, val_.type()); + } + + bool result = js::TypeOfValue(val_) == type_; + if (compareOp_ == JSOp::Ne) { + result = !result; + } + writer.loadBooleanResult(result); + writer.returnFromIC(); + writer.setTypeData(TypeData(JSValueType(val_.type()))); + trackAttached("TypeOfEq.Primitive"); + return AttachDecision::Attach; +} + +AttachDecision TypeOfEqIRGenerator::tryAttachObject(ValOperandId valId) { + if (!val_.isObject()) { + return AttachDecision::NoAction; + } + + ObjOperandId objId = writer.guardToObject(valId); + writer.loadTypeOfEqObjectResult(objId, TypeofEqOperand(type_, compareOp_)); + writer.returnFromIC(); + writer.setTypeData(TypeData(JSValueType(val_.type()))); + trackAttached("TypeOfEq.Object"); + return AttachDecision::Attach; +} + GetIteratorIRGenerator::GetIteratorIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, ICState state, @@ -9127,6 +9211,7 @@ static bool AtomicsMeetsPreconditions(TypedArrayObject* typedArray, case Scalar::BigUint64: break; + case Scalar::Float16: case Scalar::Float32: case Scalar::Float64: case Scalar::Uint8Clamped: @@ -10308,7 +10393,7 @@ AttachDecision CallIRGenerator::tryAttachFunCall(HandleFunction callee) { writer.guardNotClassConstructor(thisObjId); if (isScripted) { - writer.guardFunctionHasJitEntry(thisObjId, /*isConstructing =*/false); + writer.guardFunctionHasJitEntry(thisObjId); writer.callScriptedFunction(thisObjId, argcId, targetFlags, ClampFixedArgc(argc_)); } else { @@ -11268,7 +11353,7 @@ AttachDecision CallIRGenerator::tryAttachFunApply(HandleFunction calleeFunc) { if (isScripted) { // Guard that function is scripted. - writer.guardFunctionHasJitEntry(thisObjId, /*constructing =*/false); + writer.guardFunctionHasJitEntry(thisObjId); writer.callScriptedFunction(thisObjId, argcId, targetFlags, fixedArgc); } else { // Guard that function is native. @@ -12034,7 +12119,7 @@ void CallIRGenerator::emitCallScriptedGuards(ObjOperandId calleeObjId, } else { // Guard that object is a scripted function writer.guardClass(calleeObjId, GuardClassKind::JSFunction); - writer.guardFunctionHasJitEntry(calleeObjId, isConstructing); + writer.guardFunctionHasJitEntry(calleeObjId); if (isConstructing) { // If callee is not a constructor, we have to throw. |