mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 453747 - Avoid overuse of the fun_getProperty class getter to optimize getting and setting random properties on functions. r=mrbkap
This commit is contained in:
parent
2843975354
commit
ce684a0a6e
@ -1,5 +1,5 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=78:
|
||||
* vim: set ts=8 sw=4 et tw=99:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
@ -960,41 +960,6 @@ JS_FRIEND_DATA(JSClass) js_CallClass = {
|
||||
JS_CLASS_TRACE(args_or_call_trace), call_reserveSlots
|
||||
};
|
||||
|
||||
/*
|
||||
* ECMA-262 specifies that length is a property of function object instances,
|
||||
* but we can avoid that space cost by delegating to a prototype property that
|
||||
* is JSPROP_PERMANENT and JSPROP_SHARED. Each fun_getProperty call computes
|
||||
* a fresh length value based on the arity of the individual function object's
|
||||
* private data.
|
||||
*
|
||||
* The extensions below other than length, i.e., the ones not in ECMA-262,
|
||||
* are neither JSPROP_READONLY nor JSPROP_SHARED, because for compatibility
|
||||
* with ECMA we must allow a delegating object to override them. Therefore to
|
||||
* avoid entraining garbage in Function.prototype slots, they must be resolved
|
||||
* in non-prototype function objects, wherefore the lazy_function_props table
|
||||
* and fun_resolve's use of it.
|
||||
*/
|
||||
#define LENGTH_PROP_ATTRS (JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED)
|
||||
|
||||
static JSPropertySpec function_props[] = {
|
||||
{js_length_str, ARGS_LENGTH, LENGTH_PROP_ATTRS, 0,0},
|
||||
{0,0,0,0,0}
|
||||
};
|
||||
|
||||
typedef struct LazyFunctionProp {
|
||||
uint16 atomOffset;
|
||||
int8 tinyid;
|
||||
uint8 attrs;
|
||||
} LazyFunctionProp;
|
||||
|
||||
/* NB: no sentinel at the end -- use JS_ARRAY_LENGTH to bound loops. */
|
||||
static LazyFunctionProp lazy_function_props[] = {
|
||||
{ATOM_OFFSET(arguments), CALL_ARGUMENTS, JSPROP_PERMANENT},
|
||||
{ATOM_OFFSET(arity), FUN_ARITY, JSPROP_PERMANENT},
|
||||
{ATOM_OFFSET(caller), FUN_CALLER, JSPROP_PERMANENT},
|
||||
{ATOM_OFFSET(name), FUN_NAME, JSPROP_PERMANENT},
|
||||
};
|
||||
|
||||
static JSBool
|
||||
fun_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
@ -1092,6 +1057,41 @@ fun_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* ECMA-262 specifies that length is a property of function object instances,
|
||||
* but we can avoid that space cost by delegating to a prototype property that
|
||||
* is JSPROP_PERMANENT and JSPROP_SHARED. Each fun_getProperty call computes
|
||||
* a fresh length value based on the arity of the individual function object's
|
||||
* private data.
|
||||
*
|
||||
* The extensions below other than length, i.e., the ones not in ECMA-262,
|
||||
* are neither JSPROP_READONLY nor JSPROP_SHARED, because for compatibility
|
||||
* with ECMA we must allow a delegating object to override them. Therefore to
|
||||
* avoid entraining garbage in Function.prototype slots, they must be resolved
|
||||
* in non-prototype function objects, wherefore the lazy_function_props table
|
||||
* and fun_resolve's use of it.
|
||||
*/
|
||||
#define LENGTH_PROP_ATTRS (JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED)
|
||||
|
||||
static JSPropertySpec function_props[] = {
|
||||
{js_length_str, ARGS_LENGTH, LENGTH_PROP_ATTRS, fun_getProperty, JS_PropertyStub},
|
||||
{0,0,0,0,0}
|
||||
};
|
||||
|
||||
typedef struct LazyFunctionProp {
|
||||
uint16 atomOffset;
|
||||
int8 tinyid;
|
||||
uint8 attrs;
|
||||
} LazyFunctionProp;
|
||||
|
||||
/* NB: no sentinel at the end -- use JS_ARRAY_LENGTH to bound loops. */
|
||||
static LazyFunctionProp lazy_function_props[] = {
|
||||
{ATOM_OFFSET(arguments), CALL_ARGUMENTS, JSPROP_PERMANENT},
|
||||
{ATOM_OFFSET(arity), FUN_ARITY, JSPROP_PERMANENT},
|
||||
{ATOM_OFFSET(caller), FUN_CALLER, JSPROP_PERMANENT},
|
||||
{ATOM_OFFSET(name), FUN_NAME, JSPROP_PERMANENT},
|
||||
};
|
||||
|
||||
static JSBool
|
||||
fun_enumerate(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
@ -1182,9 +1182,9 @@ fun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
|
||||
if (id == ATOM_KEY(atom)) {
|
||||
if (!js_DefineNativeProperty(cx, obj,
|
||||
ATOM_TO_JSID(atom), JSVAL_VOID,
|
||||
NULL, NULL, lfp->attrs,
|
||||
SPROP_HAS_SHORTID, lfp->tinyid,
|
||||
NULL)) {
|
||||
fun_getProperty, JS_PropertyStub,
|
||||
lfp->attrs, SPROP_HAS_SHORTID,
|
||||
lfp->tinyid, NULL)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
*objp = obj;
|
||||
@ -1504,7 +1504,7 @@ JS_FRIEND_DATA(JSClass) js_FunctionClass = {
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(2) |
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Function),
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
fun_getProperty, JS_PropertyStub,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
fun_enumerate, (JSResolveOp)fun_resolve,
|
||||
fun_convert, fun_finalize,
|
||||
NULL, NULL,
|
||||
|
@ -3951,8 +3951,7 @@ TraceRecorder::record_JSOP_NEW()
|
||||
LIns* args[] = { get(&fval), cx_ins };
|
||||
LIns* tv_ins = lir->insCall(F_FastNewObject, args);
|
||||
guard(false, lir->ins_eq0(tv_ins), OOM_EXIT);
|
||||
jsval& tv = stackval(0 - (1 + argc));
|
||||
set(&tv, tv_ins);
|
||||
set(&tval, tv_ins);
|
||||
return interpretedFunctionCall(fval, fun, argc);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user