mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
No need to lookup parent/proto for iteration objects used for enumeration, and cache the last free iteration object for re-use (558058, r=brendan).
This commit is contained in:
parent
edcf471ddb
commit
b0f31bea3f
@ -155,6 +155,8 @@ JSThreadData::mark(JSTracer *trc)
|
|||||||
void
|
void
|
||||||
JSThreadData::purge(JSContext *cx)
|
JSThreadData::purge(JSContext *cx)
|
||||||
{
|
{
|
||||||
|
cachedIteratorObject = NULL;
|
||||||
|
|
||||||
purgeGCFreeLists();
|
purgeGCFreeLists();
|
||||||
|
|
||||||
js_PurgeGSNCache(&gsnCache);
|
js_PurgeGSNCache(&gsnCache);
|
||||||
|
@ -567,6 +567,12 @@ struct JSThreadData {
|
|||||||
|
|
||||||
jsuword nativeEnumCache[NATIVE_ENUM_CACHE_SIZE];
|
jsuword nativeEnumCache[NATIVE_ENUM_CACHE_SIZE];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* One-entry deep cache of iterator objects. We deposit here the last
|
||||||
|
* iterator that was freed in JSOP_ENDITER.
|
||||||
|
*/
|
||||||
|
JSObject *cachedIteratorObject;
|
||||||
|
|
||||||
bool init();
|
bool init();
|
||||||
void finish();
|
void finish();
|
||||||
void mark(JSTracer *trc);
|
void mark(JSTracer *trc);
|
||||||
|
@ -392,15 +392,29 @@ js_ValueToIterator(JSContext *cx, uintN flags, jsval *vp)
|
|||||||
default_iter:
|
default_iter:
|
||||||
/*
|
/*
|
||||||
* Fail over to the default enumerating native iterator.
|
* Fail over to the default enumerating native iterator.
|
||||||
*
|
|
||||||
* Create iterobj with a NULL parent to ensure that we use the
|
|
||||||
* correct scope chain to lookup the iterator's constructor. Since
|
|
||||||
* we use the parent slot to keep track of the iterable, we must
|
|
||||||
* fix it up after.
|
|
||||||
*/
|
*/
|
||||||
iterobj = js_NewObject(cx, &js_IteratorClass, NULL, NULL);
|
if (flags & JSITER_ENUMERATE) {
|
||||||
if (!iterobj)
|
/*
|
||||||
|
* The iterator object for JSITER_ENUMERATE never escapes, so we
|
||||||
|
* don't care for the proper parent/proto to be set. This also
|
||||||
|
* allows us to re-use a previous iterator object that was freed
|
||||||
|
* by JSOP_ENDITER.
|
||||||
|
*/
|
||||||
|
if ((iterobj = JS_THREAD_DATA(cx)->cachedIteratorObject) != NULL) {
|
||||||
|
JS_THREAD_DATA(cx)->cachedIteratorObject = NULL;
|
||||||
|
} else {
|
||||||
|
if (!(iterobj = js_NewObjectWithGivenProto(cx, &js_IteratorClass, NULL, NULL)))
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* These objects don't escape either, but we construct a
|
||||||
|
* StopIteration exception based on the parent of the iterator
|
||||||
|
* object, so we need the correct parent here.
|
||||||
|
*/
|
||||||
|
if (!(iterobj = js_NewObject(cx, &js_IteratorClass, NULL, NULL)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Store in *vp to protect it from GC (callers must root vp). */
|
/* Store in *vp to protect it from GC (callers must root vp). */
|
||||||
*vp = OBJECT_TO_JSVAL(iterobj);
|
*vp = OBJECT_TO_JSVAL(iterobj);
|
||||||
@ -434,6 +448,13 @@ js_CloseIterator(JSContext *cx, jsval v)
|
|||||||
|
|
||||||
if (clasp == &js_IteratorClass) {
|
if (clasp == &js_IteratorClass) {
|
||||||
js_CloseNativeIterator(cx, obj);
|
js_CloseNativeIterator(cx, obj);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that we don't care what kind of iterator we close here. Even if it
|
||||||
|
* is not JSITER_ENUMERATE, it is safe to re-use the object later on for a
|
||||||
|
* JSITER_ENUMERATE iteration.
|
||||||
|
*/
|
||||||
|
JS_THREAD_DATA(cx)->cachedIteratorObject = obj;
|
||||||
}
|
}
|
||||||
#if JS_HAS_GENERATORS
|
#if JS_HAS_GENERATORS
|
||||||
else if (clasp == &js_GeneratorClass) {
|
else if (clasp == &js_GeneratorClass) {
|
||||||
|
Loading…
Reference in New Issue
Block a user