diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2011-06-10 17:03:27 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2011-06-10 17:03:27 -0400 |
commit | 0f452e8ef4eb7d6cde86ca8c5a2ab60044041a4c (patch) | |
tree | 3adc10cb62b6f1c6e8d91ab1a8a8cb2c25b99cbc | |
parent | e5b50d0ffb72935b844a2d78b6f81e3b6c85cba9 (diff) | |
download | postgresql-0f452e8ef4eb7d6cde86ca8c5a2ab60044041a4c.tar.gz postgresql-0f452e8ef4eb7d6cde86ca8c5a2ab60044041a4c.zip |
Work around gcc 4.6.0 bug that breaks WAL replay.
ReadRecord's habit of using both direct references to tmpRecPtr and
references to *RecPtr (which is pointing at tmpRecPtr) triggers an
optimization bug in gcc 4.6.0, which apparently has forgotten about
aliasing rules. Avoid the compiler bug, and make the code more readable
to boot, by getting rid of the direct references. Improve the comments
while at it.
Back-patch to all supported versions, in case they get built with 4.6.0.
Tom Lane, with some cosmetic suggestions from Alex Hunsaker
-rw-r--r-- | src/backend/access/transam/xlog.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 594437badc0..5be726ea8ae 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -2931,12 +2931,12 @@ ReadRecord(XLogRecPtr *RecPtr, int emode) goto got_record; } /* align old recptr to next page */ - if (tmpRecPtr.xrecoff % XLOG_BLCKSZ != 0) - tmpRecPtr.xrecoff += (XLOG_BLCKSZ - tmpRecPtr.xrecoff % XLOG_BLCKSZ); - if (tmpRecPtr.xrecoff >= XLogFileSize) + if (RecPtr->xrecoff % XLOG_BLCKSZ != 0) + RecPtr->xrecoff += (XLOG_BLCKSZ - RecPtr->xrecoff % XLOG_BLCKSZ); + if (RecPtr->xrecoff >= XLogFileSize) { - (tmpRecPtr.xlogid)++; - tmpRecPtr.xrecoff = 0; + (RecPtr->xlogid)++; + RecPtr->xrecoff = 0; } /* We will account for page header size below */ } @@ -3022,11 +3022,13 @@ ReadRecord(XLogRecPtr *RecPtr, int emode) if (targetRecOff == 0) { /* - * Can only get here in the continuing-from-prev-page case, because - * XRecOffIsValid eliminated the zero-page-offset case otherwise. Need - * to skip over the new page's header. + * At page start, so skip over page header. The Assert checks that + * we're not scribbling on caller's record pointer; it's OK because we + * can only get here in the continuing-from-prev-record case, since + * XRecOffIsValid rejected the zero-page-offset case otherwise. */ - tmpRecPtr.xrecoff += pageHeaderSize; + Assert(RecPtr == &tmpRecPtr); + RecPtr->xrecoff += pageHeaderSize; targetRecOff = pageHeaderSize; } else if (targetRecOff < pageHeaderSize) |