Refactor deps log loading, fix 2 bugs
There were two bugs in DepsLog::Load's main parsing pass:
* Previously, with an invalid log file, the main pass could initialize
dep_index[output_id] with the index of a record after the point where
the log is truncated, e.g.:
- Chunk 1: path record for node #0
- Chunk 1: invalid record
- Chunk 2: path record for node #1
- Chunk 2: deps record outputting node #0, needs node #1
The result of the parse could depend on chunk boundaries (e.g. how many
threads the machine has), and the parser could crash if the later deps
record has source IDs that were also truncated.
Fix the problem by moving dep_index initialization to a later pass. The
validation and truncation work is factored out into a ValidateDepsLog
function.
* Fix node ID validation of deps record inputs. The existing code to do
this had no effect:
if (output_id < 0 || output_id >= next_node_id) break;
for (size_t i = 4; i < size; ++i) {
int input_id = log.table[index + i];
if (input_id < 0 || input_id >= next_node_id) break;
The outer break exited the for-each-record loop early, signaling that
parsing had failed. The nested break exited the for-each-input loop,
which merely prevented validation of later node IDs. Replace the break
statements with "return false" in IsValidRecord.
These two changes regressed ".ninja_deps load" run-time by about 10ms
on a 580MB .ninja_deps file. (e.g. about 140ms -> 150ms). I suspect the
compiler may have been optimizing out the source ID checking.
Test: ninja_test
Change-Id: I13c3a314cfa7d2bf15c724962a9ec35f55176779
2 files changed