16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "ci/ciArrayKlass.hpp"
27 #include "ci/ciEnv.hpp"
28 #include "ci/ciKlass.hpp"
29 #include "ci/ciMethod.hpp"
30 #include "classfile/javaClasses.inline.hpp"
31 #include "code/dependencies.hpp"
32 #include "compiler/compileLog.hpp"
33 #include "compiler/compileBroker.hpp"
34 #include "compiler/compileTask.hpp"
35 #include "memory/resourceArea.hpp"
36 #include "oops/oop.inline.hpp"
37 #include "oops/objArrayKlass.hpp"
38 #include "runtime/flags/flagSetting.hpp"
39 #include "runtime/handles.hpp"
40 #include "runtime/handles.inline.hpp"
41 #include "runtime/jniHandles.inline.hpp"
42 #include "runtime/thread.inline.hpp"
43 #include "utilities/copy.hpp"
44
45
46 #ifdef ASSERT
47 static bool must_be_in_vm() {
48 Thread* thread = Thread::current();
49 if (thread->is_Java_thread())
50 return ((JavaThread*)thread)->thread_state() == _thread_in_vm;
51 else
52 return true; //something like this: thread->is_VM_thread();
53 }
54 #endif //ASSERT
55
1211 void add_participant(Klass* participant) {
1212 assert(_num_participants + _record_witnesses < PARTICIPANT_LIMIT, "oob");
1213 int np = _num_participants++;
1214 _participants[np] = participant;
1215 _participants[np+1] = NULL;
1216 _found_methods[np+1] = NULL;
1217 }
1218
1219 void record_witnesses(int add) {
1220 if (add > PARTICIPANT_LIMIT) add = PARTICIPANT_LIMIT;
1221 assert(_num_participants + add < PARTICIPANT_LIMIT, "oob");
1222 _record_witnesses = add;
1223 }
1224
1225 bool is_witness(Klass* k) {
1226 if (doing_subtype_search()) {
1227 return Dependencies::is_concrete_klass(k);
1228 } else if (!k->is_instance_klass()) {
1229 return false; // no methods to find in an array type
1230 } else {
1231 // Search class hierarchy first.
1232 Method* m = InstanceKlass::cast(k)->find_instance_method(_name, _signature);
1233 if (!Dependencies::is_concrete_method(m, k)) {
1234 // Check for re-abstraction of method
1235 if (!k->is_interface() && m != NULL && m->is_abstract()) {
1236 // Found a matching abstract method 'm' in the class hierarchy.
1237 // This is fine iff 'k' is an abstract class and all concrete subtypes
1238 // of 'k' override 'm' and are participates of the current search.
1239 ClassHierarchyWalker wf(_participants, _num_participants);
1240 Klass* w = wf.find_witness_subtype(k);
1241 if (w != NULL) {
1242 Method* wm = InstanceKlass::cast(w)->find_instance_method(_name, _signature);
1243 if (!Dependencies::is_concrete_method(wm, w)) {
1244 // Found a concrete subtype 'w' which does not override abstract method 'm'.
1245 // Bail out because 'm' could be called with 'w' as receiver (leading to an
1246 // AbstractMethodError) and thus the method we are looking for is not unique.
1247 _found_methods[_num_participants] = m;
1248 return true;
1249 }
1250 }
1251 }
1252 // Check interface defaults also, if any exist.
|
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "ci/ciArrayKlass.hpp"
27 #include "ci/ciEnv.hpp"
28 #include "ci/ciKlass.hpp"
29 #include "ci/ciMethod.hpp"
30 #include "classfile/javaClasses.inline.hpp"
31 #include "code/dependencies.hpp"
32 #include "compiler/compileLog.hpp"
33 #include "compiler/compileBroker.hpp"
34 #include "compiler/compileTask.hpp"
35 #include "memory/resourceArea.hpp"
36 #include "oops/klass.hpp"
37 #include "oops/oop.inline.hpp"
38 #include "oops/objArrayKlass.hpp"
39 #include "runtime/flags/flagSetting.hpp"
40 #include "runtime/handles.hpp"
41 #include "runtime/handles.inline.hpp"
42 #include "runtime/jniHandles.inline.hpp"
43 #include "runtime/thread.inline.hpp"
44 #include "utilities/copy.hpp"
45
46
47 #ifdef ASSERT
48 static bool must_be_in_vm() {
49 Thread* thread = Thread::current();
50 if (thread->is_Java_thread())
51 return ((JavaThread*)thread)->thread_state() == _thread_in_vm;
52 else
53 return true; //something like this: thread->is_VM_thread();
54 }
55 #endif //ASSERT
56
1212 void add_participant(Klass* participant) {
1213 assert(_num_participants + _record_witnesses < PARTICIPANT_LIMIT, "oob");
1214 int np = _num_participants++;
1215 _participants[np] = participant;
1216 _participants[np+1] = NULL;
1217 _found_methods[np+1] = NULL;
1218 }
1219
1220 void record_witnesses(int add) {
1221 if (add > PARTICIPANT_LIMIT) add = PARTICIPANT_LIMIT;
1222 assert(_num_participants + add < PARTICIPANT_LIMIT, "oob");
1223 _record_witnesses = add;
1224 }
1225
1226 bool is_witness(Klass* k) {
1227 if (doing_subtype_search()) {
1228 return Dependencies::is_concrete_klass(k);
1229 } else if (!k->is_instance_klass()) {
1230 return false; // no methods to find in an array type
1231 } else {
1232 // Search class hierarchy first, skipping private implementations
1233 // as they never override any inherited methods
1234 Method* m = InstanceKlass::cast(k)->find_instance_method(_name, _signature, Klass::skip_private);
1235 if (!Dependencies::is_concrete_method(m, k)) {
1236 // Check for re-abstraction of method
1237 if (!k->is_interface() && m != NULL && m->is_abstract()) {
1238 // Found a matching abstract method 'm' in the class hierarchy.
1239 // This is fine iff 'k' is an abstract class and all concrete subtypes
1240 // of 'k' override 'm' and are participates of the current search.
1241 ClassHierarchyWalker wf(_participants, _num_participants);
1242 Klass* w = wf.find_witness_subtype(k);
1243 if (w != NULL) {
1244 Method* wm = InstanceKlass::cast(w)->find_instance_method(_name, _signature);
1245 if (!Dependencies::is_concrete_method(wm, w)) {
1246 // Found a concrete subtype 'w' which does not override abstract method 'm'.
1247 // Bail out because 'm' could be called with 'w' as receiver (leading to an
1248 // AbstractMethodError) and thus the method we are looking for is not unique.
1249 _found_methods[_num_participants] = m;
1250 return true;
1251 }
1252 }
1253 }
1254 // Check interface defaults also, if any exist.
|