Bug 1526403 - Part 2: Don't track buffer content changes for TypedArrays using shared memory. r=jandem

This commit is contained in:
André Bargull 2019-02-08 10:36:28 -08:00
Родитель b780900930
Коммит d0a6de319b
3 изменённых файлов: 60 добавлений и 40 удалений

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

@ -9076,6 +9076,45 @@ MInstruction* IonBuilder::addArrayBufferByteLength(MDefinition* obj) {
return ins;
}
TypedArrayObject* IonBuilder::tryTypedArrayEmbedConstantElements(
MDefinition* obj) {
JSObject* object = nullptr;
if (MConstant* objConst = obj->maybeConstantValue()) {
if (objConst->type() == MIRType::Object) {
object = &objConst->toObject();
}
} else if (TemporaryTypeSet* types = obj->resultTypeSet()) {
object = types->maybeSingleton();
}
if (!object || !object->isSingleton()) {
return nullptr;
}
TypedArrayObject* tarr = &object->as<TypedArrayObject>();
// TypedArrays are only singletons when created with a (Shared)ArrayBuffer
// and a length greater or equal to |SINGLETON_BYTE_LENGTH|.
MOZ_ASSERT(tarr->hasBuffer());
MOZ_ASSERT(tarr->byteLength() >= TypedArrayObject::SINGLETON_BYTE_LENGTH ||
tarr->hasDetachedBuffer());
// TypedArrays using an ArrayBuffer don't have nursery-allocated data, see
// |ArrayBufferViewObject::init(...)|.
MOZ_ASSERT(!tarr->runtimeFromMainThread()->gc.nursery().isInside(
tarr->dataPointerEither()));
// The 'data' pointer of TypedArrayObject can change in rare circumstances
// (ArrayBufferObject::setNewData).
TypeSet::ObjectKey* tarrKey = TypeSet::ObjectKey::get(tarr);
if (tarrKey->unknownProperties()) {
return nullptr;
}
if (!tarr->isSharedMemory()) {
tarrKey->watchStateChangeForTypedArrayData(constraints());
}
return tarr;
}
void IonBuilder::addTypedArrayLengthAndData(MDefinition* obj,
BoundsChecking checking,
MDefinition** index,
@ -9083,49 +9122,25 @@ void IonBuilder::addTypedArrayLengthAndData(MDefinition* obj,
MInstruction** elements) {
MOZ_ASSERT((index != nullptr) == (elements != nullptr));
JSObject* tarr = nullptr;
if (MConstant* objConst = obj->maybeConstantValue()) {
if (objConst->type() == MIRType::Object) {
tarr = &objConst->toObject();
}
} else if (TemporaryTypeSet* types = obj->resultTypeSet()) {
tarr = types->maybeSingleton();
}
if (tarr) {
SharedMem<void*> data = tarr->as<TypedArrayObject>().dataPointerEither();
if (TypedArrayObject* tarr = tryTypedArrayEmbedConstantElements(obj)) {
// Bug 979449 - Optimistically embed the elements and use TI to
// invalidate if we move them.
bool isTenured =
!tarr->runtimeFromMainThread()->gc.nursery().isInside(data);
if (isTenured && tarr->isSingleton()) {
// The 'data' pointer of TypedArrayObject can change in rare circumstances
// (ArrayBufferObject::changeContents).
TypeSet::ObjectKey* tarrKey = TypeSet::ObjectKey::get(tarr);
if (!tarrKey->unknownProperties()) {
if (tarr->is<TypedArrayObject>()) {
tarrKey->watchStateChangeForTypedArrayData(constraints());
}
obj->setImplicitlyUsedUnchecked();
obj->setImplicitlyUsedUnchecked();
int32_t len =
AssertedCast<int32_t>(tarr->as<TypedArrayObject>().length());
*length = MConstant::New(alloc(), Int32Value(len));
current->add(*length);
int32_t len = AssertedCast<int32_t>(tarr->length());
*length = MConstant::New(alloc(), Int32Value(len));
current->add(*length);
if (index) {
if (checking == DoBoundsCheck) {
*index = addBoundsCheck(*index, *length);
}
*elements = MConstantElements::New(alloc(), data);
current->add(*elements);
}
return;
if (index) {
if (checking == DoBoundsCheck) {
*index = addBoundsCheck(*index, *length);
}
*elements = MConstantElements::New(alloc(), tarr->dataPointerEither());
current->add(*elements);
}
return;
}
*length = MTypedArrayLength::New(alloc(), obj);

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

@ -24,6 +24,9 @@
#include "jit/OptimizationTracking.h"
namespace js {
class TypedArrayObject;
namespace jit {
class CodeGenerator;
@ -493,6 +496,8 @@ class IonBuilder : public MIRGenerator,
MInstruction* addArrayBufferByteLength(MDefinition* obj);
TypedArrayObject* tryTypedArrayEmbedConstantElements(MDefinition* obj);
// Add instructions to compute a typed array's length and data. Also
// optionally convert |*index| into a bounds-checked definition, if
// requested.

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

@ -1979,15 +1979,16 @@ namespace {
class ConstraintDataFreezeObjectForTypedArrayData {
NativeObject* obj;
uintptr_t viewData;
void* viewData;
uint32_t length;
public:
explicit ConstraintDataFreezeObjectForTypedArrayData(TypedArrayObject& tarray)
: obj(&tarray),
viewData(tarray.dataPointerEither().unwrapValue()),
viewData(tarray.dataPointerUnshared()),
length(tarray.length()) {
MOZ_ASSERT(tarray.isSingleton());
MOZ_ASSERT(!tarray.isSharedMemory());
}
const char* kind() { return "freezeObjectForTypedArrayData"; }
@ -1998,8 +1999,7 @@ class ConstraintDataFreezeObjectForTypedArrayData {
ObjectGroup* group) {
MOZ_ASSERT(obj->group() == group);
TypedArrayObject& tarr = obj->as<TypedArrayObject>();
return tarr.dataPointerEither().unwrapValue() != viewData ||
tarr.length() != length;
return tarr.dataPointerUnshared() != viewData || tarr.length() != length;
}
bool constraintHolds(const AutoSweepObjectGroup& sweep, JSContext* cx,