diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index d24ea6b2a106923634afa8d6f023cd1cdcfa7b4a..114800984469a49d89d41190324446e8444fcbf8 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *		$PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.46 2008/10/20 19:18:18 alvherre Exp $
+ *		$PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.47 2008/11/02 21:24:51 tgl Exp $
  *
  * NOTES
  *		Each global transaction is associated with a global transaction
@@ -122,7 +122,7 @@ typedef struct GlobalTransactionData
 typedef struct TwoPhaseStateData
 {
 	/* Head of linked list of free GlobalTransactionData structs */
-	SHMEM_OFFSET freeGXacts;
+	GlobalTransaction freeGXacts;
 
 	/* Number of valid prepXacts entries. */
 	int			numPrepXacts;
@@ -184,7 +184,7 @@ TwoPhaseShmemInit(void)
 		int			i;
 
 		Assert(!found);
-		TwoPhaseState->freeGXacts = INVALID_OFFSET;
+		TwoPhaseState->freeGXacts = NULL;
 		TwoPhaseState->numPrepXacts = 0;
 
 		/*
@@ -196,8 +196,8 @@ TwoPhaseShmemInit(void)
 					  sizeof(GlobalTransaction) * max_prepared_xacts));
 		for (i = 0; i < max_prepared_xacts; i++)
 		{
-			gxacts[i].proc.links.next = TwoPhaseState->freeGXacts;
-			TwoPhaseState->freeGXacts = MAKE_OFFSET(&gxacts[i]);
+			gxacts[i].proc.links.next = (SHM_QUEUE *) TwoPhaseState->freeGXacts;
+			TwoPhaseState->freeGXacts = &gxacts[i];
 		}
 	}
 	else
@@ -242,8 +242,8 @@ MarkAsPreparing(TransactionId xid, const char *gid,
 			TwoPhaseState->numPrepXacts--;
 			TwoPhaseState->prepXacts[i] = TwoPhaseState->prepXacts[TwoPhaseState->numPrepXacts];
 			/* and put it back in the freelist */
-			gxact->proc.links.next = TwoPhaseState->freeGXacts;
-			TwoPhaseState->freeGXacts = MAKE_OFFSET(gxact);
+			gxact->proc.links.next = (SHM_QUEUE *) TwoPhaseState->freeGXacts;
+			TwoPhaseState->freeGXacts = gxact;
 			/* Back up index count too, so we don't miss scanning one */
 			i--;
 		}
@@ -263,14 +263,14 @@ MarkAsPreparing(TransactionId xid, const char *gid,
 	}
 
 	/* Get a free gxact from the freelist */
-	if (TwoPhaseState->freeGXacts == INVALID_OFFSET)
+	if (TwoPhaseState->freeGXacts == NULL)
 		ereport(ERROR,
 				(errcode(ERRCODE_OUT_OF_MEMORY),
 				 errmsg("maximum number of prepared transactions reached"),
 				 errhint("Increase max_prepared_transactions (currently %d).",
 						 max_prepared_xacts)));
-	gxact = (GlobalTransaction) MAKE_PTR(TwoPhaseState->freeGXacts);
-	TwoPhaseState->freeGXacts = gxact->proc.links.next;
+	gxact = TwoPhaseState->freeGXacts;
+	TwoPhaseState->freeGXacts = (GlobalTransaction) gxact->proc.links.next;
 
 	/* Initialize it */
 	MemSet(&gxact->proc, 0, sizeof(PGPROC));
@@ -451,8 +451,8 @@ RemoveGXact(GlobalTransaction gxact)
 			TwoPhaseState->prepXacts[i] = TwoPhaseState->prepXacts[TwoPhaseState->numPrepXacts];
 
 			/* and put it back in the freelist */
-			gxact->proc.links.next = TwoPhaseState->freeGXacts;
-			TwoPhaseState->freeGXacts = MAKE_OFFSET(gxact);
+			gxact->proc.links.next = (SHM_QUEUE *) TwoPhaseState->freeGXacts;
+			TwoPhaseState->freeGXacts = gxact;
 
 			LWLockRelease(TwoPhaseStateLock);
 
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 9f218d6bdc0c5614b1c52bbdda6f661d79789a72..6f056e0e16904a9a004c525960f2d32a21a92e6d 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -55,7 +55,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.84 2008/08/13 00:07:50 alvherre Exp $
+ *	  $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.85 2008/11/02 21:24:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -244,9 +244,9 @@ typedef struct
 {
 	sig_atomic_t av_signal[AutoVacNumSignals];
 	pid_t		av_launcherpid;
-	SHMEM_OFFSET av_freeWorkers;
+	WorkerInfo	av_freeWorkers;
 	SHM_QUEUE	av_runningWorkers;
-	SHMEM_OFFSET av_startingWorker;
+	WorkerInfo	av_startingWorker;
 } AutoVacuumShmemStruct;
 
 static AutoVacuumShmemStruct *AutoVacuumShmem;
@@ -556,8 +556,8 @@ AutoVacLauncherMain(int argc, char *argv[])
 		if (!PostmasterIsAlive(true))
 			exit(1);
 
