@@ -53,12 +53,12 @@ void ppc64_flush_code_generator_state()
if(ppc64_codegen_state & PPC_CODEGEN_SP_NEEDSSTORE) {
/* stw pike_sp,stack_pointer(pike_interpreter) */
STD(PPC_REG_PIKE_SP, PPC_REG_PIKE_INTERP,
OFFSETOF(Pike_interpreter, stack_pointer));
OFFSETOF(Pike_interpreter_struct, stack_pointer));
}
if(ppc64_codegen_state & PPC_CODEGEN_MARK_SP_NEEDSSTORE) {
/* stw pike_mark_sp,mark_stack_pointer(pike_interpreter) */
STD(PPC_REG_PIKE_MARK_SP, PPC_REG_PIKE_INTERP,
OFFSETOF(Pike_interpreter, mark_stack_pointer));
OFFSETOF(Pike_interpreter_struct, mark_stack_pointer));
}
ppc64_codegen_state = 0;
last_prog_id=-1;
@@ -252,7 +252,7 @@ void ppc64_push_global(INT32 arg)
} else {
/* ld r3,stack_pointer(pike_interpreter) */
LD(PPC_REG_ARG1, PPC_REG_PIKE_INTERP,
OFFSETOF(Pike_interpreter, stack_pointer));
OFFSETOF(Pike_interpreter_struct, stack_pointer));
}
if(arg) {
/* addi r5,r5,arg */
@@ -358,13 +358,13 @@ static void ppc64_escape_catch(void)
LOAD_FP_REG();
/* ld r3,catch_ctx(pike_interpreter) */
LD(PPC_REG_ARG1, PPC_REG_PIKE_INTERP,
OFFSETOF(Pike_interpreter, catch_ctx));
OFFSETOF(Pike_interpreter_struct, catch_ctx));
/* ld r4,recovery.previous(r3) */
LD(PPC_REG_ARG2, PPC_REG_ARG1,
OFFSETOF(catch_context, recovery.previous));
/* std r4,recoveries(pike_interpreter) */
STD(PPC_REG_ARG2, PPC_REG_PIKE_INTERP,
OFFSETOF(Pike_interpreter, recoveries));
OFFSETOF(Pike_interpreter_struct, recoveries));
/* ld r4,save_expendible(r3) */
LD(PPC_REG_ARG2, PPC_REG_ARG1,
OFFSETOF(catch_context, save_expendible));
@@ -376,7 +376,7 @@ static void ppc64_escape_catch(void)
OFFSETOF(catch_context, prev));
/* std r4,catch_ctx(pike_interpreter) */
STD(PPC_REG_ARG2, PPC_REG_PIKE_INTERP,
OFFSETOF(Pike_interpreter, catch_ctx));
OFFSETOF(Pike_interpreter_struct, catch_ctx));

FLUSH_CODE_GENERATOR_STATE();
ADD_CALL(really_free_catch_context);
@@ -118,29 +118,29 @@ void ppc64_flush_code_generator_state(void);
#define PPC_CODEGEN_MARK_SP_NEEDSSTORE 16
#define PPC_CODEGEN_PC_ISSET 32

#define LOAD_FP_REG() do { \
if(!(ppc64_codegen_state & PPC_CODEGEN_FP_ISSET)) { \
/* ld pike_fp,frame_pointer(pike_interpreter) */ \
LD(PPC_REG_PIKE_FP, PPC_REG_PIKE_INTERP, \
OFFSETOF(Pike_interpreter, frame_pointer)); \
ppc64_codegen_state |= PPC_CODEGEN_FP_ISSET; \
} \
#define LOAD_FP_REG() do { \
if(!(ppc64_codegen_state & PPC_CODEGEN_FP_ISSET)) { \
/* ld pike_fp,frame_pointer(pike_interpreter) */ \
LD(PPC_REG_PIKE_FP, PPC_REG_PIKE_INTERP, \
OFFSETOF(Pike_interpreter_struct, frame_pointer)); \
ppc64_codegen_state |= PPC_CODEGEN_FP_ISSET; \
} \
} while(0)

#define LOAD_SP_REG() do { \
if(!(ppc64_codegen_state & PPC_CODEGEN_SP_ISSET)) { \
/* ld pike_sp,stack_pointer(pike_interpreter) */ \
LD(PPC_REG_PIKE_SP, PPC_REG_PIKE_INTERP, \
OFFSETOF(Pike_interpreter, stack_pointer)); \
ppc64_codegen_state |= PPC_CODEGEN_SP_ISSET; \
} \
#define LOAD_SP_REG() do { \
if(!(ppc64_codegen_state & PPC_CODEGEN_SP_ISSET)) { \
/* ld pike_sp,stack_pointer(pike_interpreter) */ \
LD(PPC_REG_PIKE_SP, PPC_REG_PIKE_INTERP, \
OFFSETOF(Pike_interpreter_struct, stack_pointer)); \
ppc64_codegen_state |= PPC_CODEGEN_SP_ISSET; \
} \
} while(0)

#define LOAD_MARK_SP_REG() do { \
if(!(ppc64_codegen_state & PPC_CODEGEN_MARK_SP_ISSET)) { \
/* ld pike_mark_sp,mark_stack_pointer(pike_interpreter) */ \
LD(PPC_REG_PIKE_MARK_SP, PPC_REG_PIKE_INTERP, \
OFFSETOF(Pike_interpreter, mark_stack_pointer)); \
OFFSETOF(Pike_interpreter_struct, mark_stack_pointer)); \
ppc64_codegen_state |= PPC_CODEGEN_MARK_SP_ISSET; \
} \
} while(0)
@@ -268,7 +268,7 @@ void ppc64_decode_program(struct program *p);
" mr "PPC_REGNAME(29)",%1\n" \
" bctr" \
: \
: "r" (pc), "r" (&Pike_interpreter) \
: "r" (pc), "r" (Pike_interpreter_pointer) \
: "ctr", "lr", "cc", "memory", "r29", "r0", "r2", \
"r3", "r4", "r5", "r6", "r7", "r8", "r9", \
"r10", "r11", "r12")
@@ -235,7 +235,7 @@
* I6 Frame pointer
* I7 Return address
*
* L0 &Pike_interpreter
* L0 Pike_interpreter_pointer
* L1 Pike_fp
* L7 &d_flag
*
@@ -271,7 +271,8 @@ ptrdiff_t sparc_last_pc = 0;
#define LOAD_PIKE_INTERPRETER() do { \
if (!(sparc_codegen_state & SPARC_CODEGEN_IP_IS_SET)) { \
SET_REG(SPARC_REG_PIKE_IP, \
((ptrdiff_t)(&Pike_interpreter))); \
((ptrdiff_t)(&Pike_interpreter_pointer))); \
PIKE_LDPTR(SPARC_REG_PIKE_IP, SPARC_REG_PIKE_IP, 0, 1); \
sparc_codegen_state |= SPARC_CODEGEN_IP_IS_SET; \
} \
} while(0)
@@ -281,7 +282,7 @@ ptrdiff_t sparc_last_pc = 0;
LOAD_PIKE_INTERPRETER(); \
/* lduw [ %ip, %offset(Pike_interpreter, frame_pointer) ], %l1 */ \
PIKE_LDPTR(SPARC_REG_PIKE_FP, SPARC_REG_PIKE_IP, \
OFFSETOF(Pike_interpreter, frame_pointer), 1); \
OFFSETOF(Pike_interpreter_struct, frame_pointer), 1); \
sparc_codegen_state |= SPARC_CODEGEN_FP_IS_SET; \
} \
} while(0)
@@ -291,7 +292,7 @@ ptrdiff_t sparc_last_pc = 0;
LOAD_PIKE_INTERPRETER(); \
/* lduw [ %ip, %offset(Pike_interpreter, stack_pointer) ], %l2 */ \
PIKE_LDPTR(SPARC_REG_PIKE_SP, SPARC_REG_PIKE_IP, \
OFFSETOF(Pike_interpreter, stack_pointer), 1); \
OFFSETOF(Pike_interpreter_struct, stack_pointer), 1); \
sparc_codegen_state |= SPARC_CODEGEN_SP_IS_SET; \
sparc_pike_sp_bias = 0; \
} else if (sparc_pike_sp_bias > 0xf00) { \
@@ -308,7 +309,7 @@ ptrdiff_t sparc_last_pc = 0;
LOAD_PIKE_INTERPRETER(); \
/* lduw [ %ip, %offset(Pike_interpreter, mark_stack_pointer) ], %l2 */ \
PIKE_LDPTR(SPARC_REG_PIKE_MARK_SP, SPARC_REG_PIKE_IP, \
OFFSETOF(Pike_interpreter, mark_stack_pointer), 1); \
OFFSETOF(Pike_interpreter_struct, mark_stack_pointer), 1); \
sparc_codegen_state |= SPARC_CODEGEN_MARK_SP_IS_SET; \
} \
} while(0)
@@ -323,13 +324,13 @@ ptrdiff_t sparc_last_pc = 0;
if (sparc_codegen_state & SPARC_CODEGEN_MARK_SP_NEEDS_STORE) { \
/* stw %pike_mark_sp, [ %ip, %offset(Pike_interpreter, mark_stack_pointer) ] */ \
PIKE_STPTR(SPARC_REG_PIKE_MARK_SP, SPARC_REG_PIKE_IP, \
OFFSETOF(Pike_interpreter, mark_stack_pointer), 1); \
OFFSETOF(Pike_interpreter_struct, mark_stack_pointer), 1); \
sparc_codegen_state &= ~SPARC_CODEGEN_MARK_SP_NEEDS_STORE; \
} \
if (sparc_codegen_state & SPARC_CODEGEN_SP_NEEDS_STORE) { \
/* stw %pike_sp, [ %ip, %offset(Pike_interpreter, stack_pointer) ] */ \
PIKE_STPTR(SPARC_REG_PIKE_SP, SPARC_REG_PIKE_IP, \
OFFSETOF(Pike_interpreter, stack_pointer), 1); \
OFFSETOF(Pike_interpreter_struct, stack_pointer), 1); \
sparc_codegen_state &= ~SPARC_CODEGEN_SP_NEEDS_STORE; \
} \
} while(0)
@@ -574,13 +575,13 @@ void sparc_local_lvalue(unsigned int no)

