> On 3. Aug 2017, at 00:21, John McCall <rjmcc...@apple.com> wrote:
>
>
>> On Aug 2, 2017, at 6:10 PM, John McCall via swift-evolution
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>
>>> On Aug 2, 2017, at 5:56 PM, Karl Wagner <razie...@gmail.com
>>> <mailto:razie...@gmail.com>> wrote:
>>>> On 31. Jul 2017, at 21:09, John McCall via swift-evolution
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>
>>>>> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan
>>>>> <gor.f.gyolchan...@icloud.com <mailto:gor.f.gyolchan...@icloud.com>>
>>>>> wrote:
>>>>>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution
>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>>>
>>>>>>> On Jul 30, 2017, at 11:43 PM, Daryle Walker <dary...@mac.com
>>>>>>> <mailto:dary...@mac.com>> wrote:
>>>>>>> The parameters for a fixed-size array type determine the type's
>>>>>>> size/stride, so how could the bounds not be needed during compile-time?
>>>>>>> The compiler can't layout objects otherwise.
>>>>>>
>>>>>> Swift is not C; it is perfectly capable of laying out objects at run
>>>>>> time. It already has to do that for generic types and types with
>>>>>> resilient members. That does, of course, have performance consequences,
>>>>>> and those performance consequences might be unacceptable to you; but the
>>>>>> fact that we can handle it means that we don't ultimately require a
>>>>>> semantic concept of a constant expression, except inasmuch as we want to
>>>>>> allow users to explicitly request guarantees about static layout.
>>>>>
>>>>> Doesn't this defeat the purpose of generic value parameters? We might as
>>>>> well use a regular parameter if there's no compile-time evaluation
>>>>> involved. In that case, fixed-sized arrays will be useless, because
>>>>> they'll be normal arrays with resizing disabled.
>>>>
>>>> You're making huge leaps here. The primary purpose of a fixed-size array
>>>> feature is to allow the array to be allocated "inline" in its context
>>>> instead of "out-of-line" using heap-allocated copy-on-write buffers.
>>>> There is no reason that that representation would not be supportable just
>>>> because the array's bound is not statically known; the only thing that
>>>> matters is whether the bound is consistent for all instances of the
>>>> container.
>>>>
>>>> That is, it would not be okay to have a type like:
>>>> struct Widget {
>>>> let length: Int
>>>> var array: [length x Int]
>>>> }
>>>> because the value of the bound cannot be computed independently of a
>>>> specific value.
>>>>
>>>> But it is absolutely okay to have a type like:
>>>> struct Widget {
>>>> var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
>>>> }
>>>> It just means that the bound would get computed at runtime and,
>>>> presumably, cached. The fact that this type's size isn't known statically
>>>> does mean that the compiler has to be more pessimistic, but its values
>>>> would still get allocated inline into their containers and even on the
>>>> stack, using pretty much the same techniques as C99 VLAs.
>>>
>>> Do we really want to make that guarantee about heap/stack allocation? C99’s
>>> VLAs are not very loop-friendly:
>>>
>>> echo "int main() {
>>> for(int i = 0; i<1000000; i++) {
>>> int myArray[i * 1000]; myArray[0] = 32;
>>> }
>>> return 0;
>>> }" | clang -x c - && ./a.out
>>>
>>> Segmentation Fault: 11
>>>
>>> C compilers also do not inline code with VLAs by default. If you force it,
>>> you expose yourself to possible stack overflows:
>>>
>>> echo "static inline void doSomething(int i) {
>>> int myArray[i * 1000]; myArray[0] = 32;
>>> }
>>> int main() {
>>> for(int i = 0; i<1000000; i++) {
>>> doSomething(i);
>>> }
>>> return 0;
>>> }" | clang -x c - && ./a.out
>>>
>>> Segmentation Fault: 11
>>>
>>> I wouldn’t like us to import these kinds of issues in to Swift
>>
>> We probably would not make an absolute guarantee of stack allocation, no.
>
> Although I will note that the problem in your example has nothing to do with
> it being a loop and everything to do with it asking for an almost 4GB array.
> :)
>
> John.
Yeah, apologies - it was a bit of a poorly-written example.
The root cause, of course, is that the VLAs require new stack allocations each
time, and the stack is only deallocated as one lump when the frame ends. A
fixed-size object could be allocated once and re-used. Inlining prevents new
stack frames being created and hence defers deallocation of those objects until
the outer function ends, pushing up the high-water mark of the stack.
The problem also happens with an outer loop of only 10_000, so only 38MB.
Still, enough to blow it up.
- Karl
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution