Bug 40970 - JSArrary can use the 'length' property as a storage size hint
Summary: JSArrary can use the 'length' property as a storage size hint
Status: UNCONFIRMED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: 528+ (Nightly build)
Hardware: All All
: P2 Enhancement
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks: 39115
  Show dependency treegraph
 
Reported: 2010-06-21 22:54 PDT by Caio Marcelo de Oliveira Filho
Modified: 2010-06-29 10:22 PDT (History)
3 users (show)

See Also:


Attachments
Patch v1 (5.07 KB, patch)
2010-06-21 22:59 PDT, Caio Marcelo de Oliveira Filho
ggaren: review-
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Caio Marcelo de Oliveira Filho 2010-06-21 22:54:51 PDT
When passing just one argument to the Array constructor in JavaScript, and its argument is an integer number, it'll create an array with the length equal to the argument, and all the values will be empty. This is implemented internally as a JSArray constructor that takes the length and preallocate part of the internal vector in the array. 

This behaviour is not available for the JSObjectMakeArray in C API, and the alternative of just setting the length property doesn't necessarily will give us the same behaviour as the JavaScript ctor (in this case it seems it doesn't preallocate the internal vector).

We could reuse an invalid input of JSObjectMakeArray, which is argumentsCount > 0 but arguments = NULL (a previously invalid, but not checked, input), to get this functionality. It would mean that one wants to construct an Array with length of argumentCount but since no arguments were given, it would be filled with empty values.
Comment 1 Caio Marcelo de Oliveira Filho 2010-06-21 22:59:26 PDT
Created attachment 59341 [details]
Patch v1

This is my take on the issue. Of course I would be glad to hear suggestions if you think there's a better way to handle this :)
Comment 2 Geoffrey Garen 2010-06-23 09:03:17 PDT
I see two requests in this bug.

1. "I want a way to create an array with an initial length".

I don't think it's a good idea to match the quirk of the JavaScript Array constructor here. It's a very confusing behavior to the uninitiated, and one we intentionally avoided in the API design.

The simple way to get this behavior in the current API is to make an array and then set its length property. That seems sufficient to me.

Plus, an author who really really wants the quirks of the Array constructor can just call the Array constructor.

2. "I want a way to preallocate the Array's internal storage, for performance reasons".

Can you give me an example of a case where the Array's built-in behavior is insufficient?

If there is such a case, I think the proper solution is to fix the built-in behavior, instead of adding to the C API. We want all array clients to go fast, not just C API clients.
Comment 3 Geoffrey Garen 2010-06-23 09:03:52 PDT
Comment on attachment 59341 [details]
Patch v1

r- because I don't think this change is warranted, but maybe you can convince me.
Comment 4 Caio Marcelo de Oliveira Filho 2010-06-28 11:19:57 PDT
Thanks for the comments, Geoffrey.

While I agree this is a quirk in the JavaScript Array API, JSC actually does something different instead of simply creating an empty Array and setting the length. It allocates storage in some situations and fill it with empty values.

So, JSC code already optimizes this case for Array constructor (even calling it a quirk). The patch would just allow C API users to access this case just like JS Array constructor provides us.


> We want all array clients to go fast, not just C API clients.

I might misunderstood your comment, but the patch seems to work in the opposite direction. Enable C API clients to have same access as JavaScript clients have.


The context of this patch is supporting the QScriptEngine::newArray(uint length), which follows the quirk on the builtin Array constructor.

We can, of course, live with the empty followed by setLength(). But just feels a little bit "odd" since we do have special tuned code for this exact case, i.e. JSC internally optimizes this case instead of simply treating as a quirk.
Comment 5 Geoffrey Garen 2010-06-28 13:31:37 PDT
> We can, of course, live with the empty followed by setLength(). But just feels a little bit "odd" since we do have special tuned code for this exact case, i.e. JSC internally optimizes this case instead of simply treating as a quirk.

Don't read too much into the current optimization. It will probably change in the future.

Though the current optimization is written for the JSArray constructor, I think a better solution going forward would be for JSArray to take any assignment to .length -- either an implicit assignment by the constructor quirk, or an explicit assignment by API or the .length property -- as a storage size hint.

It would also be nice if JSArray could allocate spare storage larger than MIN_SPARSE_ARRAY_INDEX, at least for a few arrays, reclaiming wasted / fragmented space as needed.

It's best not to expose these kinds of details in complex and quirky APIs. It might seem like the right thing to do looking at JavaScriptCore from the inside out, but API should be designed for understanding from the outside in.
Comment 6 Caio Marcelo de Oliveira Filho 2010-06-28 18:55:39 PDT
Ok. I agree now that extending C API in this case isn't desirable.


> Though the current optimization is written for the JSArray constructor, I think a better solution going forward would be for JSArray to take any assignment to .length -- either an implicit assignment by the constructor quirk, or an explicit assignment by API or the .length property -- as a storage size hint.

This seems to be a better solution and keeps the C API clean.


> It would also be nice if JSArray could allocate spare storage larger than MIN_SPARSE_ARRAY_INDEX, at least for a few arrays, reclaiming wasted / fragmented space as needed.

You mean allowing a larger vector (when e.g. it was explicitly asked) even if it doesn't satisfy the minimum threshold that today's code use? If so, when the reclaim could take place?


> It's best not to expose these kinds of details in complex and quirky APIs. It might seem like the right thing to do looking at JavaScriptCore from the inside out, but API should be designed for understanding from the outside in.

I'll keep that advice in mind. Thanks.

"Operational" question: should this bug be marked as WONTFIX or RESOLVED and another one created for the "use 'length' as storage size hint"?
Comment 7 Jędrzej Nowacki 2010-06-29 01:20:52 PDT
(In reply to comment #6)
> "Operational" question: should this bug be marked as WONTFIX or RESOLVED and another one created for the "use 'length' as storage size hint"?
I've changed summary.
Comment 8 Geoffrey Garen 2010-06-29 10:22:40 PDT
> > It would also be nice if JSArray could allocate spare storage larger than MIN_SPARSE_ARRAY_INDEX, at least for a few arrays, reclaiming wasted / fragmented space as needed.
> 
> You mean allowing a larger vector (when e.g. it was explicitly asked) even if it doesn't satisfy the minimum threshold that today's code use?

...even if it exceeds the maximum threshold.

> If so, when the reclaim could take place?

Probably at GC time. Maybe on a round-robin basis as new Array buffers are allocated.

> "Operational" question: should this bug be marked as WONTFIX or RESOLVED and another one created for the "use 'length' as storage size hint"?

Probably WONTFIX, with a new bug for using "length" as a storage hint, and another bug for using storage hints more aggressively.