92 }
93 // If the entry is not set, it will throw AbstractMethodError.
94 }
95 }
96
97 void MethodHandles::set_enabled(bool z) {
98 if (_enabled != z) {
99 guarantee(z && EnableInvokeDynamic, "can only enable once, and only if -XX:+EnableInvokeDynamic");
100 _enabled = z;
101 }
102 }
103
104 // MemberName support
105
106 // import java_lang_invoke_MemberName.*
107 enum {
108 IS_METHOD = java_lang_invoke_MemberName::MN_IS_METHOD,
109 IS_CONSTRUCTOR = java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR,
110 IS_FIELD = java_lang_invoke_MemberName::MN_IS_FIELD,
111 IS_TYPE = java_lang_invoke_MemberName::MN_IS_TYPE,
112 REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT,
113 REFERENCE_KIND_MASK = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,
114 SEARCH_SUPERCLASSES = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES,
115 SEARCH_INTERFACES = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES,
116 ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE
117 };
118
119 Handle MethodHandles::new_MemberName(TRAPS) {
120 Handle empty;
121 instanceKlassHandle k(THREAD, SystemDictionary::MemberName_klass());
122 if (!k->is_initialized()) k->initialize(CHECK_(empty));
123 return Handle(THREAD, k->allocate_instance(THREAD));
124 }
125
126 oop MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
127 Klass* target_klass = target_oop->klass();
128 if (target_klass == SystemDictionary::reflect_Field_klass()) {
129 oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
130 int slot = java_lang_reflect_Field::slot(target_oop); // fd.index()
131 int mods = java_lang_reflect_Field::modifiers(target_oop);
190 !receiver_limit->is_subtype_of(mklass)) {
191 return NULL; // bad receiver limit
192 } else if (receiver_limit->is_interface() &&
193 mklass->is_interface()) {
194 flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT);
195 receiver_limit = mklass; // ignore passed-in limit; interfaces are interconvertible
196 vmindex = klassItable::compute_itable_index(m);
197 } else if (mklass != receiver_limit && mklass->is_interface()) {
198 flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
199 // it is a miranda method, so m->vtable_index is not what we want
200 ResourceMark rm;
201 klassVtable* vt = InstanceKlass::cast(receiver_limit)->vtable();
202 vmindex = vt->index_of_miranda(m->name(), m->signature());
203 } else if (!do_dispatch || m->can_be_statically_bound()) {
204 flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
205 } else {
206 flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
207 vmindex = m->vtable_index();
208 }
209
210 java_lang_invoke_MemberName::set_flags(mname_oop, flags);
211 java_lang_invoke_MemberName::set_vmtarget(mname_oop, m);
212 java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex); // vtable/itable index
213 java_lang_invoke_MemberName::set_clazz(mname_oop, receiver_limit->java_mirror());
214 // Note: name and type can be lazily computed by resolve_MemberName,
215 // if Java code needs them as resolved String and MethodType objects.
216 // The clazz must be eagerly stored, because it provides a GC
217 // root to help keep alive the Method*.
218 // If relevant, the vtable or itable value is stored as vmindex.
219 // This is done eagerly, since it is readily available without
220 // constructing any new objects.
221 // TO DO: maybe intern mname_oop
222 return mname_oop;
223 }
224
225 Handle MethodHandles::init_method_MemberName(oop mname_oop, CallInfo& info, TRAPS) {
226 Handle empty;
227 if (info.resolved_appendix().not_null()) {
228 // The resolved MemberName must not be accompanied by an appendix argument,
229 // since there is no way to bind this value into the MemberName.
230 // Caller is responsible to prevent this from happening.
231 THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty);
232 }
233 methodHandle m = info.resolved_method();
923 JVM_ENTRY(jint, MHN_getConstant(JNIEnv *env, jobject igcls, jint which)) {
924 switch (which) {
925 case MethodHandles::GC_COUNT_GWT:
926 #ifdef COMPILER2
927 return true;
928 #else
929 return false;
930 #endif
931 }
932 return 0;
933 }
934 JVM_END
935
936 #ifndef PRODUCT
937 #define EACH_NAMED_CON(template, requirement) \
938 template(MethodHandles,GC_COUNT_GWT) \
939 template(java_lang_invoke_MemberName,MN_IS_METHOD) \
940 template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \
941 template(java_lang_invoke_MemberName,MN_IS_FIELD) \
942 template(java_lang_invoke_MemberName,MN_IS_TYPE) \
943 template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \
944 template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \
945 template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_SHIFT) \
946 template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_MASK) \
947 template(MethodHandles,GC_LAMBDA_SUPPORT) \
948 /*end*/
949
950 #define IGNORE_REQ(req_expr) /* req_expr */
951 #define ONE_PLUS(scope,value) 1+
952 static const int con_value_count = EACH_NAMED_CON(ONE_PLUS, IGNORE_REQ) 0;
953 #define VALUE_COMMA(scope,value) scope::value,
954 static const int con_values[con_value_count+1] = { EACH_NAMED_CON(VALUE_COMMA, IGNORE_REQ) 0 };
955 #define STRING_NULL(scope,value) #value "\0"
956 static const char con_names[] = { EACH_NAMED_CON(STRING_NULL, IGNORE_REQ) };
957
958 static bool advertise_con_value(int which) {
959 if (which < 0) return false;
960 bool ok = true;
961 int count = 0;
962 #define INC_COUNT(scope,value) \
|
92 }
93 // If the entry is not set, it will throw AbstractMethodError.
94 }
95 }
96
97 void MethodHandles::set_enabled(bool z) {
98 if (_enabled != z) {
99 guarantee(z && EnableInvokeDynamic, "can only enable once, and only if -XX:+EnableInvokeDynamic");
100 _enabled = z;
101 }
102 }
103
104 // MemberName support
105
106 // import java_lang_invoke_MemberName.*
107 enum {
108 IS_METHOD = java_lang_invoke_MemberName::MN_IS_METHOD,
109 IS_CONSTRUCTOR = java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR,
110 IS_FIELD = java_lang_invoke_MemberName::MN_IS_FIELD,
111 IS_TYPE = java_lang_invoke_MemberName::MN_IS_TYPE,
112 CALLER_SENSITIVE = java_lang_invoke_MemberName::MN_CALLER_SENSITIVE,
113 REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT,
114 REFERENCE_KIND_MASK = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,
115 SEARCH_SUPERCLASSES = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES,
116 SEARCH_INTERFACES = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES,
117 ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE
118 };
119
120 Handle MethodHandles::new_MemberName(TRAPS) {
121 Handle empty;
122 instanceKlassHandle k(THREAD, SystemDictionary::MemberName_klass());
123 if (!k->is_initialized()) k->initialize(CHECK_(empty));
124 return Handle(THREAD, k->allocate_instance(THREAD));
125 }
126
127 oop MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
128 Klass* target_klass = target_oop->klass();
129 if (target_klass == SystemDictionary::reflect_Field_klass()) {
130 oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
131 int slot = java_lang_reflect_Field::slot(target_oop); // fd.index()
132 int mods = java_lang_reflect_Field::modifiers(target_oop);
191 !receiver_limit->is_subtype_of(mklass)) {
192 return NULL; // bad receiver limit
193 } else if (receiver_limit->is_interface() &&
194 mklass->is_interface()) {
195 flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT);
196 receiver_limit = mklass; // ignore passed-in limit; interfaces are interconvertible
197 vmindex = klassItable::compute_itable_index(m);
198 } else if (mklass != receiver_limit && mklass->is_interface()) {
199 flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
200 // it is a miranda method, so m->vtable_index is not what we want
201 ResourceMark rm;
202 klassVtable* vt = InstanceKlass::cast(receiver_limit)->vtable();
203 vmindex = vt->index_of_miranda(m->name(), m->signature());
204 } else if (!do_dispatch || m->can_be_statically_bound()) {
205 flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
206 } else {
207 flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
208 vmindex = m->vtable_index();
209 }
210
211 // @CallerSensitive annotation detected
212 if (m->caller_sensitive()) {
213 flags |= CALLER_SENSITIVE;
214 }
215
216 java_lang_invoke_MemberName::set_flags( mname_oop, flags);
217 java_lang_invoke_MemberName::set_vmtarget(mname_oop, m);
218 java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex); // vtable/itable index
219 java_lang_invoke_MemberName::set_clazz( mname_oop, receiver_limit->java_mirror());
220 // Note: name and type can be lazily computed by resolve_MemberName,
221 // if Java code needs them as resolved String and MethodType objects.
222 // The clazz must be eagerly stored, because it provides a GC
223 // root to help keep alive the Method*.
224 // If relevant, the vtable or itable value is stored as vmindex.
225 // This is done eagerly, since it is readily available without
226 // constructing any new objects.
227 // TO DO: maybe intern mname_oop
228 return mname_oop;
229 }
230
231 Handle MethodHandles::init_method_MemberName(oop mname_oop, CallInfo& info, TRAPS) {
232 Handle empty;
233 if (info.resolved_appendix().not_null()) {
234 // The resolved MemberName must not be accompanied by an appendix argument,
235 // since there is no way to bind this value into the MemberName.
236 // Caller is responsible to prevent this from happening.
237 THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty);
238 }
239 methodHandle m = info.resolved_method();
929 JVM_ENTRY(jint, MHN_getConstant(JNIEnv *env, jobject igcls, jint which)) {
930 switch (which) {
931 case MethodHandles::GC_COUNT_GWT:
932 #ifdef COMPILER2
933 return true;
934 #else
935 return false;
936 #endif
937 }
938 return 0;
939 }
940 JVM_END
941
942 #ifndef PRODUCT
943 #define EACH_NAMED_CON(template, requirement) \
944 template(MethodHandles,GC_COUNT_GWT) \
945 template(java_lang_invoke_MemberName,MN_IS_METHOD) \
946 template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \
947 template(java_lang_invoke_MemberName,MN_IS_FIELD) \
948 template(java_lang_invoke_MemberName,MN_IS_TYPE) \
949 template(java_lang_invoke_MemberName,MN_CALLER_SENSITIVE) \
950 template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \
951 template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \
952 template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_SHIFT) \
953 template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_MASK) \
954 template(MethodHandles,GC_LAMBDA_SUPPORT) \
955 /*end*/
956
957 #define IGNORE_REQ(req_expr) /* req_expr */
958 #define ONE_PLUS(scope,value) 1+
959 static const int con_value_count = EACH_NAMED_CON(ONE_PLUS, IGNORE_REQ) 0;
960 #define VALUE_COMMA(scope,value) scope::value,
961 static const int con_values[con_value_count+1] = { EACH_NAMED_CON(VALUE_COMMA, IGNORE_REQ) 0 };
962 #define STRING_NULL(scope,value) #value "\0"
963 static const char con_names[] = { EACH_NAMED_CON(STRING_NULL, IGNORE_REQ) };
964
965 static bool advertise_con_value(int which) {
966 if (which < 0) return false;
967 bool ok = true;
968 int count = 0;
969 #define INC_COUNT(scope,value) \
|