Added profiling for JS vector and quaternion conversion functions (debug builds only). Ensured callObjC() for void-return methods always returns undefined.

git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@3944 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
Jens Ayton 2011-01-01 12:56:21 +00:00
parent 96df45381e
commit 17557402f3
3 changed files with 130 additions and 4 deletions

View File

@ -5,7 +5,7 @@ OOJSConsole.m
Oolite Debug OXP
Copyright (C) 2007-2010 Jens Ayton
Copyright (C) 2007-2011 Jens Ayton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -697,7 +697,7 @@ static JSBool ConsoleCallObjCMethod(OOJS_NATIVE_ARGS)
}
OOJSPauseTimeLimiter();
jsval result;
jsval result = JSVAL_VOID;
BOOL OK = OOJSCallObjCObjectMethod(context, object, [object jsClassName], argc, OOJS_ARGV, &result);
OOJSResumeTimeLimiter();

View File

@ -192,6 +192,63 @@ BOOL JSValueToQuaternion(JSContext *context, jsval value, Quaternion *outQuatern
}
#if OO_DEBUG
typedef struct
{
OOUInteger quatCount;
OOUInteger entityCount;
OOUInteger arrayCount;
OOUInteger protoCount;
OOUInteger failCount;
} QuaternionStatistics;
static QuaternionStatistics sQuaternionConversionStats;
@implementation PlayerEntity (JSQuaternionStatistics)
// :setM quatStats PS.callObjC("reportJSQuaternionStatistics")
// :quatStats
- (NSString *) reportJSQuaternionStatistics
{
QuaternionStatistics *stats = &sQuaternionConversionStats;
OOUInteger sum = stats->quatCount + stats->entityCount + stats->arrayCount + stats->protoCount;
double convFac = 100.0 / sum;
return [NSString stringWithFormat:
@"quaternion-to-quaternion conversions: %lu (%g %%)\n"
" entity-to-quaternion conversions: %lu (%g %%)\n"
" array-to-quaternion conversions: %lu (%g %%)\n"
" prototype-to-zero conversions: %lu (%g %%)\n"
" failed conversions: %lu (%g %%)\n"
" total: %lu",
(long)stats->quatCount, stats->quatCount * convFac,
(long)stats->entityCount, stats->entityCount * convFac,
(long)stats->arrayCount, stats->arrayCount * convFac,
(long)stats->protoCount, stats->protoCount * convFac,
(long)stats->failCount, stats->failCount * convFac,
(long)sum];
}
- (void) clearJSQuaternionStatistics
{
memset(&sQuaternionConversionStats, 0, sizeof sQuaternionConversionStats);
}
@end
#define COUNT(FIELD) do { sQuaternionConversionStats.FIELD++; } while (0)
#else
#define COUNT(FIELD) do {} while (0)
#endif
BOOL JSObjectGetQuaternion(JSContext *context, JSObject *quaternionObj, Quaternion *outQuaternion)
{
OOJS_PROFILE_ENTER
@ -209,6 +266,7 @@ BOOL JSObjectGetQuaternion(JSContext *context, JSObject *quaternionObj, Quaterni
private = JS_GetInstancePrivate(context, quaternionObj, &sQuaternionClass, NULL);
if (private != NULL) // If this is a (JS) Quaternion...
{
COUNT(quatCount);
*outQuaternion = *private;
return YES;
}
@ -216,6 +274,7 @@ BOOL JSObjectGetQuaternion(JSContext *context, JSObject *quaternionObj, Quaterni
// If it's an entity, use its orientation.
if (OOJSIsMemberOfSubclass(context, quaternionObj, JSEntityClass()))
{
COUNT(entityCount);
Entity *entity = JS_GetPrivate(context, quaternionObj);
*outQuaternion = [entity orientation];
return YES;
@ -241,6 +300,8 @@ BOOL JSObjectGetQuaternion(JSContext *context, JSObject *quaternionObj, Quaterni
outQuaternion->y = dVal;
if (!JS_ValueToNumber(context, arrayZ, &dVal)) return NO;
outQuaternion->z = dVal;
COUNT(arrayCount);
return YES;
}
}
@ -251,14 +312,16 @@ BOOL JSObjectGetQuaternion(JSContext *context, JSObject *quaternionObj, Quaterni
Quaternion.prototype)...
NOTE: it would be prettier to do this at the top when we handle normal
Vector3Ds, but it's a rare case which should be kept off the fast path.
Quaternions, but it's a rare case which should be kept off the fast path.
*/
if (JS_InstanceOf(context, quaternionObj, &sQuaternionClass, NULL))
{
COUNT(protoCount);
*outQuaternion = kZeroQuaternion;
return YES;
}
COUNT(failCount);
return NO;
OOJS_PROFILE_EXIT
@ -491,7 +554,7 @@ static JSBool QuaternionConstruct(OOJS_NATIVE_ARGS)
free(private);
OOReportJSBadArguments(context, NULL, NULL, argc, OOJS_ARGV,
@"Could not construct quaternion from parameters",
@"Vector, Entity or array of four numbers");
@"Quaternion, Entity or array of four numbers");
return NO;
}
}

