summaryrefslogtreecommitdiff
path: root/js/src
diff options
context:
space:
mode:
authorBrian Smith <brian@dbsoft.org>2023-07-21 20:25:52 -0500
committerBrian Smith <brian@dbsoft.org>2023-07-21 20:25:52 -0500
commit94609cf97bae8b30f51ddabd94cfc2d301d59b83 (patch)
treec6ce1a7e08a75aac1ba0195adbda464b414eabca /js/src
parent6257513c7e0e1e90b47b35e0c2ea63eeeb802ed8 (diff)
downloaduxp-94609cf97bae8b30f51ddabd94cfc2d301d59b83.tar.gz
Issue #1240 - Part 10 - Implement minimal Ion support for BigInt.
https://bugzilla.mozilla.org/show_bug.cgi?id=1507484 Implement IC support for BigInt. https://bugzilla.mozilla.org/show_bug.cgi?id=1522431
Diffstat (limited to 'js/src')
-rw-r--r--js/src/jit/BaselineBailouts.cpp1
-rw-r--r--js/src/jit/BaselineCacheIR.cpp3
-rw-r--r--js/src/jit/BaselineIC.cpp3
-rw-r--r--js/src/jit/CacheIR.cpp3
-rw-r--r--js/src/jit/CodeGenerator.cpp61
-rw-r--r--js/src/jit/CodeGenerator.h4
-rw-r--r--js/src/jit/IonAnalysis.cpp1
-rw-r--r--js/src/jit/IonBuilder.cpp13
-rw-r--r--js/src/jit/IonTypes.h10
-rw-r--r--js/src/jit/LIR.h1
-rw-r--r--js/src/jit/Lowering.cpp10
-rw-r--r--js/src/jit/MCallOptimize.cpp21
-rw-r--r--js/src/jit/MIR.cpp38
-rw-r--r--js/src/jit/MIR.h50
-rw-r--r--js/src/jit/MacroAssembler-inl.h1
-rw-r--r--js/src/jit/MacroAssembler.cpp6
-rw-r--r--js/src/jit/MacroAssembler.h10
-rw-r--r--js/src/jit/Snapshots.cpp2
-rw-r--r--js/src/jit/TypePolicy.cpp10
-rw-r--r--js/src/jit/VMFunctions.cpp18
-rw-r--r--js/src/jit/VMFunctions.h1
-rw-r--r--js/src/jit/arm/MacroAssembler-arm-inl.h23
-rw-r--r--js/src/jit/arm/MacroAssembler-arm.cpp43
-rw-r--r--js/src/jit/arm/MacroAssembler-arm.h7
-rw-r--r--js/src/jit/mips32/MacroAssembler-mips32-inl.h13
-rw-r--r--js/src/jit/mips64/CodeGenerator-mips64.cpp6
-rw-r--r--js/src/jit/mips64/MacroAssembler-mips64-inl.h15
-rw-r--r--js/src/jit/mips64/MacroAssembler-mips64.cpp15
-rw-r--r--js/src/jit/mips64/MacroAssembler-mips64.h3
-rw-r--r--js/src/jit/none/MacroAssembler-none.h2
-rw-r--r--js/src/jit/shared/CodeGenerator-shared.cpp1
-rw-r--r--js/src/jit/shared/Lowering-shared-inl.h3
-rw-r--r--js/src/jit/shared/Lowering-shared.cpp3
-rw-r--r--js/src/jit/x64/CodeGenerator-x64.cpp6
-rw-r--r--js/src/jit/x64/MacroAssembler-x64.h30
-rw-r--r--js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h24
-rw-r--r--js/src/jit/x86/MacroAssembler-x86.h21
-rw-r--r--js/src/vm/BigIntType.h5
-rw-r--r--js/src/vm/TypeInference.cpp4
39 files changed, 448 insertions, 43 deletions
diff --git a/js/src/jit/BaselineBailouts.cpp b/js/src/jit/BaselineBailouts.cpp
index 30c83a5042..ce27e4de19 100644
--- a/js/src/jit/BaselineBailouts.cpp
+++ b/js/src/jit/BaselineBailouts.cpp
@@ -1958,6 +1958,7 @@ jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo)
case Bailout_NonObjectInput:
case Bailout_NonStringInput:
case Bailout_NonSymbolInput:
+ case Bailout_NonBigIntInput:
case Bailout_UnexpectedSimdInput:
case Bailout_NonSharedTypedArrayInput:
case Bailout_Debugger:
diff --git a/js/src/jit/BaselineCacheIR.cpp b/js/src/jit/BaselineCacheIR.cpp
index 9bea352ae7..5317f0e4e5 100644
--- a/js/src/jit/BaselineCacheIR.cpp
+++ b/js/src/jit/BaselineCacheIR.cpp
@@ -710,6 +710,9 @@ BaselineCacheIRCompiler::emitGuardType()
case JSVAL_TYPE_SYMBOL:
masm.branchTestSymbol(Assembler::NotEqual, input, failure->label());
break;
+ case JSVAL_TYPE_BIGINT:
+ masm.branchTestBigInt(Assembler::NotEqual, input, failure->label());
+ break;
case JSVAL_TYPE_DOUBLE:
masm.branchTestNumber(Assembler::NotEqual, input, failure->label());
break;
diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp
index 0a87121c6e..2827f4b1d5 100644
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -8094,7 +8094,8 @@ ICTypeOf_Typed::Compiler::generateStubCode(MacroAssembler& masm)
break;
case JSTYPE_BIGINT:
- return false;
+ masm.branchTestBigInt(Assembler::NotEqual, R0, &failure);
+ break;
default:
MOZ_CRASH("Unexpected type");
diff --git a/js/src/jit/CacheIR.cpp b/js/src/jit/CacheIR.cpp
index 9168a344e5..4da9b7539f 100644
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -446,6 +446,9 @@ GetPropIRGenerator::tryAttachPrimitive(CacheIRWriter& writer, ValOperandId valId
} else if (val_.isSymbol()) {
primitiveType = JSVAL_TYPE_SYMBOL;
proto = MaybeNativeObject(GetBuiltinPrototypePure(cx_->global(), JSProto_Symbol));
+ } else if (val_.isBigInt()) {
+ primitiveType = JSVAL_TYPE_BIGINT;
+ proto = MaybeNativeObject(GetBuiltinPrototypePure(cx_->global(), JSProto_BigInt));
} else {
MOZ_ASSERT(val_.isNullOrUndefined() || val_.isMagic());
return true;
diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp
index 7daf6e731b..0459592448 100644
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -526,9 +526,11 @@ CodeGenerator::testValueTruthyKernel(const ValueOperand& value,
bool mightBeString = valueMIR->mightBeType(MIRType::String);
bool mightBeSymbol = valueMIR->mightBeType(MIRType::Symbol);
bool mightBeDouble = valueMIR->mightBeType(MIRType::Double);
+ bool mightBeBigInt = valueMIR->mightBeType(MIRType::BigInt);
int tagCount = int(mightBeUndefined) + int(mightBeNull) +
int(mightBeBoolean) + int(mightBeInt32) + int(mightBeObject) +
- int(mightBeString) + int(mightBeSymbol) + int(mightBeDouble);
+ int(mightBeString) + int(mightBeSymbol) + int(mightBeDouble) +
+ int(mightBeBigInt);;
MOZ_ASSERT_IF(!valueMIR->emptyResultTypeSet(), tagCount > 0);
@@ -618,6 +620,20 @@ CodeGenerator::testValueTruthyKernel(const ValueOperand& value,
--tagCount;
}
+ if (mightBeBigInt) {
+ MOZ_ASSERT(tagCount != 0);
+ Label notBigInt;
+ if (tagCount != 1) {
+ masm.branchTestBigInt(Assembler::NotEqual, tag, &notBigInt);
+ }
+ masm.branchTestBigIntTruthy(false, value, ifFalsy);
+ if (tagCount != 1) {
+ masm.jump(ifTruthy);
+ }
+ masm.bind(&notBigInt);
+ --tagCount;
+ }
+
if (mightBeSymbol) {
// All symbols are truthy.
MOZ_ASSERT(tagCount != 0);
@@ -954,8 +970,15 @@ CodeGenerator::visitValueToString(LValueToString* lir)
}
// Symbol
- if (lir->mir()->input()->mightBeType(MIRType::Symbol))
+ if (lir->mir()->input()->mightBeType(MIRType::Symbol)) {
masm.branchTestSymbol(Assembler::Equal, tag, ool->entry());
+ }
+
+ // BigInt
+ if (lir->mir()->input()->mightBeType(MIRType::BigInt)) {
+ // No fastpath currently implemented.
+ masm.branchTestBigInt(Assembler::Equal, tag, ool->entry());
+ }
#ifdef DEBUG
masm.assumeUnreachable("Unexpected type for MValueToString.");
@@ -4902,10 +4925,11 @@ CodeGenerator::branchIfInvalidated(Register temp, Label* invalidated)
}
void
-CodeGenerator::emitAssertObjectOrStringResult(Register input, MIRType type, const TemporaryTypeSet* typeset)
+CodeGenerator::emitAssertGCThingResult(Register input, MIRType type, const TemporaryTypeSet* typeset)
{
MOZ_ASSERT(type == MIRType::Object || type == MIRType::ObjectOrNull ||
- type == MIRType::String || type == MIRType::Symbol);
+ type == MIRType::String || type == MIRType::Symbol ||
+ type == MIRType::BigInt);
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
regs.take(input);
@@ -4960,6 +4984,9 @@ CodeGenerator::emitAssertObjectOrStringResult(Register input, MIRType type, cons
case MIRType::Symbol:
callee = JS_FUNC_TO_DATA_PTR(void*, AssertValidSymbolPtr);
break;
+ case MIRType::BigInt:
+ callee = JS_FUNC_TO_DATA_PTR(void*, AssertValidBigIntPtr);
+ break;
default:
MOZ_CRASH();
}
@@ -5029,7 +5056,7 @@ CodeGenerator::emitAssertResultV(const ValueOperand input, const TemporaryTypeSe
#ifdef DEBUG
void
-CodeGenerator::emitObjectOrStringResultChecks(LInstruction* lir, MDefinition* mir)
+CodeGenerator::emitGCThingResultChecks(LInstruction* lir, MDefinition* mir)
{
if (lir->numDefs() == 0)
return;
@@ -5037,7 +5064,7 @@ CodeGenerator::emitObjectOrStringResultChecks(LInstruction* lir, MDefinition* mi
MOZ_ASSERT(lir->numDefs() == 1);
Register output = ToRegister(lir->getDef(0));
- emitAssertObjectOrStringResult(output, mir->type(), mir->resultTypeSet());
+ emitAssertGCThingResult(output, mir->type(), mir->resultTypeSet());
}
void
@@ -5069,7 +5096,8 @@ CodeGenerator::emitDebugResultChecks(LInstruction* ins)
case MIRType::ObjectOrNull:
case MIRType::String:
case MIRType::Symbol:
- emitObjectOrStringResultChecks(ins, mir);
+ case MIRType::BigInt:
+ emitGCThingResultChecks(ins, mir);
break;
case MIRType::Value:
emitValueResultChecks(ins, mir);
@@ -10386,9 +10414,11 @@ CodeGenerator::visitTypeOfV(LTypeOfV* lir)
bool testNull = input->mightBeType(MIRType::Null);
bool testString = input->mightBeType(MIRType::String);
bool testSymbol = input->mightBeType(MIRType::Symbol);
+ bool testBigInt = input->mightBeType(MIRType::BigInt);
unsigned numTests = unsigned(testObject) + unsigned(testNumber) + unsigned(testBoolean) +
- unsigned(testUndefined) + unsigned(testNull) + unsigned(testString) + unsigned(testSymbol);
+ unsigned(testUndefined) + unsigned(testNull) + unsigned(testString) + unsigned(testSymbol) +
+ unsigned(testBigInt);
MOZ_ASSERT_IF(!input->emptyResultTypeSet(), numTests > 0);
@@ -10484,6 +10514,19 @@ CodeGenerator::visitTypeOfV(LTypeOfV* lir)
numTests--;
}
+ if (testBigInt) {
+ Label notBigInt;
+ if (numTests > 1) {
+ masm.branchTestBigInt(Assembler::NotEqual, tag, &notBigInt);
+ }
+ masm.movePtr(ImmGCPtr(names.bigint), output);
+ if (numTests > 1) {
+ masm.jump(&done);
+ }
+ masm.bind(&notBigInt);
+ numTests--;
+ }
+
MOZ_ASSERT(numTests == 0);
masm.bind(&done);
@@ -11794,7 +11837,7 @@ CodeGenerator::visitAssertResultT(LAssertResultT* ins)
Register input = ToRegister(ins->input());
MDefinition* mir = ins->mirRaw();
- emitAssertObjectOrStringResult(input, mir->type(), mir->resultTypeSet());
+ emitAssertGCThingResult(input, mir->type(), mir->resultTypeSet());
}
void
diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h
index 2749a68b05..64fe9378b8 100644
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -431,7 +431,7 @@ class CodeGenerator final : public CodeGeneratorSpecific
void visitAssertResultV(LAssertResultV* ins);
void visitAssertResultT(LAssertResultT* ins);
void emitAssertResultV(const ValueOperand output, const TemporaryTypeSet* typeset);
- void emitAssertObjectOrStringResult(Register input, MIRType type, const TemporaryTypeSet* typeset);
+ void emitAssertGCThingResult(Register input, MIRType type, const TemporaryTypeSet* typeset);
void visitInterruptCheck(LInterruptCheck* lir);
void visitOutOfLineInterruptCheckImplicit(OutOfLineInterruptCheckImplicit* ins);
@@ -571,7 +571,7 @@ class CodeGenerator final : public CodeGeneratorSpecific
#ifdef DEBUG
void emitDebugResultChecks(LInstruction* ins);
- void emitObjectOrStringResultChecks(LInstruction* lir, MDefinition* mir);
+ void emitGCThingResultChecks(LInstruction* lir, MDefinition* mir);
void emitValueResultChecks(LInstruction* lir, MDefinition* mir);
#endif
diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp
index 410769251c..aa8f8164b5 100644
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -2611,6 +2611,7 @@ IsResumableMIRType(MIRType type)
case MIRType::Float32:
case MIRType::String:
case MIRType::Symbol:
+ case MIRType::BigInt:
case MIRType::Object:
case MIRType::MagicOptimizedArguments:
case MIRType::MagicOptimizedOut:
diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp
index 80c2c0aa9d..a440bfa598 100644
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -721,6 +721,9 @@ IonBuilder::analyzeNewLoopTypes(MBasicBlock* entry, jsbytecode* start, jsbytecod
case JSOP_NEG:
type = inspector->expectedResultType(last);
break;
+ case JSOP_BIGINT:
+ type = MIRType::BigInt;
+ break;
default:
break;
}
@@ -1347,6 +1350,7 @@ IonBuilder::addOsrValueTypeBarrier(uint32_t slot, MInstruction** def_,
case MIRType::Double:
case MIRType::String:
case MIRType::Symbol:
+ case MIRType::BigInt:
case MIRType::Object:
if (type != def->type()) {
MUnbox* unbox = MUnbox::New(alloc(), def, type, MUnbox::Fallible);
@@ -4761,8 +4765,10 @@ IonBuilder::bitnotTrySpecialized(bool* emitted, MDefinition* input)
// Try to emit a specialized bitnot instruction based on the input type
// of the operand.
- if (input->mightBeType(MIRType::Object) || input->mightBeType(MIRType::Symbol))
+ if (input->mightBeType(MIRType::Object) || input->mightBeType(MIRType::Symbol) ||
+ input->mightBeType(MIRType::BigInt)) {
return true;
+ }
MBitNot* ins = MBitNot::New(alloc(), input);
ins->setSpecialization(MIRType::Int32);
@@ -7210,6 +7216,7 @@ ObjectOrSimplePrimitive(MDefinition* op)
// Return true if op is either undefined/null/boolean/int32 or an object.
return !op->mightBeType(MIRType::String)
&& !op->mightBeType(MIRType::Symbol)
+ && !op->mightBeType(MIRType::BigInt)
&& !op->mightBeType(MIRType::Double)
&& !op->mightBeType(MIRType::Float32)
&& !op->mightBeType(MIRType::MagicOptimizedArguments)
@@ -8349,6 +8356,10 @@ IonBuilder::testSingletonPropertyTypes(MDefinition* obj, jsid id)
key = JSProto_Symbol;
break;
+ case MIRType::BigInt:
+ key = JSProto_BigInt;
+ break;
+
case MIRType::Int32:
case MIRType::Double:
key = JSProto_Number;
diff --git a/js/src/jit/IonTypes.h b/js/src/jit/IonTypes.h
index c7a3e282aa..c9714343dc 100644
--- a/js/src/jit/IonTypes.h
+++ b/js/src/jit/IonTypes.h
@@ -103,6 +103,7 @@ enum BailoutKind
Bailout_NonObjectInput,
Bailout_NonStringInput,
Bailout_NonSymbolInput,
+ Bailout_NonBigIntInput,
// SIMD Unbox expects a given type, bails out if it doesn't match.
Bailout_UnexpectedSimdInput,
@@ -212,6 +213,8 @@ BailoutKindString(BailoutKind kind)
return "Bailout_NonStringInput";
case Bailout_NonSymbolInput:
return "Bailout_NonSymbolInput";
+ case Bailout_NonBigIntInput:
+ return "Bailout_NonBigIntInput";
case Bailout_UnexpectedSimdInput:
return "Bailout_UnexpectedSimdInput";
case Bailout_NonSharedTypedArrayInput:
@@ -412,6 +415,7 @@ enum class MIRType
// Types above have trivial conversion to a number.
String,
Symbol,
+ BigInt,
// Types above are primitive (including undefined and null).
Object,
MagicOptimizedArguments, // JS_OPTIMIZED_ARGUMENTS magic value.
@@ -496,6 +500,8 @@ MIRTypeFromValueType(JSValueType type)
return MIRType::String;
case JSVAL_TYPE_SYMBOL:
return MIRType::Symbol;
+ case JSVAL_TYPE_BIGINT:
+ return MIRType::BigInt;
case JSVAL_TYPE_BOOLEAN:
return MIRType::Boolean;
case JSVAL_TYPE_NULL:
@@ -528,6 +534,8 @@ ValueTypeFromMIRType(MIRType type)
return JSVAL_TYPE_STRING;
case MIRType::Symbol:
return JSVAL_TYPE_SYMBOL;
+ case MIRType::BigInt:
+ return JSVAL_TYPE_BIGINT;
case MIRType::MagicOptimizedArguments:
case MIRType::MagicOptimizedOut:
case MIRType::MagicHole:
@@ -568,6 +576,8 @@ StringFromMIRType(MIRType type)
return "String";
case MIRType::Symbol:
return "Symbol";
+ case MIRType::BigInt:
+ return "BigInt";
case MIRType::Object:
return "Object";
case MIRType::MagicOptimizedArguments:
diff --git a/js/src/jit/LIR.h b/js/src/jit/LIR.h
index 4083f7f1bb..e9143a6f41 100644
--- a/js/src/jit/LIR.h
+++ b/js/src/jit/LIR.h
@@ -599,6 +599,7 @@ class LDefinition
return LDefinition::INT32;
case MIRType::String:
case MIRType::Symbol:
+ case MIRType::BigInt:
case MIRType::Object:
case MIRType::ObjectOrNull:
return LDefinition::OBJECT;
diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp
index 1c80c74716..d315c618e7 100644
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -717,6 +717,10 @@ LIRGenerator::visitTest(MTest* test)
// TestPolicy).
MOZ_ASSERT(opd->type() != MIRType::String);
+ // BigInt is boxed in type analysis.
+ MOZ_ASSERT(opd->type() != MIRType::BigInt,
+ "BigInt should be boxed by TestPolicy");
+
// Testing a constant.
if (MConstant* constant = opd->maybeConstantValue()) {
bool b;
@@ -2149,9 +2153,11 @@ LIRGenerator::visitToInt32(MToInt32* convert)
case MIRType::String:
case MIRType::Symbol:
+ case MIRType::BigInt:
case MIRType::Object:
case MIRType::Undefined:
- // Objects might be effectful. Symbols throw. Undefined coerces to NaN, not int32.
+ // Objects might be effectful. Symbols and BigInts throw. Undefined
+ // coerces to NaN, not int32.
MOZ_CRASH("ToInt32 invalid input type");
default:
@@ -2939,6 +2945,8 @@ LIRGenerator::visitNot(MNot* ins)
// String is converted to length of string in the type analysis phase (see
// TestPolicy).
MOZ_ASSERT(op->type() != MIRType::String);
+ MOZ_ASSERT(op->type() != MIRType::BigInt,
+ "BigInt should be boxed by TestPolicy");
// - boolean: x xor 1
// - int32: LCompare(x, 0)
diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp
index 1a98432ffa..064c7ee7d2 100644
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -2894,6 +2894,7 @@ IonBuilder::inlineToInteger(CallInfo& callInfo)
if (input->mightBeType(MIRType::Object) ||
input->mightBeType(MIRType::String) ||
input->mightBeType(MIRType::Symbol) ||
+ input->mightBeType(MIRType::BigInt) ||
input->mightBeType(MIRType::Undefined) ||
input->mightBeMagicType())
{
@@ -3021,12 +3022,16 @@ IonBuilder::inlineAtomicsCompareExchange(CallInfo& callInfo)
// These guards are desirable here and in subsequent atomics to
// avoid bad bailouts with MTruncateToInt32, see https://bugzilla.mozilla.org/show_bug.cgi?id=1141986#c20.
MDefinition* oldval = callInfo.getArg(2);
- if (oldval->mightBeType(MIRType::Object) || oldval->mightBeType(MIRType::Symbol))
+ if (oldval->mightBeType(MIRType::Object) || oldval->mightBeType(MIRType::Symbol) ||
+ oldval->mightBeType(MIRType::BigInt)) {
return InliningStatus_NotInlined;
+ }
MDefinition* newval = callInfo.getArg(3);
- if (newval->mightBeType(MIRType::Object) || newval->mightBeType(MIRType::Symbol))
+ if (newval->mightBeType(MIRType::Object) || newval->mightBeType(MIRType::Symbol) ||
+ newval->mightBeType(MIRType::BigInt)) {
return InliningStatus_NotInlined;
+ }
Scalar::Type arrayType;
bool requiresCheck = false;
@@ -3063,8 +3068,10 @@ IonBuilder::inlineAtomicsExchange(CallInfo& callInfo)
}
MDefinition* value = callInfo.getArg(2);
- if (value->mightBeType(MIRType::Object) || value->mightBeType(MIRType::Symbol))
+ if (value->mightBeType(MIRType::Object) || value->mightBeType(MIRType::Symbol) ||
+ value->mightBeType(MIRType::BigInt)) {
return InliningStatus_NotInlined;
+ }
Scalar::Type arrayType;
bool requiresCheck = false;
@@ -3151,8 +3158,10 @@ IonBuilder::inlineAtomicsStore(CallInfo& callInfo)
return InliningStatus_NotInlined;
}
- if (value->mightBeType(MIRType::Object) || value->mightBeType(MIRType::Symbol))
+ if (value->mightBeType(MIRType::Object) || value->mightBeType(MIRType::Symbol) ||
+ value->mightBeType(MIRType::BigInt)) {
return InliningStatus_NotInlined;
+ }
Scalar::Type arrayType;
bool requiresCheck = false;
@@ -3194,8 +3203,10 @@ IonBuilder::inlineAtomicsBinop(CallInfo& callInfo, InlinableNative target)
}
MDefinition* value = callInfo.getArg(2);
- if (value->mightBeType(MIRType::Object) || value->mightBeType(MIRType::Symbol))
+ if (value->mightBeType(MIRType::Object) || value->mightBeType(MIRType::Symbol) ||
+ value->mightBeType(MIRType::BigInt)) {
return InliningStatus_NotInlined;
+ }
Scalar::Type arrayType;
bool requiresCheck = false;
diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp
index 2d4e02efea..63ff8f7201 100644
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -935,6 +935,9 @@ MConstant::MConstant(const js::Value& vp, CompilerConstraintList* constraints)
case MIRType::Symbol:
payload_.sym = vp.toSymbol();
break;
+ case MIRType::BigInt:
+ payload_.bi = vp.toBigInt();
+ break;
case MIRType::Object:
payload_.obj = &vp.toObject();
// Create a singleton type set for the object. This isn't necessary for
@@ -1014,7 +1017,12 @@ MConstant::assertInitializedPayload() const
case MIRType::String:
case MIRType::Object:
case MIRType::Symbol:
+ case MIRType::BigInt:
+#if MOZ_LITTLE_ENDIAN
MOZ_ASSERT_IF(JS_BITS_PER_WORD == 32, (payload_.asBits >> 32) == 0);
+#else
+ MOZ_ASSERT_IF(JS_BITS_PER_WORD == 32, (payload_.asBits << 32) == 0);
+#endif
break;
default:
MOZ_ASSERT(IsNullOrUndefined(type()) || IsMagicType(type()));
@@ -1103,6 +1111,9 @@ MConstant::printOpcode(GenericPrinter& out) const
case MIRType::Symbol:
out.printf("symbol at %p", (void*)toSymbol());
break;
+ case MIRType::BigInt:
+ out.printf("BigInt at %p", (void*)toBigInt());
+ break;
case MIRType::String:
out.printf("string %p", (void*)toString());
break;
@@ -1164,6 +1175,8 @@ MConstant::toJSValue() const
return StringValue(toString());
case MIRType::Symbol:
return SymbolValue(toSymbol());
+ case MIRType::BigInt:
+ return BigIntValue(toBigInt());
case MIRType::Object:
return ObjectValue(toObject());
case MIRType::MagicOptimizedArguments:
@@ -1207,6 +1220,9 @@ MConstant::valueToBoolean(bool* res) const
case MIRType::Symbol:
*res = true;
return true;
+ case MIRType::BigInt:
+ *res = !toBigInt()->isZero();
+ return true;
case MIRType::String:
*res = toString()->length() != 0;
return true;
@@ -2199,6 +2215,7 @@ MUnbox::printOpcode(GenericPrinter& out) const
case MIRType::Boolean: out.printf("to Boolean"); break;
case MIRType::String: out.printf("to String"); break;
case MIRType::Symbol: out.printf("to Symbol"); break;
+ case MIRType::BigInt: out.printf("to BigInt"); break;
case MIRType::Object: out.printf("to Object"); break;
default: break;
}
@@ -2591,6 +2608,7 @@ jit::TypeSetIncludes(TypeSet* types, MIRType input, TypeSet* inputTypes)
case MIRType::Float32:
case MIRType::String:
case MIRType::Symbol:
+ case MIRType::BigInt:
case MIRType::MagicOptimizedArguments:
return types->hasType(TypeSet::PrimitiveType(ValueTypeFromMIRType(input)));
@@ -2846,7 +2864,8 @@ void
MBinaryBitwiseInstruction::infer(BaselineInspector*, jsbytecode*)
{
if (getOperand(0)->mightBeType(MIRType::Object) || getOperand(0)->mightBeType(MIRType::Symbol) ||
- getOperand(1)->mightBeType(MIRType::Object) || getOperand(1)->mightBeType(MIRType::Symbol))
+ getOperand(1)->mightBeType(MIRType::Object) || getOperand(1)->mightBeType(MIRType::Symbol) ||
+ getOperand(1)->mightBeType(MIRType::BigInt))
{
specialization_ = MIRType::None;
setResultType(MIRType::Value);
@@ -2872,7 +2891,8 @@ void
MShiftInstruction::infer(BaselineInspector*, jsbytecode*)
{
if (getOperand(0)->mightBeType(MIRType::Object) || getOperand(1)->mightBeType(MIRType::Object) ||
- getOperand(0)->mightBeType(MIRType::Symbol) || getOperand(1)->mightBeType(MIRType::Symbol))
+ getOperand(0)->mightBeType(MIRType::Symbol) || getOperand(1)->mightBeType(MIRType::Symbol) ||
+ getOperand(0)->mightBeType(MIRType::BigInt) || getOperand(1)->mightBeType(MIRType::BigInt))
{
specialization_ = MIRType::None;
setResultType(MIRType::Value);
@@ -2886,7 +2906,8 @@ void
MUrsh::infer(BaselineInspector* inspector, jsbytecode* pc)
{
if (getOperand(0)->mightBeType(MIRType::Object) || getOperand(1)->mightBeType(MIRType::Object) ||
- getOperand(0)->mightBeType(MIRType::Symbol) || getOperand(1)->mightBeType(MIRType::Symbol))
+ getOperand(0)->mightBeType(MIRType::Symbol) || getOperand(1)->mightBeType(MIRType::Symbol) ||
+ getOperand(0)->mightBeType(MIRType::BigInt) || getOperand(1)->mightBeType(MIRType::BigInt))
{
specialization_ = MIRType::None;
setResultType(MIRType::Value);
@@ -3880,6 +3901,9 @@ MTypeOf::foldsTo(TempAllocator& alloc)
case MIRType::Symbol:
type = JSTYPE_SYMBOL;
break;
+ case MIRType::BigInt:
+ type = JSTYPE_BIGINT;
+ break;
case MIRType::Null:
type = JSTYPE_OBJECT;
break;
@@ -4459,6 +4483,12 @@ MCompare::tryFoldTypeOf(bool* result)
*result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE);
return true;
}
+ }
+ else if (constant->toString() == TypeName(JSTYPE_BIGINT, names)) {
+ if (!typeOf->input()->mightBeType(MIRType::BigInt)) {
+ *result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE);
+ return true;
+ }
} else if (constant->toString() == TypeName(JSTYPE_OBJECT, names)) {
if (!typeOf->input()->mightBeType(MIRType::Object) &&
!typeOf->input()->mightBeType(MIRType::Null))
@@ -5612,6 +5642,8 @@ MConstant::appendRoots(MRootList& roots) const
return roots.append(toString());
case MIRType::Symbol:
return roots.append(toSymbol());
+ case MIRType::BigInt:
+ return roots.append(toBigInt());
case MIRType::Object:
return roots.append(&toObject());
case MIRType::Undefined:
diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h
index f29cf6c353..6a2adc9622 100644
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -1548,6 +1548,7 @@ class MConstant : public MNullaryInstruction
double d;
JSString* str;
JS::Symbol* sym;
+ BigInt* bi;
JSObject* obj;
uint64_t asBits;
};
@@ -1672,6 +1673,10 @@ class MConstant : public MNullaryInstruction
MOZ_ASSERT(type() == MIRType::Symbol);
return payload_.sym;
}
+ BigInt* toBigInt() const {
+ MOZ_ASSERT(type() == MIRType::BigInt);
+ return payload_.bi;
+ }
JSObject& toObject() const {
MOZ_ASSERT(type() == MIRType::Object);
return *payload_.obj;
@@ -4743,6 +4748,7 @@ class MUnbox final : public MUnaryInstruction, public BoxInputsPolicy::Data
type == MIRType::Double ||
type == MIRType::String ||
type == MIRType::Symbol ||
+ type == MIRType::BigInt ||
type == MIRType::Object);
TemporaryTypeSet* resultSet = ins->resultTypeSet();
@@ -4781,6 +4787,9 @@ class MUnbox final : public MUnaryInstruction, public BoxInputsPolicy::Data
case MIRType::Symbol:
kind = Bailout_NonSymbolInput;
break;
+ case MIRType::BigInt:
+ kind = Bailout_NonBigIntInput;
+ break;
case MIRType::Object:
kind = Bailout_NonObjectInput;
break;
@@ -5189,9 +5198,11 @@ class MToDouble
setMovable();
// An object might have "valueOf", which means it is effectful.
- // ToNumber(symbol) throws.
- if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol))
+ // ToNumber(symbol) and ToNumber(bigint) throw.
+ if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol) ||
+ def->mightBeType(MIRType::BigInt)) {
setGuard();
+ }
}
public:
@@ -5226,11 +5237,15 @@ class MToDouble
MOZ_MUST_USE bool writeRecoverData(CompactBufferWriter& writer) const override;
bool canRecoverOnBailout() const override {
- if (input()->type() == MIRType::Value)
+ if (input()->type() == MIRType::Value) {
return false;
- if (input()->type() == MIRType::Symbol)
+ }
+ if (input()->type() == MIRType::Symbol) {
return false;
-
+ }
+ if (input()->type() == MIRType::BigInt) {
+ return false;
+ }
return true;
}
@@ -5253,9 +5268,11 @@ class MToFloat32
setMovable();
// An object might have "valueOf", which means it is effectful.
- // ToNumber(symbol) throws.
- if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol))
+ // ToNumber(symbol) and ToNumber(BigInt) throw.
+ if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol) ||
+ def->mightBeType(MIRType::BigInt)) {
setGuard();
+ }
}
explicit MToFloat32(MDefinition* def, bool mustPreserveNaN)
@@ -5537,9 +5554,11 @@ class MToInt32
setMovable();
// An object might have "valueOf", which means it is effectful.
- // ToNumber(symbol) throws.
- if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol))
+ // ToInt32(symbol) and ToInt32(BigInt) throw.
+ if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol) ||
+ def->mightBeType(MIRType::BigInt)) {
setGuard();
+ }
}
public:
@@ -5594,9 +5613,11 @@ class MTruncateToInt32
setMovable();
// An object might have "valueOf", which means it is effectful.
- // ToInt32(symbol) throws.
- if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol))
+ // ToInt32(symbol) and ToInt32(BigInt) throw.
+ if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol) ||
+ def->mightBeType(MIRType::BigInt)) {
setGuard();
+ }
}
public:
@@ -5639,9 +5660,12 @@ class MToString :
setResultType(MIRType::String);
setMovable();
- // Objects might override toString and Symbols throw.
- if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol))
+ // Objects might override toString; Symbol and BigInts throw. We bailout in
+ // those cases and run side-effects in baseline instead.
+ if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol) ||
+ def->mightBeType(MIRType::BigInt)) {
setGuard();
+ }
}
public:
diff --git a/js/src/jit/MacroAssembler-inl.h b/js/src/jit/MacroAssembler-inl.h
index dd20f67317..336b9e2df8 100644
--- a/js/src/jit/MacroAssembler-inl.h
+++ b/js/src/jit/MacroAssembler-inl.h
@@ -545,6 +545,7 @@ MacroAssembler::branchTestMIRType(Condition cond, const Value& val, MIRType type
case MIRType::Int32: return branchTestInt32(cond, val, label);
case MIRType::String: return branchTestString(cond, val, label);
case MIRType::Symbol: return branchTestSymbol(cond, val, label);
+ case MIRType::BigInt: return branchTestBigInt(cond, val, label);
case MIRType::Object: return branchTestObject(cond, val, label);
case MIRType::Double: return branchTestDouble(cond, val, label);
case MIRType::MagicOptimizedArguments: // Fall through.
diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp
index 0425ac03a1..fdbcc9f23c 100644
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -45,12 +45,13 @@ MacroAssembler::guardTypeSet(const Source& address, const TypeSet* types, Barrie
MOZ_ASSERT(!types->unknown());
Label matched;
- TypeSet::Type tests[8] = {
+ TypeSet::Type tests[9] = {
TypeSet::Int32Type(),
TypeSet::UndefinedType(),
TypeSet::BooleanType(),
TypeSet::StringType(),
TypeSet::SymbolType(),
+ TypeSet::BigIntType(),
TypeSet::NullType(),
TypeSet::MagicArgType(),
TypeSet::AnyObjectType()
@@ -2736,6 +2737,9 @@ MacroAssembler::maybeBranchTestType(MIRType type, MDefinition* maybeDef, Registe
case MIRType::Symbol:
branchTestSymbol(Equal, tag, label);
break;
+ case MIRType::BigInt:
+ branchTestBigInt(Equal, tag, label);
+ break;
case MIRType::Object:
branchTestObject(Equal, tag, label);
break;
diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h
index 6d9888469e..173a39014c 100644
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -1137,6 +1137,7 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void branchTestBoolean(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
inline void branchTestString(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
inline void branchTestSymbol(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
+ inline void branchTestBigInt(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
inline void branchTestNull(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
inline void branchTestObject(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
inline void branchTestPrimitive(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
@@ -1177,6 +1178,10 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void branchTestSymbol(Condition cond, const ValueOperand& value, Label* label)
DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+ inline void branchTestBigInt(Condition cond, const BaseIndex& address, Label* label) PER_SHARED_ARCH;
+ inline void branchTestBigInt(Condition cond, const ValueOperand& value, Label* label)
+ DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+
inline void branchTestNull(Condition cond, const Address& address, Label* label) PER_SHARED_ARCH;
inline void branchTestNull(Condition cond, const BaseIndex& address, Label* label) PER_SHARED_ARCH;
inline void branchTestNull(Condition cond, const ValueOperand& value, Label* label)
@@ -1216,6 +1221,8 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void branchTestBooleanTruthy(bool truthy, const ValueOperand& value, Label* label) PER_ARCH;
inline void branchTestStringTruthy(bool truthy, const ValueOperand& value, Label* label)
DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
+ inline void branchTestBigIntTruthy(bool truthy, const ValueOperand& value, Label* label)
+ DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
private:
@@ -1256,6 +1263,9 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void branchTestSymbolImpl(Condition cond, const T& t, Label* label)
DEFINED_ON(arm, arm64, x86_shared);
template <typename T>
+ inline void branchTestBigIntImpl(Condition cond, const T& t, Label* label)
+ DEFINED_ON(arm, arm64, x86_shared);
+ template <typename T>
inline void branchTestNullImpl(Condition cond, const T& t, Label* label)
DEFINED_ON(arm, arm64, x86_shared);
template <typename T>
diff --git a/js/src/jit/Snapshots.cpp b/js/src/jit/Snapshots.cpp
index 6d9a461412..3111941315 100644
--- a/js/src/jit/Snapshots.cpp
+++ b/js/src/jit/Snapshots.cpp
@@ -404,6 +404,8 @@ ValTypeToString(JSValueType type) {
return "string";
case JSVAL_TYPE_SYMBOL:
return "symbol";
+ case JSVAL_TYPE_BIGINT:
+ return "BigInt";
case JSVAL_TYPE_BOOLEAN:
return "boolean";
case JSVAL_TYPE_OBJECT:
diff --git a/js/src/jit/TypePolicy.cpp b/js/src/jit/TypePolicy.cpp
index 396fdc57f8..1222cdd2b2 100644
--- a/js/src/jit/TypePolicy.cpp
+++ b/js/src/jit/TypePolicy.cpp
@@ -700,7 +700,8 @@ ToDoublePolicy::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins)
case MIRType::Object:
case MIRType::String:
case MIRType::Symbol:
- // Objects might be effectful. Symbols give TypeError.
+ case MIRType::BigInt:
+ // Objects might be effectful. Symbols and BigInts give TypeError.
break;
default:
break;
@@ -748,7 +749,8 @@ ToInt32Policy::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins)
case MIRType::Object:
case MIRType::String:
case MIRType::Symbol:
- // Objects might be effectful. Symbols give TypeError.
+ case MIRType::BigInt:
+ // Objects might be effectful. Symbols and BigInts give TypeError.
break;
default:
break;
@@ -765,7 +767,8 @@ ToStringPolicy::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins)
MOZ_ASSERT(ins->isToString());
MIRType type = ins->getOperand(0)->type();
- if (type == MIRType::Object || type == MIRType::Symbol) {
+ if (type == MIRType::Object || type == MIRType::Symbol ||
+ type == MIRType::BigInt) {
ins->replaceOperand(0, BoxAt(alloc, ins, ins->getOperand(0)));
return true;
}
@@ -955,6 +958,7 @@ StoreUnboxedScalarPolicy::adjustValueInput(TempAllocator& alloc, MInstruction* i
case MIRType::Object:
case MIRType::String:
case MIRType::Symbol:
+ case MIRType::BigInt:
value = BoxAt(alloc, ins, value);
break;
default:
diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp
index 6e5676f153..8802d3582b 100644
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -1236,15 +1236,27 @@ AssertValidSymbolPtr(JSContext* cx, JS::Symbol* sym)
MOZ_ASSERT(sym->getAllocKind() == gc::AllocKind::SYMBOL);
}
+void
+AssertValidBigIntPtr(JSContext* cx, JS::BigInt* bi) {
+ // FIXME: check runtime?
+ MOZ_ASSERT(cx->zone() == bi->zone());
+ MOZ_ASSERT(bi->isAligned());
+ MOZ_ASSERT(bi->isTenured());
+ MOZ_ASSERT(bi->getAllocKind() == gc::AllocKind::BIGINT);
+}
+
void
AssertValidValue(JSContext* cx, Value* v)
{
- if (v->isObject())
+ if (v->isObject()) {
AssertValidObjectPtr(cx, &v->toObject());
- else if (v->isString())
+ } else if (v->isString()) {
AssertValidStringPtr(cx, v->toString());
- else if (v->isSymbol())
+ } else if (v->isSymbol()) {
AssertValidSymbolPtr(cx, v->toSymbol());
+ } else if (v->isBigInt()) {
+ AssertValidBigIntPtr(cx, v->toBigInt());
+ }
}
bool
diff --git a/js/src/jit/VMFunctions.h b/js/src/jit/VMFunctions.h
index 32830038d1..f4280f5800 100644
--- a/js/src/jit/VMFunctions.h
+++ b/js/src/jit/VMFunctions.h
@@ -751,6 +751,7 @@ void AssertValidObjectPtr(JSContext* cx, JSObject* obj);
void AssertValidObjectOrNullPtr(JSContext* cx, JSObject* obj);
void AssertValidStringPtr(JSContext* cx, JSString* str);
void AssertValidSymbolPtr(JSContext* cx, JS::Symbol* sym);
+void AssertValidBigIntPtr(JSContext* cx, JS::BigInt* bi);
void AssertValidValue(JSContext* cx, Value* v);
void MarkValueFromIon(JSRuntime* rt, Value* vp);
diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h
index 2cc26b2242..3fc07e0de5 100644
--- a/js/src/jit/arm/MacroAssembler-arm-inl.h
+++ b/js/src/jit/arm/MacroAssembler-arm-inl.h
@@ -1880,6 +1880,29 @@ MacroAssembler::branchTestSymbolImpl(Condition cond, const T& t, Label* label)
ma_b(label, c);
}
+void MacroAssembler::branchTestBigInt(Condition cond, Register tag, Label* label) {
+ branchTestBigIntImpl(cond, tag, label);
+}
+
+void MacroAssembler::branchTestBigInt(Condition cond, const BaseIndex& address, Label* label) {
+ branchTestBigIntImpl(cond, address, label);
+}
+
+void MacroAssembler::branchTestBigInt(Condition cond, const ValueOperand& value, Label* label) {
+ branchTestBigIntImpl(cond, value, label);
+}
+
+template <typename T>
+void MacroAssembler::branchTestBigIntImpl(Condition cond, const T& t, Label* label) {
+ Condition c = testBigInt(cond, t);
+ ma_b(label, c);
+}
+
+void MacroAssembler::branchTestBigIntTruthy(bool truthy, const ValueOperand& value, Label* label) {
+ Condition c = testBigIntTruthy(truthy, value);
+ ma_b(label, c);
+}
+
void
MacroAssembler::branchTestNull(Condition cond, Register tag, Label* label)
{
diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp
index a50046d697..e099022c27 100644
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -2717,6 +2717,11 @@ MacroAssemblerARMCompat::testSymbol(Assembler::Condition cond, const ValueOperan
return testSymbol(cond, value.typeReg());
}
+Assembler::Condition MacroAssemblerARMCompat::testBigInt(Assembler::Condition cond, const ValueOperand& value)
+{
+ return testBigInt(cond, value.typeReg());
+}
+
Assembler::Condition
MacroAssemblerARMCompat::testObject(Assembler::Condition cond, const ValueOperand& value)
{
@@ -2790,6 +2795,13 @@ MacroAssemblerARMCompat::testSymbol(Assembler::Condition cond, Register tag)
return cond;
}
+Assembler::Condition MacroAssemblerARMCompat::testBigInt(Assembler::Condition cond, Register tag)
+{
+ MOZ_ASSERT(cond == Equal || cond == NotEqual);
+ ma_cmp(tag, ImmTag(JSVAL_TAG_BIGINT));
+ return cond;
+}
+
Assembler::Condition
MacroAssemblerARMCompat::testObject(Assembler::Condition cond, Register tag)
{
@@ -2907,6 +2919,14 @@ MacroAssemblerARMCompat::testObject(Condition cond, const Address& address)
return testObject(cond, scratch);
}
+Assembler::Condition MacroAssemblerARMCompat::testBigInt(Condition cond, const Address& address)
+{
+ MOZ_ASSERT(cond == Equal || cond == NotEqual);
+ ScratchRegisterScope scratch(asMasm());
+ Register tag = extractTag(address, scratch);
+ return testBigInt(cond, tag);
+}
+
Assembler::Condition
MacroAssemblerARMCompat::testNumber(Condition cond, const Address& address)
{
@@ -2993,6 +3013,16 @@ MacroAssemblerARMCompat::testInt32(Condition cond, const BaseIndex& src)
return cond;
}
++Assembler::Condition
+MacroAssemblerARMCompat::testBigInt(Condition cond,const BaseIndex& src)
+{
+ MOZ_ASSERT(cond == Equal || cond == NotEqual);
+ ScratchRegisterScope scratch(asMasm());
+ Register tag = extractTag(src, scratch);
+ ma_cmp(tag, ImmTag(JSVAL_TAG_BIGINT));
+ return cond;
+}
+
Assembler::Condition
MacroAssemblerARMCompat::testObject(Condition cond, const BaseIndex& src)
{
@@ -3736,6 +3766,19 @@ MacroAssemblerARMCompat::testStringTruthy(bool truthy, const ValueOperand& value
return truthy ? Assembler::NotEqual : Assembler::Equal;
}
++Assembler::Condition
+MacroAssemblerARMCompat::testBigIntTruthy(bool truthy, const ValueOperand& value)
+{
+ Register bi = value.payloadReg();
+ ScratchRegisterScope scratch(asMasm());
+ SecondScratchRegisterScope scratch2(asMasm());
+
+ ma_dtr(IsLoad, bi, Imm32(BigInt::offsetOfLengthSignAndReservedBits()),
+ scratch, scratch2);
+ as_cmp(scratch, Imm8(0));
+ return truthy ? Assembler::NotEqual : Assembler::Equal;
+}
+
void
MacroAssemblerARMCompat::floor(FloatRegister input, Register output, Label* bail)
{
diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h
index 2ed9a4f6e1..aaf92539a3 100644
--- a/js/src/jit/arm/MacroAssembler-arm.h
+++ b/js/src/jit/arm/MacroAssembler-arm.h
@@ -695,6 +695,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
Condition testUndefined(Condition cond, const ValueOperand& value);
Condition testString(Condition cond, const ValueOperand& value);
Condition testSymbol(Condition cond, const ValueOperand& value);
+ Condition testBigInt(Condition cond, const ValueOperand& value);
Condition testObject(Condition cond, const ValueOperand& value);
Condition testNumber(Condition cond, const ValueOperand& value);
Condition testMagic(Condition cond, const ValueOperand& value);
@@ -708,6 +709,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
Condition testUndefined(Condition cond, Register tag);
Condition testString(Condition cond, Register tag);
Condition testSymbol(Condition cond, Register tag);
+ Condition testBigInt(Condition cond, Register tag);
Condition testObject(Condition cond, Register tag);
Condition testDouble(Condition cond, Register tag);
Condition testNumber(Condition cond, Register tag);
@@ -723,6 +725,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
Condition testUndefined(Condition cond, const Address& address);
Condition testString(Condition cond, const Address& address);
Condition testSymbol(Condition cond, const Address& address);
+ Condition testBigInt(Condition cond, const Address& address);
Condition testObject(Condition cond, const Address& address);
Condition testNumber(Condition cond, const Address& address);
@@ -731,6 +734,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
Condition testBoolean(Condition cond, const BaseIndex& src);
Condition testString(Condition cond, const BaseIndex& src);
Condition testSymbol(Condition cond, const BaseIndex& src);
+ Condition testBigInt(Condition cond, const BaseIndex& src);
Condition testInt32(Condition cond, const BaseIndex& src);
Condition testObject(Condition cond, const BaseIndex& src);
Condition testDouble(Condition cond, const BaseIndex& src);
@@ -749,6 +753,8 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
void unboxString(const Address& src, Register dest) { unboxNonDouble(src, dest); }
void unboxSymbol(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxSymbol(const Address& src, Register dest) { unboxNonDouble(src, dest); }
+ void unboxBigInt(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
+ void unboxBigInt(const Address& src, Register dest) { unboxNonDouble(src, dest); }
void unboxObject(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxObject(const Address& src, Register dest) { unboxNonDouble(src, dest); }
void unboxObject(const BaseIndex& src, Register dest) { unboxNonDouble(src, dest); }
@@ -797,6 +803,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
Condition testBooleanTruthy(bool truthy, const ValueOperand& operand);
Condition testDoubleTruthy(bool truthy, FloatRegister reg);
Condition testStringTruthy(bool truthy, const ValueOperand& value);
+ Condition testBigIntTruthy(bool truthy, const ValueOperand& value);
void boolValueToFloat32(const ValueOperand& operand, FloatRegister dest);
void int32ValueToFloat32(const ValueOperand& operand, FloatRegister dest);
diff --git a/js/src/jit/mips32/MacroAssembler-mips32-inl.h b/js/src/jit/mips32/MacroAssembler-mips32-inl.h
index 8a2e8c6bfd..a805f7bdb9 100644
--- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h
+++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h
@@ -963,6 +963,19 @@ MacroAssembler::branchTestSymbol(Condition cond, const ValueOperand& value, Labe
branchTestSymbol(cond, value.typeReg(), label);
}
+void MacroAssembler::branchTestBigInt(Condition cond, const ValueOperand& value, Label* label)
+{
+ branchTestBigInt(cond, value.typeReg(), label);
+}
+
+void MacroAssembler::branchTestBigIntTruthy(bool b, const ValueOperand& value, Label* label)
+{
+ Register bi = value.payloadReg();
+ SecondScratchRegisterScope scratch2(*this);
+ ma_lw(scratch2, Address(bi, BigInt::offsetOfLengthSignAndReservedBits()));
+ ma_b(scratch2, Imm32(0), label, b ? NotEqual : Equal);
+}
+
void
MacroAssembler::branchTestNull(Condition cond, const ValueOperand& value, Label* label)
{
diff --git a/js/src/jit/mips64/CodeGenerator-mips64.cpp b/js/src/jit/mips64/CodeGenerator-mips64.cpp
index 7cd90fba7a..8e96171615 100644
--- a/js/src/jit/mips64/CodeGenerator-mips64.cpp
+++ b/js/src/jit/mips64/CodeGenerator-mips64.cpp
@@ -196,6 +196,9 @@ CodeGeneratorMIPS64::visitUnbox(LUnbox* unbox)
case MIRType::Symbol:
masm.unboxSymbol(inputReg, result);
break;
+ case MIRType::BigInt:
+ masm.unboxBigInt(inputReg, result);
+ break;
default:
MOZ_CRASH("Given MIRType cannot be unboxed.");
}
@@ -219,6 +222,9 @@ CodeGeneratorMIPS64::visitUnbox(LUnbox* unbox)
case MIRType::Symbol:
masm.unboxSymbol(inputAddr, result);
break;
+ case MIRType::BigInt:
+ masm.unboxBigInt(inputAddr, result);
+ break;
default:
MOZ_CRASH("Given MIRType cannot be unboxed.");
}
diff --git a/js/src/jit/mips64/MacroAssembler-mips64-inl.h b/js/src/jit/mips64/MacroAssembler-mips64-inl.h
index 4c1f3e37f0..9ed2b35a36 100644
--- a/js/src/jit/mips64/MacroAssembler-mips64-inl.h
+++ b/js/src/jit/mips64/MacroAssembler-mips64-inl.h
@@ -622,6 +622,21 @@ MacroAssembler::branchTestSymbol(Condition cond, const ValueOperand& value, Labe
branchTestSymbol(cond, scratch2, label);
}
+void MacroAssembler::branchTestBigInt(Condition cond, const ValueOperand& value, Label* label)
+{
+ SecondScratchRegisterScope scratch2(*this);
+ splitTag(value, scratch2);
+ branchTestBigInt(cond, scratch2, label);
+}
+
+void MacroAssembler::branchTestBigIntTruthy(bool b, const ValueOperand& value, Label* label)
+{
+ SecondScratchRegisterScope scratch2(*this);
+ unboxBigInt(value, scratch2);
+ loadPtr(Address(scratch2, BigInt::offsetOfLengthSignAndReservedBits()), scratch2);
+ ma_b(scratch2, ImmWord(0), label, b ? NotEqual : Equal);
+}
+
void
MacroAssembler::branchTestNull(Condition cond, const ValueOperand& value, Label* label)
{
diff --git a/js/src/jit/mips64/MacroAssembler-mips64.cpp b/js/src/jit/mips64/MacroAssembler-mips64.cpp
index 96989e393d..df7ec624a9 100644
--- a/js/src/jit/mips64/MacroAssembler-mips64.cpp
+++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp
@@ -1495,6 +1495,21 @@ MacroAssemblerMIPS64Compat::unboxSymbol(Register src, Register dest)
ma_dext(dest, src, Imm32(0), Imm32(JSVAL_TAG_SHIFT));
}
+void MacroAssemblerMIPS64Compat::unboxBigInt(const ValueOperand& operand, Register dest)
+{
+ unboxNonDouble(operand, dest, JSVAL_TYPE_BIGINT);
+}
+
+void MacroAssemblerMIPS64Compat::unboxBigInt(Register src, Register dest)
+{
+ unboxNonDouble(src, dest, JSVAL_TYPE_BIGINT);
+}
+
+void MacroAssemblerMIPS64Compat::unboxBigInt(const Address& src, Register dest)
+{
+ unboxNonDouble(src, dest, JSVAL_TYPE_BIGINT);
+}
+
void
MacroAssemblerMIPS64Compat::unboxSymbol(const Address& src, Register dest)
{
diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h
index 04aa2ea702..3a84b7c0c9 100644
--- a/js/src/jit/mips64/MacroAssembler-mips64.h
+++ b/js/src/jit/mips64/MacroAssembler-mips64.h
@@ -361,6 +361,9 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
void unboxSymbol(const ValueOperand& src, Register dest);
void unboxSymbol(Register src, Register dest);
void unboxSymbol(const Address& src, Register dest);
+ void unboxBigInt(const ValueOperand& operand, Register dest);
+ void unboxBigInt(Register src, Register dest);
+ void unboxBigInt(const Address& src, Register dest);
void unboxObject(const ValueOperand& src, Register dest);
void unboxObject(Register src, Register dest);
void unboxObject(const Address& src, Register dest);
diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h
index 599fe75bfb..f71439a6cc 100644
--- a/js/src/jit/none/MacroAssembler-none.h
+++ b/js/src/jit/none/MacroAssembler-none.h
@@ -359,6 +359,7 @@ class MacroAssemblerNone : public Assembler
template <typename T> void unboxBoolean(T, Register) { MOZ_CRASH(); }
template <typename T> void unboxString(T, Register) { MOZ_CRASH(); }
template <typename T> void unboxSymbol(T, Register) { MOZ_CRASH(); }
+ template <typename T> void unboxBigInt(T, Register) { MOZ_CRASH(); }
template <typename T> void unboxObject(T, Register) { MOZ_CRASH(); }
template <typename T> void unboxDouble(T, FloatRegister) { MOZ_CRASH(); }
void unboxValue(const ValueOperand&, AnyRegister) { MOZ_CRASH(); }
@@ -393,6 +394,7 @@ class MacroAssemblerNone : public Assembler
void loadConstantFloat32(wasm::RawF32, FloatRegister) { MOZ_CRASH(); }
Condition testInt32Truthy(bool, ValueOperand) { MOZ_CRASH(); }
Condition testStringTruthy(bool, ValueOperand) { MOZ_CRASH(); }
+ Condition testBigIntTruthy(bool, ValueOperand) { MOZ_CRASH(); }
template <typename T> void loadUnboxedValue(T, MIRType, AnyRegister) { MOZ_CRASH(); }
template <typename T> void storeUnboxedValue(const ConstantOrRegister&, MIRType, T, MIRType) { MOZ_CRASH(); }
diff --git a/js/src/jit/shared/CodeGenerator-shared.cpp b/js/src/jit/shared/CodeGenerator-shared.cpp
index 16e082745c..3701f24872 100644
--- a/js/src/jit/shared/CodeGenerator-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-shared.cpp
@@ -431,6 +431,7 @@ CodeGeneratorShared::encodeAllocation(LSnapshot* snapshot, MDefinition* mir,
case MIRType::Int32:
case MIRType::String:
case MIRType::Symbol:
+ case MIRType::BigInt:
case MIRType::Object:
case MIRType::ObjectOrNull:
case MIRType::Boolean:
diff --git a/js/src/jit/shared/Lowering-shared-inl.h b/js/src/jit/shared/Lowering-shared-inl.h
index d17a9ba568..cdbba9ef84 100644
--- a/js/src/jit/shared/Lowering-shared-inl.h
+++ b/js/src/jit/shared/Lowering-shared-inl.h
@@ -402,7 +402,8 @@ LIRGeneratorShared::redefine(MDefinition* def, MDefinition* as)
case MIRType::Object:
case MIRType::ObjectOrNull:
case MIRType::String:
- case MIRType::Symbol: {
+ case MIRType::Symbol:
+ case MIRType::BigInt: {
LAssertResultT* check = new(alloc()) LAssertResultT(useRegister(def));
add(check, def->toInstruction());
break;
diff --git a/js/src/jit/shared/Lowering-shared.cpp b/js/src/jit/shared/Lowering-shared.cpp
index 0acf34dfb4..f0f4e5eb85 100644
--- a/js/src/jit/shared/Lowering-shared.cpp
+++ b/js/src/jit/shared/Lowering-shared.cpp
@@ -100,6 +100,9 @@ LIRGeneratorShared::visitConstant(MConstant* ins)
case MIRType::Symbol:
define(new(alloc()) LPointer(ins->toSymbol()), ins);
break;
+ case MIRType::BigInt:
+ define(new (alloc()) LPointer(ins->toBigInt()), ins);
+ break;
case MIRType::Object:
define(new(alloc()) LPointer(&ins->toObject()), ins);
break;
diff --git a/js/src/jit/x64/CodeGenerator-x64.cpp b/js/src/jit/x64/CodeGenerator-x64.cpp
index 61ce8a187c..9dea005abb 100644
--- a/js/src/jit/x64/CodeGenerator-x64.cpp
+++ b/js/src/jit/x64/CodeGenerator-x64.cpp
@@ -121,6 +121,9 @@ CodeGeneratorX64::visitUnbox(LUnbox* unbox)
case MIRType::Symbol:
cond = masm.testSymbol(Assembler::NotEqual, value);
break;
+ case MIRType::BigInt:
+ cond = masm.testBigInt(Assembler::NotEqual, value);
+ break;
default:
MOZ_CRASH("Given MIRType cannot be unboxed.");
}
@@ -145,6 +148,9 @@ CodeGeneratorX64::visitUnbox(LUnbox* unbox)
case MIRType::Symbol:
masm.unboxSymbol(input, result);
break;
+ case MIRType::BigInt:
+ masm.unboxBigInt(input, result);
+ break;
default:
MOZ_CRASH("Given MIRType cannot be unboxed.");
}
diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h
index 3af87e1ef8..7acb2d34f6 100644
--- a/js/src/jit/x64/MacroAssembler-x64.h
+++ b/js/src/jit/x64/MacroAssembler-x64.h
@@ -231,6 +231,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
cmp32(tag, ImmTag(JSVAL_TAG_SYMBOL));
return cond;
}
+ Condition testBigInt(Condition cond, Register tag) {
+ MOZ_ASSERT(cond == Equal || cond == NotEqual);
+ cmp32(tag, ImmTag(JSVAL_TAG_BIGINT));
+ return cond;
+ }
Condition testObject(Condition cond, Register tag) {
MOZ_ASSERT(cond == Equal || cond == NotEqual);
cmp32(tag, ImmTag(JSVAL_TAG_OBJECT));
@@ -306,6 +311,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
splitTag(src, scratch);
return testSymbol(cond, scratch);
}
+ Condition testBigInt(Condition cond, const ValueOperand& src) {
+ ScratchRegisterScope scratch(asMasm());
+ splitTag(src, scratch);
+ return testBigInt(cond, scratch);
+ }
Condition testObject(Condition cond, const ValueOperand& src) {
ScratchRegisterScope scratch(asMasm());
splitTag(src, scratch);
@@ -359,6 +369,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
splitTag(src, scratch);
return testSymbol(cond, scratch);
}
+ Condition testBigInt(Condition cond, const Address& src) {
+ ScratchRegisterScope scratch(asMasm());
+ splitTag(src, scratch);
+ return testBigInt(cond, scratch);
+ }
Condition testObject(Condition cond, const Address& src) {
ScratchRegisterScope scratch(asMasm());
splitTag(src, scratch);
@@ -406,6 +421,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
splitTag(src, scratch);
return testSymbol(cond, scratch);
}
+ Condition testBigInt(Condition cond, const BaseIndex& src) {
+ ScratchRegisterScope scratch(asMasm());
+ splitTag(src, scratch);
+ return testBigInt(cond, scratch);
+ }
Condition testInt32(Condition cond, const BaseIndex& src) {
ScratchRegisterScope scratch(asMasm());
splitTag(src, scratch);
@@ -794,6 +814,9 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
void unboxSymbol(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxSymbol(const Operand& src, Register dest) { unboxNonDouble(src, dest); }
+ void unboxBigInt(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
+ void unboxBigInt(const Operand& src, Register dest) { unboxNonDouble(src, dest); }
+
void unboxObject(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxObject(const Operand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxObject(const Address& src, Register dest) { unboxNonDouble(Operand(src), dest); }
@@ -894,6 +917,13 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
cmp32(Operand(scratch, JSString::offsetOfLength()), Imm32(0));
return truthy ? Assembler::NotEqual : Assembler::Equal;
}
+ Condition testBigIntTruthy(bool truthy, const ValueOperand& value) {
+ ScratchRegisterScope scratch(asMasm());
+ unboxBigInt(value, scratch);
+ cmpPtr(Operand(scratch, BigInt::offsetOfLengthSignAndReservedBits()),
+ ImmWord(0));
+ return truthy ? Assembler::NotEqual : Assembler::Equal;
+ }
template <typename T>
inline void loadInt32OrDouble(const T& src, FloatRegister dest);
diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h
index e7f058c396..36f3a008a9 100644
--- a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h
+++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h
@@ -944,6 +944,30 @@ MacroAssembler::branchTestSymbolImpl(Condition cond, const T& t, Label* label)
j(cond, label);
}
+void MacroAssembler::branchTestBigInt(Condition cond, Register tag, Label* label) {
+ branchTestBigIntImpl(cond, tag, label);
+}
+
+void MacroAssembler::branchTestBigInt(Condition cond, const BaseIndex& address, Label* label) {
+ branchTestBigIntImpl(cond, address, label);
+}
+
+void MacroAssembler::branchTestBigInt(Condition cond, const ValueOperand& value, Label* label) {
+ branchTestBigIntImpl(cond, value, label);
+}
+
+template <typename T>
+void MacroAssembler::branchTestBigIntImpl(Condition cond, const T& t, Label* label) {
+ cond = testBigInt(cond, t);
+ j(cond, label);
+}
+
+void MacroAssembler::branchTestBigIntTruthy(bool truthy, const ValueOperand& value, Label* label)
+{
+ Condition cond = testBigIntTruthy(truthy, value);
+ j(cond, label);
+}
+
void
MacroAssembler::branchTestNull(Condition cond, Register tag, Label* label)
{
diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h
index 01efd007d3..cbe1d6da8c 100644
--- a/js/src/jit/x86/MacroAssembler-x86.h
+++ b/js/src/jit/x86/MacroAssembler-x86.h
@@ -294,6 +294,11 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
cmp32(tag, ImmTag(JSVAL_TAG_SYMBOL));
return cond;
}
+ Condition testBigInt(Condition cond, Register tag) {
+ MOZ_ASSERT(cond == Equal || cond == NotEqual);
+ cmp32(tag, ImmTag(JSVAL_TAG_BIGINT));
+ return cond;
+ }
Condition testObject(Condition cond, Register tag) {
MOZ_ASSERT(cond == Equal || cond == NotEqual);
cmp32(tag, ImmTag(JSVAL_TAG_OBJECT));
@@ -410,6 +415,9 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
Condition testSymbol(Condition cond, const ValueOperand& value) {
return testSymbol(cond, value.typeReg());
}
+ Condition testBigInt(Condition cond, const ValueOperand& value) {
+ return testBigInt(cond, value.typeReg());
+ }
Condition testObject(Condition cond, const ValueOperand& value) {
return testObject(cond, value.typeReg());
}
@@ -455,6 +463,11 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
cmp32(tagOf(address), ImmTag(JSVAL_TAG_SYMBOL));
return cond;
}
+ Condition testBigInt(Condition cond, const BaseIndex& address) {
+ MOZ_ASSERT(cond == Equal || cond == NotEqual);
+ cmp32(tagOf(address), ImmTag(JSVAL_TAG_BIGINT));
+ return cond;
+ }
Condition testInt32(Condition cond, const BaseIndex& address) {
MOZ_ASSERT(cond == Equal || cond == NotEqual);
cmp32(tagOf(address), ImmTag(JSVAL_TAG_INT32));
@@ -696,6 +709,8 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
void unboxString(const Address& src, Register dest) { unboxNonDouble(src, dest); }
void unboxSymbol(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxSymbol(const Address& src, Register dest) { unboxNonDouble(src, dest); }
+ void unboxBigInt(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
+ void unboxBigInt(const Address& src, Register dest) { unboxNonDouble(src, dest); }
void unboxObject(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxObject(const Address& src, Register dest) { unboxNonDouble(src, dest); }
void unboxObject(const BaseIndex& src, Register dest) { unboxNonDouble(src, dest); }
@@ -793,6 +808,12 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
cmp32(Operand(string, JSString::offsetOfLength()), Imm32(0));
return truthy ? Assembler::NotEqual : Assembler::Equal;
}
+ Condition testBigIntTruthy(bool truthy, const ValueOperand& value) {
+ Register bi = value.payloadReg();
+ cmpPtr(Operand(bi, BigInt::offsetOfLengthSignAndReservedBits()),
+ ImmWord(0));
+ return truthy ? Assembler::NotEqual : Assembler::Equal;
+ }
template <typename T>
inline void loadInt32OrDouble(const T& src, FloatRegister dest);
diff --git a/js/src/vm/BigIntType.h b/js/src/vm/BigIntType.h
index cfc3489934..0ccba99634 100644
--- a/js/src/vm/BigIntType.h
+++ b/js/src/vm/BigIntType.h
@@ -80,6 +80,11 @@ class BigInt final : public js::gc::TenuredCell {
bool isZero() const { return digitLength() == 0; }
bool isNegative() const { return lengthSignAndReservedBits_ & SignBit; }
+ // Offset for direct access from JIT code.
+ static constexpr size_t offsetOfLengthSignAndReservedBits() {
+ return offsetof(BigInt, lengthSignAndReservedBits_);
+ }
+
void initializeDigitsToZero();
void traceChildren(JSTracer* trc);
diff --git a/js/src/vm/TypeInference.cpp b/js/src/vm/TypeInference.cpp
index 83da598815..a36926eb94 100644
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -368,6 +368,8 @@ TypeSet::mightBeMIRType(jit::MIRType type) const
return baseFlags() & TYPE_FLAG_STRING;
case jit::MIRType::Symbol:
return baseFlags() & TYPE_FLAG_SYMBOL;
+ case jit::MIRType::BigInt:
+ return baseFlags() & TYPE_FLAG_BIGINT;
case jit::MIRType::MagicOptimizedArguments:
return baseFlags() & TYPE_FLAG_LAZYARGS;
case jit::MIRType::MagicHole:
@@ -1635,6 +1637,8 @@ GetMIRTypeFromTypeFlags(TypeFlags flags)
return jit::MIRType::String;
case TYPE_FLAG_SYMBOL:
return jit::MIRType::Symbol;
+ case TYPE_FLAG_BIGINT:
+ return jit::MIRType::BigInt;
case TYPE_FLAG_LAZYARGS:
return jit::MIRType::MagicOptimizedArguments;
case TYPE_FLAG_ANYOBJECT: