< prev index next >

src/hotspot/share/cds/classListParser.cpp

Print this page

   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 "precompiled.hpp"
  26 #include "cds/archiveUtils.hpp"

  27 #include "cds/classListParser.hpp"

  28 #include "cds/lambdaFormInvokers.hpp"
  29 #include "cds/metaspaceShared.hpp"
  30 #include "cds/unregisteredClasses.hpp"
  31 #include "classfile/classLoaderExt.hpp"
  32 #include "classfile/javaClasses.inline.hpp"
  33 #include "classfile/symbolTable.hpp"
  34 #include "classfile/systemDictionary.hpp"
  35 #include "classfile/systemDictionaryShared.hpp"
  36 #include "classfile/vmClasses.hpp"
  37 #include "classfile/vmSymbols.hpp"
  38 #include "interpreter/bytecode.hpp"
  39 #include "interpreter/bytecodeStream.hpp"
  40 #include "interpreter/linkResolver.hpp"
  41 #include "jimage.hpp"
  42 #include "jvm.h"
  43 #include "logging/log.hpp"
  44 #include "logging/logTag.hpp"

  45 #include "memory/resourceArea.hpp"
  46 #include "oops/constantPool.inline.hpp"

  47 #include "runtime/atomic.hpp"
  48 #include "runtime/handles.inline.hpp"
  49 #include "runtime/java.hpp"
  50 #include "runtime/javaCalls.hpp"
  51 #include "utilities/defaultStream.hpp"
  52 #include "utilities/macros.hpp"
  53 #include "utilities/utf8.hpp"
  54 








  55 volatile Thread* ClassListParser::_parsing_thread = nullptr;
  56 ClassListParser* ClassListParser::_instance = nullptr;
  57 
  58 ClassListParser::ClassListParser(const char* file, ParseMode parse_mode) :
  59     _classlist_file(file),
  60     _id2klass_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
  61     _file_input(do_open(file), /* need_close=*/true),
  62     _input_stream(&_file_input) {
  63   log_info(cds)("Parsing %s%s", file,
  64                 parse_lambda_forms_invokers_only() ? " (lambda form invokers only)" : "");
  65   if (!_file_input.is_open()) {
  66     char errmsg[JVM_MAXPATHLEN];
  67     os::lasterror(errmsg, JVM_MAXPATHLEN);
  68     vm_exit_during_initialization("Loading classlist failed", errmsg);
  69   }
  70   _token = _line = nullptr;
  71   _interfaces = new (mtClass) GrowableArray<int>(10, mtClass);
  72   _indy_items = new (mtClass) GrowableArray<const char*>(9, mtClass);
  73   _parse_mode = parse_mode;
  74 

 282   int offset = split_at_tag_from_line();
 283   assert(offset > 0, "would have exited VM");
 284 
 285   if (strcmp(_token, LAMBDA_PROXY_TAG) == 0) {
 286     _indy_items->clear();
 287     split_tokens_by_whitespace(offset, _indy_items);
 288     if (_indy_items->length() < 2) {
 289       error("Line with @ tag has too few items \"%s\" line #%zu", _token, lineno());
 290     }
 291     if (!parse_lambda_forms_invokers_only()) {
 292       _class_name = _indy_items->at(0);
 293       check_class_name(_class_name);
 294       TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name);
 295       if (_indy_items->length() > 0) {
 296         // The current line is "@lambda-proxy class_name". Load the proxy class.
 297         resolve_indy(THREAD, class_name_symbol);
 298       }
 299     }
 300   } else if (strcmp(_token, LAMBDA_FORM_TAG) == 0) {
 301     LambdaFormInvokers::append(os::strdup((const char*)(_line + offset), mtInternal));















 302   } else {
 303     error("Invalid @ tag at the beginning of line \"%s\" line #%zu", _token, lineno());
 304   }
 305 }
 306 
 307 void ClassListParser::skip_whitespaces() {
 308   while (*_token == ' ' || *_token == '\t') {
 309     _token ++;
 310   }
 311 }
 312 
 313 void ClassListParser::skip_non_whitespaces() {
 314   while (*_token && *_token != ' ' && *_token != '\t') {
 315     _token ++;
 316   }
 317 }
 318 
 319 void ClassListParser::parse_int(int* value) {
 320   skip_whitespaces();
 321   if (sscanf(_token, "%i", value) == 1) {

 378 void ClassListParser::print_specified_interfaces() {
 379   const int n = _interfaces->length();
 380   jio_fprintf(defaultStream::error_stream(), "Currently specified interfaces[%d] = {\n", n);
 381   for (int i=0; i<n; i++) {
 382     InstanceKlass* k = lookup_class_by_id(_interfaces->at(i));
 383     jio_fprintf(defaultStream::error_stream(), "  %4d = %s\n", _interfaces->at(i), k->name()->as_klass_external_name());
 384   }
 385   jio_fprintf(defaultStream::error_stream(), "}\n");
 386 }
 387 
 388 void ClassListParser::print_actual_interfaces(InstanceKlass* ik) {
 389   int n = ik->local_interfaces()->length();
 390   jio_fprintf(defaultStream::error_stream(), "Actual interfaces[%d] = {\n", n);
 391   for (int i = 0; i < n; i++) {
 392     InstanceKlass* e = ik->local_interfaces()->at(i);
 393     jio_fprintf(defaultStream::error_stream(), "  %s\n", e->name()->as_klass_external_name());
 394   }
 395   jio_fprintf(defaultStream::error_stream(), "}\n");
 396 }
 397 
 398 void ClassListParser::error(const char* msg, ...) {
 399   va_list ap;
 400   va_start(ap, msg);





 401   int error_index = pointer_delta_as_int(_token, _line);
 402   if (error_index >= _line_len) {
 403     error_index = _line_len - 1;
 404   }
 405   if (error_index < 0) {
 406     error_index = 0;
 407   }
 408 
 409   jio_fprintf(defaultStream::error_stream(),
 410               "An error has occurred while processing class list file %s %zu:%d.\n",
 411               _classlist_file, lineno(), (error_index + 1));
 412   jio_vfprintf(defaultStream::error_stream(), msg, ap);
 413 
 414   if (_line_len <= 0) {
 415     jio_fprintf(defaultStream::error_stream(), "\n");
 416   } else {
 417     jio_fprintf(defaultStream::error_stream(), ":\n");
 418     for (int i=0; i<_line_len; i++) {
 419       char c = _line[i];
 420       if (c == '\0') {
 421         jio_fprintf(defaultStream::error_stream(), "%s", " ");
 422       } else {
 423         jio_fprintf(defaultStream::error_stream(), "%c", c);
 424       }
 425     }
 426     jio_fprintf(defaultStream::error_stream(), "\n");
 427     for (int i=0; i<error_index; i++) {
 428       jio_fprintf(defaultStream::error_stream(), "%s", " ");
 429     }
 430     jio_fprintf(defaultStream::error_stream(), "^\n");
 431   }
 432   va_end(ap);
 433 









 434   vm_exit_during_initialization("class list format error.", nullptr);
 435 }
 436 
 437 void ClassListParser::check_class_name(const char* class_name) {
 438   const char* err = nullptr;
 439   size_t len = strlen(class_name);
 440   if (len > (size_t)Symbol::max_length()) {
 441     err = "class name too long";
 442   } else {
 443     assert(Symbol::max_length() < INT_MAX && len < INT_MAX, "must be");
 444     if (!UTF8::is_legal_utf8((const unsigned char*)class_name, (int)len, /*version_leq_47*/false)) {
 445       err = "class name is not valid UTF8";
 446     }
 447   }
 448   if (err != nullptr) {
 449     jio_fprintf(defaultStream::error_stream(),
 450               "An error has occurred while processing class list file %s:%zu %s\n",
 451               _classlist_file, lineno(), err);
 452     vm_exit_during_initialization("class list format error.", nullptr);
 453   }
 454 }
 455 










 456 // This function is used for loading classes for customized class loaders
 457 // during archive dumping.
 458 InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS) {
 459 #if !(defined(_LP64) && (defined(LINUX) || defined(__APPLE__) || defined(_WINDOWS)))
 460   // The only supported platforms are: (1) Linux/64-bit and (2) Solaris/64-bit and
 461   // (3) MacOSX/64-bit and (4) Windowss/64-bit
 462   // This #if condition should be in sync with the areCustomLoadersSupportedForCDS
 463   // method in test/lib/jdk/test/lib/Platform.java.
 464   error("AppCDS custom class loaders not supported on this platform");
 465 #endif
 466 
 467   if (!is_super_specified()) {
 468     error("If source location is specified, super class must be also specified");
 469   }
 470   if (!is_id_specified()) {
 471     error("If source location is specified, id must be also specified");
 472   }
 473   if (strncmp(_class_name, "java/", 5) == 0) {
 474     log_info(cds)("Prohibited package for non-bootstrap classes: %s.class from %s",
 475           _class_name, _source);

 710     error("Class %s implements the interface %s, but no interface has been specified in the input line",
 711           _class_name, interface_name->as_klass_external_name());
 712     ShouldNotReachHere();
 713   }
 714 
 715   int i;
 716   for (i=0; i<n; i++) {
 717     InstanceKlass* k = lookup_class_by_id(_interfaces->at(i));
 718     if (interface_name == k->name()) {
 719       return k;
 720     }
 721   }
 722 
 723   // interface_name is not specified by the "interfaces:" keyword.
 724   print_specified_interfaces();
 725   error("The interface %s implemented by class %s does not match any of the specified interface IDs",
 726         interface_name->as_klass_external_name(), _class_name);
 727   ShouldNotReachHere();
 728   return nullptr;
 729 }















































































































































































































































































































   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 "precompiled.hpp"
  26 #include "cds/archiveUtils.hpp"
  27 #include "cds/cdsConfig.hpp"
  28 #include "cds/classListParser.hpp"
  29 #include "cds/classPrelinker.hpp"
  30 #include "cds/lambdaFormInvokers.hpp"
  31 #include "cds/metaspaceShared.hpp"
  32 #include "cds/unregisteredClasses.hpp"

  33 #include "classfile/javaClasses.inline.hpp"
  34 #include "classfile/symbolTable.hpp"
  35 #include "classfile/systemDictionary.hpp"
  36 #include "classfile/systemDictionaryShared.hpp"
  37 #include "classfile/vmClasses.hpp"
  38 #include "classfile/vmSymbols.hpp"
  39 #include "interpreter/bytecode.hpp"
  40 #include "interpreter/interpreterRuntime.hpp"
  41 #include "interpreter/linkResolver.hpp"
  42 #include "jimage.hpp"
  43 #include "jvm.h"
  44 #include "logging/log.hpp"
  45 #include "logging/logTag.hpp"
  46 #include "memory/oopFactory.hpp"
  47 #include "memory/resourceArea.hpp"
  48 #include "oops/constantPool.inline.hpp"
  49 #include "oops/cpCache.inline.hpp"
  50 #include "runtime/atomic.hpp"
  51 #include "runtime/handles.inline.hpp"
  52 #include "runtime/java.hpp"
  53 #include "runtime/javaCalls.hpp"
  54 #include "utilities/defaultStream.hpp"
  55 #include "utilities/macros.hpp"
  56 #include "utilities/utf8.hpp"
  57 
  58 const char* ClassListParser::CLASS_REFLECTION_DATA_TAG = "@class-reflection-data";
  59 const char* ClassListParser::CONSTANT_POOL_TAG = "@cp";
  60 const char* ClassListParser::DYNAMIC_PROXY_TAG = "@dynamic-proxy";
  61 const char* ClassListParser::LAMBDA_FORM_TAG = "@lambda-form-invoker";
  62 const char* ClassListParser::LAMBDA_PROXY_TAG = "@lambda-proxy";
  63 const char* ClassListParser::LOADER_NEGATIVE_CACHE_TAG = "@loader-negative-cache";
  64 const char* ClassListParser::ARRAY_TAG = "@array";
  65 
  66 volatile Thread* ClassListParser::_parsing_thread = nullptr;
  67 ClassListParser* ClassListParser::_instance = nullptr;
  68 
  69 ClassListParser::ClassListParser(const char* file, ParseMode parse_mode) :
  70     _classlist_file(file),
  71     _id2klass_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
  72     _file_input(do_open(file), /* need_close=*/true),
  73     _input_stream(&_file_input) {
  74   log_info(cds)("Parsing %s%s", file,
  75                 parse_lambda_forms_invokers_only() ? " (lambda form invokers only)" : "");
  76   if (!_file_input.is_open()) {
  77     char errmsg[JVM_MAXPATHLEN];
  78     os::lasterror(errmsg, JVM_MAXPATHLEN);
  79     vm_exit_during_initialization("Loading classlist failed", errmsg);
  80   }
  81   _token = _line = nullptr;
  82   _interfaces = new (mtClass) GrowableArray<int>(10, mtClass);
  83   _indy_items = new (mtClass) GrowableArray<const char*>(9, mtClass);
  84   _parse_mode = parse_mode;
  85 

 293   int offset = split_at_tag_from_line();
 294   assert(offset > 0, "would have exited VM");
 295 
 296   if (strcmp(_token, LAMBDA_PROXY_TAG) == 0) {
 297     _indy_items->clear();
 298     split_tokens_by_whitespace(offset, _indy_items);
 299     if (_indy_items->length() < 2) {
 300       error("Line with @ tag has too few items \"%s\" line #%zu", _token, lineno());
 301     }
 302     if (!parse_lambda_forms_invokers_only()) {
 303       _class_name = _indy_items->at(0);
 304       check_class_name(_class_name);
 305       TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name);
 306       if (_indy_items->length() > 0) {
 307         // The current line is "@lambda-proxy class_name". Load the proxy class.
 308         resolve_indy(THREAD, class_name_symbol);
 309       }
 310     }
 311   } else if (strcmp(_token, LAMBDA_FORM_TAG) == 0) {
 312     LambdaFormInvokers::append(os::strdup((const char*)(_line + offset), mtInternal));
 313   } else if (strcmp(_token, CONSTANT_POOL_TAG) == 0) {
 314     _token = _line + offset;
 315     parse_constant_pool_tag();
 316   } else if (strcmp(_token, ARRAY_TAG) == 0) {
 317     _token = _line + offset;
 318     parse_array_dimension_tag();
 319   } else if (strcmp(_token, CLASS_REFLECTION_DATA_TAG) == 0) {
 320     _token = _line + offset;
 321     parse_class_reflection_data_tag();
 322   } else if (strcmp(_token, DYNAMIC_PROXY_TAG) == 0) {
 323     _token = _line + offset;
 324     parse_dynamic_proxy_tag();
 325   } else if (strcmp(_token, LOADER_NEGATIVE_CACHE_TAG) == 0) {
 326     _token = _line + offset;
 327     parse_loader_negative_cache_tag();
 328   } else {
 329     error("Invalid @ tag at the beginning of line \"%s\" line #%zu", _token, lineno());
 330   }
 331 }
 332 
 333 void ClassListParser::skip_whitespaces() {
 334   while (*_token == ' ' || *_token == '\t') {
 335     _token ++;
 336   }
 337 }
 338 
 339 void ClassListParser::skip_non_whitespaces() {
 340   while (*_token && *_token != ' ' && *_token != '\t') {
 341     _token ++;
 342   }
 343 }
 344 
 345 void ClassListParser::parse_int(int* value) {
 346   skip_whitespaces();
 347   if (sscanf(_token, "%i", value) == 1) {

 404 void ClassListParser::print_specified_interfaces() {
 405   const int n = _interfaces->length();
 406   jio_fprintf(defaultStream::error_stream(), "Currently specified interfaces[%d] = {\n", n);
 407   for (int i=0; i<n; i++) {
 408     InstanceKlass* k = lookup_class_by_id(_interfaces->at(i));
 409     jio_fprintf(defaultStream::error_stream(), "  %4d = %s\n", _interfaces->at(i), k->name()->as_klass_external_name());
 410   }
 411   jio_fprintf(defaultStream::error_stream(), "}\n");
 412 }
 413 
 414 void ClassListParser::print_actual_interfaces(InstanceKlass* ik) {
 415   int n = ik->local_interfaces()->length();
 416   jio_fprintf(defaultStream::error_stream(), "Actual interfaces[%d] = {\n", n);
 417   for (int i = 0; i < n; i++) {
 418     InstanceKlass* e = ik->local_interfaces()->at(i);
 419     jio_fprintf(defaultStream::error_stream(), "  %s\n", e->name()->as_klass_external_name());
 420   }
 421   jio_fprintf(defaultStream::error_stream(), "}\n");
 422 }
 423 
 424 void ClassListParser::print_diagnostic_info(outputStream* st, const char* msg, ...) {
 425   va_list ap;
 426   va_start(ap, msg);
 427   print_diagnostic_info(st, msg, ap);
 428   va_end(ap);
 429 }
 430 
 431 void ClassListParser::print_diagnostic_info(outputStream* st, const char* msg, va_list ap) {
 432   int error_index = pointer_delta_as_int(_token, _line);
 433   if (error_index >= _line_len) {
 434     error_index = _line_len - 1;
 435   }
 436   if (error_index < 0) {
 437     error_index = 0;
 438   }
 439 
 440   jio_fprintf(defaultStream::error_stream(),
 441               "An error has occurred while processing class list file %s %zu:%d.\n",
 442               _classlist_file, lineno(), (error_index + 1));
 443   jio_vfprintf(defaultStream::error_stream(), msg, ap);
 444 
 445   if (_line_len <= 0) {
 446     st->print("\n");
 447   } else {
 448     st->print(":\n");
 449     for (int i=0; i<_line_len; i++) {
 450       char c = _line[i];
 451       if (c == '\0') {
 452         st->print("%s", " ");
 453       } else {
 454         st->print("%c", c);
 455       }
 456     }
 457     st->print("\n");
 458     for (int i=0; i<error_index; i++) {
 459       st->print("%s", " ");
 460     }
 461     st->print("^\n");
 462   }
 463 }
 464 
 465 void ClassListParser::error(const char* msg, ...) {
 466   va_list ap;
 467   va_start(ap, msg);
 468   fileStream fs(defaultStream::error_stream());
 469   //TODO: we should write to UL/error instead, but that requires fixing some tests cases.
 470   //LogTarget(Error, cds) lt;
 471   //LogStream ls(lt);
 472   print_diagnostic_info(&fs, msg, ap);
 473   va_end(ap);
 474   vm_exit_during_initialization("class list format error.", nullptr);
 475 }
 476 
 477 void ClassListParser::check_class_name(const char* class_name) {
 478   const char* err = nullptr;
 479   size_t len = strlen(class_name);
 480   if (len > (size_t)Symbol::max_length()) {
 481     err = "class name too long";
 482   } else {
 483     assert(Symbol::max_length() < INT_MAX && len < INT_MAX, "must be");
 484     if (!UTF8::is_legal_utf8((const unsigned char*)class_name, (int)len, /*version_leq_47*/false)) {
 485       err = "class name is not valid UTF8";
 486     }
 487   }
 488   if (err != nullptr) {
 489     jio_fprintf(defaultStream::error_stream(),
 490               "An error has occurred while processing class list file %s:%zu %s\n",
 491               _classlist_file, lineno(), err);
 492     vm_exit_during_initialization("class list format error.", nullptr);
 493   }
 494 }
 495 
 496 void ClassListParser::constant_pool_resolution_warning(const char* msg, ...) {
 497   va_list ap;
 498   va_start(ap, msg);
 499   LogTarget(Warning, cds, resolve) lt;
 500   LogStream ls(lt);
 501   print_diagnostic_info(&ls, msg, ap);
 502   ls.print("Your classlist may be out of sync with the JDK or the application.");
 503   va_end(ap);
 504 }
 505 
 506 // This function is used for loading classes for customized class loaders
 507 // during archive dumping.
 508 InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS) {
 509 #if !(defined(_LP64) && (defined(LINUX) || defined(__APPLE__) || defined(_WINDOWS)))
 510   // The only supported platforms are: (1) Linux/64-bit and (2) Solaris/64-bit and
 511   // (3) MacOSX/64-bit and (4) Windowss/64-bit
 512   // This #if condition should be in sync with the areCustomLoadersSupportedForCDS
 513   // method in test/lib/jdk/test/lib/Platform.java.
 514   error("AppCDS custom class loaders not supported on this platform");
 515 #endif
 516 
 517   if (!is_super_specified()) {
 518     error("If source location is specified, super class must be also specified");
 519   }
 520   if (!is_id_specified()) {
 521     error("If source location is specified, id must be also specified");
 522   }
 523   if (strncmp(_class_name, "java/", 5) == 0) {
 524     log_info(cds)("Prohibited package for non-bootstrap classes: %s.class from %s",
 525           _class_name, _source);

 760     error("Class %s implements the interface %s, but no interface has been specified in the input line",
 761           _class_name, interface_name->as_klass_external_name());
 762     ShouldNotReachHere();
 763   }
 764 
 765   int i;
 766   for (i=0; i<n; i++) {
 767     InstanceKlass* k = lookup_class_by_id(_interfaces->at(i));
 768     if (interface_name == k->name()) {
 769       return k;
 770     }
 771   }
 772 
 773   // interface_name is not specified by the "interfaces:" keyword.
 774   print_specified_interfaces();
 775   error("The interface %s implemented by class %s does not match any of the specified interface IDs",
 776         interface_name->as_klass_external_name(), _class_name);
 777   ShouldNotReachHere();
 778   return nullptr;
 779 }
 780 
 781 InstanceKlass* ClassListParser::find_builtin_class_helper(JavaThread* current, Symbol* class_name_symbol, oop class_loader_oop) {
 782   Handle class_loader(current, class_loader_oop);
 783   Handle protection_domain;
 784   return SystemDictionary::find_instance_klass(current, class_name_symbol, class_loader, protection_domain);
 785 }
 786 
 787 InstanceKlass* ClassListParser::find_builtin_class(JavaThread* current, const char* class_name) {
 788   TempNewSymbol class_name_symbol = SymbolTable::new_symbol(class_name);
 789   InstanceKlass* ik;
 790 
 791   if ( (ik = find_builtin_class_helper(current, class_name_symbol, nullptr)) != nullptr
 792     || (ik = find_builtin_class_helper(current, class_name_symbol, SystemDictionary::java_platform_loader())) != nullptr
 793     || (ik = find_builtin_class_helper(current, class_name_symbol, SystemDictionary::java_system_loader())) != nullptr) {
 794     return ik;
 795   } else {
 796     return nullptr;
 797   }
 798 }
 799 
 800 void ClassListParser::parse_array_dimension_tag() {
 801   if (parse_lambda_forms_invokers_only()) {
 802     return;
 803   }
 804 
 805   skip_whitespaces();
 806   char* class_name = _token;
 807   skip_non_whitespaces();
 808   *_token = '\0';
 809   _token ++;
 810 
 811   skip_whitespaces();
 812   int dim;
 813   parse_uint(&dim);
 814 
 815   JavaThread* THREAD = JavaThread::current();
 816   InstanceKlass* ik = find_builtin_class(THREAD, class_name);
 817   if (ik == nullptr) {
 818     _token = class_name;
 819     if (strstr(class_name, "/$Proxy") != nullptr ||
 820         strstr(class_name, "MethodHandle$Species_") != nullptr) {
 821       // ignore -- TODO: we should filter these out in classListWriter.cpp
 822     } else {
 823       constant_pool_resolution_warning("class %s is not (yet) loaded by one of the built-in loaders", class_name);
 824     }
 825     return;
 826   }
 827 
 828   if (dim > 0) {
 829     ik->array_klass(dim, THREAD);
 830     if (HAS_PENDING_EXCEPTION) {
 831       error("Array klass allocation failed: %s %d", _class_name, dim);
 832     }
 833   }
 834 }
 835 
 836 void ClassListParser::parse_constant_pool_tag() {
 837   if (parse_lambda_forms_invokers_only()) {
 838     return;
 839   }
 840 
 841   JavaThread* THREAD = JavaThread::current();
 842   skip_whitespaces();
 843   char* class_name = _token;
 844   skip_non_whitespaces();
 845   *_token = '\0';
 846   _token ++;
 847 
 848   InstanceKlass* ik = find_builtin_class(THREAD, class_name);
 849   if (ik == nullptr) {
 850     _token = class_name;
 851     if (strstr(class_name, "/$Proxy") != nullptr ||
 852         strstr(class_name, "MethodHandle$Species_") != nullptr) {
 853       // ignore -- TODO: we should filter these out in classListWriter.cpp
 854     } else {
 855       constant_pool_resolution_warning("class %s is not (yet) loaded by one of the built-in loaders", class_name);
 856     }
 857     return;
 858   }
 859 
 860   ResourceMark rm(THREAD);
 861   constantPoolHandle cp(THREAD, ik->constants());
 862   GrowableArray<bool> preresolve_list(cp->length(), cp->length(), false);
 863   bool preresolve_class = false;
 864   bool preresolve_fmi = false;
 865   bool preresolve_indy = false;
 866   
 867   while (*_token) {
 868     int cp_index;
 869     skip_whitespaces();
 870     parse_uint(&cp_index);
 871     if (cp_index < 1 || cp_index >= cp->length()) {
 872       constant_pool_resolution_warning("Invalid constant pool index %d", cp_index);
 873       return;
 874     } else {
 875       preresolve_list.at_put(cp_index, true);
 876     }
 877     constantTag cp_tag = cp->tag_at(cp_index);
 878     switch (cp_tag.value()) {
 879     case JVM_CONSTANT_UnresolvedClass:
 880       preresolve_class = true;
 881       break;
 882     case JVM_CONSTANT_UnresolvedClassInError:
 883     case JVM_CONSTANT_Class:
 884       // ignore
 885       break;
 886     case JVM_CONSTANT_Fieldref:
 887     case JVM_CONSTANT_Methodref:
 888     case JVM_CONSTANT_InterfaceMethodref:
 889       preresolve_fmi = true;
 890       break;
 891     case JVM_CONSTANT_InvokeDynamic:
 892       preresolve_indy = true;
 893       break;
 894     default:
 895       constant_pool_resolution_warning("Unsupported constant pool index %d: %s (type=%d)",
 896                                        cp_index, cp_tag.internal_name(), cp_tag.value());
 897       return;
 898     }
 899   }
 900 
 901   if (preresolve_class) {
 902     ClassPrelinker::preresolve_class_cp_entries(THREAD, ik, &preresolve_list);
 903   }
 904   if (preresolve_fmi) {
 905 // FIXME: too coarse; doesn't cover resolution of Class entries
 906 //    JavaThread::NoJavaCodeMark no_java_code(THREAD); // ensure no clinits are exectued
 907     ClassPrelinker::preresolve_field_and_method_cp_entries(THREAD, ik, &preresolve_list);
 908   }
 909   if (preresolve_indy) {
 910     ClassPrelinker::preresolve_indy_cp_entries(THREAD, ik, &preresolve_list);
 911   }
 912 }
 913 
 914 void ClassListParser::parse_class_reflection_data_tag() {
 915   if (parse_lambda_forms_invokers_only()) {
 916     return;
 917   }
 918 
 919   JavaThread* THREAD = JavaThread::current();
 920   skip_whitespaces();
 921   char* class_name = _token;
 922   skip_non_whitespaces();
 923   *_token = '\0';
 924   _token ++;
 925 
 926   InstanceKlass* ik = find_builtin_class(THREAD, class_name);
 927   if (ik == nullptr) {
 928     _token = class_name;
 929     if (strstr(class_name, "/$Proxy") != nullptr ||
 930         strstr(class_name, "MethodHandle$Species_") != nullptr) {
 931       // ignore -- TODO: we should filter these out in classListWriter.cpp
 932     } else {
 933       warning("%s: class not found: %s", CLASS_REFLECTION_DATA_TAG, class_name);
 934     }
 935     return;
 936   }
 937 
 938   ResourceMark rm(THREAD);
 939 
 940   int rd_flags = _unspecified;
 941   while (*_token) {
 942     skip_whitespaces();
 943     if (rd_flags != _unspecified) {
 944       error("rd_flags specified twice");
 945       return;
 946     }
 947     parse_uint(&rd_flags);
 948   }
 949   if (rd_flags == _unspecified) {
 950     error("no rd_flags specified");
 951     return;
 952   }
 953 
 954   if (ArchiveReflectionData) {
 955     ClassPrelinker::generate_reflection_data(THREAD, ik, rd_flags);
 956   }
 957 }
 958 
 959 oop ClassListParser::loader_from_type(const char* loader_type) {
 960   oop loader;
 961   if (!ArchiveUtils::builtin_loader_from_type(loader_type, &loader)) {
 962     error("Unknown loader %s", loader_type);
 963   }
 964   return loader;
 965 }
 966 
 967 void ClassListParser::parse_dynamic_proxy_tag() {
 968   if (parse_lambda_forms_invokers_only()) {
 969     return;
 970   }
 971 
 972   skip_whitespaces();
 973   char* loader_type = _token;
 974   skip_non_whitespaces();
 975   *_token = '\0';
 976   _token ++;
 977 
 978   skip_whitespaces();
 979   char* proxy_name_str = _token;
 980   skip_non_whitespaces();
 981   *_token = '\0';
 982   _token ++;
 983 
 984   skip_whitespaces();
 985   int access_flags;
 986   parse_uint(&access_flags);
 987 
 988   skip_whitespaces();
 989   int num_intfs;
 990   parse_uint(&num_intfs);
 991 
 992   JavaThread* THREAD = JavaThread::current();
 993   Handle loader(THREAD, loader_from_type(loader_type));
 994   Handle proxy_name(THREAD, java_lang_String::create_oop_from_str(proxy_name_str, THREAD));
 995   if (HAS_PENDING_EXCEPTION) {
 996     error("Out of memory");
 997   }
 998 
 999   objArrayHandle interfaces(THREAD, oopFactory::new_objArray(vmClasses::Class_klass(), num_intfs, THREAD));
1000   if (HAS_PENDING_EXCEPTION) {
1001     error("Out of memory");
1002   }
1003 
1004   for (int i = 0; i < num_intfs; i++) {
1005     skip_whitespaces();
1006     char* intf_name = _token;
1007     skip_non_whitespaces();
1008     *_token = '\0';
1009     _token ++;
1010 
1011     InstanceKlass* ik = find_builtin_class(THREAD, intf_name);
1012     if (ik != nullptr) {
1013       interfaces()->obj_at_put(i, ik->java_mirror());
1014     } else {
1015       error("Unknown class %s", intf_name);
1016     }
1017   }
1018 
1019   if (strncmp("jdk.proxy", proxy_name_str, 9) != 0) {
1020     return;
1021   }
1022 
1023   ClassPrelinker::define_dynamic_proxy_class(loader, proxy_name, interfaces, access_flags, THREAD);
1024   if (HAS_PENDING_EXCEPTION) {
1025     PENDING_EXCEPTION->print_on(tty);
1026     error("defineProxyClassForCDS failed");
1027   }
1028 }
1029 
1030 void ClassListParser::parse_loader_negative_cache_tag() {
1031   skip_whitespaces();
1032   char* loader_type = _token;
1033   skip_non_whitespaces();
1034   *_token = '\0';
1035   _token ++;
1036 
1037   oop loader;
1038   Klass* loader_klass;
1039   if (!strcmp(loader_type, "app")) {
1040     loader = SystemDictionary::java_system_loader();
1041     loader_klass = vmClasses::jdk_internal_loader_ClassLoaders_AppClassLoader_klass();
1042   } else if (!strcmp(loader_type, "platform")) {
1043     loader = SystemDictionary::java_platform_loader();
1044     loader_klass = vmClasses::jdk_internal_loader_ClassLoaders_PlatformClassLoader_klass();
1045   } else {
1046     warning("%s: unrecognized loader type %s is ignored", LOADER_NEGATIVE_CACHE_TAG, loader_type);
1047     return;
1048   }
1049 
1050   char* contents = _token;
1051   skip_non_whitespaces();
1052   *_token = '\0';
1053   _token ++;
1054 
1055   if (ArchiveLoaderLookupCache) {
1056     TempNewSymbol method = SymbolTable::new_symbol("generateNegativeLookupCache");
1057     TempNewSymbol signature = SymbolTable::new_symbol("(Ljava/lang/String;)V");
1058 
1059     EXCEPTION_MARK;
1060     HandleMark hm(THREAD);
1061     JavaCallArguments args(Handle(THREAD, loader));
1062     Handle contents_h = java_lang_String::create_from_str(contents, THREAD);
1063     args.push_oop(contents_h);
1064     JavaValue result(T_VOID);
1065     JavaCalls::call_virtual(&result,
1066                             loader_klass,
1067                             method,
1068                             signature,
1069                             &args, THREAD);
1070     if (HAS_PENDING_EXCEPTION) {
1071       Handle exc_handle(THREAD, PENDING_EXCEPTION);
1072       CLEAR_PENDING_EXCEPTION;
1073 
1074       log_warning(cds)("Exception during BuiltinClassLoader::generateNegativeLookupCache() call for %s loader", loader_type);
1075       LogStreamHandle(Debug, cds) log;
1076       if (log.is_enabled()) {
1077         java_lang_Throwable::print_stack_trace(exc_handle, &log);
1078       }
1079     }
1080   }
1081 }
< prev index next >