@@ -114,6 +114,7 @@ intx AOTMetaspace::_relocation_delta;
114114char * AOTMetaspace::_requested_base_address;
115115Array<Method*>* AOTMetaspace::_archived_method_handle_intrinsics = nullptr ;
116116bool AOTMetaspace::_use_optimized_module_handling = true ;
117+ FileMapInfo* AOTMetaspace::_output_mapinfo = nullptr ;
117118
118119// The CDS archive is divided into the following regions:
119120// rw - read-write metadata
@@ -322,6 +323,24 @@ void AOTMetaspace::initialize_for_static_dump() {
322323 AOTMetaspace::unrecoverable_writing_error ();
323324 }
324325 _symbol_region.init (&_symbol_rs, &_symbol_vs);
326+ if (CDSConfig::is_dumping_preimage_static_archive ()) {
327+ // We are in the AOT training run. User code is executed.
328+ //
329+ // On Windows, if the user code closes System.out and we open the AOT config file for output
330+ // only at VM exit, we might get back the same file HANDLE as stdout, and the AOT config
331+ // file may get corrupted by UL logs. By opening early, we ensure that the output
332+ // HANDLE is different than stdout so we can avoid such corruption.
333+ open_output_mapinfo ();
334+ } else {
335+ // No need for the above as we won't execute any user code.
336+ }
337+ }
338+
339+ void AOTMetaspace::open_output_mapinfo () {
340+ const char * static_archive = CDSConfig::output_archive_path ();
341+ assert (static_archive != nullptr , " sanity" );
342+ _output_mapinfo = new FileMapInfo (static_archive, true );
343+ _output_mapinfo->open_as_output ();
325344}
326345
327346// Called by universe_post_init()
@@ -655,15 +674,14 @@ class VM_PopulateDumpSharedSpace : public VM_Operation {
655674
656675public:
657676
658- VM_PopulateDumpSharedSpace (StaticArchiveBuilder& b) :
659- VM_Operation (), _mapped_heap_info(), _streamed_heap_info(), _map_info(nullptr ), _builder(b) {}
677+ VM_PopulateDumpSharedSpace (StaticArchiveBuilder& b, FileMapInfo* map_info ) :
678+ VM_Operation (), _mapped_heap_info(), _streamed_heap_info(), _map_info(map_info ), _builder(b) {}
660679
661680 bool skip_operation () const { return false ; }
662681
663682 VMOp_Type type () const { return VMOp_PopulateDumpSharedSpace; }
664683 ArchiveMappedHeapInfo* mapped_heap_info () { return &_mapped_heap_info; }
665684 ArchiveStreamedHeapInfo* streamed_heap_info () { return &_streamed_heap_info; }
666- FileMapInfo* map_info () const { return _map_info; }
667685 void doit (); // outline because gdb sucks
668686 bool allow_nested_vm_operations () const { return true ; }
669687}; // class VM_PopulateDumpSharedSpace
@@ -795,12 +813,6 @@ void VM_PopulateDumpSharedSpace::doit() {
795813 CppVtables::zero_archived_vtables ();
796814
797815 // Write the archive file
798- if (CDSConfig::is_dumping_final_static_archive ()) {
799- FileMapInfo::free_current_info (); // FIXME: should not free current info
800- }
801- const char * static_archive = CDSConfig::output_archive_path ();
802- assert (static_archive != nullptr , " sanity" );
803- _map_info = new FileMapInfo (static_archive, true );
804816 _map_info->populate_header (AOTMetaspace::core_region_alignment ());
805817 _map_info->set_early_serialized_data (early_serialized_data);
806818 _map_info->set_serialized_data (serialized_data);
@@ -1138,7 +1150,14 @@ void AOTMetaspace::dump_static_archive_impl(StaticArchiveBuilder& builder, TRAPS
11381150 }
11391151#endif
11401152
1141- VM_PopulateDumpSharedSpace op (builder);
1153+ if (!CDSConfig::is_dumping_preimage_static_archive ()) {
1154+ if (CDSConfig::is_dumping_final_static_archive ()) {
1155+ FileMapInfo::free_current_info (); // FIXME: should not free current info
1156+ }
1157+ open_output_mapinfo ();
1158+ }
1159+
1160+ VM_PopulateDumpSharedSpace op (builder, _output_mapinfo);
11421161 VMThread::execute (&op);
11431162
11441163 if (AOTCodeCache::is_on_for_dump () && CDSConfig::is_dumping_final_static_archive ()) {
@@ -1152,7 +1171,9 @@ void AOTMetaspace::dump_static_archive_impl(StaticArchiveBuilder& builder, TRAPS
11521171 CDSConfig::disable_dumping_aot_code ();
11531172 }
11541173
1155- bool status = write_static_archive (&builder, op.map_info (), op.mapped_heap_info (), op.streamed_heap_info ());
1174+ bool status = write_static_archive (&builder, _output_mapinfo, op.mapped_heap_info (), op.streamed_heap_info ());
1175+ assert (!_output_mapinfo->is_open (), " Must be closed already" );
1176+ _output_mapinfo = nullptr ;
11561177 if (status && CDSConfig::is_dumping_preimage_static_archive ()) {
11571178 tty->print_cr (" %s AOTConfiguration recorded: %s" ,
11581179 CDSConfig::has_temp_aot_config_file () ? " Temporary" : " " , AOTConfiguration);
@@ -1173,11 +1194,10 @@ bool AOTMetaspace::write_static_archive(ArchiveBuilder* builder,
11731194 // relocate the data so that it can be mapped to AOTMetaspace::requested_base_address()
11741195 // without runtime relocation.
11751196 builder->relocate_to_requested ();
1176-
1177- map_info->open_as_output ();
11781197 if (!map_info->is_open ()) {
11791198 return false ;
11801199 }
1200+ map_info->prepare_for_writing ();
11811201 builder->write_archive (map_info, mapped_heap_info, streamed_heap_info);
11821202 return true ;
11831203}
0 commit comments