Replace SetOrExtendBoxedOrUnboxedDenseElements with direct calls.

This commit is contained in:
wolfbeast 2019-06-14 11:33:28 +00:00 committed by Roy Tam
commit c6c456b12b
8 changed files with 70 additions and 77 deletions

View file

@ -8213,11 +8213,10 @@ CodeGenerator::visitFallibleStoreElementV(LFallibleStoreElementV* lir)
masm.bind(&isFrozen);
}
typedef bool (*SetDenseOrUnboxedArrayElementFn)(JSContext*, HandleObject, int32_t,
HandleValue, bool strict);
static const VMFunction SetDenseOrUnboxedArrayElementInfo =
FunctionInfo<SetDenseOrUnboxedArrayElementFn>(SetDenseOrUnboxedArrayElement,
"SetDenseOrUnboxedArrayElement");
typedef bool (*SetDenseElementFn)(JSContext*, HandleNativeObject, int32_t, HandleValue,
bool strict);
static const VMFunction SetDenseElementInfo =
FunctionInfo<SetDenseElementFn>(jit::SetDenseElement, "SetDenseElement");
void
CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool)
@ -8326,7 +8325,7 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool)
else
pushArg(ToRegister(index));
pushArg(object);
callVM(SetDenseOrUnboxedArrayElementInfo, ins);
callVM(SetDenseElementInfo, ins);
restoreLive(ins);
masm.jump(ool->rejoin());
@ -8500,7 +8499,7 @@ CodeGenerator::visitArrayPopShiftT(LArrayPopShiftT* lir)
emitArrayPopShift(lir, lir->mir(), obj, elements, length, out);
}
typedef bool (*ArrayPushDenseFn)(JSContext*, HandleObject, HandleValue, uint32_t*);
typedef bool (*ArrayPushDenseFn)(JSContext*, HandleArrayObject, HandleValue, uint32_t*);
static const VMFunction ArrayPushDenseInfo =
FunctionInfo<ArrayPushDenseFn>(jit::ArrayPushDense, "ArrayPushDense");

View file

