From fba7012b6a103ccbbb5adef10086cf7f4c5dc456 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Tue, 28 Jan 2014 04:33:00 +0100 Subject: [PATCH] Bug 961821: jit-support for writes into TypedObject arrays. As part of above, alpha-renamed IonBuilder::setElemTryTyped to IonBuilder::setElemTryTypedArray to keep clear the current distinction between TypedObject and TypedArray. Drive-by fix: Reference to Bug 894105 in comment had off-by-one typo. Bug 961821: jit-support for writes into TypedObject arrays (r=nmatsakis). As part of above, alpha-renamed IonBuilder::setElemTryTyped to IonBuilder::setElemTryTypedArray to keep clear the current distinction between TypedObject and TypedArray. Drive-by fix: Reference to Bug 894105 in comment had off-by-one typo. --- js/src/jit/IonBuilder.cpp | 91 +++++++++++++++++++++++++++++++++++++-- js/src/jit/IonBuilder.h | 11 ++++- 2 files changed, 97 insertions(+), 5 deletions(-) diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index ddf1f9ec9717..adb7b81c620e 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -6635,7 +6635,7 @@ IonBuilder::getElemTryTypedObject(bool *emitted, MDefinition *obj, MDefinition * switch (elemTypeReprs.kind()) { case TypeRepresentation::X4: - // FIXME (bug 894104): load into a MIRType_float32x4 etc + // FIXME (bug 894105): load into a MIRType_float32x4 etc return true; case TypeRepresentation::Struct: @@ -7350,10 +7350,13 @@ IonBuilder::jsop_setelem() MDefinition *index = current->pop(); MDefinition *object = current->pop(); + if (!setElemTryTypedObject(&emitted, object, index, value) || emitted) + return emitted; + if (!setElemTryTypedStatic(&emitted, object, index, value) || emitted) return emitted; - if (!setElemTryTyped(&emitted, object, index, value) || emitted) + if (!setElemTryTypedArray(&emitted, object, index, value) || emitted) return emitted; if (!setElemTryDense(&emitted, object, index, value) || emitted) @@ -7376,6 +7379,86 @@ IonBuilder::jsop_setelem() return resumeAfter(ins); } +bool +IonBuilder::setElemTryTypedObject(bool *emitted, MDefinition *obj, + MDefinition *index, MDefinition *value) +{ + JS_ASSERT(*emitted == false); + + TypeRepresentationSet objTypeReprs; + if (!lookupTypeRepresentationSet(obj, &objTypeReprs)) + return false; + + if (!objTypeReprs.allOfArrayKind()) + return true; + + TypeRepresentationSet elemTypeReprs; + if (!objTypeReprs.arrayElementType(*this, &elemTypeReprs)) + return false; + if (elemTypeReprs.empty()) + return true; + + JS_ASSERT(TypeRepresentation::isSized(elemTypeReprs.kind())); + + size_t elemSize; + if (!elemTypeReprs.allHaveSameSize(&elemSize)) + return true; + + switch (elemTypeReprs.kind()) { + case TypeRepresentation::X4: + // FIXME (bug 894105): store a MIRType_float32x4 etc + return true; + + case TypeRepresentation::Reference: + case TypeRepresentation::Struct: + case TypeRepresentation::SizedArray: + case TypeRepresentation::UnsizedArray: + // For now, only optimize storing scalars. + return true; + + case TypeRepresentation::Scalar: + return setElemTryScalarPropOfTypedObject(emitted, + obj, + index, + objTypeReprs, + value, + elemTypeReprs, + elemSize); + } + + MOZ_ASSUME_UNREACHABLE("Bad kind"); +} + +bool +IonBuilder::setElemTryScalarPropOfTypedObject(bool *emitted, + MDefinition *obj, + MDefinition *index, + TypeRepresentationSet objTypeReprs, + MDefinition *value, + TypeRepresentationSet elemTypeReprs, + size_t elemSize) +{ + // Must always be storing the same scalar type + if (!elemTypeReprs.singleton()) + return true; + + ScalarTypeRepresentation *elemTypeRepr = + elemTypeReprs.getTypeRepresentation()->asScalar(); + + MDefinition *indexAsByteOffset; + if (!checkTypedObjectIndexInBounds(elemSize, obj, index, &indexAsByteOffset, objTypeReprs)) + return false; + + // Store the element + if (!storeScalarTypedObjectValue(obj, indexAsByteOffset, elemTypeRepr, value)) + return false; + + current->push(value); + + *emitted = true; + return true; +} + bool IonBuilder::setElemTryTypedStatic(bool *emitted, MDefinition *object, MDefinition *index, MDefinition *value) @@ -7428,8 +7511,8 @@ IonBuilder::setElemTryTypedStatic(bool *emitted, MDefinition *object, } bool -IonBuilder::setElemTryTyped(bool *emitted, MDefinition *object, - MDefinition *index, MDefinition *value) +IonBuilder::setElemTryTypedArray(bool *emitted, MDefinition *object, + MDefinition *index, MDefinition *value) { JS_ASSERT(*emitted == false); diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index bce41c5df58a..5bb36ca99d54 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -464,8 +464,10 @@ class IonBuilder : public MIRGenerator TypeRepresentationSet objTypeReprs); // jsop_setelem() helpers. - bool setElemTryTyped(bool *emitted, MDefinition *object, + bool setElemTryTypedArray(bool *emitted, MDefinition *object, MDefinition *index, MDefinition *value); + bool setElemTryTypedObject(bool *emitted, MDefinition *obj, + MDefinition *index, MDefinition *value); bool setElemTryTypedStatic(bool *emitted, MDefinition *object, MDefinition *index, MDefinition *value); bool setElemTryDense(bool *emitted, MDefinition *object, @@ -474,6 +476,13 @@ class IonBuilder : public MIRGenerator MDefinition *index, MDefinition *value); bool setElemTryCache(bool *emitted, MDefinition *object, MDefinition *index, MDefinition *value); + bool setElemTryScalarPropOfTypedObject(bool *emitted, + MDefinition *obj, + MDefinition *index, + TypeRepresentationSet objTypeReprs, + MDefinition *value, + TypeRepresentationSet elemTypeReprs, + size_t elemSize); // jsop_getelem() helpers. bool getElemTryDense(bool *emitted, MDefinition *obj, MDefinition *index);