// This code sequence is relocatable to any address, even on LP64. inline void MacroAssembler::jumpl_to(const AddressLiteral& addrlit, Register temp, Register d, int offset) { assert_not_delayed(); // Force fixed length sethi because NativeJump and NativeFarCall don't handle // variable length instruction streams. patchable_sethi(addrlit, temp); jmpl(temp, addrlit.low10() + offset, d); }
void CompactingPermGenGen::generate_vtable_methods(void** vtbl_list, void** vtable, char** md_top, char* md_end, char** mc_top, char* mc_end) { intptr_t vtable_bytes = (num_virtuals * vtbl_list_size) * sizeof(void*); *(intptr_t *)(*md_top) = vtable_bytes; *md_top += sizeof(intptr_t); void** dummy_vtable = (void**)*md_top; *vtable = dummy_vtable; *md_top += vtable_bytes; guarantee(*md_top <= md_end, "Insufficient space for vtables."); // Get ready to generate dummy methods. CodeBuffer cb((unsigned char*)*mc_top, mc_end - *mc_top); MacroAssembler* masm = new MacroAssembler(&cb); Label common_code; for (int i = 0; i < vtbl_list_size; ++i) { for (int j = 0; j < num_virtuals; ++j) { dummy_vtable[num_virtuals * i + j] = (void*)masm->pc(); __ save(SP, -256, SP); __ brx(Assembler::always, false, Assembler::pt, common_code); // Load L0 with a value indicating vtable/offset pair. // -- bits[ 7..0] (8 bits) which virtual method in table? // -- bits[12..8] (5 bits) which virtual method table? // -- must fit in 13-bit instruction immediate field. __ delayed()->set((i << 8) + j, L0); } } __ bind(common_code); // Expecting to be called with the "this" pointer in O0/I0 (where // "this" is a Klass object). In addition, L0 was set (above) to // identify the method and table. // Look up the correct vtable pointer. __ set((intptr_t)vtbl_list, L2); // L2 = address of new vtable list. __ srl(L0, 8, L3); // Isolate L3 = vtable identifier. __ sll(L3, LogBytesPerWord, L3); __ ld_ptr(L2, L3, L3); // L3 = new (correct) vtable pointer. __ st_ptr(L3, Address(I0, 0)); // Save correct vtable ptr in entry. // Restore registers and jump to the correct method; __ and3(L0, 255, L4); // Isolate L3 = method offset;. __ sll(L4, LogBytesPerWord, L4); __ ld_ptr(L3, L4, L4); // Get address of correct virtual method __ jmpl(L4, 0, G0); // Jump to correct method. __ delayed()->restore(); // Restore registers. __ flush(); *mc_top = (char*)__ pc(); guarantee(*mc_top <= mc_end, "Insufficient space for method wrappers."); }
inline void MacroAssembler::callr( Register s1, Register s2 ) { jmpl( s1, s2, O7 ); }
inline void MacroAssembler::callr( Register s1, int simm13a, RelocationHolder const& rspec ) { jmpl( s1, simm13a, O7, rspec); }
inline void MacroAssembler::jmp( Register s1, Register s2 ) { jmpl( s1, s2, G0 ); }