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 */
24
25 #ifndef SHARE_VM_CODE_DEPENDENCIES_HPP
26 #define SHARE_VM_CODE_DEPENDENCIES_HPP
27
28 #include "ci/ciCallSite.hpp"
29 #include "ci/ciKlass.hpp"
30 #include "ci/ciMethodHandle.hpp"
31 #include "classfile/systemDictionary.hpp"
32 #include "code/compressedStream.hpp"
33 #include "code/nmethod.hpp"
34 #include "utilities/growableArray.hpp"
35
36 //** Dependencies represent assertions (approximate invariants) within
37 // the runtime system, e.g. class hierarchy changes. An example is an
38 // assertion that a given method is not overridden; another example is
39 // that a type has only one concrete subtype. Compiled code which
40 // relies on such assertions must be discarded if they are overturned
41 // by changes in the runtime system. We can think of these assertions
42 // as approximate invariants, because we expect them to be overturned
43 // very infrequently. We are willing to perform expensive recovery
44 // operations when they are overturned. The benefit, of course, is
45 // performing optimistic optimizations (!) on the object code.
46 //
47 // Changes in the class hierarchy due to dynamic linking or
48 // class evolution can violate dependencies. There is enough
49 // indexing between classes and nmethods to make dependency
50 // checking reasonably efficient.
51
52 class ciEnv;
53 class nmethod;
54 class OopRecorder;
509 if (result != NULL) return result;
510 return check_call_site_dependency(NULL);
511 }
512
513 // A lighter version: Checks only around recent changes in a class
514 // hierarchy. (See Universe::flush_dependents_on.)
515 Klass* spot_check_dependency_at(DepChange& changes);
516
517 // Log the current dependency to xtty or compilation log.
518 void log_dependency(Klass* witness = NULL);
519
520 // Print the current dependency to tty.
521 void print_dependency(Klass* witness = NULL, bool verbose = false);
522 };
523 friend class Dependencies::DepStream;
524
525 static void print_statistics() PRODUCT_RETURN;
526 };
527
528
529 class DependencySignature : public ResourceObj {
530 private:
531 int _args_count;
532 uintptr_t _argument_hash[Dependencies::max_arg_count];
533 Dependencies::DepType _type;
534
535
536 public:
537 DependencySignature(Dependencies::DepStream& dep) {
538 _args_count = dep.argument_count();
539 _type = dep.type();
540 for (int i = 0; i < _args_count; i++) {
541 _argument_hash[i] = dep.get_identifier(i);
542 }
543 }
544
545 bool equals(const DependencySignature& sig) const;
546
547 int args_count() const { return _args_count; }
548 uintptr_t arg(int idx) const { return _argument_hash[idx]; }
549 Dependencies::DepType type() const { return _type; }
550 };
551
552 class DependencySignatureBuffer : public StackObj {
553 private:
554 GrowableArray<DependencySignature*>** _signatures;
555
556 public:
557 DependencySignatureBuffer();
558 bool add_if_missing(const DependencySignature& sig);
559 };
560
561 // Every particular DepChange is a sub-class of this class.
562 class DepChange : public StackObj {
563 public:
564 // What kind of DepChange is this?
565 virtual bool is_klass_change() const { return false; }
566 virtual bool is_call_site_change() const { return false; }
567
568 // Subclass casting with assertions.
569 KlassDepChange* as_klass_change() {
570 assert(is_klass_change(), "bad cast");
571 return (KlassDepChange*) this;
572 }
573 CallSiteDepChange* as_call_site_change() {
574 assert(is_call_site_change(), "bad cast");
575 return (CallSiteDepChange*) this;
576 }
577
578 void print();
579
|
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 */
24
25 #ifndef SHARE_VM_CODE_DEPENDENCIES_HPP
26 #define SHARE_VM_CODE_DEPENDENCIES_HPP
27
28 #include "ci/ciCallSite.hpp"
29 #include "ci/ciKlass.hpp"
30 #include "ci/ciMethodHandle.hpp"
31 #include "classfile/systemDictionary.hpp"
32 #include "code/compressedStream.hpp"
33 #include "code/nmethod.hpp"
34 #include "utilities/growableArray.hpp"
35 #include "utilities/hashtable.hpp"
36
37 //** Dependencies represent assertions (approximate invariants) within
38 // the runtime system, e.g. class hierarchy changes. An example is an
39 // assertion that a given method is not overridden; another example is
40 // that a type has only one concrete subtype. Compiled code which
41 // relies on such assertions must be discarded if they are overturned
42 // by changes in the runtime system. We can think of these assertions
43 // as approximate invariants, because we expect them to be overturned
44 // very infrequently. We are willing to perform expensive recovery
45 // operations when they are overturned. The benefit, of course, is
46 // performing optimistic optimizations (!) on the object code.
47 //
48 // Changes in the class hierarchy due to dynamic linking or
49 // class evolution can violate dependencies. There is enough
50 // indexing between classes and nmethods to make dependency
51 // checking reasonably efficient.
52
53 class ciEnv;
54 class nmethod;
55 class OopRecorder;
510 if (result != NULL) return result;
511 return check_call_site_dependency(NULL);
512 }
513
514 // A lighter version: Checks only around recent changes in a class
515 // hierarchy. (See Universe::flush_dependents_on.)
516 Klass* spot_check_dependency_at(DepChange& changes);
517
518 // Log the current dependency to xtty or compilation log.
519 void log_dependency(Klass* witness = NULL);
520
521 // Print the current dependency to tty.
522 void print_dependency(Klass* witness = NULL, bool verbose = false);
523 };
524 friend class Dependencies::DepStream;
525
526 static void print_statistics() PRODUCT_RETURN;
527 };
528
529
530 class DependencySignature : public GenericHashtableEntry<DependencySignature, ResourceObj> {
531 private:
532 int _args_count;
533 uintptr_t _argument_hash[Dependencies::max_arg_count];
534 Dependencies::DepType _type;
535
536 public:
537 DependencySignature(Dependencies::DepStream& dep) {
538 _args_count = dep.argument_count();
539 _type = dep.type();
540 for (int i = 0; i < _args_count; i++) {
541 _argument_hash[i] = dep.get_identifier(i);
542 }
543 }
544
545 bool equals(DependencySignature* sig) const;
546 uintptr_t key() const { return _argument_hash[0] >> 2; }
547
548 int args_count() const { return _args_count; }
549 uintptr_t arg(int idx) const { return _argument_hash[idx]; }
550 Dependencies::DepType type() const { return _type; }
551 };
552
553
554 // Every particular DepChange is a sub-class of this class.
555 class DepChange : public StackObj {
556 public:
557 // What kind of DepChange is this?
558 virtual bool is_klass_change() const { return false; }
559 virtual bool is_call_site_change() const { return false; }
560
561 // Subclass casting with assertions.
562 KlassDepChange* as_klass_change() {
563 assert(is_klass_change(), "bad cast");
564 return (KlassDepChange*) this;
565 }
566 CallSiteDepChange* as_call_site_change() {
567 assert(is_call_site_change(), "bad cast");
568 return (CallSiteDepChange*) this;
569 }
570
571 void print();
572
|