Changeset 10105


Ignore:
Timestamp:
Jul 18, 2008, 8:55:27 PM (11 years ago)
Author:
rme
Message:

Changes for x8632.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/lisp-kernel/x86-gc.c

    r10104 r10105  
    4343  case fulltag_even_fixnum:
    4444  case fulltag_odd_fixnum:
     45#ifdef X8632
     46  case fulltag_imm:
     47#endif
     48#ifdef X8664
    4549  case fulltag_imm_0:
    4650  case fulltag_imm_1:
     51#endif
    4752    return;
    4853
     54#ifdef X8664
    4955  case fulltag_nil:
    5056    if (n != lisp_nil) {
     
    5258    }
    5359    return;
    54 
    55 
     60#endif
     61
     62#ifdef X8632
     63  case fulltag_nodeheader:
     64  case fulltag_immheader:
     65#endif
     66#ifdef X8664
    5667  case fulltag_nodeheader_0:
    5768  case fulltag_nodeheader_1:
     
    5970  case fulltag_immheader_1:
    6071  case fulltag_immheader_2:
     72#endif
    6173    Bug(NULL, "Header not expected : 0x%lx", n);
    6274    return;
    6375
     76#ifdef X8632
     77  case fulltag_tra:
     78#endif
     79#ifdef X8664
    6480  case fulltag_tra_0:
    6581  case fulltag_tra_1:
     82#endif
    6683    a = heap_area_containing((BytePtr)ptr_from_lispobj(n));
    6784    if (a == NULL) {
     
    7693       check the function it (should) identify.
    7794    */
     95#ifdef X8632
     96    {
     97      LispObj fun = 0;
     98
     99      if (*(unsigned char *)n == RECOVER_FN_OPCODE)
     100        fun = *(LispObj *)(n + 1);
     101      if (fun == 0 ||
     102         (header_subtag(header_of(fun)) != subtag_function) ||
     103         (heap_area_containing((BytePtr)ptr_from_lispobj(fun)) != a)) {
     104        Bug(NULL, "TRA at 0x%x has bad function address 0x%x\n", n, fun);
     105      }
     106      n = fun;
     107    }
     108#endif
     109#ifdef X8664
    78110    {
    79111      int disp = 0;
     
    91123      }
    92124    }
     125#endif
    93126    /* Otherwise, fall through and check the header on the function
    94127       that the tra references */
     
    96129  case fulltag_misc:
    97130  case fulltag_cons:
     131#ifdef X8664
    98132  case fulltag_symbol:
    99133  case fulltag_function:
     134#endif
    100135    a = heap_area_containing((BytePtr)ptr_from_lispobj(n));
    101136   
     
    163198      elements = header_element_count(node) | 1;
    164199      if (header_subtag(node) == subtag_function) {
     200#ifdef X8632
     201        int skip = *(unsigned short *)current;
     202#else
    165203        int skip = *(int *)current;
     204#endif
    166205        current += skip;
    167206        elements -= skip;
     
    250289  }
    251290
     291#ifdef X8632
     292  if (tag_n == fulltag_tra) {
     293    if (*(unsigned char *)n == RECOVER_FN_OPCODE) {
     294      n = *(LispObj *)(n + 1);
     295      tag_n = fulltag_misc;
     296    } else
     297      return;
     298  }
     299#endif
     300#ifdef X8664
    252301  if (tag_of(n) == tag_tra) {
    253302    if ((*((unsigned short *)n) == RECOVER_FN_FROM_RIP_WORD0) &&
     
    261310    }
    262311  }
     312#endif
    263313
    264314
     
    292342    tag_n = fulltag_of(header);
    293343
    294 
     344#ifdef X8664
    295345    if ((nodeheader_tag_p(tag_n)) ||
    296346        (tag_n == ivector_class_64_bit)) {
     
    308358      }
    309359    }
     360#endif
     361#ifdef X8632
     362    if ((tag_n == fulltag_nodeheader) ||
     363        (subtag <= max_32_bit_ivector_subtag)) {
     364      total_size_in_bytes = 4 + (element_count<<2);
     365    } else if (subtag <= max_8_bit_ivector_subtag) {
     366      total_size_in_bytes = 4 + element_count;
     367    } else if (subtag <= max_16_bit_ivector_subtag) {
     368      total_size_in_bytes = 4 + (element_count<<1);
     369    } else if (subtag == subtag_double_float_vector) {
     370      total_size_in_bytes = 8 + (element_count<<3);
     371    } else {
     372      total_size_in_bytes = 4 + ((element_count+7)>>3);
     373    }
     374#endif
     375
    310376
    311377    suffix_dnodes = ((total_size_in_bytes+(dnode_size-1))>>dnode_shift) -1;
     
    344410
    345411      if (subtag == subtag_function) {
     412#ifdef X8632
     413        prefix_nodes = (natural) ((unsigned short) deref(base,1));
     414#else
    346415        prefix_nodes = (natural) ((int) deref(base,1));
     416#endif
    347417        if (prefix_nodes > element_count) {
    348418          Bug(NULL, "Function 0x%lx trashed",n);
     
    397467#ifdef X8664
    398468#define RMARK_PREV_ROOT fulltag_imm_1 /* fulltag of 'undefined' value */
    399 #define RMARK_PREV_CAR fulltag_nil /* fulltag_nil + node_size. Coincidence ? I think not. */
     469#define RMARK_PREV_CAR fulltag_nil /* fulltag_cons + node_size. Coincidence ? I think not. */
    400470#else
    401 #endif
    402 
     471#define RMARK_PREV_ROOT fulltag_imm /* fulltag of 'undefined' value */
     472#define RMARK_PREV_CAR fulltag_odd_fixnum
     473#endif
    403474
    404475
     
    419490  }
    420491
     492#ifdef X8632
     493  if (tag_n == fulltag_tra) {
     494    if (*(unsigned char *)n == RECOVER_FN_OPCODE) {
     495      n = *(LispObj *)(n + 1);
     496      tag_n = fulltag_misc;
     497    } else {
     498      return;
     499    }
     500  }
     501#endif
     502#ifdef X8664
    421503  if (tag_of(n) == tag_tra) {
    422504    if ((*((unsigned short *)n) == RECOVER_FN_FROM_RIP_WORD0) &&
     
    429511    }
    430512  }
     513#endif
    431514
    432515  dnode = gc_area_dnode(n);
     
    456539      tag_n = fulltag_of(header);
    457540
     541#ifdef X8664
    458542      if ((nodeheader_tag_p(tag_n)) ||
    459543          (tag_n == ivector_class_64_bit)) {
     
    471555        }
    472556      }
     557#else
     558      if ((tag_n == fulltag_nodeheader) ||
     559          (subtag <= max_32_bit_ivector_subtag)) {
     560        total_size_in_bytes = 4 + (element_count<<2);
     561      } else if (subtag <= max_8_bit_ivector_subtag) {
     562        total_size_in_bytes = 4 + element_count;
     563      } else if (subtag <= max_16_bit_ivector_subtag) {
     564        total_size_in_bytes = 4 + (element_count<<1);
     565      } else if (subtag == subtag_double_float_vector) {
     566        total_size_in_bytes = 8 + (element_count<<3);
     567      } else {
     568        total_size_in_bytes = 4 + ((element_count+7)>>3);
     569      }
     570#endif
     571
    473572      suffix_dnodes = ((total_size_in_bytes+(dnode_size-1))>>dnode_shift)-1;
    474573
     
    513612
    514613      if (subtag == subtag_function) {
    515         if ((int)base[1] >= nmark) {
     614#ifdef X8664
     615        int code_words = (int)base[1];
     616#else
     617        int code_words = (unsigned short)base[1];
     618#endif
     619        if (code_words >= nmark) {
    516620          Bug(NULL,"Bad function at 0x%lx",n);
    517621        }
    518         nmark -= (int)base[1];
     622        nmark -= code_words;
    519623      }
    520624
     
    531635    }
    532636  } else {
    533 
    534637    /* This is all a bit more complicated than the PPC version:
    535638
     
    618721    case tag_misc:
    619722    case fulltag_misc:
     723#ifdef X8664
    620724    case tag_symbol:
    621725    case fulltag_symbol:
    622726    case tag_function:
    623727    case fulltag_function:
     728#endif
    624729      goto ClimbVector;
    625730
     
    633738      goto ClimbCar;
    634739
    635       /* default: abort() */
     740    default: abort();
    636741    }
    637742
     
    642747  MarkCons:
    643748    next = deref(this,1);
     749#ifdef X8632
     750    this += (RMARK_PREV_CAR-fulltag_cons);
     751#else
    644752    this += node_size;
     753#endif
    645754    tag_n = fulltag_of(next);
    646755    if (!is_node_fulltag(tag_n)) goto MarkCdr;
     
    660769  MarkCdr:
    661770    next = deref(this, 0);
     771#ifdef X8632
     772    this -= (RMARK_PREV_CAR-fulltag_cons);
     773#else
    662774    this -= node_size;
     775#endif
    663776    tag_n = fulltag_of(next);
    664777    if (!is_node_fulltag(tag_n)) goto Climb;
     
    677790
    678791  MarkVector:
     792#ifdef X8664
    679793    if ((tag_n == fulltag_tra_0) ||
    680794        (tag_n == fulltag_tra_1)) {
     
    717831      }
    718832    }
     833#else
     834    if (tag_n == fulltag_tra) {
     835      LispObj fn = *(LispObj *)(n + 1);
     836
     837      base = (LispObj *)untag(fn);
     838      header = *(natural *)base;
     839      subtag = header_subtag(header);
     840      boundary = base + (unsigned short)base[1];
     841      /*
     842       * On x8632, the upper 24 bits of the boundary word are zero.
     843       * Functions on x8632 can be no more than 2^16 words (or 2^24
     844       * bytes) long (including the self-reference table but excluding
     845       * any constants).  Therefore, we can do the same basic thing
     846       * that the x8664 port does: namely, we keep the byte
     847       * displacement from the address of the object (tagged tra or
     848       * fulltag_misc) that references the function to the address of
     849       * the boundary marker in those 24 bits, recovering it when
     850       * we've finished marking the function vector.
     851       */
     852      *((int *)boundary) &= 0xff;
     853      *((int *)boundary) |= ((this-(LispObj)boundary) << 8);
     854      this = (LispObj)(base)+fulltag_misc;
     855      dnode = gc_area_dnode(this);
     856      set_bit(markbits,dnode);
     857    } else {
     858      base = (LispObj *) ptr_from_lispobj(untag(this));
     859      header = *((natural *) base);
     860      subtag = header_subtag(header);
     861      if (subtag == subtag_function) {
     862        boundary = base + (unsigned short)base[1];
     863        *((int *)boundary) &= 0xff;
     864        *((int *)boundary) |= ((this-((LispObj)boundary)) << 8);
     865      }
     866    }
     867    element_count = header_element_count(header);
     868    tag_n = fulltag_of(header);
     869
     870    if ((tag_n == fulltag_nodeheader) ||
     871        (subtag <= max_32_bit_ivector_subtag)) {
     872      total_size_in_bytes = 4 + (element_count<<2);
     873    } else if (subtag <= max_8_bit_ivector_subtag) {
     874      total_size_in_bytes = 4 + element_count;
     875    } else if (subtag <= max_16_bit_ivector_subtag) {
     876      total_size_in_bytes = 4 + (element_count<<1);
     877    } else if (subtag == subtag_double_float_vector) {
     878      total_size_in_bytes = 8 + (element_count<<3);
     879    } else {
     880      total_size_in_bytes = 4 + ((element_count+7)>>3);
     881    }
     882#endif
     883
    719884    suffix_dnodes = ((total_size_in_bytes+(dnode_size-1))>>dnode_shift)-1;
    720885   
     
    759924    this -= node_size;
    760925    next = indirect_node(this);
     926#ifdef X8664
    761927    if ((tag_of(this) == tag_function) &&
    762928        (header_subtag(next) == function_boundary_marker)) goto MarkFunctionDone;
     929#else
     930    if ((tag_of(this) == tag_misc) &&
     931        (header_subtag(next) == function_boundary_marker)) goto MarkFunctionDone;
     932#endif
     933
    763934    tag_n = fulltag_of(next);
    764935    if (nodeheader_tag_p(tag_n)) goto MarkVectorDone;
     
    786957  MarkFunctionDone:
    787958    boundary = (LispObj *)(node_aligned(this));
     959#ifdef X8664
    788960    this = ((LispObj)boundary) + (((int *)boundary)[1]);
    789961    (((int *)boundary)[1]) = 0;
     962#else
     963    this = ((LispObj)boundary) + ((*((int *)boundary)) >> 8);
     964    ((int *)boundary)[0] &= 0xff;
    790965    goto Climb;
     966#endif
    791967  }
    792968}
     
    801977
    802978
    803 
     979#ifdef X8664
    804980  switch (fulltag_of(header)) {
    805981  case ivector_class_64_bit:
     
    820996  }
    821997  return ptr_from_lispobj(start+(~15 & (nbytes + 8 + 15)));
    822 
     998#else
     999  if (subtag <= max_32_bit_ivector_subtag) {
     1000    nbytes = element_count << 2;
     1001  } else if (subtag <= max_8_bit_ivector_subtag) {
     1002    nbytes = element_count;
     1003  } else if (subtag <= max_16_bit_ivector_subtag) {
     1004    nbytes = element_count << 1;
     1005  } else if (subtag == subtag_double_float_vector) {
     1006    nbytes = 4 + (element_count << 3);
     1007  } else {
     1008    nbytes = (element_count+7) >> 3;
     1009  }
     1010  return ptr_from_lispobj(start+(~7 & (nbytes + 4 + 7)));
     1011#endif
    8231012}
    8241013
     
    8401029    } else {
    8411030      if (header_subtag(x1) == subtag_function) {
     1031#ifdef X8632
     1032        int skip = (unsigned short)deref(start,1);
     1033#else
    8421034        int skip = (int) deref(start,1);
     1035#endif
    8431036        start += ((1+skip)&~1);
    8441037        x1 = *start;
     
    10151208      base = start + element_count + 1;
    10161209      if (subtag == subtag_function) {
     1210#ifdef X8632
     1211        element_count -= (unsigned short)start[1];
     1212#else
    10171213        element_count -= (int)start[1];
     1214#endif
    10181215      }
    10191216      while(element_count--) {
     
    10761273
    10771274/* Mark the lisp objects in an exception frame */
     1275#ifdef X8664
    10781276void
    10791277mark_xp(ExceptionInformation *xp)
     
    11141312  }
    11151313}
    1116 
    1117 
    1118      
    1119 
    1120 
    1121 
    1122 
     1314#else
     1315void
     1316mark_xp(ExceptionInformation *xp, natural node_regs_mask)
     1317{
     1318  natural *regs = (natural *) xpGPRvector(xp), dnode;
     1319  LispObj eip;
     1320  int i;
     1321
     1322  if (node_regs_mask & (1<<0)) mark_root(regs[REG_EAX]);
     1323  if (node_regs_mask & (1<<1)) mark_root(regs[REG_EBX]);
     1324  if (node_regs_mask & (1<<2)) mark_root(regs[REG_ECX]);
     1325  if (node_regs_mask & (1<<3)) mark_root(regs[REG_EDX]);
     1326  if (node_regs_mask & (1<<4)) mark_root(regs[REG_ESP]);
     1327  if (node_regs_mask & (1<<5)) mark_root(regs[REG_EBP]);
     1328  if (node_regs_mask & (1<<6)) mark_root(regs[REG_ESI]);
     1329  if (node_regs_mask & (1<<7)) mark_root(regs[REG_EDI]);
     1330
     1331  /* If the EIP isn't pointing into a marked function, we're probably
     1332     in trouble.  We can -maybe- recover from that if it's tagged as a
     1333     TRA. */
     1334  eip = regs[Ieip];
     1335  dnode = gc_area_dnode(eip);
     1336  if ((dnode < GCndnodes_in_area) &&
     1337      (! ref_bit(GCmarkbits,dnode))) {
     1338    if (fulltag_of(eip) == fulltag_tra) {
     1339      mark_root(eip);
     1340    } else if ((fulltag_of(eip) == fulltag_misc) &&
     1341               (header_subtag(header_of(eip)) == subtag_function) &&
     1342               (*(unsigned char *)eip == RECOVER_FN_OPCODE) &&
     1343               (*(LispObj *)(eip + 1)) == eip) {
     1344      mark_root(eip);
     1345    } else {
     1346      Bug(NULL, "Can't find function for eip 0x%4x", eip);
     1347    }
     1348  }
     1349}
     1350#endif
    11231351
    11241352/* A "pagelet" contains 32 doublewords.  The relocation table contains
     
    12181446}
    12191447#else
    1220 
     1448#ifdef X8664
    12211449/* Quicker, dirtier */
    12221450LispObj
     
    12441472  return new;
    12451473}
     1474#endif
     1475#ifdef X8632
     1476LispObj
     1477dnode_forwarding_address(natural dnode, int tag_n)
     1478{
     1479  natural pagelet, nbits;
     1480  unsigned short near_bits;
     1481  LispObj new;
     1482
     1483  if (GCDebug) {
     1484    if (! ref_bit(GCdynamic_markbits, dnode)) {
     1485      Bug(NULL, "unmarked object being forwarded!\n");
     1486    }
     1487  }
     1488
     1489  pagelet = dnode >> 5;
     1490  nbits = dnode & 0x1f;
     1491  /* On little-endian x86, we have to flip the low bit of dnode>>4 to
     1492     get the near_bits from the appropriate half-word. */
     1493  near_bits = ((unsigned short *)GCdynamic_markbits)[(dnode>>4)^1];
     1494
     1495  if (nbits < 16) {
     1496    new = GCrelocptr[pagelet] + tag_n;;
     1497    /* Increment "new" by the count of 1 bits which precede the dnode */
     1498    if (near_bits == 0xffff) {
     1499      return (new + (nbits << 3));
     1500    } else {
     1501      near_bits &= (0xffff0000 >> nbits);
     1502      if (nbits > 7) {
     1503        new += one_bits(near_bits & 0xff);
     1504      }
     1505      return (new + (one_bits(near_bits >> 8)));
     1506    }
     1507  } else {
     1508    new = GCrelocptr[pagelet+1] + tag_n;
     1509    nbits = 32-nbits;
     1510
     1511    if (near_bits == 0xffff) {
     1512      return (new - (nbits << 3));
     1513    } else {
     1514      near_bits &= (1<<nbits)-1;
     1515      if (nbits > 7) {
     1516        new -= one_bits(near_bits >> 8);
     1517      }
     1518      return (new - one_bits(near_bits & 0xff));
     1519    }
     1520  }
     1521}
     1522#endif
    12461523#endif
    12471524
     
    13161593      } else {
    13171594        if (header_subtag(node) == subtag_function) {
     1595#ifdef X8632
     1596          int skip = (unsigned short)(p[1]);
     1597#else
    13181598          int skip = (int)(p[1]);
     1599#endif
    13191600          p += skip;
    13201601          nwords -= skip;
     
    13801661}
    13811662
    1382 
     1663#ifdef X8664
    13831664void
    13841665forward_xp(ExceptionInformation *xp)
     
    13991680  update_locref(&(regs[Iip]));
    14001681}
     1682#else
     1683void
     1684forward_xp(ExceptionInformation *xp, natural node_regs_mask)
     1685{
     1686  natural *regs = (natural *) xpGPRvector(xp);
     1687
     1688  if (node_regs_mask & (1<<0)) update_noderef(&regs[REG_EAX]);
     1689  if (node_regs_mask & (1<<1)) update_noderef(&regs[REG_EBX]);
     1690  if (node_regs_mask & (1<<2)) update_noderef(&regs[REG_ECX]);
     1691  if (node_regs_mask & (1<<3)) update_noderef(&regs[REG_EDX]);
     1692  if (node_regs_mask & (1<<4)) update_noderef(&regs[REG_ESP]);
     1693  if (node_regs_mask & (1<<5)) update_noderef(&regs[REG_EBP]);
     1694  if (node_regs_mask & (1<<6)) update_noderef(&regs[REG_ESI]);
     1695  if (node_regs_mask & (1<<7)) update_noderef(&regs[REG_EDI]);
     1696
     1697  update_locref(&(regs[Iip]));
     1698}
     1699#endif
    14011700
    14021701
     
    14091708  xp = tcr->gc_context;
    14101709  if (xp) {
     1710#ifdef X8664
    14111711    forward_xp(xp);
     1712#else
     1713    forward_xp(xp, tcr->node_regs_mask);
     1714
     1715    update_noderef(&tcr->save0);
     1716    update_noderef(&tcr->save1);
     1717    update_noderef(&tcr->save2);
     1718    update_noderef(&tcr->save3);
     1719#endif
    14121720  }
    14131721  for (xframes = tcr->xframe; xframes; xframes = xframes->prev) {
     1722#ifdef X8664
    14141723    forward_xp(xframes->curr);
    1415   }
    1416 }
    1417 
    1418 
    1419 
     1724#else
     1725    forward_xp(xframes->curr, xframes->node_regs_mask);
     1726#endif
     1727  }
     1728}
     1729
     1730
     1731#ifdef X8632
     1732void
     1733update_self_references(LispObj *node)
     1734{
     1735  LispObj fn = fulltag_misc + (LispObj)node;
     1736  unsigned char *p = (unsigned char *)node;
     1737  natural i, offset;
     1738
     1739  i = ((unsigned short *)node)[2];
     1740  offset = node[--i];
     1741  while (offset) {
     1742    *(LispObj *)(p + offset) = fn;
     1743    offset = node[--i];
     1744  }   
     1745}
     1746#endif
    14201747
    14211748/*
     
    14801807          dnode += node_dnodes;
    14811808          if (header_subtag(node) == subtag_function) {
     1809#ifdef X8632
     1810            int skip = *((unsigned short *)src);
     1811            LispObj *f = dest;
     1812#else
    14821813            int skip = *((int *)src);
     1814#endif
    14831815            *dest++ = node;
    14841816            elements -= skip;
     
    14861818              *dest++ = *src++;
    14871819            }
     1820#ifdef X8632
     1821            update_self_references(f);
     1822#endif
    14881823            while(elements--) {
    14891824              *dest++ = node_forwarding_address(*src++);
     
    15411876          tag = header_subtag(node);
    15421877
    1543 
     1878#ifdef X8664
    15441879          switch(fulltag_of(tag)) {
    15451880          case ivector_class_64_bit:
     
    15581893            }
    15591894          }
     1895#endif
     1896#ifdef X8632
     1897          if (tag <= max_32_bit_ivector_subtag) {
     1898            imm_dnodes = (((elements+1)+1)>>1);
     1899          } else if (tag <= max_8_bit_ivector_subtag) {
     1900            imm_dnodes = (((elements+4)+7)>>3);
     1901          } else if (tag <= max_16_bit_ivector_subtag) {
     1902            imm_dnodes = (((elements+2)+3)>>2);
     1903          } else if (tag == subtag_bit_vector) {
     1904            imm_dnodes = (((elements+32)+63)>>6);
     1905          } else {
     1906            imm_dnodes = elements+1;
     1907          }
     1908#endif
     1909
    15601910          dnode += imm_dnodes;
    15611911          while (--imm_dnodes) {
     
    15721922        }
    15731923      }
    1574  
    1575     }
    1576 
     1924    }
    15771925  }
    15781926  return ptr_to_lispobj(dest);
     
    16071955        subtag = header_subtag(header);
    16081956
     1957#ifdef X8664
    16091958        switch(fulltag_of(header)) {
    16101959        case ivector_class_64_bit:
     
    16241973          }
    16251974        }
     1975#endif
     1976#ifdef X8632
     1977          if (subtag <= max_32_bit_ivector_subtag) {
     1978            bytes = 4 + (elements<<2);
     1979          } else if (subtag <= max_8_bit_ivector_subtag) {
     1980            bytes = 4 + elements;
     1981          } else if (subtag <= max_16_bit_ivector_subtag) {
     1982            bytes = 4 + (elements<<1);
     1983          } else if (subtag == subtag_double_float_vector) {
     1984            bytes = 8 + (elements<<3);
     1985          } else {
     1986            bytes = 4 + ((elements+7)>>3);
     1987          }
     1988#endif
     1989
    16261990        bytes = (bytes+dnode_size-1) & ~(dnode_size-1);
    16271991        total += bytes;
     
    17852149        } else {
    17862150          if (header_subtag(header) == subtag_function) {
     2151#ifdef X8632
     2152            int skip = (unsigned short)(start[1]);
     2153#else
    17872154            int skip = (int)(start[1]);
     2155#endif
    17882156            start += skip;
    17892157            nwords -= skip;
Note: See TracChangeset for help on using the changeset viewer.