< prev index next >

src/hotspot/share/interpreter/bootstrapInfo.cpp

Print this page

  1 /*
  2  * Copyright (c) 2019, 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  *
 23  */
 24 
 25 #include "classfile/javaClasses.inline.hpp"
 26 #include "classfile/resolutionErrors.hpp"
 27 #include "classfile/systemDictionary.hpp"
 28 #include "classfile/vmClasses.hpp"
 29 #include "interpreter/bootstrapInfo.hpp"
 30 #include "interpreter/linkResolver.hpp"
 31 #include "jvm.h"
 32 #include "logging/log.hpp"
 33 #include "logging/logStream.hpp"
 34 #include "memory/oopFactory.hpp"
 35 #include "memory/resourceArea.hpp"
 36 #include "oops/constantPool.inline.hpp"
 37 #include "oops/cpCache.inline.hpp"
 38 #include "oops/objArrayOop.inline.hpp"

 39 #include "oops/resolvedIndyEntry.hpp"
 40 #include "oops/typeArrayOop.inline.hpp"
 41 #include "runtime/handles.inline.hpp"
 42 #include "runtime/javaThread.hpp"
 43 #include "runtime/vmThread.hpp"
 44 
 45 //------------------------------------------------------------------------------------------------------------------------
 46 // Implementation of BootstrapInfo
 47 
 48 BootstrapInfo::BootstrapInfo(const constantPoolHandle& pool, int bss_index, int indy_index)
 49   : _pool(pool),
 50     _bss_index(bss_index),
 51     _indy_index(indy_index),
 52     // derived and eagerly cached:
 53     _argc(      pool->bootstrap_argument_count_at(bss_index) ),
 54     _name(      pool->uncached_name_ref_at(bss_index) ),
 55     _signature( pool->uncached_signature_ref_at(bss_index) )
 56 {
 57   _is_resolved = false;
 58   assert(pool->tag_at(bss_index).has_bootstrap(), "");

170   }
171 
172   const int SMALL_ARITY = 5;
173   if (use_BSCI && _argc <= SMALL_ARITY && UseBootstrapCallInfo <= 2) {
174     // If there are only a few arguments, and none of them need linking,
175     // push them, instead of asking the JDK runtime to turn around and
176     // pull them, saving a JVM/JDK transition in some simple cases.
177     bool all_resolved = true;
178     for (int i = 0; i < _argc; i++) {
179       bool found_it = false;
180       int arg_index = _pool->bootstrap_argument_index_at(_bss_index, i);
181       _pool->find_cached_constant_at(arg_index, found_it, CHECK);
182       if (!found_it) { all_resolved = false; break; }
183     }
184     if (all_resolved)
185       use_BSCI = false;
186   }
187 
188   if (!use_BSCI) {
189     // return {arg...}; resolution of arguments is done immediately, before JDK code is called
190     objArrayOop args_oop = oopFactory::new_objArray(vmClasses::Object_klass(), _argc, CHECK);
191     objArrayHandle args(THREAD, args_oop);
192     _pool->copy_bootstrap_arguments_at(_bss_index, 0, _argc, args, 0, true, Handle(), CHECK);
193     oop arg_oop = ((_argc == 1) ? args->obj_at(0) : (oop)nullptr);
194     // try to discard the singleton array
195     if (arg_oop != nullptr && !arg_oop->is_array()) {
196       // JVM treats arrays and nulls specially in this position,
197       // but other things are just single arguments
198       _arg_values = Handle(THREAD, arg_oop);
199     } else {
200       _arg_values = args;
201     }
202   } else {
203     // return {arg_count, pool_index}; JDK code must pull the arguments as needed
204     typeArrayOop ints_oop = oopFactory::new_typeArray(T_INT, 2, CHECK);
205     ints_oop->int_at_put(0, _argc);
206     ints_oop->int_at_put(1, _bss_index);
207     _arg_values = Handle(THREAD, ints_oop);
208   }
209 }
210 
211 // there must be a LinkageError pending; try to save it and then throw