-		launcher_determine_sleep(AutoVacuumShmem->av_freeWorkers !=
-								 INVALID_OFFSET, false, &nap);
+		launcher_determine_sleep((AutoVacuumShmem->av_freeWorkers != NULL),
+								 false, &nap);
 
 		/*
 		 * Sleep for a while according to schedule.
@@ -662,13 +662,12 @@ AutoVacLauncherMain(int argc, char *argv[])
 		current_time = GetCurrentTimestamp();
 		LWLockAcquire(AutovacuumLock, LW_SHARED);
 
-		can_launch = (AutoVacuumShmem->av_freeWorkers != INVALID_OFFSET);
+		can_launch = (AutoVacuumShmem->av_freeWorkers != NULL);
 
-		if (AutoVacuumShmem->av_startingWorker != INVALID_OFFSET)
+		if (AutoVacuumShmem->av_startingWorker != NULL)
 		{
 			int			waittime;
-
-			WorkerInfo	worker = (WorkerInfo) MAKE_PTR(AutoVacuumShmem->av_startingWorker);
+			WorkerInfo	worker = AutoVacuumShmem->av_startingWorker;
 
 			/*
 			 * We can't launch another worker when another one is still
@@ -698,16 +697,16 @@ AutoVacLauncherMain(int argc, char *argv[])
 				 * we assume it's the same one we saw above (so we don't
 				 * recheck the launch time).
 				 */
-				if (AutoVacuumShmem->av_startingWorker != INVALID_OFFSET)
+				if (AutoVacuumShmem->av_startingWorker != NULL)
 				{
-					worker = (WorkerInfo) MAKE_PTR(AutoVacuumShmem->av_startingWorker);
+					worker = AutoVacuumShmem->av_startingWorker;
 					worker->wi_dboid = InvalidOid;
 					worker->wi_tableoid = InvalidOid;
 					worker->wi_proc = NULL;
 					worker->wi_launchtime = 0;
-					worker->wi_links.next = AutoVacuumShmem->av_freeWorkers;
-					AutoVacuumShmem->av_freeWorkers = MAKE_OFFSET(worker);
-					AutoVacuumShmem->av_startingWorker = INVALID_OFFSET;
+					worker->wi_links.next = (SHM_QUEUE *) AutoVacuumShmem->av_freeWorkers;
+					AutoVacuumShmem->av_freeWorkers = worker;
+					AutoVacuumShmem->av_startingWorker = NULL;
 					elog(WARNING, "worker took too long to start; cancelled");
 				}
 			}
@@ -1061,7 +1060,7 @@ do_start_worker(void)
 
 	/* return quickly when there are no free workers */
 	LWLockAcquire(AutovacuumLock, LW_SHARED);
