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
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
|
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 // PRIMITIVE_OBJECT_FIELD: needed to check for inline type fields circularity
51 enum classloadAction {
52 LOAD_INSTANCE = 1, // calling load_instance_class
53 LOAD_SUPER = 2, // loading superclass for this class
54 DEFINE_CLASS = 3, // find_or_define class
55 PRIMITIVE_OBJECT_FIELD = 4 // primitive object fields
56 };
57 static void initialize();
58 static PlaceholderEntry* get_entry(Symbol* name, ClassLoaderData* loader_data);
59
60 // find_and_add returns probe pointer - old or new
61 // If no entry exists, add a placeholder entry and push SeenThread for classloadAction
62 // If entry exists, reuse entry and push SeenThread for classloadAction
63 static PlaceholderEntry* find_and_add(Symbol* name, ClassLoaderData* loader_data,
64 classloadAction action, Symbol* supername,
65 JavaThread* thread);
66
67 // find_and_remove first removes SeenThread for classloadAction
68 // If all queues are empty and definer is null, remove the PlacheholderEntry completely
69 static void find_and_remove(Symbol* name, ClassLoaderData* loader_data,
70 classloadAction action, JavaThread* thread);
71
72 static void print_on(outputStream* st);
73 static void print();
74 };
75
78 // Placeholder objects represent classes currently being loaded.
79 // All threads examining the placeholder table must hold the
80 // SystemDictionary_lock, so we don't need special precautions
81 // on store ordering here.
82 // The system dictionary is the only user of this class.
83 class PlaceholderEntry {
84 friend class PlaceholderTable;
85 private:
86 SymbolHandle _supername;
87 JavaThread* _definer; // owner of define token
88 InstanceKlass* _instanceKlass; // InstanceKlass from successful define
89 SeenThread* _superThreadQ; // doubly-linked queue of Threads loading a superclass for this class
90 SeenThread* _loadInstanceThreadQ; // loadInstance thread
91 // This can't be multiple threads since class loading waits for
92 // this token to be removed.
93
94 SeenThread* _defineThreadQ; // queue of Threads trying to define this class
95 // including _definer
96 // _definer owns token
97 // queue waits for and returns results from _definer
98 SeenThread* _inlineTypeFieldQ; // queue of inline types for circularity checking
99
100 SeenThread* actionToQueue(PlaceholderTable::classloadAction action);
101 void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action);
102 void add_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
103 bool remove_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
104
105 SeenThread* superThreadQ() const { return _superThreadQ; }
106 void set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; }
107
108 SeenThread* loadInstanceThreadQ() const { return _loadInstanceThreadQ; }
109 void set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; }
110
111 SeenThread* defineThreadQ() const { return _defineThreadQ; }
112 void set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
113 public:
114 PlaceholderEntry() :
115 _definer(nullptr), _instanceKlass(nullptr),
116 _superThreadQ(nullptr), _loadInstanceThreadQ(nullptr), _defineThreadQ(nullptr),
117 _inlineTypeFieldQ(nullptr) { }
118
119 Symbol* supername() const { return _supername; }
120 void set_supername(Symbol* supername);
121
122 JavaThread* definer() const {return _definer; }
123 void set_definer(JavaThread* definer) { _definer = definer; }
124
125 InstanceKlass* instance_klass() const {return _instanceKlass; }
126 void set_instance_klass(InstanceKlass* ik) { _instanceKlass = ik; }
127
128 SeenThread* inlineTypeFieldQ() const { return _inlineTypeFieldQ; }
129 void set_inlineTypeFieldQ(SeenThread* SeenThread) { _inlineTypeFieldQ = SeenThread; }
130
131 bool super_load_in_progress() {
132 return (_superThreadQ != nullptr);
133 }
134
135 bool instance_load_in_progress() {
136 return (_loadInstanceThreadQ != nullptr);
137 }
138
139 bool define_class_in_progress() {
140 return (_defineThreadQ != nullptr);
141 }
142
143 bool inline_type_field_in_progress() {
144 return (_inlineTypeFieldQ != nullptr);
145 }
146
147 // Used for ClassCircularityError checking
148 bool check_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
149
150 void print_on(outputStream* st) const;
151 };
152
153 #endif // SHARE_CLASSFILE_PLACEHOLDERS_HPP
|