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