GCC-3.4.6源代码学习笔记(3)

1.1.3. 树节点的内存分配

1.1.3.1.      节点大小的确定

树节点由下面的make_node函数来分配。函数中的参数code,在上面的表中给出,注意它也是由.def文件定义的。

 

202  tree

203  make_node (enum tree_code code)                                                                      in tree.c

204  {

205    tree t;

206    int type = TREE_CODE_CLASS (code);

207    size_t length;

208  #ifdef GATHER_STATISTICS

209    tree_node_kind kind;

210  #endif

211    struct tree_common ttmp;

212 

213   /* We can't allocate a TREE_VEC without knowing how many elements

214      it will have.  */

215    if (code == TREE_VEC)

216      abort ();

217 

218    TREE_SET_CODE ((tree)&ttmp, code);

219    length = tree_size ((tree)&ttmp);

 

在上面TREE_CODE_CLASS被定义如下,它获取要创建的树节点的类识别码。

 

54    #define TREE_CODE_CLASS(CODE)       tree_code_type[(int) (CODE)]                    in tree.h

 

对于C++tree_code_type包含以下文件的内容:其中文件tree.def通用于所有的语言,c-common.defC/C++使用,cp_tree.def则专用于C++。注意,DEFTREECODEtree_code_type前被重新定义,获取对应的域。

 

197  #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,

 

199  const char tree_code_type[] = {                                                                   in cp-lang.c

200  #include "tree.def"

201  'x',

202  #include "c-common.def"

203  'x',

204  #include "cp-tree.def"

205  };

 

下面,我们补上来自c-common.def的树节点的定义。它关注C/C++中的表达式和语句

Tree Code

 

Type

Description

SIZEOF_EXPR

1

 

ARROW_EXPR

1

 

ALIGNOF_EXPR

1

 

EXPR_STMT

e

用于表达式语句

COMPOUND_STMT

e

用于大括号对围起的代码块。节点中的操作数是COMPOUND_BODY节点

DECL_STMT

e

用于表示局部声明(local declaration

IF_STMT

e

表示if语句

FOR_STMT

e

表示for语句

WHILE_STMT

e

表示while语句

DO_STMT

e

表示do语句

RETURN_STMT

e

表示return语句

BREAK_STMT

e

表示break语句

CONTINUE_STMT

e

表示continue语句

SWITCH_STMT

e

表示switch语句

GOTO_STMT

e

表示goto语句

LABEL_STMT

e

表示label语句

ASM_STMT

e

表示内联的汇编代码

SCOPE_STMT

e

用于表示代码块的起始与结尾

FILE_STMT

e

表示当前源文件改变(换为另一文件)的点

CASE_LABEL

e

用于表示case语句中的标识(label

STMT_EXPR

e

用于复合表达式

COMPOUND_LITERAL_EXPR

e

用于C99复数

CLEANUP_STMT

e

用于记录对象被完全创建的点

3 c-common.def定义的树节点

在上面第218行,带有指定树节点码的伪节点被创建,它用于确定节点的真正大小。

 

12316 #define TREE_SET_CODE(NODE, VALUE) ((NODE)->common.code = (VALUE)) in tree.h

 

138  size_t

139  tree_size (tree node)                                                                                          in tree.c

140  {

141    enum tree_code code = TREE_CODE (node);

142 

143    switch (TREE_CODE_CLASS (code))

144    {

145      case 'd':  /* A decl node */

146        return sizeof (struct tree_decl);

147 

148      case 't':  /* a type node */

149        return sizeof (struct tree_type);

150 

151      case 'b':  /* a lexical block node */

152        return sizeof (struct tree_block);

153 

154      case 'r':  /* a reference */

155      case 'e':  /* an expression */

156      case 's':  /* an expression with side effects */

157      case '<':  /* a comparison expression */

158      case '1':  /* a unary arithmetic expression */

159      case '2':  /* a binary arithmetic expression */

160        return (sizeof (struct tree_exp)

161               + TREE_CODE_LENGTH (code) * sizeof (char *) - sizeof (char *));

162 

163      case 'c':  /* a constant */

164        switch (code)

165        {

166          case INTEGER_CST:     return sizeof (struct tree_int_cst);

167          case REAL_CST:           return sizeof (struct tree_real_cst);

168          case COMPLEX_CST:   return sizeof (struct tree_complex);

169          case VECTOR_CST:      return sizeof (struct tree_vector);

170          case STRING_CST:       return sizeof (struct tree_string);

171          default:

172            return (*lang_hooks.tree_size) (code);

173        }

174 

175      case 'x':  /* something random, like an identifier.  */

176        switch (code)

177        {

178          case IDENTIFIER_NODE:   return lang_hooks.identifier_size;

179          case TREE_LIST:          return sizeof (struct tree_list);

180          case TREE_VEC:          return (sizeof (struct tree_vec)

181                                     + TREE_VEC_LENGTH(node) * sizeof(char *)

182                                     - sizeof (char *));

183 

184          case ERROR_MARK:

185          case PLACEHOLDER_EXPR:      return sizeof (struct tree_common);

186 

187          default:

188            return (*lang_hooks.tree_size) (code);

189        }

190 

191      default:

192        abort ();

193    }

194  }

 

函数tree_size通用于所有的语言,如果语言提供了特定的节点类,正如我们前面提到的,必须把前端的钩子中的函数指针tree_size绑定到合适的函数,否则在172188行的调用会出问题。

1.1.3.2.      内存分配

确定要创建的树节点的大小后,make_node接着为其分配内存。这里忽略了收集统计数据的代码。

 

make_node (continue)

 

272    t = ggc_alloc_tree (length);

273 

274    memset (t, 0, length);

275 

276    TREE_SET_CODE (t, code);

277 

278    switch (type)

279    {

280      case 's':

281        TREE_SIDE_EFFECTS (t) = 1;

282        break;

283 

284      case 'd':

285        if (code != FUNCTION_DECL)

286          DECL_ALIGN (t) = 1;

287        DECL_USER_ALIGN (t) = 0;

288        DECL_IN_SYSTEM_HEADER (t) = in_system_header;

289        DECL_SOURCE_LOCATION (t) = input_location;

290        DECL_UID (t) = next_decl_uid++;

291 

292        /* We have not yet computed the alias set for this declaration.  */

293        DECL_POINTER_ALIAS_SET (t) = -1;

294        break;

295 

296      case 't':

297        TYPE_UID (t) = next_type_uid++;

298        TYPE_ALIGN (t) = char_type_node ? TYPE_ALIGN (char_type_node) : 0;

299        TYPE_USER_ALIGN (t) = 0;

300        TYPE_MAIN_VARIANT (t) = t;

301 

302        /* Default to no attributes for type, but let target change that.  */

303        TYPE_ATTRIBUTES (t) = NULL_TREE;

304        (*targetm.set_default_type_attributes) (t);

305 

306        /* We have not yet computed the alias set for this type.  */

307        TYPE_ALIAS_SET (t) = -1;

308        break;

309 

310      case 'c':

311        TREE_CONSTANT (t) = 1;

312        break;

313 

314      case 'e':

315        switch (code)

316        {

317          case INIT_EXPR:

318          case MODIFY_EXPR:

319          case VA_ARG_EXPR:

320          case RTL_EXPR:

321          case PREDECREMENT_EXPR:

322          case PREINCREMENT_EXPR:

323          case POSTDECREMENT_EXPR:

324          case POSTINCREMENT_EXPR:

325            /* All of these have side-effects, no matter what their

326              operands are.  */

327            TREE_SIDE_EFFECTS (t) = 1;

328            break;

329 

330          default:

331            break;

332        }

333        break;

334    }

335 

336    return t;

337  }

 

注意第274行的memset,因此所创建的节点是由0填充的。

 

你可能感兴趣的:(struct,vector,tree,Class,attributes,statistics)