253     for (int i = 0; i < _argc; i++) {
254       int pos = (int) strlen(argbuf);
255       if (pos + 20 > (int)sizeof(argbuf)) {
256         os::snprintf_checked(argbuf + pos, sizeof(argbuf) - pos, "...");
257         break;
258       }
259       if (i > 0)  argbuf[pos++] = ',';
260       os::snprintf_checked(argbuf+pos, sizeof(argbuf) - pos, "%d", arg_index(i));
261     }
262     st->print_cr("  argument indexes: {%s}", argbuf);
263   }
264   if (_bsm.not_null()) {
265     st->print("  resolved BSM: "); _bsm->print_on(st);
266   }
267 
268   // How the array of resolved arguments is printed depends highly
269   // on how BootstrapInfo::resolve_args structures the array based on
270   // the use_BSCI setting.
271   if (_arg_values.not_null()) {
272     // Find the static arguments within the first element of _arg_values.
273     objArrayOop static_args = (objArrayOop)_arg_values();
274     if (!static_args->is_array()) {
275       assert(_argc == 1, "Invalid BSM _arg_values for non-array");
276       st->print("  resolved arg[0]: "); static_args->print_on(st);
277     } else if (static_args->is_objArray()) {

278       int lines = 0;
279       for (int i = 0; i < _argc; i++) {
280         oop x = static_args->obj_at(i);
281         if (x != nullptr) {
282           if (++lines > 6) {
283             st->print_cr("  resolved arg[%d]: ...", i);
284             break;
285           }
286           st->print("  resolved arg[%d]: ", i); x->print_on(st);
287         }
288       }
289     } else if (static_args->is_typeArray()) {
290       typeArrayOop tmp_array = (typeArrayOop) static_args;
291       assert(tmp_array->length() == 2, "Invalid BSM _arg_values type array");
292       st->print_cr("  resolved arg[0]: %d", tmp_array->int_at(0));
293       st->print_cr("  resolved arg[1]: %d", tmp_array->int_at(1));


294     }
295   }
296 }

  1 /*
  2  * Copyright (c) 2019, 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  *
 23  */
 24 
 25 #include "classfile/javaClasses.inline.hpp"
 26 #include "classfile/resolutionErrors.hpp"
 27 #include "classfile/systemDictionary.hpp"
 28 #include "classfile/vmClasses.hpp"
 29 #include "interpreter/bootstrapInfo.hpp"
 30 #include "interpreter/linkResolver.hpp"
 31 #include "jvm.h"
 32 #include "logging/log.hpp"
 33 #include "logging/logStream.hpp"
 34 #include "memory/oopFactory.hpp"
 35 #include "memory/resourceArea.hpp"
 36 #include "oops/constantPool.inline.hpp"
 37 #include "oops/cpCache.inline.hpp"
 38 #include "oops/objArrayOop.inline.hpp"
 39 #include "oops/oopCast.inline.hpp"
 40 #include "oops/resolvedIndyEntry.hpp"
 41 #include "oops/typeArrayOop.inline.hpp"
 42 #include "runtime/handles.inline.hpp"
 43 #include "runtime/javaThread.hpp"
 44 #include "runtime/vmThread.hpp"
 45 
 46 //------------------------------------------------------------------------------------------------------------------------
 47 // Implementation of BootstrapInfo
 48 
 49 BootstrapInfo::BootstrapInfo(const constantPoolHandle& pool, int bss_index, int indy_index)
 50   : _pool(pool),
 51     _bss_index(bss_index),
 52     _indy_index(indy_index),
 53     // derived and eagerly cached:
 54     _argc(      pool->bootstrap_argument_count_at(bss_index) ),
 55     _name(      pool->uncached_name_ref_at(bss_index) ),
 56     _signature( pool->uncached_signature_ref_at(bss_index) )
 57 {
 58   _is_resolved = false;
 59   assert(pool->tag_at(bss_index).has_bootstrap(), "");

171   }
172 
173   const int SMALL_ARITY = 5;
174   if (use_BSCI && _argc <= SMALL_ARITY && UseBootstrapCallInfo <= 2) {
175     // If there are only a few arguments, and none of them need linking,
176     // push them, instead of asking the JDK runtime to turn around and
177     // pull them, saving a JVM/JDK transition in some simple cases.
178     bool all_resolved = true;
179     for (int i = 0; i < _argc; i++) {
180       bool found_it = false;
181       int arg_index = _pool->bootstrap_argument_index_at(_bss_index, i);
182       _pool->find_cached_constant_at(arg_index, found_it, CHECK);
183       if (!found_it) { all_resolved = false; break; }
184     }
185     if (all_resolved)
186       use_BSCI = false;
187   }
188 
189   if (!use_BSCI) {
190     // return {arg...}; resolution of arguments is done immediately, before JDK code is called
191     refArrayOop args_oop = oopFactory::new_refArray(vmClasses::Object_klass(),_argc, CHECK);
192     refArrayHandle args(THREAD, args_oop);
193     _pool->copy_bootstrap_arguments_at(_bss_index, 0, _argc, args, 0, true, Handle(), CHECK);
194     oop arg_oop = ((_argc == 1) ? args->obj_at(0) : (oop)nullptr);
195     // try to discard the singleton array
196     if (arg_oop != nullptr && !arg_oop->is_array()) {
197       // JVM treats arrays and nulls specially in this position,
198       // but other things are just single arguments
199       _arg_values = Handle(THREAD, arg_oop);
200     } else {
201       _arg_values = args;
202     }
203   } else {
204     // return {arg_count, pool_index}; JDK code must pull the arguments as needed
205     typeArrayOop ints_oop = oopFactory::new_typeArray(T_INT, 2, CHECK);
206     ints_oop->int_at_put(0, _argc);
207     ints_oop->int_at_put(1, _bss_index);
208     _arg_values = Handle(THREAD, ints_oop);
209   }
210 }
211 
212 // there must be a LinkageError pending; try to save it and then throw