@ -337,12 +337,11 @@ ArrayPopDense(JSContext* cx, HandleObject obj, MutableHandleValue rval)
}
bool
ArrayPushDense(JSContext* cx, HandleObject obj, HandleValue v, uint32_t* length)
ArrayPushDense(JSContext* cx, HandleArrayObject arr, HandleValue v, uint32_t* length)
{
*length = obj->as<ArrayObject>().length();
DenseElementResult result =
SetOrExtendBoxedOrUnboxedDenseElements(cx, obj, *length, v.address(), 1,
ShouldUpdateTypes::DontUpdate);
*length = arr->length();
DenseElementResult result = arr->setOrExtendDenseElements(cx, *length, v.address(), 1,
ShouldUpdateTypes::DontUpdate);
if (result != DenseElementResult::Incomplete) {
(*length)++;
return result == DenseElementResult::Success;
@ -350,7 +349,7 @@ ArrayPushDense(JSContext* cx, HandleObject obj, HandleValue v, uint32_t* length)
JS::AutoValueArray<3> argv(cx);
argv[0].setUndefined();
argv[1].setObject(*obj);
argv[1].setObject(*arr);
argv[2].set(v);
if (!js::array_push(cx, 1, argv.begin()))
return false;
@ -1143,16 +1142,14 @@ Recompile(JSContext* cx)
}
bool
SetDenseOrUnboxedArrayElement(JSContext* cx, HandleObject obj, int32_t index,
HandleValue value, bool strict)
SetDenseElement(JSContext* cx, HandleNativeObject obj, int32_t index, HandleValue value, bool strict)
{
// This function is called from Ion code for StoreElementHole's OOL path.
// In this case we know the object is native or an unboxed array and that
// no type changes are needed.
// In this case we know the object is native and that no type changes are
// needed.
DenseElementResult result =
SetOrExtendBoxedOrUnboxedDenseElements(cx, obj, index, value.address(), 1,
ShouldUpdateTypes::DontUpdate);
DenseElementResult result = obj->setOrExtendDenseElements(cx, index, value.address(), 1,
ShouldUpdateTypes::DontUpdate);
if (result != DenseElementResult::Incomplete)
return result == DenseElementResult::Success;

View file

@ -622,7 +622,7 @@ template<bool Equal>
bool StringsEqual(JSContext* cx, HandleString left, HandleString right, bool* res);
MOZ_MUST_USE bool ArrayPopDense(JSContext* cx, HandleObject obj, MutableHandleValue rval);
MOZ_MUST_USE bool ArrayPushDense(JSContext* cx, HandleObject obj, HandleValue v, uint32_t* length);
MOZ_MUST_USE bool ArrayPushDense(JSContext* cx, HandleArrayObject obj, HandleValue v, uint32_t* length);
MOZ_MUST_USE bool ArrayShiftDense(JSContext* cx, HandleObject obj, MutableHandleValue rval);
JSString* ArrayJoin(JSContext* cx, HandleObject array, HandleString sep);
@ -748,8 +748,8 @@ ForcedRecompile(JSContext* cx);
JSString* StringReplace(JSContext* cx, HandleString string, HandleString pattern,
HandleString repl);
MOZ_MUST_USE bool SetDenseOrUnboxedArrayElement(JSContext* cx, HandleObject obj, int32_t index,
HandleValue value, bool strict);
MOZ_MUST_USE bool SetDenseElement(JSContext* cx, HandleNativeObject obj, int32_t index,
HandleValue value, bool strict);
void AssertValidObjectPtr(JSContext* cx, JSObject* obj);
void AssertValidObjectOrNullPtr(JSContext* cx, JSObject* obj);

View file

@ -280,8 +280,8 @@ ElementAdder::append(JSContext* cx, HandleValue v)
{
MOZ_ASSERT(index_ < length_);
if (resObj_) {
DenseElementResult result =
SetOrExtendBoxedOrUnboxedDenseElements(cx, resObj_, index_, v.address(), 1);
NativeObject* resObj = &resObj_->as<NativeObject>();
DenseElementResult result = resObj->setOrExtendDenseElements(cx, index_, v.address(), 1);
if (result == DenseElementResult::Failure)
return false;
if (result == DenseElementResult::Incomplete) {
@ -390,8 +390,8 @@ SetArrayElement(JSContext* cx, HandleObject obj, double index, HandleValue v)
MOZ_ASSERT(index >= 0);
if (obj->is<ArrayObject>() && !obj->isIndexed() && index <= UINT32_MAX) {
DenseElementResult result =
SetOrExtendBoxedOrUnboxedDenseElements(cx, obj, uint32_t(index), v.address(), 1);
NativeObject* nobj = &obj->as<NativeObject>();
DenseElementResult result = nobj->setOrExtendDenseElements(cx, uint32_t(index), v.address(), 1);
if (result != DenseElementResult::Incomplete)
return result == DenseElementResult::Success;
}
@ -1299,8 +1299,9 @@ InitArrayElements(JSContext* cx, HandleObject obj, uint32_t start,
return false;
if (!ObjectMayHaveExtraIndexedProperties(obj)) {
DenseElementResult result =
SetOrExtendBoxedOrUnboxedDenseElements(cx, obj, start, vector, count, updateTypes);
NativeObject* nobj = &obj->as<NativeObject>();
DenseElementResult result = nobj->setOrExtendDenseElements(cx, uint32_t(start), vector,
count, updateTypes);
if (result != DenseElementResult::Incomplete)
return result == DenseElementResult::Success;
}
@ -2041,8 +2042,8 @@ js::array_push(JSContext* cx, unsigned argc, Value* vp)
if (!ObjectMayHaveExtraIndexedProperties(obj)) {
DenseElementResult result =
SetOrExtendBoxedOrUnboxedDenseElements(cx, obj, length,
args.array(), args.length());
obj->as<NativeObject>().setOrExtendDenseElements(cx, uint32_t(length),
args.array(), args.length());
if (result != DenseElementResult::Incomplete) {
if (result == DenseElementResult::Failure)
return false;
@ -3663,8 +3664,7 @@ js::NewCopiedArrayTryUseGroup(ExclusiveContext* cx, HandleObjectGroup group,
if (!obj)
return nullptr;
DenseElementResult result =
SetOrExtendBoxedOrUnboxedDenseElements(cx, obj, 0, vp, length, updateTypes);
DenseElementResult result = obj->setOrExtendDenseElements(cx->asJSContext(), 0, vp, length, updateTypes);
if (result == DenseElementResult::Failure)
return nullptr;
MOZ_ASSERT(result == DenseElementResult::Success);

View file

@ -98,12 +98,6 @@ NewFullyAllocatedArrayForCallingAllocationSite(JSContext* cx, size_t length,
extern ArrayObject*
NewPartlyAllocatedArrayForCallingAllocationSite(JSContext* cx, size_t length, HandleObject proto);
enum class ShouldUpdateTypes
{
Update,
DontUpdate
};
extern ArrayObject*
NewCopiedArrayTryUseGroup(ExclusiveContext* cx, HandleObjectGroup group,
const Value* vp, size_t length,

View file

@ -235,6 +235,38 @@ NativeObject::ensureDenseElements(ExclusiveContext* cx, uint32_t index, uint32_t
return DenseElementResult::Success;
}
inline DenseElementResult
NativeObject::setOrExtendDenseElements(JSContext* cx, uint32_t start, const Value* vp,
uint32_t count,
ShouldUpdateTypes updateTypes)
{
if (denseElementsAreFrozen())
return DenseElementResult::Incomplete;
if (is<ArrayObject>() &&
!as<ArrayObject>().lengthIsWritable() &&
start + count >= as<ArrayObject>().length())
{
return DenseElementResult::Incomplete;
}
DenseElementResult result = ensureDenseElements(cx, start, count);
if (result != DenseElementResult::Success)
return result;
if (is<ArrayObject>() && start + count >= as<ArrayObject>().length())
as<ArrayObject>().setLengthInt32(start + count);
if (updateTypes == ShouldUpdateTypes::DontUpdate && !shouldConvertDoubleElements()) {
copyDenseElements(start, vp, count);
} else {
for (size_t i = 0; i < count; i++)
setDenseElementWithType(cx, start + i, vp[i]);
}
return DenseElementResult::Success;
}
inline Value
NativeObject::getDenseOrTypedArrayElement(uint32_t idx)
{

View file

@ -349,6 +349,11 @@ enum class DenseElementResult {
Incomplete
};
enum class ShouldUpdateTypes {
Update,
DontUpdate
};
/*
* NativeObject specifies the internal implementation of a native object.
*
@ -1147,6 +1152,10 @@ class NativeObject : public ShapedObject
elementsRangeWriteBarrierPost(dstStart, count);
}
inline DenseElementResult
setOrExtendDenseElements(JSContext* cx, uint32_t start, const Value* vp, uint32_t count,
ShouldUpdateTypes updateTypes = ShouldUpdateTypes::Update);
bool shouldConvertDoubleElements() {
return getElementsHeader()->shouldConvertDoubleElements();
}

View file

@ -172,44 +172,6 @@ UnboxedPlainObject::layout() const
return group()->unboxedLayout();
}
/////////////////////////////////////////////////////////////////////
// Template methods for NativeObject and UnboxedArrayObject accesses.
/////////////////////////////////////////////////////////////////////
static inline DenseElementResult
SetOrExtendBoxedOrUnboxedDenseElements(ExclusiveContext* cx, JSObject* obj,
uint32_t start, const Value* vp, uint32_t count,
ShouldUpdateTypes updateTypes = ShouldUpdateTypes::Update)
{
NativeObject* nobj = &obj->as<NativeObject>();
if (nobj->denseElementsAreFrozen())
return DenseElementResult::Incomplete;
if (obj->is<ArrayObject>() &&
!obj->as<ArrayObject>().lengthIsWritable() &&
start + count >= obj->as<ArrayObject>().length())
{
return DenseElementResult::Incomplete;
}
DenseElementResult result = nobj->ensureDenseElements(cx, start, count);
if (result != DenseElementResult::Success)
return result;
if (obj->is<ArrayObject>() && start + count >= obj->as<ArrayObject>().length())
obj->as<ArrayObject>().setLengthInt32(start + count);
if (updateTypes == ShouldUpdateTypes::DontUpdate && !nobj->shouldConvertDoubleElements()) {
nobj->copyDenseElements(start, vp, count);
} else {
for (size_t i = 0; i < count; i++)
nobj->setDenseElementWithType(cx, start + i, vp[i]);
}
return DenseElementResult::Success;
}
} // namespace js
#endif // vm_UnboxedObject_inl_h