6812678: macro assembler needs delayed binding of a few constants (for 6655638)

Minor assembler enhancements preparing for method handles

Reviewed-by: kvn
This commit is contained in:
John R Rose 2009-03-04 09:58:39 -08:00
parent 3e2ae68252
commit 07321dec65
17 changed files with 467 additions and 83 deletions

View file

@ -140,6 +140,28 @@ class Label VALUE_OBJ_CLASS_SPEC {
}
};
// A union type for code which has to assemble both constant and
// non-constant operands, when the distinction cannot be made
// statically.
class RegisterConstant VALUE_OBJ_CLASS_SPEC {
private:
Register _r;
intptr_t _c;
public:
RegisterConstant(): _r(noreg), _c(0) {}
RegisterConstant(Register r): _r(r), _c(0) {}
RegisterConstant(intptr_t c): _r(noreg), _c(c) {}
Register as_register() const { assert(is_register(),""); return _r; }
intptr_t as_constant() const { assert(is_constant(),""); return _c; }
Register register_or_noreg() const { return _r; }
intptr_t constant_or_zero() const { return _c; }
bool is_register() const { return _r != noreg; }
bool is_constant() const { return _r == noreg; }
};
// The Abstract Assembler: Pure assembler doing NO optimizations on the
// instruction level; i.e., what you write is what you get.
@ -280,6 +302,26 @@ class AbstractAssembler : public ResourceObj {
inline address address_constant(Label& L);
inline address address_table_constant(GrowableArray<Label*> label);
// Bootstrapping aid to cope with delayed determination of constants.
// Returns a static address which will eventually contain the constant.
// The value zero (NULL) stands instead of a constant which is still uncomputed.
// Thus, the eventual value of the constant must not be zero.
// This is fine, since this is designed for embedding object field
// offsets in code which must be generated before the object class is loaded.
// Field offsets are never zero, since an object's header (mark word)
// is located at offset zero.
RegisterConstant delayed_value(int(*value_fn)(), Register tmp, int offset = 0) {
return delayed_value(delayed_value_addr(value_fn), tmp, offset);
}
RegisterConstant delayed_value(address(*value_fn)(), Register tmp, int offset = 0) {
return delayed_value(delayed_value_addr(value_fn), tmp, offset);
}
virtual RegisterConstant delayed_value(intptr_t* delayed_value_addr, Register tmp, int offset) = 0;
// Last overloading is platform-dependent; look in assembler_<arch>.cpp.
static intptr_t* delayed_value_addr(int(*constant_fn)());
static intptr_t* delayed_value_addr(address(*constant_fn)());
static void update_delayed_values();
// Bang stack to trigger StackOverflowError at a safe location
// implementation delegates to machine-specific bang_stack_with_offset
void generate_stack_overflow_check( int frame_size_in_bytes );