24
25 class ValueStack: public CompilationResourceObj {
26 private:
27 IRScope* _scope; // the enclosing scope
28 bool _lock_stack; // indicates that this ValueStack is for an exception site
29 Values _locals; // the locals
30 Values _stack; // the expression stack
31 Values _locks; // the monitor stack (holding the locked values)
32
33 Value check(ValueTag tag, Value t) {
34 assert(tag == t->type()->tag() || tag == objectTag && t->type()->tag() == addressTag, "types must correspond");
35 return t;
36 }
37
38 Value check(ValueTag tag, Value t, Value h) {
39 assert(h->as_HiWord()->lo_word() == t, "incorrect stack pair");
40 return check(tag, t);
41 }
42
43 // helper routine
44 static void apply(Values list, void f(Value*));
45
46 public:
47 // creation
48 ValueStack(IRScope* scope, int locals_size, int max_stack_size);
49
50 // merging
51 ValueStack* copy(); // returns a copy of this w/ cleared locals
52 ValueStack* copy_locks(); // returns a copy of this w/ cleared locals and stack
53 // Note that when inlining of methods with exception
54 // handlers is enabled, this stack may have a
55 // non-empty expression stack (size defined by
56 // scope()->lock_stack_size())
57 bool is_same(ValueStack* s); // returns true if this & s's types match (w/o checking locals)
58 bool is_same_across_scopes(ValueStack* s); // same as is_same but returns true even if stacks are in different scopes (used for block merging w/inlining)
59
60 // accessors
61 IRScope* scope() const { return _scope; }
62 bool is_lock_stack() const { return _lock_stack; }
63 int locals_size() const { return _locals.length(); }
64 int stack_size() const { return _stack.length(); }
126
127 // stack access
128 Value stack_at(int i) const {
129 Value x = _stack.at(i);
130 assert(x->as_HiWord() == NULL, "index points to hi word");
131 assert(x->type()->is_single_word() ||
132 x->subst() == _stack.at(i+1)->as_HiWord()->lo_word(), "stack inconsistent");
133 return x;
134 }
135
136 Value stack_at_inc(int& i) const {
137 Value x = stack_at(i);
138 i += x->type()->size();
139 return x;
140 }
141
142 // pinning support
143 void pin_stack_for_linear_scan();
144
145 // iteration
146 void values_do(void f(Value*));
147
148 // untyped manipulation (for dup_x1, etc.)
149 void clear_stack() { _stack.clear(); }
150 void truncate_stack(int size) { _stack.trunc_to(size); }
151 void raw_push(Value t) { _stack.push(t); }
152 Value raw_pop() { return _stack.pop(); }
153
154 // typed manipulation
155 void ipush(Value t) { _stack.push(check(intTag , t)); }
156 void fpush(Value t) { _stack.push(check(floatTag , t)); }
157 void apush(Value t) { _stack.push(check(objectTag , t)); }
158 void rpush(Value t) { _stack.push(check(addressTag, t)); }
159 #ifdef ASSERT
160 // in debug mode, use HiWord for 2-word values
161 void lpush(Value t) { _stack.push(check(longTag , t)); _stack.push(new HiWord(t)); }
162 void dpush(Value t) { _stack.push(check(doubleTag , t)); _stack.push(new HiWord(t)); }
163 #else
164 // in optimized mode, use NULL for 2-word values
165 void lpush(Value t) { _stack.push(check(longTag , t)); _stack.push(NULL); }
166 void dpush(Value t) { _stack.push(check(doubleTag , t)); _stack.push(NULL); }
|
24
25 class ValueStack: public CompilationResourceObj {
26 private:
27 IRScope* _scope; // the enclosing scope
28 bool _lock_stack; // indicates that this ValueStack is for an exception site
29 Values _locals; // the locals
30 Values _stack; // the expression stack
31 Values _locks; // the monitor stack (holding the locked values)
32
33 Value check(ValueTag tag, Value t) {
34 assert(tag == t->type()->tag() || tag == objectTag && t->type()->tag() == addressTag, "types must correspond");
35 return t;
36 }
37
38 Value check(ValueTag tag, Value t, Value h) {
39 assert(h->as_HiWord()->lo_word() == t, "incorrect stack pair");
40 return check(tag, t);
41 }
42
43 // helper routine
44 static void apply(Values list, ValueVisitor* f);
45
46 public:
47 // creation
48 ValueStack(IRScope* scope, int locals_size, int max_stack_size);
49
50 // merging
51 ValueStack* copy(); // returns a copy of this w/ cleared locals
52 ValueStack* copy_locks(); // returns a copy of this w/ cleared locals and stack
53 // Note that when inlining of methods with exception
54 // handlers is enabled, this stack may have a
55 // non-empty expression stack (size defined by
56 // scope()->lock_stack_size())
57 bool is_same(ValueStack* s); // returns true if this & s's types match (w/o checking locals)
58 bool is_same_across_scopes(ValueStack* s); // same as is_same but returns true even if stacks are in different scopes (used for block merging w/inlining)
59
60 // accessors
61 IRScope* scope() const { return _scope; }
62 bool is_lock_stack() const { return _lock_stack; }
63 int locals_size() const { return _locals.length(); }
64 int stack_size() const { return _stack.length(); }
126
127 // stack access
128 Value stack_at(int i) const {
129 Value x = _stack.at(i);
130 assert(x->as_HiWord() == NULL, "index points to hi word");
131 assert(x->type()->is_single_word() ||
132 x->subst() == _stack.at(i+1)->as_HiWord()->lo_word(), "stack inconsistent");
133 return x;
134 }
135
136 Value stack_at_inc(int& i) const {
137 Value x = stack_at(i);
138 i += x->type()->size();
139 return x;
140 }
141
142 // pinning support
143 void pin_stack_for_linear_scan();
144
145 // iteration
146 void values_do(ValueVisitor* f);
147
148 // untyped manipulation (for dup_x1, etc.)
149 void clear_stack() { _stack.clear(); }
150 void truncate_stack(int size) { _stack.trunc_to(size); }
151 void raw_push(Value t) { _stack.push(t); }
152 Value raw_pop() { return _stack.pop(); }
153
154 // typed manipulation
155 void ipush(Value t) { _stack.push(check(intTag , t)); }
156 void fpush(Value t) { _stack.push(check(floatTag , t)); }
157 void apush(Value t) { _stack.push(check(objectTag , t)); }
158 void rpush(Value t) { _stack.push(check(addressTag, t)); }
159 #ifdef ASSERT
160 // in debug mode, use HiWord for 2-word values
161 void lpush(Value t) { _stack.push(check(longTag , t)); _stack.push(new HiWord(t)); }
162 void dpush(Value t) { _stack.push(check(doubleTag , t)); _stack.push(new HiWord(t)); }
163 #else
164 // in optimized mode, use NULL for 2-word values
165 void lpush(Value t) { _stack.push(check(longTag , t)); _stack.push(NULL); }
166 void dpush(Value t) { _stack.push(check(doubleTag , t)); _stack.push(NULL); }
|