interfaceSupport.cpp revision 1879:f95d63e2154a
11541Srgrimes/* 21541Srgrimes * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 31541Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41541Srgrimes * 51541Srgrimes * This code is free software; you can redistribute it and/or modify it 61541Srgrimes * under the terms of the GNU General Public License version 2 only, as 71541Srgrimes * published by the Free Software Foundation. 81541Srgrimes * 91541Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT 101541Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 111541Srgrimes * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 121541Srgrimes * version 2 for more details (a copy is included in the LICENSE file that 131541Srgrimes * accompanied this code). 141541Srgrimes * 151541Srgrimes * You should have received a copy of the GNU General Public License version 161541Srgrimes * 2 along with this work; if not, write to the Free Software Foundation, 171541Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 181541Srgrimes * 191541Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 201541Srgrimes * or visit www.oracle.com if you need additional information or have any 211541Srgrimes * questions. 221541Srgrimes * 231541Srgrimes */ 241541Srgrimes 251541Srgrimes#include "precompiled.hpp" 261541Srgrimes#include "gc_implementation/shared/markSweep.hpp" 271541Srgrimes#include "gc_interface/collectedHeap.hpp" 281541Srgrimes#include "gc_interface/collectedHeap.inline.hpp" 291541Srgrimes#include "memory/genCollectedHeap.hpp" 301541Srgrimes#include "memory/resourceArea.hpp" 311541Srgrimes#include "runtime/init.hpp" 321541Srgrimes#include "runtime/interfaceSupport.hpp" 331541Srgrimes#include "runtime/threadLocalStorage.hpp" 341541Srgrimes#include "runtime/vframe.hpp" 351541Srgrimes#include "utilities/preserveException.hpp" 361541Srgrimes 371541Srgrimes 3844510Swollman// Implementation of InterfaceSupport 3950477Speter 401541Srgrimes#ifdef ASSERT 411541Srgrimes 421541Srgrimeslong InterfaceSupport::_number_of_calls = 0; 431541Srgrimeslong InterfaceSupport::_scavenge_alot_counter = 1; 4433392Sphklong InterfaceSupport::_fullgc_alot_counter = 1; 451541Srgrimeslong InterfaceSupport::_fullgc_alot_invocation = 0; 461541Srgrimes 4733392SphkHistogram* RuntimeHistogram; 4833392Sphk 4933392SphkRuntimeHistogramElement::RuntimeHistogramElement(const char* elementName) { 5033392Sphk static volatile jint RuntimeHistogram_lock = 0; 5133392Sphk _name = elementName; 5233392Sphk uintx count = 0; 5329680Sgibbs 5429680Sgibbs while (Atomic::cmpxchg(1, &RuntimeHistogram_lock, 0) != 0) { 5529680Sgibbs while (OrderAccess::load_acquire(&RuntimeHistogram_lock) != 0) { 5629680Sgibbs count +=1; 5733392Sphk if ( (WarnOnStalledSpinLock > 0) 582112Swollman && (count % WarnOnStalledSpinLock == 0)) { 5929680Sgibbs warning("RuntimeHistogram_lock seems to be stalled"); 601541Srgrimes } 611541Srgrimes } 6229680Sgibbs } 6329680Sgibbs 6429680Sgibbs if (RuntimeHistogram == NULL) { 6529680Sgibbs RuntimeHistogram = new Histogram("VM Runtime Call Counts",200); 6629680Sgibbs } 6729680Sgibbs 6829680Sgibbs RuntimeHistogram->add_element(this); 6929680Sgibbs Atomic::dec(&RuntimeHistogram_lock); 7029680Sgibbs} 7129680Sgibbs 7232388Sphkvoid InterfaceSupport::trace(const char* result_type, const char* header) { 7329680Sgibbs tty->print_cr("%6d %s", _number_of_calls, header); 741541Srgrimes} 751541Srgrimes 761541Srgrimesvoid InterfaceSupport::gc_alot() { 771541Srgrimes Thread *thread = Thread::current(); 7832391Sphk if (!thread->is_Java_thread()) return; // Avoid concurrent calls 791541Srgrimes // Check for new, not quite initialized thread. A thread in new mode cannot initiate a GC. 801541Srgrimes JavaThread *current_thread = (JavaThread *)thread; 8129805Sgibbs if (current_thread->active_handles() == NULL) return; 821541Srgrimes 8329805Sgibbs // Short-circuit any possible re-entrant gc-a-lot attempt 8433392Sphk if (thread->skip_gcalot()) return; 851541Srgrimes 8633392Sphk if (is_init_completed()) { 8733392Sphk 8833392Sphk if (++_fullgc_alot_invocation < FullGCALotStart) { 8929680Sgibbs return; 9029680Sgibbs } 911541Srgrimes 9229680Sgibbs // Use this line if you want to block at a specific point, 9329805Sgibbs // e.g. one number_of_calls/scavenge/gc before you got into problems 9429805Sgibbs if (FullGCALot) _fullgc_alot_counter--; 9529805Sgibbs 9629805Sgibbs // Check if we should force a full gc 9729805Sgibbs if (_fullgc_alot_counter == 0) { 9829805Sgibbs // Release dummy so objects are forced to move 9929805Sgibbs if (!Universe::release_fullgc_alot_dummy()) { 10029805Sgibbs warning("FullGCALot: Unable to release more dummies at bottom of heap"); 10129680Sgibbs } 10229805Sgibbs HandleMark hm(thread); 10329680Sgibbs Universe::heap()->collect(GCCause::_full_gc_alot); 10429680Sgibbs unsigned int invocations = Universe::heap()->total_full_collections(); 10529680Sgibbs // Compute new interval 10629680Sgibbs if (FullGCALotInterval > 1) { 10729805Sgibbs _fullgc_alot_counter = 1+(long)((double)FullGCALotInterval*os::random()/(max_jint+1.0)); 10829680Sgibbs if (PrintGCDetails && Verbose) { 10929680Sgibbs tty->print_cr("Full gc no: %u\tInterval: %d", invocations, 11029680Sgibbs _fullgc_alot_counter); 11129680Sgibbs } 11229680Sgibbs } else { 11329680Sgibbs _fullgc_alot_counter = 1; 11429680Sgibbs } 11529680Sgibbs // Print progress message 11629680Sgibbs if (invocations % 100 == 0) { 11729680Sgibbs if (PrintGCDetails && Verbose) tty->print_cr("Full gc no: %u", invocations); 11829805Sgibbs } 11929680Sgibbs } else { 12029680Sgibbs if (ScavengeALot) _scavenge_alot_counter--; 12129680Sgibbs // Check if we should force a scavenge 12244510Swollman if (_scavenge_alot_counter == 0) { 12344510Swollman HandleMark hm(thread); 12444510Swollman Universe::heap()->collect(GCCause::_scavenge_alot); 12544510Swollman unsigned int invocations = Universe::heap()->total_collections() - Universe::heap()->total_full_collections(); 12644510Swollman // Compute new interval 12744510Swollman if (ScavengeALotInterval > 1) { 12850673Sjlemon _scavenge_alot_counter = 1+(long)((double)ScavengeALotInterval*os::random()/(max_jint+1.0)); 12944510Swollman if (PrintGCDetails && Verbose) { 13029680Sgibbs tty->print_cr("Scavenge no: %u\tInterval: %d", invocations, 13129680Sgibbs _scavenge_alot_counter); 13229680Sgibbs } 13329680Sgibbs } else { 13429680Sgibbs _scavenge_alot_counter = 1; 13529680Sgibbs } 13629680Sgibbs // Print progress message 1371541Srgrimes if (invocations % 1000 == 0) { 13829680Sgibbs if (PrintGCDetails && Verbose) tty->print_cr("Scavenge no: %u", invocations); 1391541Srgrimes } 1401541Srgrimes } 1411541Srgrimes } 1421541Srgrimes } 1431541Srgrimes} 1441541Srgrimes 1451541Srgrimes 1461541Srgrimesvframe* vframe_array[50]; 1471541Srgrimesint walk_stack_counter = 0; 1481541Srgrimes 14929680Sgibbsvoid InterfaceSupport::walk_stack_from(vframe* start_vf) { 15029680Sgibbs // walk 15129680Sgibbs int i = 0; 1521541Srgrimes for (vframe* f = start_vf; f; f = f->sender() ) { 15329680Sgibbs if (i < 50) vframe_array[i++] = f; 15429680Sgibbs } 15529680Sgibbs} 15629680Sgibbs 1571541Srgrimes 15829680Sgibbsvoid InterfaceSupport::walk_stack() { 15929680Sgibbs JavaThread* thread = JavaThread::current(); 16033824Sbde walk_stack_counter++; 1611541Srgrimes if (!thread->has_last_Java_frame()) return; 16229680Sgibbs ResourceMark rm(thread); 1631541Srgrimes RegisterMap reg_map(thread); 16429680Sgibbs walk_stack_from(thread->last_java_vframe(®_map)); 16529680Sgibbs} 16629680Sgibbs 1671541Srgrimes 1681541Srgrimes# ifdef ENABLE_ZAP_DEAD_LOCALS 1691541Srgrimes 1701541Srgrimesstatic int zap_traversals = 0; 17129680Sgibbs 17229680Sgibbsvoid InterfaceSupport::zap_dead_locals_old() { 17329680Sgibbs JavaThread* thread = JavaThread::current(); 1741541Srgrimes if (zap_traversals == -1) // edit constant for debugging 17529680Sgibbs warning("I am here"); 17644510Swollman int zap_frame_count = 0; // count frames to help debugging 17744510Swollman for (StackFrameStream sfs(thread); !sfs.is_done(); sfs.next()) { 1781541Srgrimes sfs.current()->zap_dead_locals(thread, sfs.register_map()); 17944510Swollman ++zap_frame_count; 1801541Srgrimes } 18129680Sgibbs ++zap_traversals; 1821541Srgrimes} 1831541Srgrimes 1841541Srgrimes# endif 18529680Sgibbs 18633824Sbde 1871541Srgrimesint deoptimizeAllCounter = 0; 18829680Sgibbsint zombieAllCounter = 0; 1891541Srgrimes 1901541Srgrimes 1911541Srgrimesvoid InterfaceSupport::zombieAll() { 19229680Sgibbs if (is_init_completed() && zombieAllCounter > ZombieALotInterval) { 19329680Sgibbs zombieAllCounter = 0; 19429680Sgibbs VM_ZombieAll op; 19529680Sgibbs VMThread::execute(&op); 19629680Sgibbs } else { 19729680Sgibbs zombieAllCounter++; 19829680Sgibbs } 19929680Sgibbs} 2001541Srgrimes 20144510Swollmanvoid InterfaceSupport::deoptimizeAll() { 20244510Swollman if (is_init_completed() ) { 2031541Srgrimes if (DeoptimizeALot && deoptimizeAllCounter > DeoptimizeALotInterval) { 2041541Srgrimes deoptimizeAllCounter = 0; 2051541Srgrimes VM_DeoptimizeAll op; 20624101Sbde VMThread::execute(&op); 20729680Sgibbs } else if (DeoptimizeRandom && (deoptimizeAllCounter & 0x1f) == (os::random() & 0x1f)) { 20829680Sgibbs VM_DeoptimizeAll op; 20929680Sgibbs VMThread::execute(&op); 21029680Sgibbs } 21129680Sgibbs } 21244510Swollman deoptimizeAllCounter++; 21344510Swollman} 21444510Swollman 21544510Swollman 21644510Swollmanvoid InterfaceSupport::stress_derived_pointers() { 21744510Swollman#ifdef COMPILER2 21844510Swollman JavaThread *thread = JavaThread::current(); 21944510Swollman if (!is_init_completed()) return; 22050673Sjlemon ResourceMark rm(thread); 22144510Swollman bool found = false; 22250673Sjlemon for (StackFrameStream sfs(thread); !sfs.is_done() && !found; sfs.next()) { 22350673Sjlemon CodeBlob* cb = sfs.current()->cb(); 22450673Sjlemon if (cb != NULL && cb->oop_maps() ) { 22544510Swollman // Find oopmap for current method 22644510Swollman OopMap* map = cb->oop_map_for_return_address(sfs.current()->pc()); 22744510Swollman assert(map != NULL, "no oopmap found for pc"); 22844510Swollman found = map->has_derived_pointer(); 22944510Swollman } 23044510Swollman } 23144510Swollman if (found) { 23244510Swollman // $$$ Not sure what to do here. 23344510Swollman /* 23444510Swollman Scavenge::invoke(0); 23544510Swollman */ 23644510Swollman } 23744510Swollman#endif 23844510Swollman} 23944510Swollman 24044510Swollman 24144510Swollmanvoid InterfaceSupport::verify_stack() { 24250673Sjlemon JavaThread* thread = JavaThread::current(); 24344510Swollman ResourceMark rm(thread); 24444510Swollman // disabled because it throws warnings that oop maps should only be accessed 24544510Swollman // in VM thread or during debugging 24644510Swollman 24744510Swollman if (!thread->has_pending_exception()) { 24850673Sjlemon // verification does not work if there are pending exceptions 24944510Swollman StackFrameStream sfs(thread); 25044510Swollman CodeBlob* cb = sfs.current()->cb(); 25144510Swollman // In case of exceptions we might not have a runtime_stub on 25244510Swollman // top of stack, hence, all callee-saved registers are not going 25344510Swollman // to be setup correctly, hence, we cannot do stack verify 25444510Swollman if (cb != NULL && !(cb->is_runtime_stub() || cb->is_uncommon_trap_stub())) return; 25544510Swollman 25644510Swollman for (; !sfs.is_done(); sfs.next()) { 25744510Swollman sfs.current()->verify(sfs.register_map()); 25844510Swollman } 25944510Swollman } 26044510Swollman} 26144510Swollman 26244510Swollman 26344510Swollmanvoid InterfaceSupport::verify_last_frame() { 26444510Swollman JavaThread* thread = JavaThread::current(); 26544510Swollman ResourceMark rm(thread); 26644510Swollman RegisterMap reg_map(thread); 26744510Swollman frame fr = thread->last_frame(); 26850673Sjlemon fr.verify(®_map); 26944510Swollman} 27044510Swollman 27144510Swollman 27250673Sjlemon#endif // ASSERT 27344510Swollman 27444510Swollman 27544510Swollmanvoid InterfaceSupport_init() { 27644510Swollman#ifdef ASSERT 27744510Swollman if (ScavengeALot || FullGCALot) { 27844510Swollman srand(ScavengeALotInterval * FullGCALotInterval); 27944510Swollman } 28044510Swollman#endif 28144510Swollman} 28244510Swollman