Mercurial > hg > graal-compiler
diff src/share/vm/code/dependencies.hpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | b27c72d69fd1 |
children | eec7173947a1 3aaa4b9966f6 3c048df3ef8b 9906d432d6db |
line wrap: on
line diff
--- a/src/share/vm/code/dependencies.hpp Fri Aug 31 16:39:35 2012 -0700 +++ b/src/share/vm/code/dependencies.hpp Sat Sep 01 13:25:18 2012 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -203,7 +203,7 @@ private: // State for writing a new set of dependencies: GrowableArray<int>* _dep_seen; // (seen[h->ident] & (1<<dept)) - GrowableArray<ciObject*>* _deps[TYPE_LIMIT]; + GrowableArray<ciBaseObject*>* _deps[TYPE_LIMIT]; static const char* _dep_name[TYPE_LIMIT]; static int _dep_args[TYPE_LIMIT]; @@ -212,7 +212,7 @@ return (int)dept >= 0 && dept < TYPE_LIMIT && ((1<<dept) & mask) != 0; } - bool note_dep_seen(int dept, ciObject* x) { + bool note_dep_seen(int dept, ciBaseObject* x) { assert(dept < BitsPerInt, "oob"); int x_id = x->ident(); assert(_dep_seen != NULL, "deps must be writable"); @@ -222,7 +222,7 @@ return (seen & (1<<dept)) != 0; } - bool maybe_merge_ctxk(GrowableArray<ciObject*>* deps, + bool maybe_merge_ctxk(GrowableArray<ciBaseObject*>* deps, int ctxk_i, ciKlass* ctxk); void sort_all_deps(); @@ -260,9 +260,9 @@ assert(!is_concrete_klass(ctxk->as_instance_klass()), "must be abstract"); } - void assert_common_1(DepType dept, ciObject* x); - void assert_common_2(DepType dept, ciObject* x0, ciObject* x1); - void assert_common_3(DepType dept, ciKlass* ctxk, ciObject* x1, ciObject* x2); + void assert_common_1(DepType dept, ciBaseObject* x); + void assert_common_2(DepType dept, ciBaseObject* x0, ciBaseObject* x1); + void assert_common_3(DepType dept, ciKlass* ctxk, ciBaseObject* x1, ciBaseObject* x2); public: // Adding assertions to a new dependency set at compile time: @@ -286,8 +286,8 @@ // methods to remain non-concrete until their first invocation. // In that case, there would be a middle ground between concrete // and abstract (as defined by the Java language and VM). - static bool is_concrete_klass(klassOop k); // k is instantiable - static bool is_concrete_method(methodOop m); // m is invocable + static bool is_concrete_klass(Klass* k); // k is instantiable + static bool is_concrete_method(Method* m); // m is invocable static Klass* find_finalizable_subclass(Klass* k); // These versions of the concreteness queries work through the CI. @@ -314,24 +314,24 @@ // dependency on it must fail. // Checking old assertions at run-time (in the VM only): - static klassOop check_evol_method(methodOop m); - static klassOop check_leaf_type(klassOop ctxk); - static klassOop check_abstract_with_unique_concrete_subtype(klassOop ctxk, klassOop conck, + static Klass* check_evol_method(Method* m); + static Klass* check_leaf_type(Klass* ctxk); + static Klass* check_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck, KlassDepChange* changes = NULL); - static klassOop check_abstract_with_no_concrete_subtype(klassOop ctxk, + static Klass* check_abstract_with_no_concrete_subtype(Klass* ctxk, KlassDepChange* changes = NULL); - static klassOop check_concrete_with_no_concrete_subtype(klassOop ctxk, + static Klass* check_concrete_with_no_concrete_subtype(Klass* ctxk, KlassDepChange* changes = NULL); - static klassOop check_unique_concrete_method(klassOop ctxk, methodOop uniqm, + static Klass* check_unique_concrete_method(Klass* ctxk, Method* uniqm, KlassDepChange* changes = NULL); - static klassOop check_abstract_with_exclusive_concrete_subtypes(klassOop ctxk, klassOop k1, klassOop k2, + static Klass* check_abstract_with_exclusive_concrete_subtypes(Klass* ctxk, Klass* k1, Klass* k2, KlassDepChange* changes = NULL); - static klassOop check_exclusive_concrete_methods(klassOop ctxk, methodOop m1, methodOop m2, + static Klass* check_exclusive_concrete_methods(Klass* ctxk, Method* m1, Method* m2, KlassDepChange* changes = NULL); - static klassOop check_has_no_finalizable_subclasses(klassOop ctxk, KlassDepChange* changes = NULL); - static klassOop check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes = NULL); - // A returned klassOop is NULL if the dependency assertion is still - // valid. A non-NULL klassOop is a 'witness' to the assertion + static Klass* check_has_no_finalizable_subclasses(Klass* ctxk, KlassDepChange* changes = NULL); + static Klass* check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes = NULL); + // A returned Klass* is NULL if the dependency assertion is still + // valid. A non-NULL Klass* is a 'witness' to the assertion // failure, a point in the class hierarchy where the assertion has // been proven false. For example, if check_leaf_type returns // non-NULL, the value is a subtype of the supposed leaf type. This @@ -345,10 +345,10 @@ // It is used by DepStream::spot_check_dependency_at. // Detecting possible new assertions: - static klassOop find_unique_concrete_subtype(klassOop ctxk); - static methodOop find_unique_concrete_method(klassOop ctxk, methodOop m); - static int find_exclusive_concrete_subtypes(klassOop ctxk, int klen, klassOop k[]); - static int find_exclusive_concrete_methods(klassOop ctxk, int mlen, methodOop m[]); + 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 int find_exclusive_concrete_methods(Klass* ctxk, int mlen, Method* m[]); // Create the encoding which will be stored in an nmethod. void encode_content_bytes(); @@ -368,15 +368,15 @@ void copy_to(nmethod* nm); void log_all_dependencies(); - void log_dependency(DepType dept, int nargs, ciObject* args[]) { + void log_dependency(DepType dept, int nargs, ciBaseObject* args[]) { write_dependency_to(log(), dept, nargs, args); } void log_dependency(DepType dept, - ciObject* x0, - ciObject* x1 = NULL, - ciObject* x2 = NULL) { + ciBaseObject* x0, + ciBaseObject* x1 = NULL, + ciBaseObject* x2 = NULL) { if (log() == NULL) return; - ciObject* args[max_arg_count]; + ciBaseObject* args[max_arg_count]; args[0] = x0; args[1] = x1; args[2] = x2; @@ -384,27 +384,47 @@ log_dependency(dept, dep_args(dept), args); } - static void write_dependency_to(CompileLog* log, - DepType dept, - int nargs, ciObject* args[], - klassOop witness = NULL); + class DepArgument : public ResourceObj { + private: + bool _is_oop; + bool _valid; + void* _value; + public: + DepArgument() : _is_oop(false), _value(NULL), _valid(false) {} + DepArgument(oop v): _is_oop(true), _value(v), _valid(true) {} + DepArgument(Metadata* v): _is_oop(false), _value(v), _valid(true) {} + + bool is_null() const { return _value == NULL; } + bool is_oop() const { return _is_oop; } + bool is_metadata() const { return !_is_oop; } + bool is_klass() const { return is_metadata() && metadata_value()->is_klass(); } + bool is_method() const { return is_metadata() && metadata_value()->is_method(); } + + oop oop_value() const { assert(_is_oop && _valid, "must be"); return (oop) _value; } + Metadata* metadata_value() const { assert(!_is_oop && _valid, "must be"); return (Metadata*) _value; } + }; + static void write_dependency_to(CompileLog* log, DepType dept, - int nargs, oop args[], - klassOop witness = NULL); + int nargs, ciBaseObject* args[], + Klass* witness = NULL); + static void write_dependency_to(CompileLog* log, + DepType dept, + int nargs, DepArgument args[], + Klass* witness = NULL); static void write_dependency_to(xmlStream* xtty, DepType dept, - int nargs, oop args[], - klassOop witness = NULL); + int nargs, DepArgument args[], + Klass* witness = NULL); static void print_dependency(DepType dept, - int nargs, oop args[], - klassOop witness = NULL); + int nargs, DepArgument args[], + Klass* witness = NULL); private: // helper for encoding common context types as zero: - static ciKlass* ctxk_encoded_as_null(DepType dept, ciObject* x); + static ciKlass* ctxk_encoded_as_null(DepType dept, ciBaseObject* x); - static klassOop ctxk_encoded_as_null(DepType dept, oop x); + static Klass* ctxk_encoded_as_null(DepType dept, Metadata* x); public: // Use this to iterate over an nmethod's dependency set. @@ -433,13 +453,13 @@ void initial_asserts(size_t byte_limit) NOT_DEBUG({}); + inline Metadata* recorded_metadata_at(int i); inline oop recorded_oop_at(int i); - // => _code? _code->oop_at(i): *_deps->_oop_recorder->handle_at(i) - klassOop check_klass_dependency(KlassDepChange* changes); - klassOop check_call_site_dependency(CallSiteDepChange* changes); + Klass* check_klass_dependency(KlassDepChange* changes); + Klass* check_call_site_dependency(CallSiteDepChange* changes); - void trace_and_log_witness(klassOop witness); + void trace_and_log_witness(Klass* witness); public: DepStream(Dependencies* deps) @@ -463,38 +483,39 @@ int argument_count() { return dep_args(type()); } int argument_index(int i) { assert(0 <= i && i < argument_count(), "oob"); return _xi[i]; } - oop argument(int i); // => recorded_oop_at(argument_index(i)) - klassOop context_type(); + Metadata* argument(int i); // => recorded_oop_at(argument_index(i)) + oop argument_oop(int i); // => recorded_oop_at(argument_index(i)) + Klass* context_type(); bool is_klass_type() { return Dependencies::is_klass_type(type()); } - methodOop method_argument(int i) { - oop x = argument(i); + Method* method_argument(int i) { + Metadata* x = argument(i); assert(x->is_method(), "type"); - return (methodOop) x; + return (Method*) x; } - klassOop type_argument(int i) { - oop x = argument(i); + Klass* type_argument(int i) { + Metadata* x = argument(i); assert(x->is_klass(), "type"); - return (klassOop) x; + return (Klass*) x; } // The point of the whole exercise: Is this dep still OK? - klassOop check_dependency() { - klassOop result = check_klass_dependency(NULL); + Klass* check_dependency() { + Klass* result = check_klass_dependency(NULL); if (result != NULL) return result; return check_call_site_dependency(NULL); } // A lighter version: Checks only around recent changes in a class // hierarchy. (See Universe::flush_dependents_on.) - klassOop spot_check_dependency_at(DepChange& changes); + Klass* spot_check_dependency_at(DepChange& changes); // Log the current dependency to xtty or compilation log. - void log_dependency(klassOop witness = NULL); + void log_dependency(Klass* witness = NULL); // Print the current dependency to tty. - void print_dependency(klassOop witness = NULL, bool verbose = false); + void print_dependency(Klass* witness = NULL, bool verbose = false); }; friend class Dependencies::DepStream; @@ -533,7 +554,7 @@ // Usage: // for (DepChange::ContextStream str(changes); str.next(); ) { - // klassOop k = str.klass(); + // Klass* k = str.klass(); // switch (str.change_type()) { // ... // } @@ -545,8 +566,8 @@ // iteration variables: ChangeType _change_type; - klassOop _klass; - objArrayOop _ti_base; // i.e., transitive_interfaces + Klass* _klass; + Array<Klass*>* _ti_base; // i.e., transitive_interfaces int _ti_index; int _ti_limit; @@ -566,7 +587,7 @@ bool next(); ChangeType change_type() { return _change_type; } - klassOop klass() { return _klass; } + Klass* klass() { return _klass; } }; friend class DepChange::ContextStream; }; @@ -598,10 +619,10 @@ // What kind of DepChange is this? virtual bool is_klass_change() const { return true; } - klassOop new_type() { return _new_type(); } + Klass* new_type() { return _new_type(); } // involves_context(k) is true if k is new_type or any of the super types - bool involves_context(klassOop k); + bool involves_context(Klass* k); };