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
|
||||
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()) {
|
||||
if (!cur->isSetElem_TypedArray())
|
||||
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 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;
|
||||
}
|
||||
|
||||
@ -3600,13 +3625,22 @@ DoSetElemFallback(JSContext *cx, BaselineFrame *frame, ICSetElem_Fallback *stub,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj->isTypedArray() &&
|
||||
index.isInt32() && rhs.isNumber() &&
|
||||
!TypedArraySetElemStubExists(stub, obj))
|
||||
{
|
||||
IonSpew(IonSpew_BaselineIC, " Generating SetElem_TypedArray stub (shape=%p, type=%u)",
|
||||
obj->lastProperty(), TypedArray::type(obj));
|
||||
ICSetElem_TypedArray::Compiler compiler(cx, obj->lastProperty(), TypedArray::type(obj));
|
||||
if (obj->isTypedArray() && index.isInt32() && rhs.isNumber()) {
|
||||
uint32_t len = TypedArray::length(obj);
|
||||
int32_t idx = index.toInt32();
|
||||
bool expectOutOfBounds = (idx < 0) || (static_cast<uint32_t>(idx) >= len);
|
||||
|
||||
if (!TypedArraySetElemStubExists(stub, obj, expectOutOfBounds)) {
|
||||
// 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));
|
||||
if (!typedArrayStub)
|
||||
return false;
|
||||
@ -3614,6 +3648,7 @@ DoSetElemFallback(JSContext *cx, BaselineFrame *frame, ICSetElem_Fallback *stub,
|
||||
stub->addNewStub(typedArrayStub);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -3897,8 +3932,10 @@ ICSetElem_TypedArray::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
Register key = masm.extractInt32(R1, ExtractTemp1);
|
||||
|
||||
// Bounds check.
|
||||
Label oobWrite;
|
||||
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.
|
||||
masm.loadPtr(Address(obj, TypedArray::dataOffset()), scratchReg);
|
||||
@ -3965,6 +4002,11 @@ ICSetElem_TypedArray::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
// Failure case - jump to next stub
|
||||
masm.bind(&failure);
|
||||
EmitStubGuardFailure(masm);
|
||||
|
||||
if (expectOutOfBounds_) {
|
||||
masm.bind(&oobWrite);
|
||||
EmitReturnFromIC(masm);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3046,21 +3046,32 @@ class ICSetElem_TypedArray : public ICStub
|
||||
protected: // Protected to silence Clang warning.
|
||||
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),
|
||||
shape_(shape)
|
||||
{
|
||||
extra_ = uint16_t(type);
|
||||
extra_ = uint8_t(type);
|
||||
JS_ASSERT(extra_ == type);
|
||||
extra_ |= (static_cast<uint16_t>(expectOutOfBounds) << 8);
|
||||
}
|
||||
|
||||
public:
|
||||
static inline ICSetElem_TypedArray *New(ICStubSpace *space, IonCode *code,
|
||||
HandleShape shape, uint32_t type)
|
||||
HandleShape shape, uint32_t type,
|
||||
bool expectOutOfBounds)
|
||||
{
|
||||
if (!code)
|
||||
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() {
|
||||
@ -3074,23 +3085,27 @@ class ICSetElem_TypedArray : public ICStub
|
||||
class Compiler : public ICStubCompiler {
|
||||
RootedShape shape_;
|
||||
uint32_t type_;
|
||||
bool expectOutOfBounds_;
|
||||
|
||||
protected:
|
||||
bool generateStubCode(MacroAssembler &masm);
|
||||
|
||||
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:
|
||||
Compiler(JSContext *cx, UnrootedShape shape, uint32_t type)
|
||||
Compiler(JSContext *cx, UnrootedShape shape, uint32_t type, bool expectOutOfBounds)
|
||||
: ICStubCompiler(cx, ICStub::SetElem_TypedArray),
|
||||
shape_(cx, shape),
|
||||
type_(type)
|
||||
type_(type),
|
||||
expectOutOfBounds_(expectOutOfBounds)
|
||||
{}
|
||||
|
||||
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