ref: 9f181651fb03b9d951ae60ae7ef51589efe69015
parent: 9ded251f9ba34702dbc0d434b7be9727c5ce2072
author: Tor Andersson <tor.andersson@artifex.com>
date: Fri Nov 7 11:00:45 EST 2014
Track array sparseness to be smarter in jsV_resizearray.
--- a/jsproperty.c
+++ b/jsproperty.c
@@ -27,7 +27,7 @@
NULL, NULL
};
-static js_Property *newproperty(js_State *J, const char *name)
+static js_Property *newproperty(js_State *J, js_Object *obj, const char *name)
{
js_Property *node = js_malloc(J, sizeof *node);
node->name = js_intern(J, name);
@@ -40,6 +40,7 @@
node->value.u.number = 0;
node->getter = NULL;
node->setter = NULL;
+ ++obj->count;
return node;
}
@@ -80,14 +81,14 @@
return node;
}
-static js_Property *insert(js_State *J, js_Property *node, const char *name, js_Property **result)
+static js_Property *insert(js_State *J, js_Object *obj, js_Property *node, const char *name, js_Property **result)
{
if (node != &sentinel) {
int c = strcmp(name, node->name);
if (c < 0)
- node->left = insert(J, node->left, name, result);
+ node->left = insert(J, obj, node->left, name, result);
else if (c > 0)
- node->right = insert(J, node->right, name, result);
+ node->right = insert(J, obj, node->right, name, result);
else
return *result = node;
node = skew(node);
@@ -94,7 +95,7 @@
node = split(node);
return node;
}
- return *result = newproperty(J, name);
+ return *result = newproperty(J, obj, name);
}
static void freeproperty(js_State *J, js_Object *obj, js_Property *node)
@@ -105,6 +106,7 @@
obj->tailp = node->prevp;
*node->prevp = node->next;
js_free(J, node);
+ --obj->count;
}
static js_Property *delete(js_State *J, js_Object *obj, js_Property *node, const char *name)
@@ -207,7 +209,7 @@
if (!obj->extensible)
return lookup(obj->properties, name);
- obj->properties = insert(J, obj->properties, name, &result);
+ obj->properties = insert(J, obj, obj->properties, name, &result);
if (!result->prevp) {
result->prevp = obj->tailp;
*obj->tailp = result;
@@ -315,11 +317,19 @@
const char *s;
unsigned int k;
if (newlen < obj->u.a.length) {
- js_Object *it = jsV_newiterator(J, obj, 1);
- while ((s = jsV_nextiterator(J, it))) {
- k = jsV_numbertouint32(jsV_stringtonumber(J, s));
- if (k >= newlen && !strcmp(s, jsV_numbertostring(J, k)))
- jsV_delproperty(J, obj, s);
+ if (obj->u.a.length > obj->count * 2) {
+ js_Object *it = jsV_newiterator(J, obj, 1);
+ while ((s = jsV_nextiterator(J, it))) {
+ k = jsV_numbertouint32(jsV_stringtonumber(J, s));
+ if (k >= newlen && !strcmp(s, jsV_numbertostring(J, k)))
+ jsV_delproperty(J, obj, s);
+ }
+ } else {
+ for (k = newlen; k < obj->u.a.length; ++k) {
+ char buf[32];
+ sprintf(buf, "%u", k);
+ jsV_delproperty(J, obj, buf);
+ }
}
}
obj->u.a.length = newlen;
--- a/jsvalue.h
+++ b/jsvalue.h
@@ -63,6 +63,7 @@
int extensible;
js_Property *properties;
js_Property *head, **tailp; /* for enumeration */
+ unsigned int count; /* number of properties, for array sparseness check */
js_Object *prototype;
union {
int boolean;