src/cpu/sparc/vm/assembler_sparc.hpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File hotspot-dvm Cdiff src/cpu/sparc/vm/assembler_sparc.hpp

src/cpu/sparc/vm/assembler_sparc.hpp

Print this page
rev 522 : [mq]: meth.patch

*** 82,101 **** // These globals are used as short-lived scratch registers in the compiler: REGISTER_DECLARATION(Register, Gtemp , G5); // The compiler requires that G5_megamorphic_method is G5_inline_cache_klass, // because a single patchable "set" instruction (NativeMovConstReg, // or NativeMovConstPatching for compiler1) instruction // serves to set up either quantity, depending on whether the compiled // call site is an inline cache or is megamorphic. See the function // CompiledIC::set_to_megamorphic. // ! // On the other hand, G5_inline_cache_klass must differ from G5_method, ! // because both registers are needed for an inline cache that calls ! // an interpreted method. // // Note that G5_method is only the method-self for the interpreter, // and is logically unrelated to G5_megamorphic_method. // // Invariants on G2_thread (the JavaThread pointer): --- 82,109 ---- // These globals are used as short-lived scratch registers in the compiler: REGISTER_DECLARATION(Register, Gtemp , G5); + // JSR 292 fixed register usages: + REGISTER_DECLARATION(Register, G5_method_type , G5); + REGISTER_DECLARATION(Register, G3_method_handle , G3); + // The compiler requires that G5_megamorphic_method is G5_inline_cache_klass, // because a single patchable "set" instruction (NativeMovConstReg, // or NativeMovConstPatching for compiler1) instruction // serves to set up either quantity, depending on whether the compiled // call site is an inline cache or is megamorphic. See the function // CompiledIC::set_to_megamorphic. // ! // If a inline cache targets an interpreted method, then the ! // G5 register will be used twice during the call. First, ! // the call site will be patched to load a compiledICHolder ! // into G5. (This is an ordered pair of ic_klass, method.) ! // The c2i adapter will first check the ic_klass, then load ! // G5_method with the method part of the pair just before ! // jumping into the interpreter. // // Note that G5_method is only the method-self for the interpreter, // and is logically unrelated to G5_megamorphic_method. // // Invariants on G2_thread (the JavaThread pointer):
*** 257,266 **** --- 265,295 ---- #define Oissuing_pc AS_REGISTER(Register, Oissuing_pc) #endif + // A union type for code which has to assemble both constant and non-constant operands. + 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; } + }; + // Address is an abstraction used to represent a memory location. // // Note: A register location is represented via a Register, not // via an address for efficiency & simplicity reasons.
*** 1080,1091 **** --- 1109,1122 ---- // pp 135 (addc was addx in v8) inline void add( Register s1, Register s2, Register d ); inline void add( Register s1, int simm13a, Register d, relocInfo::relocType rtype = relocInfo::none); inline void add( Register s1, int simm13a, Register d, RelocationHolder const& rspec); + inline void add( Register s1, RegisterConstant s2, Register d, int offset = 0); inline void add( const Address& a, Register d, int offset = 0); + void addcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } void addcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } void addc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | rs2(s2) ); } void addc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } void addccc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
*** 1296,1305 **** --- 1327,1341 ---- inline void lduw( const Address& a, Register d, int offset = 0 ); inline void ldx( const Address& a, Register d, int offset = 0 ); inline void ld( const Address& a, Register d, int offset = 0 ); inline void ldd( const Address& a, Register d, int offset = 0 ); + inline void ld( Register s1, RegisterConstant s2, Register d ); + inline void lduw( Register s1, RegisterConstant s2, Register d ); + inline void ldsw( Register s1, RegisterConstant s2, Register d ); + inline void ldx( Register s1, RegisterConstant s2, Register d ); + // pp 177 void ldsba( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } void ldsba( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsb_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } void ldsha( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsh_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
*** 1516,1525 **** --- 1552,1564 ---- inline void stw( Register d, const Address& a, int offset = 0 ); inline void stx( Register d, const Address& a, int offset = 0 ); inline void st( Register d, const Address& a, int offset = 0 ); inline void std( Register d, const Address& a, int offset = 0 ); + inline void st( Register d, Register s1, RegisterConstant s2 ); + inline void stx( Register d, Register s1, RegisterConstant s2 ); + // pp 177 void stba( Register d, Register s1, Register s2, int ia ) { emit_long( op(ldst_op) | rd(d) | op3(stb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } void stba( Register d, Register s1, int simm13a ) { emit_long( op(ldst_op) | rd(d) | op3(stb_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } void stha( Register d, Register s1, Register s2, int ia ) { emit_long( op(ldst_op) | rd(d) | op3(sth_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
*** 1904,1913 **** --- 1943,1953 ---- inline void load_ptr_contents( Address& a, Register d, int offset = 0 ); inline void store_contents( Register s, Address& a, int offset = 0 ); inline void store_ptr_contents( Register s, Address& a, int offset = 0 ); inline void jumpl_to( Address& a, Register d, int offset = 0 ); inline void jump_to( Address& a, int offset = 0 ); + inline void jump_indirect_to( Address& a, Register temp, int ld_offset = 0, int jmp_offset = 0 ); // ring buffer traceable jumps void jmp2( Register r1, Register r2, const char* file, int line ); void jmp ( Register r1, int offset, const char* file, int line );
*** 1938,1950 **** --- 1978,1992 ---- // Functions for isolating 64 bit loads for LP64 // ld_ptr will perform ld for 32 bit VM's and ldx for 64 bit VM's // st_ptr will perform st for 32 bit VM's and stx for 64 bit VM's inline void ld_ptr( Register s1, Register s2, Register d ); inline void ld_ptr( Register s1, int simm13a, Register d); + inline void ld_ptr( Register s1, RegisterConstant s2, Register d ); inline void ld_ptr( const Address& a, Register d, int offset = 0 ); inline void st_ptr( Register d, Register s1, Register s2 ); inline void st_ptr( Register d, Register s1, int simm13a); + inline void st_ptr( Register d, Register s1, RegisterConstant s2 ); inline void st_ptr( Register d, const Address& a, int offset = 0 ); // ld_long will perform ld for 32 bit VM's and ldx for 64 bit VM's // st_long will perform st for 32 bit VM's and stx for 64 bit VM's inline void ld_long( Register s1, Register s2, Register d );
*** 2265,2274 **** --- 2307,2353 ---- Register t1, // temp register Label& slow_case // continuation point if fast allocation fails ); void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case); + // small bootstrap problems + RegisterConstant delayed_value(intptr_t* delayed_value_addr, Register tmp, + int offset = 0); + 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((intptr_t*) delayed_value_addr(value_fn), tmp, offset); + } + + // interface method calling + void lookup_interface_method(Register recv_klass, + Register intf_klass, + RegisterConstant itable_index, + Register method_result, + Register scan_temp, + Label& no_such_interface); + + // method handles (JSR 292) + void check_method_handle_type(Register mtype_reg, Register mh_reg, + Register temp_reg, + Label& wrong_method_type); + void jump_to_method_handle_entry(Register mh_reg, Register temp_reg); + // offset relative to Gargs of argument at tos[arg_slot]. + // (arg_slot == 0 means the last argument, not the first). + RegisterConstant argument_offset(RegisterConstant arg_slot, + int extra_slot_offset = 0); + + // klass type checking (falls through on failure) + void check_klass_subtype(Register sub_klass, + Register super_klass, + Register temp_reg, + Label& L_success); + + // Stack overflow checking // Note: this clobbers G3_scratch void bang_stack_with_offset(int offset) { // stack grows down, caller passes positive offset
src/cpu/sparc/vm/assembler_sparc.hpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File