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, §ion_size); + coltype->dequote(aTHX_ string, §ion_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
