1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/utilities/nativeCallStack.cpp Wed Aug 27 08:19:12 2014 -0400 1.3 @@ -0,0 +1,118 @@ 1.4 +/* 1.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "runtime/os.hpp" 1.30 +#include "utilities/globalDefinitions.hpp" 1.31 +#include "utilities/nativeCallStack.hpp" 1.32 + 1.33 + 1.34 +NativeCallStack::NativeCallStack(int toSkip, bool fillStack) : 1.35 + _hash_value(0) { 1.36 + 1.37 +#if !PLATFORM_NATIVE_STACK_WALKING_SUPPORTED 1.38 + fillStack = false; 1.39 +#endif 1.40 + 1.41 + if (fillStack) { 1.42 + os::get_native_stack(_stack, NMT_TrackingStackDepth, toSkip); 1.43 + } else { 1.44 + for (int index = 0; index < NMT_TrackingStackDepth; index ++) { 1.45 + _stack[index] = NULL; 1.46 + } 1.47 + } 1.48 +} 1.49 + 1.50 +NativeCallStack::NativeCallStack(address* pc, int frameCount) { 1.51 + int frameToCopy = (frameCount < NMT_TrackingStackDepth) ? 1.52 + frameCount : NMT_TrackingStackDepth; 1.53 + int index; 1.54 + for (index = 0; index < frameToCopy; index ++) { 1.55 + _stack[index] = pc[index]; 1.56 + } 1.57 + for (; index < NMT_TrackingStackDepth; index ++) { 1.58 + _stack[index] = NULL; 1.59 + } 1.60 +} 1.61 + 1.62 +// number of stack frames captured 1.63 +int NativeCallStack::frames() const { 1.64 + int index; 1.65 + for (index = 0; index < NMT_TrackingStackDepth; index ++) { 1.66 + if (_stack[index] == NULL) { 1.67 + break; 1.68 + } 1.69 + } 1.70 + return index; 1.71 +} 1.72 + 1.73 +// Hash code. Any better algorithm? 1.74 +int NativeCallStack::hash() const { 1.75 + long hash_val = _hash_value; 1.76 + if (hash_val == 0) { 1.77 + long pc; 1.78 + int index; 1.79 + for (index = 0; index < NMT_TrackingStackDepth; index ++) { 1.80 + pc = (long)_stack[index]; 1.81 + if (pc == 0) break; 1.82 + hash_val += pc; 1.83 + } 1.84 + 1.85 + NativeCallStack* p = const_cast<NativeCallStack*>(this); 1.86 + p->_hash_value = (int)(hash_val & 0xFFFFFFFF); 1.87 + } 1.88 + return _hash_value; 1.89 +} 1.90 + 1.91 +void NativeCallStack::print_on(outputStream* out) const { 1.92 + print_on(out, 0); 1.93 +} 1.94 + 1.95 +// Decode and print this call path 1.96 +void NativeCallStack::print_on(outputStream* out, int indent) const { 1.97 + address pc; 1.98 + char buf[1024]; 1.99 + int offset; 1.100 + if (is_empty()) { 1.101 + for (int index = 0; index < indent; index ++) out->print(" "); 1.102 +#if PLATFORM_NATIVE_STACK_WALKING_SUPPORTED 1.103 + out->print("[BOOTSTRAP]"); 1.104 +#else 1.105 + out->print("[No stack]"); 1.106 +#endif 1.107 + } else { 1.108 + for (int frame = 0; frame < NMT_TrackingStackDepth; frame ++) { 1.109 + pc = get_frame(frame); 1.110 + if (pc == NULL) break; 1.111 + // Print indent 1.112 + for (int index = 0; index < indent; index ++) out->print(" "); 1.113 + if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) { 1.114 + out->print_cr("[" PTR_FORMAT "] %s+0x%x", p2i(pc), buf, offset); 1.115 + } else { 1.116 + out->print_cr("[" PTR_FORMAT "]", p2i(pc)); 1.117 + } 1.118 + } 1.119 + } 1.120 +} 1.121 +