Mercurial > hg > truffle
annotate src/share/vm/adlc/forms.hpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
624
diff
changeset
|
2 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
624
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
624
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
624
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 // FORMS.HPP - ADL Parser Generic and Utility Forms Classes | |
26 | |
27 #define TRUE 1 | |
28 #define FALSE 0 | |
29 | |
30 // DEFINITIONS OF LEGAL ATTRIBUTE TYPES | |
31 #define INS_ATTR 0 | |
32 #define OP_ATTR 1 | |
33 | |
34 // DEFINITIONS OF LEGAL CONSTRAINT TYPES | |
35 | |
36 // Class List | |
37 class Form; | |
38 class InstructForm; | |
39 class MachNodeForm; | |
40 class OperandForm; | |
41 class OpClassForm; | |
42 class AttributeForm; | |
43 class RegisterForm; | |
44 class PipelineForm; | |
45 class SourceForm; | |
46 class EncodeForm; | |
47 class Component; | |
48 class Constraint; | |
49 class Predicate; | |
50 class MatchRule; | |
51 class Attribute; | |
52 class Effect; | |
53 class ExpandRule; | |
54 class RewriteRule; | |
55 class ConstructRule; | |
56 class FormatRule; | |
57 class Peephole; | |
58 class EncClass; | |
59 class Interface; | |
60 class RegInterface; | |
61 class ConstInterface; | |
62 class MemInterface; | |
63 class CondInterface; | |
64 class Opcode; | |
65 class InsEncode; | |
66 class RegDef; | |
67 class RegClass; | |
68 class AllocClass; | |
69 class ResourceForm; | |
70 class PipeClassForm; | |
71 class PeepMatch; | |
72 class PeepConstraint; | |
73 class PeepReplace; | |
74 class MatchList; | |
75 | |
76 class ArchDesc; | |
77 | |
78 //------------------------------FormDict--------------------------------------- | |
79 // Dictionary containing Forms, and objects derived from forms | |
80 class FormDict { | |
81 private: | |
82 Dict _form; // map names, char*, to their Form* or NULL | |
83 | |
84 // Disable public use of constructor, copy-ctor, operator =, operator == | |
85 FormDict( ); | |
86 FormDict &operator =( const FormDict & ); | |
87 // == compares two dictionaries; they must have the same keys (their keys | |
88 // must match using CmpKey) and they must have the same values (pointer | |
89 // comparison). If so 1 is returned, if not 0 is returned. | |
90 bool operator ==(const FormDict &d) const; // Compare dictionaries for equal | |
91 | |
92 public: | |
93 // cmp is a key comparision routine. hash is a routine to hash a key. | |
94 // FormDict( CmpKey cmp, Hash hash ); | |
95 FormDict( CmpKey cmp, Hash hash, Arena *arena ); | |
96 FormDict( const FormDict & fd ); // Deep-copy guts | |
97 ~FormDict(); | |
98 | |
99 // Return # of key-value pairs in dict | |
100 int Size(void) const; | |
101 | |
102 // Insert inserts the given key-value pair into the dictionary. The prior | |
103 // value of the key is returned; NULL if the key was not previously defined. | |
104 const Form *Insert(const char *name, Form *form); // A new key-value | |
105 | |
106 // Find finds the value of a given key; or NULL if not found. | |
107 // The dictionary is NOT changed. | |
108 const Form *operator [](const char *name) const; // Do a lookup | |
109 | |
110 void dump(); | |
111 }; | |
112 | |
113 // ***** Master Class for ADL Parser Forms ***** | |
114 //------------------------------Form------------------------------------------- | |
115 class Form { | |
116 public: | |
117 static Arena *arena; // arena used by forms | |
118 private: | |
119 static Arena *generate_arena(); // allocate arena used by forms | |
120 | |
121 protected: | |
122 int _ftype; // Indicator for derived class type | |
123 | |
124 public: | |
125 // Public Data | |
126 Form *_next; // Next pointer for form lists | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
415
diff
changeset
|
127 int _linenum; // Line number for debugging |
0 | 128 |
129 // Dynamic type check for common forms. | |
130 virtual OpClassForm *is_opclass() const; | |
131 virtual OperandForm *is_operand() const; | |
132 virtual InstructForm *is_instruction() const; | |
133 virtual MachNodeForm *is_machnode() const; | |
134 virtual AttributeForm *is_attribute() const; | |
135 virtual Effect *is_effect() const; | |
136 virtual ResourceForm *is_resource() const; | |
137 virtual PipeClassForm *is_pipeclass() const; | |
138 | |
139 // Check if this form is an operand usable for cisc-spilling | |
140 virtual bool is_cisc_reg(FormDict &globals) const { return false; } | |
141 virtual bool is_cisc_mem(FormDict &globals) const { return false; } | |
142 | |
143 // Public Methods | |
144 Form(int formType=0, int line=0) | |
145 : _next(NULL), _linenum(line), _ftype(formType) { }; | |
146 ~Form() {}; | |
147 | |
148 virtual bool ideal_only() const { | |
149 assert(0,"Check of ideal status on non-instruction/operand form.\n"); | |
150 return FALSE; | |
151 } | |
152 | |
153 // Check constraints after parsing | |
154 virtual bool verify() { return true; } | |
155 | |
156 virtual void dump() { output(stderr); } // Debug printer | |
157 // Write info to output files | |
158 virtual void output(FILE *fp) { fprintf(fp,"Form Output"); } | |
159 | |
160 public: | |
161 // ADLC types, match the last character on ideal operands and instructions | |
162 enum DataType { | |
163 none = 0, // Not a simple type | |
164 idealI = 1, // Integer type | |
165 idealP = 2, // Pointer types, oop(s) | |
166 idealL = 3, // Long type | |
167 idealF = 4, // Float type | |
168 idealD = 5, // Double type | |
169 idealB = 6, // Byte type | |
170 idealC = 7, // Char type | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
171 idealS = 8, // String type |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
172 idealN = 9 // Narrow oop types |
0 | 173 }; |
174 // Convert ideal name to a DataType, return DataType::none if not a 'ConX' | |
175 Form::DataType ideal_to_const_type(const char *ideal_type_name) const; | |
176 // Convert ideal name to a DataType, return DataType::none if not a 'sRegX | |
177 Form::DataType ideal_to_sReg_type(const char *name) const; | |
178 // Convert ideal name to a DataType, return DataType::none if not a 'RegX | |
179 Form::DataType ideal_to_Reg_type(const char *name) const; | |
180 | |
181 // Convert ideal name to a DataType, return DataType::none if not a 'LoadX | |
182 Form::DataType is_load_from_memory(const char *opType) const; | |
183 // Convert ideal name to a DataType, return DataType::none if not a 'StoreX | |
184 Form::DataType is_store_to_memory(const char *opType) const; | |
185 | |
186 // ADLC call types, matched with ideal world | |
187 enum CallType { | |
188 invalid_type = 0, // invalid call type | |
189 JAVA_STATIC = 1, // monomorphic entry | |
190 JAVA_DYNAMIC = 2, // possibly megamorphic, inline cache call | |
191 JAVA_COMPILED = 3, // callee will be compiled java | |
192 JAVA_INTERP = 4, // callee will be executed by interpreter | |
193 JAVA_NATIVE = 5, // native entrypoint | |
194 JAVA_RUNTIME = 6, // runtime entrypoint | |
195 JAVA_LEAF = 7 // calling leaf | |
196 }; | |
197 | |
198 // Interface types for operands and operand classes | |
199 enum InterfaceType { | |
200 no_interface = 0, // unknown or inconsistent interface type | |
201 constant_interface = 1, // interface to constants | |
202 register_interface = 2, // interface to registers | |
203 memory_interface = 3, // interface to memory | |
204 conditional_interface = 4 // interface for condition codes | |
205 }; | |
206 virtual Form::InterfaceType interface_type(FormDict &globals) const; | |
207 | |
208 enum CiscSpillInfo { | |
209 Not_cisc_spillable = AdlcVMDeps::Not_cisc_spillable, | |
210 Maybe_cisc_spillable = 0, | |
211 Is_cisc_spillable = 1 | |
212 // ... | |
213 }; | |
214 | |
215 // LEGAL FORM TYPES | |
216 enum { | |
217 INS, | |
218 OPER, | |
219 OPCLASS, | |
220 SRC, | |
221 ADEF, | |
222 REG, | |
223 PIPE, | |
224 CNST, | |
225 PRED, | |
226 ATTR, | |
227 MAT, | |
228 ENC, | |
229 FOR, | |
230 EXP, | |
231 REW, | |
232 EFF, | |
233 RDEF, | |
234 RCL, | |
235 ACL, | |
236 RES, | |
237 PCL, | |
238 PDEF, | |
239 REGL, | |
240 RESL, | |
241 STAL, | |
242 COMP, | |
243 PEEP, | |
244 RESO | |
245 }; | |
246 | |
247 }; | |
248 | |
249 //------------------------------FormList--------------------------------------- | |
250 class FormList { | |
251 private: | |
252 Form *_root; | |
253 Form *_tail; | |
254 Form *_cur; | |
255 int _justReset; // Set immediately after reset | |
256 Form *_cur2; // Nested iterator | |
257 int _justReset2; | |
258 | |
259 public: | |
260 void addForm(Form * entry) { | |
261 if (_tail==NULL) { _root = _tail = _cur = entry;} | |
262 else { _tail->_next = entry; _tail = entry;} | |
263 }; | |
264 Form * current() { return _cur; }; | |
265 Form * iter() { if (_justReset) _justReset = 0; | |
266 else if (_cur) _cur = _cur->_next; | |
267 return _cur;}; | |
268 void reset() { if (_root) {_cur = _root; _justReset = 1;} }; | |
269 | |
270 // Second iterator, state is internal | |
271 Form * current2(){ return _cur2; }; | |
272 Form * iter2() { if (_justReset2) _justReset2 = 0; | |
273 else if (_cur2) _cur2 = _cur2->_next; | |
274 return _cur2;}; | |
275 void reset2() { if (_root) {_cur2 = _root; _justReset2 = 1;} }; | |
276 | |
277 int count() { | |
278 int count = 0; reset(); | |
279 for( Form *cur; (cur = iter()) != NULL; ) { ++count; }; | |
280 return count; | |
281 } | |
282 | |
283 void dump() { | |
284 reset(); | |
285 Form *cur; | |
286 for(; (cur = iter()) != NULL; ) { | |
287 cur->dump(); | |
288 }; | |
289 } | |
290 | |
291 bool verify() { | |
292 bool verified = true; | |
293 | |
294 reset(); | |
295 Form *cur; | |
296 for(; (cur = iter()) != NULL; ) { | |
297 if ( ! cur->verify() ) verified = false; | |
298 }; | |
299 | |
300 return verified; | |
301 } | |
302 | |
303 void output(FILE* fp) { | |
304 reset(); | |
305 Form *cur; | |
306 for( ; (cur = iter()) != NULL; ) { | |
307 cur->output(fp); | |
308 }; | |
309 } | |
310 | |
311 FormList() { _justReset = 1; _justReset2 = 1; _root = NULL; _tail = NULL; _cur = NULL; _cur2 = NULL;}; | |
312 ~FormList(); | |
313 }; | |
314 | |
315 //------------------------------NameList--------------------------------------- | |
316 // Extendable list of pointers, <char *> | |
317 class NameList { | |
318 friend class PreserveIter; | |
319 | |
320 private: | |
321 int _cur; // Insert next entry here; count of entries | |
322 int _max; // Number of spaces allocated | |
323 const char **_names; // Array of names | |
324 | |
325 protected: | |
326 int _iter; // position during iteration | |
327 bool _justReset; // Set immediately after reset | |
328 | |
329 | |
330 public: | |
331 static const char *_signal; // reserved user-defined string | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
196
diff
changeset
|
332 static const char *_signal2; // reserved user-defined string |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
196
diff
changeset
|
333 static const char *_signal3; // reserved user-defined string |
0 | 334 enum { Not_in_list = -1 }; |
335 | |
336 void addName(const char *name); | |
337 void add_signal(); | |
338 void clear(); // Remove all entries | |
339 | |
340 int count() const; | |
341 | |
342 void reset(); // Reset iteration | |
343 const char *iter(); // after reset(), first element : else next | |
344 const char *current(); // return current element in iteration. | |
624 | 345 const char *peek(int skip = 1); // returns element + skip in iteration if there is one |
0 | 346 |
347 bool current_is_signal(); // Return 'true' if current entry is signal | |
348 bool is_signal(const char *entry); // Return true if entry is a signal | |
349 | |
350 bool search(const char *); // Search for a name in the list | |
351 int index(const char *); // Return index of name in list | |
352 const char *name (intptr_t index);// Return name at index in list | |
353 | |
354 void dump(); // output to stderr | |
355 void output(FILE *fp); // Output list of names to 'fp' | |
356 | |
357 NameList(); | |
358 ~NameList(); | |
359 }; | |
360 | |
361 | |
362 // Convenience class to preserve iteration state since iterators are | |
363 // internal instead of being external. | |
364 class PreserveIter { | |
365 private: | |
366 NameList* _list; | |
367 int _iter; | |
368 bool _justReset; | |
369 | |
370 public: | |
371 PreserveIter(NameList* nl) { | |
372 _list = nl; | |
373 _iter = _list->_iter; | |
374 _justReset = _list->_justReset; | |
375 } | |
376 ~PreserveIter() { | |
377 _list->_iter = _iter; | |
378 _list->_justReset = _justReset; | |
379 } | |
380 | |
381 }; | |
382 | |
383 | |
384 //------------------------------NameAndList------------------------------------ | |
385 // Storage for a name and an associated list of names | |
386 class NameAndList { | |
387 private: | |
388 const char *_name; | |
389 NameList _list; | |
390 | |
391 public: | |
392 NameAndList(char *name); | |
393 ~NameAndList(); | |
394 | |
395 // Add to entries in list | |
396 void add_entry(const char *entry); | |
397 | |
398 // Access the name and its associated list. | |
399 const char *name() const; | |
400 void reset(); | |
401 const char *iter(); | |
402 | |
403 int count() { return _list.count(); } | |
404 | |
405 // Return the "index" entry in the list, zero-based | |
406 const char *operator[](int index); | |
407 | |
408 | |
409 void dump(); // output to stderr | |
410 void output(FILE *fp); // Output list of names to 'fp' | |
411 }; | |
412 | |
413 //------------------------------ComponentList--------------------------------- | |
414 // Component lists always have match rule operands first, followed by parameter | |
415 // operands which do not appear in the match list (in order of declaration). | |
416 class ComponentList : private NameList { | |
417 private: | |
418 int _matchcnt; // Count of match rule operands | |
419 | |
420 public: | |
421 | |
422 // This is a batch program. (And I have a destructor bug!) | |
423 void operator delete( void *ptr ) {} | |
424 | |
425 void insert(Component *component, bool mflag); | |
426 void insert(const char *name, const char *opType, int usedef, bool mflag); | |
427 | |
428 int count(); | |
429 int match_count() { return _matchcnt; } // Get count of match rule opers | |
430 | |
431 Component *iter(); // after reset(), first element : else next | |
432 Component *match_iter(); // after reset(), first element : else next | |
433 Component *post_match_iter(); // after reset(), first element : else next | |
434 void reset(); // Reset iteration | |
435 Component *current(); // return current element in iteration. | |
436 | |
437 // Return element at "position", else NULL | |
438 Component *operator[](int position); | |
439 Component *at(int position) { return (*this)[position]; } | |
440 | |
441 // Return first component having this name. | |
442 const Component *search(const char *name); | |
443 | |
444 // Return number of USEs + number of DEFs | |
445 int num_operands(); | |
446 // Return zero-based position in list; -1 if not in list. | |
447 int operand_position(const char *name, int usedef); | |
448 // Find position for this name, regardless of use/def information | |
449 int operand_position(const char *name); | |
450 // Find position for this name when looked up for output via "format" | |
451 int operand_position_format(const char *name); | |
452 // Find position for the Label when looked up for output via "format" | |
453 int label_position(); | |
454 // Find position for the Method when looked up for output via "format" | |
455 int method_position(); | |
456 | |
457 void dump(); // output to stderr | |
458 void output(FILE *fp); // Output list of names to 'fp' | |
459 | |
460 ComponentList(); | |
461 ~ComponentList(); | |
462 }; | |
463 | |
464 //------------------------------SourceForm------------------------------------- | |
465 class SourceForm : public Form { | |
466 private: | |
467 | |
468 public: | |
469 // Public Data | |
470 char *_code; // Buffer for storing code text | |
471 | |
472 // Public Methods | |
473 SourceForm(char* code); | |
474 ~SourceForm(); | |
475 | |
476 virtual const char* classname() { return "SourceForm"; } | |
477 | |
478 void dump(); // Debug printer | |
479 void output(FILE *fp); // Write output files | |
480 }; | |
481 | |
482 class HeaderForm : public SourceForm { | |
483 public: | |
484 HeaderForm(char* code) : SourceForm(code) { } | |
485 | |
486 virtual const char* classname() { return "HeaderForm"; } | |
487 }; | |
488 | |
489 class PreHeaderForm : public SourceForm { | |
490 public: | |
491 PreHeaderForm(char* code) : SourceForm(code) { } | |
492 | |
493 virtual const char* classname() { return "PreHeaderForm"; } | |
494 }; | |
495 | |
496 | |
497 | |
498 | |
499 //------------------------------Expr------------------------------------------ | |
500 #define STRING_BUFFER_LENGTH 2048 | |
501 // class Expr represents integer expressions containing constants and addition | |
502 // Value must be in range zero through maximum positive integer. 32bits. | |
503 // Expected use: instruction and operand costs | |
504 class Expr { | |
505 public: | |
506 enum { | |
507 Zero = 0, | |
508 Max = 0x7fffffff | |
509 }; | |
510 const char *_external_name; // if !NULL, then print this instead of _expr | |
511 const char *_expr; | |
512 int _min_value; | |
513 int _max_value; | |
514 | |
515 Expr(); | |
516 Expr(const char *cost); | |
517 Expr(const char *name, const char *expression, int min_value, int max_value); | |
518 Expr *clone() const; | |
519 | |
520 bool is_unknown() const { return (this == Expr::get_unknown()); } | |
521 bool is_zero() const { return (_min_value == Expr::Zero && _max_value == Expr::Zero); } | |
522 bool less_than_or_equal(const Expr *c) const { return (_max_value <= c->_min_value); } | |
523 | |
524 void add(const Expr *c); | |
525 void add(const char *c); | |
526 void add(const char *c, ArchDesc &AD); // check if 'c' is defined in <arch>.ad | |
527 void set_external_name(const char *name) { _external_name = name; } | |
528 | |
529 const char *as_string() const { return (_external_name != NULL ? _external_name : _expr); } | |
530 void print() const; | |
531 void print_define(FILE *fp) const; | |
532 void print_assert(FILE *fp) const; | |
533 | |
534 static Expr *get_unknown(); // Returns pointer to shared unknown cost instance | |
535 | |
536 static char *buffer() { return &external_buffer[0]; } | |
537 static bool init_buffers(); // Fill buffers with 0 | |
538 static bool check_buffers(); // if buffer use may have overflowed, assert | |
539 | |
540 private: | |
541 static Expr *_unknown_expr; | |
542 static char string_buffer[STRING_BUFFER_LENGTH]; | |
543 static char external_buffer[STRING_BUFFER_LENGTH]; | |
544 static bool _init_buffers; | |
545 const char *compute_expr(const Expr *c1, const Expr *c2); // cost as string after adding 'c1' and 'c2' | |
546 int compute_min (const Expr *c1, const Expr *c2); // minimum after adding 'c1' and 'c2' | |
547 int compute_max (const Expr *c1, const Expr *c2); // maximum after adding 'c1' and 'c2' | |
548 const char *compute_external(const Expr *c1, const Expr *c2); // external name after adding 'c1' and 'c2' | |
549 }; | |
550 | |
551 //------------------------------ExprDict--------------------------------------- | |
552 // Dictionary containing Exprs | |
553 class ExprDict { | |
554 private: | |
555 Dict _expr; // map names, char*, to their Expr* or NULL | |
556 NameList _defines; // record the order of definitions entered with define call | |
557 | |
558 // Disable public use of constructor, copy-ctor, operator =, operator == | |
559 ExprDict( ); | |
560 ExprDict( const ExprDict & ); // Deep-copy guts | |
561 ExprDict &operator =( const ExprDict & ); | |
562 // == compares two dictionaries; they must have the same keys (their keys | |
563 // must match using CmpKey) and they must have the same values (pointer | |
564 // comparison). If so 1 is returned, if not 0 is returned. | |
565 bool operator ==(const ExprDict &d) const; // Compare dictionaries for equal | |
566 | |
567 public: | |
568 // cmp is a key comparision routine. hash is a routine to hash a key. | |
569 ExprDict( CmpKey cmp, Hash hash, Arena *arena ); | |
570 ~ExprDict(); | |
571 | |
572 // Return # of key-value pairs in dict | |
573 int Size(void) const; | |
574 | |
575 // define inserts the given key-value pair into the dictionary, | |
576 // and records the name in order for later output, ... | |
577 const Expr *define(const char *name, Expr *expr); | |
578 | |
579 // Insert inserts the given key-value pair into the dictionary. The prior | |
580 // value of the key is returned; NULL if the key was not previously defined. | |
581 const Expr *Insert(const char *name, Expr *expr); // A new key-value | |
582 | |
583 // Find finds the value of a given key; or NULL if not found. | |
584 // The dictionary is NOT changed. | |
585 const Expr *operator [](const char *name) const; // Do a lookup | |
586 | |
587 void print_defines(FILE *fp); | |
588 void print_asserts(FILE *fp); | |
589 void dump(); | |
590 }; |