Bug 952777 - part 5 - move JSJitInfo::argTypes to a separate JSTypedMethodJitInfo subclass; r=efaust,bz

This commit is contained in:
Nathan Froyd 2014-01-07 16:52:40 -05:00
parent ada036e541
commit 0747cf92d2
4 changed files with 69 additions and 36 deletions

View File

@ -1587,7 +1587,9 @@ class MethodDefiner(PropertyDefiner):
selfHostedName = "nullptr";
accessor = m.get("nativeName", m["name"])
if m.get("methodInfo", True):
jitinfo = ("&%s_methodinfo" % accessor)
# Cast this in case the methodInfo is a
# JSTypedMethodJitInfo.
jitinfo = ("reinterpret_cast<const JSJitInfo*>(&%s_methodinfo)" % accessor)
if m.get("allowCrossOriginThis", False):
accessor = "genericCrossOriginMethod"
else:
@ -6348,6 +6350,23 @@ class CGMemberJITInfo(CGThing):
slotStr = toStringBool(hasSlot)
returnType = reduce(CGMemberJITInfo.getSingleReturnType, returnTypes,
"")
def jitInfoInitializer(isTypedMethod):
typedMethodStr = toStringBool(isTypedMethod)
return ("{\n"
" { %s },\n"
" %s,\n"
" %s,\n"
" JSJitInfo::%s,\n"
" %s, /* returnType. Not relevant for setters. */\n"
" %s, /* isInfallible. False in setters. */\n"
" %s, /* isMovable. Not relevant for setters. */\n"
" %s, /* isInSlot. Only relevant for getters. */\n"
" %s, /* isTypedMethod. Only relevant for methods. */\n"
" %s, /* Reserved slot index, if we're stored in a slot, else 0. */\n"
" JSJitInfo::%s /* aliasSet. Not relevant for setters. */\n"
"}" % (opName, protoID, depth, opType,
returnType, failstr, movablestr, slotStr,
typedMethodStr, slotIndex, aliasSet))
if args is not None:
argTypes = "%s_argTypes" % infoName
args = [CGMemberJITInfo.getJSArgType(arg.type) for arg in args]
@ -6355,26 +6374,17 @@ class CGMemberJITInfo(CGThing):
argTypesDecl = (
"static const JSJitInfo::ArgType %s[] = { %s };\n" %
(argTypes, ", ".join(args)))
else:
argTypes = "nullptr"
argTypesDecl = ""
return ("\n"
"%s"
"static const JSTypedMethodJitInfo %s = {\n"
" %s,\n"
" %s\n"
"};\n" % (argTypesDecl, infoName,
jitInfoInitializer(True), argTypes))
return ("\n"
"%s"
"static const JSJitInfo %s = {\n"
" { %s },\n"
" %s,\n"
" %s,\n"
" JSJitInfo::%s,\n"
" %s, /* returnType. Not relevant for setters. */\n"
" %s, /* isInfallible. False in setters. */\n"
" %s, /* isMovable. Not relevant for setters. */\n"
" %s, /* isInSlot. Only relevant for getters. */\n"
" %s, /* Reserved slot index, if we're stored in a slot, else 0. */\n"
" JSJitInfo::%s, /* aliasSet. Not relevant for setters. */\n"
" %s /* argTypes. Only relevant for methods */\n"
"};\n" % (argTypesDecl, infoName, opName, protoID, depth,
opType, returnType, failstr, movablestr, slotStr,
slotIndex, aliasSet, argTypes))
"static const JSJitInfo %s = %s;\n"
% (infoName, jitInfoInitializer(False)))
def define(self):
if self.member.isAttr():

View File

