mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge.
This commit is contained in:
commit
1b0d8c9b07
@ -3416,14 +3416,39 @@ DenseSetElemStubExists(JSContext *cx, ICStub::Kind kind, ICSetElem_Fallback *stu
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
TypedArraySetElemStubExists(ICSetElem_Fallback *stub, HandleObject obj)
|
TypedArraySetElemStubExists(ICSetElem_Fallback *stub, HandleObject obj, bool expectOutOfBounds)
|
||||||
{
|
{
|
||||||
for (ICStub *cur = stub->icEntry()->firstStub(); cur != stub; cur = cur->next()) {
|
for (ICStub *cur = stub->icEntry()->firstStub(); cur != stub; cur = cur->next()) {
|
||||||
if (!cur->isSetElem_TypedArray())
|
if (!cur->isSetElem_TypedArray())
|
||||||
continue;
|
continue;
|
||||||
if (obj->lastProperty() == cur->toSetElem_TypedArray()->shape())
|
ICSetElem_TypedArray *taStub = cur->toSetElem_TypedArray();
|
||||||
|
if (obj->lastProperty() == taStub->shape() &&
|
||||||
|
taStub->expectOutOfBounds() == expectOutOfBounds)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
RemoveExistingTypedArraySetElemStub(JSContext *cx, ICSetElem_Fallback *stub, HandleObject obj)
|
||||||
|
{
|
||||||
|
ICStub *prev = NULL;
|
||||||
|
ICStub *cur = stub->icEntry()->firstStub();
|
||||||
|
while (cur != stub) {
|
||||||
|
if (cur->isSetElem_TypedArray() &&
|
||||||
|
obj->lastProperty() == cur->toSetElem_TypedArray()->shape())
|
||||||
|
{
|
||||||
|
// TypedArraySetElem stubs are only removed using this procedure if
|
||||||
|
// being replaced with one that expects out of bounds index.
|
||||||
|
JS_ASSERT(!cur->toSetElem_TypedArray()->expectOutOfBounds());
|
||||||
|
stub->unlinkStub(cx->zone(), prev, cur);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
prev = cur;
|
||||||
|
cur = cur->next();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3600,13 +3625,22 @@ DoSetElemFallback(JSContext *cx, BaselineFrame *frame, ICSetElem_Fallback *stub,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj->isTypedArray() &&
|
if (obj->isTypedArray() && index.isInt32() && rhs.isNumber()) {
|
||||||
index.isInt32() && rhs.isNumber() &&
|
uint32_t len = TypedArray::length(obj);
|
||||||
!TypedArraySetElemStubExists(stub, obj))
|
int32_t idx = index.toInt32();
|
||||||
{
|
bool expectOutOfBounds = (idx < 0) || (static_cast<uint32_t>(idx) >= len);
|
||||||
IonSpew(IonSpew_BaselineIC, " Generating SetElem_TypedArray stub (shape=%p, type=%u)",
|
|
||||||
obj->lastProperty(), TypedArray::type(obj));
|
if (!TypedArraySetElemStubExists(stub, obj, expectOutOfBounds)) {
|
||||||
ICSetElem_TypedArray::Compiler compiler(cx, obj->lastProperty(), TypedArray::type(obj));
|
// Remove any existing TypedArraySetElemStub that doesn't handle out-of-bounds
|
||||||
|
if (expectOutOfBounds)
|
||||||
|
RemoveExistingTypedArraySetElemStub(cx, stub, obj);
|
||||||
|
|
||||||
|
IonSpew(IonSpew_BaselineIC,
|
||||||
|
" Generating SetElem_TypedArray stub (shape=%p, type=%u, oob=%s)",
|
||||||
|
obj->lastProperty(), TypedArray::type(obj),
|
||||||
|
expectOutOfBounds ? "yes" : "no");
|
||||||
|
ICSetElem_TypedArray::Compiler compiler(cx, obj->lastProperty(), TypedArray::type(obj),
|
||||||
|
expectOutOfBounds);
|
||||||
ICStub *typedArrayStub = compiler.getStub(compiler.getStubSpace(script));
|
ICStub *typedArrayStub = compiler.getStub(compiler.getStubSpace(script));
|
||||||
if (!typedArrayStub)
|
if (!typedArrayStub)
|
||||||
return false;
|
return false;
|
||||||
@ -3614,6 +3648,7 @@ DoSetElemFallback(JSContext *cx, BaselineFrame *frame, ICSetElem_Fallback *stub,
|
|||||||
stub->addNewStub(typedArrayStub);
|
stub->addNewStub(typedArrayStub);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -3897,8 +3932,10 @@ ICSetElem_TypedArray::Compiler::generateStubCode(MacroAssembler &masm)
|
|||||||
Register key = masm.extractInt32(R1, ExtractTemp1);
|
Register key = masm.extractInt32(R1, ExtractTemp1);
|
||||||
|
|
||||||
// Bounds check.
|
// Bounds check.
|
||||||
|
Label oobWrite;
|
||||||
masm.unboxInt32(Address(obj, TypedArray::lengthOffset()), scratchReg);
|
masm.unboxInt32(Address(obj, TypedArray::lengthOffset()), scratchReg);
|
||||||
masm.branch32(Assembler::BelowOrEqual, scratchReg, key, &failure);
|
masm.branch32(Assembler::BelowOrEqual, scratchReg, key,
|
||||||
|
expectOutOfBounds_ ? &oobWrite : &failure);
|
||||||
|
|
||||||
// Load the elements vector.
|
// Load the elements vector.
|
||||||
masm.loadPtr(Address(obj, TypedArray::dataOffset()), scratchReg);
|
masm.loadPtr(Address(obj, TypedArray::dataOffset()), scratchReg);
|
||||||
@ -3965,6 +4002,11 @@ ICSetElem_TypedArray::Compiler::generateStubCode(MacroAssembler &masm)
|
|||||||
// Failure case - jump to next stub
|
// Failure case - jump to next stub
|
||||||
masm.bind(&failure);
|
masm.bind(&failure);
|
||||||
EmitStubGuardFailure(masm);
|
EmitStubGuardFailure(masm);
|
||||||
|
|
||||||
|
if (expectOutOfBounds_) {
|
||||||
|
masm.bind(&oobWrite);
|
||||||
|
EmitReturnFromIC(masm);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3046,21 +3046,32 @@ class ICSetElem_TypedArray : public ICStub
|
|||||||
protected: // Protected to silence Clang warning.
|
protected: // Protected to silence Clang warning.
|
||||||
HeapPtrShape shape_;
|
HeapPtrShape shape_;
|
||||||
|
|
||||||
ICSetElem_TypedArray(IonCode *stubCode, HandleShape shape, uint32_t type)
|
ICSetElem_TypedArray(IonCode *stubCode, HandleShape shape, uint32_t type,
|
||||||
|
bool expectOutOfBounds)
|
||||||
: ICStub(SetElem_TypedArray, stubCode),
|
: ICStub(SetElem_TypedArray, stubCode),
|
||||||
shape_(shape)
|
shape_(shape)
|
||||||
{
|
{
|
||||||
extra_ = uint16_t(type);
|
extra_ = uint8_t(type);
|
||||||
JS_ASSERT(extra_ == type);
|
JS_ASSERT(extra_ == type);
|
||||||
|
extra_ |= (static_cast<uint16_t>(expectOutOfBounds) << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static inline ICSetElem_TypedArray *New(ICStubSpace *space, IonCode *code,
|
static inline ICSetElem_TypedArray *New(ICStubSpace *space, IonCode *code,
|
||||||
HandleShape shape, uint32_t type)
|
HandleShape shape, uint32_t type,
|
||||||
|
bool expectOutOfBounds)
|
||||||
{
|
{
|
||||||
if (!code)
|
if (!code)
|
||||||
return NULL;
|
return NULL;
|
||||||
return space->allocate<ICSetElem_TypedArray>(code, shape, type);
|
return space->allocate<ICSetElem_TypedArray>(code, shape, type, expectOutOfBounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t type() const {
|
||||||
|
return extra_ & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool expectOutOfBounds() const {
|
||||||
|
return (extra_ >> 8) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t offsetOfShape() {
|
static size_t offsetOfShape() {
|
||||||
@ -3074,23 +3085,27 @@ class ICSetElem_TypedArray : public ICStub
|
|||||||
class Compiler : public ICStubCompiler {
|
class Compiler : public ICStubCompiler {
|
||||||
RootedShape shape_;
|
RootedShape shape_;
|
||||||
uint32_t type_;
|
uint32_t type_;
|
||||||
|
bool expectOutOfBounds_;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool generateStubCode(MacroAssembler &masm);
|
bool generateStubCode(MacroAssembler &masm);
|
||||||
|
|
||||||
virtual int32_t getKey() const {
|
virtual int32_t getKey() const {
|
||||||
return static_cast<int32_t>(kind) | (static_cast<int32_t>(type_) << 16);
|
return static_cast<int32_t>(kind) | (static_cast<int32_t>(type_) << 16) |
|
||||||
|
(static_cast<int32_t>(expectOutOfBounds_) << 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Compiler(JSContext *cx, UnrootedShape shape, uint32_t type)
|
Compiler(JSContext *cx, UnrootedShape shape, uint32_t type, bool expectOutOfBounds)
|
||||||
: ICStubCompiler(cx, ICStub::SetElem_TypedArray),
|
: ICStubCompiler(cx, ICStub::SetElem_TypedArray),
|
||||||
shape_(cx, shape),
|
shape_(cx, shape),
|
||||||
type_(type)
|
type_(type),
|
||||||
|
expectOutOfBounds_(expectOutOfBounds)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
ICStub *getStub(ICStubSpace *space) {
|
ICStub *getStub(ICStubSpace *space) {
|
||||||
return ICSetElem_TypedArray::New(space, getStubCode(), shape_, type_);
|
return ICSetElem_TypedArray::New(space, getStubCode(), shape_, type_,
|
||||||
|
expectOutOfBounds_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user