-	if (AutoVacuumShmem->av_freeWorkers == INVALID_OFFSET)
+	if (AutoVacuumShmem->av_freeWorkers == NULL)
 	{
 		LWLockRelease(AutovacuumLock);
 		return InvalidOid;
@@ -1192,7 +1191,6 @@ do_start_worker(void)
 	if (avdb != NULL)
 	{
 		WorkerInfo	worker;
-		SHMEM_OFFSET sworker;
 
 		LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
 
@@ -1201,18 +1199,17 @@ do_start_worker(void)
 		 * really should be a free slot -- complain very loudly if there
 		 * isn't.
 		 */
-		sworker = AutoVacuumShmem->av_freeWorkers;
-		if (sworker == INVALID_OFFSET)
+		worker = AutoVacuumShmem->av_freeWorkers;
+		if (worker == NULL)
 			elog(FATAL, "no free worker found");
 
-		worker = (WorkerInfo) MAKE_PTR(sworker);
-		AutoVacuumShmem->av_freeWorkers = worker->wi_links.next;
+		AutoVacuumShmem->av_freeWorkers = (WorkerInfo) worker->wi_links.next;
 
 		worker->wi_dboid = avdb->adw_datid;
 		worker->wi_proc = NULL;
 		worker->wi_launchtime = GetCurrentTimestamp();
 
-		AutoVacuumShmem->av_startingWorker = sworker;
+		AutoVacuumShmem->av_startingWorker = worker;
 
 		LWLockRelease(AutovacuumLock);
 
@@ -1549,9 +1546,9 @@ AutoVacWorkerMain(int argc, char *argv[])
 	 * launcher might have decided to remove it from the queue and start
 	 * again.
 	 */
-	if (AutoVacuumShmem->av_startingWorker != INVALID_OFFSET)
+	if (AutoVacuumShmem->av_startingWorker != NULL)
 	{
-		MyWorkerInfo = (WorkerInfo) MAKE_PTR(AutoVacuumShmem->av_startingWorker);
+		MyWorkerInfo = AutoVacuumShmem->av_startingWorker;
 		dbid = MyWorkerInfo->wi_dboid;
 		MyWorkerInfo->wi_proc = MyProc;
 
@@ -1563,7 +1560,7 @@ AutoVacWorkerMain(int argc, char *argv[])
 		 * remove from the "starting" pointer, so that the launcher can start
 		 * a new worker if required
 		 */
-		AutoVacuumShmem->av_startingWorker = INVALID_OFFSET;
+		AutoVacuumShmem->av_startingWorker = NULL;
 		LWLockRelease(AutovacuumLock);
 
 		on_shmem_exit(FreeWorkerInfo, 0);
@@ -1648,7 +1645,7 @@ FreeWorkerInfo(int code, Datum arg)
 		AutovacuumLauncherPid = AutoVacuumShmem->av_launcherpid;
 
 		SHMQueueDelete(&MyWorkerInfo->wi_links);
-		MyWorkerInfo->wi_links.next = AutoVacuumShmem->av_freeWorkers;
+		MyWorkerInfo->wi_links.next = (SHM_QUEUE *) AutoVacuumShmem->av_freeWorkers;
 		MyWorkerInfo->wi_dboid = InvalidOid;
 		MyWorkerInfo->wi_tableoid = InvalidOid;
 		MyWorkerInfo->wi_proc = NULL;
@@ -1656,7 +1653,7 @@ FreeWorkerInfo(int code, Datum arg)
 		MyWorkerInfo->wi_cost_delay = 0;
 		MyWorkerInfo->wi_cost_limit = 0;
 		MyWorkerInfo->wi_cost_limit_base = 0;
-		AutoVacuumShmem->av_freeWorkers = MAKE_OFFSET(MyWorkerInfo);
+		AutoVacuumShmem->av_freeWorkers = MyWorkerInfo;
 		/* not mine anymore */
 		MyWorkerInfo = NULL;
 
@@ -2793,9 +2790,9 @@ AutoVacuumShmemInit(void)
 		Assert(!found);
 
 		AutoVacuumShmem->av_launcherpid = 0;
-		AutoVacuumShmem->av_freeWorkers = INVALID_OFFSET;
+		AutoVacuumShmem->av_freeWorkers = NULL;
 		SHMQueueInit(&AutoVacuumShmem->av_runningWorkers);
-		AutoVacuumShmem->av_startingWorker = INVALID_OFFSET;
+		AutoVacuumShmem->av_startingWorker = NULL;
 
 		worker = (WorkerInfo) ((char *) AutoVacuumShmem +
 							   MAXALIGN(sizeof(AutoVacuumShmemStruct)));
@@ -2803,8 +2800,8 @@ AutoVacuumShmemInit(void)
 		/* initialize the WorkerInfo free list */
 		for (i = 0; i < autovacuum_max_workers; i++)
 		{
-			worker[i].wi_links.next = AutoVacuumShmem->av_freeWorkers;
-			AutoVacuumShmem->av_freeWorkers = MAKE_OFFSET(&worker[i]);
+			worker[i].wi_links.next = (SHM_QUEUE *) AutoVacuumShmem->av_freeWorkers;
+			AutoVacuumShmem->av_freeWorkers = &worker[i];
 		}
 	}
 	else
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index 831a4add7df508a1896e519f88e0eb404527ce5b..67e8d378c8f05204cb151ac5bcf896d3dfcac826 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.100 2008/01/01 19:45:51 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.101 2008/11/02 21:24:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -77,9 +77,9 @@
 
 static PGShmemHeader *ShmemSegHdr;		/* shared mem segment header */
 
-SHMEM_OFFSET ShmemBase;			/* start address of shared memory */
+static void *ShmemBase;			/* start address of shared memory */
 
-static SHMEM_OFFSET ShmemEnd;	/* end+1 address of shared memory */
+static void *ShmemEnd;			/* end+1 address of shared memory */
 
 slock_t    *ShmemLock;			/* spinlock for shared memory and LWLock
 								 * allocation */
@@ -99,8 +99,8 @@ InitShmemAccess(void *seghdr)
 	PGShmemHeader *shmhdr = (PGShmemHeader *) seghdr;
 
 	ShmemSegHdr = shmhdr;
-	ShmemBase = (SHMEM_OFFSET) shmhdr;
-	ShmemEnd = ShmemBase + shmhdr->totalsize;
+	ShmemBase = (void *) shmhdr;
+	ShmemEnd = (char *) ShmemBase + shmhdr->totalsize;
 }
 
 /*
@@ -127,7 +127,7 @@ InitShmemAllocation(void)
 	SpinLockInit(ShmemLock);
 
 	/* ShmemIndex can't be set up yet (need LWLocks first) */
-	shmhdr->indexoffset = 0;
+	shmhdr->index = NULL;
 	ShmemIndex = (HTAB *) NULL;
 
 	/*
@@ -176,7 +176,7 @@ ShmemAlloc(Size size)
 	newFree = newStart + size;
 	if (newFree <= shmemseghdr->totalsize)
 	{
-		newSpace = (void *) MAKE_PTR(newStart);
+		newSpace = (void *) ((char *) ShmemBase + newStart);
 		shmemseghdr->freeoffset = newFree;
 	}
 	else
@@ -193,14 +193,14 @@ ShmemAlloc(Size size)
 }
 
 /*
- * ShmemIsValid -- test if an offset refers to valid shared memory
+ * ShmemAddrIsValid -- test if an address refers to shared memory
  *
- * Returns TRUE if the pointer is valid.
+ * Returns TRUE if the pointer points within the shared memory segment.
  */
 bool
-ShmemIsValid(unsigned long addr)
+ShmemAddrIsValid(void *addr)
 {
-	return (addr < ShmemEnd) && (addr >= ShmemBase);
+	return (addr >= ShmemBase) && (addr < ShmemEnd);
 }
 
 /*
@@ -324,8 +324,8 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
 		if (IsUnderPostmaster)
 		{
 			/* Must be initializing a (non-standalone) backend */
-			Assert(shmemseghdr->indexoffset != 0);
-			structPtr = (void *) MAKE_PTR(shmemseghdr->indexoffset);
+			Assert(shmemseghdr->index != NULL);
+			structPtr = shmemseghdr->index;
 			*foundPtr = TRUE;
 		}
 		else
@@ -338,9 +338,9 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
 			 * index has been initialized.	This should be OK because no other
 			 * process can be accessing shared memory yet.
 			 */
-			Assert(shmemseghdr->indexoffset == 0);
+			Assert(shmemseghdr->index == NULL);
 			structPtr = ShmemAlloc(size);
-			shmemseghdr->indexoffset = MAKE_OFFSET(structPtr);
+			shmemseghdr->index = structPtr;
 			*foundPtr = FALSE;
 		}
 		LWLockRelease(ShmemIndexLock);
@@ -374,7 +374,7 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
 			/* let caller print its message too */
 			return NULL;
 		}
-		structPtr = (void *) MAKE_PTR(result->location);
+		structPtr = result->location;
 	}
 	else
 	{
@@ -395,9 +395,9 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
 			return NULL;
 		}
 		result->size = size;
-		result->location = MAKE_OFFSET(structPtr);
+		result->location = structPtr;
 	}
