Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let jfr2flame support AOT #725

Open
xiejf2020 opened this issue Mar 14, 2023 · 2 comments
Open

Let jfr2flame support AOT #725

xiejf2020 opened this issue Mar 14, 2023 · 2 comments

Comments

@xiejf2020
Copy link

xiejf2020 commented Mar 14, 2023

@xiejf2020 How do you think AOT support should look like and what problem/question this should solve?

I hope there's a [aot_comp] in addition to [Interpreter], [c1_comp] and [c2_comp].

Currently, all code (including Interpreter and C1) seems to be identified as C2 when AOT is on (maybe the whole logic used to identify the compilation is broken due to AOT). The following program was run on OpenJDK16.

java -XX:+UnlockExperimentalVMOptions -XX:+UseAOT -XX:AOTLibrary=$PWD/whatever.so -jar spring-petclinic-2.7.3.jar

Whatever whatever.so is here (maybe even if it's an empty lib with no compiled code) results in all code being recognized as C2:

image

And this is the flamegraph without AOT (C1 and C2 are correctly identified):

image

I know there are probably not many people who use AOT, so if you don't have time to fix it, maybe give me some tips about how to fix it :)

Originally posted by @xiejf2020 in #719 (comment)

@xiejf2020
Copy link
Author

xiejf2020 commented Mar 14, 2023

I think I may have found (part of) the problem.

    static NMethod* findNMethod(const void* pc) {
        if (contains(_code_heap[0], pc)) return findNMethod(_code_heap[0], pc);
        if (contains(_code_heap[1], pc)) return findNMethod(_code_heap[1], pc);
        if (contains(_code_heap[2], pc)) return findNMethod(_code_heap[2], pc);
        return NULL;
    }

It cannot find code in aot_code_heap because it does not traverse all codeheaps, instead it traverses only the first three.

So it failed at:

    if (event_type == 0) {
        // Async events
        int java_frames = getJavaTraceAsync(ucontext, frames + num_frames, _max_stack_depth, &java_ctx);
        if (java_frames > 0 && java_ctx.pc != NULL && VMStructs::hasMethodStructs()) {
            NMethod* nmethod = CodeHeap::findNMethod(java_ctx.pc);  // <- here
            if (nmethod != NULL) {
                fillFrameTypes(frames + num_frames, java_frames, nmethod);
            }
        }
        num_frames += java_frames;
    }

But that cannot explain why the interpreter and C1 are also recognized as C2.

@xiejf2020
Copy link
Author

I see. The profiler won't init the _code_heap if code_heap_count > 3:

    if (_code_heap_addr != NULL && _code_heap_low_addr != NULL && _code_heap_high_addr != NULL) {
        char* code_heaps = *_code_heap_addr;
        unsigned int code_heap_count = *(unsigned int*)code_heaps;
        if (code_heap_count <= 3 && _array_data_offset >= 0) {
            char* code_heap_array = *(char**)(code_heaps + _array_data_offset);
            memcpy(_code_heap, code_heap_array, code_heap_count * sizeof(_code_heap[0]));
        }
        _code_heap_low = *_code_heap_low_addr;
        _code_heap_high = *_code_heap_high_addr;
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant