17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_INTERPRETER_REWRITER_HPP
26 #define SHARE_VM_INTERPRETER_REWRITER_HPP
27
28 #include "memory/allocation.hpp"
29 #include "runtime/handles.inline.hpp"
30 #include "utilities/growableArray.hpp"
31
32 // The Rewriter adds caches to the constant pool and rewrites bytecode indices
33 // pointing into the constant pool for better interpreter performance.
34
35 class Rewriter: public StackObj {
36 private:
37 instanceKlassHandle _klass;
38 constantPoolHandle _pool;
39 Array<Method*>* _methods;
40 GrowableArray<int> _cp_map;
41 GrowableArray<int> _cp_cache_map; // for Methodref, Fieldref,
42 // InterfaceMethodref and InvokeDynamic
43 GrowableArray<int> _reference_map; // maps from cp index to resolved_refs index (or -1)
44 GrowableArray<int> _resolved_references_map; // for strings, methodHandle, methodType
45 GrowableArray<int> _invokedynamic_references_map; // for invokedynamic resolved refs
46 GrowableArray<int> _method_handle_invokers;
47 int _resolved_reference_limit;
48
49 // For mapping invokedynamic bytecodes, which are discovered during method
50 // scanning. The invokedynamic entries are added at the end of the cpCache.
51 // If there are any invokespecial/InterfaceMethodref special case bytecodes,
52 // these entries are added before invokedynamic entries so that the
53 // invokespecial bytecode 16 bit index doesn't overflow.
54 GrowableArray<int> _invokedynamic_cp_cache_map;
55
56 // For patching.
57 GrowableArray<address>* _patch_invokedynamic_bcps;
171 ref_index = index;
172 }
173 assert((index - entry) == ref_index, "entries must be consecutive");
174 _invokedynamic_references_map.at_put_grow(index, cache_index, -1);
175 }
176 return ref_index;
177 }
178
179 int resolved_references_entry_to_pool_index(int ref_index) {
180 int cp_index = _resolved_references_map.at(ref_index);
181 return cp_index;
182 }
183
184 // Access the contents of _cp_cache_map to determine CP cache layout.
185 int cp_cache_entry_pool_index(int cache_index) {
186 int cp_index = _cp_cache_map.at(cache_index);
187 return cp_index;
188 }
189
190 // All the work goes in here:
191 Rewriter(instanceKlassHandle klass, const constantPoolHandle& cpool, Array<Method*>* methods, TRAPS);
192
193 void compute_index_maps();
194 void make_constant_pool_cache(TRAPS);
195 void scan_method(Method* m, bool reverse, bool* invokespecial_error);
196 void rewrite_Object_init(methodHandle m, TRAPS);
197 void rewrite_member_reference(address bcp, int offset, bool reverse);
198 void maybe_rewrite_invokehandle(address opc, int cp_index, int cache_index, bool reverse);
199 void rewrite_invokedynamic(address bcp, int offset, bool reverse);
200 void maybe_rewrite_ldc(address bcp, int offset, bool is_wide, bool reverse);
201 void rewrite_invokespecial(address bcp, int offset, bool reverse, bool* invokespecial_error);
202
203 void patch_invokedynamic_bytecodes();
204
205 // Do all the work.
206 void rewrite_bytecodes(TRAPS);
207
208 // Revert bytecodes in case of an exception.
209 void restore_bytecodes();
210
211 static methodHandle rewrite_jsrs(methodHandle m, TRAPS);
212 public:
213 // Driver routine:
214 static void rewrite(instanceKlassHandle klass, TRAPS);
215 };
216
217 #endif // SHARE_VM_INTERPRETER_REWRITER_HPP
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_INTERPRETER_REWRITER_HPP
26 #define SHARE_VM_INTERPRETER_REWRITER_HPP
27
28 #include "memory/allocation.hpp"
29 #include "runtime/handles.inline.hpp"
30 #include "utilities/growableArray.hpp"
31
32 // The Rewriter adds caches to the constant pool and rewrites bytecode indices
33 // pointing into the constant pool for better interpreter performance.
34
35 class Rewriter: public StackObj {
36 private:
37 InstanceKlass* _klass;
38 constantPoolHandle _pool;
39 Array<Method*>* _methods;
40 GrowableArray<int> _cp_map;
41 GrowableArray<int> _cp_cache_map; // for Methodref, Fieldref,
42 // InterfaceMethodref and InvokeDynamic
43 GrowableArray<int> _reference_map; // maps from cp index to resolved_refs index (or -1)
44 GrowableArray<int> _resolved_references_map; // for strings, methodHandle, methodType
45 GrowableArray<int> _invokedynamic_references_map; // for invokedynamic resolved refs
46 GrowableArray<int> _method_handle_invokers;
47 int _resolved_reference_limit;
48
49 // For mapping invokedynamic bytecodes, which are discovered during method
50 // scanning. The invokedynamic entries are added at the end of the cpCache.
51 // If there are any invokespecial/InterfaceMethodref special case bytecodes,
52 // these entries are added before invokedynamic entries so that the
53 // invokespecial bytecode 16 bit index doesn't overflow.
54 GrowableArray<int> _invokedynamic_cp_cache_map;
55
56 // For patching.
57 GrowableArray<address>* _patch_invokedynamic_bcps;
171 ref_index = index;
172 }
173 assert((index - entry) == ref_index, "entries must be consecutive");
174 _invokedynamic_references_map.at_put_grow(index, cache_index, -1);
175 }
176 return ref_index;
177 }
178
179 int resolved_references_entry_to_pool_index(int ref_index) {
180 int cp_index = _resolved_references_map.at(ref_index);
181 return cp_index;
182 }
183
184 // Access the contents of _cp_cache_map to determine CP cache layout.
185 int cp_cache_entry_pool_index(int cache_index) {
186 int cp_index = _cp_cache_map.at(cache_index);
187 return cp_index;
188 }
189
190 // All the work goes in here:
191 Rewriter(InstanceKlass* klass, const constantPoolHandle& cpool, Array<Method*>* methods, TRAPS);
192
193 void compute_index_maps();
194 void make_constant_pool_cache(TRAPS);
195 void scan_method(Method* m, bool reverse, bool* invokespecial_error);
196 void rewrite_Object_init(methodHandle m, TRAPS);
197 void rewrite_member_reference(address bcp, int offset, bool reverse);
198 void maybe_rewrite_invokehandle(address opc, int cp_index, int cache_index, bool reverse);
199 void rewrite_invokedynamic(address bcp, int offset, bool reverse);
200 void maybe_rewrite_ldc(address bcp, int offset, bool is_wide, bool reverse);
201 void rewrite_invokespecial(address bcp, int offset, bool reverse, bool* invokespecial_error);
202
203 void patch_invokedynamic_bytecodes();
204
205 // Do all the work.
206 void rewrite_bytecodes(TRAPS);
207
208 // Revert bytecodes in case of an exception.
209 void restore_bytecodes();
210
211 static methodHandle rewrite_jsrs(methodHandle m, TRAPS);
212 public:
213 // Driver routine:
214 static void rewrite(InstanceKlass* klass, TRAPS);
215 };
216
217 #endif // SHARE_VM_INTERPRETER_REWRITER_HPP
|