1 /*
2 * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
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 *
35 #include "classfile/systemDictionaryShared.hpp"
36 #include "classfile/vmClasses.hpp"
37 #include "classfile/vmSymbols.hpp"
38 #include "code/codeCache.hpp"
39 #include "interpreter/bootstrapInfo.hpp"
40 #include "interpreter/linkResolver.hpp"
41 #include "jvm.h"
42 #include "logging/log.hpp"
43 #include "logging/logStream.hpp"
44 #include "memory/allocation.inline.hpp"
45 #include "memory/metadataFactory.hpp"
46 #include "memory/metaspaceClosure.hpp"
47 #include "memory/oopFactory.hpp"
48 #include "memory/resourceArea.hpp"
49 #include "memory/universe.hpp"
50 #include "oops/array.hpp"
51 #include "oops/bsmAttribute.inline.hpp"
52 #include "oops/constantPool.inline.hpp"
53 #include "oops/cpCache.inline.hpp"
54 #include "oops/fieldStreams.inline.hpp"
55 #include "oops/instanceKlass.hpp"
56 #include "oops/klass.inline.hpp"
57 #include "oops/objArrayKlass.hpp"
58 #include "oops/objArrayOop.inline.hpp"
59 #include "oops/oop.inline.hpp"
60 #include "oops/typeArrayOop.inline.hpp"
61 #include "prims/jvmtiExport.hpp"
62 #include "runtime/atomicAccess.hpp"
63 #include "runtime/fieldDescriptor.inline.hpp"
64 #include "runtime/handles.inline.hpp"
65 #include "runtime/init.hpp"
66 #include "runtime/javaCalls.hpp"
67 #include "runtime/javaThread.inline.hpp"
68 #include "runtime/perfData.hpp"
69 #include "runtime/signature.hpp"
70 #include "runtime/vframe.inline.hpp"
71 #include "utilities/checkedCast.hpp"
72 #include "utilities/copy.hpp"
73
74 ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, TRAPS) {
75 Array<u1>* tags = MetadataFactory::new_array<u1>(loader_data, length, 0, CHECK_NULL);
76 int size = ConstantPool::size(length);
77 return new (loader_data, size, MetaspaceObj::ConstantPoolType, THREAD) ConstantPool(tags);
78 }
79
150 log_trace(aot)("Iter(ConstantPool): %p", this);
151
152 it->push(&_tags, MetaspaceClosure::_writable);
153 it->push(&_cache);
154 it->push(&_pool_holder);
155 it->push(&bsm_entries().offsets());
156 it->push(&bsm_entries().bootstrap_methods());
157 it->push(&_resolved_klasses, MetaspaceClosure::_writable);
158
159 for (int i = 0; i < length(); i++) {
160 // The only MSO's embedded in the CP entries are Symbols:
161 // JVM_CONSTANT_String
162 // JVM_CONSTANT_Utf8
163 constantTag ctag = tag_at(i);
164 if (ctag.is_string() || ctag.is_utf8()) {
165 it->push(symbol_at_addr(i));
166 }
167 }
168 }
169
170 objArrayOop ConstantPool::resolved_references() const {
171 return _cache->resolved_references();
172 }
173
174 // Called from outside constant pool resolution where a resolved_reference array
175 // may not be present.
176 objArrayOop ConstantPool::resolved_references_or_null() const {
177 if (_cache == nullptr) {
178 return nullptr;
179 } else {
180 return _cache->resolved_references();
181 }
182 }
183
184 oop ConstantPool::resolved_reference_at(int index) const {
185 oop result = resolved_references()->obj_at(index);
186 assert(oopDesc::is_oop_or_null(result), "Must be oop");
187 return result;
188 }
189
190 // Use a CAS for multithreaded access
191 oop ConstantPool::set_resolved_reference_at(int index, oop new_result) {
192 assert(oopDesc::is_oop_or_null(new_result), "Must be oop");
193 return resolved_references()->replace_if_null(index, new_result);
194 }
195
196 // Create resolved_references array and mapping array for original cp indexes
197 // The ldc bytecode was rewritten to have the resolved reference array index so need a way
198 // to map it back for resolving and some unlikely miscellaneous uses.
199 // The objects created by invokedynamic are appended to this list.
200 void ConstantPool::initialize_resolved_references(ClassLoaderData* loader_data,
201 const intStack& reference_map,
202 int constant_pool_map_length,
203 TRAPS) {
204 // Initialized the resolved object cache.
205 int map_length = reference_map.length();
206 if (map_length > 0) {
207 // Only need mapping back to constant pool entries. The map isn't used for
208 // invokedynamic resolved_reference entries. For invokedynamic entries,
209 // the constant pool cache index has the mapping back to both the constant
210 // pool and to the resolved reference index.
211 if (constant_pool_map_length > 0) {
212 Array<u2>* om = MetadataFactory::new_array<u2>(loader_data, constant_pool_map_length, CHECK);
213
214 for (int i = 0; i < constant_pool_map_length; i++) {
215 int x = reference_map.at(i);
216 assert(x == (int)(jushort) x, "klass index is too big");
217 om->at_put(i, (jushort)x);
218 }
219 set_reference_map(om);
220 }
221
222 // Create Java array for holding resolved strings, methodHandles,
223 // methodTypes, invokedynamic and invokehandle appendix objects, etc.
224 objArrayOop stom = oopFactory::new_objArray(vmClasses::Object_klass(), map_length, CHECK);
225 HandleMark hm(THREAD);
226 Handle refs_handle (THREAD, stom); // must handleize.
227 set_resolved_references(loader_data->add_handle(refs_handle));
228
229 // Create a "scratch" copy of the resolved references array to archive
230 if (CDSConfig::is_dumping_heap()) {
231 objArrayOop scratch_references = oopFactory::new_objArray(vmClasses::Object_klass(), map_length, CHECK);
232 HeapShared::add_scratch_resolved_references(this, scratch_references);
233 }
234 }
235 }
236
237 void ConstantPool::allocate_resolved_klasses(ClassLoaderData* loader_data, int num_klasses, TRAPS) {
238 // A ConstantPool can't possibly have 0xffff valid class entries,
239 // because entry #0 must be CONSTANT_Invalid, and each class entry must refer to a UTF8
240 // entry for the class's name. So at most we will have 0xfffe class entries.
241 // This allows us to use 0xffff (ConstantPool::_temp_resolved_klass_index) to indicate
242 // UnresolvedKlass entries that are temporarily created during class redefinition.
243 assert(num_klasses < CPKlassSlot::_temp_resolved_klass_index, "sanity");
244 assert(resolved_klasses() == nullptr, "sanity");
245 Array<Klass*>* rk = MetadataFactory::new_array<Klass*>(loader_data, num_klasses, CHECK);
246 set_resolved_klasses(rk);
247 }
248
249 void ConstantPool::initialize_unresolved_klasses(ClassLoaderData* loader_data, TRAPS) {
250 int len = length();
251 int num_klasses = 0;
252 for (int i = 1; i <len; i++) {
253 switch (tag_at(i).value()) {
254 case JVM_CONSTANT_ClassIndex:
255 {
256 const int class_index = klass_index_at(i);
257 unresolved_klass_at_put(i, class_index, num_klasses++);
258 }
259 break;
260 #ifndef PRODUCT
261 case JVM_CONSTANT_Class:
262 case JVM_CONSTANT_UnresolvedClass:
263 case JVM_CONSTANT_UnresolvedClassInError:
264 // All of these should have been reverted back to ClassIndex before calling
265 // this function.
266 ShouldNotReachHere();
267 #endif
268 }
269 }
270 allocate_resolved_klasses(loader_data, num_klasses, THREAD);
271 }
272
273 // Hidden class support:
274 void ConstantPool::klass_at_put(int class_index, Klass* k) {
275 assert(k != nullptr, "must be valid klass");
276 CPKlassSlot kslot = klass_slot_at(class_index);
277 int resolved_klass_index = kslot.resolved_klass_index();
278 Klass** adr = resolved_klasses()->adr_at(resolved_klass_index);
279 AtomicAccess::release_store(adr, k);
280
281 // The interpreter assumes when the tag is stored, the klass is resolved
282 // and the Klass* non-null, so we need hardware store ordering here.
283 release_tag_at_put(class_index, JVM_CONSTANT_Class);
284 }
308 }
309
310 Array<ResolvedMethodEntry>* method_entries = cache()->resolved_method_entries();
311 if (method_entries != nullptr) {
312 for (int i = 0; i < method_entries->length(); i++) {
313 ResolvedMethodEntry* rme = method_entries->adr_at(i);
314 const char* rejection_reason = nullptr;
315 if (rme->is_resolved(Bytecodes::_invokehandle) && rme->has_appendix() &&
316 cache()->can_archive_resolved_method(this, rme, rejection_reason)) {
317 int rr_index = rme->resolved_references_index();
318 assert(resolved_reference_at(rr_index) != nullptr, "must exist");
319 function(rr_index);
320 }
321 }
322 }
323 }
324 }
325
326 // Returns the _resolved_reference array after removing unarchivable items from it.
327 // Returns null if this class is not supported, or _resolved_reference doesn't exist.
328 objArrayOop ConstantPool::prepare_resolved_references_for_archiving() {
329 if (_cache == nullptr) {
330 return nullptr; // nothing to do
331 }
332
333 InstanceKlass *ik = pool_holder();
334 if (!SystemDictionaryShared::is_builtin_loader(ik->class_loader_data())) {
335 // Archiving resolved references for classes from non-builtin loaders
336 // is not yet supported.
337 return nullptr;
338 }
339
340 objArrayOop rr = resolved_references();
341 if (rr != nullptr) {
342 ResourceMark rm;
343 int rr_len = rr->length();
344 GrowableArray<bool> keep_resolved_refs(rr_len, rr_len, false);
345
346 iterate_archivable_resolved_references([&](int rr_index) {
347 keep_resolved_refs.at_put(rr_index, true);
348 });
349
350 objArrayOop scratch_rr = HeapShared::scratch_resolved_references(this);
351 Array<u2>* ref_map = reference_map();
352 int ref_map_len = ref_map == nullptr ? 0 : ref_map->length();
353 for (int i = 0; i < rr_len; i++) {
354 oop obj = rr->obj_at(i);
355 scratch_rr->obj_at_put(i, nullptr);
356 if (obj != nullptr) {
357 if (i < ref_map_len) {
358 int index = object_to_cp_index(i);
359 if (tag_at(index).is_string()) {
360 assert(java_lang_String::is_instance(obj), "must be");
361 if (!HeapShared::is_string_too_large_to_archive(obj)) {
362 scratch_rr->obj_at_put(i, obj);
363 }
364 continue;
365 }
366 }
367
368 if (keep_resolved_refs.at(i)) {
369 scratch_rr->obj_at_put(i, obj);
370 }
461 if (update_resolved_reference && cache() != nullptr) {
462 set_resolved_reference_length(
463 resolved_references() != nullptr ? resolved_references()->length() : 0);
464 set_resolved_references(OopHandle());
465 }
466 remove_unshareable_entries();
467 }
468
469 static const char* get_type(Klass* k) {
470 const char* type;
471 Klass* src_k;
472 if (ArchiveBuilder::is_active() && ArchiveBuilder::current()->is_in_buffer_space(k)) {
473 src_k = ArchiveBuilder::current()->get_source_addr(k);
474 } else {
475 src_k = k;
476 }
477
478 if (src_k->is_objArray_klass()) {
479 src_k = ObjArrayKlass::cast(src_k)->bottom_klass();
480 assert(!src_k->is_objArray_klass(), "sanity");
481 }
482
483 if (src_k->is_typeArray_klass()) {
484 type = "prim";
485 } else {
486 InstanceKlass* src_ik = InstanceKlass::cast(src_k);
487 if (src_ik->defined_by_boot_loader()) {
488 return "boot";
489 } else if (src_ik->defined_by_platform_loader()) {
490 return "plat";
491 } else if (src_ik->defined_by_app_loader()) {
492 return "app";
493 } else {
494 return "unreg";
495 }
496 }
497
498 return type;
499 }
500
660
661 HandleMark hm(THREAD);
662 Handle mirror_handle;
663 Symbol* name = this_cp->symbol_at(name_index);
664 Handle loader (THREAD, this_cp->pool_holder()->class_loader());
665
666 Klass* k;
667 {
668 // Turn off the single stepping while doing class resolution
669 JvmtiHideSingleStepping jhss(javaThread);
670 k = SystemDictionary::resolve_or_fail(name, loader, true, THREAD);
671 } // JvmtiHideSingleStepping jhss(javaThread);
672
673 if (!HAS_PENDING_EXCEPTION) {
674 // preserve the resolved klass from unloading
675 mirror_handle = Handle(THREAD, k->java_mirror());
676 // Do access check for klasses
677 verify_constant_pool_resolve(this_cp, k, THREAD);
678 }
679
680 // Failed to resolve class. We must record the errors so that subsequent attempts
681 // to resolve this constant pool entry fail with the same error (JVMS 5.4.3).
682 if (HAS_PENDING_EXCEPTION) {
683 save_and_throw_exception(this_cp, cp_index, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_NULL);
684 // If CHECK_NULL above doesn't return the exception, that means that
685 // some other thread has beaten us and has resolved the class.
686 // To preserve old behavior, we return the resolved class.
687 Klass* klass = this_cp->resolved_klasses()->at(resolved_klass_index);
688 assert(klass != nullptr, "must be resolved if exception was cleared");
689 return klass;
690 }
691
692 // logging for class+resolve.
693 if (log_is_enabled(Debug, class, resolve)){
694 trace_class_resolution(this_cp, k);
695 }
696
697 // The interpreter assumes when the tag is stored, the klass is resolved
698 // and the Klass* stored in _resolved_klasses is non-null, so we need
699 // hardware store ordering here.
1327 // the result here for MethodHandles.
1328 if (old_result == Universe::the_null_sentinel())
1329 old_result = nullptr;
1330 return old_result;
1331 }
1332 } else {
1333 assert(result_oop != Universe::the_null_sentinel(), "");
1334 return result_oop;
1335 }
1336 }
1337
1338 oop ConstantPool::uncached_string_at(int cp_index, TRAPS) {
1339 Symbol* sym = unresolved_string_at(cp_index);
1340 oop str = StringTable::intern(sym, CHECK_(nullptr));
1341 assert(java_lang_String::is_instance(str), "must be string");
1342 return str;
1343 }
1344
1345 void ConstantPool::copy_bootstrap_arguments_at_impl(const constantPoolHandle& this_cp, int cp_index,
1346 int start_arg, int end_arg,
1347 objArrayHandle info, int pos,
1348 bool must_resolve, Handle if_not_available,
1349 TRAPS) {
1350 int limit = pos + end_arg - start_arg;
1351 // checks: cp_index in range [0..this_cp->length),
1352 // tag at cp_index, start..end in range [0..this_cp->bootstrap_argument_count],
1353 // info array non-null, pos..limit in [0..info.length]
1354 if ((0 >= cp_index || cp_index >= this_cp->length()) ||
1355 !(this_cp->tag_at(cp_index).is_invoke_dynamic() ||
1356 this_cp->tag_at(cp_index).is_dynamic_constant()) ||
1357 (0 > start_arg || start_arg > end_arg) ||
1358 (end_arg > this_cp->bootstrap_argument_count_at(cp_index)) ||
1359 (0 > pos || pos > limit) ||
1360 (info.is_null() || limit > info->length())) {
1361 // An index or something else went wrong; throw an error.
1362 // Since this is an internal API, we don't expect this,
1363 // so we don't bother to craft a nice message.
1364 THROW_MSG(vmSymbols::java_lang_LinkageError(), "bad BSM argument access");
1365 }
1366 // now we can loop safely
1367 int info_i = pos;
|
1 /*
2 * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
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 *
35 #include "classfile/systemDictionaryShared.hpp"
36 #include "classfile/vmClasses.hpp"
37 #include "classfile/vmSymbols.hpp"
38 #include "code/codeCache.hpp"
39 #include "interpreter/bootstrapInfo.hpp"
40 #include "interpreter/linkResolver.hpp"
41 #include "jvm.h"
42 #include "logging/log.hpp"
43 #include "logging/logStream.hpp"
44 #include "memory/allocation.inline.hpp"
45 #include "memory/metadataFactory.hpp"
46 #include "memory/metaspaceClosure.hpp"
47 #include "memory/oopFactory.hpp"
48 #include "memory/resourceArea.hpp"
49 #include "memory/universe.hpp"
50 #include "oops/array.hpp"
51 #include "oops/bsmAttribute.inline.hpp"
52 #include "oops/constantPool.inline.hpp"
53 #include "oops/cpCache.inline.hpp"
54 #include "oops/fieldStreams.inline.hpp"
55 #include "oops/flatArrayKlass.hpp"
56 #include "oops/instanceKlass.hpp"
57 #include "oops/klass.inline.hpp"
58 #include "oops/objArrayKlass.hpp"
59 #include "oops/objArrayOop.inline.hpp"
60 #include "oops/oop.inline.hpp"
61 #include "oops/oopCast.inline.hpp"
62 #include "oops/refArrayOop.hpp"
63 #include "oops/typeArrayOop.inline.hpp"
64 #include "prims/jvmtiExport.hpp"
65 #include "runtime/atomicAccess.hpp"
66 #include "runtime/fieldDescriptor.inline.hpp"
67 #include "runtime/handles.inline.hpp"
68 #include "runtime/init.hpp"
69 #include "runtime/javaCalls.hpp"
70 #include "runtime/javaThread.inline.hpp"
71 #include "runtime/perfData.hpp"
72 #include "runtime/signature.hpp"
73 #include "runtime/vframe.inline.hpp"
74 #include "utilities/checkedCast.hpp"
75 #include "utilities/copy.hpp"
76
77 ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, TRAPS) {
78 Array<u1>* tags = MetadataFactory::new_array<u1>(loader_data, length, 0, CHECK_NULL);
79 int size = ConstantPool::size(length);
80 return new (loader_data, size, MetaspaceObj::ConstantPoolType, THREAD) ConstantPool(tags);
81 }
82
153 log_trace(aot)("Iter(ConstantPool): %p", this);
154
155 it->push(&_tags, MetaspaceClosure::_writable);
156 it->push(&_cache);
157 it->push(&_pool_holder);
158 it->push(&bsm_entries().offsets());
159 it->push(&bsm_entries().bootstrap_methods());
160 it->push(&_resolved_klasses, MetaspaceClosure::_writable);
161
162 for (int i = 0; i < length(); i++) {
163 // The only MSO's embedded in the CP entries are Symbols:
164 // JVM_CONSTANT_String
165 // JVM_CONSTANT_Utf8
166 constantTag ctag = tag_at(i);
167 if (ctag.is_string() || ctag.is_utf8()) {
168 it->push(symbol_at_addr(i));
169 }
170 }
171 }
172
173 refArrayOop ConstantPool::resolved_references() const {
174 return _cache->resolved_references();
175 }
176
177 // Called from outside constant pool resolution where a resolved_reference array
178 // may not be present.
179 refArrayOop ConstantPool::resolved_references_or_null() const {
180 if (_cache == nullptr) {
181 return nullptr;
182 } else {
183 return _cache->resolved_references();
184 }
185 }
186
187 oop ConstantPool::resolved_reference_at(int index) const {
188 oop result = resolved_references()->obj_at(index);
189 assert(oopDesc::is_oop_or_null(result), "Must be oop");
190 return result;
191 }
192
193 // Use a CAS for multithreaded access
194 oop ConstantPool::set_resolved_reference_at(int index, oop new_result) {
195 assert(oopDesc::is_oop_or_null(new_result), "Must be oop");
196 return oop_cast<refArrayOop>(resolved_references())->replace_if_null(index, new_result);
197 }
198
199 // Create resolved_references array and mapping array for original cp indexes
200 // The ldc bytecode was rewritten to have the resolved reference array index so need a way
201 // to map it back for resolving and some unlikely miscellaneous uses.
202 // The objects created by invokedynamic are appended to this list.
203 void ConstantPool::initialize_resolved_references(ClassLoaderData* loader_data,
204 const intStack& reference_map,
205 int constant_pool_map_length,
206 TRAPS) {
207 // Initialized the resolved object cache.
208 int map_length = reference_map.length();
209 if (map_length > 0) {
210 // Only need mapping back to constant pool entries. The map isn't used for
211 // invokedynamic resolved_reference entries. For invokedynamic entries,
212 // the constant pool cache index has the mapping back to both the constant
213 // pool and to the resolved reference index.
214 if (constant_pool_map_length > 0) {
215 Array<u2>* om = MetadataFactory::new_array<u2>(loader_data, constant_pool_map_length, CHECK);
216
217 for (int i = 0; i < constant_pool_map_length; i++) {
218 int x = reference_map.at(i);
219 assert(x == (int)(jushort) x, "klass index is too big");
220 om->at_put(i, (jushort)x);
221 }
222 set_reference_map(om);
223 }
224
225 // Create Java array for holding resolved strings, methodHandles,
226 // methodTypes, invokedynamic and invokehandle appendix objects, etc.
227 refArrayOop stom = oopFactory::new_refArray(vmClasses::Object_klass(), map_length, CHECK);
228 HandleMark hm(THREAD);
229 Handle refs_handle (THREAD, stom); // must handleize.
230 set_resolved_references(loader_data->add_handle(refs_handle));
231
232 // Create a "scratch" copy of the resolved references array to archive
233 if (CDSConfig::is_dumping_heap()) {
234 refArrayOop scratch_references = oopFactory::new_refArray(vmClasses::Object_klass(), map_length, CHECK);
235 HeapShared::add_scratch_resolved_references(this, scratch_references);
236 }
237 }
238 }
239
240 void ConstantPool::allocate_resolved_klasses(ClassLoaderData* loader_data, int num_klasses, TRAPS) {
241 // A ConstantPool can't possibly have 0xffff valid class entries,
242 // because entry #0 must be CONSTANT_Invalid, and each class entry must refer to a UTF8
243 // entry for the class's name. So at most we will have 0xfffe class entries.
244 // This allows us to use 0xffff (ConstantPool::_temp_resolved_klass_index) to indicate
245 // UnresolvedKlass entries that are temporarily created during class redefinition.
246 assert(num_klasses < CPKlassSlot::_temp_resolved_klass_index, "sanity");
247 assert(resolved_klasses() == nullptr, "sanity");
248 Array<Klass*>* rk = MetadataFactory::new_array<Klass*>(loader_data, num_klasses, CHECK);
249 set_resolved_klasses(rk);
250 }
251
252 void ConstantPool::initialize_unresolved_klasses(ClassLoaderData* loader_data, TRAPS) {
253 int len = length();
254 int num_klasses = 0;
255 for (int i = 1; i <len; i++) {
256 switch (tag_at(i).value()) {
257 case JVM_CONSTANT_ClassIndex:
258 {
259 const int class_index = klass_index_at(i);
260 unresolved_klass_at_put(i, class_index, num_klasses++);
261 }
262 break;
263 #ifndef PRODUCT
264 case JVM_CONSTANT_Class:
265 case JVM_CONSTANT_UnresolvedClass:
266 case JVM_CONSTANT_UnresolvedClassInError:
267 // All of these should have been reverted back to Unresolved before calling
268 // this function.
269 ShouldNotReachHere();
270 #endif
271 }
272 }
273 allocate_resolved_klasses(loader_data, num_klasses, THREAD);
274 }
275
276 // Hidden class support:
277 void ConstantPool::klass_at_put(int class_index, Klass* k) {
278 assert(k != nullptr, "must be valid klass");
279 CPKlassSlot kslot = klass_slot_at(class_index);
280 int resolved_klass_index = kslot.resolved_klass_index();
281 Klass** adr = resolved_klasses()->adr_at(resolved_klass_index);
282 AtomicAccess::release_store(adr, k);
283
284 // The interpreter assumes when the tag is stored, the klass is resolved
285 // and the Klass* non-null, so we need hardware store ordering here.
286 release_tag_at_put(class_index, JVM_CONSTANT_Class);
287 }
311 }
312
313 Array<ResolvedMethodEntry>* method_entries = cache()->resolved_method_entries();
314 if (method_entries != nullptr) {
315 for (int i = 0; i < method_entries->length(); i++) {
316 ResolvedMethodEntry* rme = method_entries->adr_at(i);
317 const char* rejection_reason = nullptr;
318 if (rme->is_resolved(Bytecodes::_invokehandle) && rme->has_appendix() &&
319 cache()->can_archive_resolved_method(this, rme, rejection_reason)) {
320 int rr_index = rme->resolved_references_index();
321 assert(resolved_reference_at(rr_index) != nullptr, "must exist");
322 function(rr_index);
323 }
324 }
325 }
326 }
327 }
328
329 // Returns the _resolved_reference array after removing unarchivable items from it.
330 // Returns null if this class is not supported, or _resolved_reference doesn't exist.
331 refArrayOop ConstantPool::prepare_resolved_references_for_archiving() {
332 if (_cache == nullptr) {
333 return nullptr; // nothing to do
334 }
335
336 InstanceKlass *ik = pool_holder();
337 if (!SystemDictionaryShared::is_builtin_loader(ik->class_loader_data())) {
338 // Archiving resolved references for classes from non-builtin loaders
339 // is not yet supported.
340 return nullptr;
341 }
342
343 refArrayOop rr = resolved_references();
344 if (rr != nullptr) {
345 ResourceMark rm;
346 int rr_len = rr->length();
347 GrowableArray<bool> keep_resolved_refs(rr_len, rr_len, false);
348
349 iterate_archivable_resolved_references([&](int rr_index) {
350 keep_resolved_refs.at_put(rr_index, true);
351 });
352
353 refArrayOop scratch_rr = HeapShared::scratch_resolved_references(this);
354 Array<u2>* ref_map = reference_map();
355 int ref_map_len = ref_map == nullptr ? 0 : ref_map->length();
356 for (int i = 0; i < rr_len; i++) {
357 oop obj = rr->obj_at(i);
358 scratch_rr->obj_at_put(i, nullptr);
359 if (obj != nullptr) {
360 if (i < ref_map_len) {
361 int index = object_to_cp_index(i);
362 if (tag_at(index).is_string()) {
363 assert(java_lang_String::is_instance(obj), "must be");
364 if (!HeapShared::is_string_too_large_to_archive(obj)) {
365 scratch_rr->obj_at_put(i, obj);
366 }
367 continue;
368 }
369 }
370
371 if (keep_resolved_refs.at(i)) {
372 scratch_rr->obj_at_put(i, obj);
373 }
464 if (update_resolved_reference && cache() != nullptr) {
465 set_resolved_reference_length(
466 resolved_references() != nullptr ? resolved_references()->length() : 0);
467 set_resolved_references(OopHandle());
468 }
469 remove_unshareable_entries();
470 }
471
472 static const char* get_type(Klass* k) {
473 const char* type;
474 Klass* src_k;
475 if (ArchiveBuilder::is_active() && ArchiveBuilder::current()->is_in_buffer_space(k)) {
476 src_k = ArchiveBuilder::current()->get_source_addr(k);
477 } else {
478 src_k = k;
479 }
480
481 if (src_k->is_objArray_klass()) {
482 src_k = ObjArrayKlass::cast(src_k)->bottom_klass();
483 assert(!src_k->is_objArray_klass(), "sanity");
484 assert(src_k->is_instance_klass() || src_k->is_typeArray_klass(), "Sanity check");
485 }
486
487 if (src_k->is_typeArray_klass()) {
488 type = "prim";
489 } else {
490 InstanceKlass* src_ik = InstanceKlass::cast(src_k);
491 if (src_ik->defined_by_boot_loader()) {
492 return "boot";
493 } else if (src_ik->defined_by_platform_loader()) {
494 return "plat";
495 } else if (src_ik->defined_by_app_loader()) {
496 return "app";
497 } else {
498 return "unreg";
499 }
500 }
501
502 return type;
503 }
504
664
665 HandleMark hm(THREAD);
666 Handle mirror_handle;
667 Symbol* name = this_cp->symbol_at(name_index);
668 Handle loader (THREAD, this_cp->pool_holder()->class_loader());
669
670 Klass* k;
671 {
672 // Turn off the single stepping while doing class resolution
673 JvmtiHideSingleStepping jhss(javaThread);
674 k = SystemDictionary::resolve_or_fail(name, loader, true, THREAD);
675 } // JvmtiHideSingleStepping jhss(javaThread);
676
677 if (!HAS_PENDING_EXCEPTION) {
678 // preserve the resolved klass from unloading
679 mirror_handle = Handle(THREAD, k->java_mirror());
680 // Do access check for klasses
681 verify_constant_pool_resolve(this_cp, k, THREAD);
682 }
683
684 #ifdef DEBUG
685 if (!HAS_PENDING_EXCEPTION && k->is_objArray_klass()) {
686 Klass* bottom_klass = ObjArrayKlass::cast(k)->bottom_klass();
687 assert(bottom_klass != nullptr, "Should be set");
688 assert(bottom_klass->is_instance_klass() || bottom_klass->is_typeArray_klass(), "Sanity check");
689 }
690 #endif
691
692 // Failed to resolve class. We must record the errors so that subsequent attempts
693 // to resolve this constant pool entry fail with the same error (JVMS 5.4.3).
694 if (HAS_PENDING_EXCEPTION) {
695 save_and_throw_exception(this_cp, cp_index, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_NULL);
696 // If CHECK_NULL above doesn't return the exception, that means that
697 // some other thread has beaten us and has resolved the class.
698 // To preserve old behavior, we return the resolved class.
699 Klass* klass = this_cp->resolved_klasses()->at(resolved_klass_index);
700 assert(klass != nullptr, "must be resolved if exception was cleared");
701 return klass;
702 }
703
704 // logging for class+resolve.
705 if (log_is_enabled(Debug, class, resolve)){
706 trace_class_resolution(this_cp, k);
707 }
708
709 // The interpreter assumes when the tag is stored, the klass is resolved
710 // and the Klass* stored in _resolved_klasses is non-null, so we need
711 // hardware store ordering here.
1339 // the result here for MethodHandles.
1340 if (old_result == Universe::the_null_sentinel())
1341 old_result = nullptr;
1342 return old_result;
1343 }
1344 } else {
1345 assert(result_oop != Universe::the_null_sentinel(), "");
1346 return result_oop;
1347 }
1348 }
1349
1350 oop ConstantPool::uncached_string_at(int cp_index, TRAPS) {
1351 Symbol* sym = unresolved_string_at(cp_index);
1352 oop str = StringTable::intern(sym, CHECK_(nullptr));
1353 assert(java_lang_String::is_instance(str), "must be string");
1354 return str;
1355 }
1356
1357 void ConstantPool::copy_bootstrap_arguments_at_impl(const constantPoolHandle& this_cp, int cp_index,
1358 int start_arg, int end_arg,
1359 refArrayHandle info, int pos,
1360 bool must_resolve, Handle if_not_available,
1361 TRAPS) {
1362 int limit = pos + end_arg - start_arg;
1363 // checks: cp_index in range [0..this_cp->length),
1364 // tag at cp_index, start..end in range [0..this_cp->bootstrap_argument_count],
1365 // info array non-null, pos..limit in [0..info.length]
1366 if ((0 >= cp_index || cp_index >= this_cp->length()) ||
1367 !(this_cp->tag_at(cp_index).is_invoke_dynamic() ||
1368 this_cp->tag_at(cp_index).is_dynamic_constant()) ||
1369 (0 > start_arg || start_arg > end_arg) ||
1370 (end_arg > this_cp->bootstrap_argument_count_at(cp_index)) ||
1371 (0 > pos || pos > limit) ||
1372 (info.is_null() || limit > info->length())) {
1373 // An index or something else went wrong; throw an error.
1374 // Since this is an internal API, we don't expect this,
1375 // so we don't bother to craft a nice message.
1376 THROW_MSG(vmSymbols::java_lang_LinkageError(), "bad BSM argument access");
1377 }
1378 // now we can loop safely
1379 int info_i = pos;
|