1.1 --- a/src/share/vm/asm/assembler.cpp Tue Mar 03 18:25:57 2009 -0800 1.2 +++ b/src/share/vm/asm/assembler.cpp Wed Mar 04 09:58:39 2009 -0800 1.3 @@ -239,6 +239,78 @@ 1.4 } 1.5 } 1.6 1.7 +struct DelayedConstant { 1.8 + typedef void (*value_fn_t)(); 1.9 + BasicType type; 1.10 + intptr_t value; 1.11 + value_fn_t value_fn; 1.12 + // This limit of 20 is generous for initial uses. 1.13 + // The limit needs to be large enough to store the field offsets 1.14 + // into classes which do not have statically fixed layouts. 1.15 + // (Initial use is for method handle object offsets.) 1.16 + // Look for uses of "delayed_value" in the source code 1.17 + // and make sure this number is generous enough to handle all of them. 1.18 + enum { DC_LIMIT = 20 }; 1.19 + static DelayedConstant delayed_constants[DC_LIMIT]; 1.20 + static DelayedConstant* add(BasicType type, value_fn_t value_fn); 1.21 + bool match(BasicType t, value_fn_t cfn) { 1.22 + return type == t && value_fn == cfn; 1.23 + } 1.24 + static void update_all(); 1.25 +}; 1.26 + 1.27 +DelayedConstant DelayedConstant::delayed_constants[DC_LIMIT]; 1.28 +// Default C structure initialization rules have the following effect here: 1.29 +// = { { (BasicType)0, (intptr_t)NULL }, ... }; 1.30 + 1.31 +DelayedConstant* DelayedConstant::add(BasicType type, 1.32 + DelayedConstant::value_fn_t cfn) { 1.33 + for (int i = 0; i < DC_LIMIT; i++) { 1.34 + DelayedConstant* dcon = &delayed_constants[i]; 1.35 + if (dcon->match(type, cfn)) 1.36 + return dcon; 1.37 + if (dcon->value_fn == NULL) { 1.38 + // (cmpxchg not because this is multi-threaded but because I'm paranoid) 1.39 + if (Atomic::cmpxchg_ptr(CAST_FROM_FN_PTR(void*, cfn), &dcon->value_fn, NULL) == NULL) { 1.40 + dcon->type = type; 1.41 + return dcon; 1.42 + } 1.43 + } 1.44 + } 1.45 + // If this assert is hit (in pre-integration testing!) then re-evaluate 1.46 + // the comment on the definition of DC_LIMIT. 1.47 + guarantee(false, "too many delayed constants"); 1.48 + return NULL; 1.49 +} 1.50 + 1.51 +void DelayedConstant::update_all() { 1.52 + for (int i = 0; i < DC_LIMIT; i++) { 1.53 + DelayedConstant* dcon = &delayed_constants[i]; 1.54 + if (dcon->value_fn != NULL && dcon->value == 0) { 1.55 + typedef int (*int_fn_t)(); 1.56 + typedef address (*address_fn_t)(); 1.57 + switch (dcon->type) { 1.58 + case T_INT: dcon->value = (intptr_t) ((int_fn_t) dcon->value_fn)(); break; 1.59 + case T_ADDRESS: dcon->value = (intptr_t) ((address_fn_t)dcon->value_fn)(); break; 1.60 + } 1.61 + } 1.62 + } 1.63 +} 1.64 + 1.65 +intptr_t* AbstractAssembler::delayed_value_addr(int(*value_fn)()) { 1.66 + DelayedConstant* dcon = DelayedConstant::add(T_INT, (DelayedConstant::value_fn_t) value_fn); 1.67 + return &dcon->value; 1.68 +} 1.69 +intptr_t* AbstractAssembler::delayed_value_addr(address(*value_fn)()) { 1.70 + DelayedConstant* dcon = DelayedConstant::add(T_ADDRESS, (DelayedConstant::value_fn_t) value_fn); 1.71 + return &dcon->value; 1.72 +} 1.73 +void AbstractAssembler::update_delayed_values() { 1.74 + DelayedConstant::update_all(); 1.75 +} 1.76 + 1.77 + 1.78 + 1.79 1.80 void AbstractAssembler::block_comment(const char* comment) { 1.81 if (sect() == CodeBuffer::SECT_INSTS) {