133 if (_release_icholder) {
134 assert(_is_icholder, "must be");
135 CompiledICHolder* icholder = (CompiledICHolder*)_cached_value;
136 icholder->claim();
137 delete icholder;
138 }
139 }
140 };
141
142 class CompiledIC: public ResourceObj {
143 friend class InlineCacheBuffer;
144 friend class ICStub;
145
146
147 private:
148 NativeCall* _ic_call; // the call instruction
149 NativeMovConstReg* _value; // patchable value cell for this IC
150 bool _is_optimized; // an optimized virtual call (i.e., no compiled IC)
151
152 CompiledIC(nmethod* nm, NativeCall* ic_call);
153
154 static bool is_icholder_entry(address entry);
155
156 // low-level inline-cache manipulation. Cannot be accessed directly, since it might not be MT-safe
157 // to change an inline-cache. These changes the underlying inline-cache directly. They *newer* make
158 // changes to a transition stub.
159 void internal_set_ic_destination(address entry_point, bool is_icstub, void* cache, bool is_icholder);
160 void set_ic_destination(ICStub* stub);
161 void set_ic_destination(address entry_point) {
162 assert(_is_optimized, "use set_ic_destination_and_value instead");
163 internal_set_ic_destination(entry_point, false, NULL, false);
164 }
165 // This only for use by ICStubs where the type of the value isn't known
166 void set_ic_destination_and_value(address entry_point, void* value) {
167 internal_set_ic_destination(entry_point, false, value, is_icholder_entry(entry_point));
168 }
169 void set_ic_destination_and_value(address entry_point, Metadata* value) {
170 internal_set_ic_destination(entry_point, false, value, false);
171 }
172 void set_ic_destination_and_value(address entry_point, CompiledICHolder* value) {
173 internal_set_ic_destination(entry_point, false, value, true);
174 }
175
176 // Reads the location of the transition stub. This will fail with an assertion, if no transition stub is
177 // associated with the inline cache.
178 address stub_address() const;
179 bool is_in_transition_state() const; // Use InlineCacheBuffer
180
181 public:
182 // conversion (machine PC to CompiledIC*)
183 friend CompiledIC* CompiledIC_before(nmethod* nm, address return_addr);
184 friend CompiledIC* CompiledIC_at(nmethod* nm, address call_site);
185 friend CompiledIC* CompiledIC_at(Relocation* call_site);
186
187 // This is used to release CompiledICHolder*s from nmethods that
188 // are about to be freed. The callsite might contain other stale
189 // values of other kinds so it must be careful.
190 static void cleanup_call_site(virtual_call_Relocation* call_site);
191 static bool is_icholder_call_site(virtual_call_Relocation* call_site);
192
193 // Return the cached_metadata/destination associated with this inline cache. If the cache currently points
194 // to a transition stub, it will read the values from the transition stub.
195 void* cached_value() const;
196 CompiledICHolder* cached_icholder() const {
197 assert(is_icholder_call(), "must be");
198 return (CompiledICHolder*) cached_value();
199 }
200 Metadata* cached_metadata() const {
201 assert(!is_icholder_call(), "must be");
202 return (Metadata*) cached_value();
203 }
204
205 address ic_destination() const;
246 inline CompiledIC* CompiledIC_before(nmethod* nm, address return_addr) {
247 CompiledIC* c_ic = new CompiledIC(nm, nativeCall_before(return_addr));
248 c_ic->verify();
249 return c_ic;
250 }
251
252 inline CompiledIC* CompiledIC_at(nmethod* nm, address call_site) {
253 CompiledIC* c_ic = new CompiledIC(nm, nativeCall_at(call_site));
254 c_ic->verify();
255 return c_ic;
256 }
257
258 inline CompiledIC* CompiledIC_at(Relocation* call_site) {
259 assert(call_site->type() == relocInfo::virtual_call_type ||
260 call_site->type() == relocInfo::opt_virtual_call_type, "wrong reloc. info");
261 CompiledIC* c_ic = new CompiledIC(call_site->code(), nativeCall_at(call_site->addr()));
262 c_ic->verify();
263 return c_ic;
264 }
265
266
267 //-----------------------------------------------------------------------------
268 // The CompiledStaticCall represents a call to a static method in the compiled
269 //
270 // Transition diagram of a static call site is somewhat simpler than for an inlined cache:
271 //
272 //
273 // -----<----- Clean ----->-----
274 // / \
275 // / \
276 // compilled code <------------> interpreted code
277 //
278 // Clean: Calls directly to runtime method for fixup
279 // Compiled code: Calls directly to compiled code
280 // Interpreted code: Calls to stub that set Method* reference
281 //
282 //
283 class CompiledStaticCall;
284
285 class StaticCallInfo {
|
133 if (_release_icholder) {
134 assert(_is_icholder, "must be");
135 CompiledICHolder* icholder = (CompiledICHolder*)_cached_value;
136 icholder->claim();
137 delete icholder;
138 }
139 }
140 };
141
142 class CompiledIC: public ResourceObj {
143 friend class InlineCacheBuffer;
144 friend class ICStub;
145
146
147 private:
148 NativeCall* _ic_call; // the call instruction
149 NativeMovConstReg* _value; // patchable value cell for this IC
150 bool _is_optimized; // an optimized virtual call (i.e., no compiled IC)
151
152 CompiledIC(nmethod* nm, NativeCall* ic_call);
153 CompiledIC(RelocIterator* iter);
154
155 void initialize_from_iter(RelocIterator* iter);
156
157 static bool is_icholder_entry(address entry);
158
159 // low-level inline-cache manipulation. Cannot be accessed directly, since it might not be MT-safe
160 // to change an inline-cache. These changes the underlying inline-cache directly. They *newer* make
161 // changes to a transition stub.
162 void internal_set_ic_destination(address entry_point, bool is_icstub, void* cache, bool is_icholder);
163 void set_ic_destination(ICStub* stub);
164 void set_ic_destination(address entry_point) {
165 assert(_is_optimized, "use set_ic_destination_and_value instead");
166 internal_set_ic_destination(entry_point, false, NULL, false);
167 }
168 // This only for use by ICStubs where the type of the value isn't known
169 void set_ic_destination_and_value(address entry_point, void* value) {
170 internal_set_ic_destination(entry_point, false, value, is_icholder_entry(entry_point));
171 }
172 void set_ic_destination_and_value(address entry_point, Metadata* value) {
173 internal_set_ic_destination(entry_point, false, value, false);
174 }
175 void set_ic_destination_and_value(address entry_point, CompiledICHolder* value) {
176 internal_set_ic_destination(entry_point, false, value, true);
177 }
178
179 // Reads the location of the transition stub. This will fail with an assertion, if no transition stub is
180 // associated with the inline cache.
181 address stub_address() const;
182 bool is_in_transition_state() const; // Use InlineCacheBuffer
183
184 public:
185 // conversion (machine PC to CompiledIC*)
186 friend CompiledIC* CompiledIC_before(nmethod* nm, address return_addr);
187 friend CompiledIC* CompiledIC_at(nmethod* nm, address call_site);
188 friend CompiledIC* CompiledIC_at(Relocation* call_site);
189 friend CompiledIC* CompiledIC_at(RelocIterator* reloc_iter);
190
191 // This is used to release CompiledICHolder*s from nmethods that
192 // are about to be freed. The callsite might contain other stale
193 // values of other kinds so it must be careful.
194 static void cleanup_call_site(virtual_call_Relocation* call_site);
195 static bool is_icholder_call_site(virtual_call_Relocation* call_site);
196
197 // Return the cached_metadata/destination associated with this inline cache. If the cache currently points
198 // to a transition stub, it will read the values from the transition stub.
199 void* cached_value() const;
200 CompiledICHolder* cached_icholder() const {
201 assert(is_icholder_call(), "must be");
202 return (CompiledICHolder*) cached_value();
203 }
204 Metadata* cached_metadata() const {
205 assert(!is_icholder_call(), "must be");
206 return (Metadata*) cached_value();
207 }
208
209 address ic_destination() const;
250 inline CompiledIC* CompiledIC_before(nmethod* nm, address return_addr) {
251 CompiledIC* c_ic = new CompiledIC(nm, nativeCall_before(return_addr));
252 c_ic->verify();
253 return c_ic;
254 }
255
256 inline CompiledIC* CompiledIC_at(nmethod* nm, address call_site) {
257 CompiledIC* c_ic = new CompiledIC(nm, nativeCall_at(call_site));
258 c_ic->verify();
259 return c_ic;
260 }
261
262 inline CompiledIC* CompiledIC_at(Relocation* call_site) {
263 assert(call_site->type() == relocInfo::virtual_call_type ||
264 call_site->type() == relocInfo::opt_virtual_call_type, "wrong reloc. info");
265 CompiledIC* c_ic = new CompiledIC(call_site->code(), nativeCall_at(call_site->addr()));
266 c_ic->verify();
267 return c_ic;
268 }
269
270 inline CompiledIC* CompiledIC_at(RelocIterator* reloc_iter) {
271 assert(reloc_iter->type() == relocInfo::virtual_call_type ||
272 reloc_iter->type() == relocInfo::opt_virtual_call_type, "wrong reloc. info");
273 CompiledIC* c_ic = new CompiledIC(reloc_iter);
274 c_ic->verify();
275 return c_ic;
276 }
277
278 //-----------------------------------------------------------------------------
279 // The CompiledStaticCall represents a call to a static method in the compiled
280 //
281 // Transition diagram of a static call site is somewhat simpler than for an inlined cache:
282 //
283 //
284 // -----<----- Clean ----->-----
285 // / \
286 // / \
287 // compilled code <------------> interpreted code
288 //
289 // Clean: Calls directly to runtime method for fixup
290 // Compiled code: Calls directly to compiled code
291 // Interpreted code: Calls to stub that set Method* reference
292 //
293 //
294 class CompiledStaticCall;
295
296 class StaticCallInfo {
|