Keep plperl's current_call_data record on the stack, instead of palloc'ing.
authorTom Lane
Thu, 13 Sep 2012 17:44:20 +0000 (13:44 -0400)
committerTom Lane
Thu, 13 Sep 2012 17:44:20 +0000 (13:44 -0400)
This at least saves some palloc overhead, and should furthermore reduce
the risk of anything going wrong, eg somebody resetting the context the
current_call_data record was in.

src/pl/plperl/plperl.c

index 2c39edac5bd93ca8b446aafb88a17e0b7a5088db..c1e81b4d0297ae74de91ab48fe5d14a33b2889df 100644 (file)
@@ -1705,10 +1705,15 @@ plperl_call_handler(PG_FUNCTION_ARGS)
    Datum       retval;
    plperl_call_data *save_call_data = current_call_data;
    plperl_interp_desc *oldinterp = plperl_active_interp;
+   plperl_call_data this_call_data;
+
+   /* Initialize current-call status record */
+   MemSet(&this_call_data, 0, sizeof(this_call_data));
+   this_call_data.fcinfo = fcinfo;
 
    PG_TRY();
    {
-       current_call_data = NULL;
+       current_call_data = &this_call_data;
        if (CALLED_AS_TRIGGER(fcinfo))
            retval = PointerGetDatum(plperl_trigger_handler(fcinfo));
        else
@@ -1716,16 +1721,16 @@ plperl_call_handler(PG_FUNCTION_ARGS)
    }
    PG_CATCH();
    {
-       if (current_call_data && current_call_data->prodesc)
-           decrement_prodesc_refcount(current_call_data->prodesc);
+       if (this_call_data.prodesc)
+           decrement_prodesc_refcount(this_call_data.prodesc);
        current_call_data = save_call_data;
        activate_interpreter(oldinterp);
        PG_RE_THROW();
    }
    PG_END_TRY();
 
-   if (current_call_data && current_call_data->prodesc)
-       decrement_prodesc_refcount(current_call_data->prodesc);
+   if (this_call_data.prodesc)
+       decrement_prodesc_refcount(this_call_data.prodesc);
    current_call_data = save_call_data;
    activate_interpreter(oldinterp);
    return retval;
@@ -1745,8 +1750,12 @@ plperl_inline_handler(PG_FUNCTION_ARGS)
    plperl_proc_desc desc;
    plperl_call_data *save_call_data = current_call_data;
    plperl_interp_desc *oldinterp = plperl_active_interp;
+   plperl_call_data this_call_data;
    ErrorContextCallback pl_error_context;
 
+   /* Initialize current-call status record */
+   MemSet(&this_call_data, 0, sizeof(this_call_data));
+
    /* Set up a callback for error reporting */
    pl_error_context.callback = plperl_inline_callback;
    pl_error_context.previous = error_context_stack;
@@ -1777,14 +1786,15 @@ plperl_inline_handler(PG_FUNCTION_ARGS)
    desc.nargs = 0;
    desc.reference = NULL;
 
+   this_call_data.fcinfo = &fake_fcinfo;
+   this_call_data.prodesc = &desc;
+   /* we do not bother with refcounting the fake prodesc */
+
    PG_TRY();
    {
        SV         *perlret;
 
-       current_call_data = (plperl_call_data *) palloc0(sizeof(plperl_call_data));
-       current_call_data->fcinfo = &fake_fcinfo;
-       current_call_data->prodesc = &desc;
-       /* we do not bother with refcounting the fake prodesc */
+       current_call_data = &this_call_data;
 
        if (SPI_connect() != SPI_OK_CONNECT)
            elog(ERROR, "could not connect to SPI manager");
@@ -2167,13 +2177,6 @@ plperl_func_handler(PG_FUNCTION_ARGS)
    ReturnSetInfo *rsi;
    ErrorContextCallback pl_error_context;
 
-   /*
-    * Create the call_data before connecting to SPI, so that it is not
-    * allocated in the SPI memory context
-    */
-   current_call_data = (plperl_call_data *) palloc0(sizeof(plperl_call_data));
-   current_call_data->fcinfo = fcinfo;
-
    if (SPI_connect() != SPI_OK_CONNECT)
        elog(ERROR, "could not connect to SPI manager");
 
@@ -2286,13 +2289,6 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
    HV         *hvTD;
    ErrorContextCallback pl_error_context;
 
-   /*
-    * Create the call_data before connecting to SPI, so that it is not
-    * allocated in the SPI memory context
-    */
-   current_call_data = (plperl_call_data *) palloc0(sizeof(plperl_call_data));
-   current_call_data->fcinfo = fcinfo;
-
    /* Connect to SPI manager */
    if (SPI_connect() != SPI_OK_CONNECT)
        elog(ERROR, "could not connect to SPI manager");