mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 14:55:47 +00:00
Bug 991153: Split uses of temp allocations into explicit float32 and doubles (r=djvj)
This commit is contained in:
parent
10aa17972c
commit
9479a316d2
@ -7111,19 +7111,20 @@ CodeGenerator::addSetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Regi
|
||||
|
||||
bool
|
||||
CodeGenerator::addSetElementCache(LInstruction *ins, Register obj, Register unboxIndex,
|
||||
Register temp, FloatRegister tempFloat, ValueOperand index,
|
||||
Register temp, FloatRegister tempDouble,
|
||||
FloatRegister tempFloat32, ValueOperand index,
|
||||
ConstantOrRegister value, bool strict, bool guardHoles,
|
||||
jsbytecode *profilerLeavePc)
|
||||
{
|
||||
switch (gen->info().executionMode()) {
|
||||
case SequentialExecution: {
|
||||
SetElementIC cache(obj, unboxIndex, temp, tempFloat, index, value, strict,
|
||||
SetElementIC cache(obj, unboxIndex, temp, tempDouble, tempFloat32, index, value, strict,
|
||||
guardHoles);
|
||||
cache.setProfilerLeavePC(profilerLeavePc);
|
||||
return addCache(ins, allocateCache(cache));
|
||||
}
|
||||
case ParallelExecution: {
|
||||
SetElementParIC cache(obj, unboxIndex, temp, tempFloat, index, value, strict,
|
||||
SetElementParIC cache(obj, unboxIndex, temp, tempDouble, tempFloat32, index, value, strict,
|
||||
guardHoles);
|
||||
cache.setProfilerLeavePC(profilerLeavePc);
|
||||
return addCache(ins, allocateCache(cache));
|
||||
@ -7283,11 +7284,12 @@ CodeGenerator::visitSetElementCacheV(LSetElementCacheV *ins)
|
||||
Register obj = ToRegister(ins->object());
|
||||
Register unboxIndex = ToTempUnboxRegister(ins->tempToUnboxIndex());
|
||||
Register temp = ToRegister(ins->temp());
|
||||
FloatRegister tempFloat = ToFloatRegister(ins->tempFloat());
|
||||
FloatRegister tempDouble = ToFloatRegister(ins->tempDouble());
|
||||
FloatRegister tempFloat32 = ToFloatRegister(ins->tempFloat32());
|
||||
ValueOperand index = ToValue(ins, LSetElementCacheV::Index);
|
||||
ConstantOrRegister value = TypedOrValueRegister(ToValue(ins, LSetElementCacheV::Value));
|
||||
|
||||
return addSetElementCache(ins, obj, unboxIndex, temp, tempFloat, index, value,
|
||||
return addSetElementCache(ins, obj, unboxIndex, temp, tempDouble, tempFloat32, index, value,
|
||||
ins->mir()->strict(), ins->mir()->guardHoles(),
|
||||
ins->mir()->profilerLeavePc());
|
||||
}
|
||||
@ -7298,7 +7300,8 @@ CodeGenerator::visitSetElementCacheT(LSetElementCacheT *ins)
|
||||
Register obj = ToRegister(ins->object());
|
||||
Register unboxIndex = ToTempUnboxRegister(ins->tempToUnboxIndex());
|
||||
Register temp = ToRegister(ins->temp());
|
||||
FloatRegister tempFloat = ToFloatRegister(ins->tempFloat());
|
||||
FloatRegister tempDouble = ToFloatRegister(ins->tempDouble());
|
||||
FloatRegister tempFloat32 = ToFloatRegister(ins->tempFloat32());
|
||||
ValueOperand index = ToValue(ins, LSetElementCacheT::Index);
|
||||
ConstantOrRegister value;
|
||||
const LAllocation *tmp = ins->value();
|
||||
@ -7307,7 +7310,7 @@ CodeGenerator::visitSetElementCacheT(LSetElementCacheT *ins)
|
||||
else
|
||||
value = TypedOrValueRegister(ins->mir()->value()->type(), ToAnyRegister(tmp));
|
||||
|
||||
return addSetElementCache(ins, obj, unboxIndex, temp, tempFloat, index, value,
|
||||
return addSetElementCache(ins, obj, unboxIndex, temp, tempDouble, tempFloat32, index, value,
|
||||
ins->mir()->strict(), ins->mir()->guardHoles(),
|
||||
ins->mir()->profilerLeavePc());
|
||||
}
|
||||
@ -8722,11 +8725,16 @@ CodeGenerator::visitAssertRangeF(LAssertRangeF *ins)
|
||||
{
|
||||
FloatRegister input = ToFloatRegister(ins->input());
|
||||
FloatRegister temp = ToFloatRegister(ins->temp());
|
||||
FloatRegister dest = input;
|
||||
if (hasMultiAlias())
|
||||
dest = ToFloatRegister(ins->armtemp());
|
||||
|
||||
const Range *r = ins->range();
|
||||
|
||||
masm.convertFloat32ToDouble(input, input);
|
||||
bool success = emitAssertRangeD(r, input, temp);
|
||||
masm.convertDoubleToFloat32(input, input);
|
||||
masm.convertFloat32ToDouble(input, dest);
|
||||
bool success = emitAssertRangeD(r, dest, temp);
|
||||
if (dest == input)
|
||||
masm.convertDoubleToFloat32(input, input);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@ -369,7 +369,8 @@ class CodeGenerator : public CodeGeneratorSpecific
|
||||
PropertyName *name, ConstantOrRegister value, bool strict,
|
||||
bool needsTypeBarrier, jsbytecode *profilerLeavePc);
|
||||
bool addSetElementCache(LInstruction *ins, Register obj, Register unboxIndex, Register temp,
|
||||
FloatRegister tempFloat, ValueOperand index, ConstantOrRegister value,
|
||||
FloatRegister tempDouble, FloatRegister tempFloat32,
|
||||
ValueOperand index, ConstantOrRegister value,
|
||||
bool strict, bool guardHoles, jsbytecode *profilerLeavePc);
|
||||
|
||||
bool generateBranchV(const ValueOperand &value, Label *ifTrue, Label *ifFalse, FloatRegister fr);
|
||||
|
@ -3702,7 +3702,8 @@ static bool
|
||||
GenerateSetTypedArrayElement(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher,
|
||||
HandleTypedArrayObject tarr, Register object,
|
||||
ValueOperand indexVal, ConstantOrRegister value,
|
||||
Register tempUnbox, Register temp, FloatRegister tempFloat)
|
||||
Register tempUnbox, Register temp, FloatRegister tempDouble,
|
||||
FloatRegister tempFloat32)
|
||||
{
|
||||
Label failures, done, popObjectAndFail;
|
||||
|
||||
@ -3731,18 +3732,22 @@ GenerateSetTypedArrayElement(JSContext *cx, MacroAssembler &masm, IonCache::Stub
|
||||
BaseIndex target(elements, index, ScaleFromElemWidth(width));
|
||||
|
||||
if (arrayType == ScalarTypeDescr::TYPE_FLOAT32) {
|
||||
FloatRegister ftemp;
|
||||
if (LIRGenerator::allowFloat32Optimizations()) {
|
||||
if (!masm.convertConstantOrRegisterToFloat(cx, value, tempFloat, &failures))
|
||||
JS_ASSERT(tempFloat32 != InvalidFloatReg);
|
||||
if (!masm.convertConstantOrRegisterToFloat(cx, value, tempFloat32, &failures))
|
||||
return false;
|
||||
ftemp = tempFloat32;
|
||||
} else {
|
||||
if (!masm.convertConstantOrRegisterToDouble(cx, value, tempFloat, &failures))
|
||||
if (!masm.convertConstantOrRegisterToDouble(cx, value, tempDouble, &failures))
|
||||
return false;
|
||||
ftemp = tempDouble;
|
||||
}
|
||||
masm.storeToTypedFloatArray(arrayType, tempFloat, target);
|
||||
masm.storeToTypedFloatArray(arrayType, ftemp, target);
|
||||
} else if (arrayType == ScalarTypeDescr::TYPE_FLOAT64) {
|
||||
if (!masm.convertConstantOrRegisterToDouble(cx, value, tempFloat, &failures))
|
||||
if (!masm.convertConstantOrRegisterToDouble(cx, value, tempDouble, &failures))
|
||||
return false;
|
||||
masm.storeToTypedFloatArray(arrayType, tempFloat, target);
|
||||
masm.storeToTypedFloatArray(arrayType, tempDouble, target);
|
||||
} else {
|
||||
// On x86 we only have 6 registers available to use, so reuse the object
|
||||
// register to compute the intermediate value to store and restore it
|
||||
@ -3750,13 +3755,13 @@ GenerateSetTypedArrayElement(JSContext *cx, MacroAssembler &masm, IonCache::Stub
|
||||
masm.push(object);
|
||||
|
||||
if (arrayType == ScalarTypeDescr::TYPE_UINT8_CLAMPED) {
|
||||
if (!masm.clampConstantOrRegisterToUint8(cx, value, tempFloat, object,
|
||||
if (!masm.clampConstantOrRegisterToUint8(cx, value, tempDouble, object,
|
||||
&popObjectAndFail))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!masm.truncateConstantOrRegisterToInt32(cx, value, tempFloat, object,
|
||||
if (!masm.truncateConstantOrRegisterToInt32(cx, value, tempDouble, object,
|
||||
&popObjectAndFail))
|
||||
{
|
||||
return false;
|
||||
@ -3789,7 +3794,7 @@ SetElementIC::attachTypedArrayElement(JSContext *cx, HandleScript outerScript, I
|
||||
RepatchStubAppender attacher(*this);
|
||||
if (!GenerateSetTypedArrayElement(cx, masm, attacher, tarr,
|
||||
object(), index(), value(),
|
||||
tempToUnboxIndex(), temp(), tempFloat()))
|
||||
tempToUnboxIndex(), temp(), tempDouble(), tempFloat32()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -3860,7 +3865,7 @@ SetElementParIC::attachTypedArrayElement(LockedJSContext &cx, IonScript *ion,
|
||||
DispatchStubPrepender attacher(*this);
|
||||
if (!GenerateSetTypedArrayElement(cx, masm, attacher, tarr,
|
||||
object(), index(), value(),
|
||||
tempToUnboxIndex(), temp(), tempFloat()))
|
||||
tempToUnboxIndex(), temp(), tempDouble(), tempFloat32()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -851,7 +851,8 @@ class SetElementIC : public RepatchIonCache
|
||||
Register object_;
|
||||
Register tempToUnboxIndex_;
|
||||
Register temp_;
|
||||
FloatRegister tempFloat_;
|
||||
FloatRegister tempDouble_;
|
||||
FloatRegister tempFloat32_;
|
||||
ValueOperand index_;
|
||||
ConstantOrRegister value_;
|
||||
bool strict_;
|
||||
@ -861,12 +862,14 @@ class SetElementIC : public RepatchIonCache
|
||||
|
||||
public:
|
||||
SetElementIC(Register object, Register tempToUnboxIndex, Register temp,
|
||||
FloatRegister tempFloat, ValueOperand index, ConstantOrRegister value,
|
||||
FloatRegister tempDouble, FloatRegister tempFloat32,
|
||||
ValueOperand index, ConstantOrRegister value,
|
||||
bool strict, bool guardHoles)
|
||||
: object_(object),
|
||||
tempToUnboxIndex_(tempToUnboxIndex),
|
||||
temp_(temp),
|
||||
tempFloat_(tempFloat),
|
||||
tempDouble_(tempDouble),
|
||||
tempFloat32_(tempFloat32),
|
||||
index_(index),
|
||||
value_(value),
|
||||
strict_(strict),
|
||||
@ -888,8 +891,11 @@ class SetElementIC : public RepatchIonCache
|
||||
Register temp() const {
|
||||
return temp_;
|
||||
}
|
||||
FloatRegister tempFloat() const {
|
||||
return tempFloat_;
|
||||
FloatRegister tempDouble() const {
|
||||
return tempDouble_;
|
||||
}
|
||||
FloatRegister tempFloat32() const {
|
||||
return tempFloat32_;
|
||||
}
|
||||
ValueOperand index() const {
|
||||
return index_;
|
||||
@ -1247,7 +1253,8 @@ class SetElementParIC : public ParallelIonCache
|
||||
Register object_;
|
||||
Register tempToUnboxIndex_;
|
||||
Register temp_;
|
||||
FloatRegister tempFloat_;
|
||||
FloatRegister tempDouble_;
|
||||
FloatRegister tempFloat32_;
|
||||
ValueOperand index_;
|
||||
ConstantOrRegister value_;
|
||||
bool strict_;
|
||||
@ -1255,12 +1262,13 @@ class SetElementParIC : public ParallelIonCache
|
||||
|
||||
public:
|
||||
SetElementParIC(Register object, Register tempToUnboxIndex, Register temp,
|
||||
FloatRegister tempFloat, ValueOperand index, ConstantOrRegister value,
|
||||
FloatRegister tempDouble, FloatRegister tempFloat32, ValueOperand index, ConstantOrRegister value,
|
||||
bool strict, bool guardHoles)
|
||||
: object_(object),
|
||||
tempToUnboxIndex_(tempToUnboxIndex),
|
||||
temp_(temp),
|
||||
tempFloat_(tempFloat),
|
||||
tempDouble_(tempDouble),
|
||||
tempFloat32_(tempFloat32),
|
||||
index_(index),
|
||||
value_(value),
|
||||
strict_(strict),
|
||||
@ -1285,8 +1293,11 @@ class SetElementParIC : public ParallelIonCache
|
||||
Register temp() const {
|
||||
return temp_;
|
||||
}
|
||||
FloatRegister tempFloat() const {
|
||||
return tempFloat_;
|
||||
FloatRegister tempDouble() const {
|
||||
return tempDouble_;
|
||||
}
|
||||
FloatRegister tempFloat32() const {
|
||||
return tempFloat32_;
|
||||
}
|
||||
ValueOperand index() const {
|
||||
return index_;
|
||||
|
@ -5091,7 +5091,7 @@ class LSetPropertyCacheT : public LInstructionHelper<0, 2, 2>
|
||||
}
|
||||
};
|
||||
|
||||
class LSetElementCacheV : public LInstructionHelper<0, 1 + 2 * BOX_PIECES, 3>
|
||||
class LSetElementCacheV : public LInstructionHelper<0, 1 + 2 * BOX_PIECES, 4>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(SetElementCacheV);
|
||||
@ -5100,12 +5100,14 @@ class LSetElementCacheV : public LInstructionHelper<0, 1 + 2 * BOX_PIECES, 3>
|
||||
static const size_t Value = 1 + BOX_PIECES;
|
||||
|
||||
LSetElementCacheV(const LAllocation &object, const LDefinition &tempToUnboxIndex,
|
||||
const LDefinition &temp, const LDefinition &tempFloat)
|
||||
const LDefinition &temp, const LDefinition &tempDouble,
|
||||
const LDefinition &tempFloat32)
|
||||
{
|
||||
setOperand(0, object);
|
||||
setTemp(0, tempToUnboxIndex);
|
||||
setTemp(1, temp);
|
||||
setTemp(2, tempFloat);
|
||||
setTemp(2, tempDouble);
|
||||
setTemp(3, tempFloat32);
|
||||
}
|
||||
const MSetElementCache *mir() const {
|
||||
return mir_->toSetElementCache();
|
||||
@ -5120,12 +5122,18 @@ class LSetElementCacheV : public LInstructionHelper<0, 1 + 2 * BOX_PIECES, 3>
|
||||
const LDefinition *temp() {
|
||||
return getTemp(1);
|
||||
}
|
||||
const LDefinition *tempFloat() {
|
||||
const LDefinition *tempDouble() {
|
||||
return getTemp(2);
|
||||
}
|
||||
const LDefinition *tempFloat32() {
|
||||
if (hasUnaliasedDouble())
|
||||
return getTemp(3);
|
||||
return getTemp(2);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class LSetElementCacheT : public LInstructionHelper<0, 2 + BOX_PIECES, 3>
|
||||
class LSetElementCacheT : public LInstructionHelper<0, 2 + BOX_PIECES, 4>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(SetElementCacheT);
|
||||
@ -5134,12 +5142,14 @@ class LSetElementCacheT : public LInstructionHelper<0, 2 + BOX_PIECES, 3>
|
||||
|
||||
LSetElementCacheT(const LAllocation &object, const LAllocation &value,
|
||||
const LDefinition &tempToUnboxIndex,
|
||||
const LDefinition &temp, const LDefinition &tempFloat) {
|
||||
const LDefinition &temp, const LDefinition &tempDouble,
|
||||
const LDefinition &tempFloat32) {
|
||||
setOperand(0, object);
|
||||
setOperand(1, value);
|
||||
setTemp(0, tempToUnboxIndex);
|
||||
setTemp(1, temp);
|
||||
setTemp(2, tempFloat);
|
||||
setTemp(2, tempDouble);
|
||||
setTemp(3, tempFloat32);
|
||||
}
|
||||
const MSetElementCache *mir() const {
|
||||
return mir_->toSetElementCache();
|
||||
@ -5157,9 +5167,15 @@ class LSetElementCacheT : public LInstructionHelper<0, 2 + BOX_PIECES, 3>
|
||||
const LDefinition *temp() {
|
||||
return getTemp(1);
|
||||
}
|
||||
const LDefinition *tempFloat() {
|
||||
const LDefinition *tempDouble() {
|
||||
return getTemp(2);
|
||||
}
|
||||
const LDefinition *tempFloat32() {
|
||||
if (hasUnaliasedDouble())
|
||||
return getTemp(3);
|
||||
return getTemp(2);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class LCallIteratorStart : public LCallInstructionHelper<1, 1, 0>
|
||||
@ -6025,14 +6041,17 @@ class LAssertRangeD : public LInstructionHelper<0, 1, 1>
|
||||
}
|
||||
};
|
||||
|
||||
class LAssertRangeF : public LInstructionHelper<0, 1, 1>
|
||||
class LAssertRangeF : public LInstructionHelper<0, 1, 2>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(AssertRangeF)
|
||||
|
||||
LAssertRangeF(const LAllocation &input, const LDefinition &temp) {
|
||||
LAssertRangeF(const LAllocation &input, const LDefinition &temp, const LDefinition &armtemp) {
|
||||
setOperand(0, input);
|
||||
setTemp(0, temp);
|
||||
setTemp(1, armtemp);
|
||||
}
|
||||
const LDefinition *armtemp() {
|
||||
return getTemp(1);
|
||||
}
|
||||
|
||||
const LAllocation *input() {
|
||||
|
@ -1216,7 +1216,7 @@ LIRGenerator::visitRound(MRound *ins)
|
||||
return define(lir, ins);
|
||||
}
|
||||
|
||||
LRoundF *lir = new (alloc()) LRoundF(useRegister(ins->num()), tempDouble());
|
||||
LRoundF *lir = new (alloc()) LRoundF(useRegister(ins->num()), tempFloat32());
|
||||
if (!assignSnapshot(lir, Bailout_Round))
|
||||
return false;
|
||||
return define(lir, ins);
|
||||
@ -3085,10 +3085,11 @@ LIRGenerator::visitAssertRange(MAssertRange *ins)
|
||||
lir = new(alloc()) LAssertRangeD(useRegister(input), tempDouble());
|
||||
break;
|
||||
|
||||
case MIRType_Float32:
|
||||
lir = new(alloc()) LAssertRangeF(useRegister(input), tempFloat32());
|
||||
case MIRType_Float32: {
|
||||
LDefinition armtemp = hasMultiAlias() ? tempFloat32() : LDefinition::BogusTemp();
|
||||
lir = new(alloc()) LAssertRangeF(useRegister(input), tempFloat32(), armtemp);
|
||||
break;
|
||||
|
||||
}
|
||||
case MIRType_Value:
|
||||
lir = new(alloc()) LAssertRangeV(tempToUnbox(), tempDouble(), tempDouble());
|
||||
if (!useBox(lir, LAssertRangeV::Input, input))
|
||||
@ -3195,17 +3196,20 @@ LIRGenerator::visitSetElementCache(MSetElementCache *ins)
|
||||
// |useRegister| below.
|
||||
LInstruction *lir;
|
||||
if (ins->value()->type() == MIRType_Value) {
|
||||
LDefinition tempF32 = hasUnaliasedDouble() ? tempFloat32() : LDefinition::BogusTemp();
|
||||
lir = new(alloc()) LSetElementCacheV(useByteOpRegister(ins->object()), tempToUnbox(),
|
||||
temp(), tempDouble());
|
||||
temp(), tempDouble(), tempF32);
|
||||
|
||||
if (!useBox(lir, LSetElementCacheV::Index, ins->index()))
|
||||
return false;
|
||||
if (!useBox(lir, LSetElementCacheV::Value, ins->value()))
|
||||
return false;
|
||||
} else {
|
||||
LDefinition tempF32 = hasUnaliasedDouble() ? tempFloat32() : LDefinition::BogusTemp();
|
||||
lir = new(alloc()) LSetElementCacheT(useByteOpRegister(ins->object()),
|
||||
useRegisterOrConstant(ins->value()),
|
||||
tempToUnbox(), temp(), tempDouble());
|
||||
tempToUnbox(), temp(), tempDouble(),
|
||||
tempF32);
|
||||
|
||||
if (!useBox(lir, LSetElementCacheT::Index, ins->index()))
|
||||
return false;
|
||||
|
@ -398,9 +398,20 @@ uint32_t GetARMFlags();
|
||||
bool HasMOVWT();
|
||||
bool HasVFPv3();
|
||||
bool HasVFP();
|
||||
bool Has16DP();
|
||||
bool Has32DP();
|
||||
bool HasIDIV();
|
||||
|
||||
// Arm/D32 has double registers that can NOT be treated as float32
|
||||
// and this requires some dances in lowering.
|
||||
static bool hasUnaliasedDouble() {
|
||||
return Has32DP();
|
||||
}
|
||||
// On ARM, Dn aliases both S2n and S2n+1, so if you need to convert a float32
|
||||
// to a double as a temporary, you need a temporary double register.
|
||||
static bool hasMultiAlias() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParseARMHwCapFlags(const char *armHwCap);
|
||||
|
||||
// If the simulator is used then the ABI choice is dynamic. Otherwise the ABI is static
|
||||
|
@ -215,6 +215,7 @@ class LIRGeneratorShared : public MInstructionVisitorWithDefaults
|
||||
static bool allowInlineForkJoinGetSlice() {
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace jit
|
||||
|
@ -191,6 +191,17 @@ struct FloatRegister {
|
||||
bool aliases(FloatRegister const &other) const;
|
||||
};
|
||||
|
||||
// Arm/D32 has double registers that can NOT be treated as float32
|
||||
// and this requires some dances in lowering.
|
||||
static bool hasUnaliasedDouble() {
|
||||
return false;
|
||||
}
|
||||
// On ARM, Dn aliases both S2n and S2n+1, so if you need to convert a float32
|
||||
// to a double as a temporary, you need a temporary double register.
|
||||
static bool hasMultiAlias() {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
@ -169,6 +169,18 @@ struct FloatRegister {
|
||||
bool aliases(FloatRegister const &other) const;
|
||||
};
|
||||
|
||||
// Arm/D32 has double registers that can NOT be treated as float32
|
||||
// and this requires some dances in lowering.
|
||||
static bool hasUnaliasedDouble() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// On ARM, Dn aliases both S2n and S2n+1, so if you need to convert a float32
|
||||
// to a double as a temporary, you need a temporary double register.
|
||||
static bool hasMultiAlias() {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
@ -64,11 +64,9 @@ class LIRGeneratorX86 : public LIRGeneratorX86Shared
|
||||
static bool allowStaticTypedArrayAccesses() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool allowFloat32Optimizations() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool allowInlineForkJoinGetSlice() {
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user