254     for (int i = 0; i < _argc; i++) {
255       int pos = (int) strlen(argbuf);
256       if (pos + 20 > (int)sizeof(argbuf)) {
257         os::snprintf_checked(argbuf + pos, sizeof(argbuf) - pos, "...");
258         break;
259       }
260       if (i > 0)  argbuf[pos++] = ',';
261       os::snprintf_checked(argbuf+pos, sizeof(argbuf) - pos, "%d", arg_index(i));
262     }
263     st->print_cr("  argument indexes: {%s}", argbuf);
264   }
265   if (_bsm.not_null()) {
266     st->print("  resolved BSM: "); _bsm->print_on(st);
267   }
268 
269   // How the array of resolved arguments is printed depends highly
270   // on how BootstrapInfo::resolve_args structures the array based on
271   // the use_BSCI setting.
272   if (_arg_values.not_null()) {
273     // Find the static arguments within the first element of _arg_values.
274     oop static_args = _arg_values();
275     if (!static_args->is_array()) {
276       assert(_argc == 1, "Invalid BSM _arg_values for non-array");
277       st->print("  resolved arg[0]: "); static_args->print_on(st);
278     } else if (static_args->is_refArray()) {
279       refArrayOop static_args_array = oop_cast<refArrayOop>(static_args);
280       int lines = 0;
281       for (int i = 0; i < _argc; i++) {
282         oop x = static_args_array->obj_at(i);
283         if (x != nullptr) {
284           if (++lines > 6) {
285             st->print_cr("  resolved arg[%d]: ...", i);
286             break;
287           }
288           st->print("  resolved arg[%d]: ", i); x->print_on(st);
289         }
290       }
291     } else if (static_args->is_typeArray()) {
292       typeArrayOop tmp_array = (typeArrayOop) static_args;
293       assert(tmp_array->length() == 2, "Invalid BSM _arg_values type array");
294       st->print_cr("  resolved arg[0]: %d", tmp_array->int_at(0));
295       st->print_cr("  resolved arg[1]: %d", tmp_array->int_at(1));
296     } else if (static_args->is_flatArray()) {
297       ShouldNotReachHere();
298     }
299   }
300 }
< prev index next >