зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1526403 - Part 2: Don't track buffer content changes for TypedArrays using shared memory. r=jandem
This commit is contained in:
Родитель
b780900930
Коммит
d0a6de319b
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче