mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 03:35:33 +00:00
Bug 1165053 - Part 0.2: Inline PossiblyWrappedArrayBufferByteLength self-hosting intrinsic. r=jwalden
This commit is contained in:
parent
2e027fb88d
commit
863f2c7e9c
@ -0,0 +1,41 @@
|
||||
var PossiblyWrappedArrayBufferByteLength = getSelfHostedValue("PossiblyWrappedArrayBufferByteLength");
|
||||
|
||||
setJitCompilerOption("ion.warmup.trigger", 50);
|
||||
|
||||
function testBasic() {
|
||||
var arr = [1, 2, 3];
|
||||
var tarr = new Int32Array(arr);
|
||||
var abuf = tarr.buffer;
|
||||
|
||||
var arrLength = arr.length;
|
||||
var bytesPerElement = Int32Array.BYTES_PER_ELEMENT;
|
||||
|
||||
var f = function() {
|
||||
assertEq(PossiblyWrappedArrayBufferByteLength(abuf), arrLength * bytesPerElement);
|
||||
};
|
||||
do {
|
||||
f();
|
||||
} while (!inIon());
|
||||
}
|
||||
testBasic();
|
||||
|
||||
function testWrapped() {
|
||||
var g = newGlobal();
|
||||
g.eval(`
|
||||
var arr = [1, 2, 3];
|
||||
var tarr = new Int32Array(arr);
|
||||
var abuf = tarr.buffer;
|
||||
`);
|
||||
|
||||
var abuf = g.abuf;
|
||||
var arrLength = g.arr.length;
|
||||
var bytesPerElement = g.Int32Array.BYTES_PER_ELEMENT;
|
||||
|
||||
var f = function() {
|
||||
assertEq(PossiblyWrappedArrayBufferByteLength(abuf), arrLength * bytesPerElement);
|
||||
};
|
||||
do {
|
||||
f();
|
||||
} while (!inIon());
|
||||
}
|
||||
testWrapped();
|
@ -111,6 +111,8 @@
|
||||
\
|
||||
_(IntrinsicGetNextMapEntryForIterator) \
|
||||
\
|
||||
_(IntrinsicPossiblyWrappedArrayBufferByteLength) \
|
||||
\
|
||||
_(IntrinsicIsTypedArray) \
|
||||
_(IntrinsicIsPossiblyWrappedTypedArray) \
|
||||
_(IntrinsicTypedArrayLength) \
|
||||
|
@ -9500,6 +9500,15 @@ IonBuilder::jsop_getelem_dense(MDefinition* obj, MDefinition* index, JSValueType
|
||||
return pushTypeBarrier(load, types, barrier);
|
||||
}
|
||||
|
||||
MInstruction*
|
||||
IonBuilder::addArrayBufferByteLength(MDefinition* obj)
|
||||
{
|
||||
MLoadFixedSlot* ins = MLoadFixedSlot::New(alloc(), obj, ArrayBufferObject::BYTE_LENGTH_SLOT);
|
||||
current->add(ins);
|
||||
ins->setResultType(MIRType_Int32);
|
||||
return ins;
|
||||
}
|
||||
|
||||
void
|
||||
IonBuilder::addTypedArrayLengthAndData(MDefinition* obj,
|
||||
BoundsChecking checking,
|
||||
|
@ -623,6 +623,8 @@ class IonBuilder
|
||||
|
||||
enum BoundsChecking { DoBoundsCheck, SkipBoundsCheck };
|
||||
|
||||
MInstruction* addArrayBufferByteLength(MDefinition* obj);
|
||||
|
||||
// Add instructions to compute a typed array's length and data. Also
|
||||
// optionally convert |*index| into a bounds-checked definition, if
|
||||
// requested.
|
||||
@ -844,6 +846,9 @@ class IonBuilder
|
||||
// Map intrinsics.
|
||||
InliningStatus inlineGetNextMapEntryForIterator(CallInfo& callInfo);
|
||||
|
||||
// ArrayBuffer intrinsics.
|
||||
InliningStatus inlinePossiblyWrappedArrayBufferByteLength(CallInfo& callInfo);
|
||||
|
||||
// TypedArray intrinsics.
|
||||
enum WrappingBehavior { AllowWrappedTypedArrays, RejectWrappedTypedArrays };
|
||||
InliningStatus inlineIsTypedArrayHelper(CallInfo& callInfo, WrappingBehavior wrappingBehavior);
|
||||
|
@ -264,6 +264,10 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target)
|
||||
case InlinableNative::IntrinsicGetNextMapEntryForIterator:
|
||||
return inlineGetNextMapEntryForIterator(callInfo);
|
||||
|
||||
// ArrayBuffer intrinsics.
|
||||
case InlinableNative::IntrinsicPossiblyWrappedArrayBufferByteLength:
|
||||
return inlinePossiblyWrappedArrayBufferByteLength(callInfo);
|
||||
|
||||
// TypedArray intrinsics.
|
||||
case InlinableNative::IntrinsicIsTypedArray:
|
||||
return inlineIsTypedArray(callInfo);
|
||||
@ -2234,6 +2238,40 @@ IonBuilder::inlineGetNextMapEntryForIterator(CallInfo& callInfo)
|
||||
return InliningStatus_Inlined;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsArrayBufferObject(CompilerConstraintList* constraints, MDefinition* def)
|
||||
{
|
||||
MOZ_ASSERT(def->type() == MIRType_Object);
|
||||
|
||||
TemporaryTypeSet* types = def->resultTypeSet();
|
||||
if (!types)
|
||||
return false;
|
||||
|
||||
return types->getKnownClass(constraints) == &ArrayBufferObject::class_;
|
||||
}
|
||||
|
||||
IonBuilder::InliningStatus
|
||||
IonBuilder::inlinePossiblyWrappedArrayBufferByteLength(CallInfo& callInfo)
|
||||
{
|
||||
MOZ_ASSERT(!callInfo.constructing());
|
||||
MOZ_ASSERT(callInfo.argc() == 1);
|
||||
|
||||
MDefinition* objArg = callInfo.getArg(0);
|
||||
if (objArg->type() != MIRType_Object)
|
||||
return InliningStatus_NotInlined;
|
||||
if (getInlineReturnType() != MIRType_Int32)
|
||||
return InliningStatus_NotInlined;
|
||||
|
||||
if (!IsArrayBufferObject(constraints(), objArg))
|
||||
return InliningStatus_NotInlined;
|
||||
|
||||
MInstruction* ins = addArrayBufferByteLength(objArg);
|
||||
current->push(ins);
|
||||
|
||||
callInfo.setImplicitlyUsedUnchecked();
|
||||
return InliningStatus_Inlined;
|
||||
}
|
||||
|
||||
IonBuilder::InliningStatus
|
||||
IonBuilder::inlineIsTypedArrayHelper(CallInfo& callInfo, WrappingBehavior wrappingBehavior)
|
||||
{
|
||||
|
@ -2169,7 +2169,8 @@ static const JSFunctionSpec intrinsic_functions[] = {
|
||||
intrinsic_IsInstanceOfBuiltin<SharedArrayBufferObject>, 1,0),
|
||||
|
||||
JS_FN("ArrayBufferByteLength", intrinsic_ArrayBufferByteLength, 1,0),
|
||||
JS_FN("PossiblyWrappedArrayBufferByteLength", intrinsic_PossiblyWrappedArrayBufferByteLength, 1,0),
|
||||
JS_INLINABLE_FN("PossiblyWrappedArrayBufferByteLength", intrinsic_PossiblyWrappedArrayBufferByteLength, 1,0,
|
||||
IntrinsicPossiblyWrappedArrayBufferByteLength),
|
||||
JS_FN("ArrayBufferCopyData", intrinsic_ArrayBufferCopyData, 4,0),
|
||||
|
||||
JS_FN("IsUint8TypedArray", intrinsic_IsUint8TypedArray, 1,0),
|
||||
|
Loading…
Reference in New Issue
Block a user