Movatterモバイル変換


[0]ホーム

URL:


Next:, Up:Memory Management and Type Information   [Contents][Index]


22.1 The Inside of aGTY(())

Sometimes the C code is not enough to fully describe the typestructure. Extra information can be provided withGTY optionsand additional markers. Some options take a parameter, which may beeither a string or a type name, depending on the parameter. If anoption takes no parameter, it is acceptable either to omit theparameter entirely, or to provide an empty string as a parameter. Forexample,GTY ((skip)) andGTY ((skip (""))) areequivalent.

When the parameter is a string, often it is a fragment of C code. Fourspecial escapes may be used in these strings, to refer to pieces ofthe data structure being marked:

%h

The current structure.

%1

The structure that immediately contains the current structure.

%0

The outermost structure that contains the current structure.

%a

A partial expression of the form[i1][i2]… that indexesthe array item currently being marked.

For instance, suppose that you have a structure of the form

struct A {  …};struct B {  struct A foo[12];};

andb is a variable of typestruct B. When marking‘b.foo[11]’,%h would expand to ‘b.foo[11]’,%0 and%1 would both expand to ‘b’, and%awould expand to ‘[11]’.

As in ordinary C, adjacent strings will be concatenated; this ishelpful when you have a complicated expression.

GTY ((chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE"                  " ? TYPE_NEXT_VARIANT (&%h.generic)"                  " : TREE_CHAIN (&%h.generic)")))

The available options are:

length ("expression")

There are two places the type machinery will need to be explicitly toldthe length of an array of non-atomic objects. The first case is when astructure ends in a variable-length array, like this:

struct GTY(()) rtvec_def {  int num_elem;         /*number of elements */  rtx GTY ((length ("%h.num_elem"))) elem[1];};

In this case, thelength option is used to override the specifiedarray length (which should usually be1). The parameter of theoption is a fragment of C code that calculates the length.

The second case is when a structure or a global variable contains apointer to an array, like this:

struct gimple_omp_for_iter * GTY((length ("%h.collapse"))) iter;

In this case,iter has been allocated by writing something like

  x->iter = ggc_alloc_cleared_vec_gimple_omp_for_iter (collapse);

and thecollapse provides the length of the field.

This second use oflength also works on global variables, like:

static GTY((length("reg_known_value_size"))) rtx *reg_known_value;

Note that thelength option is only meant for use with arrays ofnon-atomic objects, that is, objects that contain pointers pointing toother GTY-managed objects. For other GC-allocated arrays and stringsyou should useatomic orstring_length.

string_length ("expression")

In order to simplify production of PCH, a structure member that is a plainarray of bytes (an optionallyconst and/orunsignedchar*) is treated specially by the infrastructure. Even if such an array has notbeen allocated in GC-controlled memory, it will still be written properly intoa PCH. The machinery responsible for this needs to know the length of thedata; by default, the length is determined by callingstrlen on thepointer. Thestring_length option specifies an alternate way todetermine the length, such as by inspecting another struct member:

struct GTY(()) non_terminated_string {  size_t sz;  const char * GTY((string_length ("%h.sz"))) data;};

Similarly, this is useful for (regular NUL-terminated) strings withNUL characters embedded (that the defaultstrlen use would runafoul of):

struct GTY(()) multi_string {  const char * GTY((string_length ("%h.len + 1"))) str;  size_t len;};

Thestring_length option currently is not supported for (fieldsin) global variables.

skip

Ifskip is applied to a field, the type machinery will ignore it.This is somewhat dangerous; the only safe use is in a union when onefield really isn’t ever used.

callback

callback should be applied to fields with pointer to function typeand causes the field to be ignored similarly toskip, except whenwriting PCH and the field is non-NULL it will remember the field’s addressfor relocation purposes if the process writing PCH has different load basefrom a process reading PCH.

for_user

Use this to mark types that need to be marked by user gc routines, but are notrefered to in a template argument. So if you have some user gc type T1 and anon user gc type T2 you can give T2 the for_user option so that the markingfunctions for T1 can call non mangled functions to mark T2.

desc ("expression")
tag ("constant")
default

The type machinery needs to be told which field of aunion iscurrently active. This is done by giving each field a constanttag value, and then specifying a discriminator usingdesc.The value of the expression given bydesc is compared againsteachtag value, each of which should be different. If notag is matched, the field marked withdefault is used ifthere is one, otherwise no field in the union will be marked.

In thedesc option, the “current structure” is the union thatit discriminates. Use%1 to mean the structure containing it.There are no escapes available to thetag option, since it is aconstant.

For example,

struct GTY(()) tree_binding{  struct tree_common common;  union tree_binding_u {    tree GTY ((tag ("0"))) scope;    struct cp_binding_level * GTY ((tag ("1"))) level;  } GTY ((desc ("BINDING_HAS_LEVEL_P ((tree)&%0)"))) xscope;  tree value;};

In this example, the value of BINDING_HAS_LEVEL_P when applied to astruct tree_binding * is presumed to be 0 or 1. If 1, the typemechanism will treat the fieldlevel as being present and if 0,will treat the fieldscope as being present.

Thedesc andtag options can also be used for inheritanceto denote which subclass an instance is. SeeSupport for inheritancefor more information.

cache

When thecache option is applied to a global variable gt_cleare_cache iscalled on that variable between the mark and sweep phases of garbagecollection. The gt_clear_cache function is free to mark blocks as used, or toclear pointers in the variable.

In a hash table, the ‘gt_cleare_cache’ function discards entriesif the key is not marked, or marks the value if the key is marked.

Note that caches should generally usedeletable instead;cache is only preferable if the value is impractical torecompute from the key when needed.

Thecache option can have an optional argument, name of the functionwhich should be called before ‘gt_cleare_cache’. This can be usefulif the hash table needs to be traversed and mark some pointers before‘gt_cleare_cache’ could clear slots in it.

deletable

deletable, when applied to a global variable, indicates that whengarbage collection runs, there’s no need to mark anything pointed toby this variable, it can just be set toNULL instead. This is usedto keep a list of free structures around for re-use.

maybe_undef

When applied to a field,maybe_undef indicates that it’s OK ifthe structure that this fields points to is never defined, so long asthis field is alwaysNULL. This is used to avoid requiringbackends to define certain optional structures. It doesn’t work withlanguage frontends.

nested_ptr (type, "to expression", "from expression")

The type machinery expects all pointers to point to the start of anobject. Sometimes for abstraction purposes it’s convenient to havea pointer which points inside an object. So long as it’s possible toconvert the original object to and from the pointer, such pointerscan still be used.type is the type of the original object,theto expression returns the pointer given the original object,and thefrom expression returns the original object giventhe pointer. The pointer will be available using the%hescape.

chain_next ("expression")
chain_prev ("expression")
chain_circular ("expression")

It’s helpful for the type machinery to know if objects are oftenchained together in long lists; this lets it generate code that usesless stack space by iterating along the list instead of recursing downit.chain_next is an expression for the next item in the list,chain_prev is an expression for the previous item. For singlylinked lists, use onlychain_next; for doubly linked lists, useboth. The machinery requires that taking the next item of theprevious item gives the original item.chain_circular is similartochain_next, but can be used for circular single linked lists.

reorder ("function name")

Some data structures depend on the relative ordering of pointers. Ifthe precompiled header machinery needs to change that ordering, itwill call the function referenced by thereorder option, beforechanging the pointers in the object that’s pointed to by the field theoption applies to. The function must take four arguments, with thesignature ‘void *, void *, gt_pointer_operator, void *’.The first parameter is a pointer to the structure that contains theobject being updated, or the object itself if there is no containingstructure. The second parameter is a cookie that should be ignored.The third parameter is a routine that, given a pointer, will update itto its correct new value. The fourth parameter is a cookie that mustbe passed to the second parameter.

PCH cannot handle data structures that depend on the absolute valuesof pointers.reorder functions can be expensive. Whenpossible, it is better to depend on properties of the data, like an IDnumber or the hash of a string instead.

atomic

Theatomic option can only be used with pointers. It informsthe GC machinery that the memory that the pointer points to does notcontain any pointers, and hence it should be treated by the GC and PCHmachinery as an “atomic” block of memory that does not need to beexamined when scanning memory for pointers. In particular, themachinery will not scan that memory for pointers to mark them asreachable (when marking pointers for GC) or to relocate them (whenwriting a PCH file).

Theatomic option differs from theskip option.atomic keeps the memory under Garbage Collection, but makes theGC ignore the contents of the memory.skip is more drastic inthat it causes the pointer and the memory to be completely ignored bythe Garbage Collector. So, memory marked asatomic isautomatically freed when no longer reachable, while memory marked asskip is not.

Theatomic option must be used with great care, because allsorts of problem can occur if used incorrectly, that is, if the memorythe pointer points to does actually contain a pointer.

Here is an example of how to use it:

struct GTY(()) my_struct {  int number_of_elements;  unsigned int * GTY ((atomic)) elements;};

In this case,elements is a pointer under GC, and the memory itpoints to needs to be allocated using the Garbage Collector, and willbe freed automatically by the Garbage Collector when it is no longerreferenced. But the memory that the pointer points to is an array ofunsigned int elements, and the GC must not try to scan it tofind pointers to mark or relocate, which is why it is marked with theatomic option.

Note that, currently, global variables cannot be marked withatomic; only fields of a struct can. This is a knownlimitation. It would be useful to be able to mark global pointerswithatomic to make the PCH machinery aware of them so thatthey are saved and restored correctly to PCH files.

special ("name")

Thespecial option is used to mark types that have to be dealtwith by special case machinery. The parameter is the name of thespecial case. Seegengtype.cc for further details. Avoidadding new special cases unless there is no other alternative.

user

Theuser option indicates that the code to mark structurefields is completely handled by user-provided routines. See sectionSupport for user-provided GC marking routines for details on what functions need to be provided.


Next:Support for inheritance, Up:Memory Management and Type Information   [Contents][Index]


[8]ページ先頭

©2009-2026 Movatter.jp