@ -675,11 +675,13 @@ MCallDOMNative::getAliasSet() const
// If we don't know anything about the types of our arguments, we have to
// assume that type-coercions can have side-effects, so we need to alias
// everything.
if (jitInfo->aliasSet != JSJitInfo::AliasDOMSets || !jitInfo->argTypes)
if (jitInfo->aliasSet != JSJitInfo::AliasDOMSets || !jitInfo->isTypedMethodJitInfo())
return AliasSet::Store(AliasSet::Any);
uint32_t argIndex = 0;
for (const JSJitInfo::ArgType *argType = jitInfo->argTypes;
const JSTypedMethodJitInfo *methodInfo =
reinterpret_cast<const JSTypedMethodJitInfo*>(jitInfo);
for (const JSJitInfo::ArgType *argType = methodInfo->argTypes;
*argType != JSJitInfo::ArgTypeListEnd;
++argType, ++argIndex)
{

View File

@ -1504,6 +1504,11 @@ struct JSJitInfo {
return type != ParallelNative;
}
bool isTypedMethodJitInfo() const
{
return isTypedMethod;
}
union {
JSJitGetterOp getter;
JSJitSetterOp setter;
@ -1526,7 +1531,9 @@ struct JSJitInfo {
throw). */
uint16_t isInSlot : 1; /* True if this is a getter that can get a member
from a slot of the "this" object directly. */
uint16_t slotIndex : 13; /* If isInSlot is true, the index of the slot to
uint16_t isTypedMethod : 1; /* True if this is an instance of
JSTypedMethodJitInfo. */
uint16_t slotIndex : 12; /* If isInSlot is true, the index of the slot to
get the value from. Otherwise 0. */
AliasSet aliasSet; /* The alias set for this op. This is a _minimal_
@ -1536,12 +1543,6 @@ struct JSJitInfo {
of the actual argument types being passed in. */
// XXXbz should we have a JSGetterJitInfo subclass or something?
// XXXbz should we have a JSValueType for the type of the member?
const ArgType* const argTypes; /* For a method, a list of sets of types that
the function expects. This can be used,
for example, to figure out when argument
coercions can have side-effects. nullptr
if we have no type information for
arguments. */
private:
static void staticAsserts()
@ -1555,6 +1556,26 @@ private:
}
};
struct JSTypedMethodJitInfo
{
// We use C-style inheritance here, rather than C++ style inheritance
// because not all compilers support brace-initialization for non-aggregate
// classes. Using C++ style inheritance and constructors instead of
// brace-initialization would also force the creation of static
// constructors (on some compilers) when JSJitInfo and JSTypedMethodJitInfo
// structures are declared. Since there can be several thousand of these
// structures present and we want to have roughly equivalent performance
// across a range of compilers, we do things manually.
JSJitInfo base;
const JSJitInfo::ArgType* const argTypes; /* For a method, a list of sets of
types that the function
expects. This can be used,
for example, to figure out
when argument coercions can
have side-effects. */
};
/*
* You may ask yourself: why do we define a wrapper around a wrapper here?
* The answer is that some compilers don't understand initializing a union
@ -1575,7 +1596,7 @@ private:
return JSParallelNativeThreadSafeWrapper<serialOp>(slice, argc, vp); \
} \
const JSJitInfo infoName = \
{{reinterpret_cast<JSJitGetterOp>(wrapperName##_ParallelNativeThreadSafeWrapper)},0,0,JSJitInfo::ParallelNative,JSVAL_TYPE_MISSING,false,false,false,0,JSJitInfo::AliasEverything,nullptr}
{{reinterpret_cast<JSJitGetterOp>(wrapperName##_ParallelNativeThreadSafeWrapper)},0,0,JSJitInfo::ParallelNative,JSVAL_TYPE_MISSING,false,false,false,false,0,JSJitInfo::AliasEverything}
static JS_ALWAYS_INLINE const JSJitInfo *
FUNCTION_VALUE_TO_JITINFO(const JS::Value& v)

View File

@ -4838,9 +4838,9 @@ static const JSJitInfo dom_x_getterinfo = {
true, /* isInfallible. False in setters. */
true, /* isMovable */
false, /* isInSlot */
false, /* isTypedMethod */
0, /* slotIndex */
JSJitInfo::AliasNone, /* aliasSet */
nullptr /* argTypes */
JSJitInfo::AliasNone /* aliasSet */
};
static const JSJitInfo dom_x_setterinfo = {
@ -4852,9 +4852,9 @@ static const JSJitInfo dom_x_setterinfo = {
false, /* isInfallible. False in setters. */
false, /* isMovable. */
false, /* isInSlot */
false, /* isTypedMethod */
0, /* slotIndex */
JSJitInfo::AliasEverything, /* aliasSet */
nullptr /* argTypes */
JSJitInfo::AliasEverything /* aliasSet */
};
static const JSJitInfo doFoo_methodinfo = {
@ -4866,9 +4866,9 @@ static const JSJitInfo doFoo_methodinfo = {
false, /* isInfallible. False in setters. */
false, /* isMovable */
false, /* isInSlot */
false, /* isTypedMethod */
0, /* slotIndex */
JSJitInfo::AliasEverything, /* aliasSet */
nullptr /* argTypes */
JSJitInfo::AliasEverything /* aliasSet */
};
static const JSPropertySpec dom_props[] = {