src/share/vm/runtime/interfaceSupport.cpp

Thu, 22 May 2014 15:52:41 -0400

author
drchase
date
Thu, 22 May 2014 15:52:41 -0400
changeset 6680
78bbf4d43a14
parent 2708
1d1603768966
child 6876
710a3c8b516e
child 6911
ce8f6bb717c9
permissions
-rw-r--r--

8037816: Fix for 8036122 breaks build with Xcode5/clang
8043029: Change 8037816 breaks HS build with older GCC versions which don't support diagnostic pragmas
8043164: Format warning in traceStream.hpp
Summary: Backport of main fix + two corrections, enables clang compilation, turns on format attributes, corrects/mutes warnings
Reviewed-by: kvn, coleenp, iveresov, twisti

     1 /*
     2  * Copyright (c) 1997, 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  */
    25 #include "precompiled.hpp"
    26 #include "gc_implementation/shared/markSweep.hpp"
    27 #include "gc_interface/collectedHeap.hpp"
    28 #include "gc_interface/collectedHeap.inline.hpp"
    29 #include "memory/genCollectedHeap.hpp"
    30 #include "memory/resourceArea.hpp"
    31 #include "runtime/init.hpp"
    32 #include "runtime/interfaceSupport.hpp"
    33 #include "runtime/threadLocalStorage.hpp"
    34 #include "runtime/vframe.hpp"
    35 #include "utilities/preserveException.hpp"
    37 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
    39 // Implementation of InterfaceSupport
    41 #ifdef ASSERT
    43 long InterfaceSupport::_number_of_calls       = 0;
    44 long InterfaceSupport::_scavenge_alot_counter = 1;
    45 long InterfaceSupport::_fullgc_alot_counter   = 1;
    46 long InterfaceSupport::_fullgc_alot_invocation = 0;
    48 Histogram* RuntimeHistogram;
    50 RuntimeHistogramElement::RuntimeHistogramElement(const char* elementName) {
    51   static volatile jint RuntimeHistogram_lock = 0;
    52   _name = elementName;
    53   uintx count = 0;
    55   while (Atomic::cmpxchg(1, &RuntimeHistogram_lock, 0) != 0) {
    56     while (OrderAccess::load_acquire(&RuntimeHistogram_lock) != 0) {
    57       count +=1;
    58       if ( (WarnOnStalledSpinLock > 0)
    59         && (count % WarnOnStalledSpinLock == 0)) {
    60         warning("RuntimeHistogram_lock seems to be stalled");
    61       }
    62     }
    63   }
    65   if (RuntimeHistogram == NULL) {
    66     RuntimeHistogram = new Histogram("VM Runtime Call Counts",200);
    67   }
    69   RuntimeHistogram->add_element(this);
    70   Atomic::dec(&RuntimeHistogram_lock);
    71 }
    73 void InterfaceSupport::trace(const char* result_type, const char* header) {
    74   tty->print_cr("%6d  %s", _number_of_calls, header);
    75 }
    77 void InterfaceSupport::gc_alot() {
    78   Thread *thread = Thread::current();
    79   if (!thread->is_Java_thread()) return; // Avoid concurrent calls
    80   // Check for new, not quite initialized thread. A thread in new mode cannot initiate a GC.
    81   JavaThread *current_thread = (JavaThread *)thread;
    82   if (current_thread->active_handles() == NULL) return;
    84   // Short-circuit any possible re-entrant gc-a-lot attempt
    85   if (thread->skip_gcalot()) return;
    87   if (is_init_completed()) {
    89     if (++_fullgc_alot_invocation < FullGCALotStart) {
    90       return;
    91     }
    93     // Use this line if you want to block at a specific point,
    94     // e.g. one number_of_calls/scavenge/gc before you got into problems
    95     if (FullGCALot) _fullgc_alot_counter--;
    97     // Check if we should force a full gc
    98     if (_fullgc_alot_counter == 0) {
    99       // Release dummy so objects are forced to move
   100       if (!Universe::release_fullgc_alot_dummy()) {
   101         warning("FullGCALot: Unable to release more dummies at bottom of heap");
   102       }
   103       HandleMark hm(thread);
   104       Universe::heap()->collect(GCCause::_full_gc_alot);
   105       unsigned int invocations = Universe::heap()->total_full_collections();
   106       // Compute new interval
   107       if (FullGCALotInterval > 1) {
   108         _fullgc_alot_counter = 1+(long)((double)FullGCALotInterval*os::random()/(max_jint+1.0));
   109         if (PrintGCDetails && Verbose) {
   110           tty->print_cr("Full gc no: %u\tInterval: %d", invocations,
   111                         _fullgc_alot_counter);
   112         }
   113       } else {
   114         _fullgc_alot_counter = 1;
   115       }
   116       // Print progress message
   117       if (invocations % 100 == 0) {
   118         if (PrintGCDetails && Verbose) tty->print_cr("Full gc no: %u", invocations);
   119       }
   120     } else {
   121       if (ScavengeALot) _scavenge_alot_counter--;
   122       // Check if we should force a scavenge
   123       if (_scavenge_alot_counter == 0) {
   124         HandleMark hm(thread);
   125         Universe::heap()->collect(GCCause::_scavenge_alot);
   126         unsigned int invocations = Universe::heap()->total_collections() - Universe::heap()->total_full_collections();
   127         // Compute new interval
   128         if (ScavengeALotInterval > 1) {
   129           _scavenge_alot_counter = 1+(long)((double)ScavengeALotInterval*os::random()/(max_jint+1.0));
   130           if (PrintGCDetails && Verbose) {
   131             tty->print_cr("Scavenge no: %u\tInterval: %d", invocations,
   132                           _scavenge_alot_counter);
   133           }
   134         } else {
   135           _scavenge_alot_counter = 1;
   136         }
   137         // Print progress message
   138         if (invocations % 1000 == 0) {
   139           if (PrintGCDetails && Verbose) tty->print_cr("Scavenge no: %u", invocations);
   140         }
   141       }
   142     }
   143   }
   144 }
   147 vframe* vframe_array[50];
   148 int walk_stack_counter = 0;
   150 void InterfaceSupport::walk_stack_from(vframe* start_vf) {
   151   // walk
   152   int i = 0;
   153   for (vframe* f = start_vf; f; f = f->sender() ) {
   154     if (i < 50) vframe_array[i++] = f;
   155   }
   156 }
   159 void InterfaceSupport::walk_stack() {
   160   JavaThread* thread = JavaThread::current();
   161   walk_stack_counter++;
   162   if (!thread->has_last_Java_frame()) return;
   163   ResourceMark rm(thread);
   164   RegisterMap reg_map(thread);
   165   walk_stack_from(thread->last_java_vframe(&reg_map));
   166 }
   169 # ifdef ENABLE_ZAP_DEAD_LOCALS
   171 static int zap_traversals = 0;
   173 void InterfaceSupport::zap_dead_locals_old() {
   174   JavaThread* thread = JavaThread::current();
   175   if (zap_traversals == -1) // edit constant for debugging
   176     warning("I am here");
   177   int zap_frame_count = 0; // count frames to help debugging
   178   for (StackFrameStream sfs(thread); !sfs.is_done(); sfs.next()) {
   179     sfs.current()->zap_dead_locals(thread, sfs.register_map());
   180     ++zap_frame_count;
   181   }
   182   ++zap_traversals;
   183 }
   185 # endif
   188 int deoptimizeAllCounter = 0;
   189 int zombieAllCounter = 0;
   192 void InterfaceSupport::zombieAll() {
   193   if (is_init_completed() && zombieAllCounter > ZombieALotInterval) {
   194     zombieAllCounter = 0;
   195     VM_ZombieAll op;
   196     VMThread::execute(&op);
   197   } else {
   198     zombieAllCounter++;
   199   }
   200 }
   202 void InterfaceSupport::unlinkSymbols() {
   203   VM_UnlinkSymbols op;
   204   VMThread::execute(&op);
   205 }
   207 void InterfaceSupport::deoptimizeAll() {
   208   if (is_init_completed() ) {
   209     if (DeoptimizeALot && deoptimizeAllCounter > DeoptimizeALotInterval) {
   210       deoptimizeAllCounter = 0;
   211       VM_DeoptimizeAll op;
   212       VMThread::execute(&op);
   213     } else if (DeoptimizeRandom && (deoptimizeAllCounter & 0x1f) == (os::random() & 0x1f)) {
   214       VM_DeoptimizeAll op;
   215       VMThread::execute(&op);
   216     }
   217   }
   218   deoptimizeAllCounter++;
   219 }
   222 void InterfaceSupport::stress_derived_pointers() {
   223 #ifdef COMPILER2
   224   JavaThread *thread = JavaThread::current();
   225   if (!is_init_completed()) return;
   226   ResourceMark rm(thread);
   227   bool found = false;
   228   for (StackFrameStream sfs(thread); !sfs.is_done() && !found; sfs.next()) {
   229     CodeBlob* cb = sfs.current()->cb();
   230     if (cb != NULL && cb->oop_maps() ) {
   231       // Find oopmap for current method
   232       OopMap* map = cb->oop_map_for_return_address(sfs.current()->pc());
   233       assert(map != NULL, "no oopmap found for pc");
   234       found = map->has_derived_pointer();
   235     }
   236   }
   237   if (found) {
   238     // $$$ Not sure what to do here.
   239     /*
   240     Scavenge::invoke(0);
   241     */
   242   }
   243 #endif
   244 }
   247 void InterfaceSupport::verify_stack() {
   248   JavaThread* thread = JavaThread::current();
   249   ResourceMark rm(thread);
   250   // disabled because it throws warnings that oop maps should only be accessed
   251   // in VM thread or during debugging
   253   if (!thread->has_pending_exception()) {
   254     // verification does not work if there are pending exceptions
   255     StackFrameStream sfs(thread);
   256     CodeBlob* cb = sfs.current()->cb();
   257       // In case of exceptions we might not have a runtime_stub on
   258       // top of stack, hence, all callee-saved registers are not going
   259       // to be setup correctly, hence, we cannot do stack verify
   260     if (cb != NULL && !(cb->is_runtime_stub() || cb->is_uncommon_trap_stub())) return;
   262     for (; !sfs.is_done(); sfs.next()) {
   263       sfs.current()->verify(sfs.register_map());
   264     }
   265   }
   266 }
   269 void InterfaceSupport::verify_last_frame() {
   270   JavaThread* thread = JavaThread::current();
   271   ResourceMark rm(thread);
   272   RegisterMap reg_map(thread);
   273   frame fr = thread->last_frame();
   274   fr.verify(&reg_map);
   275 }
   278 #endif // ASSERT
   281 void InterfaceSupport_init() {
   282 #ifdef ASSERT
   283   if (ScavengeALot || FullGCALot) {
   284     srand(ScavengeALotInterval * FullGCALotInterval);
   285   }
   286 #endif
   287 }

mercurial