< prev index next >

src/hotspot/share/cds/lambdaFormInvokers.cpp

Print this page
*** 1,7 ***
  /*
!  * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.
--- 1,7 ---
  /*
!  * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.

*** 22,10 ***
--- 22,11 ---
   *
   */
  
  #include "precompiled.hpp"
  #include "cds/archiveBuilder.hpp"
+ #include "cds/cdsConfig.hpp"
  #include "cds/lambdaFormInvokers.hpp"
  #include "cds/metaspaceShared.hpp"
  #include "cds/regeneratedClasses.hpp"
  #include "classfile/classLoadInfo.hpp"
  #include "classfile/classFileStream.hpp"

*** 88,16 ***
--- 89,34 ---
      log_info(cds)("Regenerate MethodHandle Holder classes...done");
    }
  };
  
  void LambdaFormInvokers::regenerate_holder_classes(TRAPS) {
+   if (!CDSConfig::is_dumping_regenerated_lambdaform_invokers()) {
+     return;
+   }
    PrintLambdaFormMessage plm;
    if (_lambdaform_lines == nullptr || _lambdaform_lines->length() == 0) {
      log_info(cds)("Nothing to regenerate for holder classes");
      return;
    }
  
+   if (CDSConfig::is_dumping_static_archive() && CDSConfig::is_dumping_invokedynamic()) {
+     // Work around JDK-8310831, as some methods in lambda form holder classes may not get generated.
+     log_info(cds)("Archived MethodHandles may refer to lambda form holder classes. Cannot regenerate.");
+     return;
+   }
+ 
+   if (CDSConfig::is_dumping_dynamic_archive() && CDSConfig::is_dumping_aot_linked_classes() &&
+       CDSConfig::is_using_aot_linked_classes()) {
+     // The base archive may have some pre-resolved CP entries that point to the lambda form holder
+     // classes in the base archive. If we generate new versions of these classes, those CP entries
+     // will be pointing to invalid classes.
+     log_info(cds)("Base archive already have aot-linked lambda form holder classes. Cannot regenerate.");
+     return;
+   }
+ 
    ResourceMark rm(THREAD);
  
    Symbol* cds_name  = vmSymbols::jdk_internal_misc_CDS();
    Klass*  cds_klass = SystemDictionary::resolve_or_null(cds_name, THREAD);
    guarantee(cds_klass != nullptr, "jdk/internal/misc/CDS must exist!");

*** 165,11 ***
        int len = h_bytes->length();
        // make a copy of class bytes so GC will not affect us.
        char *buf = NEW_RESOURCE_ARRAY(char, len);
        memcpy(buf, (char*)h_bytes->byte_at_addr(0), len);
        ClassFileStream st((u1*)buf, len, nullptr, ClassFileStream::verify);
!       regenerate_class(class_name, st, CHECK);
      }
    }
  }
  
  void LambdaFormInvokers::regenerate_class(char* class_name, ClassFileStream& st, TRAPS) {
--- 184,13 ---
        int len = h_bytes->length();
        // make a copy of class bytes so GC will not affect us.
        char *buf = NEW_RESOURCE_ARRAY(char, len);
        memcpy(buf, (char*)h_bytes->byte_at_addr(0), len);
        ClassFileStream st((u1*)buf, len, nullptr, ClassFileStream::verify);
!       if (!CDSConfig::is_dumping_invokedynamic() /* work around JDK-8310831 */) {
+         regenerate_class(class_name, st, CHECK);
+       }
      }
    }
  }
  
  void LambdaFormInvokers::regenerate_class(char* class_name, ClassFileStream& st, TRAPS) {

*** 204,10 ***
--- 225,17 ---
    log_info(cds, lambda)("Regenerated class %s, old: " INTPTR_FORMAT " new: " INTPTR_FORMAT,
                   class_name, p2i(klass), p2i(result));
  }
  
  void LambdaFormInvokers::dump_static_archive_invokers() {
+   if (CDSConfig::is_dumping_preimage_static_archive() ||
+       CDSConfig::is_dumping_final_static_archive()) {
+     // This function writes the "names" of the invokers.
+     // This is not supported in new CDS workflow for now.
+     return;
+   }
+ 
    if (_lambdaform_lines != nullptr && _lambdaform_lines->length() > 0) {
      int count = 0;
      int len   = _lambdaform_lines->length();
      for (int i = 0; i < len; i++) {
        char* str = _lambdaform_lines->at(i);
< prev index next >