Lazily pin the less likely atoms when resolving standard class names (77861, r=jst, sr=jband).

This commit is contained in:
brendan%mozilla.org 2001-05-23 04:02:06 +00:00
Родитель 4f2e65a484
Коммит c2a6ad4e5f
4 изменённых файлов: 106 добавлений и 57 удалений

Просмотреть файл

@ -1124,11 +1124,6 @@ JS_InitStandardClasses(JSContext *cx, JSObject *obj)
#define ATOM_OFFSET(name) offsetof(JSAtomState, name##Atom)
#define OFFSET_TO_ATOM(rt,off) (*(JSAtom **)((char*)&(rt)->atomState + (off)))
#define TAG_ATOM_OFFSET(name) ((const char *) ATOM_OFFSET(name))
#define TAG_CHAR_STRING(name) name
#define UNTAG_ATOM_OFFSET(ptr) ((size_t)(ptr))
#define UNTAG_CHAR_STRING(ptr) ptr
#define IS_ATOM_OFFSET(ptr) ((size_t)(ptr) < sizeof(JSAtomState))
/*
* Table of class initializers and their atom offsets in rt->atomState.
@ -1168,87 +1163,106 @@ static struct {
*/
typedef struct JSStdName {
JSObjectOp init;
const char *name; /* tagged (const char *) or atom offset */
size_t atomOffset; /* offset of atom pointer in JSAtomState */
const char *name; /* null if atom is pre-pinned, else name */
} JSStdName;
static JSAtom *
StdNameToAtom(JSContext *cx, const char *name)
StdNameToAtom(JSContext *cx, JSStdName *stdn)
{
if (IS_ATOM_OFFSET(name))
return OFFSET_TO_ATOM(cx->runtime, UNTAG_ATOM_OFFSET(name));
name = UNTAG_CHAR_STRING(name);
return js_Atomize(cx, name, strlen(name), 0);
size_t offset;
JSAtom *atom;
const char *name;
offset = stdn->atomOffset;
atom = OFFSET_TO_ATOM(cx->runtime, offset);
if (!atom) {
name = stdn->name;
if (name) {
atom = js_Atomize(cx, name, strlen(name), ATOM_PINNED);
OFFSET_TO_ATOM(cx->runtime, offset) = atom;
}
}
return atom;
}
#define EAGERLY_PINNED_ATOM(name) ATOM_OFFSET(name), NULL
#define LAZILY_PINNED_ATOM(name) ATOM_OFFSET(lazy.name), js_##name##_str
static JSStdName standard_class_names[] = {
/* ECMA requires that eval be a direct property of the global object. */
{js_InitObjectClass, TAG_ATOM_OFFSET(eval)},
{js_InitObjectClass, EAGERLY_PINNED_ATOM(eval)},
/* Global properties and functions defined by the Number class. */
{js_InitNumberClass, TAG_CHAR_STRING(js_NaN_str)},
{js_InitNumberClass, TAG_CHAR_STRING(js_Infinity_str)},
{js_InitNumberClass, TAG_CHAR_STRING(js_isNaN_str)},
{js_InitNumberClass, TAG_CHAR_STRING(js_isFinite_str)},
{js_InitNumberClass, TAG_CHAR_STRING(js_parseFloat_str)},
{js_InitNumberClass, TAG_CHAR_STRING(js_parseInt_str)},
{js_InitNumberClass, LAZILY_PINNED_ATOM(NaN)},
{js_InitNumberClass, LAZILY_PINNED_ATOM(Infinity)},
{js_InitNumberClass, LAZILY_PINNED_ATOM(isNaN)},
{js_InitNumberClass, LAZILY_PINNED_ATOM(isFinite)},
{js_InitNumberClass, LAZILY_PINNED_ATOM(parseFloat)},
{js_InitNumberClass, LAZILY_PINNED_ATOM(parseInt)},
/* String global functions. */
#ifndef MOZILLA_CLIENT
/* These two are predefined in a backward-compatible way by the DOM. */
{js_InitStringClass, TAG_CHAR_STRING(js_escape_str)},
{js_InitStringClass, TAG_CHAR_STRING(js_unescape_str)},
{js_InitStringClass, LAZILY_PINNED_ATOM(escape)},
{js_InitStringClass, LAZILY_PINNED_ATOM(unescape)},
#endif
{js_InitStringClass, TAG_CHAR_STRING(js_decodeURI_str)},
{js_InitStringClass, TAG_CHAR_STRING(js_encodeURI_str)},
{js_InitStringClass, TAG_CHAR_STRING(js_decodeURIComponent_str)},
{js_InitStringClass, TAG_CHAR_STRING(js_encodeURIComponent_str)},
{js_InitStringClass, LAZILY_PINNED_ATOM(decodeURI)},
{js_InitStringClass, LAZILY_PINNED_ATOM(encodeURI)},
{js_InitStringClass, LAZILY_PINNED_ATOM(decodeURIComponent)},
{js_InitStringClass, LAZILY_PINNED_ATOM(encodeURIComponent)},
#if JS_HAS_UNEVAL
{js_InitStringClass, TAG_CHAR_STRING(js_uneval_str)},
{js_InitStringClass, LAZILY_PINNED_ATOM(uneval)},
#endif
/* Exception constructors. */
#if JS_HAS_ERROR_EXCEPTIONS
{js_InitExceptionClasses, TAG_ATOM_OFFSET(Error)},
{js_InitExceptionClasses, TAG_CHAR_STRING(js_InternalError_str)},
{js_InitExceptionClasses, TAG_CHAR_STRING(js_EvalError_str)},
{js_InitExceptionClasses, TAG_CHAR_STRING(js_RangeError_str)},
{js_InitExceptionClasses, TAG_CHAR_STRING(js_ReferenceError_str)},
{js_InitExceptionClasses, TAG_CHAR_STRING(js_SyntaxError_str)},
{js_InitExceptionClasses, TAG_CHAR_STRING(js_TypeError_str)},
{js_InitExceptionClasses, TAG_CHAR_STRING(js_URIError_str)},
{js_InitExceptionClasses, EAGERLY_PINNED_ATOM(Error)},
{js_InitExceptionClasses, LAZILY_PINNED_ATOM(InternalError)},
{js_InitExceptionClasses, LAZILY_PINNED_ATOM(EvalError)},
{js_InitExceptionClasses, LAZILY_PINNED_ATOM(RangeError)},
{js_InitExceptionClasses, LAZILY_PINNED_ATOM(ReferenceError)},
{js_InitExceptionClasses, LAZILY_PINNED_ATOM(SyntaxError)},
{js_InitExceptionClasses, LAZILY_PINNED_ATOM(TypeError)},
{js_InitExceptionClasses, LAZILY_PINNED_ATOM(URIError)},
#endif
{NULL, NULL}
{NULL, 0, NULL}
};
static JSStdName object_prototype_names[] = {
/* Object.prototype properties (global delegates to Object.prototype). */
{js_InitObjectClass, TAG_ATOM_OFFSET(proto)},
{js_InitObjectClass, TAG_ATOM_OFFSET(parent)},
{js_InitObjectClass, TAG_ATOM_OFFSET(count)},
{js_InitObjectClass, EAGERLY_PINNED_ATOM(proto)},
{js_InitObjectClass, EAGERLY_PINNED_ATOM(parent)},
{js_InitObjectClass, EAGERLY_PINNED_ATOM(count)},
#if JS_HAS_TOSOURCE
{js_InitObjectClass, TAG_ATOM_OFFSET(toSource)},
{js_InitObjectClass, EAGERLY_PINNED_ATOM(toSource)},
#endif
{js_InitObjectClass, TAG_ATOM_OFFSET(toString)},
{js_InitObjectClass, TAG_ATOM_OFFSET(toLocaleString)},
{js_InitObjectClass, TAG_ATOM_OFFSET(valueOf)},
{js_InitObjectClass, EAGERLY_PINNED_ATOM(toString)},
{js_InitObjectClass, EAGERLY_PINNED_ATOM(toLocaleString)},
{js_InitObjectClass, EAGERLY_PINNED_ATOM(valueOf)},
#if JS_HAS_OBJ_WATCHPOINT
{js_InitObjectClass, TAG_CHAR_STRING(js_watch_str)},
{js_InitObjectClass, TAG_CHAR_STRING(js_unwatch_str)},
{js_InitObjectClass, LAZILY_PINNED_ATOM(watch)},
{js_InitObjectClass, LAZILY_PINNED_ATOM(unwatch)},
#endif
#if JS_HAS_NEW_OBJ_METHODS
{js_InitObjectClass, TAG_CHAR_STRING(js_hasOwnProperty_str)},
{js_InitObjectClass, TAG_CHAR_STRING(js_isPrototypeOf_str)},
{js_InitObjectClass, TAG_CHAR_STRING(js_propertyIsEnumerable_str)},
{js_InitObjectClass, LAZILY_PINNED_ATOM(hasOwnProperty)},
{js_InitObjectClass, LAZILY_PINNED_ATOM(isPrototypeOf)},
{js_InitObjectClass, LAZILY_PINNED_ATOM(propertyIsEnumerable)},
#endif
#if JS_HAS_GETTER_SETTER
{js_InitObjectClass, TAG_CHAR_STRING(js_defineGetter_str)},
{js_InitObjectClass, TAG_CHAR_STRING(js_defineSetter_str)},
{js_InitObjectClass, LAZILY_PINNED_ATOM(defineGetter)},
{js_InitObjectClass, LAZILY_PINNED_ATOM(defineSetter)},
{js_InitObjectClass, LAZILY_PINNED_ATOM(lookupGetter)},
{js_InitObjectClass, LAZILY_PINNED_ATOM(lookupSetter)},
#endif
{NULL, NULL}
{NULL, 0, NULL}
};
#undef EAGERLY_PINNED_ATOM
#undef LAZILY_PINNED_ATOM
JS_PUBLIC_API(JSBool)
JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsval id,
JSBool *resolved)
@ -1290,7 +1304,9 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsval id,
if (!init) {
/* Try less frequently used top-level functions and constants. */
for (i = 0; standard_class_names[i].init; i++) {
atom = StdNameToAtom(cx, standard_class_names[i].name);
atom = StdNameToAtom(cx, &standard_class_names[i]);
if (!atom)
return JS_FALSE;
if (idstr == ATOM_TO_STRING(atom)) {
init = standard_class_names[i].init;
break;
@ -1304,7 +1320,9 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsval id,
* yet been initialized.
*/
for (i = 0; object_prototype_names[i].init; i++) {
atom = StdNameToAtom(cx, object_prototype_names[i].name);
atom = StdNameToAtom(cx, &object_prototype_names[i]);
if (!atom)
return JS_FALSE;
if (idstr == ATOM_TO_STRING(atom)) {
init = standard_class_names[i].init;
break;
@ -1372,11 +1390,6 @@ JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj)
#undef ATOM_OFFSET
#undef OFFSET_TO_ATOM
#undef TAG_ATOM_OFFSET
#undef TAG_CHAR_STRING
#undef UNTAG_ATOM_OFFSET
#undef UNTAG_CHAR_STRING
#undef IS_ATOM_OFFSET
JS_PUBLIC_API(JSObject *)
JS_GetScopeChain(JSContext *cx)

Просмотреть файл

@ -295,6 +295,7 @@ js_InitPinnedAtoms(JSContext *cx, JSAtomState *state)
#undef FROB
memset(&state->lazy, 0, sizeof state->lazy);
return JS_TRUE;
}

Просмотреть файл

@ -142,7 +142,7 @@ struct JSAtomState {
JSAtom *booleanAtoms[2];
JSAtom *nullAtom;
/* Various built-in or commonly-used atoms. */
/* Various built-in or commonly-used atoms, pinned on first context. */
JSAtom *ArgumentsAtom;
JSAtom *ArrayAtom;
JSAtom *BooleanAtom;
@ -180,6 +180,39 @@ struct JSAtomState {
JSAtom *toStringAtom;
JSAtom *valueOfAtom;
/* Less frequently used atoms, pinned lazily by JS_ResolveStandardClass. */
struct {
JSAtom *EvalErrorAtom;
JSAtom *InfinityAtom;
JSAtom *InternalErrorAtom;
JSAtom *NaNAtom;
JSAtom *RangeErrorAtom;
JSAtom *ReferenceErrorAtom;
JSAtom *SyntaxErrorAtom;
JSAtom *TypeErrorAtom;
JSAtom *URIErrorAtom;
JSAtom *decodeURIAtom;
JSAtom *decodeURIComponentAtom;
JSAtom *defineGetterAtom;
JSAtom *defineSetterAtom;
JSAtom *encodeURIAtom;
JSAtom *encodeURIComponentAtom;
JSAtom *escapeAtom;
JSAtom *hasOwnPropertyAtom;
JSAtom *isFiniteAtom;
JSAtom *isNaNAtom;
JSAtom *isPrototypeOfAtom;
JSAtom *lookupGetterAtom;
JSAtom *lookupSetterAtom;
JSAtom *parseFloatAtom;
JSAtom *parseIntAtom;
JSAtom *propertyIsEnumerableAtom;
JSAtom *unescapeAtom;
JSAtom *unevalAtom;
JSAtom *unwatchAtom;
JSAtom *watchAtom;
} lazy;
#ifdef JS_THREADSAFE
JSThinLock lock;
volatile uint32 tablegen;

Просмотреть файл

@ -237,6 +237,8 @@ extern const char js_isPrototypeOf_str[];
extern const char js_propertyIsEnumerable_str[];
extern const char js_defineGetter_str[];
extern const char js_defineSetter_str[];
extern const char js_lookupGetter_str[];
extern const char js_lookupSetter_str[];
extern void
js_InitObjectMap(JSObjectMap *map, jsrefcount nrefs, JSObjectOps *ops,