View File

@ -214,6 +214,64 @@ BOOL JSValueToVector(JSContext *context, jsval value, Vector *outVector)
}
#if OO_DEBUG
typedef struct
{
OOUInteger vectorCount;
OOUInteger entityCount;
OOUInteger arrayCount;
OOUInteger protoCount;
OOUInteger failCount;
} VectorStatistics;
static VectorStatistics sVectorConversionStats;
@implementation PlayerEntity (JSVectorStatistics)
// :setM vectorStats PS.callObjC("reportJSVectorStatistics")
// :vectorStats
- (NSString *) reportJSVectorStatistics
{
VectorStatistics *stats = &sVectorConversionStats;
OOUInteger sum = stats->vectorCount + stats->entityCount + stats->arrayCount + stats->protoCount;
double convFac = 100.0 / sum;
if (sum == 0) convFac = 0;
return [NSString stringWithFormat:
@" vector-to-vector conversions: %lu (%g %%)\n"
" entity-to-vector conversions: %lu (%g %%)\n"
" array-to-vector conversions: %lu (%g %%)\n"
"prototype-to-zero conversions: %lu (%g %%)\n"
" failed conversions: %lu (%g %%)\n"
" total: %lu",
(long)stats->vectorCount, stats->vectorCount * convFac,
(long)stats->entityCount, stats->entityCount * convFac,
(long)stats->arrayCount, stats->arrayCount * convFac,
(long)stats->protoCount, stats->protoCount * convFac,
(long)stats->failCount, stats->failCount * convFac,
(long)sum];
}
- (void) clearJSVectorStatistics
{
memset(&sVectorConversionStats, 0, sizeof sVectorConversionStats);
}
@end
#define COUNT(FIELD) do { sVectorConversionStats.FIELD++; } while (0)
#else
#define COUNT(FIELD) do {} while (0)
#endif
BOOL JSObjectGetVector(JSContext *context, JSObject *vectorObj, Vector *outVector)
{
OOJS_PROFILE_ENTER
@ -232,6 +290,7 @@ BOOL JSObjectGetVector(JSContext *context, JSObject *vectorObj, Vector *outVecto
private = JS_GetInstancePrivate(context, vectorObj, &sVectorClass, NULL);
if (private != NULL)
{
COUNT(vectorCount);
*outVector = *private;
return YES;
}
@ -239,6 +298,7 @@ BOOL JSObjectGetVector(JSContext *context, JSObject *vectorObj, Vector *outVecto
// If it's an entity, use its position.
if (OOJSIsMemberOfSubclass(context, vectorObj, JSEntityClass()))
{
COUNT(entityCount);
Entity *entity = JS_GetPrivate(context, vectorObj);
*outVector = [entity position];
return YES;
@ -259,6 +319,7 @@ BOOL JSObjectGetVector(JSContext *context, JSObject *vectorObj, Vector *outVecto
JS_ValueToNumber(context, arrayY, &y) &&
JS_ValueToNumber(context, arrayZ, &z))
{
COUNT(arrayCount);
*outVector = make_vector(x, y, z);
return YES;
}
@ -275,10 +336,12 @@ BOOL JSObjectGetVector(JSContext *context, JSObject *vectorObj, Vector *outVecto
*/
if (JS_InstanceOf(context, vectorObj, &sVectorClass, NULL))
{
COUNT(protoCount);
*outVector = kZeroVector;
return YES;
}
COUNT(failCount);
return NO;
OOJS_PROFILE_EXIT