-	Assert(ShmemIsValid((unsigned long) structPtr));
+	Assert(ShmemAddrIsValid(structPtr));
 
 	LWLockRelease(ShmemIndexLock);
 	return structPtr;
diff --git a/src/backend/storage/ipc/shmqueue.c b/src/backend/storage/ipc/shmqueue.c
index 3e3b3a73b6b8d508d2b84f670f032eae05963ffe..24542e7b63a7b9477feaf8b8579f0ed149ab7cc4 100644
--- a/src/backend/storage/ipc/shmqueue.c
+++ b/src/backend/storage/ipc/shmqueue.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/ipc/shmqueue.c,v 1.31 2008/01/01 19:45:51 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/ipc/shmqueue.c,v 1.32 2008/11/02 21:24:52 tgl Exp $
  *
  * NOTES
  *
@@ -27,12 +27,6 @@
 
 #include "storage/shmem.h"
 
-/*#define SHMQUEUE_DEBUG*/
-
-#ifdef SHMQUEUE_DEBUG
-static void dumpQ(SHM_QUEUE *q, char *s);
-#endif
-
 
 /*
  * ShmemQueueInit -- make the head of a new queue point
@@ -41,8 +35,8 @@ static void dumpQ(SHM_QUEUE *q, char *s);
 void
 SHMQueueInit(SHM_QUEUE *queue)
 {
-	Assert(SHM_PTR_VALID(queue));
-	(queue)->prev = (queue)->next = MAKE_OFFSET(queue);
+	Assert(ShmemAddrIsValid(queue));
+	queue->prev = queue->next = queue;
 }
 
 /*
@@ -53,8 +47,8 @@ SHMQueueInit(SHM_QUEUE *queue)
 bool
 SHMQueueIsDetached(SHM_QUEUE *queue)
 {
-	Assert(SHM_PTR_VALID(queue));
-	return (queue)->prev == INVALID_OFFSET;
+	Assert(ShmemAddrIsValid(queue));
+	return (queue->prev == NULL);
 }
 #endif
 
@@ -64,8 +58,8 @@ SHMQueueIsDetached(SHM_QUEUE *queue)
 void
 SHMQueueElemInit(SHM_QUEUE *queue)
 {
-	Assert(SHM_PTR_VALID(queue));
-	(queue)->prev = (queue)->next = INVALID_OFFSET;
+	Assert(ShmemAddrIsValid(queue));
+	queue->prev = queue->next = NULL;
 }
 
 /*
@@ -75,21 +69,17 @@ SHMQueueElemInit(SHM_QUEUE *queue)
 void
 SHMQueueDelete(SHM_QUEUE *queue)
 {
-	SHM_QUEUE  *nextElem = (SHM_QUEUE *) MAKE_PTR((queue)->next);
-	SHM_QUEUE  *prevElem = (SHM_QUEUE *) MAKE_PTR((queue)->prev);
+	SHM_QUEUE  *nextElem = queue->next;
+	SHM_QUEUE  *prevElem = queue->prev;
 
-	Assert(SHM_PTR_VALID(queue));
-	Assert(SHM_PTR_VALID(nextElem));
-	Assert(SHM_PTR_VALID(prevElem));
+	Assert(ShmemAddrIsValid(queue));
+	Assert(ShmemAddrIsValid(nextElem));
+	Assert(ShmemAddrIsValid(prevElem));
 
-#ifdef SHMQUEUE_DEBUG
-	dumpQ(queue, "in SHMQueueDelete: begin");
-#endif
-
-	prevElem->next = (queue)->next;
-	nextElem->prev = (queue)->prev;
+	prevElem->next = queue->next;
+	nextElem->prev = queue->prev;
 
-	(queue)->prev = (queue)->next = INVALID_OFFSET;
+	queue->prev = queue->next = NULL;
 }
 
 /*
@@ -100,24 +90,15 @@ SHMQueueDelete(SHM_QUEUE *queue)
 void
 SHMQueueInsertBefore(SHM_QUEUE *queue, SHM_QUEUE *elem)
 {
-	SHM_QUEUE  *prevPtr = (SHM_QUEUE *) MAKE_PTR((queue)->prev);
-	SHMEM_OFFSET elemOffset = MAKE_OFFSET(elem);
-
-	Assert(SHM_PTR_VALID(queue));
-	Assert(SHM_PTR_VALID(elem));
+	SHM_QUEUE  *prevPtr = queue->prev;
 
-#ifdef SHMQUEUE_DEBUG
-	dumpQ(queue, "in SHMQueueInsertBefore: begin");
-#endif
-
-	(elem)->next = prevPtr->next;
-	(elem)->prev = queue->prev;
-	(queue)->prev = elemOffset;
-	prevPtr->next = elemOffset;
+	Assert(ShmemAddrIsValid(queue));
+	Assert(ShmemAddrIsValid(elem));
 
-#ifdef SHMQUEUE_DEBUG
-	dumpQ(queue, "in SHMQueueInsertBefore: end");
-#endif
+	elem->next = prevPtr->next;
+	elem->prev = queue->prev;
+	queue->prev = elem;
+	prevPtr->next = elem;
 }
 
 /*
@@ -129,24 +110,15 @@ SHMQueueInsertBefore(SHM_QUEUE *queue, SHM_QUEUE *elem)
 void
 SHMQueueInsertAfter(SHM_QUEUE *queue, SHM_QUEUE *elem)
 {
-	SHM_QUEUE  *nextPtr = (SHM_QUEUE *) MAKE_PTR((queue)->next);
-	SHMEM_OFFSET elemOffset = MAKE_OFFSET(elem);
-
-	Assert(SHM_PTR_VALID(queue));
-	Assert(SHM_PTR_VALID(elem));
-
-#ifdef SHMQUEUE_DEBUG
-	dumpQ(queue, "in SHMQueueInsertAfter: begin");
-#endif
+	SHM_QUEUE  *nextPtr = queue->next;
 
-	(elem)->prev = nextPtr->prev;
-	(elem)->next = queue->next;
-	(queue)->next = elemOffset;
-	nextPtr->prev = elemOffset;
+	Assert(ShmemAddrIsValid(queue));
+	Assert(ShmemAddrIsValid(elem));
 
-#ifdef SHMQUEUE_DEBUG
-	dumpQ(queue, "in SHMQueueInsertAfter: end");
-#endif
+	elem->prev = nextPtr->prev;
+	elem->next = queue->next;
+	queue->next = elem;
+	nextPtr->prev = elem;
 }
 #endif   /* NOT_USED */
 
