Bug 1352006 - Inline NewArrayIterator in Ion. r=jandem

This commit is contained in:
Tom Schuster 2017-04-03 22:24:03 +02:00
Родитель e0317a08e6
Коммит 7c9aab27bc
17 изменённых файлов: 142 добавлений и 8 удалений

Просмотреть файл

@ -1914,6 +1914,11 @@ GetTemplateObjectForNative(JSContext* cx, HandleFunction target, const CallArgs&
return !!res;
}
if (native == js::intrinsic_NewArrayIterator) {
res.set(NewArrayIteratorObject(cx, TenuredObject));
return !!res;
}
if (JitSupportsSimd() && GetTemplateObjectForSimd(cx, target, res))
return !!res;

Просмотреть файл

@ -5635,6 +5635,26 @@ CodeGenerator::visitNewArrayDynamicLength(LNewArrayDynamicLength* lir)
masm.bind(ool->rejoin());
}
typedef ArrayIteratorObject* (*NewArrayIteratorObjectFn)(JSContext*, NewObjectKind);
static const VMFunction NewArrayIteratorObjectInfo =
FunctionInfo<NewArrayIteratorObjectFn>(NewArrayIteratorObject, "NewArrayIteratorObject");
void
CodeGenerator::visitNewArrayIterator(LNewArrayIterator* lir)
{
Register objReg = ToRegister(lir->output());
Register tempReg = ToRegister(lir->temp());
JSObject* templateObject = lir->mir()->templateObject();
OutOfLineCode* ool = oolCallVM(NewArrayIteratorObjectInfo, lir,
ArgList(Imm32(GenericObject)),
StoreRegisterTo(objReg));
masm.createGCObject(objReg, tempReg, templateObject, gc::DefaultHeap, ool->entry());
masm.bind(ool->rejoin());
}
typedef TypedArrayObject* (*TypedArrayConstructorOneArgFn)(JSContext*, HandleObject, int32_t length);
static const VMFunction TypedArrayConstructorOneArgInfo =
FunctionInfo<TypedArrayConstructorOneArgFn>(TypedArrayCreateWithTemplate,

Просмотреть файл

@ -198,6 +198,7 @@ class CodeGenerator final : public CodeGeneratorSpecific
void visitOutOfLineNewArray(OutOfLineNewArray* ool);
void visitNewArrayCopyOnWrite(LNewArrayCopyOnWrite* lir);
void visitNewArrayDynamicLength(LNewArrayDynamicLength* lir);
void visitNewArrayIterator(LNewArrayIterator* lir);
void visitNewTypedArray(LNewTypedArray* lir);
void visitNewTypedArrayDynamicLength(LNewTypedArrayDynamicLength* lir);
void visitNewObjectVMCall(LNewObject* lir);

Просмотреть файл

@ -129,6 +129,8 @@
\
_(IntrinsicGetNextSetEntryForIterator) \
\
_(IntrinsicNewArrayIterator) \
\
_(IntrinsicArrayBufferByteLength) \
_(IntrinsicPossiblyWrappedArrayBufferByteLength) \
\

Просмотреть файл

@ -631,6 +631,9 @@ class IonBuilder
InliningResult inlineArraySlice(CallInfo& callInfo);
InliningResult inlineArrayJoin(CallInfo& callInfo);
// Array intrinsics.
InliningResult inlineNewArrayIterator(CallInfo& callInfo);
// Math natives.
InliningResult inlineMathAbs(CallInfo& callInfo);
InliningResult inlineMathFloor(CallInfo& callInfo);

Просмотреть файл

@ -243,6 +243,14 @@ LIRGenerator::visitNewArrayDynamicLength(MNewArrayDynamicLength* ins)
assignSafepoint(lir, ins);
}
void
LIRGenerator::visitNewArrayIterator(MNewArrayIterator* ins)
{
LNewArrayIterator* lir = new(alloc()) LNewArrayIterator(temp());
define(lir, ins);
assignSafepoint(lir, ins);
}
void
LIRGenerator::visitNewTypedArray(MNewTypedArray* ins)
{

Просмотреть файл

@ -78,6 +78,7 @@ class LIRGenerator : public LIRGeneratorSpecific
void visitNewArray(MNewArray* ins);
void visitNewArrayCopyOnWrite(MNewArrayCopyOnWrite* ins);
void visitNewArrayDynamicLength(MNewArrayDynamicLength* ins);
void visitNewArrayIterator(MNewArrayIterator* ins);
void visitNewTypedArray(MNewTypedArray* ins);
void visitNewTypedArrayDynamicLength(MNewTypedArrayDynamicLength* ins);
void visitNewObject(MNewObject* ins);

Просмотреть файл

@ -88,6 +88,10 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target)
case InlinableNative::ArraySlice:
return inlineArraySlice(callInfo);
// Array intrinsics.
case InlinableNative::IntrinsicNewArrayIterator:
return inlineNewArrayIterator(callInfo);
// Atomic natives.
case InlinableNative::AtomicsCompareExchange:
return inlineAtomicsCompareExchange(callInfo);
@ -886,6 +890,32 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo)
return InliningStatus_Inlined;
}
IonBuilder::InliningResult
IonBuilder::inlineNewArrayIterator(CallInfo& callInfo)
{
if (callInfo.argc() != 0 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
JSObject* templateObject = inspector->getTemplateObjectForNative(pc, js::intrinsic_NewArrayIterator);
if (!templateObject)
return InliningStatus_NotInlined;
MOZ_ASSERT(templateObject->is<ArrayIteratorObject>());
callInfo.setImplicitlyUsedUnchecked();
MConstant* templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject);
current->add(templateConst);
MNewArrayIterator* ins = MNewArrayIterator::New(alloc(), constraints(), templateConst);
current->add(ins);
current->push(ins);
MOZ_TRY(resumeAfter(ins));
return InliningStatus_Inlined;
}
IonBuilder::InliningResult
IonBuilder::inlineMathAbs(CallInfo& callInfo)
{

Просмотреть файл

@ -3532,6 +3532,33 @@ class MNewObject
}
};
class MNewArrayIterator
: public MUnaryInstruction,
public NoTypePolicy::Data
{
explicit MNewArrayIterator(CompilerConstraintList* constraints, MConstant* templateConst)
: MUnaryInstruction(templateConst)
{
setResultType(MIRType::Object);
setResultTypeSet(MakeSingletonTypeSet(constraints, templateObject()));
templateConst->setEmittedAtUses();
}
public:
INSTRUCTION_HEADER(NewArrayIterator)
TRIVIAL_NEW_WRAPPERS
JSObject* templateObject() {
return getOperand(0)->toConstant()->toObjectOrNull();
}
AliasSet getAliasSet() const override {
return AliasSet::None();
}
};
class MNewTypedObject : public MNullaryInstruction
{
CompilerGCPointer<InlineTypedObject*> templateObject_;

Просмотреть файл

@ -133,6 +133,7 @@ namespace jit {
_(NewArray) \
_(NewArrayCopyOnWrite) \
_(NewArrayDynamicLength) \
_(NewArrayIterator) \
_(NewTypedArray) \
_(NewTypedArrayDynamicLength) \
_(NewObject) \

Просмотреть файл

@ -282,6 +282,7 @@ template <> struct TypeToDataType<NamedLambdaObject*> { static const DataType re
template <> struct TypeToDataType<LexicalEnvironmentObject*> { static const DataType result = Type_Object; };
template <> struct TypeToDataType<ArrayObject*> { static const DataType result = Type_Object; };
template <> struct TypeToDataType<TypedArrayObject*> { static const DataType result = Type_Object; };
template <> struct TypeToDataType<ArrayIteratorObject*> { static const DataType result = Type_Object; };
template <> struct TypeToDataType<JSString*> { static const DataType result = Type_Object; };
template <> struct TypeToDataType<JSFlatString*> { static const DataType result = Type_Object; };
template <> struct TypeToDataType<HandleObject> { static const DataType result = Type_Handle; };

Просмотреть файл

@ -1062,6 +1062,24 @@ class LNewArrayDynamicLength : public LInstructionHelper<1, 1, 1>
}
};
class LNewArrayIterator : public LInstructionHelper<1, 0, 1>
{
public:
LIR_HEADER(NewArrayIterator)
explicit LNewArrayIterator(const LDefinition& temp) {
setTemp(0, temp);
}
const LDefinition* temp() {
return getTemp(0);
}
MNewArrayIterator* mir() const {
return mir_->toNewArrayIterator();
}
};
class LNewTypedArray : public LInstructionHelper<1, 0, 2>
{
public:

Просмотреть файл

@ -67,6 +67,7 @@
_(NewArray) \
_(NewArrayCopyOnWrite) \
_(NewArrayDynamicLength) \
_(NewArrayIterator) \
_(NewTypedArray) \
_(NewTypedArrayDynamicLength) \
_(NewObject) \

Просмотреть файл

@ -1134,6 +1134,17 @@ const Class ArrayIteratorObject::class_ = {
JSCLASS_HAS_RESERVED_SLOTS(ArrayIteratorSlotCount)
};
ArrayIteratorObject*
js::NewArrayIteratorObject(JSContext* cx, NewObjectKind newKind)
{
RootedObject proto(cx, GlobalObject::getOrCreateArrayIteratorPrototype(cx, cx->global()));
if (!proto)
return nullptr;
return NewObjectWithGivenProto<ArrayIteratorObject>(cx, proto, newKind);
}
static const JSFunctionSpec array_iterator_methods[] = {
JS_SELF_HOSTED_FN("next", "ArrayIteratorNext", 0, 0),
JS_FS_END

Просмотреть файл

@ -145,6 +145,9 @@ class ArrayIteratorObject : public JSObject
static const Class class_;
};
ArrayIteratorObject*
NewArrayIteratorObject(JSContext* cx, NewObjectKind newKind = GenericObject);
class StringIteratorObject : public JSObject
{
public:

Просмотреть файл

@ -18,6 +18,7 @@
#include "jsfriendapi.h"
#include "jsfun.h"
#include "jshashutil.h"
#include "jsiter.h"
#include "jsstr.h"
#include "jsweakmap.h"
#include "jswrapper.h"
@ -754,17 +755,13 @@ intrinsic_GetIteratorPrototype(JSContext* cx, unsigned argc, Value* vp)
return true;
}
static bool
intrinsic_NewArrayIterator(JSContext* cx, unsigned argc, Value* vp)
bool
js::intrinsic_NewArrayIterator(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
MOZ_ASSERT(args.length() == 0);
RootedObject proto(cx, GlobalObject::getOrCreateArrayIteratorPrototype(cx, cx->global()));
if (!proto)
return false;
JSObject* obj = NewObjectWithGivenProto(cx, &ArrayIteratorObject::class_, proto);
JSObject* obj = NewArrayIteratorObject(cx);
if (!obj)
return false;
@ -2441,7 +2438,9 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_FN("GetIteratorPrototype", intrinsic_GetIteratorPrototype, 0,0),
JS_FN("NewArrayIterator", intrinsic_NewArrayIterator, 0,0),
JS_INLINABLE_FN("NewArrayIterator", intrinsic_NewArrayIterator, 0,0,
IntrinsicNewArrayIterator),
JS_FN("CallArrayIteratorMethodIfWrapped",
CallNonGenericSelfhostedMethod<Is<ArrayIteratorObject>>, 2,0),

Просмотреть файл

@ -47,6 +47,9 @@ CallSelfHostedFunction(JSContext* cx, HandlePropertyName name, HandleValue thisv
bool
intrinsic_StringSplitString(JSContext* cx, unsigned argc, JS::Value* vp);
bool
intrinsic_NewArrayIterator(JSContext* cx, unsigned argc, JS::Value* vp);
} /* namespace js */
#endif /* vm_SelfHosting_h_ */