src/share/vm/runtime/interfaceSupport.cpp

Fri, 28 Mar 2014 10:13:37 -0700

author
vlivanov
date
Fri, 28 Mar 2014 10:13:37 -0700
changeset 6528
248ff38d2950
parent 2708
1d1603768966
child 6680
78bbf4d43a14
permissions
-rw-r--r--

8035828: Turn on @Stable support in VM
Reviewed-by: jrose, twisti

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

mercurial