97 // To be able to process "ret" bytecodes, we keep track of these return
98 // PC's in a 'retAddrs' structure in abstract interpreter context (when
99 // processing a "ret" bytecodes, it is not sufficient to know that it gets
100 // an argument of the right type 'p'; we need to know which address it
101 // returns to).
102 //
103 // (Note this comment is borrowed form the original author of the algorithm)
104
105 // ComputeCallStack
106 //
107 // Specialization of SignatureIterator - compute the effects of a call
108 //
109 class ComputeCallStack : public SignatureIterator {
110 CellTypeState *_effect;
111 int _idx;
112
113 void setup();
114 void set(CellTypeState state) { _effect[_idx++] = state; }
115 int length() { return _idx; };
116
117 virtual void do_bool () { set(CellTypeState::value); };
118 virtual void do_char () { set(CellTypeState::value); };
119 virtual void do_float () { set(CellTypeState::value); };
120 virtual void do_byte () { set(CellTypeState::value); };
121 virtual void do_short () { set(CellTypeState::value); };
122 virtual void do_int () { set(CellTypeState::value); };
123 virtual void do_void () { set(CellTypeState::bottom);};
124 virtual void do_object(int begin, int end) { set(CellTypeState::ref); };
125 virtual void do_array (int begin, int end) { set(CellTypeState::ref); };
126
127 void do_double() { set(CellTypeState::value);
128 set(CellTypeState::value); }
129 void do_long () { set(CellTypeState::value);
130 set(CellTypeState::value); }
131
132 public:
133 ComputeCallStack(Symbol* signature) : SignatureIterator(signature) {};
134
135 // Compute methods
136 int compute_for_parameters(bool is_static, CellTypeState *effect) {
137 _idx = 0;
138 _effect = effect;
139
140 if (!is_static)
141 effect[_idx++] = CellTypeState::ref;
142
143 iterate_parameters();
144
145 return length();
146 };
147
148 int compute_for_returntype(CellTypeState *effect) {
149 _idx = 0;
150 _effect = effect;
151 iterate_returntype();
152 set(CellTypeState::bottom); // Always terminate with a bottom state, so ppush works
153
154 return length();
155 }
156 };
157
158 //=========================================================================================
159 // ComputeEntryStack
160 //
161 // Specialization of SignatureIterator - in order to set up first stack frame
162 //
163 class ComputeEntryStack : public SignatureIterator {
164 CellTypeState *_effect;
165 int _idx;
166
167 void setup();
168 void set(CellTypeState state) { _effect[_idx++] = state; }
169 int length() { return _idx; };
170
171 virtual void do_bool () { set(CellTypeState::value); };
172 virtual void do_char () { set(CellTypeState::value); };
173 virtual void do_float () { set(CellTypeState::value); };
174 virtual void do_byte () { set(CellTypeState::value); };
175 virtual void do_short () { set(CellTypeState::value); };
176 virtual void do_int () { set(CellTypeState::value); };
177 virtual void do_void () { set(CellTypeState::bottom);};
178 virtual void do_object(int begin, int end) { set(CellTypeState::make_slot_ref(_idx)); }
179 virtual void do_array (int begin, int end) { set(CellTypeState::make_slot_ref(_idx)); }
180
181 void do_double() { set(CellTypeState::value);
182 set(CellTypeState::value); }
183 void do_long () { set(CellTypeState::value);
184 set(CellTypeState::value); }
185
186 public:
187 ComputeEntryStack(Symbol* signature) : SignatureIterator(signature) {};
188
189 // Compute methods
190 int compute_for_parameters(bool is_static, CellTypeState *effect) {
191 _idx = 0;
192 _effect = effect;
193
194 if (!is_static)
195 effect[_idx++] = CellTypeState::make_slot_ref(0);
196
197 iterate_parameters();
198
199 return length();
200 };
201
202 int compute_for_returntype(CellTypeState *effect) {
203 _idx = 0;
204 _effect = effect;
205 iterate_returntype();
206 set(CellTypeState::bottom); // Always terminate with a bottom state, so ppush works
207
208 return length();
209 }
210 };
211
212 //=====================================================================================
213 //
214 // Implementation of RetTable/RetTableEntry
215 //
216 // Contains function to itereate through all bytecodes
217 // and find all return entry points
218 //
219 int RetTable::_init_nof_entries = 10;
220 int RetTableEntry::_init_nof_jsrs = 5;
221
222 RetTableEntry::RetTableEntry(int target, RetTableEntry *next) {
223 _target_bci = target;
224 _jsrs = new GrowableArray<intptr_t>(_init_nof_jsrs);
225 _next = next;
1913 }
1914
1915 // Copies bottom/zero terminated CTS string from "src" into "dst".
1916 // Does NOT terminate with a bottom. Returns the number of cells copied.
1917 int GenerateOopMap::copy_cts(CellTypeState *dst, CellTypeState *src) {
1918 int idx = 0;
1919 while (!src[idx].is_bottom()) {
1920 dst[idx] = src[idx];
1921 idx++;
1922 }
1923 return idx;
1924 }
1925
1926 void GenerateOopMap::do_field(int is_get, int is_static, int idx, int bci) {
1927 // Dig up signature for field in constant pool
1928 ConstantPool* cp = method()->constants();
1929 int nameAndTypeIdx = cp->name_and_type_ref_index_at(idx);
1930 int signatureIdx = cp->signature_ref_index_at(nameAndTypeIdx);
1931 Symbol* signature = cp->symbol_at(signatureIdx);
1932
1933 // Parse signature (espcially simple for fields)
1934 assert(signature->utf8_length() > 0, "field signatures cannot have zero length");
1935 // The signature is UFT8 encoded, but the first char is always ASCII for signatures.
1936 char sigch = (char)*(signature->base());
1937 CellTypeState temp[4];
1938 CellTypeState *eff = sigchar_to_effect(sigch, bci, temp);
1939
1940 CellTypeState in[4];
1941 CellTypeState *out;
1942 int i = 0;
1943
1944 if (is_get) {
1945 out = eff;
1946 } else {
1947 out = epsilonCTS;
1948 i = copy_cts(in, eff);
1949 }
1950 if (!is_static) in[i++] = CellTypeState::ref;
1951 in[i] = CellTypeState::bottom;
1952 assert(i<=3, "sanity check");
1953 pp(in, out);
1954 }
1955
1956 void GenerateOopMap::do_method(int is_static, int is_interface, int idx, int bci) {
1957 // Dig up signature for field in constant pool
1958 ConstantPool* cp = _method->constants();
1974 assert(res_length<=4, "max value should be vv");
1975
1976 // Compute arguments
1977 int arg_length = cse.compute_for_parameters(is_static != 0, in);
1978 assert(arg_length<=MAXARGSIZE, "too many locals");
1979
1980 // Pop arguments
1981 for (int i = arg_length - 1; i >= 0; i--) ppop1(in[i]);// Do args in reverse order.
1982
1983 // Report results
1984 if (_report_result_for_send == true) {
1985 fill_stackmap_for_opcodes(_itr_send, vars(), stack(), _stack_top);
1986 _report_result_for_send = false;
1987 }
1988
1989 // Push return address
1990 ppush(out);
1991 }
1992
1993 // This is used to parse the signature for fields, since they are very simple...
1994 CellTypeState *GenerateOopMap::sigchar_to_effect(char sigch, int bci, CellTypeState *out) {
1995 // Object and array
1996 if (sigch==JVM_SIGNATURE_CLASS || sigch==JVM_SIGNATURE_ARRAY) {
1997 out[0] = CellTypeState::make_line_ref(bci);
1998 out[1] = CellTypeState::bottom;
1999 return out;
2000 }
2001 if (sigch == JVM_SIGNATURE_LONG || sigch == JVM_SIGNATURE_DOUBLE) return vvCTS; // Long and Double
2002 if (sigch == JVM_SIGNATURE_VOID) return epsilonCTS; // Void
2003 return vCTS; // Otherwise
2004 }
2005
2006 long GenerateOopMap::_total_byte_count = 0;
2007 elapsedTimer GenerateOopMap::_total_oopmap_time;
2008
2009 // This function assumes "bcs" is at a "ret" instruction and that the vars
2010 // state is valid for that instruction. Furthermore, the ret instruction
2011 // must be the last instruction in "bb" (we store information about the
2012 // "ret" in "bb").
2013 void GenerateOopMap::ret_jump_targets_do(BytecodeStream *bcs, jmpFct_t jmpFct, int varNo, int *data) {
2014 CellTypeState ra = vars()[varNo];
2015 if (!ra.is_good_address()) {
2016 verify_error("ret returns from two jsr subroutines?");
2017 return;
2018 }
2019 int target = ra.get_info();
2020
2021 RetTableEntry* rtEnt = _rt.find_jsrs_for_target(target);
2022 int bci = bcs->bci();
|
97 // To be able to process "ret" bytecodes, we keep track of these return
98 // PC's in a 'retAddrs' structure in abstract interpreter context (when
99 // processing a "ret" bytecodes, it is not sufficient to know that it gets
100 // an argument of the right type 'p'; we need to know which address it
101 // returns to).
102 //
103 // (Note this comment is borrowed form the original author of the algorithm)
104
105 // ComputeCallStack
106 //
107 // Specialization of SignatureIterator - compute the effects of a call
108 //
109 class ComputeCallStack : public SignatureIterator {
110 CellTypeState *_effect;
111 int _idx;
112
113 void setup();
114 void set(CellTypeState state) { _effect[_idx++] = state; }
115 int length() { return _idx; };
116
117 friend class SignatureIterator; // so do_parameters_on can call do_type
118 void do_type(BasicType type, bool for_return = false) {
119 if (for_return && type == T_VOID) {
120 set(CellTypeState::bottom);
121 } else if (is_reference_type(type)) {
122 set(CellTypeState::ref);
123 } else {
124 assert(is_java_primitive(type), "");
125 set(CellTypeState::value);
126 if (is_double_word_type(type)) {
127 set(CellTypeState::value);
128 }
129 }
130 }
131
132 public:
133 ComputeCallStack(Symbol* signature) : SignatureIterator(signature) {};
134
135 // Compute methods
136 int compute_for_parameters(bool is_static, CellTypeState *effect) {
137 _idx = 0;
138 _effect = effect;
139
140 if (!is_static)
141 effect[_idx++] = CellTypeState::ref;
142
143 do_parameters_on(this);
144
145 return length();
146 };
147
148 int compute_for_returntype(CellTypeState *effect) {
149 _idx = 0;
150 _effect = effect;
151 do_type(return_type(), true);
152 set(CellTypeState::bottom); // Always terminate with a bottom state, so ppush works
153
154 return length();
155 }
156 };
157
158 //=========================================================================================
159 // ComputeEntryStack
160 //
161 // Specialization of SignatureIterator - in order to set up first stack frame
162 //
163 class ComputeEntryStack : public SignatureIterator {
164 CellTypeState *_effect;
165 int _idx;
166
167 void setup();
168 void set(CellTypeState state) { _effect[_idx++] = state; }
169 int length() { return _idx; };
170
171 friend class SignatureIterator; // so do_parameters_on can call do_type
172 void do_type(BasicType type, bool for_return = false) {
173 if (for_return && type == T_VOID) {
174 set(CellTypeState::bottom);
175 } else if (is_reference_type(type)) {
176 set(CellTypeState::make_slot_ref(_idx));
177 } else {
178 assert(is_java_primitive(type), "");
179 set(CellTypeState::value);
180 if (is_double_word_type(type)) {
181 set(CellTypeState::value);
182 }
183 }
184 }
185
186 public:
187 ComputeEntryStack(Symbol* signature) : SignatureIterator(signature) {};
188
189 // Compute methods
190 int compute_for_parameters(bool is_static, CellTypeState *effect) {
191 _idx = 0;
192 _effect = effect;
193
194 if (!is_static)
195 effect[_idx++] = CellTypeState::make_slot_ref(0);
196
197 do_parameters_on(this);
198
199 return length();
200 };
201
202 int compute_for_returntype(CellTypeState *effect) {
203 _idx = 0;
204 _effect = effect;
205 do_type(return_type(), true);
206 set(CellTypeState::bottom); // Always terminate with a bottom state, so ppush works
207
208 return length();
209 }
210 };
211
212 //=====================================================================================
213 //
214 // Implementation of RetTable/RetTableEntry
215 //
216 // Contains function to itereate through all bytecodes
217 // and find all return entry points
218 //
219 int RetTable::_init_nof_entries = 10;
220 int RetTableEntry::_init_nof_jsrs = 5;
221
222 RetTableEntry::RetTableEntry(int target, RetTableEntry *next) {
223 _target_bci = target;
224 _jsrs = new GrowableArray<intptr_t>(_init_nof_jsrs);
225 _next = next;
1913 }
1914
1915 // Copies bottom/zero terminated CTS string from "src" into "dst".
1916 // Does NOT terminate with a bottom. Returns the number of cells copied.
1917 int GenerateOopMap::copy_cts(CellTypeState *dst, CellTypeState *src) {
1918 int idx = 0;
1919 while (!src[idx].is_bottom()) {
1920 dst[idx] = src[idx];
1921 idx++;
1922 }
1923 return idx;
1924 }
1925
1926 void GenerateOopMap::do_field(int is_get, int is_static, int idx, int bci) {
1927 // Dig up signature for field in constant pool
1928 ConstantPool* cp = method()->constants();
1929 int nameAndTypeIdx = cp->name_and_type_ref_index_at(idx);
1930 int signatureIdx = cp->signature_ref_index_at(nameAndTypeIdx);
1931 Symbol* signature = cp->symbol_at(signatureIdx);
1932
1933 CellTypeState temp[4];
1934 CellTypeState *eff = signature_to_effect(signature, bci, temp);
1935
1936 CellTypeState in[4];
1937 CellTypeState *out;
1938 int i = 0;
1939
1940 if (is_get) {
1941 out = eff;
1942 } else {
1943 out = epsilonCTS;
1944 i = copy_cts(in, eff);
1945 }
1946 if (!is_static) in[i++] = CellTypeState::ref;
1947 in[i] = CellTypeState::bottom;
1948 assert(i<=3, "sanity check");
1949 pp(in, out);
1950 }
1951
1952 void GenerateOopMap::do_method(int is_static, int is_interface, int idx, int bci) {
1953 // Dig up signature for field in constant pool
1954 ConstantPool* cp = _method->constants();
1970 assert(res_length<=4, "max value should be vv");
1971
1972 // Compute arguments
1973 int arg_length = cse.compute_for_parameters(is_static != 0, in);
1974 assert(arg_length<=MAXARGSIZE, "too many locals");
1975
1976 // Pop arguments
1977 for (int i = arg_length - 1; i >= 0; i--) ppop1(in[i]);// Do args in reverse order.
1978
1979 // Report results
1980 if (_report_result_for_send == true) {
1981 fill_stackmap_for_opcodes(_itr_send, vars(), stack(), _stack_top);
1982 _report_result_for_send = false;
1983 }
1984
1985 // Push return address
1986 ppush(out);
1987 }
1988
1989 // This is used to parse the signature for fields, since they are very simple...
1990 CellTypeState *GenerateOopMap::signature_to_effect(const Symbol* sig, int bci, CellTypeState *out) {
1991 // Object and array
1992 BasicType bt = Signature::basic_type(sig);
1993 if (is_reference_type(bt)) {
1994 out[0] = CellTypeState::make_line_ref(bci);
1995 out[1] = CellTypeState::bottom;
1996 return out;
1997 }
1998 if (is_double_word_type(bt)) return vvCTS; // Long and Double
1999 if (bt == T_VOID) return epsilonCTS; // Void
2000 return vCTS; // Otherwise
2001 }
2002
2003 long GenerateOopMap::_total_byte_count = 0;
2004 elapsedTimer GenerateOopMap::_total_oopmap_time;
2005
2006 // This function assumes "bcs" is at a "ret" instruction and that the vars
2007 // state is valid for that instruction. Furthermore, the ret instruction
2008 // must be the last instruction in "bb" (we store information about the
2009 // "ret" in "bb").
2010 void GenerateOopMap::ret_jump_targets_do(BytecodeStream *bcs, jmpFct_t jmpFct, int varNo, int *data) {
2011 CellTypeState ra = vars()[varNo];
2012 if (!ra.is_good_address()) {
2013 verify_error("ret returns from two jsr subroutines?");
2014 return;
2015 }
2016 int target = ra.get_info();
2017
2018 RetTableEntry* rtEnt = _rt.find_jsrs_for_target(target);
2019 int bci = bcs->bci();
|