@@ -275,28 +275,51 @@ lnk_do_debug_info_discard(CV_DebugS *debug_s_arr, CV_SymbolListArray *parsed_sym
275275}
276276
277277internal
278- THREAD_POOL_TASK_FUNC (lnk_get_external_leaves_task )
278+ THREAD_POOL_TASK_FUNC (lnk_msf_parsed_from_data_task )
279279{
280280 ProfBeginFunction ();
281+ LNK_MsfParsedFromDataTask * task = raw_task ;
282+ // TODO: pick Info, TPI and IPI to flattten to make sure we don't waste compute on throw-away streams
283+ task -> msf_parse_arr [task_id ] = msf_parsed_from_data (arena , task -> data_arr .v [task_id ]);
284+ ProfEnd ();
285+ }
281286
282- LNK_GetExternalLeavesTask * task = raw_task ;
287+ internal MSF_Parsed * *
288+ lnk_msf_parsed_from_data_parallel (TP_Arena * arena , TP_Context * tp , String8Array data_arr )
289+ {
290+ ProfBeginFunction ();
291+ LNK_MsfParsedFromDataTask task = {0 };
292+ task .data_arr = data_arr ;
293+ task .msf_parse_arr = push_array_no_zero (arena -> v [0 ], MSF_Parsed * , data_arr .count );
294+ tp_for_parallel (tp , arena , data_arr .count , lnk_msf_parsed_from_data_task , & task );
295+ ProfEnd ();
296+ return task .msf_parse_arr ;
297+ }
283298
284- U64 ts_idx = task_id ;
299+ internal
300+ THREAD_POOL_TASK_FUNC (lnk_get_external_leaves_task )
301+ {
302+ ProfBeginFunction ();
303+
304+ U64 ts_idx = task_id ;
305+ LNK_GetExternalLeavesTask * task = raw_task ;
306+ MSF_Parsed * msf_parse = task -> msf_parse_arr [ts_idx ];
285307
286308 task -> external_ti_ranges [ts_idx ] = push_array_no_zero (arena , Rng1U64 , CV_TypeIndexSource_COUNT );
287309 task -> external_leaves [ts_idx ] = push_array_no_zero (arena , CV_DebugT , CV_TypeIndexSource_COUNT );
288310 task -> is_corrupted [ts_idx ] = 1 ;
289311
290- // TODO: pick TPI and IPI to flattten to make sure we don't waste compute on throw-away streams
291- MSF_Parsed * msf_parse = msf_parsed_from_data (arena , task -> msf_data_arr [ts_idx ]);
292-
293312 if (msf_parse ) {
313+ PDB_OpenTypeServerError tpi_error = PDB_OpenTypeServerError_UNKNOWN ;
314+ PDB_OpenTypeServerError ipi_error = PDB_OpenTypeServerError_UNKNOWN ;
315+
294316 PDB_TypeServerParse tpi_parse , ipi_parse ;
295- PDB_OpenTypeServerError tpi_error = pdb_type_server_parse_from_data (msf_parse -> streams [PDB_FixedStream_Tpi ], & tpi_parse );
296- PDB_OpenTypeServerError ipi_error = pdb_type_server_parse_from_data (msf_parse -> streams [PDB_FixedStream_Ipi ], & ipi_parse );
317+ if (PDB_FixedStream_Tpi < msf_parse -> stream_count && PDB_FixedStream_Ipi < msf_parse -> stream_count ) {
318+ tpi_error = pdb_type_server_parse_from_data (msf_parse -> streams [PDB_FixedStream_Tpi ], & tpi_parse );
319+ ipi_error = pdb_type_server_parse_from_data (msf_parse -> streams [PDB_FixedStream_Ipi ], & ipi_parse );
320+ }
297321
298- if (tpi_error == PDB_OpenTypeServerError_OK &&
299- ipi_error == PDB_OpenTypeServerError_OK ) {
322+ if (tpi_error == PDB_OpenTypeServerError_OK && ipi_error == PDB_OpenTypeServerError_OK ) {
300323 task -> is_corrupted [ts_idx ] = 0 ;
301324
302325 task -> external_ti_ranges [ts_idx ][CV_TypeIndexSource_NULL ] = rng_1u64 (0 ,0 );
@@ -308,15 +331,12 @@ THREAD_POOL_TASK_FUNC(lnk_get_external_leaves_task)
308331 task -> external_leaves [ts_idx ][CV_TypeIndexSource_IPI ] = cv_debug_t_from_data (arena , ipi_parse .leaf_data , PDB_LEAF_ALIGN );
309332 } else {
310333 if (tpi_error != PDB_OpenTypeServerError_OK ) {
311- lnk_error (LNK_Error_UnableToOpenTypeServer , "failed to open TPI in %S, reson %S" , task -> path_arr [ts_idx ], pdb_string_from_open_type_server_error (tpi_error ));
334+ lnk_error (LNK_Error_UnableToOpenTypeServer , "failed to open TPI in %S, reson %S" , task -> ts_info_arr [ts_idx ]. name , pdb_string_from_open_type_server_error (tpi_error ));
312335 }
313336 if (ipi_error != PDB_OpenTypeServerError_OK ) {
314- lnk_error (LNK_Error_UnableToOpenTypeServer , "failed to open IPI in %S, reason %S" , task -> path_arr [ts_idx ], pdb_string_from_open_type_server_error (ipi_error ));
337+ lnk_error (LNK_Error_UnableToOpenTypeServer , "failed to open IPI in %S, reason %S" , task -> ts_info_arr [ts_idx ]. name , pdb_string_from_open_type_server_error (ipi_error ));
315338 }
316339 }
317- } else {
318- MemoryZeroTyped (task -> external_ti_ranges [ts_idx ], CV_TypeIndexSource_COUNT );
319- MemoryZeroTyped (task -> external_leaves [ts_idx ], CV_TypeIndexSource_COUNT );
320340 }
321341
322342 ProfEnd ();
@@ -537,18 +557,20 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, String8List lib_dir
537557 CV_DebugT * merged_debug_t_p_arr = lnk_merge_debug_t_and_debug_p (tp_arena -> v [0 ], internal_count , internal_debug_t_arr , internal_debug_p_arr );
538558
539559 ProfBegin ("Analyze & Read External Type Server Files" );
540- String8Array type_server_path_arr ;
560+ String8Array ts_path_arr ;
541561 Rng1U64 * * external_ti_ranges ;
542562 CV_DebugT * * external_leaves ;
543563 U64 * obj_to_ts_idx_arr = push_array_no_zero (tp_arena -> v [0 ], U64 , external_count );
544564 U64List * ts_to_obj_arr = push_array (tp_arena -> v [0 ], U64List , external_count );
545565 {
546- HashTable * type_server_path_ht = hash_table_init (scratch .arena , 256 );
547- HashTable * ignored_path_ht = hash_table_init (scratch .arena , 256 );
548- String8List type_server_path_list ; MemoryZeroStruct ( & type_server_path_list ) ;
566+ HashTable * type_server_path_ht = hash_table_init (scratch .arena , 256 );
567+ HashTable * ignored_path_ht = hash_table_init (scratch .arena , 256 );
568+ CV_TypeServerInfoList ts_info_list = { 0 } ;
549569
550570 // push null
551- str8_list_pushf (scratch .arena , & type_server_path_list , "" );
571+ CV_TypeServerInfoNode * null_ts_info = push_array (scratch .arena , CV_TypeServerInfoNode , 1 );
572+ SLLQueuePush (ts_info_list .first , ts_info_list .last , null_ts_info );
573+ ++ ts_info_list .count ;
552574
553575 for (U64 obj_idx = 0 ; obj_idx < external_count ; ++ obj_idx ) {
554576 // first leaf always type server
@@ -620,9 +642,20 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, String8List lib_dir
620642 present -> obj -> path );
621643 }
622644 } else {
623- U64 ts_idx = type_server_path_list .node_count ;
645+ U64 ts_idx = ts_info_list .count ;
646+
647+ // when we search matches on disk we store path on scratch,
648+ // make path copy in case we need it for error reporting
624649 path = push_str8_copy (tp_arena -> v [0 ], path );
625- str8_list_push (scratch .arena , & type_server_path_list , path );
650+
651+ // fill out type server info we read from obj
652+ CV_TypeServerInfoNode * ts_info_node = push_array (scratch .arena , CV_TypeServerInfoNode , 1 );
653+ ts_info_node -> data = ts ;
654+ ts_info_node -> data .name = path ;
655+
656+ // push to type server info list
657+ SLLQueuePush (ts_info_list .first , ts_info_list .last , ts_info_node );
658+ ts_info_list .count += 1 ;
626659
627660 // wire obj to type server
628661 obj_to_ts_idx_arr [obj_idx ] = ts_idx ;
@@ -642,25 +675,69 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, String8List lib_dir
642675 }
643676 }
644677
645- // read type servers from disk in parallel
646- type_server_path_arr = str8_array_from_list (tp_arena -> v [0 ], & type_server_path_list );
678+ // type server info list -> array
679+ ts_path_arr .count = ts_info_list .count ;
680+ ts_path_arr .v = push_array (tp_arena -> v [0 ], String8 , ts_info_list .count );
681+ CV_TypeServerInfo * ts_info_arr = push_array (scratch .arena , CV_TypeServerInfo , ts_info_list .count );
682+ {
683+ U64 idx = 0 ;
684+ for (CV_TypeServerInfoNode * n = ts_info_list .first ; n != 0 ; n = n -> next , ++ idx ) {
685+ ts_path_arr .v [idx ] = n -> data .name ;
686+ ts_info_arr [idx ] = n -> data ;
687+ }
688+ }
647689
690+ // read type servers from disk in parallel
648691 {
649692 ProfBegin ("Read External Type Servers" );
650- String8Array msf_data_arr = os_data_from_file_path_parallel (tp , scratch .arena , type_server_path_arr );
693+ String8Array msf_data_arr = os_data_from_file_path_parallel (tp , scratch .arena , ts_path_arr );
694+ ProfEnd ();
695+
696+ MSF_Parsed * * msf_parse_arr = lnk_msf_parsed_from_data_parallel (tp_arena , tp , msf_data_arr );
697+
698+ ProfBegin ("Error check type servers" );
699+ for (U64 ts_idx = 0 ; ts_idx < msf_data_arr .count ; ++ ts_idx ) {
700+ MSF_Parsed * msf_parse = msf_parse_arr [ts_idx ];
701+
702+ B32 do_debug_info_discard = 0 ;
703+
704+ if (!msf_parse ) {
705+ do_debug_info_discard = 1 ;
706+ } else {
707+ PDB_InfoParse info_parse = {0 };
708+ pdb_info_parse_from_data (msf_parse -> streams [PDB_FixedStream_Info ], & info_parse );
709+ if (!MemoryMatchStruct (& info_parse .guid , & ts_info_arr [ts_idx ].sig )) {
710+ Temp scratch = scratch_begin (0 ,0 );
711+ String8 expected_sig_str = os_string_from_guid (scratch .arena , ts_info_arr [ts_idx ].sig );
712+ String8 on_disk_sig_str = os_string_from_guid (scratch .arena , info_parse .guid );
713+ lnk_error (LNK_Warning_MismatchedTypeServerSignature , "%S: signature mismatch in type server read from disk, expected %S, got %S" ,
714+ ts_info_arr [ts_idx ].name , expected_sig_str , on_disk_sig_str );
715+ scratch_end (scratch );
716+
717+ do_debug_info_discard = 1 ;
718+ }
719+ }
720+
721+ if (do_debug_info_discard ) {
722+ U64List obj_idx_list = ts_to_obj_arr [ts_idx ];
723+ for (U64Node * obj_idx_n = obj_idx_list .first ; obj_idx_n != 0 ; obj_idx_n = obj_idx_n -> next ) {
724+ lnk_do_debug_info_discard (external_debug_s_arr , external_parsed_symbols , obj_idx_n -> data );
725+ }
726+ }
727+ }
651728 ProfEnd ();
652729
653- ProfBeginDynamic ("Open External Type Servers [Count %llu]" , type_server_path_arr .count );
654- LNK_GetExternalLeavesTask task ;
655- task .path_arr = type_server_path_arr . v ;
656- task .msf_data_arr = msf_data_arr . v ;
657- task .external_ti_ranges = push_array_no_zero (tp_arena -> v [0 ], Rng1U64 * , msf_data_arr .count );
658- task .external_leaves = push_array_no_zero (tp_arena -> v [0 ], CV_DebugT * , msf_data_arr .count );
659- task .is_corrupted = push_array_no_zero (scratch .arena , B8 , msf_data_arr .count );
730+ ProfBeginDynamic ("Open External Type Servers [Count %llu]" , ts_path_arr .count );
731+ LNK_GetExternalLeavesTask task = { 0 } ;
732+ task .ts_info_arr = ts_info_arr ;
733+ task .msf_parse_arr = msf_parse_arr ;
734+ task .external_ti_ranges = push_array_no_zero (tp_arena -> v [0 ], Rng1U64 * , msf_data_arr .count );
735+ task .external_leaves = push_array_no_zero (tp_arena -> v [0 ], CV_DebugT * , msf_data_arr .count );
736+ task .is_corrupted = push_array_no_zero (scratch .arena , B8 , msf_data_arr .count );
660737 tp_for_parallel (tp , tp_arena , msf_data_arr .count , lnk_get_external_leaves_task , & task );
661738 ProfEnd ();
662739
663- String8List unopen_type_server_list ; MemoryZeroStruct ( & unopen_type_server_list ) ;
740+ String8List unopen_type_server_list = { 0 } ;
664741
665742 // discard debug info that depends on the missing type server
666743 for (U64 ts_idx = 1 ; ts_idx < msf_data_arr .count ; ++ ts_idx ) {
@@ -676,7 +753,7 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, String8List lib_dir
676753 for (U64 ts_idx = 1 ; ts_idx < msf_data_arr .count ; ++ ts_idx ) {
677754 if (task .is_corrupted [ts_idx ]) {
678755 U64List obj_idx_list = ts_to_obj_arr [ts_idx ];
679- str8_list_pushf (scratch .arena , & unopen_type_server_list , "\t%S\n" , type_server_path_arr .v [ts_idx ]);
756+ str8_list_pushf (scratch .arena , & unopen_type_server_list , "\t%S\n" , ts_path_arr .v [ts_idx ]);
680757 str8_list_pushf (scratch .arena , & unopen_type_server_list , "\t\tDependent obj(s):\n" );
681758 for (U64Node * obj_idx_node = obj_idx_list .first ; obj_idx_node != 0 ; obj_idx_node = obj_idx_node -> next ) {
682759 String8 obj_path = external_obj_arr [obj_idx_node -> data ].path ;
@@ -704,8 +781,8 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, String8List lib_dir
704781 cv .count = obj_count ;
705782 cv .internal_count = internal_count ;
706783 cv .external_count = external_count ;
707- cv .type_server_count = type_server_path_arr .count ;
708- cv .type_server_path_arr = type_server_path_arr .v ;
784+ cv .type_server_count = ts_path_arr .count ;
785+ cv .type_server_path_arr = ts_path_arr .v ;
709786 cv .ts_to_obj_arr = ts_to_obj_arr ;
710787 cv .obj_arr = sorted_obj_arr ;
711788 cv .pch_arr = pch_arr ;
0 commit comments