nativeCallStack.cpp revision 6853:91eeb8807a03
1/* 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25#include "precompiled.hpp" 26#include "runtime/os.hpp" 27#include "utilities/globalDefinitions.hpp" 28#include "utilities/nativeCallStack.hpp" 29 30 31NativeCallStack::NativeCallStack(int toSkip, bool fillStack) : 32 _hash_value(0) { 33 34#if !PLATFORM_NATIVE_STACK_WALKING_SUPPORTED 35 fillStack = false; 36#endif 37 38 if (fillStack) { 39 os::get_native_stack(_stack, NMT_TrackingStackDepth, toSkip); 40 } else { 41 for (int index = 0; index < NMT_TrackingStackDepth; index ++) { 42 _stack[index] = NULL; 43 } 44 } 45} 46 47NativeCallStack::NativeCallStack(address* pc, int frameCount) { 48 int frameToCopy = (frameCount < NMT_TrackingStackDepth) ? 49 frameCount : NMT_TrackingStackDepth; 50 int index; 51 for (index = 0; index < frameToCopy; index ++) { 52 _stack[index] = pc[index]; 53 } 54 for (; index < NMT_TrackingStackDepth; index ++) { 55 _stack[index] = NULL; 56 } 57} 58 59// number of stack frames captured 60int NativeCallStack::frames() const { 61 int index; 62 for (index = 0; index < NMT_TrackingStackDepth; index ++) { 63 if (_stack[index] == NULL) { 64 break; 65 } 66 } 67 return index; 68} 69 70// Hash code. Any better algorithm? 71int NativeCallStack::hash() const { 72 long hash_val = _hash_value; 73 if (hash_val == 0) { 74 long pc; 75 int index; 76 for (index = 0; index < NMT_TrackingStackDepth; index ++) { 77 pc = (long)_stack[index]; 78 if (pc == 0) break; 79 hash_val += pc; 80 } 81 82 NativeCallStack* p = const_cast<NativeCallStack*>(this); 83 p->_hash_value = (int)(hash_val & 0xFFFFFFFF); 84 } 85 return _hash_value; 86} 87 88void NativeCallStack::print_on(outputStream* out) const { 89 print_on(out, 0); 90} 91 92// Decode and print this call path 93void NativeCallStack::print_on(outputStream* out, int indent) const { 94 address pc; 95 char buf[1024]; 96 int offset; 97 if (is_empty()) { 98 for (int index = 0; index < indent; index ++) out->print(" "); 99#if PLATFORM_NATIVE_STACK_WALKING_SUPPORTED 100 out->print("[BOOTSTRAP]"); 101#else 102 out->print("[No stack]"); 103#endif 104 } else { 105 for (int frame = 0; frame < NMT_TrackingStackDepth; frame ++) { 106 pc = get_frame(frame); 107 if (pc == NULL) break; 108 // Print indent 109 for (int index = 0; index < indent; index ++) out->print(" "); 110 if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) { 111 out->print_cr("[" PTR_FORMAT "] %s+0x%x", p2i(pc), buf, offset); 112 } else { 113 out->print_cr("[" PTR_FORMAT "]", p2i(pc)); 114 } 115 } 116 } 117} 118 119