@@ -159,15 +131,15 @@ SHMQueueInsertAfter(SHM_QUEUE *queue, SHM_QUEUE *elem)
  * Next element is at curElem->next.  If SHMQueue is part of
  * a larger structure, we want to return a pointer to the
  * whole structure rather than a pointer to its SHMQueue field.
- * I.E. struct {
+ * For example,
+ * struct {
  *		int				stuff;
  *		SHMQueue		elem;
  * } ELEMType;
- * When this element is in a queue, (prevElem->next) is struct.elem.
+ * When this element is in a queue, prevElem->next points at struct.elem.
  * We subtract linkOffset to get the correct start address of the structure.
  *
  * calls to SHMQueueNext should take these parameters:
- *
  *	 &(queueHead), &(queueHead), offsetof(ELEMType, elem)
  * or
  *	 &(queueHead), &(curElem->elem), offsetof(ELEMType, elem)
@@ -176,9 +148,9 @@ SHMQueueInsertAfter(SHM_QUEUE *queue, SHM_QUEUE *elem)
 Pointer
 SHMQueueNext(SHM_QUEUE *queue, SHM_QUEUE *curElem, Size linkOffset)
 {
-	SHM_QUEUE  *elemPtr = (SHM_QUEUE *) MAKE_PTR((curElem)->next);
+	SHM_QUEUE  *elemPtr = curElem->next;
 
-	Assert(SHM_PTR_VALID(curElem));
+	Assert(ShmemAddrIsValid(curElem));
 
 	if (elemPtr == queue)		/* back to the queue head? */
 		return NULL;
@@ -192,64 +164,12 @@ SHMQueueNext(SHM_QUEUE *queue, SHM_QUEUE *curElem, Size linkOffset)
 bool
 SHMQueueEmpty(SHM_QUEUE *queue)
 {
-	Assert(SHM_PTR_VALID(queue));
+	Assert(ShmemAddrIsValid(queue));
 
-	if (queue->prev == MAKE_OFFSET(queue))
+	if (queue->prev == queue)
 	{
-		Assert(queue->next = MAKE_OFFSET(queue));
+		Assert(queue->next == queue);
 		return TRUE;
 	}
 	return FALSE;
 }
-
-#ifdef SHMQUEUE_DEBUG
-
-static void
-dumpQ(SHM_QUEUE *q, char *s)
-{
-	char		elem[NAMEDATALEN];
-	char		buf[1024];
-	SHM_QUEUE  *start = q;
-	int			count = 0;
-
-	snprintf(buf, sizeof(buf), "q prevs: %lx", MAKE_OFFSET(q));
-	q = (SHM_QUEUE *) MAKE_PTR(q->prev);
-	while (q != start)
-	{
-		snprintf(elem, sizeof(elem), "--->%lx", MAKE_OFFSET(q));
-		strcat(buf, elem);
-		q = (SHM_QUEUE *) MAKE_PTR(q->prev);
-		if (q->prev == MAKE_OFFSET(q))
-			break;
-		if (count++ > 40)
-		{
-			strcat(buf, "BAD PREV QUEUE!!");
-			break;
-		}
-	}
-	snprintf(elem, sizeof(elem), "--->%lx", MAKE_OFFSET(q));
-	strcat(buf, elem);
-	elog(DEBUG2, "%s: %s", s, buf);
-
-	snprintf(buf, sizeof(buf), "q nexts: %lx", MAKE_OFFSET(q));
-	count = 0;
-	q = (SHM_QUEUE *) MAKE_PTR(q->next);
-	while (q != start)
-	{
-		snprintf(elem, sizeof(elem), "--->%lx", MAKE_OFFSET(q));
-		strcat(buf, elem);
-		q = (SHM_QUEUE *) MAKE_PTR(q->next);
-		if (q->next == MAKE_OFFSET(q))
-			break;
-		if (count++ > 10)
-		{
-			strcat(buf, "BAD NEXT QUEUE!!");
-			break;
-		}
-	}
-	snprintf(elem, sizeof(elem), "--->%lx", MAKE_OFFSET(q));
-	strcat(buf, elem);
-	elog(DEBUG2, "%s: %s", s, buf);
-}
-
-#endif   /* SHMQUEUE_DEBUG */
diff --git a/src/backend/storage/lmgr/deadlock.c b/src/backend/storage/lmgr/deadlock.c
index 8a564a1754c97f1dc6f61beee7bf5995fd89621a..713d1065b1cbb16d39c06b1fefbf23fe69db5d7a 100644
--- a/src/backend/storage/lmgr/deadlock.c
+++ b/src/backend/storage/lmgr/deadlock.c
@@ -12,7 +12,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/lmgr/deadlock.c,v 1.54 2008/08/01 13:16:09 alvherre Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/lmgr/deadlock.c,v 1.55 2008/11/02 21:24:52 tgl Exp $
  *
  *	Interface:
  *
@@ -495,7 +495,7 @@ FindLockCycleRecurse(PGPROC *checkProc,
 	/*
 	 * If the proc is not waiting, we have no outgoing waits-for edges.
 	 */
-	if (checkProc->links.next == INVALID_OFFSET)
+	if (checkProc->links.next == NULL)
 		return false;
 	lock = checkProc->waitLock;
 	if (lock == NULL)
@@ -629,7 +629,7 @@ FindLockCycleRecurse(PGPROC *checkProc,
 		waitQueue = &(lock->waitProcs);
 		queue_size = waitQueue->size;
 
-		proc = (PGPROC *) MAKE_PTR(waitQueue->links.next);
+		proc = (PGPROC *) waitQueue->links.next;
 
 		while (queue_size-- > 0)
 		{
@@ -662,7 +662,7 @@ FindLockCycleRecurse(PGPROC *checkProc,
 				}
 			}
 
-			proc = (PGPROC *) MAKE_PTR(proc->links.next);
+			proc = (PGPROC *) proc->links.next;
 		}
 	}
 
@@ -772,11 +772,11 @@ TopoSort(LOCK *lock,
 				last;
 
 	/* First, fill topoProcs[] array with the procs in their current order */
-	proc = (PGPROC *) MAKE_PTR(waitQueue->links.next);
+	proc = (PGPROC *) waitQueue->links.next;
 	for (i = 0; i < queue_size; i++)
 	{
 		topoProcs[i] = proc;
-		proc = (PGPROC *) MAKE_PTR(proc->links.next);
+		proc = (PGPROC *) proc->links.next;
 	}
 
 	/*
@@ -864,12 +864,12 @@ PrintLockQueue(LOCK *lock, const char *info)
 	PGPROC	   *proc;
 	int			i;
 
-	printf("%s lock %lx queue ", info, MAKE_OFFSET(lock));
-	proc = (PGPROC *) MAKE_PTR(waitQueue->links.next);
+	printf("%s lock %p queue ", info, lock);
+	proc = (PGPROC *) waitQueue->links.next;
 	for (i = 0; i < queue_size; i++)
 	{
 		printf(" %d", proc->pid);
-		proc = (PGPROC *) MAKE_PTR(proc->links.next);
+		proc = (PGPROC *) proc->links.next;
 	}
 	printf("\n");
 	fflush(stdout);
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 991d94fe35374029eaf56578f265a35c12175b13..7a990e0d7e7e0d6990214989879ace976a14aef9 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.184 2008/08/01 13:16:09 alvherre Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.185 2008/11/02 21:24:52 tgl Exp $
  *
  * NOTES
  *	  A lock table is a shared memory hash table.  When
@@ -1214,7 +1214,7 @@ RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
 
 	/* Make sure proc is waiting */
 	Assert(proc->waitStatus == STATUS_WAITING);
-	Assert(proc->links.next != INVALID_OFFSET);
+	Assert(proc->links.next != NULL);
 	Assert(waitLock);
 	Assert(waitLock->waitProcs.size > 0);
 	Assert(0 < lockmethodid && lockmethodid < lengthof(LockMethods));
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 9548b6c0fa13197c904a7ee7b60ded89b8731449..0ceff0ffe35ce337690610b290a75eb79e4d7ad1 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.201 2008/06/09 18:23:05 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.202 2008/11/02 21:24:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -170,8 +170,8 @@ InitProcGlobal(void)
 	/*
 	 * Initialize the data structures.
 	 */
-	ProcGlobal->freeProcs = INVALID_OFFSET;
-	ProcGlobal->autovacFreeProcs = INVALID_OFFSET;
+	ProcGlobal->freeProcs = NULL;
+	ProcGlobal->autovacFreeProcs = NULL;
 
 	ProcGlobal->spins_per_delay = DEFAULT_SPINS_PER_DELAY;
 
@@ -187,8 +187,8 @@ InitProcGlobal(void)
 	for (i = 0; i < MaxConnections; i++)
 	{
 		PGSemaphoreCreate(&(procs[i].sem));
-		procs[i].links.next = ProcGlobal->freeProcs;
-		ProcGlobal->freeProcs = MAKE_OFFSET(&procs[i]);
+		procs[i].links.next = (SHM_QUEUE *) ProcGlobal->freeProcs;
+		ProcGlobal->freeProcs = &procs[i];
 	}
 
 	procs = (PGPROC *) ShmemAlloc((autovacuum_max_workers) * sizeof(PGPROC));
@@ -200,8 +200,8 @@ InitProcGlobal(void)
 	for (i = 0; i < autovacuum_max_workers; i++)
 	{
 		PGSemaphoreCreate(&(procs[i].sem));
-		procs[i].links.next = ProcGlobal->autovacFreeProcs;
-		ProcGlobal->autovacFreeProcs = MAKE_OFFSET(&procs[i]);
+		procs[i].links.next = (SHM_QUEUE *) ProcGlobal->autovacFreeProcs;
+		ProcGlobal->autovacFreeProcs = &procs[i];
 	}
 
 	MemSet(AuxiliaryProcs, 0, NUM_AUXILIARY_PROCS * sizeof(PGPROC));
@@ -224,7 +224,6 @@ InitProcess(void)
 {
 	/* use volatile pointer to prevent code rearrangement */
 	volatile PROC_HDR *procglobal = ProcGlobal;
-	SHMEM_OFFSET myOffset;
 	int			i;
 
 	/*
@@ -249,17 +248,16 @@ InitProcess(void)
 	set_spins_per_delay(procglobal->spins_per_delay);
 
 	if (IsAutoVacuumWorkerProcess())
-		myOffset = procglobal->autovacFreeProcs;
+		MyProc = procglobal->autovacFreeProcs;
 	else
-		myOffset = procglobal->freeProcs;
+		MyProc = procglobal->freeProcs;
 
-	if (myOffset != INVALID_OFFSET)
+	if (MyProc != NULL)
 	{
-		MyProc = (PGPROC *) MAKE_PTR(myOffset);
 		if (IsAutoVacuumWorkerProcess())
-			procglobal->autovacFreeProcs = MyProc->links.next;
+			procglobal->autovacFreeProcs = (PGPROC *) MyProc->links.next;
 		else
-			procglobal->freeProcs = MyProc->links.next;
+			procglobal->freeProcs = (PGPROC *) MyProc->links.next;
 		SpinLockRelease(ProcStructLock);
 	}
 	else
@@ -461,7 +459,6 @@ InitAuxiliaryProcess(void)
 bool
 HaveNFreeProcs(int n)
 {
-	SHMEM_OFFSET offset;
 	PGPROC	   *proc;
 
 	/* use volatile pointer to prevent code rearrangement */
@@ -469,12 +466,11 @@ HaveNFreeProcs(int n)
 
 	SpinLockAcquire(ProcStructLock);
 
-	offset = procglobal->freeProcs;
+	proc = procglobal->freeProcs;
 
-	while (n > 0 && offset != INVALID_OFFSET)
+	while (n > 0 && proc != NULL)
 	{
-		proc = (PGPROC *) MAKE_PTR(offset);
-		offset = proc->links.next;
+		proc = (PGPROC *) proc->links.next;
 		n--;
 	}
 
@@ -506,7 +502,7 @@ LockWaitCancel(void)
 	partitionLock = LockHashPartitionLock(lockAwaited->hashcode);
 	LWLockAcquire(partitionLock, LW_EXCLUSIVE);
 
-	if (MyProc->links.next != INVALID_OFFSET)
+	if (MyProc->links.next != NULL)
 	{
 		/* We could not have been granted the lock yet */
 		RemoveFromWaitQueue(MyProc, lockAwaited->hashcode);
@@ -601,13 +597,13 @@ ProcKill(int code, Datum arg)
 	/* Return PGPROC structure (and semaphore) to freelist */
 	if (IsAutoVacuumWorkerProcess())
 	{
-		MyProc->links.next = procglobal->autovacFreeProcs;
-		procglobal->autovacFreeProcs = MAKE_OFFSET(MyProc);
+		MyProc->links.next = (SHM_QUEUE *) procglobal->autovacFreeProcs;
+		procglobal->autovacFreeProcs = MyProc;
 	}
 	else
 	{
-		MyProc->links.next = procglobal->freeProcs;
-		procglobal->freeProcs = MAKE_OFFSET(MyProc);
+		MyProc->links.next = (SHM_QUEUE *) procglobal->freeProcs;
+		procglobal->freeProcs = MyProc;
 	}
 
 	/* PGPROC struct isn't mine anymore */
@@ -752,7 +748,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
 	{
 		LOCKMASK	aheadRequests = 0;
 
-		proc = (PGPROC *) MAKE_PTR(waitQueue->links.next);
+		proc = (PGPROC *) waitQueue->links.next;
 		for (i = 0; i < waitQueue->size; i++)
 		{
 			/* Must he wait for me? */
@@ -790,7 +786,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
 			}
 			/* Nope, so advance to next waiter */
 			aheadRequests |= LOCKBIT_ON(proc->waitLockMode);
-			proc = (PGPROC *) MAKE_PTR(proc->links.next);
+			proc = (PGPROC *) proc->links.next;
 		}
 
 		/*
@@ -1054,13 +1050,13 @@ ProcWakeup(PGPROC *proc, int waitStatus)
 	PGPROC	   *retProc;
 
 	/* Proc should be sleeping ... */
-	if (proc->links.prev == INVALID_OFFSET ||
-		proc->links.next == INVALID_OFFSET)
+	if (proc->links.prev == NULL ||
+		proc->links.next == NULL)
 		return NULL;
 	Assert(proc->waitStatus == STATUS_WAITING);
 
 	/* Save next process before we zap the list link */
-	retProc = (PGPROC *) MAKE_PTR(proc->links.next);
+	retProc = (PGPROC *) proc->links.next;
 
 	/* Remove process from wait queue */
 	SHMQueueDelete(&(proc->links));
@@ -1097,7 +1093,7 @@ ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock)
 	if (queue_size == 0)
 		return;
 
-	proc = (PGPROC *) MAKE_PTR(waitQueue->links.next);
+	proc = (PGPROC *) waitQueue->links.next;
 
 	while (queue_size-- > 0)
 	{
@@ -1130,7 +1126,7 @@ ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock)
 			 * Cannot wake this guy. Remember his request for later checks.
 			 */
 			aheadRequests |= LOCKBIT_ON(lockmode);
-			proc = (PGPROC *) MAKE_PTR(proc->links.next);
+			proc = (PGPROC *) proc->links.next;
 		}
 	}
 
@@ -1179,8 +1175,8 @@ CheckDeadLock(void)
 	 * This is quicker than checking our semaphore's state, since no kernel
 	 * call is needed, and it is safe because we hold the lock partition lock.
 	 */
-	if (MyProc->links.prev == INVALID_OFFSET ||
-		MyProc->links.next == INVALID_OFFSET)
+	if (MyProc->links.prev == NULL ||
+		MyProc->links.next == NULL)
 		goto check_done;
 
 #ifdef LOCK_DEBUG
diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h
index e5fd8e3ac21bbb282c970610d94fc30b47e4c5ea..cbe723d1d7ab583bf68366201834278d9d722dff 100644
--- a/src/include/storage/pg_shmem.h
+++ b/src/include/storage/pg_shmem.h
@@ -17,7 +17,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/storage/pg_shmem.h,v 1.23 2008/01/01 19:45:59 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/storage/pg_shmem.h,v 1.24 2008/11/02 21:24:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -31,7 +31,7 @@ typedef struct PGShmemHeader	/* standard header for all Postgres shmem */
 	pid_t		creatorPID;		/* PID of creating process */
 	Size		totalsize;		/* total size of segment */
 	Size		freeoffset;		/* offset to first free space */
-	Size		indexoffset;	/* offset to ShmemIndex table */
+	void	   *index;			/* pointer to ShmemIndex table */
 #ifndef WIN32					/* Windows doesn't have useful inode#s */
 	dev_t		device;			/* device data directory is on */
 	ino_t		inode;			/* inode number of data directory */
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index d1ab71d0eeb7ea2f5ba71fade79aa1db088a1448..ccdc48884a2087253639e189a426b24e1e8490fe 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.106 2008/04/15 20:28:47 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.107 2008/11/02 21:24:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -128,9 +128,9 @@ extern PGDLLIMPORT PGPROC *MyProc;
 typedef struct PROC_HDR
 {
 	/* Head of list of free PGPROC structures */
-	SHMEM_OFFSET freeProcs;
+	PGPROC	   *freeProcs;
 	/* Head of list of autovacuum's free PGPROC structures */
-	SHMEM_OFFSET autovacFreeProcs;
+	PGPROC	   *autovacFreeProcs;
 	/* Current shared estimate of appropriate spins_per_delay value */
 	int			spins_per_delay;
 } PROC_HDR;
diff --git a/src/include/storage/shmem.h b/src/include/storage/shmem.h
index 4bee544fb63536d1025dbdd632022430938a098f..cbfca69e674a1075d4f5d5c980c7f5511745208f 100644
--- a/src/include/storage/shmem.h
+++ b/src/include/storage/shmem.h
@@ -3,11 +3,18 @@
  * shmem.h
  *	  shared memory management structures
  *
+ * Historical note:
+ * A long time ago, Postgres' shared memory region was allowed to be mapped
+ * at a different address in each process, and shared memory "pointers" were
+ * passed around as offsets relative to the start of the shared memory region.
+ * That is no longer the case: each process must map the shared memory region
+ * at the same address.  This means shared memory pointers can be passed
+ * around directly between different processes.
  *
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/storage/shmem.h,v 1.53 2008/01/01 19:45:59 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/storage/shmem.h,v 1.54 2008/11/02 21:24:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -17,53 +24,18 @@
 #include "utils/hsearch.h"
 
 
-/*
- * The shared memory region can start at a different address
- * in every process.  Shared memory "pointers" are actually
- * offsets relative to the start of the shared memory region(s).
- *
- * In current usage, this is not actually a problem, but we keep
- * the code that used to handle it...
- */
-typedef unsigned long SHMEM_OFFSET;
-
-#define INVALID_OFFSET	(-1)
-
-/*
- * Start of the primary shared memory region, in this process' address space.
- * The macros in this header file can only cope with offsets into this
- * shared memory region!
- */
-extern PGDLLIMPORT SHMEM_OFFSET ShmemBase;
-
-
-/* coerce an offset into a pointer in this process's address space */
-#define MAKE_PTR(xx_offs)\
-  (ShmemBase+((unsigned long)(xx_offs)))
-
-/* coerce a pointer into a shmem offset */
-#define MAKE_OFFSET(xx_ptr)\
-  ((SHMEM_OFFSET) (((unsigned long)(xx_ptr))-ShmemBase))
-
-#define SHM_PTR_VALID(xx_ptr)\
-  (((unsigned long)(xx_ptr)) > ShmemBase)
-
-/* cannot have an offset to ShmemFreeStart (offset 0) */
-#define SHM_OFFSET_VALID(xx_offs)\
-  (((xx_offs) != 0) && ((xx_offs) != INVALID_OFFSET))
-
 /* shmqueue.c */
 typedef struct SHM_QUEUE
 {
-	SHMEM_OFFSET prev;
-	SHMEM_OFFSET next;
+	struct SHM_QUEUE *prev;
+	struct SHM_QUEUE *next;
 } SHM_QUEUE;
 
 /* shmem.c */
 extern void InitShmemAccess(void *seghdr);
 extern void InitShmemAllocation(void);
 extern void *ShmemAlloc(Size size);
-extern bool ShmemIsValid(unsigned long addr);
+extern bool ShmemAddrIsValid(void *addr);
 extern void InitShmemIndex(void);
 extern HTAB *ShmemInitHash(const char *name, long init_size, long max_size,
 			  HASHCTL *infoP, int hash_flags);
@@ -77,15 +49,15 @@ extern void RequestAddinShmemSpace(Size size);
 /* size constants for the shmem index table */
  /* max size of data structure string name */
 #define SHMEM_INDEX_KEYSIZE		 (48)
- /* max size of the shmem index table (not a hard limit) */
+ /* estimated size of the shmem index table (not a hard limit) */
 #define SHMEM_INDEX_SIZE		 (32)
 
 /* this is a hash bucket in the shmem index table */
 typedef struct
 {
 	char		key[SHMEM_INDEX_KEYSIZE];		/* string name */
-	unsigned long location;		/* location in shared mem */
-	unsigned long size;			/* numbytes allocated for the structure */
+	void	   *location;			/* location in shared mem */
+	Size		size;				/* # bytes allocated for the structure */
 } ShmemIndexEnt;
 
 /*