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 }
306 }
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 if (rme->is_resolved(Bytecodes::_invokehandle) && rme->has_appendix() &&
314 cache()->can_archive_resolved_method(this, rme)) {
315 int rr_index = rme->resolved_references_index();
316 assert(resolved_reference_at(rr_index) != nullptr, "must exist");
317 function(rr_index);
318 }
319 }
320 }
321 }
322 }
323
324 // Returns the _resolved_reference array after removing unarchivable items from it.
325 // Returns null if this class is not supported, or _resolved_reference doesn't exist.
326 objArrayOop ConstantPool::prepare_resolved_references_for_archiving() {
327 if (_cache == nullptr) {
328 return nullptr; // nothing to do
329 }
330
331 InstanceKlass *ik = pool_holder();
332 if (!SystemDictionaryShared::is_builtin_loader(ik->class_loader_data())) {
333 // Archiving resolved references for classes from non-builtin loaders
334 // is not yet supported.
335 return nullptr;
336 }
337
338 objArrayOop rr = resolved_references();
339 if (rr != nullptr) {
340 ResourceMark rm;
341 int rr_len = rr->length();
342 GrowableArray<bool> keep_resolved_refs(rr_len, rr_len, false);
343
344 iterate_archivable_resolved_references([&](int rr_index) {
345 keep_resolved_refs.at_put(rr_index, true);
346 });
347
348 objArrayOop scratch_rr = HeapShared::scratch_resolved_references(this);
349 Array<u2>* ref_map = reference_map();
350 int ref_map_len = ref_map == nullptr ? 0 : ref_map->length();
351 for (int i = 0; i < rr_len; i++) {
352 oop obj = rr->obj_at(i);
353 scratch_rr->obj_at_put(i, nullptr);
354 if (obj != nullptr) {
355 if (i < ref_map_len) {
356 int index = object_to_cp_index(i);
357 if (tag_at(index).is_string()) {
358 assert(java_lang_String::is_instance(obj), "must be");
359 if (!HeapShared::is_string_too_large_to_archive(obj)) {
360 scratch_rr->obj_at_put(i, obj);
361 }
362 continue;
363 }
364 }
365
366 if (keep_resolved_refs.at(i)) {
367 scratch_rr->obj_at_put(i, obj);
368 }
459 if (update_resolved_reference && cache() != nullptr) {
460 set_resolved_reference_length(
461 resolved_references() != nullptr ? resolved_references()->length() : 0);
462 set_resolved_references(OopHandle());
463 }
464 remove_unshareable_entries();
465 }
466
467 static const char* get_type(Klass* k) {
468 const char* type;
469 Klass* src_k;
470 if (ArchiveBuilder::is_active() && ArchiveBuilder::current()->is_in_buffer_space(k)) {
471 src_k = ArchiveBuilder::current()->get_source_addr(k);
472 } else {
473 src_k = k;
474 }
475
476 if (src_k->is_objArray_klass()) {
477 src_k = ObjArrayKlass::cast(src_k)->bottom_klass();
478 assert(!src_k->is_objArray_klass(), "sanity");
479 }
480
481 if (src_k->is_typeArray_klass()) {
482 type = "prim";
483 } else {
484 InstanceKlass* src_ik = InstanceKlass::cast(src_k);
485 if (src_ik->defined_by_boot_loader()) {
486 return "boot";
487 } else if (src_ik->defined_by_platform_loader()) {
488 return "plat";
489 } else if (src_ik->defined_by_app_loader()) {
490 return "app";
491 } else {
492 return "unreg";
493 }
494 }
495
496 return type;
497 }
498
658
659 HandleMark hm(THREAD);
660 Handle mirror_handle;
661 Symbol* name = this_cp->symbol_at(name_index);
662 Handle loader (THREAD, this_cp->pool_holder()->class_loader());
663
664 Klass* k;
665 {
666 // Turn off the single stepping while doing class resolution
667 JvmtiHideSingleStepping jhss(javaThread);
668 k = SystemDictionary::resolve_or_fail(name, loader, true, THREAD);
669 } // JvmtiHideSingleStepping jhss(javaThread);
670
671 if (!HAS_PENDING_EXCEPTION) {
672 // preserve the resolved klass from unloading
673 mirror_handle = Handle(THREAD, k->java_mirror());
674 // Do access check for klasses
675 verify_constant_pool_resolve(this_cp, k, THREAD);
676 }
677
678 // Failed to resolve class. We must record the errors so that subsequent attempts
679 // to resolve this constant pool entry fail with the same error (JVMS 5.4.3).
680 if (HAS_PENDING_EXCEPTION) {
681 save_and_throw_exception(this_cp, cp_index, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_NULL);
682 // If CHECK_NULL above doesn't return the exception, that means that
683 // some other thread has beaten us and has resolved the class.
684 // To preserve old behavior, we return the resolved class.
685 Klass* klass = this_cp->resolved_klasses()->at(resolved_klass_index);
686 assert(klass != nullptr, "must be resolved if exception was cleared");
687 return klass;
688 }
689
690 // logging for class+resolve.
691 if (log_is_enabled(Debug, class, resolve)){
692 trace_class_resolution(this_cp, k);
693 }
694
695 // The interpreter assumes when the tag is stored, the klass is resolved
696 // and the Klass* stored in _resolved_klasses is non-null, so we need
697 // hardware store ordering here.
1325 // the result here for MethodHandles.
1326 if (old_result == Universe::the_null_sentinel())
1327 old_result = nullptr;
1328 return old_result;
1329 }
1330 } else {
1331 assert(result_oop != Universe::the_null_sentinel(), "");
1332 return result_oop;
1333 }
1334 }
1335
1336 oop ConstantPool::uncached_string_at(int cp_index, TRAPS) {
1337 Symbol* sym = unresolved_string_at(cp_index);
1338 oop str = StringTable::intern(sym, CHECK_(nullptr));
1339 assert(java_lang_String::is_instance(str), "must be string");
1340 return str;
1341 }
1342
1343 void ConstantPool::copy_bootstrap_arguments_at_impl(const constantPoolHandle& this_cp, int cp_index,
1344 int start_arg, int end_arg,
1345 objArrayHandle info, int pos,
1346 bool must_resolve, Handle if_not_available,
1347 TRAPS) {
1348 int limit = pos + end_arg - start_arg;
1349 // checks: cp_index in range [0..this_cp->length),
1350 // tag at cp_index, start..end in range [0..this_cp->bootstrap_argument_count],
1351 // info array non-null, pos..limit in [0..info.length]
1352 if ((0 >= cp_index || cp_index >= this_cp->length()) ||
1353 !(this_cp->tag_at(cp_index).is_invoke_dynamic() ||
1354 this_cp->tag_at(cp_index).is_dynamic_constant()) ||
1355 (0 > start_arg || start_arg > end_arg) ||
1356 (end_arg > this_cp->bootstrap_argument_count_at(cp_index)) ||
1357 (0 > pos || pos > limit) ||
1358 (info.is_null() || limit > info->length())) {
1359 // An index or something else went wrong; throw an error.
1360 // Since this is an internal API, we don't expect this,
1361 // so we don't bother to craft a nice message.
1362 THROW_MSG(vmSymbols::java_lang_LinkageError(), "bad BSM argument access");
1363 }
1364 // now we can loop safely
1365 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 }
309 }
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 if (rme->is_resolved(Bytecodes::_invokehandle) && rme->has_appendix() &&
317 cache()->can_archive_resolved_method(this, rme)) {
318 int rr_index = rme->resolved_references_index();
319 assert(resolved_reference_at(rr_index) != nullptr, "must exist");
320 function(rr_index);
321 }
322 }
323 }
324 }
325 }
326
327 // Returns the _resolved_reference array after removing unarchivable items from it.
328 // Returns null if this class is not supported, or _resolved_reference doesn't exist.
329 refArrayOop ConstantPool::prepare_resolved_references_for_archiving() {
330 if (_cache == nullptr) {
331 return nullptr; // nothing to do
332 }
333
334 InstanceKlass *ik = pool_holder();
335 if (!SystemDictionaryShared::is_builtin_loader(ik->class_loader_data())) {
336 // Archiving resolved references for classes from non-builtin loaders
337 // is not yet supported.
338 return nullptr;
339 }
340
341 refArrayOop rr = resolved_references();
342 if (rr != nullptr) {
343 ResourceMark rm;
344 int rr_len = rr->length();
345 GrowableArray<bool> keep_resolved_refs(rr_len, rr_len, false);
346
347 iterate_archivable_resolved_references([&](int rr_index) {
348 keep_resolved_refs.at_put(rr_index, true);
349 });
350
351 refArrayOop scratch_rr = HeapShared::scratch_resolved_references(this);
352 Array<u2>* ref_map = reference_map();
353 int ref_map_len = ref_map == nullptr ? 0 : ref_map->length();
354 for (int i = 0; i < rr_len; i++) {
355 oop obj = rr->obj_at(i);
356 scratch_rr->obj_at_put(i, nullptr);
357 if (obj != nullptr) {
358 if (i < ref_map_len) {
359 int index = object_to_cp_index(i);
360 if (tag_at(index).is_string()) {
361 assert(java_lang_String::is_instance(obj), "must be");
362 if (!HeapShared::is_string_too_large_to_archive(obj)) {
363 scratch_rr->obj_at_put(i, obj);
364 }
365 continue;
366 }
367 }
368
369 if (keep_resolved_refs.at(i)) {
370 scratch_rr->obj_at_put(i, obj);
371 }
462 if (update_resolved_reference && cache() != nullptr) {
463 set_resolved_reference_length(
464 resolved_references() != nullptr ? resolved_references()->length() : 0);
465 set_resolved_references(OopHandle());
466 }
467 remove_unshareable_entries();
468 }
469
470 static const char* get_type(Klass* k) {
471 const char* type;
472 Klass* src_k;
473 if (ArchiveBuilder::is_active() && ArchiveBuilder::current()->is_in_buffer_space(k)) {
474 src_k = ArchiveBuilder::current()->get_source_addr(k);
475 } else {
476 src_k = k;
477 }
478
479 if (src_k->is_objArray_klass()) {
480 src_k = ObjArrayKlass::cast(src_k)->bottom_klass();
481 assert(!src_k->is_objArray_klass(), "sanity");
482 assert(src_k->is_instance_klass() || src_k->is_typeArray_klass(), "Sanity check");
483 }
484
485 if (src_k->is_typeArray_klass()) {
486 type = "prim";
487 } else {
488 InstanceKlass* src_ik = InstanceKlass::cast(src_k);
489 if (src_ik->defined_by_boot_loader()) {
490 return "boot";
491 } else if (src_ik->defined_by_platform_loader()) {
492 return "plat";
493 } else if (src_ik->defined_by_app_loader()) {
494 return "app";
495 } else {
496 return "unreg";
497 }
498 }
499
500 return type;
501 }
502
662
663 HandleMark hm(THREAD);
664 Handle mirror_handle;
665 Symbol* name = this_cp->symbol_at(name_index);
666 Handle loader (THREAD, this_cp->pool_holder()->class_loader());
667
668 Klass* k;
669 {
670 // Turn off the single stepping while doing class resolution
671 JvmtiHideSingleStepping jhss(javaThread);
672 k = SystemDictionary::resolve_or_fail(name, loader, true, THREAD);
673 } // JvmtiHideSingleStepping jhss(javaThread);
674
675 if (!HAS_PENDING_EXCEPTION) {
676 // preserve the resolved klass from unloading
677 mirror_handle = Handle(THREAD, k->java_mirror());
678 // Do access check for klasses
679 verify_constant_pool_resolve(this_cp, k, THREAD);
680 }
681
682 #ifdef DEBUG
683 if (!HAS_PENDING_EXCEPTION && k->is_objArray_klass()) {
684 Klass* bottom_klass = ObjArrayKlass::cast(k)->bottom_klass();
685 assert(bottom_klass != nullptr, "Should be set");
686 assert(bottom_klass->is_instance_klass() || bottom_klass->is_typeArray_klass(), "Sanity check");
687 }
688 #endif
689
690 // Failed to resolve class. We must record the errors so that subsequent attempts
691 // to resolve this constant pool entry fail with the same error (JVMS 5.4.3).
692 if (HAS_PENDING_EXCEPTION) {
693 save_and_throw_exception(this_cp, cp_index, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_NULL);
694 // If CHECK_NULL above doesn't return the exception, that means that
695 // some other thread has beaten us and has resolved the class.
696 // To preserve old behavior, we return the resolved class.
697 Klass* klass = this_cp->resolved_klasses()->at(resolved_klass_index);
698 assert(klass != nullptr, "must be resolved if exception was cleared");
699 return klass;
700 }
701
702 // logging for class+resolve.
703 if (log_is_enabled(Debug, class, resolve)){
704 trace_class_resolution(this_cp, k);
705 }
706
707 // The interpreter assumes when the tag is stored, the klass is resolved
708 // and the Klass* stored in _resolved_klasses is non-null, so we need
709 // hardware store ordering here.
1337 // the result here for MethodHandles.
1338 if (old_result == Universe::the_null_sentinel())
1339 old_result = nullptr;
1340 return old_result;
1341 }
1342 } else {
1343 assert(result_oop != Universe::the_null_sentinel(), "");
1344 return result_oop;
1345 }
1346 }
1347
1348 oop ConstantPool::uncached_string_at(int cp_index, TRAPS) {
1349 Symbol* sym = unresolved_string_at(cp_index);
1350 oop str = StringTable::intern(sym, CHECK_(nullptr));
1351 assert(java_lang_String::is_instance(str), "must be string");
1352 return str;
1353 }
1354
1355 void ConstantPool::copy_bootstrap_arguments_at_impl(const constantPoolHandle& this_cp, int cp_index,
1356 int start_arg, int end_arg,
1357 refArrayHandle info, int pos,
1358 bool must_resolve, Handle if_not_available,
1359 TRAPS) {
1360 int limit = pos + end_arg - start_arg;
1361 // checks: cp_index in range [0..this_cp->length),
1362 // tag at cp_index, start..end in range [0..this_cp->bootstrap_argument_count],
1363 // info array non-null, pos..limit in [0..info.length]
1364 if ((0 >= cp_index || cp_index >= this_cp->length()) ||
1365 !(this_cp->tag_at(cp_index).is_invoke_dynamic() ||
1366 this_cp->tag_at(cp_index).is_dynamic_constant()) ||
1367 (0 > start_arg || start_arg > end_arg) ||
1368 (end_arg > this_cp->bootstrap_argument_count_at(cp_index)) ||
1369 (0 > pos || pos > limit) ||
1370 (info.is_null() || limit > info->length())) {
1371 // An index or something else went wrong; throw an error.
1372 // Since this is an internal API, we don't expect this,
1373 // so we don't bother to craft a nice message.
1374 THROW_MSG(vmSymbols::java_lang_LinkageError(), "bad BSM argument access");
1375 }
1376 // now we can loop safely
1377 int info_i = pos;
|