Путеводитель по Руководству Linux

  User  |  Syst  |  Libr  |  Device  |  Files  |  Other  |  Admin  |  Head  |



   pcrejit    ( 3 )

Perl-совместимые регулярные выражения (Perl-compatible regular expressions)

CONTROLLING THE JIT STACK

When the compiled JIT code runs, it needs a block of memory to use as a stack. By default, it uses 32K on the machine stack. However, some large or complicated patterns need more than this. The error PCRE_ERROR_JIT_STACKLIMIT is given when there is not enough stack. Three functions are provided for managing blocks of memory for use as JIT stacks. There is further discussion about the use of JIT stacks in the section entitled "JIT stack FAQ" below.

The pcre_jit_stack_alloc() function creates a JIT stack. Its arguments are a starting size and a maximum size, and it returns a pointer to an opaque structure of type pcre_jit_stack, or NULL if there is an error. The pcre_jit_stack_free() function can be used to free a stack that is no longer needed. (For the technically minded: the address space is allocated by mmap or VirtualAlloc.)

JIT uses far less memory for recursion than the interpretive code, and a maximum stack size of 512K to 1M should be more than enough for any pattern.

The pcre_assign_jit_stack() function specifies which stack JIT code should use. Its arguments are as follows:

pcre_extra *extra pcre_jit_callback callback void *data

The extra argument must be the result of studying a pattern with PCRE_STUDY_JIT_COMPILE etc. There are three cases for the values of the other two options:

(1) If callback is NULL and data is NULL, an internal 32K block on the machine stack is used.

(2) If callback is NULL and data is not NULL, data must be a valid JIT stack, the result of calling pcre_jit_stack_alloc().

(3) If callback is not NULL, it must point to a function that is called with data as an argument at the start of matching, in order to set up a JIT stack. If the return from the callback function is NULL, the internal 32K stack is used; otherwise the return value must be a valid JIT stack, the result of calling pcre_jit_stack_alloc().

A callback function is obeyed whenever JIT code is about to be run; it is not obeyed when pcre_exec() is called with options that are incompatible for JIT execution. A callback function can therefore be used to determine whether a match operation was executed by JIT or by the interpreter.

You may safely use the same JIT stack for more than one pattern (either by assigning directly or by callback), as long as the patterns are all matched sequentially in the same thread. In a multithread application, if you do not specify a JIT stack, or if you assign or pass back NULL from a callback, that is thread- safe, because each thread has its own machine stack. However, if you assign or pass back a non-NULL JIT stack, this must be a different stack for each thread so that the application is thread-safe.

Strictly speaking, even more is allowed. You can assign the same non-NULL stack to any number of patterns as long as they are not used for matching by multiple threads at the same time. For example, you can assign the same stack to all compiled patterns, and use a global mutex in the callback to wait until the stack is available for use. However, this is an inefficient solution, and not recommended.

This is a suggestion for how a multithreaded program that needs to set up non-default JIT stacks might operate:

During thread initialization thread_local_var = pcre_jit_stack_alloc(...)

During thread exit pcre_jit_stack_free(thread_local_var)

Use a one-line callback function return thread_local_var

All the functions described in this section do nothing if JIT is not available, and pcre_assign_jit_stack() does nothing unless the extra argument is non-NULL and points to a pcre_extra block that is the result of a successful study with PCRE_STUDY_JIT_COMPILE etc.