dependencies.cpp revision 975
196N/A * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 0N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 0N/A * CA 95054 USA or visit www.sun.com if you need additional information or 0N/A * have any questions. 0N/A#
include "incls/_precompiled.incl" 0N/A return true;
//something like this: thread->is_VM_thread(); 0N/A // As a special case, support this assertion on an array type, 0N/A // which reduces to an assertion on its element type. 0N/A // Note that this cannot be done with assertions that 0N/A // relate to concreteness or abstractness. 0N/A //if (ctxk->is_final()) return; // Ex: String[][] 0N/A// Helper function. If we are adding a new dep. under ctxk2, 0N/A// try to find an old dep. under a broader* ctxk1. If there is 0N/A return true;
// success, and no need to change 0N/A // new context class fully subsumes previous one 0N/A // see if the same (or a similar) dep is already recorded 0N/A // see if the same (or a similar) dep is already recorded 0N/A // look in this bucket for redundant assertions 0N/A if (x ==
x1) {
// same subject; check the context 0N/A // append the assertion in the correct bucket: 0N/A // try to normalize an unordered pair: 0N/A // see if the same (or a similar) dep is already recorded 0N/A // look in this bucket for redundant assertions 0N/A if (x == y &&
x2 ==
y2) {
// same subjects; check the context 0N/A // append the assertion in the correct bucket: 0N/A/// Support for encoding dependencies into an nmethod: 0N/A // cast is safe, no deps can overflow INT_MAX 0N/A // write a sentinel byte to mark the end 0N/A // round it out to a word boundary 0N/A // check whether the dept byte encoding really works 0N/A "abstract_with_unique_concrete_subtype",
0N/A "abstract_with_no_concrete_subtype",
0N/A "concrete_with_no_concrete_subtype",
0N/A "unique_concrete_method",
0N/A "abstract_with_exclusive_concrete_subtypes_2",
0N/A "exclusive_concrete_methods_2",
0N/A "no_finalizable_subclasses" 0N/A 1,
// leaf_type ctxk 0N/A 2,
// abstract_with_unique_concrete_subtype ctxk, k 0N/A 1,
// abstract_with_no_concrete_subtype ctxk 0N/A 1,
// concrete_with_no_concrete_subtype ctxk 0N/A 2,
// unique_concrete_method ctxk, m 0N/A 3,
// unique_concrete_subtypes_2 ctxk, k1, k2 0N/A 3,
// unique_concrete_methods_2 ctxk, m1, m2 0N/A 1 // no_finalizable_subclasses ctxk 0N/A// for the sake of the compiler log, print out current dependencies: 0N/A // flush out the identities before printing 0N/A // write remaining arguments, if any. 0N/A if (j ==
ctxkj)
continue;
// already logged 0N/A // write remaining arguments, if any. 0N/A if (j ==
ctxkj)
continue;
// already logged 0N/A/// Dependency stream support (decodes dependencies from an nmethod): 0N/A // Method has no dependencies at all. 0N/A "bad dependency type tag");
0N/A skipj = 0;
// currently the only context argument is at zero 0N/A return NULL;
// for example, evol_method 0N/A if (k !=
NULL) {
// context type was not compressed away 0N/A }
else {
// recompute "default" context type 0N/A/// Checking dependencies: 0N/A// This hierarchy walker inspects subtypes of a given type, 0N/A// trying to find a "bad" class which breaks a dependency. 0N/A// Such a class is called a "witness" to the broken dependency. 0N/A// While searching around, we ignore "participants", which 0N/A// are already known to the dependency. 0N/A // optional method descriptor to check for: 0N/A // special classes which are not allowed to be witnesses: 0N/A // cache of method lookups 0N/A // if non-zero, tells how many witnesses to convert to participants 0N/A // Terminating NULL. 0N/A // The walker is initialized to recognize certain methods and/or types 0N/A // as friendly participants. 0N/A // This is common code for two searches: One for concrete subtypes, 0N/A // the other for concrete method implementations and overrides. 0N/A // Note: If n==num_participants, returns NULL. 0N/A // Assert that m is inherited into ctxk, without intervening overrides. 0N/A // (May return true even if this is not true, in corner cases where we punt.) 0N/A return true;
// Quick win. 0N/A return false;
// Quick lose. Should not happen. 0N/A // The override story is complex when packages get involved. 0N/A return true;
// Must punt the assertion to true. 0N/A // It might be an abstract interface method, devoid of mirandas. 0N/A // Method m is inherited into ctxk. 0N/A // Method is [package-]private, so the override story is complex. 0N/A return true;
// Must punt the assertion to true. 0N/A // Method m is overridden by lm, but both are non-concrete. 0N/A tty->
print_cr(
"Dependency method not found in the associated context:");
0N/A // Note: If add_participant(k) is called, 0N/A // the method m will already be memoized for it. 0N/A for (
int i = 0; ; i++) {
0N/A if (y == x)
return true;
0N/A return false;
// not in list 0N/A // the actual search method: 0N/A // the spot-checking version: 0N/A // When looking for unexpected concrete types, 0N/A // do not look beneath expected ones. 0N/A // CX > CC > C' is OK, even if C' is new. 0N/A // CX > { CC, C' } is not OK if C' is new, and C' is the witness. 0N/A // When looking for unexpected concrete methods, 0N/A // look beneath expected ones, to see if there are overrides. 0N/A // CX.m > CC.m > C'.m is not OK, if C'.m is new, and C' is the witness. 0N/A tty->
print_cr(
"Warning: TraceDependencies results may be inflated by VerifyDependencies");
0N/A // Every now and then dump a little info about dependency searching. 0N/A xtty->
elem(
"deps_find_witness calls='%d' steps='%d' recursions='%d' singles='%d'",
0N/A "calls=%d, steps=%d (avg=%.1f), recursions=%d, singles=%d",
0N/A // Current thread must be in VM (not native mode, as in CI): 0N/A // Must not move the class hierarchy during this check: 30N/A // Avoid this case: *I.m > { A.m, C }; B.m > C 30N/A // %%% Until this is fixed more systematically, bail out. 30N/A // See corresponding comment in find_witness_anywhere. 0N/A // If the new type is a subtype of a participant, we are done. 0N/A "correct marking of participants, b/c new_type is unique");
0N/A // new guy is protected from this check by previous participant 0N/A// Walk hierarchy under a context type, looking for unexpected types. 0N/A// Do not report participant types, and recursively walk beneath 0N/A// them only if participants_hide_witnesses is false. 0N/A// If top_level_call is false, skip testing the context type, 0N/A// because the caller has already considered it. 0N/A // Current thread must be in VM (not native mode, as in CI): 0N/A // Must not move the class hierarchy during this check: 0N/A // Check the root of the sub-hierarchy first. 0N/A // else fall through to search loop... 0N/A // The context is an abstract class or interface, to start with. 0N/A // Now we must check each implementor and each subclass. 0N/A // Use a short worklist to avoid blowing the stack. 0N/A // Each worklist entry is a *chain* of subklass siblings to process. 0N/A const int CHAINMAX =
100;
// >= 1 + instanceKlass::implementors_limit 0N/A // Look for non-abstract subclasses. 0N/A // (Note: Interfaces do not have subclasses.) 0N/A // If it is an interface, search its direct implementors. 0N/A // (Their subclasses are additional indirect implementors. 0N/A // See instanceKlass::add_implementor.) 0N/A // (Note: nof_implementors is always zero for non-interfaces.) 0N/A // Avoid this case: *I.m > { A.m, C }; B.m > C 0N/A // Here, I.m has 2 concrete implementations, but m appears unique 0N/A // as A.m, because the search misses B.m when checking C. 0N/A // The inherited method B.m was getting missed by the walker 0N/A // when interface 'I' was the starting point. 0N/A // %%% Until this is fixed more systematically, bail out. 0N/A // (Old CHA had the same limitation.) 0N/A // implementors array overflowed => no exact info. 0N/A // else fall through to process this guy's subclasses 0N/A // Recursively process each non-trivial sibling chain. 0N/A // else fall through to process this guy's subclasses 0N/A // Fast path. (Partially disabled if VerifyDependencies.) 0N/A // Worklist overflow. Do a recursive call. Should be rare. 0N/A // The recursive call will have its own worklist, of course. 0N/A // (Note that sub has already been tested, so that there is 0N/A // no need for the recursive call to re-test. That's handy, 0N/A // since the recursive call sees sub as the context_type.) 0N/A /*top_level_call=*/ false);
0N/A // No witness found. The dependency remains unbroken. 0N/A // %%% We could treat classes which are concrete but 0N/A // have not yet been instantiated as virtually abstract. 0N/A // This would require a deoptimization barrier on first instantiation. 0N/A //if (k->is_not_instantiated()) return false; 0N/A // %%% We could treat unexecuted methods as virtually abstract also. 0N/A // This would require a deoptimization barrier on first execution. 0N/A // We could return also false if k does not yet appear to be 0N/A // instantiated, if the VM version supports this distinction also. 0N/A //if (k->is_not_instantiated()) return false; 0N/A // Statics are irrelevant to virtual call sites. 0N/A // We could return also false if m does not yet appear to be 0N/A // executed, if the VM version supports this distinction also. 0N/A// Any use of the contents (bytecodes) of a method must be 0N/A// marked by an "evol_method" dependency, if those contents 0N/A// can change. (Note: A method is always dependent on itself.) 0N/A // Did somebody do a JVMTI RedefineClasses while our backs were turned? 0N/A // Or is there a now a breakpoint? 0N/A // (Assumes compiled code cannot handle bkpts; change if UseFastBreakpoints.) 0N/A// This is a strong assertion: It is that the given type 0N/A// has no subtypes whatever. It is most useful for 0N/A// optimizing checks on reflected types or on array types. 0N/A// (Checks on types which are derived from real instances 0N/A// can be optimized more strongly than this, because we 0N/A// know that the checked type comes from a concrete type, 0N/A// and therefore we can disregard abstract types.) 0N/A // if it is an interface, it must be unimplemented 0N/A // (if it is not an interface, nof_implementors is always zero) 0N/A// Test the assertion that conck is the only concrete subtype* of ctxk. 0N/A// The type conck itself is allowed to have have further concrete subtypes. 0N/A// This allows the compiler to narrow occurrences of ctxk by conck, 0N/A// when dealing with the types of actual instances. 0N/A// If a non-concrete class has no concrete subtypes, it is not (yet) 0N/A// instantiatable. This can allow the compiler to make some paths go 0N/A// dead, if they are gated by a test of the type. 0N/A // Find any concrete subtype, with no participants: 0N/A// If a concrete class has no concrete subtypes, it can always be 0N/A// exactly typed. This allows the use of a cheaper type test. 0N/A // Find any concrete subtype, with only the ctxk as participant: 0N/A// Find the unique concrete proper subtype of ctxk, or NULL if there 0N/A// is more than one concrete proper subtype. If there are no concrete 0N/A// proper subtypes, return ctxk itself, whether it is concrete or not. 0N/A// The returned subtype is allowed to have have further concrete subtypes. 0N/A// That is, return CC1 for CX > CC1 > CC2, but NULL for CX > { CC1, CC2 }. 0N/A // Make sure the dependency mechanism will pass this discovery: 0N/A // Turn off dependency tracing while actually testing deps. 0N/A return ctxk;
// Return ctxk as a flag for "no subtypes". 0N/A // Make sure the dependency mechanism will pass this discovery: 0N/A // Turn off dependency tracing while actually testing deps. 0N/A// Test the assertion that the k[12] are the only concrete subtypes of ctxk, 0N/A// except possibly for further subtypes of k[12] themselves. 0N/A// The context type must be abstract. The types k1 and k2 are themselves 0N/A// allowed to have further concrete subtypes. 0N/A// Search ctxk for concrete implementations. If there are klen or fewer, 0N/A// pack them into the given array and return the number. 0N/A// Otherwise, return -1, meaning the given array would overflow. 0N/A// (Note that a return of 0 means there are exactly no concrete subtypes.) 0N/A// In this search, if ctxk is concrete, it will be reported alone. 0N/A// For any type CC reported, no proper subtypes of CC will be reported. 0N/A if (
wit !=
NULL)
return -
1;
// Too many witnesses. 0N/A // Pack the result array with the good news. 0N/A // Make sure the dependency mechanism will pass this discovery: 0N/A // Turn off dependency tracing while actually testing deps. 0N/A case -
1:
// ctxk was itself concrete 0N/A// If a class (or interface) has a unique concrete method uniqm, return NULL. 0N/A// Otherwise, return a class that contains an interfering method. 0N/A // Here is a missing optimization: If uniqm->is_final(), 0N/A // we don't really need to search beneath it for overrides. 0N/A // This is probably not important, since we don't use dependencies 0N/A // to track final methods. (They can't be "definalized".) 0N/A// Find the set of all non-abstract methods under ctxk that match m. 0N/A// (The method m must be defined or inherited in ctxk.) 0N/A// Include m itself in the set, unless it is abstract. 0N/A// If this set has exactly one element, return that element. 0N/A // It turns out that m was always the only implementation. 0N/A // Two conflicting implementations after all. 0N/A // (This can happen if m is inherited into ctxk and fm overrides it.) 0N/A // Make sure the dependency mechanism will pass this discovery: 0N/A// Find the set of all non-abstract methods under ctxk that match m[0]. 0N/A// (The method m[0] must be defined or inherited in ctxk.) 0N/A// Include m itself in the set, unless it is abstract. 0N/A// Fill the given array m[0..(mlen-1)] with this set, and return the length. 0N/A// (The length may be zero if no concrete methods are found anywhere.) 0N/A// If there are too many concrete methods to fit in marray, return -1. 0N/A if (
wit !=
NULL)
return -
1;
// Too many witnesses. 0N/A // Keep track of whether m is also part of the result set. 0N/A mfill++;
// keep m0 as marray[0], the first result 0N/A for (
int i = 0; i <
num; i++) {
0N/A if (
fm ==
m0)
continue;
// Already put this guy in the list. 0N/A return -
1;
// Oops. Too many methods after all! 0N/A // Make sure the dependency mechanism will pass this discovery: 0N/A // Turn off dependency tracing while actually testing deps. 0N/A // The following is a no-op unless logging is enabled: 0N/A // irrelevant dependency; skip it 0N/A // entire transaction must be under this lock: 0N/A // Mark all dependee and all its superclasses 0N/A // Mark transitive interfaces 0N/A // Unmark all dependee and all its superclasses 0N/A // Unmark transitive interfaces 0N/A "correct marking of potential context types");
54N/A // 6598190: brackets workaround Sun Studio C++ compiler bug 6629277 0N/A // else set up _ti_limit and fall through: 0N/A // Call one final time, to flush out the data.