зеркало из https://github.com/mozilla/gecko-dev.git
Bug 711563 - more compact property and function tables; r=jorendorff
This commit is contained in:
Родитель
b19568f2e7
Коммит
932c51585a
|
@ -389,7 +389,9 @@ SharedDefineSetter(JSContext *cx, uintN argc, jsval *vp)
|
|||
JSBool
|
||||
xpc_qsDefineQuickStubs(JSContext *cx, JSObject *proto, uintN flags,
|
||||
PRUint32 ifacec, const nsIID **interfaces,
|
||||
PRUint32 tableSize, const xpc_qsHashEntry *table)
|
||||
PRUint32 tableSize, const xpc_qsHashEntry *table,
|
||||
const xpc_qsPropertySpec *propspecs,
|
||||
const xpc_qsFunctionSpec *funcspecs)
|
||||
{
|
||||
/*
|
||||
* Walk interfaces in reverse order to behave like XPConnect when a
|
||||
|
@ -408,27 +410,25 @@ xpc_qsDefineQuickStubs(JSContext *cx, JSObject *proto, uintN flags,
|
|||
if (entry) {
|
||||
for (;;) {
|
||||
// Define quick stubs for attributes.
|
||||
const xpc_qsPropertySpec *ps = entry->properties;
|
||||
if (ps) {
|
||||
for (; ps->name; ps++) {
|
||||
const xpc_qsPropertySpec *ps = propspecs + entry->prop_index;
|
||||
const xpc_qsPropertySpec *ps_end = ps + entry->n_props;
|
||||
for ( ; ps < ps_end; ++ps) {
|
||||
definedProperty = true;
|
||||
if (!JS_DefineProperty(cx, proto, ps->name, JSVAL_VOID,
|
||||
ps->getter, ps->setter,
|
||||
flags | JSPROP_SHARED))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Define quick stubs for methods.
|
||||
const xpc_qsFunctionSpec *fs = entry->functions;
|
||||
if (fs) {
|
||||
for (; fs->name; fs++) {
|
||||
const xpc_qsFunctionSpec *fs = funcspecs + entry->func_index;
|
||||
const xpc_qsFunctionSpec *fs_end = fs + entry->n_funcs;
|
||||
for ( ; fs < fs_end; ++fs) {
|
||||
if (!JS_DefineFunction(cx, proto, fs->name,
|
||||
reinterpret_cast<JSNative>(fs->native),
|
||||
fs->arity, flags))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Next.
|
||||
size_t j = entry->parentInterface;
|
||||
|
|
|
@ -72,8 +72,10 @@ struct xpc_qsTraceableSpec {
|
|||
/** A table mapping interfaces to quick stubs. */
|
||||
struct xpc_qsHashEntry {
|
||||
nsID iid;
|
||||
const xpc_qsPropertySpec *properties;
|
||||
const xpc_qsFunctionSpec *functions;
|
||||
uint16_t prop_index;
|
||||
uint16_t n_props;
|
||||
uint16_t func_index;
|
||||
uint16_t n_funcs;
|
||||
// These last two fields index to other entries in the same table.
|
||||
// XPC_QS_NULL_ENTRY indicates there are no more entries in the chain.
|
||||
uint16_t parentInterface;
|
||||
|
@ -164,7 +166,9 @@ public:
|
|||
JSBool
|
||||
xpc_qsDefineQuickStubs(JSContext *cx, JSObject *proto, uintN extraFlags,
|
||||
PRUint32 ifacec, const nsIID **interfaces,
|
||||
PRUint32 tableSize, const xpc_qsHashEntry *table);
|
||||
PRUint32 tableSize, const xpc_qsHashEntry *table,
|
||||
const xpc_qsPropertySpec *propspecs,
|
||||
const xpc_qsFunctionSpec *funcspecs);
|
||||
|
||||
/** Raise an exception on @a cx and return false. */
|
||||
JSBool
|
||||
|
|
|
@ -1109,18 +1109,8 @@ def writeStubsForInterface(f, customMethodCalls, iface):
|
|||
raise TypeError('expected attribute or method, not %r'
|
||||
% member.__class__.__name__)
|
||||
|
||||
if propspecs:
|
||||
f.write("static const xpc_qsPropertySpec %s_properties[] = {\n"
|
||||
% iface.name)
|
||||
for ps in propspecs:
|
||||
f.write(" %s,\n" % ps)
|
||||
f.write(" {nsnull}};\n")
|
||||
if funcspecs:
|
||||
f.write("static const xpc_qsFunctionSpec %s_functions[] = {\n" % iface.name)
|
||||
for fs in funcspecs:
|
||||
f.write(" %s,\n" % fs)
|
||||
f.write(" {nsnull}};\n")
|
||||
f.write('\n\n')
|
||||
iface.propspecs = propspecs
|
||||
iface.funcspecs = funcspecs
|
||||
|
||||
def hashIID(iid):
|
||||
# See nsIDKey::HashCode in nsHashtable.h.
|
||||
|
@ -1153,9 +1143,32 @@ def writeResultXPCInterfacesArray(f, conf, resulttypes):
|
|||
if count > 0:
|
||||
f.write("\n\n")
|
||||
|
||||
def writeSpecs(f, elementType, varname, spec_type, spec_indices, interfaces):
|
||||
index = 0
|
||||
f.write("static const %s %s[] = {\n" % (elementType, varname))
|
||||
for iface in interfaces:
|
||||
specs = getattr(iface, spec_type)
|
||||
if specs:
|
||||
spec_indices[iface.name] = index
|
||||
f.write(" // %s (index %d)\n" % (iface.name,index))
|
||||
for s in specs:
|
||||
f.write(" %s,\n" % s)
|
||||
index += len(specs)
|
||||
f.write("};\n\n")
|
||||
|
||||
def writeDefiner(f, conf, interfaces):
|
||||
f.write("// === Definer\n\n")
|
||||
|
||||
# Write out the properties and functions
|
||||
propspecs_indices = {}
|
||||
funcspecs_indices = {}
|
||||
prop_array_name = "all_properties"
|
||||
func_array_name = "all_functions"
|
||||
writeSpecs(f, "xpc_qsPropertySpec", prop_array_name,
|
||||
"propspecs", propspecs_indices, interfaces)
|
||||
writeSpecs(f, "xpc_qsFunctionSpec", func_array_name,
|
||||
"funcspecs", funcspecs_indices, interfaces)
|
||||
|
||||
# generate the static hash table
|
||||
loadFactor = 0.6
|
||||
size = int(len(interfaces) / loadFactor)
|
||||
|
@ -1180,7 +1193,7 @@ def writeDefiner(f, conf, interfaces):
|
|||
arraySize += 1
|
||||
|
||||
entries = [" {{0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}, "
|
||||
"nsnull, nsnull, XPC_QS_NULL_INDEX, XPC_QS_NULL_INDEX}"
|
||||
"0, 0, 0, 0, XPC_QS_NULL_INDEX, XPC_QS_NULL_INDEX}"
|
||||
for i in range(arraySize)]
|
||||
for i, bucket in enumerate(buckets):
|
||||
for j, iface in enumerate(bucket):
|
||||
|
@ -1194,19 +1207,19 @@ def writeDefiner(f, conf, interfaces):
|
|||
m4[4:6], m4[6:8], m4[8:10], m4[10:12]))
|
||||
iid = ('{0x%s, 0x%s, 0x%s, %s}' % (m0, m1, m2, m3arr))
|
||||
|
||||
# properties field
|
||||
properties = "nsnull"
|
||||
for member in iface.stubMembers:
|
||||
if member.kind == 'attribute':
|
||||
properties = iface.name + "_properties"
|
||||
break
|
||||
# properties fields
|
||||
prop_index = 0
|
||||
prop_n_entries = 0
|
||||
if iface.propspecs:
|
||||
prop_index = propspecs_indices[iface.name]
|
||||
prop_n_entries = len(iface.propspecs)
|
||||
|
||||
# member field
|
||||
functions = "nsnull"
|
||||
for member in iface.stubMembers:
|
||||
if member.kind == 'method':
|
||||
functions = iface.name + "_functions"
|
||||
break
|
||||
# member fields
|
||||
func_index = 0
|
||||
func_n_entries = 0
|
||||
if iface.funcspecs:
|
||||
func_index = funcspecs_indices[iface.name]
|
||||
func_n_entries = len(iface.funcspecs)
|
||||
|
||||
# parentInterface field
|
||||
baseName = iface.base
|
||||
|
@ -1228,8 +1241,9 @@ def writeDefiner(f, conf, interfaces):
|
|||
chain = str(k)
|
||||
|
||||
# add entry
|
||||
entry = " {%s, %s, %s, %s, %s}" % (
|
||||
iid, properties, functions, parentInterface, chain)
|
||||
entry = " /* %s */ {%s, %d, %d, %d, %d, %s, %s}" % (
|
||||
iface.name, iid, prop_index, prop_n_entries,
|
||||
func_index, func_n_entries, parentInterface, chain)
|
||||
entries[entryIndexes[iface.attributes.uuid]] = entry
|
||||
|
||||
f.write("static const xpc_qsHashEntry tableData[] = {\n")
|
||||
|
@ -1245,7 +1259,8 @@ def writeDefiner(f, conf, interfaces):
|
|||
"const nsID **iids)\n"
|
||||
"{\n")
|
||||
f.write(" return xpc_qsDefineQuickStubs("
|
||||
"cx, proto, flags, count, iids, %d, tableData);\n" % size)
|
||||
"cx, proto, flags, count, iids, %d, tableData, %s, %s);\n" % (
|
||||
size, prop_array_name, func_array_name))
|
||||
f.write("}\n\n\n")
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче