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 { ...@@ -135,9 +135,8 @@ namespace array {
deferred { deferred {
const newLength: intptr = CalculateNewElementsCapacity(length); const newLength: intptr = CalculateNewElementsCapacity(length);
assert(index < newLength); assert(index < newLength);
const newfixedArray: FixedArray = ExtractFixedArray( const newfixedArray: FixedArray =
fixedArray, 0, length, newLength, ExtractFixedArray(fixedArray, 0, length, newLength);
ExtractFixedArrayFlag::kFixedArrays);
newfixedArray.objects[index] = element; newfixedArray.objects[index] = element;
return newfixedArray; return newfixedArray;
} }
......
...@@ -7,25 +7,26 @@ namespace array { ...@@ -7,25 +7,26 @@ namespace array {
// FixedArrayType. Most of this behavior is outsourced to ExtractFixedArray(), // FixedArrayType. Most of this behavior is outsourced to ExtractFixedArray(),
// but the special case of wanting to have a FixedDoubleArray when given a // but the special case of wanting to have a FixedDoubleArray when given a
// zero-length input FixedArray is handled here. // zero-length input FixedArray is handled here.
macro Extract<FixedArrayType : type extends FixedArrayBase>( macro Extract(implicit context: Context)(
elements: FixedArrayBase, first: Smi, count: Smi, elements: FixedArray, first: Smi, count: Smi, capacity: Smi): FixedArray {
capacity: Smi): FixedArrayType; return ExtractFixedArray(
elements, Convert<intptr>(first), Convert<intptr>(count),
Extract<FixedArray>(implicit context: Context)( Convert<intptr>(capacity));
elements: FixedArrayBase, first: Smi, count: Smi, }
capacity: Smi): FixedArray {
return UnsafeCast<FixedArray>( macro Extract(implicit context: Context)(
ExtractFixedArray(elements, first, count, capacity)); elements: FixedDoubleArray|EmptyFixedArray, first: Smi, count: Smi,
} capacity: Smi): FixedDoubleArray|EmptyFixedArray {
typeswitch (elements) {
Extract<FixedDoubleArray>(implicit context: Context)( case (EmptyFixedArray): {
elements: FixedArrayBase, first: Smi, count: Smi,
capacity: Smi): FixedDoubleArray {
if (elements == kEmptyFixedArray) {
return AllocateZeroedFixedDoubleArray(Convert<intptr>(capacity)); return AllocateZeroedFixedDoubleArray(Convert<intptr>(capacity));
} }
return UnsafeCast<FixedDoubleArray>( case (elements: FixedDoubleArray): {
ExtractFixedArray(elements, first, count, capacity)); return ExtractFixedDoubleArray(
elements, Convert<intptr>(first), Convert<intptr>(count),
Convert<intptr>(capacity));
}
}
} }
macro DoMoveElements<FixedArrayType : type extends FixedArrayBase>( macro DoMoveElements<FixedArrayType : type extends FixedArrayBase>(
...@@ -60,29 +61,29 @@ namespace array { ...@@ -60,29 +61,29 @@ namespace array {
array::EnsureWriteableFastElements(a); array::EnsureWriteableFastElements(a);
if (insertCount != actualDeleteCount) { if (insertCount != actualDeleteCount) {
const elements: FixedArrayBase = a.elements; const elements =
UnsafeCast<(FixedArrayType | EmptyFixedArray)>(a.elements);
const dstIndex: Smi = actualStart + insertCount; const dstIndex: Smi = actualStart + insertCount;
const srcIndex: Smi = actualStart + actualDeleteCount; const srcIndex: Smi = actualStart + actualDeleteCount;
const count: Smi = length - actualDeleteCount - actualStart; const count: Smi = length - actualDeleteCount - actualStart;
if (insertCount < actualDeleteCount) { if (insertCount < actualDeleteCount) {
// Shrink. // Shrink.
DoMoveElements<FixedArrayType>( DoMoveElements(
UnsafeCast<FixedArrayType>(elements), dstIndex, srcIndex, count); UnsafeCast<FixedArrayType>(elements), dstIndex, srcIndex, count);
StoreHoles<FixedArrayType>( StoreHoles(UnsafeCast<FixedArrayType>(elements), newLength, length);
UnsafeCast<FixedArrayType>(elements), newLength, length);
} else if (insertCount > actualDeleteCount) { } else if (insertCount > actualDeleteCount) {
// If the backing store is big enough, then moving elements is enough. // If the backing store is big enough, then moving elements is enough.
if (newLength <= elements.length) { if (newLength <= elements.length) {
DoMoveElements<FixedArrayType>( DoMoveElements(
UnsafeCast<FixedArrayType>(elements), dstIndex, srcIndex, count); UnsafeCast<FixedArrayType>(elements), dstIndex, srcIndex, count);
} else { } else {
// Grow. // Grow.
const capacity: Smi = CalculateNewElementsCapacity(newLength); const capacity: Smi = CalculateNewElementsCapacity(newLength);
const newElements: FixedArrayType = const newElements: FixedArrayType = UnsafeCast<FixedArrayType>(
Extract<FixedArrayType>(elements, 0, actualStart, capacity); Extract(elements, 0, actualStart, capacity));
a.elements = newElements; a.elements = newElements;
if (elements.length > 0) { if (elements.length > 0) {
DoCopyElements<FixedArrayType>( DoCopyElements(
newElements, dstIndex, UnsafeCast<FixedArrayType>(elements), newElements, dstIndex, UnsafeCast<FixedArrayType>(elements),
srcIndex, count); srcIndex, count);
} }
......
...@@ -26,9 +26,10 @@ namespace array { ...@@ -26,9 +26,10 @@ namespace array {
// extract FixedArrays and don't have to worry about FixedDoubleArrays. // extract FixedArrays and don't have to worry about FixedDoubleArrays.
assert(IsFastSmiOrTaggedElementsKind(array.map.elements_kind)); assert(IsFastSmiOrTaggedElementsKind(array.map.elements_kind));
const length: Smi = Cast<Smi>(array.length) otherwise unreachable; const length =
array.elements = ExtractFixedArray( Convert<intptr>(Cast<Smi>(array.length) otherwise unreachable);
elements, 0, length, length, ExtractFixedArrayFlag::kFixedArrays); array.elements =
ExtractFixedArray(UnsafeCast<FixedArray>(elements), 0, length, length);
assert(array.elements.map != kCOWMap); assert(array.elements.map != kCOWMap);
} }
......
...@@ -886,6 +886,7 @@ macro UnsafeCast<A : type extends Object>(implicit context: Context)(o: Object): ...@@ -886,6 +886,7 @@ macro UnsafeCast<A : type extends Object>(implicit context: Context)(o: Object):
} }
extern macro FixedArrayMapConstant(): Map; extern macro FixedArrayMapConstant(): Map;
extern macro FixedDoubleArrayMapConstant(): Map;
extern macro FixedCOWArrayMapConstant(): Map; extern macro FixedCOWArrayMapConstant(): Map;
extern macro EmptyByteArrayConstant(): ByteArray; extern macro EmptyByteArrayConstant(): ByteArray;
extern macro EmptyFixedArrayConstant(): EmptyFixedArray; extern macro EmptyFixedArrayConstant(): EmptyFixedArray;
...@@ -895,6 +896,7 @@ extern macro StringMapConstant(): Map; ...@@ -895,6 +896,7 @@ extern macro StringMapConstant(): Map;
extern macro SloppyArgumentsElementsMapConstant(): Map; extern macro SloppyArgumentsElementsMapConstant(): Map;
const kFixedArrayMap: Map = FixedArrayMapConstant(); const kFixedArrayMap: Map = FixedArrayMapConstant();
const kFixedDoubleArrayMap: Map = FixedDoubleArrayMapConstant();
const kCOWMap: Map = FixedCOWArrayMapConstant(); const kCOWMap: Map = FixedCOWArrayMapConstant();
const kEmptyByteArray: ByteArray = EmptyByteArrayConstant(); const kEmptyByteArray: ByteArray = EmptyByteArrayConstant();
const kEmptyFixedArray: EmptyFixedArray = EmptyFixedArrayConstant(); const kEmptyFixedArray: EmptyFixedArray = EmptyFixedArrayConstant();
......
...@@ -288,6 +288,32 @@ Cast<FixedDoubleArray>(o: HeapObject): FixedDoubleArray ...@@ -288,6 +288,32 @@ Cast<FixedDoubleArray>(o: HeapObject): FixedDoubleArray
return HeapObjectToFixedDoubleArray(o) otherwise CastError; 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 Cast<SloppyArgumentsElements>(o: HeapObject): SloppyArgumentsElements
labels CastError { labels CastError {
return HeapObjectToSloppyArgumentsElements(o) otherwise CastError; return HeapObjectToSloppyArgumentsElements(o) otherwise CastError;
......
...@@ -14,9 +14,7 @@ namespace growable_fixed_array { ...@@ -14,9 +14,7 @@ namespace growable_fixed_array {
assert(newCapacity >= 0); assert(newCapacity >= 0);
assert(newCapacity >= this.length); assert(newCapacity >= this.length);
const first: intptr = 0; const first: intptr = 0;
return ExtractFixedArray( return ExtractFixedArray(this.array, first, this.length, newCapacity);
this.array, first, this.length, newCapacity,
ExtractFixedArrayFlag::kFixedArrays);
} }
macro EnsureCapacity() { macro EnsureCapacity() {
assert(this.length <= this.capacity); assert(this.length <= this.capacity);
......
...@@ -63,6 +63,19 @@ namespace torque_internal { ...@@ -63,6 +63,19 @@ namespace torque_internal {
unsafeMarker: Unsafe {} 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 object: HeapObject;
const offset: intptr; const offset: intptr;
...@@ -85,7 +98,11 @@ namespace torque_internal { ...@@ -85,7 +98,11 @@ namespace torque_internal {
return this.start == this.end; 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()) { if (this.Empty()) {
goto NoMore; goto NoMore;
} else { } else {
...@@ -143,7 +160,7 @@ namespace torque_internal { ...@@ -143,7 +160,7 @@ namespace torque_internal {
let targetIterator = target.Iterator(); let targetIterator = target.Iterator();
let originIterator = originIterator; let originIterator = originIterator;
while (true) { while (true) {
const ref:&T = targetIterator.Next() otherwise break; const ref:&T = targetIterator.NextReference() otherwise break;
* ref = originIterator.Next() otherwise unreachable; * ref = originIterator.Next() otherwise unreachable;
} }
} }
...@@ -180,3 +197,23 @@ struct UninitializedIterator {} ...@@ -180,3 +197,23 @@ struct UninitializedIterator {}
// type assert() // type assert()
intrinsic %RawDownCast<To: type, From: type>(x: From): To; intrinsic %RawDownCast<To: type, From: type>(x: From): To;
intrinsic %RawConstexprCast<To: type, From: type>(f: 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( ...@@ -99,17 +99,39 @@ extern macro CopyFixedArrayElements(
constexpr ElementsKind, FixedArray, constexpr ElementsKind, FixedArray, Smi, constexpr ElementsKind, FixedArray, constexpr ElementsKind, FixedArray, Smi,
Smi, Smi): void; Smi, Smi): void;
extern macro ExtractFixedArray(FixedArrayBase, Smi, Smi, Smi): FixedArrayBase; macro ExtractFixedArray(
extern macro ExtractFixedArray( source: FixedArray, first: intptr, count: intptr,
FixedArrayBase, Smi, Smi, Smi, capacity: intptr): FixedArray {
constexpr ExtractFixedArrayFlag): FixedArrayBase; // TODO(tebbi): This should be optimized to use memcpy for initialization.
return NewFixedArray(
extern macro ExtractFixedArray( capacity,
FixedArray, intptr, intptr, intptr, IteratorSequence<Object>(
constexpr ExtractFixedArrayFlag): FixedArray; (& 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; if (length == 0) return kEmptyFixedArray;
return new return new
FixedArray{map: kFixedArrayMap, length: Convert<Smi>(length), objects: ...it}; 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 { ...@@ -905,8 +905,7 @@ namespace test {
let it = slice.Iterator(); let it = slice.Iterator();
let count: Smi = 0; let count: Smi = 0;
while (true) { while (true) {
let ref = it.Next() otherwise break; const value = UnsafeCast<Smi>(it.Next() otherwise break);
const value = UnsafeCast<Smi>(* ref);
check(value == count + 7); check(value == count + 7);
count++; 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