Bug 209043 - Should not use variable-length-array (VLA)
Summary: Should not use variable-length-array (VLA)
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Yusuke Suzuki
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2020-03-13 01:07 PDT by Yusuke Suzuki
Modified: 2020-03-15 13:02 PDT (History)
26 users (show)

See Also:


Attachments
Patch (40.58 KB, patch)
2020-03-13 02:47 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (40.53 KB, patch)
2020-03-13 02:52 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (45.96 KB, patch)
2020-03-13 22:46 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (51.08 KB, patch)
2020-03-13 23:22 PDT, Yusuke Suzuki
mark.lam: review+
Details | Formatted Diff | Diff
Patch (53.40 KB, patch)
2020-03-15 02:55 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yusuke Suzuki 2020-03-13 01:07:53 PDT
...
Comment 1 Yusuke Suzuki 2020-03-13 02:39:43 PDT
<rdar://problem/59175669>
Comment 2 Yusuke Suzuki 2020-03-13 02:47:55 PDT
Created attachment 393467 [details]
Patch

Add tests later
Comment 3 Yusuke Suzuki 2020-03-13 02:52:55 PDT
Created attachment 393468 [details]
Patch

Add tests later
Comment 4 Yusuke Suzuki 2020-03-13 22:46:12 PDT
Created attachment 393574 [details]
Patch
Comment 5 Yusuke Suzuki 2020-03-13 23:22:50 PDT
Created attachment 393579 [details]
Patch
Comment 6 Mark Lam 2020-03-14 19:04:12 PDT
Comment on attachment 393579 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=393579&action=review

r=me with one concern about JSAPIValueWrapper on !CPU(ADDRESS64) targets.

> Source/JavaScriptCore/API/MarkedJSValueRefArray.cpp:60
> +        visitor.appendUnbarriered(jsCell); // We should mark the wrapper itself to keep JSValueRef live.

I didn't quite understand what this comment meant in the first place until I read JSC::JSValue toJS(JSC::JSGlobalObject* globalObject, JSValueRef v).

From my reading of the code, I see that the jsCell here may be a JSAPIValueWrapper which is itself a JSCell.  Hence, we should visit the JSAPIValueWrapper itself, and that means appending the jsCell here should do the right thing regardless of whether the jsCell is a JSAPIValueWrapper or some other JSCell.

That said, JSAPIValueWrapper does not appear to have a visitChildren() function.  Hence, I don't see how its m_value will get visited.  Am I missing something?

If the above is accurate, I think we don't need this comment.  We do need to look into how the JSAPIValueWrapper::m_value gets visited, and add a visitChildren() there for the !CPU(ADDRESS64) case.  Should probably do that in a separate bug.

> Source/JavaScriptCore/heap/Heap.cpp:3011
> +void Heap::addmarkedJSValueRefArray(MarkedJSValueRefArray* array)

typo: /addmarkedJSValueRefArray/addMarkedJSValueRefArray/
Comment 7 Yusuke Suzuki 2020-03-15 02:53:20 PDT
Comment on attachment 393579 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=393579&action=review

>> Source/JavaScriptCore/API/MarkedJSValueRefArray.cpp:60
>> +        visitor.appendUnbarriered(jsCell); // We should mark the wrapper itself to keep JSValueRef live.
> 
> I didn't quite understand what this comment meant in the first place until I read JSC::JSValue toJS(JSC::JSGlobalObject* globalObject, JSValueRef v).
> 
> From my reading of the code, I see that the jsCell here may be a JSAPIValueWrapper which is itself a JSCell.  Hence, we should visit the JSAPIValueWrapper itself, and that means appending the jsCell here should do the right thing regardless of whether the jsCell is a JSAPIValueWrapper or some other JSCell.
> 
> That said, JSAPIValueWrapper does not appear to have a visitChildren() function.  Hence, I don't see how its m_value will get visited.  Am I missing something?
> 
> If the above is accurate, I think we don't need this comment.  We do need to look into how the JSAPIValueWrapper::m_value gets visited, and add a visitChildren() there for the !CPU(ADDRESS64) case.  Should probably do that in a separate bug.

JSAPIValueWrapper is only used for non-cell values (undefined, number etc.). So this means that the wrapped value itself does not require visitChildren.
This wrapper exists only because we need to keep sizeof(JSValueRef) 32bit in 32bit architecture. Since our non-cell values require 64bit value representation, we decided to use JSAPIValueWrapper as a work-around for this problem.
Comment 8 Yusuke Suzuki 2020-03-15 02:55:36 PDT
Created attachment 393610 [details]
Patch

Patch for landing
Comment 9 Yusuke Suzuki 2020-03-15 03:13:39 PDT
Comment on attachment 393579 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=393579&action=review

>> Source/JavaScriptCore/heap/Heap.cpp:3011
>> +void Heap::addmarkedJSValueRefArray(MarkedJSValueRefArray* array)
> 
> typo: /addmarkedJSValueRefArray/addMarkedJSValueRefArray/

Fixed.
Comment 10 Yusuke Suzuki 2020-03-15 03:16:57 PDT
Committed r258478: <https://trac.webkit.org/changeset/258478>
Comment 11 Darin Adler 2020-03-15 12:08:39 PDT
Comment on attachment 393610 [details]
Patch

WTF::Vector with inline capacity was originally invented to use in local variables to create a safer alternative to variable length arrays that spills out onto the heap when needed, but has similar efficiency when the array is smaller than a fixed predicted size. I’m maybe a tiny bit surprised that we didn’t switch to use them in any of these cases.
Comment 12 Darin Adler 2020-03-15 13:02:43 PDT
Comment on attachment 393610 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=393610&action=review

> Source/JavaScriptCore/API/JSContext.mm:237
> +            [arguments setObject:[JSValue valueWithJSValueRef:entry->arguments[i] inContext:context] atIndexedSubscript:i];

This should just be calling addObject: rather than setObject:atIndexedSubscript: unless I am missing something.

What’s the benefit of using setObject:atIndexedSubscript: here?

> Source/JavaScriptCore/API/MarkedJSValueRefArray.h:68
> +    unsigned m_size;
> +    JSValueRef m_inlineBuffer[inlineCapacity] { };
> +    BufferUniquePtr m_buffer;

Frustrating that this is basically re-implementing Vector with inline capacity. Is there some way to take advantage of Vector or are there just not enough template arguments?

> Source/WebCore/html/canvas/WebGL2RenderingContext.cpp:396
> +    Vector<GCGLint> params(numValues);

Could use inline capacity here if we want to avoid allocating on the heap when there are small numbers of arguments.

> Source/WebCore/html/canvas/WebGL2RenderingContext.cpp:426
> +    Vector<GCGLint> params(numValues);

Ditto.

> Source/WebCore/platform/mediastream/mac/CoreAudioCaptureDeviceManager.cpp:170
> +    Vector<AudioObjectID> deviceIDs(deviceCount);

Ditto.

> Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm:65
> +    Vector<CGDirectDisplayID> activeDisplays(displayCount);

Ditto.

> Source/WebKit/UIProcess/_WKTouchEventGenerator.mm:297
> +    Vector<CGPoint> locations(touchCount);

Ditto.

> Source/WebKit/UIProcess/_WKTouchEventGenerator.mm:330
> +    Vector<CGPoint> locations(touchCount);

Ditto.

> Source/WebKit/UIProcess/_WKTouchEventGenerator.mm:348
> +    Vector<CGPoint> startLocations(touchCount);
> +    Vector<CGPoint> nextLocations(touchCount);

Ditto.