Commit 9ba4bbd8 authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[torque] use iterators and constructors for ExtractFixedArray

Bug: v8:7793
Change-Id: I8334a97033ebfa4bbd6bba27eb75c6ae129deab5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1995384
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarMichael Stanton <mvstanton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65812}
parent 1e15724f
......@@ -135,9 +135,8 @@ namespace array {
deferred {
const newLength: intptr = CalculateNewElementsCapacity(length);
assert(index < newLength);
const newfixedArray: FixedArray = ExtractFixedArray(
fixedArray, 0, length, newLength,
ExtractFixedArrayFlag::kFixedArrays);
const newfixedArray: FixedArray =
ExtractFixedArray(fixedArray, 0, length, newLength);
newfixedArray.objects[index] = element;
return newfixedArray;
}
......
......@@ -7,25 +7,26 @@ namespace array {
// FixedArrayType. Most of this behavior is outsourced to ExtractFixedArray(),
// but the special case of wanting to have a FixedDoubleArray when given a
// zero-length input FixedArray is handled here.
macro Extract<FixedArrayType : type extends FixedArrayBase>(
elements: FixedArrayBase, first: Smi, count: Smi,
capacity: Smi): FixedArrayType;
Extract<FixedArray>(implicit context: Context)(
elements: FixedArrayBase, first: Smi, count: Smi,
capacity: Smi): FixedArray {
return UnsafeCast<FixedArray>(
ExtractFixedArray(elements, first, count, capacity));
}
Extract<FixedDoubleArray>(implicit context: Context)(
elements: FixedArrayBase, first: Smi, count: Smi,
capacity: Smi): FixedDoubleArray {
if (elements == kEmptyFixedArray) {
macro Extract(implicit context: Context)(
elements: FixedArray, first: Smi, count: Smi, capacity: Smi): FixedArray {
return ExtractFixedArray(
elements, Convert<intptr>(first), Convert<intptr>(count),
Convert<intptr>(capacity));
}
macro Extract(implicit context: Context)(
elements: FixedDoubleArray|EmptyFixedArray, first: Smi, count: Smi,
capacity: Smi): FixedDoubleArray|EmptyFixedArray {
typeswitch (elements) {
case (EmptyFixedArray): {
return AllocateZeroedFixedDoubleArray(Convert<intptr>(capacity));
}
return UnsafeCast<FixedDoubleArray>(
ExtractFixedArray(elements, first, count, capacity));
case (elements: FixedDoubleArray): {
return ExtractFixedDoubleArray(
elements, Convert<intptr>(first), Convert<intptr>(count),
Convert<intptr>(capacity));
}
}
}
macro DoMoveElements<FixedArrayType : type extends FixedArrayBase>(
......@@ -60,29 +61,29 @@ namespace array {
array::EnsureWriteableFastElements(a);
if (insertCount != actualDeleteCount) {
const elements: FixedArrayBase = a.elements;
const elements =
UnsafeCast<(FixedArrayType | EmptyFixedArray)>(a.elements);
const dstIndex: Smi = actualStart + insertCount;
const srcIndex: Smi = actualStart + actualDeleteCount;
const count: Smi = length - actualDeleteCount - actualStart;
if (insertCount < actualDeleteCount) {
// Shrink.
DoMoveElements<FixedArrayType>(
DoMoveElements(
UnsafeCast<FixedArrayType>(elements), dstIndex, srcIndex, count);
StoreHoles<FixedArrayType>(
UnsafeCast<FixedArrayType>(elements), newLength, length);
StoreHoles(UnsafeCast<FixedArrayType>(elements), newLength, length);
} else if (insertCount > actualDeleteCount) {
// If the backing store is big enough, then moving elements is enough.
if (newLength <= elements.length) {
DoMoveElements<FixedArrayType>(
DoMoveElements(
UnsafeCast<FixedArrayType>(elements), dstIndex, srcIndex, count);
} else {
// Grow.
const capacity: Smi = CalculateNewElementsCapacity(newLength);
const newElements: FixedArrayType =
Extract<FixedArrayType>(elements, 0, actualStart, capacity);
const newElements: FixedArrayType = UnsafeCast<FixedArrayType>(
Extract(elements, 0, actualStart, capacity));
a.elements = newElements;
if (elements.length > 0) {
DoCopyElements<FixedArrayType>(
DoCopyElements(
newElements, dstIndex, UnsafeCast<FixedArrayType>(elements),
srcIndex, count);
}
......
......@@ -26,9 +26,10 @@ namespace array {
// extract FixedArrays and don't have to worry about FixedDoubleArrays.
assert(IsFastSmiOrTaggedElementsKind(array.map.elements_kind));
const length: Smi = Cast<Smi>(array.length) otherwise unreachable;
array.elements = ExtractFixedArray(
elements, 0, length, length, ExtractFixedArrayFlag::kFixedArrays);
const length =
Convert<intptr>(Cast<Smi>(array.length) otherwise unreachable);
array.elements =
ExtractFixedArray(UnsafeCast<FixedArray>(elements), 0, length, length);
assert(array.elements.map != kCOWMap);
}
......
......@@ -886,6 +886,7 @@ macro UnsafeCast<A : type extends Object>(implicit context: Context)(o: Object):
}
extern macro FixedArrayMapConstant(): Map;
extern macro FixedDoubleArrayMapConstant(): Map;
extern macro FixedCOWArrayMapConstant(): Map;
extern macro EmptyByteArrayConstant(): ByteArray;
extern macro EmptyFixedArrayConstant(): EmptyFixedArray;
......@@ -895,6 +896,7 @@ extern macro StringMapConstant(): Map;
extern macro SloppyArgumentsElementsMapConstant(): Map;
const kFixedArrayMap: Map = FixedArrayMapConstant();
const kFixedDoubleArrayMap: Map = FixedDoubleArrayMapConstant();
const kCOWMap: Map = FixedCOWArrayMapConstant();
const kEmptyByteArray: ByteArray = EmptyByteArrayConstant();
const kEmptyFixedArray: EmptyFixedArray = EmptyFixedArrayConstant();
......
......@@ -288,6 +288,32 @@ Cast<FixedDoubleArray>(o: HeapObject): FixedDoubleArray
return HeapObjectToFixedDoubleArray(o) otherwise CastError;
}
Cast<EmptyFixedArray>(o: Object): EmptyFixedArray
labels CastError {
if (o != kEmptyFixedArray) goto CastError;
return %RawDownCast<EmptyFixedArray>(o);
}
Cast<EmptyFixedArray>(o: HeapObject): EmptyFixedArray
labels CastError {
const o: Object = o;
return Cast<EmptyFixedArray>(o) otherwise CastError;
}
Cast<(FixedDoubleArray | EmptyFixedArray)>(o: HeapObject): FixedDoubleArray|
EmptyFixedArray labels CastError {
typeswitch (o) {
case (o: EmptyFixedArray): {
return o;
}
case (o: FixedDoubleArray): {
return o;
}
case (HeapObject): {
goto CastError;
}
}
}
Cast<SloppyArgumentsElements>(o: HeapObject): SloppyArgumentsElements
labels CastError {
return HeapObjectToSloppyArgumentsElements(o) otherwise CastError;
......
......@@ -14,9 +14,7 @@ namespace growable_fixed_array {
assert(newCapacity >= 0);
assert(newCapacity >= this.length);
const first: intptr = 0;
return ExtractFixedArray(
this.array, first, this.length, newCapacity,
ExtractFixedArrayFlag::kFixedArrays);
return ExtractFixedArray(this.array, first, this.length, newCapacity);
}
macro EnsureCapacity() {
assert(this.length <= this.capacity);
......
......@@ -63,6 +63,19 @@ namespace torque_internal {
unsafeMarker: Unsafe {}
};
}
macro Iterator(startIndex: intptr, endIndex: intptr): SliceIterator<T> {
check(
Convert<uintptr>(endIndex) <= Convert<uintptr>(this.length) &&
Convert<uintptr>(startIndex) <= Convert<uintptr>(endIndex));
const start = this.offset + startIndex * %SizeOf<T>();
const end = this.offset + endIndex * %SizeOf<T>();
return SliceIterator<T>{
object: this.object,
start,
end,
unsafeMarker: Unsafe {}
};
}
const object: HeapObject;
const offset: intptr;
......@@ -85,7 +98,11 @@ namespace torque_internal {
return this.start == this.end;
}
macro Next():&T labels NoMore {
macro Next(): T labels NoMore {
return * this.NextReference() otherwise NoMore;
}
macro NextReference():&T labels NoMore {
if (this.Empty()) {
goto NoMore;
} else {
......@@ -143,7 +160,7 @@ namespace torque_internal {
let targetIterator = target.Iterator();
let originIterator = originIterator;
while (true) {
const ref:&T = targetIterator.Next() otherwise break;
const ref:&T = targetIterator.NextReference() otherwise break;
* ref = originIterator.Next() otherwise unreachable;
}
}
......@@ -180,3 +197,23 @@ struct UninitializedIterator {}
// type assert()
intrinsic %RawDownCast<To: type, From: type>(x: From): To;
intrinsic %RawConstexprCast<To: type, From: type>(f: From): To;
struct IteratorSequence<T: type, FirstIterator: type, SecondIterator: type> {
macro Empty(): bool {
return this.first.Empty() && this.second.Empty();
}
macro Next(): T labels NoMore {
return this.first.Next()
otherwise return (this.second.Next() otherwise NoMore);
}
first: FirstIterator;
second: SecondIterator;
}
macro IteratorSequence<T: type, FirstIterator: type, SecondIterator: type>(
first: FirstIterator, second: SecondIterator):
IteratorSequence<T, FirstIterator, SecondIterator> {
return IteratorSequence<T>{first, second};
}
......@@ -99,17 +99,39 @@ extern macro CopyFixedArrayElements(
constexpr ElementsKind, FixedArray, constexpr ElementsKind, FixedArray, Smi,
Smi, Smi): void;
extern macro ExtractFixedArray(FixedArrayBase, Smi, Smi, Smi): FixedArrayBase;
extern macro ExtractFixedArray(
FixedArrayBase, Smi, Smi, Smi,
constexpr ExtractFixedArrayFlag): FixedArrayBase;
extern macro ExtractFixedArray(
FixedArray, intptr, intptr, intptr,
constexpr ExtractFixedArrayFlag): FixedArray;
macro ExtractFixedArray(
source: FixedArray, first: intptr, count: intptr,
capacity: intptr): FixedArray {
// TODO(tebbi): This should be optimized to use memcpy for initialization.
return NewFixedArray(
capacity,
IteratorSequence<Object>(
(& source.objects).Iterator(first, first + count),
ConstantIterator(TheHole)));
}
macro ExtractFixedDoubleArray(
source: FixedDoubleArray, first: intptr, count: intptr,
capacity: intptr): FixedDoubleArray|EmptyFixedArray {
// TODO(tebbi): This should be optimized to use memcpy for initialization.
return NewFixedDoubleArray(
capacity,
IteratorSequence<float64_or_hole>(
(& source.floats).Iterator(first, first + count),
ConstantIterator(kDoubleHole)));
}
macro NewFixedArray<I: type>(length: intptr, it: I): FixedArray {
macro NewFixedArray<Iterator: type>(length: intptr, it: Iterator): FixedArray {
if (length == 0) return kEmptyFixedArray;
return new
FixedArray{map: kFixedArrayMap, length: Convert<Smi>(length), objects: ...it};
}
macro NewFixedDoubleArray<Iterator: type>(
length: intptr, it: Iterator): FixedDoubleArray|EmptyFixedArray {
if (length == 0) return kEmptyFixedArray;
return new FixedDoubleArray{
map: kFixedDoubleArrayMap,
length: Convert<Smi>(length),
floats: ...it
};
}
......@@ -905,8 +905,7 @@ namespace test {
let it = slice.Iterator();
let count: Smi = 0;
while (true) {
let ref = it.Next() otherwise break;
const value = UnsafeCast<Smi>(* ref);
const value = UnsafeCast<Smi>(it.Next() otherwise break);
check(value == count + 7);
count++;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment