63 } |
63 } |
64 |
64 |
65 // ------------------------------------------------------------------ |
65 // ------------------------------------------------------------------ |
66 // Note: the logic of this method should mirror the logic of |
66 // Note: the logic of this method should mirror the logic of |
67 // constantPoolOopDesc::verify_constant_pool_resolve. |
67 // constantPoolOopDesc::verify_constant_pool_resolve. |
68 bool JVMCIEnv::check_klass_accessibility(KlassHandle accessing_klass, KlassHandle resolved_klass) { |
68 bool JVMCIEnv::check_klass_accessibility(Klass* accessing_klass, Klass* resolved_klass) { |
69 if (accessing_klass->is_objArray_klass()) { |
69 if (accessing_klass->is_objArray_klass()) { |
70 accessing_klass = ObjArrayKlass::cast(accessing_klass())->bottom_klass(); |
70 accessing_klass = ObjArrayKlass::cast(accessing_klass)->bottom_klass(); |
71 } |
71 } |
72 if (!accessing_klass->is_instance_klass()) { |
72 if (!accessing_klass->is_instance_klass()) { |
73 return true; |
73 return true; |
74 } |
74 } |
75 |
75 |
76 if (resolved_klass->is_objArray_klass()) { |
76 if (resolved_klass->is_objArray_klass()) { |
77 // Find the element klass, if this is an array. |
77 // Find the element klass, if this is an array. |
78 resolved_klass = ObjArrayKlass::cast(resolved_klass())->bottom_klass(); |
78 resolved_klass = ObjArrayKlass::cast(resolved_klass)->bottom_klass(); |
79 } |
79 } |
80 if (resolved_klass->is_instance_klass()) { |
80 if (resolved_klass->is_instance_klass()) { |
81 Reflection::VerifyClassAccessResults result = |
81 Reflection::VerifyClassAccessResults result = |
82 Reflection::verify_class_access(accessing_klass(), InstanceKlass::cast(resolved_klass()), true); |
82 Reflection::verify_class_access(accessing_klass, InstanceKlass::cast(resolved_klass), true); |
83 return result == Reflection::ACCESS_OK; |
83 return result == Reflection::ACCESS_OK; |
84 } |
84 } |
85 return true; |
85 return true; |
86 } |
86 } |
87 |
87 |
88 // ------------------------------------------------------------------ |
88 // ------------------------------------------------------------------ |
89 KlassHandle JVMCIEnv::get_klass_by_name_impl(KlassHandle& accessing_klass, |
89 Klass* JVMCIEnv::get_klass_by_name_impl(Klass* accessing_klass, |
90 const constantPoolHandle& cpool, |
90 const constantPoolHandle& cpool, |
91 Symbol* sym, |
91 Symbol* sym, |
92 bool require_local) { |
92 bool require_local) { |
93 JVMCI_EXCEPTION_CONTEXT; |
93 JVMCI_EXCEPTION_CONTEXT; |
94 |
94 |
95 // Now we need to check the SystemDictionary |
95 // Now we need to check the SystemDictionary |
96 if (sym->byte_at(0) == 'L' && |
96 if (sym->byte_at(0) == 'L' && |
97 sym->byte_at(sym->utf8_length()-1) == ';') { |
97 sym->byte_at(sym->utf8_length()-1) == ';') { |
98 // This is a name from a signature. Strip off the trimmings. |
98 // This is a name from a signature. Strip off the trimmings. |
99 // Call recursive to keep scope of strippedsym. |
99 // Call recursive to keep scope of strippedsym. |
100 TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1, |
100 TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1, |
101 sym->utf8_length()-2, |
101 sym->utf8_length()-2, |
102 CHECK_(KlassHandle())); |
102 CHECK_NULL); |
103 return get_klass_by_name_impl(accessing_klass, cpool, strippedsym, require_local); |
103 return get_klass_by_name_impl(accessing_klass, cpool, strippedsym, require_local); |
104 } |
104 } |
105 |
105 |
106 Handle loader(THREAD, (oop)NULL); |
106 Handle loader(THREAD, (oop)NULL); |
107 Handle domain(THREAD, (oop)NULL); |
107 Handle domain(THREAD, (oop)NULL); |
108 if (!accessing_klass.is_null()) { |
108 if (accessing_klass != NULL) { |
109 loader = Handle(THREAD, accessing_klass->class_loader()); |
109 loader = Handle(THREAD, accessing_klass->class_loader()); |
110 domain = Handle(THREAD, accessing_klass->protection_domain()); |
110 domain = Handle(THREAD, accessing_klass->protection_domain()); |
111 } |
111 } |
112 |
112 |
113 KlassHandle found_klass; |
113 Klass* found_klass = NULL; |
114 { |
114 { |
115 ttyUnlocker ttyul; // release tty lock to avoid ordering problems |
115 ttyUnlocker ttyul; // release tty lock to avoid ordering problems |
116 MutexLocker ml(Compile_lock); |
116 MutexLocker ml(Compile_lock); |
117 Klass* kls; |
|
118 if (!require_local) { |
117 if (!require_local) { |
119 kls = SystemDictionary::find_constrained_instance_or_array_klass(sym, loader, CHECK_(KlassHandle())); |
118 found_klass = SystemDictionary::find_constrained_instance_or_array_klass(sym, loader, CHECK_NULL); |
120 } else { |
119 } else { |
121 kls = SystemDictionary::find_instance_or_array_klass(sym, loader, domain, CHECK_(KlassHandle())); |
120 found_klass = SystemDictionary::find_instance_or_array_klass(sym, loader, domain, CHECK_NULL); |
122 } |
121 } |
123 found_klass = KlassHandle(THREAD, kls); |
|
124 } |
122 } |
125 |
123 |
126 // If we fail to find an array klass, look again for its element type. |
124 // If we fail to find an array klass, look again for its element type. |
127 // The element type may be available either locally or via constraints. |
125 // The element type may be available either locally or via constraints. |
128 // In either case, if we can find the element type in the system dictionary, |
126 // In either case, if we can find the element type in the system dictionary, |
133 (sym->byte_at(1) == '[' || sym->byte_at(1) == 'L')) { |
131 (sym->byte_at(1) == '[' || sym->byte_at(1) == 'L')) { |
134 // We have an unloaded array. |
132 // We have an unloaded array. |
135 // Build it on the fly if the element class exists. |
133 // Build it on the fly if the element class exists. |
136 TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1, |
134 TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1, |
137 sym->utf8_length()-1, |
135 sym->utf8_length()-1, |
138 CHECK_(KlassHandle())); |
136 CHECK_NULL); |
139 |
137 |
140 // Get element Klass recursively. |
138 // Get element Klass recursively. |
141 KlassHandle elem_klass = |
139 Klass* elem_klass = |
142 get_klass_by_name_impl(accessing_klass, |
140 get_klass_by_name_impl(accessing_klass, |
143 cpool, |
141 cpool, |
144 elem_sym, |
142 elem_sym, |
145 require_local); |
143 require_local); |
146 if (!elem_klass.is_null()) { |
144 if (elem_klass != NULL) { |
147 // Now make an array for it |
145 // Now make an array for it |
148 return elem_klass->array_klass(CHECK_(KlassHandle())); |
146 return elem_klass->array_klass(CHECK_NULL); |
149 } |
147 } |
150 } |
148 } |
151 |
149 |
152 if (found_klass.is_null() && !cpool.is_null() && cpool->has_preresolution()) { |
150 if (found_klass == NULL && !cpool.is_null() && cpool->has_preresolution()) { |
153 // Look inside the constant pool for pre-resolved class entries. |
151 // Look inside the constant pool for pre-resolved class entries. |
154 for (int i = cpool->length() - 1; i >= 1; i--) { |
152 for (int i = cpool->length() - 1; i >= 1; i--) { |
155 if (cpool->tag_at(i).is_klass()) { |
153 if (cpool->tag_at(i).is_klass()) { |
156 Klass* kls = cpool->resolved_klass_at(i); |
154 Klass* kls = cpool->resolved_klass_at(i); |
157 if (kls->name() == sym) { |
155 if (kls->name() == sym) { |
159 } |
157 } |
160 } |
158 } |
161 } |
159 } |
162 } |
160 } |
163 |
161 |
164 return found_klass(); |
162 return found_klass; |
165 } |
163 } |
166 |
164 |
167 // ------------------------------------------------------------------ |
165 // ------------------------------------------------------------------ |
168 KlassHandle JVMCIEnv::get_klass_by_name(KlassHandle accessing_klass, |
166 Klass* JVMCIEnv::get_klass_by_name(Klass* accessing_klass, |
169 Symbol* klass_name, |
167 Symbol* klass_name, |
170 bool require_local) { |
168 bool require_local) { |
171 ResourceMark rm; |
169 ResourceMark rm; |
172 constantPoolHandle cpool; |
170 constantPoolHandle cpool; |
173 return get_klass_by_name_impl(accessing_klass, |
171 return get_klass_by_name_impl(accessing_klass, |
174 cpool, |
172 cpool, |
175 klass_name, |
173 klass_name, |
176 require_local); |
174 require_local); |
177 } |
175 } |
178 |
176 |
179 // ------------------------------------------------------------------ |
177 // ------------------------------------------------------------------ |
180 // Implementation of get_klass_by_index. |
178 // Implementation of get_klass_by_index. |
181 KlassHandle JVMCIEnv::get_klass_by_index_impl(const constantPoolHandle& cpool, |
179 Klass* JVMCIEnv::get_klass_by_index_impl(const constantPoolHandle& cpool, |
182 int index, |
180 int index, |
183 bool& is_accessible, |
181 bool& is_accessible, |
184 KlassHandle accessor) { |
182 Klass* accessor) { |
185 JVMCI_EXCEPTION_CONTEXT; |
183 JVMCI_EXCEPTION_CONTEXT; |
186 KlassHandle klass (THREAD, ConstantPool::klass_at_if_loaded(cpool, index)); |
184 Klass* klass = ConstantPool::klass_at_if_loaded(cpool, index); |
187 Symbol* klass_name = NULL; |
185 Symbol* klass_name = NULL; |
188 if (klass.is_null()) { |
186 if (klass == NULL) { |
189 klass_name = cpool->klass_name_at(index); |
187 klass_name = cpool->klass_name_at(index); |
190 } |
188 } |
191 |
189 |
192 if (klass.is_null()) { |
190 if (klass == NULL) { |
193 // Not found in constant pool. Use the name to do the lookup. |
191 // Not found in constant pool. Use the name to do the lookup. |
194 KlassHandle k = get_klass_by_name_impl(accessor, |
192 Klass* k = get_klass_by_name_impl(accessor, |
195 cpool, |
193 cpool, |
196 klass_name, |
194 klass_name, |
197 false); |
195 false); |
198 // Calculate accessibility the hard way. |
196 // Calculate accessibility the hard way. |
199 if (k.is_null()) { |
197 if (k == NULL) { |
200 is_accessible = false; |
198 is_accessible = false; |
201 } else if (k->class_loader() != accessor->class_loader() && |
199 } else if (k->class_loader() != accessor->class_loader() && |
202 get_klass_by_name_impl(accessor, cpool, k->name(), true).is_null()) { |
200 get_klass_by_name_impl(accessor, cpool, k->name(), true) == NULL) { |
203 // Loaded only remotely. Not linked yet. |
201 // Loaded only remotely. Not linked yet. |
204 is_accessible = false; |
202 is_accessible = false; |
205 } else { |
203 } else { |
206 // Linked locally, and we must also check public/private, etc. |
204 // Linked locally, and we must also check public/private, etc. |
207 is_accessible = check_klass_accessibility(accessor, k); |
205 is_accessible = check_klass_accessibility(accessor, k); |
208 } |
206 } |
209 if (!is_accessible) { |
207 if (!is_accessible) { |
210 return KlassHandle(); |
208 return NULL; |
211 } |
209 } |
212 return k; |
210 return k; |
213 } |
211 } |
214 |
212 |
215 // It is known to be accessible, since it was found in the constant pool. |
213 // It is known to be accessible, since it was found in the constant pool. |
217 return klass; |
215 return klass; |
218 } |
216 } |
219 |
217 |
220 // ------------------------------------------------------------------ |
218 // ------------------------------------------------------------------ |
221 // Get a klass from the constant pool. |
219 // Get a klass from the constant pool. |
222 KlassHandle JVMCIEnv::get_klass_by_index(const constantPoolHandle& cpool, |
220 Klass* JVMCIEnv::get_klass_by_index(const constantPoolHandle& cpool, |
223 int index, |
221 int index, |
224 bool& is_accessible, |
222 bool& is_accessible, |
225 KlassHandle accessor) { |
223 Klass* accessor) { |
226 ResourceMark rm; |
224 ResourceMark rm; |
227 KlassHandle result = get_klass_by_index_impl(cpool, index, is_accessible, accessor); |
225 return get_klass_by_index_impl(cpool, index, is_accessible, accessor); |
228 return result; |
|
229 } |
226 } |
230 |
227 |
231 // ------------------------------------------------------------------ |
228 // ------------------------------------------------------------------ |
232 // Implementation of get_field_by_index. |
229 // Implementation of get_field_by_index. |
233 // |
230 // |
234 // Implementation note: the results of field lookups are cached |
231 // Implementation note: the results of field lookups are cached |
235 // in the accessor klass. |
232 // in the accessor klass. |
236 void JVMCIEnv::get_field_by_index_impl(instanceKlassHandle klass, fieldDescriptor& field_desc, |
233 void JVMCIEnv::get_field_by_index_impl(InstanceKlass* klass, fieldDescriptor& field_desc, |
237 int index) { |
234 int index) { |
238 JVMCI_EXCEPTION_CONTEXT; |
235 JVMCI_EXCEPTION_CONTEXT; |
239 |
236 |
240 assert(klass->is_linked(), "must be linked before using its constant-pool"); |
237 assert(klass->is_linked(), "must be linked before using its constant-pool"); |
241 |
238 |
249 Symbol* signature = cpool->symbol_at(sig_index); |
246 Symbol* signature = cpool->symbol_at(sig_index); |
250 |
247 |
251 // Get the field's declared holder. |
248 // Get the field's declared holder. |
252 int holder_index = cpool->klass_ref_index_at(index); |
249 int holder_index = cpool->klass_ref_index_at(index); |
253 bool holder_is_accessible; |
250 bool holder_is_accessible; |
254 KlassHandle declared_holder = get_klass_by_index(cpool, holder_index, |
251 Klass* declared_holder = get_klass_by_index(cpool, holder_index, |
255 holder_is_accessible, |
252 holder_is_accessible, |
256 klass); |
253 klass); |
257 |
254 |
258 // The declared holder of this field may not have been loaded. |
255 // The declared holder of this field may not have been loaded. |
259 // Bail out with partial field information. |
256 // Bail out with partial field information. |
260 if (!holder_is_accessible) { |
257 if (!holder_is_accessible) { |
261 return; |
258 return; |
262 } |
259 } |
263 |
260 |
264 |
261 |
265 // Perform the field lookup. |
262 // Perform the field lookup. |
266 Klass* canonical_holder = |
263 Klass* canonical_holder = |
267 InstanceKlass::cast(declared_holder())->find_field(name, signature, &field_desc); |
264 InstanceKlass::cast(declared_holder)->find_field(name, signature, &field_desc); |
268 if (canonical_holder == NULL) { |
265 if (canonical_holder == NULL) { |
269 return; |
266 return; |
270 } |
267 } |
271 |
268 |
272 assert(canonical_holder == field_desc.field_holder(), "just checking"); |
269 assert(canonical_holder == field_desc.field_holder(), "just checking"); |
273 } |
270 } |
274 |
271 |
275 // ------------------------------------------------------------------ |
272 // ------------------------------------------------------------------ |
276 // Get a field by index from a klass's constant pool. |
273 // Get a field by index from a klass's constant pool. |
277 void JVMCIEnv::get_field_by_index(instanceKlassHandle accessor, fieldDescriptor& fd, int index) { |
274 void JVMCIEnv::get_field_by_index(InstanceKlass* accessor, fieldDescriptor& fd, int index) { |
278 ResourceMark rm; |
275 ResourceMark rm; |
279 return get_field_by_index_impl(accessor, fd, index); |
276 return get_field_by_index_impl(accessor, fd, index); |
280 } |
277 } |
281 |
278 |
282 // ------------------------------------------------------------------ |
279 // ------------------------------------------------------------------ |
283 // Perform an appropriate method lookup based on accessor, holder, |
280 // Perform an appropriate method lookup based on accessor, holder, |
284 // name, signature, and bytecode. |
281 // name, signature, and bytecode. |
285 methodHandle JVMCIEnv::lookup_method(instanceKlassHandle h_accessor, |
282 methodHandle JVMCIEnv::lookup_method(InstanceKlass* accessor, |
286 KlassHandle h_holder, |
283 Klass* holder, |
287 Symbol* name, |
284 Symbol* name, |
288 Symbol* sig, |
285 Symbol* sig, |
289 Bytecodes::Code bc, |
286 Bytecodes::Code bc, |
290 constantTag tag) { |
287 constantTag tag) { |
291 // Accessibility checks are performed in JVMCIEnv::get_method_by_index_impl(). |
288 // Accessibility checks are performed in JVMCIEnv::get_method_by_index_impl(). |
292 assert(check_klass_accessibility(h_accessor, h_holder), "holder not accessible"); |
289 assert(check_klass_accessibility(accessor, holder), "holder not accessible"); |
293 |
290 |
294 methodHandle dest_method; |
291 methodHandle dest_method; |
295 LinkInfo link_info(h_holder, name, sig, h_accessor, LinkInfo::needs_access_check, tag); |
292 LinkInfo link_info(holder, name, sig, accessor, LinkInfo::needs_access_check, tag); |
296 switch (bc) { |
293 switch (bc) { |
297 case Bytecodes::_invokestatic: |
294 case Bytecodes::_invokestatic: |
298 dest_method = |
295 dest_method = |
299 LinkResolver::resolve_static_call_or_null(link_info); |
296 LinkResolver::resolve_static_call_or_null(link_info); |
300 break; |
297 break; |
334 return NULL; |
331 return NULL; |
335 } |
332 } |
336 |
333 |
337 int holder_index = cpool->klass_ref_index_at(index); |
334 int holder_index = cpool->klass_ref_index_at(index); |
338 bool holder_is_accessible; |
335 bool holder_is_accessible; |
339 KlassHandle holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor); |
336 Klass* holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor); |
340 |
337 |
341 // Get the method's name and signature. |
338 // Get the method's name and signature. |
342 Symbol* name_sym = cpool->name_ref_at(index); |
339 Symbol* name_sym = cpool->name_ref_at(index); |
343 Symbol* sig_sym = cpool->signature_ref_at(index); |
340 Symbol* sig_sym = cpool->signature_ref_at(index); |
344 |
341 |
345 if (cpool->has_preresolution() |
342 if (cpool->has_preresolution() |
346 || ((holder() == SystemDictionary::MethodHandle_klass() || holder() == SystemDictionary::VarHandle_klass()) && |
343 || ((holder == SystemDictionary::MethodHandle_klass() || holder == SystemDictionary::VarHandle_klass()) && |
347 MethodHandles::is_signature_polymorphic_name(holder(), name_sym))) { |
344 MethodHandles::is_signature_polymorphic_name(holder, name_sym))) { |
348 // Short-circuit lookups for JSR 292-related call sites. |
345 // Short-circuit lookups for JSR 292-related call sites. |
349 // That is, do not rely only on name-based lookups, because they may fail |
346 // That is, do not rely only on name-based lookups, because they may fail |
350 // if the names are not resolvable in the boot class loader (7056328). |
347 // if the names are not resolvable in the boot class loader (7056328). |
351 switch (bc) { |
348 switch (bc) { |
352 case Bytecodes::_invokevirtual: |
349 case Bytecodes::_invokevirtual: |
383 |
380 |
384 return NULL; |
381 return NULL; |
385 } |
382 } |
386 |
383 |
387 // ------------------------------------------------------------------ |
384 // ------------------------------------------------------------------ |
388 instanceKlassHandle JVMCIEnv::get_instance_klass_for_declared_method_holder(KlassHandle method_holder) { |
385 InstanceKlass* JVMCIEnv::get_instance_klass_for_declared_method_holder(Klass* method_holder) { |
389 // For the case of <array>.clone(), the method holder can be an ArrayKlass* |
386 // For the case of <array>.clone(), the method holder can be an ArrayKlass* |
390 // instead of an InstanceKlass*. For that case simply pretend that the |
387 // instead of an InstanceKlass*. For that case simply pretend that the |
391 // declared holder is Object.clone since that's where the call will bottom out. |
388 // declared holder is Object.clone since that's where the call will bottom out. |
392 if (method_holder->is_instance_klass()) { |
389 if (method_holder->is_instance_klass()) { |
393 return instanceKlassHandle(method_holder()); |
390 return InstanceKlass::cast(method_holder); |
394 } else if (method_holder->is_array_klass()) { |
391 } else if (method_holder->is_array_klass()) { |
395 return instanceKlassHandle(SystemDictionary::Object_klass()); |
392 return SystemDictionary::Object_klass(); |
396 } else { |
393 } else { |
397 ShouldNotReachHere(); |
394 ShouldNotReachHere(); |
398 } |
395 } |
399 return NULL; |
396 return NULL; |
400 } |
397 } |
401 |
398 |
402 |
399 |
403 // ------------------------------------------------------------------ |
400 // ------------------------------------------------------------------ |
404 methodHandle JVMCIEnv::get_method_by_index(const constantPoolHandle& cpool, |
401 methodHandle JVMCIEnv::get_method_by_index(const constantPoolHandle& cpool, |
405 int index, Bytecodes::Code bc, |
402 int index, Bytecodes::Code bc, |
406 instanceKlassHandle accessor) { |
403 InstanceKlass* accessor) { |
407 ResourceMark rm; |
404 ResourceMark rm; |
408 return get_method_by_index_impl(cpool, index, bc, accessor); |
405 return get_method_by_index_impl(cpool, index, bc, accessor); |
409 } |
406 } |
410 |
407 |
411 // ------------------------------------------------------------------ |
408 // ------------------------------------------------------------------ |