[project @ 2001-08-03 15:05:52 by sewardj]
[ghc-hetmet.git] / ghc / rts / Interpreter.c
index 2fd1580..c249c76 100644 (file)
@@ -5,12 +5,10 @@
  * Copyright (c) 1994-2000.
  *
  * $RCSfile: Interpreter.c,v $
- * $Revision: 1.14 $
- * $Date: 2001/02/05 17:27:48 $
+ * $Revision: 1.26 $
+ * $Date: 2001/08/03 15:05:52 $
  * ---------------------------------------------------------------------------*/
 
-#ifdef GHCI
-
 #include "Rts.h"
 #include "RtsAPI.h"
 #include "RtsUtils.h"
@@ -95,8 +93,8 @@ int it_slides;
 int it_insns;
 int it_BCO_entries;
 
-int it_ofreq[26];
-int it_oofreq[26][26];
+int it_ofreq[27];
+int it_oofreq[27][27];
 int it_lastopc;
 
 void interp_startup ( void )
@@ -107,9 +105,9 @@ void interp_startup ( void )
    for (i = 0; i < N_CLOSURE_TYPES; i++)
       it_unknown_entries[i] = 0;
    it_slides = it_insns = it_BCO_entries = 0;
-   for (i = 0; i < 26; i++) it_ofreq[i] = 0;
-   for (i = 0; i < 26; i++) 
-     for (j = 0; j < 26; j++)
+   for (i = 0; i < 27; i++) it_ofreq[i] = 0;
+   for (i = 0; i < 27; i++) 
+     for (j = 0; j < 27; j++)
         it_oofreq[i][j] = 0;
    it_lastopc = 0;
 }
