Attached are two patches that remove use of dTHX in functions in quote.c
and types.c

dTHX is ithreads only, but relatively expensive, as it needs to make a
function call to retreive a value from thread local storage. It's much
better to pass that value as a function parameter, as the caller will have
it already.

Tested for (almost) everything ithreads and not from 5.8.1 to 5.18.2

I can't see how to make the same change to dbdimp.c without also changing
Driver.xst to optionaly support it.

Nicholas Clark
>From 268ab00a9e1180a8d125fbf75cfe8e5420136780 Mon Sep 17 00:00:00 2001
From: Nicholas Clark <[email protected]>
Date: Wed, 21 May 2014 10:53:25 +0200
Subject: [PATCH 1/2] Pass the interpreter struct into quote functions, instead
 of using dTHX;

dTHX; makes a moderately expensive call to get a value from thread-local
storage, whereas the interpreter struct pointer is available "for free" in
the calling function. This only affects multiplicity builds (ie ithreads).
---
 Pg.xs    |  2 +-
 dbdimp.c |  5 +++--
 quote.c  | 58 +++++++++++++++++++---------------------------------------
 quote.h  | 36 ++++++++++++++++++------------------
 4 files changed, 41 insertions(+), 60 deletions(-)

diff --git a/Pg.xs b/Pg.xs
index 2616552..45e9912 100644
--- a/Pg.xs
+++ b/Pg.xs
@@ -279,7 +279,7 @@ quote(dbh, to_quote_sv, type_sv=Nullsv)
 				
 			to_quote = SvPV(to_quote_sv, len);
 			/* Need good debugging here */
-			quoted = type_info->quote(to_quote, len, &retlen, imp_dbh->pg_server_version >= 80100 ? 1 : 0);
+			quoted = type_info->quote(aTHX_ to_quote, len, &retlen, imp_dbh->pg_server_version >= 80100 ? 1 : 0);
 			RETVAL = newSVpvn_utf8(quoted, retlen, utf8);
 			Safefree (quoted);
 		}
