src/cpu/mips/vm/vtableStubs_mips_64.cpp

Tue, 26 Jul 2016 17:06:17 +0800

author
fujie
date
Tue, 26 Jul 2016 17:06:17 +0800
changeset 41
d885f8d65c58
parent 1
2d8a650513c2
child 6880
52ea28d233d2
permissions
-rw-r--r--

Add multiply word to GPR instruction (mul) in MIPS assembler.

     1 /*
     2  * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
     3  * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
     4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5  *
     6  * This code is free software; you can redistribute it and/or modify it
     7  * under the terms of the GNU General Public License version 2 only, as
     8  * published by the Free Software Foundation.
     9  *
    10  * This code is distributed in the hope that it will be useful, but WITHOUT
    11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    13  * version 2 for more details (a copy is included in the LICENSE file that
    14  * accompanied this code).
    15  *
    16  * You should have received a copy of the GNU General Public License version
    17  * 2 along with this work; if not, write to the Free Software Foundation,
    18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    19  *
    20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    21  * or visit www.oracle.com if you need additional information or have any
    22  * questions.
    23  *
    24  */
    26 #include "precompiled.hpp"
    27 #include "asm/macroAssembler.hpp"
    28 #include "code/vtableStubs.hpp"
    29 #include "interp_masm_mips_64.hpp"
    30 #include "memory/resourceArea.hpp"
    31 //#include "oops/InstanceKlass.hpp"
    32 #include "oops/klassVtable.hpp"
    33 #include "runtime/sharedRuntime.hpp"
    34 #include "vmreg_mips.inline.hpp"
    35 #ifdef COMPILER2
    36 #include "opto/runtime.hpp"
    37 #endif
    40 // machine-dependent part of VtableStubs: create VtableStub of correct size and
    41 // initialize its code
    43 #define __ masm->
    45 #ifndef PRODUCT
    46 extern "C" void bad_compiled_vtable_index(JavaThread* thread,
    47                                           oop receiver,
    48                                           int index);
    49 #endif
    51 // used by compiler only;  reciever in T0.
    52 // used registers :
    53 // Rmethod : receiver klass & method
    54 // NOTE: If this code is used by the C1, the receiver_location is always 0.
    55 // when reach here, receiver in T0, klass in T8
    56 VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
    57 	const int gs2_code_length = VtableStub::pd_code_size_limit(true);
    58 	//VtableStub* s = new(gs2_code_length) VtableStub(true, vtable_index, receiver_location);
    59 	//FIXME aoqi
    60 	VtableStub* s = new(gs2_code_length) VtableStub(true, vtable_index);
    61 	ResourceMark rm;
    62         CodeBuffer cb(s->entry_point(), gs2_code_length);
    63 	MacroAssembler* masm = new MacroAssembler(&cb);
    64 	Register t1 = T8, t2 = Rmethod;
    65 #ifndef PRODUCT
    66 //#ifdef COMPILER2
    67 	if (CountCompiledCalls) {
    68 		__ li(AT, SharedRuntime::nof_megamorphic_calls_addr());
    69 	        __ lw(t1, AT , 0);	
    70 		__ addiu(t1, t1, 1);
    71 		__ sw(t1, AT,0);
    72 	}
    73 //#endif
    74 #endif
    76      // get receiver (need to skip return address on top of stack)
    77      //assert(receiver_location == T0->as_VMReg(), "receiver expected in T0");
    79      // get receiver klass
    80 	address npe_addr = __ pc();
    81 	//__ ld_ptr(t1, T0, oopDesc::klass_offset_in_bytes());
    82 	//add for compressedoops
    83 	__ load_klass(t1, T0);
    84 	// compute entry offset (in words)
    85 	int entry_offset = InstanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
    86 #ifndef PRODUCT
    87 	if (DebugVtables) { 
    88 		Label L;
    89 		// check offset vs vtable length
    90 		__ lw(t2, t1, InstanceKlass::vtable_length_offset()*wordSize);
    91 		assert(Assembler::is_simm16(vtable_index*vtableEntry::size()), "change this code");
    92 		__ move(AT, vtable_index*vtableEntry::size());
    93 		__ slt(AT, AT, t2);
    94 		__ bne(AT, R0, L);
    95 		__ delayed()->nop();
    96 		__ move(A2, vtable_index);
    97 		__ move(A1, A0);
    98 		__ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), A1, A2);
    99 		__ bind(L);
   100 	}
   101 #endif // PRODUCT
   102 	// load methodOop and target address
   103 	const Register method = Rmethod;
   104 	__ ld_ptr(method, t1,  entry_offset*wordSize + vtableEntry::method_offset_in_bytes()); 
   105 	if (DebugVtables) { 
   106 	      Label L;
   107 	      __ beq(method, R0, L); 
   108 	      __ delayed()->nop();
   109 	      // __ cmpl(Address(method, Method::from_compiled_offset()), NULL_WORD);
   110 	      __ lw(AT, method,in_bytes(Method::from_compiled_offset())); 
   111 	      //__ jcc(Assembler::notZero, L);
   112 	      __ bne(AT, R0, L);
   113               __ delayed()->nop();	
   114 	      __ stop("Vtable entry is NULL");
   115 	      __ bind(L);
   116       }
   117 	// T8: receiver klass
   118 	// T0: receiver
   119 	// Rmethod: methodOop
   120 	// T9: entry
   121 	address ame_addr = __ pc();
   122          __ ld_ptr(T9, method,in_bytes(Method::from_compiled_offset()));	
   123          __ jr(T9);	
   124          __ delayed()->nop();	
   125 	masm->flush();
   126 	s->set_exception_points(npe_addr, ame_addr);
   127 	return s;
   128 }
   131 // i am not sure which register to contain Interface, now i just assume A1. FIXME
   132 // used registers : 
   133 //	T1 T2
   134 // when reach here, the receiver in T0, klass in T1
   135 VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
   136   // Note well: pd_code_size_limit is the absolute minimum we can get
   137   // away with.  If you add code here, bump the code stub size
   138   // returned by pd_code_size_limit!
   139    const int gs2_code_length = VtableStub::pd_code_size_limit(false);
   140    VtableStub* s = new(gs2_code_length) VtableStub(false, vtable_index);
   141    ResourceMark rm;
   142    CodeBuffer cb(s->entry_point(), gs2_code_length);
   143    MacroAssembler* masm = new MacroAssembler(&cb);
   144 // we T8,T9 as temparary register, they are free from register allocator
   145      Register t1 = T8, t2 = T2;
   146 	// Entry arguments:
   147 	//  T1: Interface
   148 	//  T0: Receiver
   149 #ifndef PRODUCT
   150   if (CountCompiledCalls) {
   151 	  //__ incl(Address((int)SharedRuntime::nof_megamorphic_calls_addr(), relocInfo::none));
   152             __ li(AT, SharedRuntime::nof_megamorphic_calls_addr());
   153             __ lw(T8, AT, 0);
   154 	    __ addi(T8, T8,1); 
   155             __ sw(T8, AT, 0);
   156   }
   157 #endif /* PRODUCT */
   158 	//assert(receiver_location == T0->as_VMReg(), "receiver expected in T0");
   159 	// get receiver klass (also an implicit null-check)
   160 	address npe_addr = __ pc();
   161 	//__ ld_ptr(t1, T0, oopDesc::klass_offset_in_bytes());
   162 	//add for compressedoops
   163 	__ load_klass(t1, T0);
   164 	// compute itable entry offset (in words)  
   165 	const int base = InstanceKlass::vtable_start_offset() * wordSize;    
   166 	assert(vtableEntry::size() * wordSize == 8, "adjust the scaling in the code below");
   167 	assert(Assembler::is_simm16(base), "change this code");
   168 	__ daddi(t2, t1, base);
   169 	assert(Assembler::is_simm16(InstanceKlass::vtable_length_offset() * wordSize), "change this code");
   170 	__ lw(AT, t1, InstanceKlass::vtable_length_offset() * wordSize);
   171 	__ dsll(AT, AT, Address::times_8);
   172 	__ dadd(t2, t2, AT);
   173 	if (HeapWordsPerLong > 1) {
   174 		__ round_to(t2, BytesPerLong);
   175 	}
   177 	Label hit, entry;
   178    	assert(Assembler::is_simm16(itableOffsetEntry::size() * wordSize), "change this code");
   179 	__ bind(entry);
   181 #ifdef ASSERT
   182 	// Check that the entry is non-null
   183 	if (DebugVtables) { 
   184 		Label L;
   185 		assert(Assembler::is_simm16(itableOffsetEntry::interface_offset_in_bytes()), "change this code");
   186 		__ lw(AT, t1, itableOffsetEntry::interface_offset_in_bytes());
   187 		__ bne(AT, R0, L);
   188 		__ delayed()->nop();
   189 		__ stop("null entry point found in itable's offset table");
   190 		__ bind(L);
   191 	}
   192 #endif
   193 	assert(Assembler::is_simm16(itableOffsetEntry::interface_offset_in_bytes()), "change this code");
   194 	__ ld_ptr(AT, t2, itableOffsetEntry::interface_offset_in_bytes());
   195 	__ bne(AT, T1, entry);
   196 	__ delayed()->addi(t2, t2, itableOffsetEntry::size() * wordSize);
   198 	// We found a hit, move offset into T9
   199 	__ ld_ptr(t2, t2, itableOffsetEntry::offset_offset_in_bytes() - itableOffsetEntry::size() * wordSize);
   201 	// Compute itableMethodEntry.  
   202 	const int method_offset = (itableMethodEntry::size() * wordSize * vtable_index) + 
   203 		itableMethodEntry::method_offset_in_bytes();
   205   // Get methodOop and entrypoint for compiler    
   206 //  const Register method = ebx;
   207       const Register method = Rmethod;
   208 //   __ movl(method, Address(esi, edx, Address::times_1, method_offset));  
   209       __ dsll(AT, t2, Address::times_1); 
   210       __ add(AT, AT, t1 );  
   211       __ ld_ptr(method, AT,  method_offset);  
   215 #ifdef ASSERT
   216 	if (DebugVtables) {
   217 		Label L1;
   218 	//      __ cmpl(method, NULL_WORD);
   219  //     __ jcc(Assembler::equal, L1);
   220         __ beq(method, R0, L1); 
   221         __ delayed()->nop();		
   222 //	__ cmpl(Address(method, Method::from_compiled_offset()), NULL_WORD);
   223         __ lw(AT, method,in_bytes(Method::from_compiled_offset())); 
   224 //	__ jcc(Assembler::notZero, L1);
   225         __ bne(AT, R0, L1); 
   226         __ delayed()->nop();
   227 	__ stop("methodOop is null");
   228 	__ bind(L1);
   229 	}
   230 #endif // ASSERT
   231 /*
   232 	// Rmethod: methodOop
   233 	// T0: receiver
   234 	// T9: entry point      
   235 	__ jmp(T9);
   236 #endif // COMPILER2
   237 */
   238         address ame_addr = __ pc();
   239         __ ld_ptr(T9, method,in_bytes(Method::from_compiled_offset()));
   240         __ jr(T9);
   241         __ delayed()->nop();	
   242     masm->flush();
   243 	s->set_exception_points(npe_addr, ame_addr);
   244 	return s;
   245 }
   247 // NOTE : whenever you change the code above, dont forget to change the const here
   248 int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
   249 	if (is_vtable_stub) {
   250             return ( DebugVtables ? 600 : 28) + (CountCompiledCalls ? 24 : 0)+ 
   251 		(UseCompressedOops ? 16 : 0); 
   252 	} else {
   253             return  ( DebugVtables ? 636 : 72) + (CountCompiledCalls ? 24 : 0)+ 
   254 		(UseCompressedOops ? 32 : 0);
   255 	}
   256 }
   258 int VtableStub::pd_code_alignment() {
   259   return wordSize;
   260 }

mercurial