mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 11:45:37 +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) \
|
_(IntrinsicGetNextMapEntryForIterator) \
|
||||||
\
|
\
|
||||||
|
_(IntrinsicPossiblyWrappedArrayBufferByteLength) \
|
||||||
|
\
|
||||||
_(IntrinsicIsTypedArray) \
|
_(IntrinsicIsTypedArray) \
|
||||||
_(IntrinsicIsPossiblyWrappedTypedArray) \
|
_(IntrinsicIsPossiblyWrappedTypedArray) \
|
||||||
_(IntrinsicTypedArrayLength) \
|
_(IntrinsicTypedArrayLength) \
|
||||||
|
@ -9500,6 +9500,15 @@ IonBuilder::jsop_getelem_dense(MDefinition* obj, MDefinition* index, JSValueType
|
|||||||
return pushTypeBarrier(load, types, barrier);
|
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
|
void
|
||||||
IonBuilder::addTypedArrayLengthAndData(MDefinition* obj,
|
IonBuilder::addTypedArrayLengthAndData(MDefinition* obj,
|
||||||
BoundsChecking checking,
|
BoundsChecking checking,
|
||||||
|
@ -623,6 +623,8 @@ class IonBuilder
|
|||||||
|
|
||||||
enum BoundsChecking { DoBoundsCheck, SkipBoundsCheck };
|
enum BoundsChecking { DoBoundsCheck, SkipBoundsCheck };
|
||||||
|
|
||||||
|
MInstruction* addArrayBufferByteLength(MDefinition* obj);
|
||||||
|
|
||||||
// Add instructions to compute a typed array's length and data. Also
|
// Add instructions to compute a typed array's length and data. Also
|
||||||
// optionally convert |*index| into a bounds-checked definition, if
|
// optionally convert |*index| into a bounds-checked definition, if
|
||||||
// requested.
|
// requested.
|
||||||
@ -844,6 +846,9 @@ class IonBuilder
|
|||||||
// Map intrinsics.
|
// Map intrinsics.
|
||||||
InliningStatus inlineGetNextMapEntryForIterator(CallInfo& callInfo);
|
InliningStatus inlineGetNextMapEntryForIterator(CallInfo& callInfo);
|
||||||
|
|
||||||
|
// ArrayBuffer intrinsics.
|
||||||
|
InliningStatus inlinePossiblyWrappedArrayBufferByteLength(CallInfo& callInfo);
|
||||||
|
|
||||||
// TypedArray intrinsics.
|
// TypedArray intrinsics.
|
||||||
enum WrappingBehavior { AllowWrappedTypedArrays, RejectWrappedTypedArrays };
|
enum WrappingBehavior { AllowWrappedTypedArrays, RejectWrappedTypedArrays };
|
||||||
InliningStatus inlineIsTypedArrayHelper(CallInfo& callInfo, WrappingBehavior wrappingBehavior);
|
InliningStatus inlineIsTypedArrayHelper(CallInfo& callInfo, WrappingBehavior wrappingBehavior);
|
||||||
|
@ -264,6 +264,10 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target)
|
|||||||
case InlinableNative::IntrinsicGetNextMapEntryForIterator:
|
case InlinableNative::IntrinsicGetNextMapEntryForIterator:
|
||||||
return inlineGetNextMapEntryForIterator(callInfo);
|
return inlineGetNextMapEntryForIterator(callInfo);
|
||||||
|
|
||||||
|
// ArrayBuffer intrinsics.
|
||||||
|
case InlinableNative::IntrinsicPossiblyWrappedArrayBufferByteLength:
|
||||||
|
return inlinePossiblyWrappedArrayBufferByteLength(callInfo);
|
||||||
|
|
||||||
// TypedArray intrinsics.
|
// TypedArray intrinsics.
|
||||||
case InlinableNative::IntrinsicIsTypedArray:
|
case InlinableNative::IntrinsicIsTypedArray:
|
||||||
return inlineIsTypedArray(callInfo);
|
return inlineIsTypedArray(callInfo);
|
||||||
@ -2234,6 +2238,40 @@ IonBuilder::inlineGetNextMapEntryForIterator(CallInfo& callInfo)
|
|||||||
return InliningStatus_Inlined;
|
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::InliningStatus
|
||||||
IonBuilder::inlineIsTypedArrayHelper(CallInfo& callInfo, WrappingBehavior wrappingBehavior)
|
IonBuilder::inlineIsTypedArrayHelper(CallInfo& callInfo, WrappingBehavior wrappingBehavior)
|
||||||
{
|
{
|
||||||
|
@ -2169,7 +2169,8 @@ static const JSFunctionSpec intrinsic_functions[] = {
|
|||||||
intrinsic_IsInstanceOfBuiltin<SharedArrayBufferObject>, 1,0),
|
intrinsic_IsInstanceOfBuiltin<SharedArrayBufferObject>, 1,0),
|
||||||
|
|
||||||
JS_FN("ArrayBufferByteLength", intrinsic_ArrayBufferByteLength, 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("ArrayBufferCopyData", intrinsic_ArrayBufferCopyData, 4,0),
|
||||||
|
|
||||||
JS_FN("IsUint8TypedArray", intrinsic_IsUint8TypedArray, 1,0),
|
JS_FN("IsUint8TypedArray", intrinsic_IsUint8TypedArray, 1,0),
|
||||||
|
Loading…
Reference in New Issue
Block a user