comparison src/share/vm/asm/assembler.cpp @ 622:56aae7be60d4

6812678: macro assembler needs delayed binding of a few constants (for 6655638) Summary: minor assembler enhancements preparing for method handles Reviewed-by: kvn
author jrose
date Wed, 04 Mar 2009 09:58:39 -0800
parents 98cb887364d3
children 660978a2a31a
comparison
equal deleted inserted replaced
621:19f25e603e7b 622:56aae7be60d4
237 // Push the target offset into the branch instruction. 237 // Push the target offset into the branch instruction.
238 masm->pd_patch_instruction(branch, target); 238 masm->pd_patch_instruction(branch, target);
239 } 239 }
240 } 240 }
241 241
242 struct DelayedConstant {
243 typedef void (*value_fn_t)();
244 BasicType type;
245 intptr_t value;
246 value_fn_t value_fn;
247 // This limit of 20 is generous for initial uses.
248 // The limit needs to be large enough to store the field offsets
249 // into classes which do not have statically fixed layouts.
250 // (Initial use is for method handle object offsets.)
251 // Look for uses of "delayed_value" in the source code
252 // and make sure this number is generous enough to handle all of them.
253 enum { DC_LIMIT = 20 };
254 static DelayedConstant delayed_constants[DC_LIMIT];
255 static DelayedConstant* add(BasicType type, value_fn_t value_fn);
256 bool match(BasicType t, value_fn_t cfn) {
257 return type == t && value_fn == cfn;
258 }
259 static void update_all();
260 };
261
262 DelayedConstant DelayedConstant::delayed_constants[DC_LIMIT];
263 // Default C structure initialization rules have the following effect here:
264 // = { { (BasicType)0, (intptr_t)NULL }, ... };
265
266 DelayedConstant* DelayedConstant::add(BasicType type,
267 DelayedConstant::value_fn_t cfn) {
268 for (int i = 0; i < DC_LIMIT; i++) {
269 DelayedConstant* dcon = &delayed_constants[i];
270 if (dcon->match(type, cfn))
271 return dcon;
272 if (dcon->value_fn == NULL) {
273 // (cmpxchg not because this is multi-threaded but because I'm paranoid)
274 if (Atomic::cmpxchg_ptr(CAST_FROM_FN_PTR(void*, cfn), &dcon->value_fn, NULL) == NULL) {
275 dcon->type = type;
276 return dcon;
277 }
278 }
279 }
280 // If this assert is hit (in pre-integration testing!) then re-evaluate
281 // the comment on the definition of DC_LIMIT.
282 guarantee(false, "too many delayed constants");
283 return NULL;
284 }
285
286 void DelayedConstant::update_all() {
287 for (int i = 0; i < DC_LIMIT; i++) {
288 DelayedConstant* dcon = &delayed_constants[i];
289 if (dcon->value_fn != NULL && dcon->value == 0) {
290 typedef int (*int_fn_t)();
291 typedef address (*address_fn_t)();
292 switch (dcon->type) {
293 case T_INT: dcon->value = (intptr_t) ((int_fn_t) dcon->value_fn)(); break;
294 case T_ADDRESS: dcon->value = (intptr_t) ((address_fn_t)dcon->value_fn)(); break;
295 }
296 }
297 }
298 }
299
300 intptr_t* AbstractAssembler::delayed_value_addr(int(*value_fn)()) {
301 DelayedConstant* dcon = DelayedConstant::add(T_INT, (DelayedConstant::value_fn_t) value_fn);
302 return &dcon->value;
303 }
304 intptr_t* AbstractAssembler::delayed_value_addr(address(*value_fn)()) {
305 DelayedConstant* dcon = DelayedConstant::add(T_ADDRESS, (DelayedConstant::value_fn_t) value_fn);
306 return &dcon->value;
307 }
308 void AbstractAssembler::update_delayed_values() {
309 DelayedConstant::update_all();
310 }
311
312
313
242 314
243 void AbstractAssembler::block_comment(const char* comment) { 315 void AbstractAssembler::block_comment(const char* comment) {
244 if (sect() == CodeBuffer::SECT_INSTS) { 316 if (sect() == CodeBuffer::SECT_INSTS) {
245 code_section()->outer()->block_comment(offset(), comment); 317 code_section()->outer()->block_comment(offset(), comment);
246 } 318 }