mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 854400 - Rebase Shu's patch, and combine inlined code with jsop_setelem_dense r=jandem
This commit is contained in:
parent
acfd12a00f
commit
36df22ee4c
@ -6518,7 +6518,8 @@ IonBuilder::jsop_setelem()
|
||||
types::StackTypeSet::DoubleConversion conversion =
|
||||
object->resultTypeSet()->convertDoubleElements(cx);
|
||||
if (conversion != types::StackTypeSet::AmbiguousDoubleConversion)
|
||||
return jsop_setelem_dense(conversion, object, index, value);
|
||||
return jsop_setelem_dense(conversion, SetElem_Normal,
|
||||
object, index, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6537,6 +6538,7 @@ IonBuilder::jsop_setelem()
|
||||
|
||||
bool
|
||||
IonBuilder::jsop_setelem_dense(types::StackTypeSet::DoubleConversion conversion,
|
||||
SetElemSafety safety,
|
||||
MDefinition *obj, MDefinition *id, MDefinition *value)
|
||||
{
|
||||
MIRType elementType = DenseNativeElementType(cx, obj);
|
||||
@ -6565,15 +6567,22 @@ IonBuilder::jsop_setelem_dense(types::StackTypeSet::DoubleConversion conversion,
|
||||
MElements *elements = MElements::New(obj);
|
||||
current->add(elements);
|
||||
|
||||
bool writeHole = script()->analysis()->getCode(pc).arrayWriteHole;
|
||||
SetElemICInspector icInspect(inspector->setElemICInspector(pc));
|
||||
writeHole |= icInspect.sawOOBDenseWrite();
|
||||
bool writeHole;
|
||||
if (safety == SetElem_Normal) {
|
||||
writeHole = script()->analysis()->getCode(pc).arrayWriteHole;
|
||||
SetElemICInspector icInspect(inspector->setElemICInspector(pc));
|
||||
writeHole |= icInspect.sawOOBDenseWrite();
|
||||
} else {
|
||||
writeHole = false;
|
||||
}
|
||||
|
||||
// Use MStoreElementHole if this SETELEM has written to out-of-bounds
|
||||
// indexes in the past. Otherwise, use MStoreElement so that we can hoist
|
||||
// the initialized length and bounds check.
|
||||
MStoreElementCommon *store;
|
||||
if (writeHole && writeOutOfBounds) {
|
||||
JS_ASSERT(safety == SetElem_Normal);
|
||||
|
||||
MStoreElementHole *ins = MStoreElementHole::New(obj, elements, id, newValue);
|
||||
store = ins;
|
||||
|
||||
@ -6586,15 +6595,24 @@ IonBuilder::jsop_setelem_dense(types::StackTypeSet::DoubleConversion conversion,
|
||||
MInitializedLength *initLength = MInitializedLength::New(elements);
|
||||
current->add(initLength);
|
||||
|
||||
id = addBoundsCheck(id, initLength);
|
||||
|
||||
bool needsHoleCheck = !packed && !writeOutOfBounds;
|
||||
bool needsHoleCheck;
|
||||
if (safety == SetElem_Normal) {
|
||||
id = addBoundsCheck(id, initLength);
|
||||
needsHoleCheck = !packed && !writeOutOfBounds;
|
||||
} else {
|
||||
needsHoleCheck = false;
|
||||
}
|
||||
|
||||
MStoreElement *ins = MStoreElement::New(elements, id, newValue, needsHoleCheck);
|
||||
store = ins;
|
||||
|
||||
if (safety == SetElem_Unsafe)
|
||||
ins->setRacy();
|
||||
|
||||
current->add(ins);
|
||||
current->push(value);
|
||||
|
||||
if (safety == SetElem_Normal)
|
||||
current->push(value);
|
||||
|
||||
if (!resumeAfter(ins))
|
||||
return false;
|
||||
|
@ -31,6 +31,16 @@ class IonBuilder : public MIRGenerator
|
||||
ControlStatus_None // No control flow.
|
||||
};
|
||||
|
||||
enum SetElemSafety {
|
||||
// Normal write like a[b] = c.
|
||||
SetElem_Normal,
|
||||
|
||||
// Write due to UnsafeSetElement:
|
||||
// - assumed to be in bounds,
|
||||
// - not checked for data races
|
||||
SetElem_Unsafe,
|
||||
};
|
||||
|
||||
struct DeferredEdge : public TempObject
|
||||
{
|
||||
MBasicBlock *block;
|
||||
@ -383,6 +393,7 @@ class IonBuilder : public MIRGenerator
|
||||
bool jsop_getelem_string();
|
||||
bool jsop_setelem();
|
||||
bool jsop_setelem_dense(types::StackTypeSet::DoubleConversion conversion,
|
||||
SetElemSafety safety,
|
||||
MDefinition *object, MDefinition *index, MDefinition *value);
|
||||
bool jsop_setelem_typed(int arrayType,
|
||||
SetElemSafety safety,
|
||||
|
@ -942,12 +942,6 @@ IonBuilder::inlineUnsafeSetElement(CallInfo &callInfo)
|
||||
{
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
|
||||
if (obj->resultTypeSet()->convertDoubleElements(cx) !=
|
||||
types::StackTypeSet::DontConvertToDoubles)
|
||||
{
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
}
|
||||
|
||||
callInfo.unwrapArgs();
|
||||
@ -985,7 +979,8 @@ IonBuilder::inlineUnsafeSetElement(CallInfo &callInfo)
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::inlineUnsafeSetDenseArrayElement(CallInfo &callInfo, uint32_t base)
|
||||
IonBuilder::inlineUnsafeSetDenseArrayElement(
|
||||
CallInfo &callInfo, uint32_t base)
|
||||
{
|
||||
// Note: we do not check the conditions that are asserted as true
|
||||
// in intrinsic_UnsafeSetElement():
|
||||
@ -994,33 +989,14 @@ IonBuilder::inlineUnsafeSetDenseArrayElement(CallInfo &callInfo, uint32_t base)
|
||||
// Furthermore, note that inlineUnsafeSetElement ensures the type of the
|
||||
// value is reflected in the JSID_VOID property of the array.
|
||||
|
||||
uint32_t arri = base + 0;
|
||||
uint32_t idxi = base + 1;
|
||||
uint32_t elemi = base + 2;
|
||||
MDefinition *obj = callInfo.getArg(base + 0);
|
||||
MDefinition *id = callInfo.getArg(base + 1);
|
||||
MDefinition *elem = callInfo.getArg(base + 2);
|
||||
|
||||
MElements *elements = MElements::New(callInfo.getArg(arri));
|
||||
current->add(elements);
|
||||
|
||||
MToInt32 *id = MToInt32::New(callInfo.getArg(idxi));
|
||||
current->add(id);
|
||||
|
||||
// We disable the hole check for this store. This implies that if
|
||||
// there were setters on the prototype, they would not be invoked.
|
||||
// But this is actually the desired behavior.
|
||||
|
||||
MStoreElement *store = MStoreElement::New(elements, id,
|
||||
callInfo.getArg(elemi),
|
||||
/* needsHoleCheck = */ false);
|
||||
store->setRacy();
|
||||
|
||||
if (callInfo.getArg(arri)->resultTypeSet()->propertyNeedsBarrier(cx, JSID_VOID))
|
||||
store->setNeedsBarrier();
|
||||
|
||||
current->add(store);
|
||||
|
||||
if (!resumeAfter(store))
|
||||
types::StackTypeSet::DoubleConversion conversion =
|
||||
obj->resultTypeSet()->convertDoubleElements(cx);
|
||||
if (!jsop_setelem_dense(conversion, SetElem_Unsafe, obj, id, elem))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,19 @@ function testPushConvert() {
|
||||
}
|
||||
testPushConvert();
|
||||
|
||||
var UnsafeSetElement = getSelfHostedValue("UnsafeSetElement");
|
||||
function testUnsafeSetConvert() {
|
||||
var x = [0.5, 1.5, 2.1];
|
||||
for (var i = 0; i < 2000; i++)
|
||||
// try to ensure we JIT and hence inline
|
||||
UnsafeSetElement(x, 1, i);
|
||||
var res = 0;
|
||||
for (var i = 0; i < x.length; i++)
|
||||
res += x[i];
|
||||
assertEq(res, 2001.6);
|
||||
}
|
||||
testUnsafeSetConvert();
|
||||
|
||||
function testArrayInitializer() {
|
||||
var x = [.5,1.5,2.5,3];
|
||||
var res = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user