WIP: Support profiling in ghc-heap
Needs ReviewPublic

Authored by mpickering on Oct 11 2018, 9:53 AM.

Details

Reviewers
bgamari
osa1
Trac Issues
#15735
Summary

Currently the fields are populated by garbage as the offset seems wrong.

mpickering created this revision.Oct 11 2018, 9:53 AM
  • Correct the offset calculation, now working

I made some progress, it no longer prints out garbage but the result looks wrong.

Running the following code:

let !con = Just 1                                                           
getClosureData con >>= print . prof . info

prints out...

Just (StgProfInfo {closure_type = "", closure_desc = "HC.Maybe.Nothing"})

which looks quite wrong but I don't know what it should be.

osa1 added a comment.Oct 12 2018, 7:13 AM

What does it show if you print return value of getClosureData con? I'm asking because you don't know in this code that con points to a constructor without any indirections. For example, GHC can float con to the top-level and make it a CAF, in which case con might point to a IND_STATIC, not to a CONSTR_1_0.

The output still looks weird, but perhaps this is still the correct prof info and we just generate weird prof info for IND_STATICs.

I also checked the peek code and it looks correct to me for the TABLES_NEXT_TO_CODE case (it's not correct otherwise, but I'm guessing that's because this is WIP). The code would be simpler if you could use #peek instead of manually calculating the offsets (not sure if #peek can offset nested structs though).

In D5223#143889, @osa1 wrote:

What does it show if you print return value of getClosureData con? I'm asking because you don't know in this code that con points to a constructor without any indirections. For example, GHC can float con to the top-level and make it a CAF, in which case con might point to a IND_STATIC, not to a CONSTR_1_0.

The module is compiled with -O0 so this shouldn't happen?

The output you requested is:

+ConstrClosure {info = StgInfoTable {entry = Nothing, prof = Just (StgProfInfo {closure_type = "", closure_desc = "HC.Maybe.Nothing"}), ptrs = 1, nptrs = 0, tipe = CONSTR_1_0, srtlen = 1, code = Nothing}, ptrArgs = [0x0000004200104a38/1], dataArgs = [], pkg = "base", modl = "GHC.Maybe", name = "Just"}

The output still looks weird, but perhaps this is still the correct prof info and we just generate weird prof info for IND_STATICs.

There's a possibility of a bug here, seeing that there is some answer but it's wrong (and we're dealing with pointer arithmetic) indicates to me that the info is wrong to begin with.

I also checked the peek code and it looks correct to me for the TABLES_NEXT_TO_CODE case (it's not correct otherwise, but I'm guessing that's because this is WIP). The code would be simpler if you could use #peek instead of manually calculating the offsets (not sure if #peek can offset nested structs though).

Yes, I will fix that once I get the basics working.

bgamari added inline comments.Oct 15 2018, 11:44 AM
libraries/ghc-heap/GHC/Exts/Heap/InfoTableProf.hsc
27

I'm actually quite confused; this comment doesn't even look right. We entry' ends up being Nothing in the TNTC case.

39

I suspect this is your issue: I think you need to offset ptr by the size of StgInfoTable as well. Here is a more readable transcription of GET_PROF_TYPE:

INLINE_HEADER char *GET_PROF_TYPE(StgInfoTable *info) {
#if defined(TABLES_NEXT_TO_CODE)
    StgWord base = (StgWord) (info + 1);
    return (char *)(base + info->prof.closure_type_off);
#else
    return info->prof.closure_type;
#endif
}

Notice the info + 1.

mpickering added inline comments.Oct 15 2018, 2:33 PM
libraries/ghc-heap/GHC/Exts/Heap/InfoTableProf.hsc
27

This confused me as well but I put it down to a lack of understanding.

39

I don't understand what info I am currently reading then? With this code I expected one of three outcomes.

  1. Segfault
  2. Garbage
  3. The correct answer

and instead we end up with 4. An incorrect answer!