Mercurial > hg > graal-jvmci-8
comparison src/share/vm/code/dependencies.hpp @ 3852:fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
Reviewed-by: kvn, never, bdelsart
author | twisti |
---|---|
date | Tue, 16 Aug 2011 04:14:05 -0700 |
parents | f95d63e2154a |
children | b27c72d69fd1 |
comparison
equal
deleted
inserted
replaced
3851:95134e034042 | 3852:fdb992d83a87 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 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 | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
23 */ | 23 */ |
24 | 24 |
25 #ifndef SHARE_VM_CODE_DEPENDENCIES_HPP | 25 #ifndef SHARE_VM_CODE_DEPENDENCIES_HPP |
26 #define SHARE_VM_CODE_DEPENDENCIES_HPP | 26 #define SHARE_VM_CODE_DEPENDENCIES_HPP |
27 | 27 |
28 #include "ci/ciCallSite.hpp" | |
28 #include "ci/ciKlass.hpp" | 29 #include "ci/ciKlass.hpp" |
30 #include "ci/ciMethodHandle.hpp" | |
31 #include "classfile/systemDictionary.hpp" | |
29 #include "code/compressedStream.hpp" | 32 #include "code/compressedStream.hpp" |
30 #include "code/nmethod.hpp" | 33 #include "code/nmethod.hpp" |
31 #include "utilities/growableArray.hpp" | 34 #include "utilities/growableArray.hpp" |
32 | 35 |
33 //** Dependencies represent assertions (approximate invariants) within | 36 //** Dependencies represent assertions (approximate invariants) within |
34 // the class hierarchy. An example is an assertion that a given | 37 // the runtime system, e.g. class hierarchy changes. An example is an |
35 // method is not overridden; another example is that a type has only | 38 // assertion that a given method is not overridden; another example is |
36 // one concrete subtype. Compiled code which relies on such | 39 // that a type has only one concrete subtype. Compiled code which |
37 // assertions must be discarded if they are overturned by changes in | 40 // relies on such assertions must be discarded if they are overturned |
38 // the class hierarchy. We can think of these assertions as | 41 // by changes in the runtime system. We can think of these assertions |
39 // approximate invariants, because we expect them to be overturned | 42 // as approximate invariants, because we expect them to be overturned |
40 // very infrequently. We are willing to perform expensive recovery | 43 // very infrequently. We are willing to perform expensive recovery |
41 // operations when they are overturned. The benefit, of course, is | 44 // operations when they are overturned. The benefit, of course, is |
42 // performing optimistic optimizations (!) on the object code. | 45 // performing optimistic optimizations (!) on the object code. |
43 // | 46 // |
44 // Changes in the class hierarchy due to dynamic linking or | 47 // Changes in the class hierarchy due to dynamic linking or |
50 class nmethod; | 53 class nmethod; |
51 class OopRecorder; | 54 class OopRecorder; |
52 class xmlStream; | 55 class xmlStream; |
53 class CompileLog; | 56 class CompileLog; |
54 class DepChange; | 57 class DepChange; |
58 class KlassDepChange; | |
59 class CallSiteDepChange; | |
55 class No_Safepoint_Verifier; | 60 class No_Safepoint_Verifier; |
56 | 61 |
57 class Dependencies: public ResourceObj { | 62 class Dependencies: public ResourceObj { |
58 public: | 63 public: |
59 // Note: In the comments on dependency types, most uses of the terms | 64 // Note: In the comments on dependency types, most uses of the terms |
149 exclusive_concrete_methods_2, | 154 exclusive_concrete_methods_2, |
150 | 155 |
151 // This dependency asserts that no instances of class or it's | 156 // This dependency asserts that no instances of class or it's |
152 // subclasses require finalization registration. | 157 // subclasses require finalization registration. |
153 no_finalizable_subclasses, | 158 no_finalizable_subclasses, |
159 | |
160 // This dependency asserts when the CallSite.target value changed. | |
161 call_site_target_value, | |
154 | 162 |
155 TYPE_LIMIT | 163 TYPE_LIMIT |
156 }; | 164 }; |
157 enum { | 165 enum { |
158 LG2_TYPE_LIMIT = 4, // assert(TYPE_LIMIT <= (1<<LG2_TYPE_LIMIT)) | 166 LG2_TYPE_LIMIT = 4, // assert(TYPE_LIMIT <= (1<<LG2_TYPE_LIMIT)) |
177 static const char* dep_name(DepType dept); | 185 static const char* dep_name(DepType dept); |
178 static int dep_args(DepType dept); | 186 static int dep_args(DepType dept); |
179 static int dep_context_arg(DepType dept) { | 187 static int dep_context_arg(DepType dept) { |
180 return dept_in_mask(dept, ctxk_types)? 0: -1; | 188 return dept_in_mask(dept, ctxk_types)? 0: -1; |
181 } | 189 } |
190 static void check_valid_dependency_type(DepType dept); | |
182 | 191 |
183 private: | 192 private: |
184 // State for writing a new set of dependencies: | 193 // State for writing a new set of dependencies: |
185 GrowableArray<int>* _dep_seen; // (seen[h->ident] & (1<<dept)) | 194 GrowableArray<int>* _dep_seen; // (seen[h->ident] & (1<<dept)) |
186 GrowableArray<ciObject*>* _deps[TYPE_LIMIT]; | 195 GrowableArray<ciObject*>* _deps[TYPE_LIMIT]; |
253 void assert_concrete_with_no_concrete_subtype(ciKlass* ctxk); | 262 void assert_concrete_with_no_concrete_subtype(ciKlass* ctxk); |
254 void assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm); | 263 void assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm); |
255 void assert_abstract_with_exclusive_concrete_subtypes(ciKlass* ctxk, ciKlass* k1, ciKlass* k2); | 264 void assert_abstract_with_exclusive_concrete_subtypes(ciKlass* ctxk, ciKlass* k1, ciKlass* k2); |
256 void assert_exclusive_concrete_methods(ciKlass* ctxk, ciMethod* m1, ciMethod* m2); | 265 void assert_exclusive_concrete_methods(ciKlass* ctxk, ciMethod* m1, ciMethod* m2); |
257 void assert_has_no_finalizable_subclasses(ciKlass* ctxk); | 266 void assert_has_no_finalizable_subclasses(ciKlass* ctxk); |
267 void assert_call_site_target_value(ciKlass* ctxk, ciCallSite* call_site, ciMethodHandle* method_handle); | |
258 | 268 |
259 // Define whether a given method or type is concrete. | 269 // Define whether a given method or type is concrete. |
260 // These methods define the term "concrete" as used in this module. | 270 // These methods define the term "concrete" as used in this module. |
261 // For this module, an "abstract" class is one which is non-concrete. | 271 // For this module, an "abstract" class is one which is non-concrete. |
262 // | 272 // |
294 | 304 |
295 // Checking old assertions at run-time (in the VM only): | 305 // Checking old assertions at run-time (in the VM only): |
296 static klassOop check_evol_method(methodOop m); | 306 static klassOop check_evol_method(methodOop m); |
297 static klassOop check_leaf_type(klassOop ctxk); | 307 static klassOop check_leaf_type(klassOop ctxk); |
298 static klassOop check_abstract_with_unique_concrete_subtype(klassOop ctxk, klassOop conck, | 308 static klassOop check_abstract_with_unique_concrete_subtype(klassOop ctxk, klassOop conck, |
299 DepChange* changes = NULL); | 309 KlassDepChange* changes = NULL); |
300 static klassOop check_abstract_with_no_concrete_subtype(klassOop ctxk, | 310 static klassOop check_abstract_with_no_concrete_subtype(klassOop ctxk, |
301 DepChange* changes = NULL); | 311 KlassDepChange* changes = NULL); |
302 static klassOop check_concrete_with_no_concrete_subtype(klassOop ctxk, | 312 static klassOop check_concrete_with_no_concrete_subtype(klassOop ctxk, |
303 DepChange* changes = NULL); | 313 KlassDepChange* changes = NULL); |
304 static klassOop check_unique_concrete_method(klassOop ctxk, methodOop uniqm, | 314 static klassOop check_unique_concrete_method(klassOop ctxk, methodOop uniqm, |
305 DepChange* changes = NULL); | 315 KlassDepChange* changes = NULL); |
306 static klassOop check_abstract_with_exclusive_concrete_subtypes(klassOop ctxk, klassOop k1, klassOop k2, | 316 static klassOop check_abstract_with_exclusive_concrete_subtypes(klassOop ctxk, klassOop k1, klassOop k2, |
307 DepChange* changes = NULL); | 317 KlassDepChange* changes = NULL); |
308 static klassOop check_exclusive_concrete_methods(klassOop ctxk, methodOop m1, methodOop m2, | 318 static klassOop check_exclusive_concrete_methods(klassOop ctxk, methodOop m1, methodOop m2, |
309 DepChange* changes = NULL); | 319 KlassDepChange* changes = NULL); |
310 static klassOop check_has_no_finalizable_subclasses(klassOop ctxk, | 320 static klassOop check_has_no_finalizable_subclasses(klassOop ctxk, KlassDepChange* changes = NULL); |
311 DepChange* changes = NULL); | 321 static klassOop check_call_site_target_value(klassOop ctxk, oop call_site, oop method_handle, CallSiteDepChange* changes = NULL); |
312 // A returned klassOop is NULL if the dependency assertion is still | 322 // A returned klassOop is NULL if the dependency assertion is still |
313 // valid. A non-NULL klassOop is a 'witness' to the assertion | 323 // valid. A non-NULL klassOop is a 'witness' to the assertion |
314 // failure, a point in the class hierarchy where the assertion has | 324 // failure, a point in the class hierarchy where the assertion has |
315 // been proven false. For example, if check_leaf_type returns | 325 // been proven false. For example, if check_leaf_type returns |
316 // non-NULL, the value is a subtype of the supposed leaf type. This | 326 // non-NULL, the value is a subtype of the supposed leaf type. This |
413 void initial_asserts(size_t byte_limit) NOT_DEBUG({}); | 423 void initial_asserts(size_t byte_limit) NOT_DEBUG({}); |
414 | 424 |
415 inline oop recorded_oop_at(int i); | 425 inline oop recorded_oop_at(int i); |
416 // => _code? _code->oop_at(i): *_deps->_oop_recorder->handle_at(i) | 426 // => _code? _code->oop_at(i): *_deps->_oop_recorder->handle_at(i) |
417 | 427 |
418 klassOop check_dependency_impl(DepChange* changes); | 428 klassOop check_klass_dependency(KlassDepChange* changes); |
429 klassOop check_call_site_dependency(CallSiteDepChange* changes); | |
430 | |
431 void trace_and_log_witness(klassOop witness); | |
419 | 432 |
420 public: | 433 public: |
421 DepStream(Dependencies* deps) | 434 DepStream(Dependencies* deps) |
422 : _deps(deps), | 435 : _deps(deps), |
423 _code(NULL), | 436 _code(NULL), |
451 oop x = argument(i); | 464 oop x = argument(i); |
452 assert(x->is_klass(), "type"); | 465 assert(x->is_klass(), "type"); |
453 return (klassOop) x; | 466 return (klassOop) x; |
454 } | 467 } |
455 | 468 |
456 // The point of the whole exercise: Is this dep is still OK? | 469 // The point of the whole exercise: Is this dep still OK? |
457 klassOop check_dependency() { | 470 klassOop check_dependency() { |
458 return check_dependency_impl(NULL); | 471 klassOop result = check_klass_dependency(NULL); |
472 if (result != NULL) return result; | |
473 return check_call_site_dependency(NULL); | |
459 } | 474 } |
475 | |
460 // A lighter version: Checks only around recent changes in a class | 476 // A lighter version: Checks only around recent changes in a class |
461 // hierarchy. (See Universe::flush_dependents_on.) | 477 // hierarchy. (See Universe::flush_dependents_on.) |
462 klassOop spot_check_dependency_at(DepChange& changes); | 478 klassOop spot_check_dependency_at(DepChange& changes); |
463 | 479 |
464 // Log the current dependency to xtty or compilation log. | 480 // Log the current dependency to xtty or compilation log. |
470 friend class Dependencies::DepStream; | 486 friend class Dependencies::DepStream; |
471 | 487 |
472 static void print_statistics() PRODUCT_RETURN; | 488 static void print_statistics() PRODUCT_RETURN; |
473 }; | 489 }; |
474 | 490 |
475 // A class hierarchy change coming through the VM (under the Compile_lock). | 491 |
476 // The change is structured as a single new type with any number of supers | 492 // Every particular DepChange is a sub-class of this class. |
477 // and implemented interface types. Other than the new type, any of the | |
478 // super types can be context types for a relevant dependency, which the | |
479 // new type could invalidate. | |
480 class DepChange : public StackObj { | 493 class DepChange : public StackObj { |
494 public: | |
495 // What kind of DepChange is this? | |
496 virtual bool is_klass_change() const { return false; } | |
497 virtual bool is_call_site_change() const { return false; } | |
498 | |
499 // Subclass casting with assertions. | |
500 KlassDepChange* as_klass_change() { | |
501 assert(is_klass_change(), "bad cast"); | |
502 return (KlassDepChange*) this; | |
503 } | |
504 CallSiteDepChange* as_call_site_change() { | |
505 assert(is_call_site_change(), "bad cast"); | |
506 return (CallSiteDepChange*) this; | |
507 } | |
508 | |
509 void print(); | |
510 | |
481 public: | 511 public: |
482 enum ChangeType { | 512 enum ChangeType { |
483 NO_CHANGE = 0, // an uninvolved klass | 513 NO_CHANGE = 0, // an uninvolved klass |
484 Change_new_type, // a newly loaded type | 514 Change_new_type, // a newly loaded type |
485 Change_new_sub, // a super with a new subtype | 515 Change_new_sub, // a super with a new subtype |
486 Change_new_impl, // an interface with a new implementation | 516 Change_new_impl, // an interface with a new implementation |
487 CHANGE_LIMIT, | 517 CHANGE_LIMIT, |
488 Start_Klass = CHANGE_LIMIT // internal indicator for ContextStream | 518 Start_Klass = CHANGE_LIMIT // internal indicator for ContextStream |
489 }; | 519 }; |
490 | |
491 private: | |
492 // each change set is rooted in exactly one new type (at present): | |
493 KlassHandle _new_type; | |
494 | |
495 void initialize(); | |
496 | |
497 public: | |
498 // notes the new type, marks it and all its super-types | |
499 DepChange(KlassHandle new_type) | |
500 : _new_type(new_type) | |
501 { | |
502 initialize(); | |
503 } | |
504 | |
505 // cleans up the marks | |
506 ~DepChange(); | |
507 | |
508 klassOop new_type() { return _new_type(); } | |
509 | |
510 // involves_context(k) is true if k is new_type or any of the super types | |
511 bool involves_context(klassOop k); | |
512 | 520 |
513 // Usage: | 521 // Usage: |
514 // for (DepChange::ContextStream str(changes); str.next(); ) { | 522 // for (DepChange::ContextStream str(changes); str.next(); ) { |
515 // klassOop k = str.klass(); | 523 // klassOop k = str.klass(); |
516 // switch (str.change_type()) { | 524 // switch (str.change_type()) { |
528 objArrayOop _ti_base; // i.e., transitive_interfaces | 536 objArrayOop _ti_base; // i.e., transitive_interfaces |
529 int _ti_index; | 537 int _ti_index; |
530 int _ti_limit; | 538 int _ti_limit; |
531 | 539 |
532 // start at the beginning: | 540 // start at the beginning: |
533 void start() { | 541 void start(); |
534 klassOop new_type = _changes.new_type(); | |
535 _change_type = (new_type == NULL ? NO_CHANGE: Start_Klass); | |
536 _klass = new_type; | |
537 _ti_base = NULL; | |
538 _ti_index = 0; | |
539 _ti_limit = 0; | |
540 } | |
541 | 542 |
542 public: | 543 public: |
543 ContextStream(DepChange& changes) | 544 ContextStream(DepChange& changes) |
544 : _changes(changes) | 545 : _changes(changes) |
545 { start(); } | 546 { start(); } |
553 | 554 |
554 ChangeType change_type() { return _change_type; } | 555 ChangeType change_type() { return _change_type; } |
555 klassOop klass() { return _klass; } | 556 klassOop klass() { return _klass; } |
556 }; | 557 }; |
557 friend class DepChange::ContextStream; | 558 friend class DepChange::ContextStream; |
558 | |
559 void print(); | |
560 }; | 559 }; |
561 | 560 |
561 | |
562 // A class hierarchy change coming through the VM (under the Compile_lock). | |
563 // The change is structured as a single new type with any number of supers | |
564 // and implemented interface types. Other than the new type, any of the | |
565 // super types can be context types for a relevant dependency, which the | |
566 // new type could invalidate. | |
567 class KlassDepChange : public DepChange { | |
568 private: | |
569 // each change set is rooted in exactly one new type (at present): | |
570 KlassHandle _new_type; | |
571 | |
572 void initialize(); | |
573 | |
574 public: | |
575 // notes the new type, marks it and all its super-types | |
576 KlassDepChange(KlassHandle new_type) | |
577 : _new_type(new_type) | |
578 { | |
579 initialize(); | |
580 } | |
581 | |
582 // cleans up the marks | |
583 ~KlassDepChange(); | |
584 | |
585 // What kind of DepChange is this? | |
586 virtual bool is_klass_change() const { return true; } | |
587 | |
588 klassOop new_type() { return _new_type(); } | |
589 | |
590 // involves_context(k) is true if k is new_type or any of the super types | |
591 bool involves_context(klassOop k); | |
592 }; | |
593 | |
594 | |
595 // A CallSite has changed its target. | |
596 class CallSiteDepChange : public DepChange { | |
597 private: | |
598 Handle _call_site; | |
599 Handle _method_handle; | |
600 | |
601 public: | |
602 CallSiteDepChange(Handle call_site, Handle method_handle) | |
603 : _call_site(call_site), | |
604 _method_handle(method_handle) | |
605 { | |
606 assert(_call_site() ->is_a(SystemDictionary::CallSite_klass()), "must be"); | |
607 assert(_method_handle()->is_a(SystemDictionary::MethodHandle_klass()), "must be"); | |
608 } | |
609 | |
610 // What kind of DepChange is this? | |
611 virtual bool is_call_site_change() const { return true; } | |
612 | |
613 oop call_site() const { return _call_site(); } | |
614 oop method_handle() const { return _method_handle(); } | |
615 }; | |
616 | |
562 #endif // SHARE_VM_CODE_DEPENDENCIES_HPP | 617 #endif // SHARE_VM_CODE_DEPENDENCIES_HPP |