Called whenever our breakpoint trap is hit
| 47 | |
| 48 | // Called whenever our breakpoint trap is hit |
| 49 | void AllocTracer::trapHandler(int signo, siginfo_t* siginfo, void* ucontext) { |
| 50 | StackFrame frame(ucontext); |
| 51 | EventType event_type; |
| 52 | uintptr_t total_size; |
| 53 | uintptr_t instance_size; |
| 54 | |
| 55 | // PC points either to BREAKPOINT instruction or to the next one |
| 56 | if (_in_new_tlab.covers(frame.pc())) { |
| 57 | // send_allocation_in_new_tlab(Klass* klass, HeapWord* obj, size_t tlab_size, size_t alloc_size, Thread* thread) |
| 58 | // send_allocation_in_new_tlab_event(KlassHandle klass, size_t tlab_size, size_t alloc_size) |
| 59 | event_type = ALLOC_SAMPLE; |
| 60 | total_size = _trap_kind == 1 ? frame.arg2() : frame.arg1(); |
| 61 | instance_size = _trap_kind == 1 ? frame.arg3() : frame.arg2(); |
| 62 | } else if (_outside_tlab.covers(frame.pc())) { |
| 63 | // send_allocation_outside_tlab(Klass* klass, HeapWord* obj, size_t alloc_size, Thread* thread) |
| 64 | // send_allocation_outside_tlab_event(KlassHandle klass, size_t alloc_size); |
| 65 | event_type = ALLOC_OUTSIDE_TLAB; |
| 66 | total_size = _trap_kind == 1 ? frame.arg2() : frame.arg1(); |
| 67 | instance_size = 0; |
| 68 | } else { |
| 69 | // Not our trap |
| 70 | Profiler::instance()->trapHandler(signo, siginfo, ucontext); |
| 71 | return; |
| 72 | } |
| 73 | |
| 74 | // Leave the trapped function by simulating "ret" instruction |
| 75 | uintptr_t klass = frame.arg0(); |
| 76 | frame.ret(); |
| 77 | |
| 78 | if (_enabled && updateCounter(_allocated_bytes, total_size, _interval)) { |
| 79 | recordAllocation(ucontext, event_type, klass, total_size, instance_size); |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | void AllocTracer::recordAllocation(void* ucontext, EventType event_type, uintptr_t rklass, |
| 84 | uintptr_t total_size, uintptr_t instance_size) { |