/* -----------------------------------------------------------------------------
- * $Id: PrimOps.hc,v 1.10 1999/02/01 18:05:34 simonm Exp $
+ * $Id: PrimOps.hc,v 1.25 1999/03/22 13:01:38 simonm Exp $
+ *
+ * (c) The GHC Team, 1998-1999
*
* Primitive functions / data
*
#include "Storage.h"
#include "BlockAlloc.h" /* tmp */
#include "StablePriv.h"
+#include "HeapStackCheck.h"
+#include "StgRun.h"
/* ** temporary **
W_ GHC_ZCCCallable_static_info[0];
W_ GHC_ZCCReturnable_static_info[0];
-#ifndef aix_TARGET_OS /* AIX gives link errors with this as a const (RO assembler section) */
-const
-#endif
- StgClosure *PrelBase_Bool_closure_tbl[] = {
- &False_closure,
- &True_closure
-};
/* -----------------------------------------------------------------------------
Macros for Hand-written primitives.
R1.w = (W_)(a); R2.w = (W_)(b); R3.w = (W_)(c); R4.w = (W_)d; \
JMP_(ENTRY_CODE(Sp[0]));
+# define RET_NPNP(a,b,c,d) \
+ R1.w = (W_)(a); R2.w = (W_)(b); R3.w = (W_)(c); R4.w = (W_)(d); \
+ JMP_(ENTRY_CODE(Sp[0]));
+
# define RET_NNPNNP(a,b,c,d,e,f) \
R1.w = (W_)(a); R2.w = (W_)(b); R3.w = (W_)(c); \
R4.w = (W_)(d); R5.w = (W_)(e); R6.w = (W_)(f); \
Sp -= 5; \
JMP_(ENTRY_CODE(Sp[5]));
+# define RET_NPNP(a,b,c,d) \
+ R1.w = (W_)(a); \
+ Sp[-4] = (W_)(b); \
+ /* Sp[-3] = ARGTAG(1); */ \
+ Sp[-2] = (W_)(c); \
+ Sp[-1] = (W_)(d); \
+ Sp -= 4; \
+ JMP_(ENTRY_CODE(Sp[4]));
+
# define RET_NNPNNP(a,b,c,d,e,f) \
R1.w = (W_)(a); \
Sp[-1] = (W_)(f); \
# define RET_NNP(a,b,c) PUSH_N(6,a); PUSH_N(4,b); PUSH_N(2,c); PUSHED(6)
# define RET_NNNP(a,b,c,d) PUSH_N(7,a); PUSH_N(5,b); PUSH_N(3,c); PUSH_P(1,d); PUSHED(7)
+# define RET_NPNP(a,b,c,d) PUSH_N(6,a); PUSH_P(4,b); PUSH_N(3,c); PUSH_P(1,d); PUSHED(6)
# define RET_NNPNNP(a,b,c,d,e,f) PUSH_N(10,a); PUSH_N(8,b); PUSH_P(6,c); PUSH_N(5,d); PUSH_N(3,e); PUSH_P(1,f); PUSHED(10)
#endif
size = sizeofW(StgArrWords)+ stuff_size; \
p = (StgArrWords *)RET_STGCALL1(P_,allocate,size); \
TICK_ALLOC_PRIM(sizeofW(StgArrWords),stuff_size,0); \
- SET_HDR(p, &MUT_ARR_WORDS_info, CCCS); \
+ SET_HDR(p, &ARR_WORDS_info, CCCS); \
p->words = stuff_size; \
TICK_RET_UNBOXED_TUP(1) \
RET_P(p); \
}
#endif
+/* These two are out-of-line for the benefit of the NCG */
+FN_(unsafeThawArrayzh_fast)
+{
+ FB_
+ SET_INFO((StgClosure *)R1.cl,&MUT_ARR_PTRS_info);
+ recordMutable((StgMutClosure*)R1.cl);
+
+ TICK_RET_UNBOXED_TUP(1);
+ RET_P(R1.p);
+ FE_
+}
+
/* -----------------------------------------------------------------------------
Weak Pointer Primitives
-------------------------------------------------------------------------- */
{
/* R1.p = key
R2.p = value
- R3.p = finaliser
+ R3.p = finalizer
*/
StgWeak *w;
FB_
w->key = R1.cl;
w->value = R2.cl;
if (R3.cl) {
- w->finaliser = R3.cl;
- } else
- w->finaliser = &NO_FINALISER_closure;
+ w->finalizer = R3.cl;
+ } else {
+ w->finalizer = &NO_FINALIZER_closure;
}
w->link = weak_ptr_list;
FE_
}
-FN_(finaliseWeakzh_fast)
+FN_(finalizzeWeakzh_fast)
{
/* R1.p = weak ptr
*/
- StgWeak *w;
+ StgDeadWeak *w;
+ StgClosure *f;
FB_
TICK_RET_UNBOXED_TUP(0);
- w = (StgWeak *)R1.p;
+ w = (StgDeadWeak *)R1.p;
- if (w->finaliser != &NO_FINALISER_info) {
-#ifdef INTERPRETER
- STGCALL2(StgTSO *, createGenThread,
- RtsFlags.GcFlags.initialStkSize, w->finaliser);
-#else
- STGCALL2(StgTSO *, createIOThread,
- RtsFlags.GcFlags.initialStkSize, w->finaliser);
-#endif
+ /* already dead? */
+ if (w->header.info == &DEAD_WEAK_info) {
+ RET_NP(0,&NO_FINALIZER_closure);
}
- w->header.info = &DEAD_WEAK_info;
- JMP_(ENTRY_CODE(Sp[0]));
+ /* kill it */
+ w->header.info = &DEAD_WEAK_info;
+ f = ((StgWeak *)w)->finalizer;
+ w->link = ((StgWeak *)w)->link;
+
+ /* return the finalizer */
+ if (f == &NO_FINALIZER_closure) {
+ RET_NP(0,&NO_FINALIZER_closure);
+ } else {
+ RET_NP(1,f);
+ }
FE_
}
TICK_ALLOC_PRIM(sizeofW(StgArrWords),1,0);
CCS_ALLOC(CCCS,sizeofW(StgArrWords)+1); /* ccs prof */
- p = stgCast(StgArrWords*,Hp)-1;
+ p = (StgArrWords *)Hp - 1;
SET_ARR_HDR(p, &ARR_WORDS_info, CCCS, 1);
/* mpz_set_si is inlined here, makes things simpler */
s = 0;
}
- /* returns (# alloc :: Int#,
- size :: Int#,
+ /* returns (# size :: Int#,
data :: ByteArray#
#)
*/
- TICK_RET_UNBOXED_TUP(3);
- RET_NNP(1,s,p);
+ TICK_RET_UNBOXED_TUP(2);
+ RET_NP(s,p);
FE_
}
TICK_ALLOC_PRIM(sizeofW(StgArrWords),1,0);
CCS_ALLOC(CCCS,sizeofW(StgArrWords)+1); /* ccs prof */
- p = stgCast(StgArrWords*,Hp)-1;
+ p = (StgArrWords *)Hp - 1;
SET_ARR_HDR(p, &ARR_WORDS_info, CCCS, 1);
if (val != 0) {
s = 0;
}
- /* returns (# alloc :: Int#,
- size :: Int#,
+ /* returns (# size :: Int#,
data :: ByteArray#
#)
*/
- TICK_RET_UNBOXED_TUP(3);
- RET_NNP(1,s,p);
+ TICK_RET_UNBOXED_TUP(2);
+ RET_NP(s,p);
FE_
}
if (RET_STGCALL3(int, mpz_init_set_str,&result,(str),/*base*/10))
abort();
- TICK_RET_UNBOXED_TUP(3);
- RET_NNP(result._mp_alloc, result._mp_size,
+ /* returns (# size :: Int#,
+ data :: ByteArray#
+ #)
+ */
+ TICK_RET_UNBOXED_TUP(2);
+ RET_NP(result._mp_size,
result._mp_d - sizeofW(StgArrWords));
FE_
}
StgInt64 val; /* to avoid aliasing */
W_ hi;
- I_ s,a, neg, words_needed;
+ I_ s, neg, words_needed;
StgArrWords* p; /* address of array result */
FB_
TICK_ALLOC_PRIM(sizeofW(StgArrWords),words_needed,0);
CCS_ALLOC(CCCS,sizeofW(StgArrWords)+words_needed); /* ccs prof */
- p = stgCast(StgArrWords*,(Hp-words_needed+1))-1;
+ p = (StgArrWords *)(Hp-words_needed+1) - 1;
SET_ARR_HDR(p, &ARR_WORDS_info, CCCS, words_needed);
- a = words_needed;
-
if ( val < 0LL ) {
neg = 1;
val = -val;
hi = (W_)((LW_)val / 0x100000000ULL);
- if ( a == 2 ) {
+ if ( words_needed == 2 ) {
s = 2;
Hp[-1] = (W_)val;
Hp[0] = hi;
}
s = ( neg ? -s : s );
- /* returns (# alloc :: Int#,
- size :: Int#,
+ /* returns (# size :: Int#,
data :: ByteArray#
#)
*/
- TICK_RET_UNBOXED_TUP(3);
- RET_NNP(a,s,p);
+ TICK_RET_UNBOXED_TUP(2);
+ RET_NP(s,p);
FE_
}
{
/* arguments: L1 = Word64# */
- StgNat64 val; /* to avoid aliasing */
+ StgWord64 val; /* to avoid aliasing */
StgWord hi;
- I_ s,a,words_needed;
+ I_ s, words_needed;
StgArrWords* p; /* address of array result */
FB_
TICK_ALLOC_PRIM(sizeofW(StgArrWords),words_needed,0);
CCS_ALLOC(CCCS,sizeofW(StgArrWords)+words_needed); /* ccs prof */
- p = stgCast(StgArrWords*,(Hp-words_needed+1))-1;
+ p = (StgArrWords *)(Hp-words_needed+1) - 1;
SET_ARR_HDR(p, &ARR_WORDS_info, CCCS, words_needed);
- a = words_needed;
-
hi = (W_)((LW_)val / 0x100000000ULL);
if ( val >= 0x100000000ULL ) {
s = 2;
s = 0;
}
- /* returns (# alloc :: Int#,
- size :: Int#,
+ /* returns (# size :: Int#,
data :: ByteArray#
#)
*/
- TICK_RET_UNBOXED_TUP(3);
- RET_NNP(a,s,p);
+ TICK_RET_UNBOXED_TUP(2);
+ RET_NP(s,p);
FE_
}
FN_(name) \
{ \
MP_INT arg1, arg2, result; \
- I_ a1, s1, a2, s2; \
+ I_ s1, s2; \
StgArrWords* d1; \
StgArrWords* d2; \
FB_ \
\
/* call doYouWantToGC() */ \
- MAYBE_GC(R3_PTR | R6_PTR, name); \
+ MAYBE_GC(R2_PTR | R4_PTR, name); \
\
- a1 = R1.i; \
- s1 = R2.i; \
- d1 = stgCast(StgArrWords*,R3.p); \
- a2 = R4.i; \
- s2 = R5.i; \
- d2 = stgCast(StgArrWords*,R6.p); \
+ d1 = (StgArrWords *)R2.p; \
+ s1 = R1.i; \
+ d2 = (StgArrWords *)R4.p; \
+ s2 = R3.i; \
\
- arg1._mp_alloc = (a1); \
+ arg1._mp_alloc = d1->words; \
arg1._mp_size = (s1); \
arg1._mp_d = (unsigned long int *) (BYTE_ARR_CTS(d1)); \
- arg2._mp_alloc = (a2); \
+ arg2._mp_alloc = d2->words; \
arg2._mp_size = (s2); \
arg2._mp_d = (unsigned long int *) (BYTE_ARR_CTS(d2)); \
\
/* Perform the operation */ \
STGCALL3(mp_fun,&result,&arg1,&arg2); \
\
- TICK_RET_UNBOXED_TUP(3); \
- RET_NNP(result._mp_alloc, \
- result._mp_size, \
- result._mp_d-sizeofW(StgArrWords)); \
+ TICK_RET_UNBOXED_TUP(2); \
+ RET_NP(result._mp_size, \
+ result._mp_d-sizeofW(StgArrWords)); \
FE_ \
}
FN_(name) \
{ \
MP_INT arg1, arg2, result1, result2; \
- I_ a1, s1, a2, s2; \
+ I_ s1, s2; \
StgArrWords* d1; \
StgArrWords* d2; \
FB_ \
\
/* call doYouWantToGC() */ \
- MAYBE_GC(R3_PTR | R6_PTR, name); \
+ MAYBE_GC(R2_PTR | R4_PTR, name); \
\
- a1 = R1.i; \
- s1 = R2.i; \
- d1 = stgCast(StgArrWords*,R3.p); \
- a2 = R4.i; \
- s2 = R5.i; \
- d2 = stgCast(StgArrWords*,R6.p); \
+ d1 = (StgArrWords *)R2.p; \
+ s1 = R1.i; \
+ d2 = (StgArrWords *)R4.p; \
+ s2 = R3.i; \
\
- arg1._mp_alloc = (a1); \
+ arg1._mp_alloc = d1->words; \
arg1._mp_size = (s1); \
arg1._mp_d = (unsigned long int *) (BYTE_ARR_CTS(d1)); \
- arg2._mp_alloc = (a2); \
+ arg2._mp_alloc = d2->words; \
arg2._mp_size = (s2); \
arg2._mp_d = (unsigned long int *) (BYTE_ARR_CTS(d2)); \
\
/* Perform the operation */ \
STGCALL4(mp_fun,&result1,&result2,&arg1,&arg2); \
\
- TICK_RET_UNBOXED_TUP(6); \
- RET_NNPNNP(result1._mp_alloc, \
- result1._mp_size, \
- result1._mp_d-sizeofW(StgArrWords), \
- result2._mp_alloc, \
- result2._mp_size, \
- result2._mp_d-sizeofW(StgArrWords)); \
+ TICK_RET_UNBOXED_TUP(4); \
+ RET_NPNP(result1._mp_size, \
+ result1._mp_d-sizeofW(StgArrWords), \
+ result2._mp_size, \
+ result2._mp_d-sizeofW(StgArrWords)); \
FE_ \
}
/* arguments: F1 = Float# */
arg = F1;
- HP_CHK_GEN(sizeof(StgArrWords)+1, NO_PTRS, decodeFloatzh_fast,);
+ HP_CHK_GEN(sizeofW(StgArrWords)+1, NO_PTRS, decodeFloatzh_fast,);
TICK_ALLOC_PRIM(sizeofW(StgArrWords),1,0);
CCS_ALLOC(CCCS,sizeofW(StgArrWords)+1); /* ccs prof */
/* Be prepared to tell Lennart-coded __decodeFloat */
/* where mantissa._mp_d can be put (it does not care about the rest) */
- p = stgCast(StgArrWords*,Hp)-1;
+ p = (StgArrWords *)Hp - 1;
SET_ARR_HDR(p,&ARR_WORDS_info,CCCS,1)
mantissa._mp_d = (void *)BYTE_ARR_CTS(p);
/* Perform the operation */
STGCALL3(__decodeFloat,&mantissa,&exponent,arg);
- /* returns: (R1 = Int# (expn), R2 = Int#, R3 = Int#, R4 = ByteArray#) */
- TICK_RET_UNBOXED_TUP(4);
- RET_NNNP(exponent,mantissa._mp_alloc,mantissa._mp_size,p);
+ /* returns: (Int# (expn), Int#, ByteArray#) */
+ TICK_RET_UNBOXED_TUP(3);
+ RET_NNP(exponent,mantissa._mp_size,p);
FE_
}
#endif /* !FLOATS_AS_DOUBLES */
-#define DOUBLE_MANTISSA_SIZE (sizeof(StgDouble)/sizeof(W_))
-#define ARR_SIZE (sizeof(StgArrWords) + DOUBLE_MANTISSA_SIZE)
+#define DOUBLE_MANTISSA_SIZE (sizeofW(StgDouble))
+#define ARR_SIZE (sizeofW(StgArrWords) + DOUBLE_MANTISSA_SIZE)
FN_(decodeDoublezh_fast)
{ MP_INT mantissa;
arg = D1;
HP_CHK_GEN(ARR_SIZE, NO_PTRS, decodeDoublezh_fast,);
- TICK_ALLOC_PRIM(sizeof(StgArrWords),DOUBLE_MANTISSA_SIZE,0);
+ TICK_ALLOC_PRIM(sizeofW(StgArrWords),DOUBLE_MANTISSA_SIZE,0);
CCS_ALLOC(CCCS,ARR_SIZE); /* ccs prof */
/* Be prepared to tell Lennart-coded __decodeDouble */
/* where mantissa.d can be put (it does not care about the rest) */
- p = stgCast(StgArrWords*,Hp-ARR_SIZE+1);
+ p = (StgArrWords *)(Hp-ARR_SIZE+1);
SET_ARR_HDR(p, &ARR_WORDS_info, CCCS, DOUBLE_MANTISSA_SIZE);
mantissa._mp_d = (void *)BYTE_ARR_CTS(p);
/* Perform the operation */
STGCALL3(__decodeDouble,&mantissa,&exponent,arg);
- /* returns: (R1 = Int# (expn), R2 = Int#, R3 = Int#, R4 = ByteArray#) */
- TICK_RET_UNBOXED_TUP(4);
- RET_NNNP(exponent,mantissa._mp_alloc,mantissa._mp_size,p);
+ /* returns: (Int# (expn), Int#, ByteArray#) */
+ TICK_RET_UNBOXED_TUP(3);
+ RET_NNP(exponent,mantissa._mp_size,p);
FE_
}
FB_
/* args: R1 = closure to spark */
- if (closure_SHOULD_SPARK(stgCast(StgClosure*,R1.p))) {
+ if (closure_SHOULD_SPARK(R1.cl)) {
MAYBE_GC(R1_PTR, forkzh_fast);
FE_
}
+FN_(yieldzh_fast)
+{
+ FB_
+ JMP_(stg_yield_noregs);
+ FE_
+}
+
FN_(killThreadzh_fast)
{
FB_
- /* args: R1.p = TSO to kill */
+ /* args: R1.p = TSO to kill, R2.p = Exception */
/* The thread is dead, but the TSO sticks around for a while. That's why
* we don't have to explicitly remove it from any queues it might be on.
*/
- STGCALL1(deleteThread, (StgTSO *)R1.p);
- /* We might have killed ourselves. In which case, better return to the
- * scheduler...
+ /* We might have killed ourselves. In which case, better be *very*
+ * careful. If the exception killed us, then return to the scheduler.
+ * If the exception went to a catch frame, we'll just continue from
+ * the handler.
*/
- if ((StgTSO *)R1.p == CurrentTSO) {
- JMP_(stg_stop_thread_entry); /* leave semi-gracefully */
+ if (R1.t == CurrentTSO) {
+ SaveThreadState(); /* inline! */
+ STGCALL2(raiseAsync, R1.t, R2.cl);
+ if (CurrentTSO->whatNext == ThreadKilled) {
+ R1.w = ThreadYielding;
+ JMP_(StgReturn);
+ }
+ LoadThreadState();
+ if (CurrentTSO->whatNext == ThreadEnterGHC) {
+ R1.w = Sp[0];
+ Sp++;
+ JMP_(GET_ENTRY(R1.cl));
+ } else {
+ barf("killThreadzh_fast");
+ }
+ } else {
+ STGCALL2(raiseAsync, R1.t, R2.cl);
}
JMP_(ENTRY_CODE(Sp[0]));
mvar->tail->link = CurrentTSO;
}
CurrentTSO->link = (StgTSO *)&END_TSO_QUEUE_closure;
+ CurrentTSO->blocked_on = (StgClosure *)mvar;
mvar->tail = CurrentTSO;
BLOCK(R1_PTR, takeMVarzh_fast);
index = RET_STGCALL1(StgWord,lookupStableName,R1.p);
- sn_obj = (StgStableName *) (Hp - sizeofW(StgStableName) + 1);
- sn_obj->header.info = &STABLE_NAME_info;
- sn_obj->sn = index;
+ /* Is there already a StableName for this heap object? */
+ if (stable_ptr_table[index].sn_obj == NULL) {
+ sn_obj = (StgStableName *) (Hp - sizeofW(StgStableName) + 1);
+ sn_obj->header.info = &STABLE_NAME_info;
+ sn_obj->sn = index;
+ stable_ptr_table[index].sn_obj = (StgClosure *)sn_obj;
+ } else {
+ (StgClosure *)sn_obj = stable_ptr_table[index].sn_obj;
+ }
TICK_RET_UNBOXED_TUP(1);
RET_P(sn_obj);