Workaround brokenness of __builtin_frame_address(0) on gcc 4.1 (as shipped with FC5, at least). b=331436 r=brendan

This commit is contained in:
dbaron%dbaron.org 2006-03-23 23:21:27 +00:00
Родитель 762f2755bd
Коммит ace148d610
5 изменённых файлов: 74 добавлений и 26 удалений

Просмотреть файл

@ -2442,7 +2442,16 @@ struct stack_frame {
static stack_frame* getStackFrame()
{
stack_frame* currentFrame;
#if defined(__i386)
__asm__( "movl %%ebp, %0" : "=g"(currentFrame));
#elif defined(__x86_64__)
__asm__( "movq %%rbp, %0" : "=g"(currentFrame));
#else
// It would be nice if this worked uniformly, but at least on i386 and
// x86_64, it stopped working with gcc 4.1, because it points to the
// end of the saved registers instead of the start.
currentFrame = (stack_frame*)__builtin_frame_address(0);
#endif
currentFrame = currentFrame->next;
return currentFrame;
}

Просмотреть файл

@ -73,9 +73,9 @@ JS_PUBLIC_API(void) JS_Assert(const char *s, const char *file, JSIntn ln)
JSCallsite js_calltree_root = {0, NULL, NULL, 0, NULL, NULL, NULL, NULL};
static JSCallsite *
CallTree(uint32 *bp)
CallTree(void **bp)
{
uint32 *bpup, *bpdown, pc;
void **bpup, **bpdown, *pc;
JSCallsite *parent, *site, **csp;
Dl_info info;
int ok, offset;
@ -85,9 +85,9 @@ CallTree(uint32 *bp)
/* Reverse the stack frame list to avoid recursion. */
bpup = NULL;
for (;;) {
bpdown = (uint32*) bp[0];
bp[0] = (uint32) bpup;
if ((uint32*) bpdown[0] < bpdown)
bpdown = (void**) bp[0];
bp[0] = (void*) bpup;
if ((void**) bpdown[0] < bpdown)
break;
bpup = bp;
bp = bpdown;
@ -96,8 +96,8 @@ CallTree(uint32 *bp)
/* Reverse the stack again, finding and building a path in the tree. */
parent = &js_calltree_root;
do {
bpup = (uint32*) bp[0];
bp[0] = (uint32) bpdown;
bpup = (void**) bp[0];
bp[0] = (void*) bpdown;
pc = bp[1];
csp = &parent->kids;
@ -125,7 +125,7 @@ CallTree(uint32 *bp)
* XXX static syms are masked by nearest lower global
*/
info.dli_fname = info.dli_sname = NULL;
ok = dladdr((void*) pc, &info);
ok = dladdr(pc, &info);
if (ok < 0) {
fprintf(stderr, "dladdr failed!\n");
return NULL;
@ -169,12 +169,21 @@ CallTree(uint32 *bp)
JSCallsite *
JS_Backtrace(int skip)
{
uint32 *bp, *bpdown;
void **bp, **bpdown;
/* Stack walking code adapted from Kipp's "leaky". */
bp = (uint32*) __builtin_frame_address(0);
#if defined(__i386)
__asm__( "movl %%ebp, %0" : "=g"(bp));
#elif defined(__x86_64__)
__asm__( "movq %%rbp, %0" : "=g"(bp));
#else
// It would be nice if this worked uniformly, but at least on i386 and
// x86_64, it stopped working with gcc 4.1, because it points to the
// end of the saved registers instead of the start.
bp = (void**) __builtin_frame_address(0);
#endif
while (--skip >= 0) {
bpdown = (uint32*) *bp++;
bpdown = (void**) *bp++;
if (bpdown < bp)
break;
bp = bpdown;

Просмотреть файл

@ -93,7 +93,7 @@ static int enableRTCSignals(bool enable);
#if defined(i386) || defined(_i386)
static void CrawlStack(malloc_log_entry* me, void* frame_ptr, char* first)
{
u_long* bp = (u_long*)frame_ptr;
void** bp = (void**)frame_ptr;
u_long numpcs = 0;
#ifdef JPROF_PTHREAD_HACK
@ -106,8 +106,8 @@ static void CrawlStack(malloc_log_entry* me, void* frame_ptr, char* first)
int skip = 2;
#endif
while (numpcs < MAX_STACK_CRAWL) {
u_long* nextbp = (u_long*) *bp++;
u_long pc = *bp;
void** nextbp = (void**) *bp++;
void* pc = *bp;
#ifdef JPROF_PTHREAD_HACK
if ((pc < 0x08000000) || ((pc > 0x7fffffff) && (skip <= 0)) || (nextbp < bp)) {
#else
@ -180,7 +180,18 @@ Log(u_long aTime, char *first)
me.delTime = aTime;
CrawlStack(&me, __builtin_frame_address(0), first);
void *bp;
#if defined(__i386)
__asm__( "movl %%ebp, %0" : "=g"(bp));
#elif defined(__x86_64__)
__asm__( "movq %%rbp, %0" : "=g"(bp));
#else
// It would be nice if this worked uniformly, but at least on i386 and
// x86_64, it stopped working with gcc 4.1, because it points to the
// end of the saved registers instead of the start.
bp = __builtin_frame_address(0);
#endif
CrawlStack(&me, bp, first);
#ifndef NTO
write(gLogFD, &me, offsetof(malloc_log_entry, pcs) + me.numpcs*sizeof(char*));

Просмотреть файл

@ -1005,10 +1005,10 @@ static callsite *calltree(int skip)
#else /*XP_UNIX*/
static callsite *calltree(uint32 *bp)
static callsite *calltree(void **bp)
{
logfile *fp = logfp;
uint32 *bpup, *bpdown, pc;
void **bpup, **bpdown, *pc;
uint32 depth, nkids;
callsite *parent, *site, **csp, *tmp;
Dl_info info;
@ -1026,9 +1026,9 @@ static callsite *calltree(uint32 *bp)
/* Reverse the stack frame list to avoid recursion. */
bpup = NULL;
for (depth = 0; ; depth++) {
bpdown = (uint32*) bp[0];
bp[0] = (uint32) bpup;
if ((uint32*) bpdown[0] < bpdown)
bpdown = (void**) bp[0];
bp[0] = (void*) bpup;
if ((void**) bpdown[0] < bpdown)
break;
bpup = bp;
bp = bpdown;
@ -1040,8 +1040,8 @@ static callsite *calltree(uint32 *bp)
/* Reverse the stack again, finding and building a path in the tree. */
parent = &calltree_root;
do {
bpup = (uint32*) bp[0];
bp[0] = (uint32) bpdown;
bpup = (void**) bp[0];
bp[0] = (void*) bpdown;
pc = bp[1];
csp = &parent->kids;
@ -1338,7 +1338,7 @@ backtrace(int skip)
callsite *
backtrace(int skip)
{
uint32 *bp, *bpdown;
void **bp, **bpdown;
callsite *site, **key;
PLHashNumber hash;
PLHashEntry **hep, *he;
@ -1348,9 +1348,18 @@ backtrace(int skip)
suppress_tracing++;
/* Stack walking code adapted from Kipp's "leaky". */
bp = (uint32*) __builtin_frame_address(0);
#if defined(__i386)
__asm__( "movl %%ebp, %0" : "=g"(bp));
#elif defined(__x86_64__)
__asm__( "movq %%rbp, %0" : "=g"(bp));
#else
// It would be nice if this worked uniformly, but at least on i386 and
// x86_64, it stopped working with gcc 4.1, because it points to the
// end of the saved registers instead of the start.
bp = (void**) __builtin_frame_address(0);
#endif
while (--skip >= 0) {
bpdown = (uint32*) *bp++;
bpdown = (void**) *bp++;
if (bpdown < bp)
break;
bp = bpdown;

Просмотреть файл

@ -91,7 +91,17 @@ void DumpStackToFile(FILE* aStream)
// Stack walking code courtesy Kipp's "leaky".
// Get the frame pointer
void **bp = (void**) __builtin_frame_address(0);
void **bp;
#if defined(__i386)
__asm__( "movl %%ebp, %0" : "=g"(bp));
#elif defined(__x86_64__)
__asm__( "movq %%rbp, %0" : "=g"(bp));
#else
// It would be nice if this worked uniformly, but at least on i386 and
// x86_64, it stopped working with gcc 4.1, because it points to the
// end of the saved registers instead of the start.
bp = (void**) __builtin_frame_address(0);
#endif
int skip = 2;
for ( ; (void**)*bp > bp; bp = (void**)*bp) {