From: Reini Urban on
Immediately after I released B-C-1.27
http://search.cpan.org/dist/B-C/
I added two new compiler optimizations to svn
http://code.google.com/p/perl-compiler/source/detail?r=498

-fro-inc read-only strings of @INC, %INC entries and
global curpad names and symbols
assuming that nobody wants to change those names and paths at run-time

and -fno-destruct - no perl_destruct
which leaves the optree and sv data cleanup to exit.

There's no need in single process to cleanup by ourselves.
But this is tricky, since perl_destruct does only the destruction, but
much more.
But I want it desperately, since copy-on-grow on strings cannot be used
since 5.10 because there are no flags for hek's which let the compiler
skip static hek's. (as it was supported until 5.10).
That means all hek strings have to be allocated at run-time, which is
slow. With -no-destruct -fcog (copy-on-grow) can be enabled again.

copy-on-grow: we start with static strings, and once someone wants to
extend it, we realloc it to the heap.

We save a lot of time with static init, but we loose a lot of time with
run-time destruct.

What is needed and what does perl_destruct really do?
DESTROY hooks? hmm, this would mean to run through all the sv's and
check for DESTROY hooks.
END blocks? call_list(PL_scopestack_ix, PL_endav) looks like so.
IO teardown for sure.
thread cancellation for sure.

e.g. without perl_destruct perl -e'print "bla"' would not print anything.

This is my current attempt:
int fast_perl_destruct( PerlInterpreter *my_perl ) {
dVAR;
VOL signed char destruct_level; /* see possible values in
intrpvar.h */
HV *hv;
#ifdef DEBUG_LEAKING_SCALARS_FORK_DUMP
pid_t child;
#endif

PERL_ARGS_ASSERT_PERL_DESTRUCT;
#ifndef MULTIPLICITY
PERL_UNUSED_ARG(my_perl);
#endif

assert(PL_scopestack_ix == 1);

/* wait for all pseudo-forked children to finish */
PERL_WAIT_FOR_CHILDREN;

destruct_level = PL_perl_destruct_level;
#ifdef DEBUGGING
{
const char * const s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL");
if (s) {
const int i = atoi(s);
if (destruct_level < i)
destruct_level = i;
}
}
#endif

if (PL_exit_flags & PERL_EXIT_DESTRUCT_END) {
dJMPENV;
int x = 0;

JMPENV_PUSH(x);
PERL_UNUSED_VAR(x);
if (PL_endav && !PL_minus_c)
call_list(PL_scopestack_ix, PL_endav);
JMPENV_POP;
}
LEAVE;
FREETMPS;
assert(PL_scopestack_ix == 0);

/* Need to flush since END blocks can produce output */
my_fflush_all();

if (CALL_FPTR(PL_threadhook)(aTHX)) {
/* Threads hook has vetoed further cleanup */
PL_veto_cleanup = TRUE;
return STATUS_EXIT;
}
PerlIO_destruct(aTHX);
}

--
Reini