1.1 --- a/src/share/vm/code/dependencies.hpp Thu Aug 11 12:08:11 2011 -0700 1.2 +++ b/src/share/vm/code/dependencies.hpp Tue Aug 16 04:14:05 2011 -0700 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -25,18 +25,21 @@ 1.11 #ifndef SHARE_VM_CODE_DEPENDENCIES_HPP 1.12 #define SHARE_VM_CODE_DEPENDENCIES_HPP 1.13 1.14 +#include "ci/ciCallSite.hpp" 1.15 #include "ci/ciKlass.hpp" 1.16 +#include "ci/ciMethodHandle.hpp" 1.17 +#include "classfile/systemDictionary.hpp" 1.18 #include "code/compressedStream.hpp" 1.19 #include "code/nmethod.hpp" 1.20 #include "utilities/growableArray.hpp" 1.21 1.22 //** Dependencies represent assertions (approximate invariants) within 1.23 -// the class hierarchy. An example is an assertion that a given 1.24 -// method is not overridden; another example is that a type has only 1.25 -// one concrete subtype. Compiled code which relies on such 1.26 -// assertions must be discarded if they are overturned by changes in 1.27 -// the class hierarchy. We can think of these assertions as 1.28 -// approximate invariants, because we expect them to be overturned 1.29 +// the runtime system, e.g. class hierarchy changes. An example is an 1.30 +// assertion that a given method is not overridden; another example is 1.31 +// that a type has only one concrete subtype. Compiled code which 1.32 +// relies on such assertions must be discarded if they are overturned 1.33 +// by changes in the runtime system. We can think of these assertions 1.34 +// as approximate invariants, because we expect them to be overturned 1.35 // very infrequently. We are willing to perform expensive recovery 1.36 // operations when they are overturned. The benefit, of course, is 1.37 // performing optimistic optimizations (!) on the object code. 1.38 @@ -52,6 +55,8 @@ 1.39 class xmlStream; 1.40 class CompileLog; 1.41 class DepChange; 1.42 +class KlassDepChange; 1.43 +class CallSiteDepChange; 1.44 class No_Safepoint_Verifier; 1.45 1.46 class Dependencies: public ResourceObj { 1.47 @@ -152,6 +157,9 @@ 1.48 // subclasses require finalization registration. 1.49 no_finalizable_subclasses, 1.50 1.51 + // This dependency asserts when the CallSite.target value changed. 1.52 + call_site_target_value, 1.53 + 1.54 TYPE_LIMIT 1.55 }; 1.56 enum { 1.57 @@ -179,6 +187,7 @@ 1.58 static int dep_context_arg(DepType dept) { 1.59 return dept_in_mask(dept, ctxk_types)? 0: -1; 1.60 } 1.61 + static void check_valid_dependency_type(DepType dept); 1.62 1.63 private: 1.64 // State for writing a new set of dependencies: 1.65 @@ -255,6 +264,7 @@ 1.66 void assert_abstract_with_exclusive_concrete_subtypes(ciKlass* ctxk, ciKlass* k1, ciKlass* k2); 1.67 void assert_exclusive_concrete_methods(ciKlass* ctxk, ciMethod* m1, ciMethod* m2); 1.68 void assert_has_no_finalizable_subclasses(ciKlass* ctxk); 1.69 + void assert_call_site_target_value(ciKlass* ctxk, ciCallSite* call_site, ciMethodHandle* method_handle); 1.70 1.71 // Define whether a given method or type is concrete. 1.72 // These methods define the term "concrete" as used in this module. 1.73 @@ -296,19 +306,19 @@ 1.74 static klassOop check_evol_method(methodOop m); 1.75 static klassOop check_leaf_type(klassOop ctxk); 1.76 static klassOop check_abstract_with_unique_concrete_subtype(klassOop ctxk, klassOop conck, 1.77 - DepChange* changes = NULL); 1.78 + KlassDepChange* changes = NULL); 1.79 static klassOop check_abstract_with_no_concrete_subtype(klassOop ctxk, 1.80 - DepChange* changes = NULL); 1.81 + KlassDepChange* changes = NULL); 1.82 static klassOop check_concrete_with_no_concrete_subtype(klassOop ctxk, 1.83 - DepChange* changes = NULL); 1.84 + KlassDepChange* changes = NULL); 1.85 static klassOop check_unique_concrete_method(klassOop ctxk, methodOop uniqm, 1.86 - DepChange* changes = NULL); 1.87 + KlassDepChange* changes = NULL); 1.88 static klassOop check_abstract_with_exclusive_concrete_subtypes(klassOop ctxk, klassOop k1, klassOop k2, 1.89 - DepChange* changes = NULL); 1.90 + KlassDepChange* changes = NULL); 1.91 static klassOop check_exclusive_concrete_methods(klassOop ctxk, methodOop m1, methodOop m2, 1.92 - DepChange* changes = NULL); 1.93 - static klassOop check_has_no_finalizable_subclasses(klassOop ctxk, 1.94 - DepChange* changes = NULL); 1.95 + KlassDepChange* changes = NULL); 1.96 + static klassOop check_has_no_finalizable_subclasses(klassOop ctxk, KlassDepChange* changes = NULL); 1.97 + static klassOop check_call_site_target_value(klassOop ctxk, oop call_site, oop method_handle, CallSiteDepChange* changes = NULL); 1.98 // A returned klassOop is NULL if the dependency assertion is still 1.99 // valid. A non-NULL klassOop is a 'witness' to the assertion 1.100 // failure, a point in the class hierarchy where the assertion has 1.101 @@ -415,7 +425,10 @@ 1.102 inline oop recorded_oop_at(int i); 1.103 // => _code? _code->oop_at(i): *_deps->_oop_recorder->handle_at(i) 1.104 1.105 - klassOop check_dependency_impl(DepChange* changes); 1.106 + klassOop check_klass_dependency(KlassDepChange* changes); 1.107 + klassOop check_call_site_dependency(CallSiteDepChange* changes); 1.108 + 1.109 + void trace_and_log_witness(klassOop witness); 1.110 1.111 public: 1.112 DepStream(Dependencies* deps) 1.113 @@ -453,10 +466,13 @@ 1.114 return (klassOop) x; 1.115 } 1.116 1.117 - // The point of the whole exercise: Is this dep is still OK? 1.118 + // The point of the whole exercise: Is this dep still OK? 1.119 klassOop check_dependency() { 1.120 - return check_dependency_impl(NULL); 1.121 + klassOop result = check_klass_dependency(NULL); 1.122 + if (result != NULL) return result; 1.123 + return check_call_site_dependency(NULL); 1.124 } 1.125 + 1.126 // A lighter version: Checks only around recent changes in a class 1.127 // hierarchy. (See Universe::flush_dependents_on.) 1.128 klassOop spot_check_dependency_at(DepChange& changes); 1.129 @@ -472,13 +488,27 @@ 1.130 static void print_statistics() PRODUCT_RETURN; 1.131 }; 1.132 1.133 -// A class hierarchy change coming through the VM (under the Compile_lock). 1.134 -// The change is structured as a single new type with any number of supers 1.135 -// and implemented interface types. Other than the new type, any of the 1.136 -// super types can be context types for a relevant dependency, which the 1.137 -// new type could invalidate. 1.138 + 1.139 +// Every particular DepChange is a sub-class of this class. 1.140 class DepChange : public StackObj { 1.141 public: 1.142 + // What kind of DepChange is this? 1.143 + virtual bool is_klass_change() const { return false; } 1.144 + virtual bool is_call_site_change() const { return false; } 1.145 + 1.146 + // Subclass casting with assertions. 1.147 + KlassDepChange* as_klass_change() { 1.148 + assert(is_klass_change(), "bad cast"); 1.149 + return (KlassDepChange*) this; 1.150 + } 1.151 + CallSiteDepChange* as_call_site_change() { 1.152 + assert(is_call_site_change(), "bad cast"); 1.153 + return (CallSiteDepChange*) this; 1.154 + } 1.155 + 1.156 + void print(); 1.157 + 1.158 + public: 1.159 enum ChangeType { 1.160 NO_CHANGE = 0, // an uninvolved klass 1.161 Change_new_type, // a newly loaded type 1.162 @@ -488,28 +518,6 @@ 1.163 Start_Klass = CHANGE_LIMIT // internal indicator for ContextStream 1.164 }; 1.165 1.166 - private: 1.167 - // each change set is rooted in exactly one new type (at present): 1.168 - KlassHandle _new_type; 1.169 - 1.170 - void initialize(); 1.171 - 1.172 - public: 1.173 - // notes the new type, marks it and all its super-types 1.174 - DepChange(KlassHandle new_type) 1.175 - : _new_type(new_type) 1.176 - { 1.177 - initialize(); 1.178 - } 1.179 - 1.180 - // cleans up the marks 1.181 - ~DepChange(); 1.182 - 1.183 - klassOop new_type() { return _new_type(); } 1.184 - 1.185 - // involves_context(k) is true if k is new_type or any of the super types 1.186 - bool involves_context(klassOop k); 1.187 - 1.188 // Usage: 1.189 // for (DepChange::ContextStream str(changes); str.next(); ) { 1.190 // klassOop k = str.klass(); 1.191 @@ -530,14 +538,7 @@ 1.192 int _ti_limit; 1.193 1.194 // start at the beginning: 1.195 - void start() { 1.196 - klassOop new_type = _changes.new_type(); 1.197 - _change_type = (new_type == NULL ? NO_CHANGE: Start_Klass); 1.198 - _klass = new_type; 1.199 - _ti_base = NULL; 1.200 - _ti_index = 0; 1.201 - _ti_limit = 0; 1.202 - } 1.203 + void start(); 1.204 1.205 public: 1.206 ContextStream(DepChange& changes) 1.207 @@ -555,8 +556,62 @@ 1.208 klassOop klass() { return _klass; } 1.209 }; 1.210 friend class DepChange::ContextStream; 1.211 +}; 1.212 1.213 - void print(); 1.214 + 1.215 +// A class hierarchy change coming through the VM (under the Compile_lock). 1.216 +// The change is structured as a single new type with any number of supers 1.217 +// and implemented interface types. Other than the new type, any of the 1.218 +// super types can be context types for a relevant dependency, which the 1.219 +// new type could invalidate. 1.220 +class KlassDepChange : public DepChange { 1.221 + private: 1.222 + // each change set is rooted in exactly one new type (at present): 1.223 + KlassHandle _new_type; 1.224 + 1.225 + void initialize(); 1.226 + 1.227 + public: 1.228 + // notes the new type, marks it and all its super-types 1.229 + KlassDepChange(KlassHandle new_type) 1.230 + : _new_type(new_type) 1.231 + { 1.232 + initialize(); 1.233 + } 1.234 + 1.235 + // cleans up the marks 1.236 + ~KlassDepChange(); 1.237 + 1.238 + // What kind of DepChange is this? 1.239 + virtual bool is_klass_change() const { return true; } 1.240 + 1.241 + klassOop new_type() { return _new_type(); } 1.242 + 1.243 + // involves_context(k) is true if k is new_type or any of the super types 1.244 + bool involves_context(klassOop k); 1.245 +}; 1.246 + 1.247 + 1.248 +// A CallSite has changed its target. 1.249 +class CallSiteDepChange : public DepChange { 1.250 + private: 1.251 + Handle _call_site; 1.252 + Handle _method_handle; 1.253 + 1.254 + public: 1.255 + CallSiteDepChange(Handle call_site, Handle method_handle) 1.256 + : _call_site(call_site), 1.257 + _method_handle(method_handle) 1.258 + { 1.259 + assert(_call_site() ->is_a(SystemDictionary::CallSite_klass()), "must be"); 1.260 + assert(_method_handle()->is_a(SystemDictionary::MethodHandle_klass()), "must be"); 1.261 + } 1.262 + 1.263 + // What kind of DepChange is this? 1.264 + virtual bool is_call_site_change() const { return true; } 1.265 + 1.266 + oop call_site() const { return _call_site(); } 1.267 + oop method_handle() const { return _method_handle(); } 1.268 }; 1.269 1.270 #endif // SHARE_VM_CODE_DEPENDENCIES_HPP