Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-15 Thread Tom Lane
Robert Haas  writes:
> There are an awful lot of places in our source tree where the error
> level is fixed.  We could invent a new construct, say ereport_error or
> so, that is just like ereport except that it takes no error-level
> parameter because it's hard-coded to ERROR.

> It would be a bit of a pain to change all of the existing call sites,
> but presumably it would dodge a lot of these issues about the way
> compilers optimize things, because we could simply say categorically
> that ereport_error NEVER returns.

Meh.  We've already got it working, and in a way that doesn't require
the compiler to understand __attribute__((noreturn)) --- it only has
to be aware that abort() doesn't return, in one fashion or another.
So I'm disinclined to run around and change a few thousand call sites,
much less expect extension authors to do so too.

(By my count there are about six thousand places we'd have to change.)

Note that whatever's going on on dugong is not a counterexample to
"got it working", because presumably dugong would also be misbehaving
if we'd used a different method of flagging all the ereports/elogs
as nonreturning.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-15 Thread Robert Haas
On Sun, Jan 13, 2013 at 4:16 PM, Tom Lane  wrote:
> Andres Freund  writes:
>>> Basically, the aspects of this that I think are likely to be
>>> reproducible wins across different platforms are (a) teaching the
>>> compiler that elog(ERROR) doesn't return, and (b) reducing code size as
>>> much as possible.  The single-function change isn't going to help on
>>> either ground --- maybe it would have helped on (b) without the errno
>>> problem, but that's going to destroy any possible code size savings.
>
>> Agreed. I am happy to produce an updated patch unless youre already on
>> it?
>
> On it now (busy testing on some old slow boxes, else I'd be done already).

Just a random thought here...

There are an awful lot of places in our source tree where the error
level is fixed.  We could invent a new construct, say ereport_error or
so, that is just like ereport except that it takes no error-level
parameter because it's hard-coded to ERROR.

It would be a bit of a pain to change all of the existing call sites,
but presumably it would dodge a lot of these issues about the way
compilers optimize things, because we could simply say categorically
that ereport_error NEVER returns.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-13 Thread Tom Lane
Andres Freund  writes:
>> Basically, the aspects of this that I think are likely to be
>> reproducible wins across different platforms are (a) teaching the
>> compiler that elog(ERROR) doesn't return, and (b) reducing code size as
>> much as possible.  The single-function change isn't going to help on
>> either ground --- maybe it would have helped on (b) without the errno
>> problem, but that's going to destroy any possible code size savings.

> Agreed. I am happy to produce an updated patch unless youre already on
> it?

On it now (busy testing on some old slow boxes, else I'd be done already).

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-13 Thread Tom Lane
Andres Freund  writes:
> On 2013-01-13 14:17:52 -0500, Tom Lane wrote:
>> I find these numbers pretty hard to credit.

> There are quite some elog(DEBUG*)s in the backend, and those are taken,
> so I don't find it unreasonable that doing less work in those cases is
> measurable.

Meh.  If there are any elog(DEBUG)s in time-critical places, they should
be changed to ereport's anyway, so as to eliminate most of the overhead
when they're not firing.

> And if you look at the disassembly of ERROR codepaths:

I think your numbers are being twisted by -fno-omit-frame-pointer.
What I get, with the __builtin_unreachable version of the macro,
looks more like

MemoryContextAlloc:
cmpq$1073741823, %rsi
pushq   %rbx
movq%rsi, %rbx
ja  .L53
movq8(%rdi), %rax
movb$0, 48(%rdi)
popq%rbx
movq(%rax), %rax
jmp *%rax
.L53:
movl$__func__.5262, %edx
movl$576, %esi
movl$.LC2, %edi
callelog_start
movq%rbx, %rdx
movl$.LC3, %esi
movl$20, %edi
xorl%eax, %eax
callelog_finish

With -fno-omit-frame-pointer it's a little worse, but still not what you
show --- in particular, for me gcc still pushes the elog calls out of
the main code path.  I don't think that the main path will get any
better with one elog function instead of two.  It could easily get worse.
On many machines, the single-function version would be worse because of
needing to use more parameter registers, which would translate into more
save/restore work in the calling function, which is overhead that would
likely be paid whether elog actually gets called or not.  (As an
example, in the above code gcc evidently isn't noticing that it doesn't
need to save/restore rbx so far as the main path is concerned.)

In any case, results from a single micro-benchmark on a single platform
with a single compiler version (and single set of compiler options)
don't convince me a whole lot here.

Basically, the aspects of this that I think are likely to be
reproducible wins across different platforms are (a) teaching the
compiler that elog(ERROR) doesn't return, and (b) reducing code size as
much as possible.  The single-function change isn't going to help on
either ground --- maybe it would have helped on (b) without the errno
problem, but that's going to destroy any possible code size savings.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-13 Thread Tom Lane
Andres Freund  writes:
> On 2013-01-12 15:39:16 -0500, Tom Lane wrote:
>> This is actually a disadvantage of the proposal to replace the abort()
>> calls with __builtin_unreachable(), too.  The gcc boys interpret the
>> semantics of that as "if control reaches here, the behavior is
>> undefined"

> We could make add an Assert() additionally?

I see little value in that.  In a non-assert build it will do nothing at
all, and in an assert build it'd just add code bloat.

I think there might be a good argument for defining pg_unreachable() as
abort() in assert-enabled builds, even if the compiler has
__builtin_unreachable(): that way, if the impossible happens, we'll find
out about it in a predictable and debuggable way.  And by definition,
we're not so concerned about either performance or code bloat in assert
builds.

> Where my variant is:
> #define ereport_domain(elevel, domain, rest)\
> do {\
> const int elevel_ = elevel; \
> if (errstart(elevel_,__FILE__, __LINE__, PG_FUNCNAME_MACRO, domain))\
> {   \
> errfinish rest; \
> }   \
> if (elevel_>= ERROR)\
> pg_unreachable();   \
> } while(0)

This is the same implementation I'd arrived at after looking at
Heikki's.  I think we should probably use this for non-gcc builds.
However, for recent gcc (those with __builtin_constant_p) I think that
my original suggestion is better, ie don't use a local variable but
instead use __builtin_constant_p(elevel) && (elevel) >= ERROR in the
second test.  That way we don't have the problem with unreachability
tests failing at -O0.  We may still have some issues with bogus warnings
in other compilers, but I think most PG developers are using recent gcc.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-13 Thread Andres Freund
On 2013-01-12 18:15:17 -0500, Tom Lane wrote:
> Andres Freund  writes:
> > On 2013-01-12 13:16:56 -0500, Tom Lane wrote:
> >> However, using a do-block with a local variable is definitely something
> >> worth considering.  I'm getting less enamored of the __builtin_constant_p
> >> idea after finding out that the gcc boys seem to have curious ideas
> >> about what its semantics ought to be:
> >> https://bugzilla.redhat.com/show_bug.cgi?id=894515
> 
> > I wonder whether __builtin_choose_expr is any better?
> 
> Right offhand I don't see how that helps us.  AFAICS,
> __builtin_choose_expr is the same as x?y:z except that y and z are not
> required to have the same datatype, which is okay because they require
> the value of x to be determinable at compile time.  So we couldn't just
> write __builtin_choose_expr((elevel) >= ERROR, ...).  That would fail
> if elevel wasn't compile-time-constant.  We could conceivably do
> 
> __builtin_choose_expr(__builtin_constant_p(elevel) && (elevel) >= ERROR, ...)
> 
> with the idea of making real sure that that expression reduces to a
> compile time constant ... but stacking two nonstandard constructs on
> each other seems to me to probably increase our exposure to gcc's
> definitional randomness rather than reduce it.  I mean, if
> __builtin_constant_p can't already be trusted to act like a constant,
> why should we trust that __builtin_choose_expr doesn't also have a
> curious definition of constant-ness?

I was thinking of something like the above, yes. It seems to me to
generate code the compiler would need to really make sure the condition
in __builtin_choose_expr() is really constant, so I hoped the checks
inside are somewhat strict...

Greetings,

Andres Freund

-- 
 Andres Freund http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-12 Thread Tom Lane
Andres Freund  writes:
> On 2013-01-12 13:16:56 -0500, Tom Lane wrote:
>> However, using a do-block with a local variable is definitely something
>> worth considering.  I'm getting less enamored of the __builtin_constant_p
>> idea after finding out that the gcc boys seem to have curious ideas
>> about what its semantics ought to be:
>> https://bugzilla.redhat.com/show_bug.cgi?id=894515

> I wonder whether __builtin_choose_expr is any better?

Right offhand I don't see how that helps us.  AFAICS,
__builtin_choose_expr is the same as x?y:z except that y and z are not
required to have the same datatype, which is okay because they require
the value of x to be determinable at compile time.  So we couldn't just
write __builtin_choose_expr((elevel) >= ERROR, ...).  That would fail
if elevel wasn't compile-time-constant.  We could conceivably do

__builtin_choose_expr(__builtin_constant_p(elevel) && (elevel) >= ERROR, ...)

with the idea of making real sure that that expression reduces to a
compile time constant ... but stacking two nonstandard constructs on
each other seems to me to probably increase our exposure to gcc's
definitional randomness rather than reduce it.  I mean, if
__builtin_constant_p can't already be trusted to act like a constant,
why should we trust that __builtin_choose_expr doesn't also have a
curious definition of constant-ness?

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-12 Thread Tom Lane
Heikki Linnakangas  writes:
> On 12.01.2013 20:42, Andres Freund wrote:
>>> I don't care for that too much in detail -- if errstart were to return
>>> false (it shouldn't, but if it did) this would be utterly broken,

> With the current ereport(), we'll call abort() if errstart returns false 
> and elevel >= ERROR. That's even worse than making an error reporting 
> calls that elog.c isn't prepared for.

No it isn't: you'd get a clean and easily interpretable abort.  I am not
sure exactly what would happen if we plow forward with calling elog.c
functions after errstart returns false, but it wouldn't be good, and
debugging a field report of such behavior wouldn't be easy.

This is actually a disadvantage of the proposal to replace the abort()
calls with __builtin_unreachable(), too.  The gcc boys interpret the
semantics of that as "if control reaches here, the behavior is
undefined" --- and their notion of undefined generally seems to amount
to "we will screw you as hard as we can".  For example, they have no
problem with using the assumption that control won't reach there to make
deductions while optimizing the rest of the function.  If it ever did
happen, I would not want to have to debug it.  The same goes for
__attribute__((noreturn)), BTW.

>> Yea, I didn't really like it all that much either - but anyway, I have
>> yet to find *any* version with a local variable that doesn't lead to
>> 200kb size increase :(.

> Hmm, that's strange. Assuming the optimizer optimizes away the paths in 
> the macro that are never taken when elevel is a constant, I would expect 
> the resulting binary to be smaller than what we have now.

I was wondering about that too, but haven't tried it locally yet.  It
could be that Andres was looking at an optimization level in which a
register still got allocated for the local variable.

> Here's what I got with and without my patch on my laptop:

> -rwxr-xr-x 1 heikki heikki 24767237 tammi 12 21:27 postgres-do-while-mypatch
> -rwxr-xr-x 1 heikki heikki 24623081 tammi 12 21:28 postgres-unpatched

> But when I build without --enable-debug, the situation reverses:

> -rwxr-xr-x 1 heikki heikki 5961309 tammi 12 21:48 postgres-do-while-mypatch
> -rwxr-xr-x 1 heikki heikki 5986961 tammi 12 21:49 postgres-unpatched

Yes, I noticed that too: these patches make the debug overhead grow
substantially for some reason.  It's better to look at the output of
"size" rather than the executable's total file size.  That way you don't
need to rebuild without debug to see reality.  (I guess you could also
"strip" the executables for comparison purposes.)

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-12 Thread Heikki Linnakangas

On 12.01.2013 20:42, Andres Freund wrote:

On 2013-01-12 13:16:56 -0500, Tom Lane wrote:

Heikki Linnakangas  writes:

Here's one more construct to consider:



#define ereport_domain(elevel, domain, rest) \
do { \
const int elevel_ = elevel; \
if (errstart(elevel_,__FILE__, __LINE__, PG_FUNCNAME_MACRO, 
domain) ||
elevel_>= ERROR) \
{ \
(void) rest; \
if (elevel_>= ERROR) \
errfinish_noreturn(1); \
else \
errfinish(1); \
} \
} while(0)


I don't care for that too much in detail -- if errstart were to return
false (it shouldn't, but if it did) this would be utterly broken,
because we'd be making error reporting calls that elog.c wouldn't be
prepared to accept.  We should stick to the technique of doing the
ereport as today and then adding something that tells the compiler we
don't expect to get here; preferably something that emits no added code.


With the current ereport(), we'll call abort() if errstart returns false 
and elevel >= ERROR. That's even worse than making an error reporting 
calls that elog.c isn't prepared for. If we take that risk seriously, 
with bogus error reporting calls we at least have chance of catching it 
and reporting an error.



Yea, I didn't really like it all that much either - but anyway, I have
yet to find *any* version with a local variable that doesn't lead to
200kb size increase :(.


Hmm, that's strange. Assuming the optimizer optimizes away the paths in 
the macro that are never taken when elevel is a constant, I would expect 
the resulting binary to be smaller than what we have now. All those 
useless abort() calls must take up some space.


Here's what I got with and without my patch on my laptop:

-rwxr-xr-x 1 heikki heikki 24767237 tammi 12 21:27 postgres-do-while-mypatch
-rwxr-xr-x 1 heikki heikki 24623081 tammi 12 21:28 postgres-unpatched

But when I build without --enable-debug, the situation reverses:

-rwxr-xr-x 1 heikki heikki 5961309 tammi 12 21:48 postgres-do-while-mypatch
-rwxr-xr-x 1 heikki heikki 5986961 tammi 12 21:49 postgres-unpatched

I suspect you're also just seeing bloat caused by more debugging 
symbols, which won't have any effect at runtime. It would be nice to 
have smaller debug-enabled builds, too, of course, but it's not that 
important.



However, using a do-block with a local variable is definitely something
worth considering.  I'm getting less enamored of the __builtin_constant_p
idea after finding out that the gcc boys seem to have curious ideas
about what its semantics ought to be:
https://bugzilla.redhat.com/show_bug.cgi?id=894515


I wonder whether __builtin_choose_expr is any better?


I forgot to mention (and it wasn't visible in the snippet I posted) the 
reason I used __attribute__ ((noreturn)). We already use that attribute 
elsewhere, so this optimization wouldn't require anything more from the 
compiler than what already take advantage of. I think that noreturn is 
more widely supported than these other constructs. Also, if I'm reading 
the MSDN docs correctly, while MSVC doesn't understand __attribute__ 
((noreturn)) directly, it has an equivalent syntax _declspec(noreturn). 
So we could easily support MSVC with this approach.


Attached is the complete patch I used for the above tests.

- Heikki
diff --git a/src/backend/bootstrap/bootscanner.l b/src/backend/bootstrap/bootscanner.l
index bdd7dcb..b97bee4 100644
--- a/src/backend/bootstrap/bootscanner.l
+++ b/src/backend/bootstrap/bootscanner.l
@@ -42,8 +42,13 @@
 
 /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
 #undef fprintf
-#define fprintf(file, fmt, msg)  ereport(ERROR, (errmsg_internal("%s", msg)))
+#define fprintf(file, fmt, msg)  fprintf_to_ereport(fmt, msg)
 
+static void
+fprintf_to_ereport(char *fmt, const char *msg)
+{
+	ereport(ERROR, (errmsg_internal("%s", msg)));
+}
 
 static int	yyline = 1;			/* line number for error reporting */
 
diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l
index 622cb1f..877345b 100644
--- a/src/backend/parser/scan.l
+++ b/src/backend/parser/scan.l
@@ -42,7 +42,14 @@
 
 /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
 #undef fprintf
-#define fprintf(file, fmt, msg)  ereport(ERROR, (errmsg_internal("%s", msg)))
+#define fprintf(file, fmt, msg)  fprintf_to_ereport(fmt, msg)
+
+static void
+fprintf_to_ereport(char *fmt, const char *msg)
+{
+	ereport(ERROR, (errmsg_internal("%s", msg)));
+}
+
 
 /*
  * GUC variables.  This is a DIRECT violation of the warning given at the
diff --git a/src/backend/replication/repl_scanner.l b/src/backend/replication/repl_scanner.l
index 9ccf02a..b62625b 100644
--- a/src/backend/replication/repl_scanner.l
+++ b/src/backend/replication/repl_scanner.l
@@ -19,7 +19,13 @@
 
 /* Avoid exit() on fatal scanner errors (a

Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-12 Thread Andres Freund
On 2013-01-12 13:16:56 -0500, Tom Lane wrote:
> Heikki Linnakangas  writes:
> > On 11.01.2013 23:49, Tom Lane wrote:
> >> Hm ... well, that's a point.  I may be putting too much weight on the
> >> fact that any such bug for elevel would be a new one that never existed
> >> before.  What do others think?
>
> > It sure would be nice to avoid multiple evaluation. At least in xlog.c
> > we use emode_for_corrupt_record() to pass the elevel, and it does have a
> > side-effect.
>
> Um.  I had forgotten about that example, but its existence is sufficient
> to reinforce my opinion that we must not risk double evaluation of the
> elevel argument.

Unfortunately I aggree :(

> > Here's one more construct to consider:
>
> > #define ereport_domain(elevel, domain, rest) \
> > do { \
> > const int elevel_ = elevel; \
> > if (errstart(elevel_,__FILE__, __LINE__, PG_FUNCNAME_MACRO, 
> > domain) ||
> > elevel_>= ERROR) \
> > { \
> > (void) rest; \
> > if (elevel_>= ERROR) \
> > errfinish_noreturn(1); \
> > else \
> > errfinish(1); \
> > } \
> > } while(0)
>
> I don't care for that too much in detail -- if errstart were to return
> false (it shouldn't, but if it did) this would be utterly broken,
> because we'd be making error reporting calls that elog.c wouldn't be
> prepared to accept.  We should stick to the technique of doing the
> ereport as today and then adding something that tells the compiler we
> don't expect to get here; preferably something that emits no added code.

Yea, I didn't really like it all that much either - but anyway, I have
yet to find *any* version with a local variable that doesn't lead to
200kb size increase :(.

> However, using a do-block with a local variable is definitely something
> worth considering.  I'm getting less enamored of the __builtin_constant_p
> idea after finding out that the gcc boys seem to have curious ideas
> about what its semantics ought to be:
> https://bugzilla.redhat.com/show_bug.cgi?id=894515

I wonder whether __builtin_choose_expr is any better?

Greetings,

Andres Freund

--
 Andres Freund http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-12 Thread Tom Lane
Heikki Linnakangas  writes:
> On 11.01.2013 23:49, Tom Lane wrote:
>> Hm ... well, that's a point.  I may be putting too much weight on the
>> fact that any such bug for elevel would be a new one that never existed
>> before.  What do others think?

> It sure would be nice to avoid multiple evaluation. At least in xlog.c 
> we use emode_for_corrupt_record() to pass the elevel, and it does have a 
> side-effect.

Um.  I had forgotten about that example, but its existence is sufficient
to reinforce my opinion that we must not risk double evaluation of the
elevel argument.

> Here's one more construct to consider:

> #define ereport_domain(elevel, domain, rest) \
>   do { \
>   const int elevel_ = elevel; \
>   if (errstart(elevel_,__FILE__, __LINE__, PG_FUNCNAME_MACRO, 
> domain) || 
> elevel_>= ERROR) \
>   { \
>   (void) rest; \
>   if (elevel_>= ERROR) \
>   errfinish_noreturn(1); \
>   else \
>   errfinish(1); \
>   } \
>   } while(0)

I don't care for that too much in detail -- if errstart were to return
false (it shouldn't, but if it did) this would be utterly broken,
because we'd be making error reporting calls that elog.c wouldn't be
prepared to accept.  We should stick to the technique of doing the
ereport as today and then adding something that tells the compiler we
don't expect to get here; preferably something that emits no added code.

However, using a do-block with a local variable is definitely something
worth considering.  I'm getting less enamored of the __builtin_constant_p
idea after finding out that the gcc boys seem to have curious ideas
about what its semantics ought to be:
https://bugzilla.redhat.com/show_bug.cgi?id=894515

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-11 Thread Tom Lane
Andres Freund  writes:
> On 2013-01-11 16:28:13 -0500, Tom Lane wrote:
>> I'm not very satisfied with that answer.  Right now, Peter's
>> patch has added a class of bugs that never existed before 9.3, and yours
>> would add more.  It might well be that those classes are empty ... but
>> *we can't know that*.  I don't think that keeping a new optimization for
>> non-gcc compilers is worth that risk.  Postgres is already full of
>> gcc-only optimizations, anyway.

> ISTM that ereport() already has so strange behaviour wrt evaluation of
> arguments (i.e doing it only when the message is really logged) that its
> doesn't seem to add a real additional risk.

Hm ... well, that's a point.  I may be putting too much weight on the
fact that any such bug for elevel would be a new one that never existed
before.  What do others think?

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-11 Thread Tom Lane
Andres Freund  writes:
> On 2013-01-11 16:16:58 -0500, Tom Lane wrote:
>> Uh ... because it's *not* unreachable if elevel < ERROR.  Otherwise we'd
>> just mark errfinish as __attribute((noreturn)) and be done.  Of course,
>> that's a gcc-ism too.

> Well, I mean with the double evaluation risk.

Oh, are you saying you don't want to make the __builtin_constant_p
addition?  I'm not very satisfied with that answer.  Right now, Peter's
patch has added a class of bugs that never existed before 9.3, and yours
would add more.  It might well be that those classes are empty ... but
*we can't know that*.  I don't think that keeping a new optimization for
non-gcc compilers is worth that risk.  Postgres is already full of
gcc-only optimizations, anyway.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-11 Thread Tom Lane
Andres Freund  writes:
> On 2013-01-11 15:52:19 -0500, Tom Lane wrote:
>> I agree the scenario doesn't seem all that probable, but what scares me
>> here is that if we use "__builtin_constant_p(elevel) && (elevel) >= ERROR"
>> in some builds, and just "(elevel) >= ERROR" in others, then if there is
>> any code with a multiple-evaluation hazard, it is only buggy in the
>> latter builds.  That's sufficiently nasty that I'm willing to give up
>> an optimization that we never had before 9.3 anyway.

> Well, why use it at all then and not just rely on
> __builtin_unreachable() in any recent gcc (and llvm fwiw) and abort()
> otherwise? Then the code is small for anything recent (gcc 4.4 afair)
> and always consistently buggy.

Uh ... because it's *not* unreachable if elevel < ERROR.  Otherwise we'd
just mark errfinish as __attribute((noreturn)) and be done.  Of course,
that's a gcc-ism too.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-11 Thread Tom Lane
Andres Freund  writes:
> On 2013-01-11 15:05:54 -0500, Tom Lane wrote:
>> And another thing: what if the elevel argument isn't safe for multiple
>> evaluation?  No such hazard ever existed before these patches, so I'm
>> not very comfortable with adding one.  (Even if all our own code is
>> safe, there's third-party code to worry about.)

> Hm. I am not really too scared about those dangers I have to admit.

I agree the scenario doesn't seem all that probable, but what scares me
here is that if we use "__builtin_constant_p(elevel) && (elevel) >= ERROR"
in some builds, and just "(elevel) >= ERROR" in others, then if there is
any code with a multiple-evaluation hazard, it is only buggy in the
latter builds.  That's sufficiently nasty that I'm willing to give up
an optimization that we never had before 9.3 anyway.

> I dislike the latter somewhat as it would mean not to give that
> information at all to msvc and others which seems a bit sad. But I don't
> feel particularly strongly.

It's not like our code isn't rather gcc-biased anyway.  I'd keep the
optimization for other compilers if possible, but not at the cost of
introducing bugs that occur only on those compilers.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-09 Thread Tom Lane
Andres Freund  writes:
> I wonder whether it makes sense to "inline" the contents pstrdup()
> additionally? My gut feeling is not, but...

I don't recall ever having seen MemoryContextStrdup amount to much,
so probably not worth the extra code space.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-09 Thread Tom Lane
Andres Freund  writes:
> On 2013-01-09 15:43:19 -0500, Tom Lane wrote:
>> I had thought of proposing that we code
>> palloc() like this:
>> 
>> void *
>> palloc(Size size)
>> {
>> MemoryContext context = CurrentMemoryContext;
>> 
>> AssertArg(MemoryContextIsValid(context));
>> 
>> if (!AllocSizeIsValid(size))
>> elog(ERROR, "invalid memory alloc request size %lu",
>>  (unsigned long) size);
>> 
>> context->isReset = false;
>> 
>> return (*context->methods->alloc) (context, size);
>> }
>> 
>> but at least on this specific hardware and compiler that would evidently
>> be a net loss compared to direct use of CurrentMemoryContext.  I would
>> not put a lot of faith in that result holding up on other machines
>> though.

> Thats not optimized to the same? ISTM the compiler should produce
> exactly the same code for both.

No, that's exactly the point here, you can't just assume that you get
the same code; this is tense enough that a few instructions matter.
Remember we're considering non-assert builds, so the AssertArg vanishes.
So in the form where CurrentMemoryContext is only read after the elog
call, the compiler can see that it requires but one fetch - it can't
change within the two lines where it's used.  In the form given above,
the compiler is required to fetch CurrentMemoryContext into a local
variable and keep it across the elog call.  (We know this doesn't
matter, but gcc doesn't; this version of gcc apparently isn't doing much
with the knowledge that elog won't return.)  Since the extra local
variable adds several instructions to the overall function's entry/exit
sequences, you come out behind.  At least on this platform.  On other
machines with different code generation behavior, the story could easily
be very different.

>> In any case this doesn't explain the whole 2% speedup, but it probably
>> accounts for palloc() showing as slightly cheaper than
>> MemoryContextAlloc had been in the oprofile listing.

> I'd guess that a good part of the cost is just smeared across all
> callers and not individually accountable to any function visible in the
> profile.

Yeah, I think this is most likely showing that there is a real,
measurable cost of code bloat.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-09 Thread Tom Lane
Andres Freund  writes:
> On 2013-01-09 11:57:35 -0500, Tom Lane wrote:
>> My objection is that you're forcing *all* backend code to go through
>> the trampoline.  That probably has a negative impact on performance, and
>> if you think it'll get committed without a thorough proof that there's
>> no such impact, you're mistaken.  Perhaps you're not aware of exactly
>> how hot a hot-spot palloc is?  It's not unlikely that this patch could
>> hurt backend performance by several percent all by itself.

> There is no additional overhead except some minor increase in code size.
> If you look at the patch palloc() now simply directly calls
> CurrentMemoryContext->methods->alloc. So there is no additional function
> call relative to the previous state.

Apparently we're failing to communicate, so let me put this as clearly
as possible: an unsupported assertion that this patch has zero cost
isn't worth the electrons it's written on.  We're talking about a place
where single instructions can make a large difference.  I see that
you've avoided an extra level of function call by duplicating code,
but there are (at least) two reasons why that could be a loser:

* now there are two hotspots not one, ie both MemoryContextAlloc and
palloc will be competing for L1 cache, likewise for
MemoryContextAllocZero and palloc0;

* depending on machine architecture and compiler optimizations, multiple
fetches of the global variable CurrentMemoryContext are quite likely to
cost more than fetching it once into a parameter register.

As I said, it's possible that this is a wash.  But it's very possible
that it isn't.

In any case it's not clear to me why duplicating code like that is a
less ugly approach than having different macro definitions for frontend
and backend.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-09 Thread Tom Lane
Andres Freund  writes:
> On 2013-01-09 11:37:46 -0500, Tom Lane wrote:
>> I agree that what dirmod is doing is pretty ugly, but it's localized
>> enough that I don't care particularly.  (Really, the only reason it's
>> a hack and not The Solution is that at the moment there's only one
>> file doing it that way.  A trampoline function for use only by code
>> that needs to work in both frontend and backend isn't an unreasonable
>> idea.)

> Well, after the patch the trampoline function would be palloc() itself.

My objection is that you're forcing *all* backend code to go through
the trampoline.  That probably has a negative impact on performance, and
if you think it'll get committed without a thorough proof that there's
no such impact, you're mistaken.  Perhaps you're not aware of exactly
how hot a hot-spot palloc is?  It's not unlikely that this patch could
hurt backend performance by several percent all by itself.

Now on the other side of the coin, it's also possible that it's a wash,
particularly on machines where fetching a global variable is a
relatively expensive thing to do.  But the driving force behind any
proposed change to the backend's palloc mechanism has to be performance,
and nothing but.  Convenience for a patch such as this not only doesn't
trump performance, I'm unwilling to grant it any standing at all.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-09 Thread Andres Freund
On 2013-01-09 11:37:46 -0500, Tom Lane wrote:
> Andres Freund  writes:
> > On 2013-01-09 13:46:53 +0200, Heikki Linnakangas wrote:
> >> I don't understand the need for this change. Can't you just:
> >> #define palloc(s) pg_malloc(s)
> >> in the frontend context?
>
> > Yes, that would be possible, but imo its the inferior solution:
>
> I'm with Heikki: in fact, I will go farther and say that this approach
> is DOA.  The only way you get to change the backend's definition of
> palloc is if you can show that doing so yields a performance boost
> in the backend.  Otherwise, we use a macro or whatever is necessary
> to allow frontend code to have a different underlying implementation
> of palloc(x).

Whats the usecase for being able to redefine it after the patch? Its not
like you can do anything interesting given that pfree() et. al. is not a
macro.

> > * removing allows us to get rid of the following ugliness in dirmod.c:
>
> I agree that what dirmod is doing is pretty ugly, but it's localized
> enough that I don't care particularly.  (Really, the only reason it's
> a hack and not The Solution is that at the moment there's only one
> file doing it that way.  A trampoline function for use only by code
> that needs to work in both frontend and backend isn't an unreasonable
> idea.)

Well, after the patch the trampoline function would be palloc() itself.

Greetings,

Andres Freund


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-09 Thread Tom Lane
Andres Freund  writes:
> On 2013-01-09 13:46:53 +0200, Heikki Linnakangas wrote:
>> I don't understand the need for this change. Can't you just:
>> #define palloc(s) pg_malloc(s)
>> in the frontend context?

> Yes, that would be possible, but imo its the inferior solution:

I'm with Heikki: in fact, I will go farther and say that this approach
is DOA.  The only way you get to change the backend's definition of
palloc is if you can show that doing so yields a performance boost
in the backend.  Otherwise, we use a macro or whatever is necessary
to allow frontend code to have a different underlying implementation
of palloc(x).

> * it precludes ever sharing code without compiling twice

That's never going to happen anyway, or at least there are plenty more
problems in the way of it.

> * removing allows us to get rid of the following ugliness in dirmod.c:

I agree that what dirmod is doing is pretty ugly, but it's localized
enough that I don't care particularly.  (Really, the only reason it's
a hack and not The Solution is that at the moment there's only one
file doing it that way.  A trampoline function for use only by code
that needs to work in both frontend and backend isn't an unreasonable
idea.)

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-09 Thread Andres Freund
On 2013-01-09 13:46:53 +0200, Heikki Linnakangas wrote:
> On 09.01.2013 13:27, Andres Freund wrote:
> >- makes palloc() into a real function so CurrentMemoryContext doesn't
> >   need to be provided
>
> I don't understand the need for this change. Can't you just:
>
> #define palloc(s) pg_malloc(s)
>
> in the frontend context?

Yes, that would be possible, but imo its the inferior solution:
* it precludes ever sharing code without compiling twice
* removing allows us to get rid of the following ugliness in dirmod.c:
-#ifndef FRONTEND
-
-/*
- * On Windows, call non-macro versions of palloc; we can't reference
- * CurrentMemoryContext in this file because of PGDLLIMPORT conflict.
- */
-#if defined(WIN32) || defined(__CYGWIN__)
-#undef palloc
-#undef pstrdup
-#define palloc(sz) pgport_palloc(sz)
-#define pstrdup(str)   pgport_pstrdup(str)
-#endif
-#else  /* FRONTEND */
-
* it opens the window for moving more stuff from utils/palloc.h to memutils.h

Greetings,

Andres Freund

--
 Andres Freund http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [PATCH] unified frontend support for pg_malloc et al and palloc/pfree mulation (was xlogreader-v4)

2013-01-09 Thread Heikki Linnakangas

On 09.01.2013 13:27, Andres Freund wrote:

- makes palloc() into a real function so CurrentMemoryContext doesn't
   need to be provided


I don't understand the need for this change. Can't you just:

#define palloc(s) pg_malloc(s)

in the frontend context?

- Heikki


--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers