Guest User

Untitled

a guest
Feb 11th, 2018
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.89 KB | None | 0 0
  1. /*
  2. * Copyright 2017 Andrei Pangin
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16.  
  17. #include <stdint.h>
  18. #include <sys/mman.h>
  19. #include "allocTracer.h"
  20. #include "codeCache.h"
  21. #include "profiler.h"
  22. #include "stackFrame.h"
  23. #include "vmStructs.h"
  24.  
  25.  
  26. Trap AllocTracer::_in_new_tlab("_ZN11AllocTracer33send_allocation_in_new_tlab_event");
  27. Trap AllocTracer::_outside_tlab("_ZN11AllocTracer34send_allocation_outside_tlab_event");
  28.  
  29.  
  30. // Make the entry point writeable and insert breakpoint at the very first instruction
  31. void Trap::install() {
  32. uintptr_t page_start = (uintptr_t)_entry & ~PAGE_MASK;
  33. mprotect((void*)page_start, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC);
  34.  
  35. _saved_insn = *_entry;
  36. *_entry = BREAKPOINT;
  37. flushCache(_entry);
  38. }
  39.  
  40. // Clear breakpoint - restore the original instruction
  41. void Trap::uninstall() {
  42. *_entry = _saved_insn;
  43. flushCache(_entry);
  44. }
  45.  
  46.  
  47. void AllocTracer::installSignalHandler() {
  48. struct sigaction sa;
  49. sigemptyset(&sa.sa_mask);
  50. sa.sa_handler = NULL;
  51. sa.sa_sigaction = signalHandler;
  52. sa.sa_flags = SA_RESTART | SA_SIGINFO;
  53.  
  54. sigaction(SIGTRAP, &sa, NULL);
  55. }
  56.  
  57. // Called whenever our breakpoint trap is hit
  58. void AllocTracer::signalHandler(int signo, siginfo_t* siginfo, void* ucontext) {
  59. StackFrame frame(ucontext);
  60.  
  61. // PC points either to BREAKPOINT instruction or to the next one
  62. if (frame.pc() - (uintptr_t)_in_new_tlab._entry <= sizeof(instruction_t)) {
  63. // send_allocation_in_new_tlab_event(KlassHandle klass, size_t tlab_size, size_t alloc_size)
  64. jmethodID alloc_class = (jmethodID)frame.arg0();
  65. u64 obj_size = frame.arg2();
  66. u64 tlab_size = frame.arg1();
  67. Profiler::_instance.recordSample(ucontext, obj_size + tlab_size, BCI_KLASS, alloc_class);
  68. } else if (frame.pc() - (uintptr_t)_outside_tlab._entry <= sizeof(instruction_t)) {
  69. // send_allocation_outside_tlab_event(KlassHandle klass, size_t alloc_size);
  70. // Invert last bit to distinguish jmethodID from the allocation in new TLAB
  71. jmethodID alloc_class = (jmethodID)(frame.arg0() ^ 1);
  72. u64 obj_size = frame.arg1();
  73. Profiler::_instance.recordSample(ucontext, obj_size, BCI_KLASS_OUTSIDE_TLAB, alloc_class);
  74. } else {
  75. // Not our trap; nothing to do
  76. return;
  77. }
  78.  
  79. // Leave the trapped function by simulating "ret" instruction
  80. frame.ret();
  81. }
  82.  
  83. Error AllocTracer::start(const char* event, long interval) {
  84. NativeCodeCache* libjvm = Profiler::_instance.jvmLibrary();
  85. if (libjvm == NULL) {
  86. return Error("libjvm not found among loaded libraries");
  87. }
  88.  
  89. if (!VMStructs::init(libjvm)) {
  90. return Error("VMStructs unavailable. Unsupported JVM?");
  91. }
  92.  
  93. if (_in_new_tlab._entry == NULL || _outside_tlab._entry == NULL) {
  94. _in_new_tlab._entry = (instruction_t*)libjvm->findSymbol(_in_new_tlab._func_name);
  95. _outside_tlab._entry = (instruction_t*)libjvm->findSymbol(_outside_tlab._func_name);
  96. if (_in_new_tlab._entry == NULL || _outside_tlab._entry == NULL) {
  97. return Error("No AllocTracer symbols found. Are JDK debug symbols installed?");
  98. }
  99. }
  100.  
  101. installSignalHandler();
  102.  
  103. _in_new_tlab.install();
  104. _outside_tlab.install();
  105.  
  106. return Error::OK;
  107. }
  108.  
  109. void AllocTracer::stop() {
  110. _in_new_tlab.uninstall();
  111. _outside_tlab.uninstall();
  112. }
Advertisement
Add Comment
Please, Sign In to add comment