@@ -117,7 +115,7 @@ void interp_startup ( void )
 void interp_shutdown ( void )
 {
    int i, j, k, o_max, i_max, j_max;
-   fprintf(stderr, "%d constrs entered -> (%d BCO, %d UPD, %d ???)\n",
+   fprintf(stderr, "%d constrs entered -> (%d BCO, %d UPD, %d ??? )\n",
                    it_retto_BCO + it_retto_UPDATE + it_retto_other,
                    it_retto_BCO, it_retto_UPDATE, it_retto_other );
    fprintf(stderr, "%d total entries, %d unknown entries \n", 
@@ -131,14 +129,14 @@ void interp_shutdown ( void )
    }
    fprintf(stderr, "%d insns, %d slides, %d BCO_entries\n", 
                    it_insns, it_slides, it_BCO_entries);
-   for (i = 0; i < 26; i++) 
+   for (i = 0; i < 27; i++) 
       fprintf(stderr, "opcode %2d got %d\n", i, it_ofreq[i] );
 
    for (k = 1; k < 20; k++) {
       o_max = 0;
       i_max = j_max = 0;
-      for (i = 0; i < 26; i++) {
-         for (j = 0; j < 26; j++) {
+      for (i = 0; i < 27; i++) {
+         for (j = 0; j < 27; j++) {
            if (it_oofreq[i][j] > o_max) {
                o_max = it_oofreq[i][j];
               i_max = i; j_max = j;
@@ -322,7 +320,7 @@ StgThreadReturnCode interpretBCO ( Capability* cap )
 
              case SEQ_FRAME:
                 /* Too complicated ... adopt the Usual Solution. */
-                fprintf(stderr, "!!! SEQ frame in PAP update\n");
+                /* fprintf(stderr, "!!! SEQ frame in PAP update\n"); */
                 goto defer_to_sched;
 
              case CATCH_FRAME:
@@ -369,12 +367,30 @@ StgThreadReturnCode interpretBCO ( Capability* cap )
           register StgInfoTable** itbls = (StgInfoTable**)
                                              (&bco->itbls->payload[0]);
 
+          /* Heap check */
           if (doYouWantToGC()) {
             iSp--; StackWord(0) = (W_)bco;
-             cap->rCurrentTSO->what_next = ThreadEnterGHC;
+             cap->rCurrentTSO->what_next = ThreadEnterInterp;
              RETURN(HeapOverflow);
           }
 
+          /* "Standard" stack check */
+          if (iSp - (INTERP_STACK_CHECK_THRESH+1) < iSpLim) {
+             iSp--;
+             StackWord(0) = (W_)obj;
+             cap->rCurrentTSO->what_next = ThreadEnterInterp;
+             RETURN(StackOverflow);
+          }
+
+          /* Context-switch check */
+          if (context_switch) {
+             iSp--;
+             StackWord(0) = (W_)obj;
+             cap->rCurrentTSO->what_next = ThreadEnterInterp;
+             RETURN(ThreadYielding);
+         }
+
 #         ifdef INTERP_STATS
           it_lastopc = 0; /* no opcode */
 #         endif
@@ -402,7 +418,7 @@ StgThreadReturnCode interpretBCO ( Capability* cap )
 
 #         ifdef INTERP_STATS
           it_insns++;
-          ASSERT( (int)instrs[bciPtr] >= 0 && (int)instrs[bciPtr] < 26 );
+          ASSERT( (int)instrs[bciPtr] >= 0 && (int)instrs[bciPtr] < 27 );
           it_ofreq[ (int)instrs[bciPtr] ] ++;
           it_oofreq[ it_lastopc ][ (int)instrs[bciPtr] ] ++;
           it_lastopc = (int)instrs[bciPtr];
@@ -410,6 +426,18 @@ StgThreadReturnCode interpretBCO ( Capability* cap )
 
           switch (BCO_NEXT) {
 
+              case bci_STKCHECK: {
+               /* An explicit stack check; we hope these will be
+                   rare. */
+                int stk_words_reqd = BCO_NEXT + 1;
+                if (iSp - stk_words_reqd < iSpLim) {
+                   iSp--;
+                   StackWord(0) = (W_)obj;
+                   cap->rCurrentTSO->what_next = ThreadEnterInterp;
+                   RETURN(StackOverflow);
+                }
+                goto nextInsn;
+              }
               case bci_ARGCHECK: {
                  int i;
                  StgPAP* pap;
@@ -534,7 +562,7 @@ StgThreadReturnCode interpretBCO ( Capability* cap )
                  ap = (StgAP_UPD*)allocate_UPD(request);
                  StackWord(-1) = (W_)ap;
                  ap->n_args = n_payload;
-                 SET_HDR(ap, &stg_AP_UPD_info, ??)
+                 SET_HDR(ap, &stg_AP_UPD_info, CCS_SYSTEM/*ToDo*/)
                  iSp --;
                  goto nextInsn;
               }
@@ -663,6 +691,30 @@ StgThreadReturnCode interpretBCO ( Capability* cap )
                     bciPtr = failto;
                  goto nextInsn;
               }
+              case bci_TESTLT_F: {
+                 /* The top thing on the stack should be a tagged float. */
+                 int discr   = BCO_NEXT;
+                 int failto  = BCO_NEXT;
+                 StgFloat stackFlt, discrFlt;
+                 ASSERT(sizeofW(StgFloat) == StackWord(0));
+                 stackFlt = PK_FLT( & StackWord(1) );
+                 discrFlt = PK_FLT( & BCO_LIT(discr) );
+                 if (stackFlt >= discrFlt)
+                    bciPtr = failto;
+                 goto nextInsn;
+              }
+              case bci_TESTEQ_F: {
+                 /* The top thing on the stack should be a tagged float. */
+                 int discr   = BCO_NEXT;
+                 int failto  = BCO_NEXT;
+                 StgFloat stackFlt, discrFlt;
+                 ASSERT(sizeofW(StgFloat) == StackWord(0));
+                 stackFlt = PK_FLT( & StackWord(1) );
+                 discrFlt = PK_FLT( & BCO_LIT(discr) );
+                 if (stackFlt != discrFlt)
+                    bciPtr = failto;
+                 goto nextInsn;
+              }
 
               /* Control-flow ish things */
               case bci_ENTER: {
@@ -678,7 +730,8 @@ StgThreadReturnCode interpretBCO ( Capability* cap )
                  if (ret_itbl == (StgInfoTable*)&stg_ctoi_ret_R1p_info
                      || ret_itbl == (StgInfoTable*)&stg_ctoi_ret_R1n_info
                      || ret_itbl == (StgInfoTable*)&stg_ctoi_ret_F1_info
-                     || ret_itbl == (StgInfoTable*)&stg_ctoi_ret_D1_info) {
+                     || ret_itbl == (StgInfoTable*)&stg_ctoi_ret_D1_info
+                     || ret_itbl == (StgInfoTable*)&stg_ctoi_ret_V_info) {
                      /* Returning to interpreted code.  Interpret the BCO 
                         immediately underneath the itbl. */
                      StgBCO* ret_bco = (StgBCO*)StackWord(tag +1+1);
@@ -692,19 +745,37 @@ StgThreadReturnCode interpretBCO ( Capability* cap )
                         the TOS value into R1/F1/D1 and do a standard
                         compiled-code return. */
                      StgInfoTable* magic_itbl = BCO_ITBL(o_itoc_itbl);
-                     StackWord(0) = (W_)magic_itbl;
-                     cap->rCurrentTSO->what_next = ThreadRunGHC;
-                     RETURN(ThreadYielding);
+                     if (magic_itbl != NULL) {
+                        StackWord(0) = (W_)magic_itbl;
+                        cap->rCurrentTSO->what_next = ThreadRunGHC;
+                        RETURN(ThreadYielding);
+                     } else {
+                        /* Special case -- returning a VoidRep to
+                           compiled code.  T.O.S is the VoidRep tag,
+                           and underneath is the return itbl.  Zap the
+                           tag and enter the itbl. */
+                       ASSERT(StackWord(0) == (W_)NULL);
+                       iSp ++;
+                        cap->rCurrentTSO->what_next = ThreadRunGHC;
+                        RETURN(ThreadYielding);
+                     }
                  }
               }
-        
+              case bci_CCALL: {
+                 int o_itbl                = BCO_NEXT;
+                 void(*marshall_fn)(void*) = (void (*)(void*))BCO_LIT(o_itbl);
+                 marshall_fn ( (void*)(& StackWord(0) ) );
+                 goto nextInsn;
+              }
+              case bci_JMP: {
+                 /* BCO_NEXT modifies bciPtr, so be conservative. */
+                 int nextpc = BCO_NEXT;
+                 bciPtr     = nextpc;
+                 goto nextInsn;
+              }
               case bci_CASEFAIL:
                  barf("interpretBCO: hit a CASEFAIL");
 
-              /* As yet unimplemented */
-              case bci_TESTLT_F:
-              case bci_TESTEQ_F:
-
               /* Errors */
               default: 
                  barf("interpretBCO: unknown or unimplemented opcode");
@@ -741,5 +812,3 @@ StgThreadReturnCode interpretBCO ( Capability* cap )
 
     barf("fallen off end of object-type switch in interpretBCO()");
 }
-
-#endif /* GHCI */