@@ -113,6 +113,7 @@ intx MetaspaceShared::_relocation_delta;
113113char * MetaspaceShared::_requested_base_address;
114114Array<Method*>* MetaspaceShared::_archived_method_handle_intrinsics = nullptr ;
115115bool MetaspaceShared::_use_optimized_module_handling = true ;
116+ FileMapInfo* MetaspaceShared::_output_mapinfo = nullptr ;
116117
117118// The CDS archive is divided into the following regions:
118119// rw - read-write metadata
@@ -321,6 +322,24 @@ void MetaspaceShared::initialize_for_static_dump() {
321322 MetaspaceShared::unrecoverable_writing_error ();
322323 }
323324 _symbol_region.init (&_symbol_rs, &_symbol_vs);
325+ if (CDSConfig::is_dumping_preimage_static_archive ()) {
326+ // We are in the AOT training run. User code is executed.
327+ //
328+ // On Windows, if the user code closes System.out and we open the AOT config file for output
329+ // only at VM exit, we might get back the same file HANDLE as stdout, and the AOT config
330+ // file may get corrupted by UL logs. By opening early, we ensure that the output
331+ // HANDLE is different than stdout so we can avoid such corruption.
332+ open_output_mapinfo ();
333+ } else {
334+ // No need for the above as we won't execute any user code.
335+ }
336+ }
337+
338+ void MetaspaceShared::open_output_mapinfo () {
339+ const char * static_archive = CDSConfig::output_archive_path ();
340+ assert (static_archive != nullptr , " sanity" );
341+ _output_mapinfo = new FileMapInfo (static_archive, true );
342+ _output_mapinfo->open_as_output ();
324343}
325344
326345// Called by universe_post_init()
@@ -551,14 +570,13 @@ class VM_PopulateDumpSharedSpace : public VM_Operation {
551570
552571public:
553572
554- VM_PopulateDumpSharedSpace (StaticArchiveBuilder& b) :
555- VM_Operation (), _heap_info(), _map_info(nullptr ), _builder(b) {}
573+ VM_PopulateDumpSharedSpace (StaticArchiveBuilder& b, FileMapInfo* map_info ) :
574+ VM_Operation (), _heap_info(), _map_info(map_info ), _builder(b) {}
556575
557576 bool skip_operation () const { return false ; }
558577
559578 VMOp_Type type () const { return VMOp_PopulateDumpSharedSpace; }
560579 ArchiveHeapInfo* heap_info () { return &_heap_info; }
561- FileMapInfo* map_info () const { return _map_info; }
562580 void doit (); // outline because gdb sucks
563581 bool allow_nested_vm_operations () const { return true ; }
564582}; // class VM_PopulateDumpSharedSpace
@@ -688,12 +706,6 @@ void VM_PopulateDumpSharedSpace::doit() {
688706 CppVtables::zero_archived_vtables ();
689707
690708 // Write the archive file
691- if (CDSConfig::is_dumping_final_static_archive ()) {
692- FileMapInfo::free_current_info (); // FIXME: should not free current info
693- }
694- const char * static_archive = CDSConfig::output_archive_path ();
695- assert (static_archive != nullptr , " sanity" );
696- _map_info = new FileMapInfo (static_archive, true );
697709 _map_info->populate_header (MetaspaceShared::core_region_alignment ());
698710 _map_info->set_early_serialized_data (early_serialized_data);
699711 _map_info->set_serialized_data (serialized_data);
@@ -1012,7 +1024,14 @@ void MetaspaceShared::preload_and_dump_impl(StaticArchiveBuilder& builder, TRAPS
10121024 }
10131025#endif
10141026
1015- VM_PopulateDumpSharedSpace op (builder);
1027+ if (!CDSConfig::is_dumping_preimage_static_archive ()) {
1028+ if (CDSConfig::is_dumping_final_static_archive ()) {
1029+ FileMapInfo::free_current_info (); // FIXME: should not free current info
1030+ }
1031+ open_output_mapinfo ();
1032+ }
1033+
1034+ VM_PopulateDumpSharedSpace op (builder, _output_mapinfo);
10161035 VMThread::execute (&op);
10171036
10181037 if (AOTCodeCache::is_on_for_dump () && CDSConfig::is_dumping_final_static_archive ()) {
@@ -1026,7 +1045,9 @@ void MetaspaceShared::preload_and_dump_impl(StaticArchiveBuilder& builder, TRAPS
10261045 CDSConfig::disable_dumping_aot_code ();
10271046 }
10281047
1029- bool status = write_static_archive (&builder, op.map_info (), op.heap_info ());
1048+ bool status = write_static_archive (&builder, _output_mapinfo, op.heap_info ());
1049+ assert (!_output_mapinfo->is_open (), " Must be closed already" );
1050+ _output_mapinfo = nullptr ;
10301051 if (status && CDSConfig::is_dumping_preimage_static_archive ()) {
10311052 tty->print_cr (" %s AOTConfiguration recorded: %s" ,
10321053 CDSConfig::has_temp_aot_config_file () ? " Temporary" : " " , AOTConfiguration);
@@ -1044,11 +1065,10 @@ bool MetaspaceShared::write_static_archive(ArchiveBuilder* builder, FileMapInfo*
10441065 // relocate the data so that it can be mapped to MetaspaceShared::requested_base_address()
10451066 // without runtime relocation.
10461067 builder->relocate_to_requested ();
1047-
1048- map_info->open_as_output ();
10491068 if (!map_info->is_open ()) {
10501069 return false ;
10511070 }
1071+ map_info->prepare_for_writing ();
10521072 builder->write_archive (map_info, heap_info);
10531073
10541074 if (AllowArchivingWithJavaAgent) {
0 commit comments