diff --git a/dbdimp.c b/dbdimp.c
index 59e2f61..057d66b 100644
--- a/dbdimp.c
+++ b/dbdimp.c
@@ -2829,7 +2829,7 @@ static SV * pg_destringify_array(pTHX_ imp_dbh_t *imp_dbh, unsigned char * input
 				else {
 					// Bytea gets special dequoting
 					if (0 == strncmp(coltype->type_name, "_bytea", 6)) {
-						coltype->dequote(string, &section_size);
+						coltype->dequote(aTHX_ string, &section_size);
 					}
 
 					SV *sv = newSVpvn(string, section_size);
@@ -3258,6 +3258,7 @@ int dbd_st_execute (SV * sth, imp_sth_t * imp_sth)
 				if (currph->quoted)
 					Safefree(currph->quoted);
 				currph->quoted = currph->bind_type->quote(
+					aTHX_
 					currph->value,
 					currph->valuelen,
 					&currph->quotedlen,
@@ -3651,7 +3652,7 @@ AV * dbd_st_fetch (SV * sth, imp_sth_t * imp_sth)
 			}
 			else {
 				if (type_info) {
-					type_info->dequote(value, &value_len); /* dequote in place */
+					type_info->dequote(aTHX_ value, &value_len); /* dequote in place */
 					/* For certain types, we can cast to non-string Perlish values */
 					switch (type_info->type_id) {
 					case PG_BOOL:
diff --git a/quote.c b/quote.c
index cc5ac13..54bf681 100644
--- a/quote.c
+++ b/quote.c
@@ -34,9 +34,8 @@ In other words, is it 8.1 or better?
 It must arrive as 0 or 1
 */
 
-char * null_quote(const char *string, STRLEN len, STRLEN *retlen, int estring)
+char * null_quote(pTHX_ const char *string, STRLEN len, STRLEN *retlen, int estring)
 {
-	dTHX;
 	char *result;
 
 	New(0, result, len+1, char);
@@ -47,9 +46,8 @@ char * null_quote(const char *string, STRLEN len, STRLEN *retlen, int estring)
 }
 
 
-char * quote_string(const char *string, STRLEN len, STRLEN *retlen, int estring)
+char * quote_string(pTHX_ const char *string, STRLEN len, STRLEN *retlen, int estring)
 {
-	dTHX;
 	char * result;
 	STRLEN oldlen = len;
 	const char * const tmp = string;
@@ -93,9 +91,8 @@ char * quote_string(const char *string, STRLEN len, STRLEN *retlen, int estring)
 /* Quote a geometric constant. */
 /* Note: we only verify correct characters here, not for 100% valid input */
 /* Covers: points, lines, lsegs, boxes, polygons */
-char * quote_geom(const char *string, STRLEN len, STRLEN *retlen, int estring)
+char * quote_geom(pTHX_ const char *string, STRLEN len, STRLEN *retlen, int estring)
 {
-	dTHX;
 	char * result;
 	const char *tmp;
 
@@ -125,9 +122,8 @@ char * quote_geom(const char *string, STRLEN len, STRLEN *retlen, int estring)
 }
 
 /* Same as quote_geom, but also allows square brackets */
-char * quote_path(const char *string, STRLEN len, STRLEN *retlen, int estring)
+char * quote_path(pTHX_ const char *string, STRLEN len, STRLEN *retlen, int estring)
 {
-	dTHX;
 	char * result;
 	const char * const tmp = string;
 
@@ -156,9 +152,8 @@ char * quote_path(const char *string, STRLEN len, STRLEN *retlen, int estring)
 }
 
 /* Same as quote_geom, but also allows less than / greater than signs */
-char * quote_circle(const char *string, STRLEN len, STRLEN *retlen, int estring)
+char * quote_circle(pTHX_ const char *string, STRLEN len, STRLEN *retlen, int estring)
 {
-	dTHX;
 	char * result;
 	const char * const tmp = string;
 
@@ -188,9 +183,8 @@ char * quote_circle(const char *string, STRLEN len, STRLEN *retlen, int estring)
 }
 
 
-char * quote_bytea(char *string, STRLEN len, STRLEN *retlen, int estring)
+char * quote_bytea(pTHX_ char *string, STRLEN len, STRLEN *retlen, int estring)
 {
-	dTHX;
 	char * result;
 	STRLEN oldlen = len;
 
@@ -249,20 +243,18 @@ char * quote_bytea(char *string, STRLEN len, STRLEN *retlen, int estring)
 	return (char *)result - (*retlen);
 }
 
-char * quote_sql_binary(char *string, STRLEN len, STRLEN *retlen, int estring)
+char * quote_sql_binary(pTHX_ char *string, STRLEN len, STRLEN *retlen, int estring)
 {
-	dTHX;
 	/* We are going to return a quote_bytea() for backwards compat but
 		 we warn first */
 	warn("Use of SQL_BINARY invalid in quote()");
-	return quote_bytea(string, len, retlen, estring);
+	return quote_bytea(aTHX_ string, len, retlen, estring);
 	
 }
 
 /* Return TRUE, FALSE, or throws an error */
-char * quote_bool(const char *value, STRLEN len, STRLEN *retlen, int estring) 
+char * quote_bool(pTHX_ const char *value, STRLEN len, STRLEN *retlen, int estring)
 {
-	dTHX;
 	char *result;
 	
 	/* Things that are true: t, T, 1, true, TRUE, 0E0, 0 but true */
@@ -299,9 +291,8 @@ char * quote_bool(const char *value, STRLEN len, STRLEN *retlen, int estring)
 	
 }
 
-char * quote_int(const char *string, STRLEN len, STRLEN *retlen, int estring)
+char * quote_int(pTHX_ const char *string, STRLEN len, STRLEN *retlen, int estring)
 {
-	dTHX;
 	char * result;
 
 	New(0, result, len+1, char);
@@ -320,9 +311,8 @@ char * quote_int(const char *string, STRLEN len, STRLEN *retlen, int estring)
 	return result;
 }
 
-char * quote_float(char *string, STRLEN len, STRLEN *retlen, int estring)
+char * quote_float(pTHX_ char *string, STRLEN len, STRLEN *retlen, int estring)
 {
-	dTHX;
 	char * result;
 
 	/* Empty string is always an error. Here for dumb compilers. */
@@ -359,9 +349,8 @@ char * quote_float(char *string, STRLEN len, STRLEN *retlen, int estring)
 	return result;
 }
 
-char * quote_name(const char *string, STRLEN len, STRLEN *retlen, int estring)
+char * quote_name(pTHX_ const char *string, STRLEN len, STRLEN *retlen, int estring)
 {
-	dTHX;
 	char * result;
 	const char *ptr;
 	int nquotes = 0;
@@ -424,17 +413,15 @@ char * quote_name(const char *string, STRLEN len, STRLEN *retlen, int estring)
 	return result;
 }
 
-void dequote_char(const char *string, STRLEN *retlen, int estring)
+void dequote_char(pTHX_ const char *string, STRLEN *retlen, int estring)
 {
-	dTHX;
 	/* TODO: chop_blanks if requested */
 	*retlen = strlen(string);
 }
 
 
-void dequote_string(const char *string, STRLEN *retlen, int estring)
+void dequote_string(pTHX_ const char *string, STRLEN *retlen, int estring)
 {
-	dTHX;
 	*retlen = strlen(string);
 }
 
@@ -442,7 +429,6 @@ void dequote_string(const char *string, STRLEN *retlen, int estring)
 
 static void _dequote_bytea_escape(char *string, STRLEN *retlen, int estring)
 {
-	dTHX;
 	char *result;
 
 	(*retlen) = 0;
@@ -480,7 +466,6 @@ static void _dequote_bytea_escape(char *string, STRLEN *retlen, int estring)
 
 static int _decode_hex_digit(char digit)
 {
-	dTHX;
 	if (digit >= '0' && digit <= '9')
 		return digit - '0';
 	if (digit >= 'a' && digit <= 'f')
@@ -493,7 +478,6 @@ static int _decode_hex_digit(char digit)
 
 static void _dequote_bytea_hex(char *string, STRLEN *retlen, int estring)
 {
-	dTHX;
 	char *result;
 
 	(*retlen) = 0;
@@ -515,9 +499,8 @@ static void _dequote_bytea_hex(char *string, STRLEN *retlen, int estring)
 	}
 }
 
-void dequote_bytea(char *string, STRLEN *retlen, int estring)
+void dequote_bytea(pTHX_ char *string, STRLEN *retlen, int estring)
 {
-	dTHX;
 
 	if (NULL != string) {
 		if ('\\' == *string && 'x' == *(string+1))
@@ -532,22 +515,20 @@ void dequote_bytea(char *string, STRLEN *retlen, int estring)
 	it might be nice to let people go the other way too. Say when talking
 	to something that uses SQL_BINARY
  */
-void dequote_sql_binary(char *string, STRLEN *retlen, int estring)
+void dequote_sql_binary(pTHX_ char *string, STRLEN *retlen, int estring)
 {
-	dTHX;
 
 	/* We are going to return a dequote_bytea(), just in case */
 	warn("Use of SQL_BINARY invalid in dequote()");
-	dequote_bytea(string, retlen, estring);
+	dequote_bytea(aTHX_ string, retlen, estring);
 
 	/* Put dequote_sql_binary function here at some point */
 }
 
 
 
-void dequote_bool(char *string, STRLEN *retlen, int estring)
+void dequote_bool(pTHX_ char *string, STRLEN *retlen, int estring)
 {
-	dTHX;
 
 	switch(*string){
 	case 'f': *string = '0'; break;
@@ -559,9 +540,8 @@ void dequote_bool(char *string, STRLEN *retlen, int estring)
 }
 
 
-void null_dequote(const char *string, STRLEN *retlen, int estring)
+void null_dequote(pTHX_ const char *string, STRLEN *retlen, int estring)
 {
-	dTHX;
 	*retlen = strlen(string);
 
 }
diff --git a/quote.h b/quote.h
index 56ac0c3..40e7609 100644
--- a/quote.h
+++ b/quote.h
@@ -1,20 +1,20 @@
 
-char * null_quote(const char *string, STRLEN len, STRLEN *retlen, int estring);
-char * quote_string(const char *string, STRLEN len, STRLEN *retlen, int estring);
-char * quote_bytea(char *string, STRLEN len, STRLEN *retlen, int estring);
-char * quote_sql_binary(char *string, STRLEN len, STRLEN *retlen, int estring);
-char * quote_bool(const char *string, STRLEN len, STRLEN *retlen, int estring);
-char * quote_integer(const char *string, STRLEN len, STRLEN *retlen, int estring);
-char * quote_int(const char *string, STRLEN len, STRLEN *retlen, int estring);
-char * quote_float(char *string, STRLEN len, STRLEN *retlen, int estring);
-char * quote_name(const char *string, STRLEN len, STRLEN *retlen, int estring);
-char * quote_geom(const char *string, STRLEN len, STRLEN *retlen, int estring);
-char * quote_path(const char *string, STRLEN len, STRLEN *retlen, int estring);
-char * quote_circle(const char *string, STRLEN len, STRLEN *retlen, int estring);
-void dequote_char(const char *string, STRLEN *retlen, int estring);
-void dequote_string(const char *string, STRLEN *retlen, int estring);
-void dequote_bytea(char *string, STRLEN *retlen, int estring);
-void dequote_sql_binary(char *string, STRLEN *retlen, int estring);
-void dequote_bool(char *string, STRLEN *retlen, int estring);
-void null_dequote(const char *string, STRLEN *retlen, int estring);
+char * null_quote(pTHX_ const char *string, STRLEN len, STRLEN *retlen, int estring);
+char * quote_string(pTHX_ const char *string, STRLEN len, STRLEN *retlen, int estring);
+char * quote_bytea(pTHX_ char *string, STRLEN len, STRLEN *retlen, int estring);
+char * quote_sql_binary(pTHX_ char *string, STRLEN len, STRLEN *retlen, int estring);
+char * quote_bool(pTHX_ const char *string, STRLEN len, STRLEN *retlen, int estring);
+char * quote_integer(pTHX_ const char *string, STRLEN len, STRLEN *retlen, int estring);
+char * quote_int(pTHX_ const char *string, STRLEN len, STRLEN *retlen, int estring);
+char * quote_float(pTHX_ char *string, STRLEN len, STRLEN *retlen, int estring);
+char * quote_name(pTHX_ const char *string, STRLEN len, STRLEN *retlen, int estring);
+char * quote_geom(pTHX_ const char *string, STRLEN len, STRLEN *retlen, int estring);
+char * quote_path(pTHX_ const char *string, STRLEN len, STRLEN *retlen, int estring);
+char * quote_circle(pTHX_ const char *string, STRLEN len, STRLEN *retlen, int estring);
+void dequote_char(pTHX_ const char *string, STRLEN *retlen, int estring);
+void dequote_string(pTHX_ const char *string, STRLEN *retlen, int estring);
+void dequote_bytea(pTHX_ char *string, STRLEN *retlen, int estring);
+void dequote_sql_binary(pTHX_ char *string, STRLEN *retlen, int estring);
+void dequote_bool(pTHX_ char *string, STRLEN *retlen, int estring);
+void null_dequote(pTHX_ const char *string, STRLEN *retlen, int estring);
 bool is_keyword(const char *string);
-- 
1.9.1

>From 7c06ccd368476acf82d3178a091e19e62ccf2a65 Mon Sep 17 00:00:00 2001
From: Nicholas Clark <[email protected]>
Date: Wed, 21 May 2014 11:15:34 +0200
Subject: [PATCH 2/2] Remove references to the interpreter struct in types.c -
 it's not used there.

---
 types.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/types.c b/types.c
index f18ebf6..08d1d2d 100644
--- a/types.c
+++ b/types.c
@@ -175,8 +175,6 @@ static sql_type_info_t pg_types[] = {
 
 sql_type_info_t* pg_type_data(int sql_type)
 {
-	dTHX;
-
 	switch(sql_type) {
 
 		case PG_ABSTIMEARRAY:       return &pg_types[0];
@@ -366,8 +364,6 @@ static sql_type_info_t sql_types[] = {
 
 sql_type_info_t* sql_type_data(int sql_type)
 {
-	dTHX;
-
 	switch(sql_type) {
 		case SQL_BOOLEAN:                      return &sql_types[0];
 		case SQL_CHAR:                         return &sql_types[1];
@@ -700,8 +696,6 @@ print $newfh "\};\n\n";
 print $newfh
 "sql_type_info_t* pg_type_data(int sql_type)
 {
-\tdTHX;
-
 \tswitch(sql_type) {
 \n";
 
@@ -728,7 +722,7 @@ for my $name (sort { $a cmp $b } keys %pgtype) {
 }
 print $newfh "\};\n\n";
 
-print $newfh "sql_type_info_t* sql_type_data(int sql_type)\n\{\n\tdTHX;\n\n";
+print $newfh "sql_type_info_t* sql_type_data(int sql_type)\n\{\n";
 
 print $newfh "\tswitch(sql_type) \{\n";
 for (sort { $pos{$a} <=> $pos{$b} } keys %pos) {
-- 
1.9.1

Reply via email to