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