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!

Do you intend on continuing work on this, @mpickering?

No, but the code is here for anyone to use if they wish.