24
25 #ifndef SHARE_CLASSFILE_PLACEHOLDERS_HPP
26 #define SHARE_CLASSFILE_PLACEHOLDERS_HPP
27
28 #include "oops/symbolHandle.hpp"
29
30 class PlaceholderEntry;
31 class Thread;
32 class ClassLoaderData;
33
34 // Placeholder objects. These represent classes currently
35 // being loaded, as well as arrays of primitives.
36 //
37
38 class PlaceholderTable : public AllStatic {
39 public:
40 // caller to create a placeholder entry must enumerate an action
41 // caller claims ownership of that action
42 // For parallel classloading:
43 // multiple LOAD_INSTANCE threads can proceed in parallel
44 // multiple LOAD_SUPER threads can proceed in parallel
45 // LOAD_SUPER needed to check for class circularity
46 // DEFINE_CLASS: ultimately define class must be single threaded
47 // on a class/classloader basis
48 // so the head of that queue owns the token
49 // and the rest of the threads return the result the first thread gets
50 enum classloadAction {
51 LOAD_INSTANCE = 1, // calling load_instance_class
52 LOAD_SUPER = 2, // loading superclass for this class
53 DEFINE_CLASS = 3 // find_or_define class
54 };
55 static void initialize();
56 static PlaceholderEntry* get_entry(Symbol* name, ClassLoaderData* loader_data);
57
58 // find_and_add returns probe pointer - old or new
59 // If no entry exists, add a placeholder entry and push SeenThread for classloadAction
60 // If entry exists, reuse entry and push SeenThread for classloadAction
61 static PlaceholderEntry* find_and_add(Symbol* name, ClassLoaderData* loader_data,
62 classloadAction action, Symbol* supername,
63 JavaThread* thread);
64
65 // find_and_remove first removes SeenThread for classloadAction
66 // If all queues are empty and definer is null, remove the PlacheholderEntry completely
67 static void find_and_remove(Symbol* name, ClassLoaderData* loader_data,
68 classloadAction action, JavaThread* thread);
69
70 static void print_on(outputStream* st);
71 static void print();
72 };
73
74 class SeenThread;
75
76 // Placeholder objects represent classes currently being loaded.
77 // All threads examining the placeholder table must hold the
78 // SystemDictionary_lock, so we don't need special precautions
79 // on store ordering here.
80 // The system dictionary is the only user of this class.
81 class PlaceholderEntry {
82 friend class PlaceholderTable;
83 private:
84 SymbolHandle _supername;
85 JavaThread* _definer; // owner of define token
86 InstanceKlass* _instanceKlass; // InstanceKlass from successful define
87 SeenThread* _superThreadQ; // doubly-linked queue of Threads loading a superclass for this class
88 SeenThread* _loadInstanceThreadQ; // loadInstance thread
89 // This can't be multiple threads since class loading waits for
90 // this token to be removed.
91
92 SeenThread* _defineThreadQ; // queue of Threads trying to define this class
93 // including _definer
94 // _definer owns token
95 // queue waits for and returns results from _definer
96
97 SeenThread* actionToQueue(PlaceholderTable::classloadAction action);
98 void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action);
99 void add_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
100 bool remove_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
101
102 SeenThread* superThreadQ() const { return _superThreadQ; }
103 void set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; }
104
105 SeenThread* loadInstanceThreadQ() const { return _loadInstanceThreadQ; }
106 void set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; }
107
108 SeenThread* defineThreadQ() const { return _defineThreadQ; }
109 void set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
110 public:
111 PlaceholderEntry() :
112 _definer(nullptr), _instanceKlass(nullptr),
113 _superThreadQ(nullptr), _loadInstanceThreadQ(nullptr), _defineThreadQ(nullptr) { }
114
115 Symbol* supername() const { return _supername; }
116 void set_supername(Symbol* supername);
117
118 JavaThread* definer() const {return _definer; }
119 void set_definer(JavaThread* definer) { _definer = definer; }
120
121 InstanceKlass* instance_klass() const {return _instanceKlass; }
122 void set_instance_klass(InstanceKlass* ik) { _instanceKlass = ik; }
123
124 bool super_load_in_progress() {
125 return (_superThreadQ != nullptr);
126 }
127
128 bool instance_load_in_progress() {
129 return (_loadInstanceThreadQ != nullptr);
130 }
131
132 bool define_class_in_progress() {
133 return (_defineThreadQ != nullptr);
134 }
135
136 // Used for ClassCircularityError checking
137 bool check_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
138
139 void print_on(outputStream* st) const;
140 };
141
142 #endif // SHARE_CLASSFILE_PLACEHOLDERS_HPP
|
24
25 #ifndef SHARE_CLASSFILE_PLACEHOLDERS_HPP
26 #define SHARE_CLASSFILE_PLACEHOLDERS_HPP
27
28 #include "oops/symbolHandle.hpp"
29
30 class PlaceholderEntry;
31 class Thread;
32 class ClassLoaderData;
33
34 // Placeholder objects. These represent classes currently
35 // being loaded, as well as arrays of primitives.
36 //
37
38 class PlaceholderTable : public AllStatic {
39 public:
40 // caller to create a placeholder entry must enumerate an action
41 // caller claims ownership of that action
42 // For parallel classloading:
43 // multiple LOAD_INSTANCE threads can proceed in parallel
44 // multiple DETECT_CIRCULARITY threads can proceed in parallel
45 // DETECT_CIRCULARITY needed to check for class circularity
46 // DEFINE_CLASS: ultimately define class must be single threaded
47 // on a class/classloader basis
48 // so the head of that queue owns the token
49 // and the rest of the threads return the result the first thread gets
50 // VALUE_OBJECT_FIELD: needed to check for inline type fields circularity
51 enum classloadAction {
52 LOAD_INSTANCE = 1, // calling load_instance_class
53 DETECT_CIRCULARITY = 2, // loading while detecting class circularity
54 DEFINE_CLASS = 3 // find_or_define class
55 };
56 static void initialize();
57 static PlaceholderEntry* get_entry(Symbol* name, ClassLoaderData* loader_data);
58
59 // find_and_add returns probe pointer - old or new
60 // If no entry exists, add a placeholder entry and push SeenThread for classloadAction
61 // If entry exists, reuse entry and push SeenThread for classloadAction
62 static PlaceholderEntry* find_and_add(Symbol* name, ClassLoaderData* loader_data,
63 classloadAction action, Symbol* supername,
64 JavaThread* thread);
65
66 // find_and_remove first removes SeenThread for classloadAction
67 // If all queues are empty and definer is null, remove the PlacheholderEntry completely
68 static void find_and_remove(Symbol* name, ClassLoaderData* loader_data,
69 classloadAction action, JavaThread* thread);
70
71 static void print_on(outputStream* st);
72 static void print();
73 };
74
75 class SeenThread;
76
77 // Placeholder objects represent classes currently being loaded.
78 // All threads examining the placeholder table must hold the
79 // SystemDictionary_lock, so we don't need special precautions
80 // on store ordering here.
81 // The system dictionary is the only user of this class.
82 class PlaceholderEntry {
83 friend class PlaceholderTable;
84 private:
85 SymbolHandle _next_klass_name;
86 JavaThread* _definer; // owner of define token
87 InstanceKlass* _instanceKlass; // InstanceKlass from successful define
88 SeenThread* _circularityThreadQ; // doubly-linked queue of Threads loading with circularity detection
89 SeenThread* _loadInstanceThreadQ; // loadInstance thread
90 // This can't be multiple threads since class loading waits for
91 // this token to be removed.
92
93 SeenThread* _defineThreadQ; // queue of Threads trying to define this class
94 // including _definer
95 // _definer owns token
96 // queue waits for and returns results from _definer
97
98 SeenThread* actionToQueue(PlaceholderTable::classloadAction action);
99 void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action);
100 void add_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
101 bool remove_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
102
103 SeenThread* superThreadQ() const { return _circularityThreadQ; }
104 void set_superThreadQ(SeenThread* SeenThread) { _circularityThreadQ = SeenThread; }
105
106 SeenThread* loadInstanceThreadQ() const { return _loadInstanceThreadQ; }
107 void set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; }
108
109 SeenThread* defineThreadQ() const { return _defineThreadQ; }
110 void set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
111 public:
112 PlaceholderEntry() :
113 _definer(nullptr), _instanceKlass(nullptr),
114 _circularityThreadQ(nullptr), _loadInstanceThreadQ(nullptr), _defineThreadQ(nullptr) { }
115
116 Symbol* next_klass_name() const { return _next_klass_name; }
117 void set_next_klass_name(Symbol* next_klass_name);
118
119 JavaThread* definer() const {return _definer; }
120 void set_definer(JavaThread* definer) { _definer = definer; }
121
122 InstanceKlass* instance_klass() const {return _instanceKlass; }
123 void set_instance_klass(InstanceKlass* ik) { _instanceKlass = ik; }
124
125 bool circularity_detection_in_progress() {
126 return (_circularityThreadQ != nullptr);
127 }
128
129 bool instance_load_in_progress() {
130 return (_loadInstanceThreadQ != nullptr);
131 }
132
133 bool define_class_in_progress() {
134 return (_defineThreadQ != nullptr);
135 }
136
137 // Used for ClassCircularityError checking
138 bool check_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
139
140 void print_on(outputStream* st) const;
141 };
142
143 #endif // SHARE_CLASSFILE_PLACEHOLDERS_HPP
|