< prev index next >
src/share/vm/code/dependencies.hpp
Print this page
@@ -57,10 +57,11 @@
class xmlStream;
class CompileLog;
class DepChange;
class KlassDepChange;
class CallSiteDepChange;
+class ConstantFieldDepChange;
class No_Safepoint_Verifier;
class Dependencies: public ResourceObj {
public:
// Note: In the comments on dependency types, most uses of the terms
@@ -160,10 +161,13 @@
no_finalizable_subclasses,
// This dependency asserts when the CallSite.target value changed.
call_site_target_value,
+ constant_field_value_instance,
+ constant_field_value_klass,
+
TYPE_LIMIT
};
enum {
LG2_TYPE_LIMIT = 4, // assert(TYPE_LIMIT <= (1<<LG2_TYPE_LIMIT))
@@ -277,10 +281,13 @@
void assert_abstract_with_exclusive_concrete_subtypes(ciKlass* ctxk, ciKlass* k1, ciKlass* k2);
void assert_exclusive_concrete_methods(ciKlass* ctxk, ciMethod* m1, ciMethod* m2);
void assert_has_no_finalizable_subclasses(ciKlass* ctxk);
void assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle);
+ void assert_constant_field_value_klass(ciField* field, ciKlass* ctxk);
+ void assert_constant_field_value_instance(ciField* field, ciObject* obj);
+
// Define whether a given method or type is concrete.
// These methods define the term "concrete" as used in this module.
// For this module, an "abstract" class is one which is non-concrete.
//
// Future optimizations may allow some classes to remain
@@ -348,10 +355,12 @@
// Detecting possible new assertions:
static Klass* find_unique_concrete_subtype(Klass* ctxk);
static Method* find_unique_concrete_method(Klass* ctxk, Method* m);
static int find_exclusive_concrete_subtypes(Klass* ctxk, int klen, Klass* k[]);
+ static void invalidate_dependent_nmethods(instanceKlassHandle ctxk, DepChange& changes, TRAPS);
+
// Create the encoding which will be stored in an nmethod.
void encode_content_bytes();
address content_bytes() {
assert(_content_bytes != NULL, "encode it first");
@@ -398,10 +407,16 @@
}
assert(ciargs->length() == dep_args(dept), "");
log_dependency(dept, ciargs);
}
+ static PerfCounter* _perf_dependency_checking_time;
+ static PerfCounter* _perf_dependencies_checked_count;
+ static PerfCounter* _perf_dependencies_context_traversals;
+ static PerfCounter* _perf_dependencies_invalidated;
+ static PerfCounter* _perf_dependencies_total_count;
+
class DepArgument : public ResourceObj {
private:
bool _is_oop;
bool _valid;
void* _value;
@@ -494,18 +509,34 @@
}
bool next();
DepType type() { return _type; }
- bool is_oop_argument(int i) { return type() == call_site_target_value; }
+ bool is_oop_argument(int i) {
+ assert(0 <= i && i < argument_count(), "oob");
+ switch (type()) {
+ case call_site_target_value: return true;
+ case constant_field_value_instance: return (i == 1);
+ default: return false;
+ }
+ }
+ bool is_int_argument(int i) {
+ assert(0 <= i && i < argument_count(), "oob");
+ switch (type()) {
+ case constant_field_value_instance: return (i == 2);
+ case constant_field_value_klass: return (i == 1);
+ default: return false;
+ }
+ }
uintptr_t get_identifier(int i);
int argument_count() { return dep_args(type()); }
int argument_index(int i) { assert(0 <= i && i < argument_count(), "oob");
return _xi[i]; }
Metadata* argument(int i); // => recorded_oop_at(argument_index(i))
oop argument_oop(int i); // => recorded_oop_at(argument_index(i))
+ int argument_int(int i) { return argument_index(i); }
Klass* context_type();
bool is_klass_type() { return Dependencies::is_klass_type(type()); }
Method* method_argument(int i) {
@@ -571,20 +602,25 @@
class DepChange : public StackObj {
public:
// What kind of DepChange is this?
virtual bool is_klass_change() const { return false; }
virtual bool is_call_site_change() const { return false; }
+ virtual bool is_constant_field_change() const { return false; }
// Subclass casting with assertions.
KlassDepChange* as_klass_change() {
assert(is_klass_change(), "bad cast");
return (KlassDepChange*) this;
}
CallSiteDepChange* as_call_site_change() {
assert(is_call_site_change(), "bad cast");
return (CallSiteDepChange*) this;
}
+ ConstantFieldDepChange* as_constant_field_change() {
+ assert(is_constant_field_change(), "bad cast");
+ return (ConstantFieldDepChange*) this;
+ }
void print();
public:
enum ChangeType {
@@ -690,6 +726,22 @@
oop call_site() const { return _call_site(); }
oop method_handle() const { return _method_handle(); }
};
+class ConstantFieldDepChange : public DepChange {
+ private:
+ Handle _holder;
+ int _offset;
+
+ public:
+ ConstantFieldDepChange(Handle holder, int offset) : _holder(holder), _offset(offset) {}
+
+ // What kind of DepChange is this?
+ virtual bool is_constant_field_change() const { return true; }
+
+ oop holder() const { return _holder(); }
+ int offset() const { return _offset; }
+};
+
+
#endif // SHARE_VM_CODE_DEPENDENCIES_HPP
< prev index next >