-/* dseg_addlinenumbertablesize *************************************************
-
- XXX
-
-*******************************************************************************/
-
-void dseg_addlinenumbertablesize(codegendata *cd)
-{
-#if SIZEOF_VOID_P == 8
- /* 4-byte ALIGNMENT PADDING */
-
- dseg_add_unique_s4(cd, 0);
-#endif
-
- cd->linenumbertablesizepos = dseg_add_unique_address(cd, NULL);
- cd->linenumbertablestartpos = dseg_add_unique_address(cd, NULL);
-
-#if SIZEOF_VOID_P == 8
- /* 4-byte ALIGNMENT PADDING */
-
- dseg_add_unique_s4(cd, 0);
-#endif
-}
-
-
-/* dseg_addlinenumber **********************************************************
-
- Add a line number reference.
-
- IN:
- cd.............current codegen data
- linenumber.....number of line that starts with the given mcodeptr
- mcodeptr.......start mcodeptr of line
-
-*******************************************************************************/
-
-void dseg_addlinenumber(codegendata *cd, u2 linenumber)
-{
- linenumberref *lr;
-
- lr = DNEW(linenumberref);
-
- lr->linenumber = linenumber;
- lr->tablepos = 0;
- lr->targetmpc = cd->mcodeptr - cd->mcodebase;
- lr->next = cd->linenumberreferences;
-
- cd->linenumberreferences = lr;
-}
-
-
-/* dseg_addlinenumber_inline_start *********************************************
-
- Add a marker to the line number table indicating the start of an inlined
- method body. (see doc/inlining_stacktrace.txt)
-
- IN:
- cd.............current codegen data
- iptr...........the ICMD_INLINE_START instruction
- mcodeptr.......start mcodeptr of inlined body
-
-*******************************************************************************/
-
-void dseg_addlinenumber_inline_start(codegendata *cd, instruction *iptr)
-{
- linenumberref *lr;
- insinfo_inline *insinfo;
- ptrint mpc;
-
- lr = DNEW(linenumberref);
-
- lr->linenumber = (-2); /* marks start of inlined method */
- lr->tablepos = 0;
- lr->targetmpc = (mpc = (u1 *) cd->mcodeptr - cd->mcodebase);
- lr->next = cd->linenumberreferences;
-
- cd->linenumberreferences = lr;
-
- insinfo = iptr->sx.s23.s3.inlineinfo;
-
- insinfo->startmpc = mpc; /* store for corresponding INLINE_END */
-}
-
-
-/* dseg_addlinenumber_inline_end ***********************************************
-
- Add a marker to the line number table indicating the end of an inlined
- method body. (see doc/inlining_stacktrace.txt)
-
- IN:
- cd.............current codegen data
- iptr...........the ICMD_INLINE_END instruction
-
- Note:
- iptr->method must point to the inlined callee.
-
-*******************************************************************************/
-
-void dseg_addlinenumber_inline_end(codegendata *cd, instruction *iptr)
-{
- linenumberref *lr;
- linenumberref *prev;
- insinfo_inline *insinfo;
-
- insinfo = iptr->sx.s23.s3.inlineinfo;
-
- assert(insinfo);
-
- lr = DNEW(linenumberref);
-
- /* special entry containing the methodinfo * */
- lr->linenumber = (-3) - iptr->line;
- lr->tablepos = 0;
- lr->targetmpc = (ptrint) insinfo->method;
- lr->next = cd->linenumberreferences;
-
- prev = lr;
- lr = DNEW(linenumberref);
-
- /* end marker with PC of start of body */
- lr->linenumber = (-1);
- lr->tablepos = 0;
- lr->targetmpc = insinfo->startmpc;
- lr->next = prev;
-
- cd->linenumberreferences = lr;
-}
-
-
-/* dseg_createlinenumbertable **************************************************
-
- Creates a line number table in the data segment from the created
- entries in linenumberreferences.
-
-*******************************************************************************/
-
-void dseg_createlinenumbertable(codegendata *cd)
-{
- linenumberref *lr;
-
- for (lr = cd->linenumberreferences; lr != NULL; lr = lr->next) {
- lr->tablepos = dseg_add_unique_address(cd, NULL);
-
- if (cd->linenumbertab == 0)
- cd->linenumbertab = lr->tablepos;
-
-#if SIZEOF_VOID_P == 8
- /* This is for alignment and easier usage. */
- (void) dseg_add_unique_s8(cd, lr->linenumber);
-#else
- (void) dseg_add_unique_s4(cd, lr->linenumber);
-#endif
- }
-}
-
-
-/* dseg_get_linenumber_from_pc_intern ******************************************
-
- This function search the line number table for the line
- corresponding to a given pc. The function recurses for inlined
- methods.
-
-*******************************************************************************/
-
-static s4 dseg_get_linenumber_from_pc_intern(methodinfo **pm, linenumbertable_entry *lntentry, s4 lntsize, u1 *pc)
-{
- linenumbertable_entry *lntinline; /* special entry for inlined method */
-
- for (; lntsize > 0; lntsize--, lntentry--) {
- /* did we reach the current line? */
-
- /* Note: In case of inlining this may actually compare the pc
- against a methodinfo *, yielding a non-sensical
- result. This is no problem, however, as we ignore such
- entries in the switch below. This way we optimize for the
- common case (ie. a real pc in lntentry->pc). */
-
- if (pc >= lntentry->pc) {
- /* check for special inline entries (see
- doc/inlining_stacktrace.txt for details */
-
- if ((s4) lntentry->line < 0) {
- switch (lntentry->line) {
- case -1:
- /* begin of inlined method (ie. INLINE_END
- instruction) */
-
- lntinline = --lntentry;/* get entry with methodinfo * */
- lntentry--; /* skip the special entry */
- lntsize -= 2;
-
- /* search inside the inlined method */
-
- if (dseg_get_linenumber_from_pc_intern(pm,
- lntentry,
- lntsize,
- pc))
- {
- /* the inlined method contained the pc */
-
- *pm = (methodinfo *) lntinline->pc;
-
- assert(lntinline->line <= -3);
-
- return (-3) - lntinline->line;
- }
-
- /* pc was not in inlined method, continue
- search. Entries inside the inlined method
- will be skipped because their lntentry->pc
- is higher than pc. */
- break;
-
- case -2:
- /* end of inlined method */
-
- return 0;
-
- /* default: is only reached for an -3-line entry
- after a skipped -2 entry. We can safely ignore
- it and continue searching. */
- }
- }
- else {
- /* found a normal entry */
-
- return (s4) lntentry->line;
- }
- }
- }
-
- /* not found, return 0 */
-
- return 0;
-}
-
-
-/* dseg_get_linenumber_from_pc *************************************************
-
- A wrapper for dseg_get_linenumber_from_pc_intern, so we don't have
- to evaluate the method header on every call.
-
-*******************************************************************************/
-
-s4 dseg_get_linenumber_from_pc(methodinfo **pm, u1 *pv, u1 *pc)
-{
- ptrint lntsize; /* size of line number table */
- u1 *lntstart; /* start of line number table */
- linenumbertable_entry *lntentry; /* points to last entry in the table */
- s4 linenumber;
-
- /* get size of line number table */
-
- lntsize = *((ptrint *) (pv + LineNumberTableSize));
- lntstart = *((u1 **) (pv + LineNumberTableStart));
-
- /* Subtract the size of the line number entry of the structure,
- since the line number table start points to the pc. */
-
- lntentry = (linenumbertable_entry *) (lntstart - SIZEOF_VOID_P);
-
- /* get the line number */
-
- linenumber = dseg_get_linenumber_from_pc_intern(pm, lntentry, lntsize, pc);
-
- return linenumber;
-}
-
-