Revision ea041c0e exec.c
b/exec.c | ||
---|---|---|
26 | 26 |
#include <inttypes.h> |
27 | 27 |
#include <sys/mman.h> |
28 | 28 |
|
29 |
#include "config.h" |
|
30 |
#ifdef TARGET_I386 |
|
29 | 31 |
#include "cpu-i386.h" |
32 |
#endif |
|
33 |
#ifdef TARGET_ARM |
|
34 |
#include "cpu-arm.h" |
|
35 |
#endif |
|
30 | 36 |
#include "exec.h" |
31 | 37 |
|
32 | 38 |
//#define DEBUG_TB_INVALIDATE |
... | ... | |
564 | 570 |
return &tbs[m_max]; |
565 | 571 |
} |
566 | 572 |
|
573 |
static void tb_reset_jump_recursive(TranslationBlock *tb); |
|
574 |
|
|
575 |
static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n) |
|
576 |
{ |
|
577 |
TranslationBlock *tb1, *tb_next, **ptb; |
|
578 |
unsigned int n1; |
|
579 |
|
|
580 |
tb1 = tb->jmp_next[n]; |
|
581 |
if (tb1 != NULL) { |
|
582 |
/* find head of list */ |
|
583 |
for(;;) { |
|
584 |
n1 = (long)tb1 & 3; |
|
585 |
tb1 = (TranslationBlock *)((long)tb1 & ~3); |
|
586 |
if (n1 == 2) |
|
587 |
break; |
|
588 |
tb1 = tb1->jmp_next[n1]; |
|
589 |
} |
|
590 |
/* we are now sure now that tb jumps to tb1 */ |
|
591 |
tb_next = tb1; |
|
592 |
|
|
593 |
/* remove tb from the jmp_first list */ |
|
594 |
ptb = &tb_next->jmp_first; |
|
595 |
for(;;) { |
|
596 |
tb1 = *ptb; |
|
597 |
n1 = (long)tb1 & 3; |
|
598 |
tb1 = (TranslationBlock *)((long)tb1 & ~3); |
|
599 |
if (n1 == n && tb1 == tb) |
|
600 |
break; |
|
601 |
ptb = &tb1->jmp_next[n1]; |
|
602 |
} |
|
603 |
*ptb = tb->jmp_next[n]; |
|
604 |
tb->jmp_next[n] = NULL; |
|
605 |
|
|
606 |
/* suppress the jump to next tb in generated code */ |
|
607 |
tb_reset_jump(tb, n); |
|
608 |
|
|
609 |
/* suppress jumps in the tb on which we could have jump */ |
|
610 |
tb_reset_jump_recursive(tb_next); |
|
611 |
} |
|
612 |
} |
|
613 |
|
|
614 |
static void tb_reset_jump_recursive(TranslationBlock *tb) |
|
615 |
{ |
|
616 |
tb_reset_jump_recursive2(tb, 0); |
|
617 |
tb_reset_jump_recursive2(tb, 1); |
|
618 |
} |
|
619 |
|
|
620 |
void cpu_interrupt(CPUState *env) |
|
621 |
{ |
|
622 |
TranslationBlock *tb; |
|
623 |
|
|
624 |
env->interrupt_request = 1; |
|
625 |
/* if the cpu is currently executing code, we must unlink it and |
|
626 |
all the potentially executing TB */ |
|
627 |
tb = env->current_tb; |
|
628 |
if (tb) { |
|
629 |
tb_reset_jump_recursive(tb); |
|
630 |
} |
|
631 |
} |
|
632 |
|
|
633 |
|
|
567 | 634 |
void cpu_abort(CPUState *env, const char *fmt, ...) |
568 | 635 |
{ |
569 | 636 |
va_list ap; |
Also available in: Unified diff