import changes from `dev' branch of rmottola/Arctic-Fox:

- Bug 1175165 - Eagerly analyze large array literals to see if an unboxed representation can be used, r=jandem. (2251e1071)
- Bug 1175165 - Fix build break on a CLOSED TREE. (983798c03)
- Bug 1175535 - Don't require objects embedded in MIR nodes to always be tenured, r=jandem. (9afba1c8c)
- Bug 1176751 - Eagerly convert unboxed arrays to native arrays more often during Ion compilation, r=jandem. (7605d0e8b)
- Bug 1176451 - Optimize Array.concat when used on different types of boxed vs. unboxed arrays, r=jandem. (0f764f61c)
- Bug 1186561 - add #include <vector> to a protobuf header to work around problems on Android; r=fitzgen (ff9a3912b)
- Bug 1192556 - #ifdef AtomicWord typedef in protobuf to fix build on OpenBSD/i386. r=fitzgen (2748adc36)
- Bug 1204165 - Fix typo when concatenating arrays with different unboxed layouts, r=jandem. (12d4f8ab3)
- pointer style (01a644250)
- Bug 1210596 - Mark array groups as not packed when initializing individual elements with holes, r=jandem. (8a006f88f)
This commit is contained in:
2020-11-11 21:52:52 +08:00
parent c8820524bc
commit 424329dee5
20 changed files with 571 additions and 226 deletions
+93 -21
View File
@@ -2568,40 +2568,41 @@ js::array_splice_impl(JSContext* cx, unsigned argc, Value* vp, bool returnValueI
return true;
}
template <JSValueType Type>
template <JSValueType TypeOne, JSValueType TypeTwo>
DenseElementResult
ArrayConcatDenseKernel(JSContext* cx, JSObject* obj1, JSObject* obj2, JSObject* result)
{
uint32_t initlen1 = GetBoxedOrUnboxedInitializedLength<Type>(obj1);
uint32_t initlen1 = GetBoxedOrUnboxedInitializedLength<TypeOne>(obj1);
MOZ_ASSERT(initlen1 == GetAnyBoxedOrUnboxedArrayLength(obj1));
uint32_t initlen2 = GetBoxedOrUnboxedInitializedLength<Type>(obj2);
uint32_t initlen2 = GetBoxedOrUnboxedInitializedLength<TypeTwo>(obj2);
MOZ_ASSERT(initlen2 == GetAnyBoxedOrUnboxedArrayLength(obj2));
/* No overflow here due to nelements limit. */
uint32_t len = initlen1 + initlen2;
MOZ_ASSERT(GetBoxedOrUnboxedInitializedLength<Type>(result) == 0);
MOZ_ASSERT(GetBoxedOrUnboxedInitializedLength<TypeOne>(result) == 0);
if (!EnsureBoxedOrUnboxedDenseElements<Type>(cx, result, len))
return DenseElementResult::Failure;
DenseElementResult rv = EnsureBoxedOrUnboxedDenseElements<TypeOne>(cx, result, len);
if (rv != DenseElementResult::Success)
return rv;
CopyBoxedOrUnboxedDenseElements<Type>(cx, result, obj1, 0, 0, initlen1);
CopyBoxedOrUnboxedDenseElements<Type>(cx, result, obj2, initlen1, 0, initlen2);
CopyBoxedOrUnboxedDenseElements<TypeOne, TypeOne>(cx, result, obj1, 0, 0, initlen1);
CopyBoxedOrUnboxedDenseElements<TypeOne, TypeTwo>(cx, result, obj2, initlen1, 0, initlen2);
SetAnyBoxedOrUnboxedArrayLength(cx, result, len);
return DenseElementResult::Success;
}
DefineBoxedOrUnboxedFunctor4(ArrayConcatDenseKernel,
JSContext*, JSObject*, JSObject*, JSObject*);
DefineBoxedOrUnboxedFunctorPair4(ArrayConcatDenseKernel,
JSContext*, JSObject*, JSObject*, JSObject*);
bool
js::array_concat_dense(JSContext* cx, HandleObject obj1, HandleObject obj2,
HandleObject result)
{
ArrayConcatDenseKernelFunctor functor(cx, obj1, obj2, result);
DenseElementResult rv = CallBoxedOrUnboxedSpecialization(functor, result);
DenseElementResult rv = CallBoxedOrUnboxedSpecialization(functor, obj1, obj2);
MOZ_ASSERT(rv != DenseElementResult::Incomplete);
return rv == DenseElementResult::Success;
}
@@ -2632,17 +2633,63 @@ js::array_concat(JSContext* cx, unsigned argc, Value* vp)
narr = NewFullyAllocatedArrayTryReuseGroup(cx, aobj, initlen);
if (!narr)
return false;
CopyAnyBoxedOrUnboxedDenseElements(cx, narr, aobj, 0, 0, initlen);
SetAnyBoxedOrUnboxedArrayLength(cx, narr, length);
DebugOnly<DenseElementResult> result =
CopyAnyBoxedOrUnboxedDenseElements(cx, narr, aobj, 0, 0, initlen);
MOZ_ASSERT(result.value == DenseElementResult::Success);
args.rval().setObject(*narr);
if (argc == 0)
return true;
argc--;
p++;
if (length == initlen) {
while (argc) {
HandleValue v = HandleValue::fromMarkedLocation(p);
if (!v.isObject())
break;
RootedObject obj(cx, &v.toObject());
// This should be IsConcatSpreadable
if (!IsArray(obj, cx) || ObjectMayHaveExtraIndexedProperties(obj))
break;
uint32_t argLength;
if (!GetLengthProperty(cx, obj, &argLength))
return false;
initlen = GetAnyBoxedOrUnboxedInitializedLength(obj);
if (argLength != initlen)
break;
DenseElementResult result =
EnsureAnyBoxedOrUnboxedDenseElements(cx, narr, length + argLength);
if (result == DenseElementResult::Failure)
return false;
if (result == DenseElementResult::Incomplete)
break;
SetAnyBoxedOrUnboxedInitializedLength(cx, narr, length + argLength);
bool success = true;
for (size_t i = 0; i < initlen; i++) {
Value v = GetAnyBoxedOrUnboxedDenseElement(obj, i);
if (!InitAnyBoxedOrUnboxedDenseElement(cx, narr, length + i, v)) {
success = false;
break;
}
}
if (!success) {
SetAnyBoxedOrUnboxedInitializedLength(cx, narr, length);
break;
}
length += argLength;
SetAnyBoxedOrUnboxedArrayLength(cx, narr, length);
argc--;
p++;
}
}
} else {
narr = NewDenseEmptyArray(cx);
if (!narr)
@@ -2939,9 +2986,10 @@ ArraySliceDenseKernel(JSContext* cx, JSObject* obj, int32_t beginArg, int32_t en
if (initlen > begin) {
size_t count = Min<size_t>(initlen - begin, end - begin);
if (count) {
if (!EnsureBoxedOrUnboxedDenseElements<Type>(cx, result, count))
return DenseElementResult::Failure;
CopyBoxedOrUnboxedDenseElements<Type>(cx, result, obj, 0, begin, count);
DenseElementResult rv = EnsureBoxedOrUnboxedDenseElements<Type>(cx, result, count);
if (rv != DenseElementResult::Success)
return rv;
CopyBoxedOrUnboxedDenseElements<Type, Type>(cx, result, obj, 0, begin, count);
}
}
@@ -3593,9 +3641,9 @@ NewArrayTryUseGroup(ExclusiveContext* cx, HandleObjectGroup group, size_t length
JSObject*
js::NewFullyAllocatedArrayTryUseGroup(ExclusiveContext* cx, HandleObjectGroup group, size_t length,
NewObjectKind newKind)
NewObjectKind newKind, bool forceAnalyze)
{
return NewArrayTryUseGroup<UINT32_MAX>(cx, group, length, newKind);
return NewArrayTryUseGroup<UINT32_MAX>(cx, group, length, newKind, forceAnalyze);
}
JSObject*
@@ -3666,7 +3714,31 @@ js::NewCopiedArrayTryUseGroup(ExclusiveContext* cx, HandleObjectGroup group,
const Value* vp, size_t length, NewObjectKind newKind,
ShouldUpdateTypes updateTypes)
{
JSObject* obj = NewFullyAllocatedArrayTryUseGroup(cx, group, length, newKind);
bool forceAnalyze = false;
static const size_t EagerPreliminaryObjectAnalysisThreshold = 800;
// Force analysis to see if an unboxed array can be used when making a
// sufficiently large array, to avoid excessive analysis and copying later
// on. If this is the first array of its group that is being created, first
// make a dummy array with the initial elements of the array we are about
// to make, so there is some basis for the unboxed array analysis.
if (length > EagerPreliminaryObjectAnalysisThreshold) {
if (PreliminaryObjectArrayWithTemplate* objects = group->maybePreliminaryObjects()) {
if (objects->empty()) {
size_t nlength = Min<size_t>(length, 100);
JSObject* obj = NewFullyAllocatedArrayTryUseGroup(cx, group, nlength);
if (!obj)
return nullptr;
DebugOnly<DenseElementResult> result =
SetOrExtendAnyBoxedOrUnboxedDenseElements(cx, obj, 0, vp, nlength, updateTypes);
MOZ_ASSERT(result.value == DenseElementResult::Success);
}
}
forceAnalyze = true;
}
JSObject* obj = NewFullyAllocatedArrayTryUseGroup(cx, group, length, newKind, forceAnalyze);
if (!obj)
return nullptr;