22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/shared/collectedHeap.hpp"
27 #include "interpreter/interp_masm.hpp"
28 #include "interpreter/templateTable.hpp"
29 #include "runtime/logTimer.hpp"
30
31 #ifdef CC_INTERP
32
33 void templateTable_init() {
34 }
35
36 #else
37
38 //----------------------------------------------------------------------------------------------------
39 // Implementation of Template
40
41
42 void Template::initialize(int flags, TosState tos_in, TosState tos_out, generator gen, int arg) {
43 _flags = flags;
44 _tos_in = tos_in;
45 _tos_out = tos_out;
46 _gen = gen;
47 _arg = arg;
48 }
49
50
51 Bytecodes::Code Template::bytecode() const {
52 int i = this - TemplateTable::_template_table;
53 if (i < 0 || i >= Bytecodes::number_of_codes) i = this - TemplateTable::_template_table_wide;
54 return Bytecodes::cast(i);
55 }
56
57
58 void Template::generate(InterpreterMacroAssembler* masm) {
59 // parameter passing
60 TemplateTable::_desc = this;
61 TemplateTable::_masm = masm;
62 // code generation
63 _gen(_arg);
64 masm->flush();
65 }
66
67
68 //----------------------------------------------------------------------------------------------------
69 // Implementation of TemplateTable: Platform-independent helper routines
70
71 void TemplateTable::call_VM(Register oop_result, address entry_point) {
72 assert(_desc->calls_vm(), "inconsistent calls_vm information");
73 _masm->call_VM(oop_result, entry_point);
74 }
152 void TemplateTable::jsr() {
153 transition(vtos, vtos); // result is not an oop, so do not transition to atos
154 branch(true, false);
155 }
156
157
158
159 //----------------------------------------------------------------------------------------------------
160 // Implementation of TemplateTable: Debugging
161
162 void TemplateTable::transition(TosState tos_in, TosState tos_out) {
163 assert(_desc->tos_in() == tos_in , "inconsistent tos_in information");
164 assert(_desc->tos_out() == tos_out, "inconsistent tos_out information");
165 }
166
167
168 //----------------------------------------------------------------------------------------------------
169 // Implementation of TemplateTable: Initialization
170
171 bool TemplateTable::_is_initialized = false;
172 Template TemplateTable::_template_table [Bytecodes::number_of_codes];
173 Template TemplateTable::_template_table_wide[Bytecodes::number_of_codes];
174
175 Template* TemplateTable::_desc;
176 InterpreterMacroAssembler* TemplateTable::_masm;
177 BarrierSet* TemplateTable::_bs;
178
179
180 void TemplateTable::def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(), char filler) {
181 assert(filler == ' ', "just checkin'");
182 def(code, flags, in, out, (Template::generator)gen, 0);
183 }
184
185
186 void TemplateTable::def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(int arg), int arg) {
187 // should factor out these constants
188 const int ubcp = 1 << Template::uses_bcp_bit;
189 const int disp = 1 << Template::does_dispatch_bit;
190 const int clvm = 1 << Template::calls_vm_bit;
191 const int iswd = 1 << Template::wide_bit;
192 // determine which table to use
193 bool is_wide = (flags & iswd) != 0;
194 // make sure that wide instructions have a vtos entry point
195 // (since they are executed extremely rarely, it doesn't pay out to have an
196 // extra set of 5 dispatch tables for the wide instructions - for simplicity
197 // they all go with one table)
198 assert(in == vtos || !is_wide, "wide instructions have vtos entry point only");
199 Template* t = is_wide ? template_for_wide(code) : template_for(code);
200 // setup entry
201 t->initialize(flags, in, out, gen, arg);
202 assert(t->bytecode() == code, "just checkin'");
203 }
204
205
206 void TemplateTable::def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(Operation op), Operation op) {
207 def(code, flags, in, out, (Template::generator)gen, (int)op);
208 }
209
210
211 void TemplateTable::def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(bool arg ), bool arg) {
212 def(code, flags, in, out, (Template::generator)gen, (int)arg);
213 }
214
215
216 void TemplateTable::def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(TosState tos), TosState tos) {
217 def(code, flags, in, out, (Template::generator)gen, (int)tos);
218 }
219
220
221 void TemplateTable::def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(Condition cc), Condition cc) {
232 #define iload TemplateTable::iload
233 #define lload TemplateTable::lload
234 #define fload TemplateTable::fload
235 #define dload TemplateTable::dload
236 #define aload TemplateTable::aload
237 #define istore TemplateTable::istore
238 #define lstore TemplateTable::lstore
239 #define fstore TemplateTable::fstore
240 #define dstore TemplateTable::dstore
241 #define astore TemplateTable::astore
242 #endif // TEMPLATE_TABLE_BUG
243
244 void TemplateTable::initialize() {
245 if (_is_initialized) return;
246
247 // Initialize table
248 TraceStartupTime timer("TemplateTable initialization");
249
250 _bs = Universe::heap()->barrier_set();
251
252 // For better readability
253 const char _ = ' ';
254 const int ____ = 0;
255 const int ubcp = 1 << Template::uses_bcp_bit;
256 const int disp = 1 << Template::does_dispatch_bit;
257 const int clvm = 1 << Template::calls_vm_bit;
258 const int iswd = 1 << Template::wide_bit;
259 // interpr. templates
260 // Java spec bytecodes ubcp|disp|clvm|iswd in out generator argument
261 def(Bytecodes::_nop , ____|____|____|____, vtos, vtos, nop , _ );
262 def(Bytecodes::_aconst_null , ____|____|____|____, vtos, atos, aconst_null , _ );
263 def(Bytecodes::_iconst_m1 , ____|____|____|____, vtos, itos, iconst , -1 );
264 def(Bytecodes::_iconst_0 , ____|____|____|____, vtos, itos, iconst , 0 );
265 def(Bytecodes::_iconst_1 , ____|____|____|____, vtos, itos, iconst , 1 );
266 def(Bytecodes::_iconst_2 , ____|____|____|____, vtos, itos, iconst , 2 );
267 def(Bytecodes::_iconst_3 , ____|____|____|____, vtos, itos, iconst , 3 );
268 def(Bytecodes::_iconst_4 , ____|____|____|____, vtos, itos, iconst , 4 );
269 def(Bytecodes::_iconst_5 , ____|____|____|____, vtos, itos, iconst , 5 );
270 def(Bytecodes::_lconst_0 , ____|____|____|____, vtos, ltos, lconst , 0 );
271 def(Bytecodes::_lconst_1 , ____|____|____|____, vtos, ltos, lconst , 1 );
453 def(Bytecodes::_checkcast , ubcp|____|clvm|____, atos, atos, checkcast , _ );
454 def(Bytecodes::_instanceof , ubcp|____|clvm|____, atos, itos, instanceof , _ );
455 def(Bytecodes::_monitorenter , ____|disp|clvm|____, atos, vtos, monitorenter , _ );
456 def(Bytecodes::_monitorexit , ____|____|clvm|____, atos, vtos, monitorexit , _ );
457 def(Bytecodes::_wide , ubcp|disp|____|____, vtos, vtos, wide , _ );
458 def(Bytecodes::_multianewarray , ubcp|____|clvm|____, vtos, atos, multianewarray , _ );
459 def(Bytecodes::_ifnull , ubcp|____|clvm|____, atos, vtos, if_nullcmp , equal );
460 def(Bytecodes::_ifnonnull , ubcp|____|clvm|____, atos, vtos, if_nullcmp , not_equal );
461 def(Bytecodes::_goto_w , ubcp|____|clvm|____, vtos, vtos, goto_w , _ );
462 def(Bytecodes::_jsr_w , ubcp|____|____|____, vtos, vtos, jsr_w , _ );
463 def(Bytecodes::_breakpoint , ubcp|disp|clvm|____, vtos, vtos, _breakpoint , _ );
464 def(Bytecodes::_vload , ubcp|____|clvm|____, vtos, qtos, vload , _ );
465 def(Bytecodes::_vstore , ubcp|____|clvm|____, vtos, vtos, vstore , _ );
466 def(Bytecodes::_vaload , ____|____|clvm|____, itos, qtos, vaload , _ );
467 def(Bytecodes::_vastore , ____|____|clvm|____, vtos, vtos, vastore , _ );
468 def(Bytecodes::_vnew , ubcp|____|clvm|____, vtos, qtos, _vnew , _ );
469 def(Bytecodes::_vnewarray , ubcp|____|clvm|____, itos, atos, vnewarray , _ );
470 def(Bytecodes::_multivnewarray , ubcp|____|clvm|____, vtos, atos, multianewarray , _ );
471 def(Bytecodes::_vreturn , ____|disp|clvm|____, qtos, qtos, _return , qtos );
472 def(Bytecodes::_vgetfield , ubcp|____|clvm|____, vtos, vtos, vgetfield , f1_byte );
473 def(Bytecodes::_typed , ubcp|disp|clvm|____, vtos, vtos, unimplemented_bc , _ );
474 def(Bytecodes::_invokedirect , ubcp|disp|clvm|____, vtos, vtos, invokedirect , f2_byte );
475 def(Bytecodes::_vbox , ubcp|____|clvm|____, qtos, atos, _vbox , _ );
476 def(Bytecodes::_vunbox , ubcp|____|clvm|____, atos, qtos, _vunbox , _ );
477
478 // wide Java spec bytecodes
479 def(Bytecodes::_iload , ubcp|____|____|iswd, vtos, itos, wide_iload , _ );
480 def(Bytecodes::_lload , ubcp|____|____|iswd, vtos, ltos, wide_lload , _ );
481 def(Bytecodes::_fload , ubcp|____|____|iswd, vtos, ftos, wide_fload , _ );
482 def(Bytecodes::_dload , ubcp|____|____|iswd, vtos, dtos, wide_dload , _ );
483 def(Bytecodes::_aload , ubcp|____|____|iswd, vtos, atos, wide_aload , _ );
484 def(Bytecodes::_vload , ubcp|____|____|iswd, vtos, qtos, wide_vload , _ );
485 def(Bytecodes::_istore , ubcp|____|____|iswd, vtos, vtos, wide_istore , _ );
486 def(Bytecodes::_lstore , ubcp|____|____|iswd, vtos, vtos, wide_lstore , _ );
487 def(Bytecodes::_fstore , ubcp|____|____|iswd, vtos, vtos, wide_fstore , _ );
488 def(Bytecodes::_dstore , ubcp|____|____|iswd, vtos, vtos, wide_dstore , _ );
489 def(Bytecodes::_astore , ubcp|____|____|iswd, vtos, vtos, wide_astore , _ );
490 def(Bytecodes::_vstore , ubcp|____|____|iswd, vtos, vtos, wide_vstore , _ );
491 def(Bytecodes::_iinc , ubcp|____|____|iswd, vtos, vtos, wide_iinc , _ );
492 def(Bytecodes::_ret , ubcp|disp|____|iswd, vtos, vtos, wide_ret , _ );
493
547 }
548
549 #if defined(TEMPLATE_TABLE_BUG)
550 #undef iload
551 #undef lload
552 #undef fload
553 #undef dload
554 #undef aload
555 #undef istore
556 #undef lstore
557 #undef fstore
558 #undef dstore
559 #undef astore
560 #endif // TEMPLATE_TABLE_BUG
561
562
563 void templateTable_init() {
564 TemplateTable::initialize();
565 }
566
567
568 void TemplateTable::unimplemented_bc() {
569 _masm->unimplemented( Bytecodes::name(_desc->bytecode()));
570 }
571 #endif /* !CC_INTERP */
|
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/shared/collectedHeap.hpp"
27 #include "interpreter/interp_masm.hpp"
28 #include "interpreter/templateTable.hpp"
29 #include "runtime/logTimer.hpp"
30
31 #ifdef CC_INTERP
32
33 void templateTable_init() {
34 }
35
36 #else
37
38 //----------------------------------------------------------------------------------------------------
39 // Implementation of Template
40
41
42 void Template::initialize(Bytecodes::Code code, int flags, TosState tos_in, TosState tos_out, generator gen, int arg) {
43 _code = code;
44 _flags = flags;
45 _tos_in = tos_in;
46 _tos_out = tos_out;
47 _gen = gen;
48 _arg = arg;
49 }
50
51
52 Bytecodes::Code Template::bytecode() const {
53 return _code;
54 // int i = this - TemplateTable::_template_table;
55 // if (i < 0 || i >= Bytecodes::number_of_codes) i = this - TemplateTable::_template_table_wide;
56 // return Bytecodes::cast(i);
57 }
58
59
60 void Template::generate(InterpreterMacroAssembler* masm) {
61 // parameter passing
62 TemplateTable::_desc = this;
63 TemplateTable::_masm = masm;
64 // code generation
65 _gen(_arg);
66 masm->flush();
67 }
68
69
70 //----------------------------------------------------------------------------------------------------
71 // Implementation of TemplateTable: Platform-independent helper routines
72
73 void TemplateTable::call_VM(Register oop_result, address entry_point) {
74 assert(_desc->calls_vm(), "inconsistent calls_vm information");
75 _masm->call_VM(oop_result, entry_point);
76 }
154 void TemplateTable::jsr() {
155 transition(vtos, vtos); // result is not an oop, so do not transition to atos
156 branch(true, false);
157 }
158
159
160
161 //----------------------------------------------------------------------------------------------------
162 // Implementation of TemplateTable: Debugging
163
164 void TemplateTable::transition(TosState tos_in, TosState tos_out) {
165 assert(_desc->tos_in() == tos_in , "inconsistent tos_in information");
166 assert(_desc->tos_out() == tos_out, "inconsistent tos_out information");
167 }
168
169
170 //----------------------------------------------------------------------------------------------------
171 // Implementation of TemplateTable: Initialization
172
173 bool TemplateTable::_is_initialized = false;
174 Template* TemplateTable::_template_table = NULL;
175 Template* TemplateTable::_template_table_wide = NULL;
176
177 Template* TemplateTable::_desc;
178 InterpreterMacroAssembler* TemplateTable::_masm;
179 BarrierSet* TemplateTable::_bs;
180
181
182 void TemplateTable::def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(), char filler) {
183 assert(filler == ' ', "just checkin'");
184 def(code, flags, in, out, (Template::generator)gen, 0);
185 }
186
187
188 void TemplateTable::def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(int arg), int arg) {
189 // should factor out these constants
190 const int ubcp = 1 << Template::uses_bcp_bit;
191 const int disp = 1 << Template::does_dispatch_bit;
192 const int clvm = 1 << Template::calls_vm_bit;
193 const int iswd = 1 << Template::wide_bit;
194 // determine which table to use
195 bool is_wide = (flags & iswd) != 0;
196 // make sure that wide instructions have a vtos entry point
197 // (since they are executed extremely rarely, it doesn't pay out to have an
198 // extra set of 5 dispatch tables for the wide instructions - for simplicity
199 // they all go with one table)
200 assert(in == vtos || !is_wide, "wide instructions have vtos entry point only");
201 Template* t = is_wide ? template_for_wide(code) : template_for(code);
202 // setup entry
203 t->initialize(code, flags, in, out, gen, arg);
204 assert(t->bytecode() == code, "just checkin'");
205 }
206
207
208 void TemplateTable::def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(Operation op), Operation op) {
209 def(code, flags, in, out, (Template::generator)gen, (int)op);
210 }
211
212
213 void TemplateTable::def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(bool arg ), bool arg) {
214 def(code, flags, in, out, (Template::generator)gen, (int)arg);
215 }
216
217
218 void TemplateTable::def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(TosState tos), TosState tos) {
219 def(code, flags, in, out, (Template::generator)gen, (int)tos);
220 }
221
222
223 void TemplateTable::def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(Condition cc), Condition cc) {
234 #define iload TemplateTable::iload
235 #define lload TemplateTable::lload
236 #define fload TemplateTable::fload
237 #define dload TemplateTable::dload
238 #define aload TemplateTable::aload
239 #define istore TemplateTable::istore
240 #define lstore TemplateTable::lstore
241 #define fstore TemplateTable::fstore
242 #define dstore TemplateTable::dstore
243 #define astore TemplateTable::astore
244 #endif // TEMPLATE_TABLE_BUG
245
246 void TemplateTable::initialize() {
247 if (_is_initialized) return;
248
249 // Initialize table
250 TraceStartupTime timer("TemplateTable initialization");
251
252 _bs = Universe::heap()->barrier_set();
253
254 TemplateTable::_template_table = NEW_C_HEAP_ARRAY(Template, Bytecodes::number_of_codes, mtInternal);
255 TemplateTable::_template_table_wide = NEW_C_HEAP_ARRAY(Template, Bytecodes::number_of_codes, mtInternal);
256
257 // For better readability
258 const char _ = ' ';
259 const int ____ = 0;
260 const int ubcp = 1 << Template::uses_bcp_bit;
261 const int disp = 1 << Template::does_dispatch_bit;
262 const int clvm = 1 << Template::calls_vm_bit;
263 const int iswd = 1 << Template::wide_bit;
264 // interpr. templates
265 // Java spec bytecodes ubcp|disp|clvm|iswd in out generator argument
266 def(Bytecodes::_nop , ____|____|____|____, vtos, vtos, nop , _ );
267 def(Bytecodes::_aconst_null , ____|____|____|____, vtos, atos, aconst_null , _ );
268 def(Bytecodes::_iconst_m1 , ____|____|____|____, vtos, itos, iconst , -1 );
269 def(Bytecodes::_iconst_0 , ____|____|____|____, vtos, itos, iconst , 0 );
270 def(Bytecodes::_iconst_1 , ____|____|____|____, vtos, itos, iconst , 1 );
271 def(Bytecodes::_iconst_2 , ____|____|____|____, vtos, itos, iconst , 2 );
272 def(Bytecodes::_iconst_3 , ____|____|____|____, vtos, itos, iconst , 3 );
273 def(Bytecodes::_iconst_4 , ____|____|____|____, vtos, itos, iconst , 4 );
274 def(Bytecodes::_iconst_5 , ____|____|____|____, vtos, itos, iconst , 5 );
275 def(Bytecodes::_lconst_0 , ____|____|____|____, vtos, ltos, lconst , 0 );
276 def(Bytecodes::_lconst_1 , ____|____|____|____, vtos, ltos, lconst , 1 );
458 def(Bytecodes::_checkcast , ubcp|____|clvm|____, atos, atos, checkcast , _ );
459 def(Bytecodes::_instanceof , ubcp|____|clvm|____, atos, itos, instanceof , _ );
460 def(Bytecodes::_monitorenter , ____|disp|clvm|____, atos, vtos, monitorenter , _ );
461 def(Bytecodes::_monitorexit , ____|____|clvm|____, atos, vtos, monitorexit , _ );
462 def(Bytecodes::_wide , ubcp|disp|____|____, vtos, vtos, wide , _ );
463 def(Bytecodes::_multianewarray , ubcp|____|clvm|____, vtos, atos, multianewarray , _ );
464 def(Bytecodes::_ifnull , ubcp|____|clvm|____, atos, vtos, if_nullcmp , equal );
465 def(Bytecodes::_ifnonnull , ubcp|____|clvm|____, atos, vtos, if_nullcmp , not_equal );
466 def(Bytecodes::_goto_w , ubcp|____|clvm|____, vtos, vtos, goto_w , _ );
467 def(Bytecodes::_jsr_w , ubcp|____|____|____, vtos, vtos, jsr_w , _ );
468 def(Bytecodes::_breakpoint , ubcp|disp|clvm|____, vtos, vtos, _breakpoint , _ );
469 def(Bytecodes::_vload , ubcp|____|clvm|____, vtos, qtos, vload , _ );
470 def(Bytecodes::_vstore , ubcp|____|clvm|____, vtos, vtos, vstore , _ );
471 def(Bytecodes::_vaload , ____|____|clvm|____, itos, qtos, vaload , _ );
472 def(Bytecodes::_vastore , ____|____|clvm|____, vtos, vtos, vastore , _ );
473 def(Bytecodes::_vnew , ubcp|____|clvm|____, vtos, qtos, _vnew , _ );
474 def(Bytecodes::_vnewarray , ubcp|____|clvm|____, itos, atos, vnewarray , _ );
475 def(Bytecodes::_multivnewarray , ubcp|____|clvm|____, vtos, atos, multianewarray , _ );
476 def(Bytecodes::_vreturn , ____|disp|clvm|____, qtos, qtos, _return , qtos );
477 def(Bytecodes::_vgetfield , ubcp|____|clvm|____, vtos, vtos, vgetfield , f1_byte );
478 def(Bytecodes::_typed , ubcp|disp|clvm|____, vtos, vtos, typed , _ );
479 def(Bytecodes::_invokedirect , ubcp|disp|clvm|____, vtos, vtos, invokedirect , f2_byte );
480 def(Bytecodes::_vbox , ubcp|____|clvm|____, qtos, atos, _vbox , _ );
481 def(Bytecodes::_vunbox , ubcp|____|clvm|____, atos, qtos, _vunbox , _ );
482
483 // wide Java spec bytecodes
484 def(Bytecodes::_iload , ubcp|____|____|iswd, vtos, itos, wide_iload , _ );
485 def(Bytecodes::_lload , ubcp|____|____|iswd, vtos, ltos, wide_lload , _ );
486 def(Bytecodes::_fload , ubcp|____|____|iswd, vtos, ftos, wide_fload , _ );
487 def(Bytecodes::_dload , ubcp|____|____|iswd, vtos, dtos, wide_dload , _ );
488 def(Bytecodes::_aload , ubcp|____|____|iswd, vtos, atos, wide_aload , _ );
489 def(Bytecodes::_vload , ubcp|____|____|iswd, vtos, qtos, wide_vload , _ );
490 def(Bytecodes::_istore , ubcp|____|____|iswd, vtos, vtos, wide_istore , _ );
491 def(Bytecodes::_lstore , ubcp|____|____|iswd, vtos, vtos, wide_lstore , _ );
492 def(Bytecodes::_fstore , ubcp|____|____|iswd, vtos, vtos, wide_fstore , _ );
493 def(Bytecodes::_dstore , ubcp|____|____|iswd, vtos, vtos, wide_dstore , _ );
494 def(Bytecodes::_astore , ubcp|____|____|iswd, vtos, vtos, wide_astore , _ );
495 def(Bytecodes::_vstore , ubcp|____|____|iswd, vtos, vtos, wide_vstore , _ );
496 def(Bytecodes::_iinc , ubcp|____|____|iswd, vtos, vtos, wide_iinc , _ );
497 def(Bytecodes::_ret , ubcp|disp|____|iswd, vtos, vtos, wide_ret , _ );
498
552 }
553
554 #if defined(TEMPLATE_TABLE_BUG)
555 #undef iload
556 #undef lload
557 #undef fload
558 #undef dload
559 #undef aload
560 #undef istore
561 #undef lstore
562 #undef fstore
563 #undef dstore
564 #undef astore
565 #endif // TEMPLATE_TABLE_BUG
566
567
568 void templateTable_init() {
569 TemplateTable::initialize();
570 }
571
572 void TemplateTable::cleanup() {
573 FREE_C_HEAP_ARRAY(Template, TemplateTable::_template_table);
574 TemplateTable::_template_table = NULL;
575 FREE_C_HEAP_ARRAY(Template, TemplateTable::_template_table_wide);
576 TemplateTable::_template_table_wide = NULL;
577 }
578
579 void TemplateTable::unimplemented_bc() {
580 _masm->unimplemented( Bytecodes::name(_desc->bytecode()));
581 }
582 #endif /* !CC_INTERP */
|