59
60 #ifndef PRODUCT
61 if (CountCompiledCalls) {
62 __ inc_counter(SharedRuntime::nof_megamorphic_calls_addr(), G5, G3_scratch);
63 }
64 #endif /* PRODUCT */
65
66 assert(VtableStub::receiver_location() == O0->as_VMReg(), "receiver expected in O0");
67
68 // get receiver klass
69 address npe_addr = __ pc();
70 __ load_klass(O0, G3_scratch);
71
72 // set methodOop (in case of interpreted method), and destination address
73 int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
74 #ifndef PRODUCT
75 if (DebugVtables) {
76 Label L;
77 // check offset vs vtable length
78 __ ld(G3_scratch, instanceKlass::vtable_length_offset()*wordSize, G5);
79 __ cmp(G5, vtable_index*vtableEntry::size());
80 __ br(Assembler::greaterUnsigned, false, Assembler::pt, L);
81 __ delayed()->nop();
82 __ set(vtable_index, O2);
83 __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), O0, O2);
84 __ bind(L);
85 }
86 #endif
87 int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
88 if( __ is_simm13(v_off) ) {
89 __ ld_ptr(G3, v_off, G5_method);
90 } else {
91 __ set(v_off,G5);
92 __ ld_ptr(G3, G5, G5_method);
93 }
94
95 #ifndef PRODUCT
96 if (DebugVtables) {
97 Label L;
98 __ br_notnull(G5_method, false, Assembler::pt, L);
99 __ delayed()->nop();
100 __ stop("Vtable entry is ZERO");
101 __ bind(L);
102 }
103 #endif
104
105 address ame_addr = __ pc(); // if the vtable entry is null, the method is abstract
106 // NOTE: for vtable dispatches, the vtable entry will never be null.
107
108 __ ld_ptr(G5_method, in_bytes(methodOopDesc::from_compiled_offset()), G3_scratch);
109
110 // jump to target (either compiled code or c2iadapter)
111 __ JMP(G3_scratch, 0);
112 // load methodOop (in case we call c2iadapter)
113 __ delayed()->nop();
114
115 masm->flush();
116
117 if (PrintMiscellaneous && (WizardMode || Verbose)) {
118 tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d",
119 vtable_index, s->entry_point(),
160 __ save(SP,-frame::register_save_words*wordSize,SP);
161
162 #ifndef PRODUCT
163 if (CountCompiledCalls) {
164 __ inc_counter(SharedRuntime::nof_megamorphic_calls_addr(), L0, L1);
165 }
166 #endif /* PRODUCT */
167
168 Label throw_icce;
169
170 Register L5_method = L5;
171 __ lookup_interface_method(// inputs: rec. class, interface, itable index
172 G3_klassOop, G5_interface, itable_index,
173 // outputs: method, scan temp. reg
174 L5_method, L2, L3,
175 throw_icce);
176
177 #ifndef PRODUCT
178 if (DebugVtables) {
179 Label L01;
180 __ bpr(Assembler::rc_nz, false, Assembler::pt, L5_method, L01);
181 __ delayed()->nop();
182 __ stop("methodOop is null");
183 __ bind(L01);
184 __ verify_oop(L5_method);
185 }
186 #endif
187
188 // If the following load is through a NULL pointer, we'll take an OS
189 // exception that should translate into an AbstractMethodError. We need the
190 // window count to be correct at that time.
191 __ restore(L5_method, 0, G5_method);
192 // Restore registers *before* the AME point.
193
194 address ame_addr = __ pc(); // if the vtable entry is null, the method is abstract
195 __ ld_ptr(G5_method, in_bytes(methodOopDesc::from_compiled_offset()), G3_scratch);
196
197 // G5_method: methodOop
198 // O0: Receiver
199 // G3_scratch: entry point
200 __ JMP(G3_scratch, 0);
201 __ delayed()->nop();
|
59
60 #ifndef PRODUCT
61 if (CountCompiledCalls) {
62 __ inc_counter(SharedRuntime::nof_megamorphic_calls_addr(), G5, G3_scratch);
63 }
64 #endif /* PRODUCT */
65
66 assert(VtableStub::receiver_location() == O0->as_VMReg(), "receiver expected in O0");
67
68 // get receiver klass
69 address npe_addr = __ pc();
70 __ load_klass(O0, G3_scratch);
71
72 // set methodOop (in case of interpreted method), and destination address
73 int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
74 #ifndef PRODUCT
75 if (DebugVtables) {
76 Label L;
77 // check offset vs vtable length
78 __ ld(G3_scratch, instanceKlass::vtable_length_offset()*wordSize, G5);
79 __ cmp_and_br_short(G5, vtable_index*vtableEntry::size(), Assembler::greaterUnsigned, Assembler::pt, L);
80 __ set(vtable_index, O2);
81 __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), O0, O2);
82 __ bind(L);
83 }
84 #endif
85 int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
86 if( __ is_simm13(v_off) ) {
87 __ ld_ptr(G3, v_off, G5_method);
88 } else {
89 __ set(v_off,G5);
90 __ ld_ptr(G3, G5, G5_method);
91 }
92
93 #ifndef PRODUCT
94 if (DebugVtables) {
95 Label L;
96 __ br_notnull_short(G5_method, Assembler::pt, L);
97 __ stop("Vtable entry is ZERO");
98 __ bind(L);
99 }
100 #endif
101
102 address ame_addr = __ pc(); // if the vtable entry is null, the method is abstract
103 // NOTE: for vtable dispatches, the vtable entry will never be null.
104
105 __ ld_ptr(G5_method, in_bytes(methodOopDesc::from_compiled_offset()), G3_scratch);
106
107 // jump to target (either compiled code or c2iadapter)
108 __ JMP(G3_scratch, 0);
109 // load methodOop (in case we call c2iadapter)
110 __ delayed()->nop();
111
112 masm->flush();
113
114 if (PrintMiscellaneous && (WizardMode || Verbose)) {
115 tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d",
116 vtable_index, s->entry_point(),
157 __ save(SP,-frame::register_save_words*wordSize,SP);
158
159 #ifndef PRODUCT
160 if (CountCompiledCalls) {
161 __ inc_counter(SharedRuntime::nof_megamorphic_calls_addr(), L0, L1);
162 }
163 #endif /* PRODUCT */
164
165 Label throw_icce;
166
167 Register L5_method = L5;
168 __ lookup_interface_method(// inputs: rec. class, interface, itable index
169 G3_klassOop, G5_interface, itable_index,
170 // outputs: method, scan temp. reg
171 L5_method, L2, L3,
172 throw_icce);
173
174 #ifndef PRODUCT
175 if (DebugVtables) {
176 Label L01;
177 __ br_notnull_short(L5_method, Assembler::pt, L01);
178 __ stop("methodOop is null");
179 __ bind(L01);
180 __ verify_oop(L5_method);
181 }
182 #endif
183
184 // If the following load is through a NULL pointer, we'll take an OS
185 // exception that should translate into an AbstractMethodError. We need the
186 // window count to be correct at that time.
187 __ restore(L5_method, 0, G5_method);
188 // Restore registers *before* the AME point.
189
190 address ame_addr = __ pc(); // if the vtable entry is null, the method is abstract
191 __ ld_ptr(G5_method, in_bytes(methodOopDesc::from_compiled_offset()), G3_scratch);
192
193 // G5_method: methodOop
194 // O0: Receiver
195 // G3_scratch: entry point
196 __ JMP(G3_scratch, 0);
197 __ delayed()->nop();
|