#ifdef PIKE_DEBUG
void sparc_debug_check_registers(int state,
struct Pike_interpreter *cached_ip,
struct Pike_interpreter_struct *cached_ip,
struct pike_frame *cached_fp,
struct svalue *cached_sp,
struct svalue **cached_mark_sp)
{
if (((state & SPARC_CODEGEN_IP_IS_SET) &&
(cached_ip != &Pike_interpreter)) ||
(cached_ip != Pike_interpreter_pointer)) ||
((state & SPARC_CODEGEN_FP_IS_SET) &&
(cached_fp != Pike_interpreter.frame_pointer)) ||
((state & SPARC_CODEGEN_SP_IS_SET) &&
@@ -593,7 +594,8 @@ void sparc_debug_check_registers(int state,
state,
(INT32)cached_ip, (INT32)cached_fp,
(INT32)cached_sp, (INT32)cached_mark_sp,
(INT32)&Pike_interpreter, (INT32)Pike_interpreter.frame_pointer,
(INT32)Pike_interpreter_pointer,
(INT32)Pike_interpreter.frame_pointer,
(INT32)Pike_interpreter.stack_pointer,
(INT32)Pike_interpreter.mark_stack_pointer);
}
@@ -110,10 +110,16 @@ PMOD_EXPORT unsigned long evaluator_callback_calls = 0;

int fast_check_threads_counter = 0;

/* This is used for strapping the interpreter before the threads
* are loaded, and when there's no support for threads.
*/
static struct Pike_interpreter_struct static_pike_interpreter;

/* Pike_sp points to first unused value on stack
* (much simpler than letting it point at the last used value.)
*/
PMOD_EXPORT struct Pike_interpreter Pike_interpreter;
PMOD_EXPORT struct Pike_interpreter_struct *Pike_interpreter_pointer =
&static_pike_interpreter;
PMOD_EXPORT int Pike_stack_size = EVALUATOR_STACK_SIZE;

static void do_trace_call(INT32 args, dynamic_buffer *old_buf);
@@ -192,7 +198,7 @@ static void gc_check_stack_callback(struct callback *foo, void *bar, void *gazon
*/
static int eval_instruction(PIKE_OPCODE_T *pc);

PMOD_EXPORT int low_init_interpreter(struct Pike_interpreter *interpreter)
PMOD_EXPORT int low_init_interpreter(struct Pike_interpreter_struct *interpreter)
{
#ifdef USE_MMAP_FOR_STACK
static int fd = -1;
@@ -291,7 +297,7 @@ PMOD_EXPORT int low_init_interpreter(struct Pike_interpreter *interpreter)

PMOD_EXPORT void init_interpreter(void)
{
if (low_init_interpreter(&Pike_interpreter)) {
if (low_init_interpreter(Pike_interpreter_pointer)) {
Pike_fatal("Out of memory initializing the interpreter stack.\n");
}

@@ -3035,10 +3041,7 @@ void gdb_backtrace (
fputs ("Not a Pike thread.\n", stderr);
return;
}
if (ts->swapped)
f = ts->state.frame_pointer;
else
f = Pike_fp;
f = ts->state.frame_pointer;
#else
f = Pike_fp;
#endif
@@ -3245,7 +3248,7 @@ PMOD_EXPORT void custom_check_stack(ptrdiff_t amount, const char *fmt, ...)
}
}

PMOD_EXPORT void low_cleanup_interpret(struct Pike_interpreter *interpreter)
PMOD_EXPORT void low_cleanup_interpret(struct Pike_interpreter_struct *interpreter)
{
#ifdef USE_MMAP_FOR_STACK
if(!interpreter->evaluator_stack_malloced)
@@ -26,7 +26,7 @@ struct catch_context
#endif
};

struct Pike_interpreter {
struct Pike_interpreter_struct {
/* Swapped variables */
struct svalue *stack_pointer;
struct svalue *evaluator_stack;
@@ -757,7 +757,7 @@ void push_sp_mark(void);
ptrdiff_t pop_sp_mark(void);
void gc_mark_stack_external (struct pike_frame *frame,
struct svalue *stack_p, struct svalue *stack);
PMOD_EXPORT int low_init_interpreter(struct Pike_interpreter *interpreter);
PMOD_EXPORT int low_init_interpreter(struct Pike_interpreter_struct *interpreter);
PMOD_EXPORT void init_interpreter(void);
void lvalue_to_svalue_no_free(struct svalue *to,struct svalue *lval);
PMOD_EXPORT void assign_lvalue(struct svalue *lval,struct svalue *from);
@@ -826,7 +826,7 @@ void slow_check_stack(void);
PMOD_EXPORT void custom_check_stack(ptrdiff_t amount, const char *fmt, ...)
ATTRIBUTE((format (printf, 2, 3)));
PMOD_EXPORT void cleanup_interpret(void);
PMOD_EXPORT void low_cleanup_interpret(struct Pike_interpreter *interpreter);
PMOD_EXPORT void low_cleanup_interpret(struct Pike_interpreter_struct *interpreter);
void really_clean_up_interpret(void);
/* Prototypes end here */

@@ -883,7 +883,8 @@ PMOD_EXPORT extern struct callback_list evaluator_callbacks;
* The above define could also be used to facilitate dynamic loading
* on Win32..
*/
PMOD_EXPORT extern struct Pike_interpreter Pike_interpreter;
PMOD_EXPORT extern struct Pike_interpreter_struct *Pike_interpreter_pointer;
#define Pike_interpreter (*Pike_interpreter_pointer)

#define Pike_sp Pike_interpreter.stack_pointer
#define Pike_fp Pike_interpreter.frame_pointer
@@ -547,7 +547,7 @@ PMOD_EXPORT void debug_list_all_threads(void);
#endif

#define HIDE_GLOBAL_VARIABLES() do { \
int Pike_interpreter =0; \
int Pike_interpreter_pointer =0; \
int pop_n_elems = 0; \
int push_sp_mark = 0, pop_sp_mark = 0, threads_disabled = 1; \
HIDE_PC; \
@@ -540,8 +540,13 @@ PMOD_EXPORT INLINE int pike_timedwait_interpreter (COND_T *cond,

PMOD_EXPORT void pike_init_thread_state (struct thread_state *ts)
{
/* NB: Assumes that there's a temporary Pike_interpreter_struct
* in Pike_interpreter_pointer, which we copy, and replace
* with ourselves.
*/
Pike_interpreter.thread_state = ts;
ts->state = Pike_interpreter;
Pike_interpreter_pointer = &ts->state;
ts->id = th_self();
ts->status = THREAD_RUNNING;
ts->swapped = 0;
@@ -572,8 +577,6 @@ PMOD_EXPORT void pike_swap_out_thread (struct thread_state *ts
ts
COMMA_DLOC_ARGS_OPT));

ts->state = Pike_interpreter;

#ifdef PROFILING
if (!ts->swapped) {
cpu_time_t now = get_cpu_time();
@@ -588,14 +591,7 @@ PMOD_EXPORT void pike_swap_out_thread (struct thread_state *ts

ts->swapped=1;

#ifdef PIKE_DEBUG
Pike_sp = (struct svalue *) (ptrdiff_t) -1;
Pike_fp = (struct pike_frame *) (ptrdiff_t) -1;
#endif

/* Do this one always to catch nested THREADS_ALLOW(), etc. */
Pike_interpreter.thread_state =
(struct thread_state *) (ptrdiff_t) -1;
Pike_interpreter_pointer = NULL;
}

PMOD_EXPORT void pike_swap_in_thread (struct thread_state *ts
@@ -605,7 +601,7 @@ PMOD_EXPORT void pike_swap_in_thread (struct thread_state *ts
ts COMMA_DLOC_ARGS_OPT));

#ifdef PIKE_DEBUG
if (Pike_sp != (struct svalue *) (ptrdiff_t) -1)
if (Pike_interpreter_pointer)
pike_fatal_dloc ("Thread %"PRINTSIZET"x swapped in "
"over existing thread %"PRINTSIZET"x.\n",
(size_t) ts->id,
@@ -633,7 +629,7 @@ PMOD_EXPORT void pike_swap_in_thread (struct thread_state *ts
#endif

ts->swapped=0;
Pike_interpreter=ts->state;
Pike_interpreter_pointer = &ts->state;
#ifdef PIKE_DEBUG
thread_swaps++;
#endif
@@ -1183,8 +1179,10 @@ PMOD_EXPORT void call_with_interpreter(void (*func)(void *ctx), void *ctx)
} else {
/* Not a pike thread. Create a temporary thread_id... */
struct object *thread_obj;
struct Pike_interpreter_struct new_interpreter;

mt_lock_interpreter();
Pike_interpreter_pointer = &new_interpreter;
init_interpreter();
Pike_interpreter.stack_top=((char *)&state)+ (thread_stack_size-16384) * STACK_DIRECTION;
Pike_interpreter.recoveries = NULL;
@@ -1725,7 +1723,7 @@ TH_RETURN_TYPE new_thread_func(void *data)
#endif

arg.thread_state->swapped = 0;
Pike_interpreter = arg.thread_state->state;
Pike_interpreter_pointer = &arg.thread_state->state;

#ifdef PROFILING
Pike_interpreter.stack_bottom=((char *)&data);
@@ -1811,6 +1809,7 @@ TH_RETURN_TYPE new_thread_func(void *data)
thread_table_delete(thread_state);
EXIT_THREAD_STATE(thread_state);
Pike_interpreter.thread_state = thread_state = NULL;
Pike_interpreter_pointer = NULL;

/* Free ourselves.
* NB: This really ought to run in some other thread...
@@ -2621,7 +2620,7 @@ void exit_cond_obj(struct object *o)
*/
void f_thread_backtrace(INT32 args)
{
void low_backtrace(struct Pike_interpreter *);
void low_backtrace(struct Pike_interpreter_struct *);
struct thread_state *foo = THIS_THREAD;

pop_n_elems(args);
@@ -2813,7 +2812,7 @@ static void f_thread_id_kill(INT32 args)

void init_thread_obj(struct object *o)
{
MEMSET(&THIS_THREAD->state, 0, sizeof(struct Pike_interpreter));
MEMSET(&THIS_THREAD->state, 0, sizeof(struct Pike_interpreter_struct));
THIS_THREAD->thread_obj = Pike_fp->current_object;
THIS_THREAD->swapped = 0;
THIS_THREAD->status=THREAD_NOT_STARTED;
@@ -3188,6 +3187,8 @@ void low_th_init(void)

static struct object *backend_thread_obj = NULL;

static struct Pike_interpreter_struct *original_interpreter = NULL;

void th_init(void)
{
ptrdiff_t mutex_key_offset;
@@ -3334,6 +3335,7 @@ void th_init(void)
add_integer_constant("THREAD_RUNNING", THREAD_RUNNING, 0);
add_integer_constant("THREAD_EXITED", THREAD_EXITED, 0);

original_interpreter = Pike_interpreter_pointer;
backend_thread_obj = fast_clone_object(thread_id_prog);
INIT_THREAD_STATE((struct thread_state *)(backend_thread_obj->storage +
thread_storage_offset));
@@ -3386,9 +3388,15 @@ void th_cleanup(void)

if(backend_thread_obj)
{
/* Switch back to the original interpreter struct. */
*original_interpreter = Pike_interpreter;

destruct(backend_thread_obj);
free_object(backend_thread_obj);
backend_thread_obj = NULL;

Pike_interpreter_pointer = original_interpreter;

destruct_objects_to_destruct_cb();
}

@@ -35,7 +35,7 @@ struct pike_frame;
#define THREAD_DEBUG_LOOSE 1 /* Thread is not bound to the interpreter. */

struct thread_state {
struct Pike_interpreter state;
struct Pike_interpreter_struct state;
struct object *thread_obj; /* NOTE: Not ref-counted! */
struct mapping *thread_local;
struct thread_state *hashlink, **backlink;