Bug 134639 - speedup unix x86 XPTC_InvokeByIndex

r=dbradley, sr=jband, a=rjesup


git-svn-id: svn://10.0.0.236/trunk@118054 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bbaetz%student.usyd.edu.au 2002-04-03 23:59:13 +00:00
parent 5382ec1645
commit 835a87cec8
2 changed files with 60 additions and 28 deletions

View File

@ -42,36 +42,10 @@
extern "C" {
// Remember that these 'words' are 32bit DWORDS
static PRUint32
invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s)
{
PRUint32 result = 0;
for(PRUint32 i = 0; i < paramCount; i++, s++)
{
if(s->IsPtrData())
{
result++;
continue;
}
result++;
switch(s->type)
{
case nsXPTType::T_I64 :
case nsXPTType::T_U64 :
case nsXPTType::T_DOUBLE :
result++;
break;
}
}
return result;
}
static void
invoke_copy_to_stack(PRUint32 paramCount, nsXPTCVariant* s, PRUint32* d)
{
for(PRUint32 i = 0; i < paramCount; i++, d++, s++)
for(PRUint32 i = paramCount; i >0; i--, d++, s++)
{
if(s->IsPtrData())
{
@ -104,7 +78,10 @@ XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
{
#ifdef __GNUC__ /* Gnu compiler. */
PRUint32 result;
PRUint32 n = invoke_count_words (paramCount, params) * 4;
// Each param takes at most 2, 4-byte words
// It doesn't matter if we push too many words, and calculating the exact
// ammount takes time.
PRUint32 n = paramCount << 3;
void (*fn_copy) (unsigned int, nsXPTCVariant *, PRUint32 *) = invoke_copy_to_stack;
int temp1, temp2, temp3;

View File

@ -43,10 +43,13 @@
#include <stdio.h>
#include "xptcall.h"
#include "prlong.h"
#include "prinrval.h"
// forward declration
static void DoMultipleInheritenceTest();
static void DoMultipleInheritenceTest2();
static void DoSpeedTest();
// {AAC1FB90-E099-11d2-984E-006008962422}
#define INVOKETESTTARGET_IID \
@ -663,6 +666,8 @@ int main()
DoMultipleInheritenceTest();
DoMultipleInheritenceTest2();
// Disabled by default - takes too much time on slow machines
//DoSpeedTest();
return 0;
}
@ -1074,4 +1079,54 @@ static void DoMultipleInheritenceTest2()
NS_RELEASE(impl);
}
static void DoSpeedTest()
{
InvokeTestTarget *test = new InvokeTestTarget();
nsXPTCVariant var[3];
var[0].val.i32 = 1;
var[0].type = nsXPTType::T_I32;
var[0].flags = 0;
var[1].val.i32 = 1;
var[1].type = nsXPTType::T_I32;
var[1].flags = 0;
var[2].val.i32 = 0;
var[2].type = nsXPTType::T_I32;
var[2].flags = nsXPTCVariant::PTR_IS_DATA;
var[2].ptr = &var[2].val.i32;
PRInt32 in1 = 1;
PRInt32 in2 = 1;
PRInt32 out;
// Crank this number down if your platform is slow :)
static const int count = 100000000;
int i;
PRIntervalTime start;
PRIntervalTime interval_direct;
PRIntervalTime interval_invoke;
printf("Speed test...\n\n");
printf("Doing %d direct call iterations...\n", count);
start = PR_IntervalNow();
for(i = count; i; i--)
(void)test->AddTwoInts(in1, in2, &out);
interval_direct = PR_IntervalNow() - start;
printf("Doing %d invoked call iterations...\n", count);
start = PR_IntervalNow();
for(i = count; i; i--)
(void)XPTC_InvokeByIndex(test, 3, 3, var);
interval_invoke = PR_IntervalNow() - start;
printf(" direct took %0.2f seconds\n",
(double)interval_direct/(double)PR_TicksPerSecond());
printf(" invoke took %0.2f seconds\n",
(double)interval_invoke/(double)PR_TicksPerSecond());
printf(" So, invoke overhead was ~ %0.2f seconds (~ %0.0f%%)\n",
(double)(interval_invoke-interval_direct)/(double)PR_TicksPerSecond(),
(double)(interval_invoke-interval_direct)/(double)interval_invoke*100);
}