src/cpu/mips/vm/jniFastGetField_mips_64.cpp

Fri, 29 Apr 2016 00:06:10 +0800

author
aoqi
date
Fri, 29 Apr 2016 00:06:10 +0800
changeset 1
2d8a650513c2
child 368
11ec15adb6c4
permissions
-rw-r--r--

Added MIPS 64-bit port.

     1 /*
     2  * Copyright (c) 2004, 2010, 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 "memory/resourceArea.hpp"
    29 #include "prims/jniFastGetField.hpp"
    30 #include "prims/jvm_misc.hpp"
    31 #include "runtime/safepoint.hpp"
    33 #define __ masm->
    35 #define BUFFER_SIZE 30*wordSize
    37 // Instead of issuing lfence for LoadLoad barrier, we create data dependency
    38 // between loads, which is more efficient than lfence.
    40 address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
    41   const char *name;
    42   switch (type) {
    43     case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
    44     case T_BYTE:    name = "jni_fast_GetByteField";    break;
    45     case T_CHAR:    name = "jni_fast_GetCharField";    break;
    46     case T_SHORT:   name = "jni_fast_GetShortField";   break;
    47     case T_INT:     name = "jni_fast_GetIntField";     break;
    48     case T_LONG:    name = "jni_fast_GetLongField";    break;
    49     default:        ShouldNotReachHere();
    50   }
    51   ResourceMark rm;
    52   BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
    53     CodeBuffer cbuf(blob);
    54   MacroAssembler* masm = new MacroAssembler(&cbuf);
    55   address fast_entry = __ pc();
    57   Label slow;
    59   //  return pc        RA
    60   //  jni env          A0
    61   //  obj              A1
    62   //  jfieldID         A2
    64   address counter_addr = SafepointSynchronize::safepoint_counter_addr();
    65   __ li48(AT, (long)counter_addr);
    66   __ lw(T1, AT, 0);
    68   /* 2012/4/28 Jin: the parameters(A0~A3) should not be modified, since
    69    *   they will be used in slow path. */
    70   __ andi(AT, T1, 1);
    71   __ bne(AT, R0, slow);
    72   __ delayed()->nop();
    74   __ ld(T0, A1, 0);              // unbox, *obj 
    75   __ move(T2, A2);
    76   __ shr(T2, 2);                 // offset
    77   __ dadd(T0, T0, T2);
    79   assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
    80   speculative_load_pclist[count] = __ pc();
    81   switch (type) {
    82     case T_BOOLEAN: __ lbu (V0, T0, 0); break;
    83     case T_BYTE:    __ lb  (V0, T0, 0); break;
    84     case T_CHAR:    __ lhu (V0, T0, 0); break;
    85     case T_SHORT:   __ lh  (V0, T0, 0); break;
    86     case T_INT:     __ lw  (V0, T0, 0); break;
    87     case T_LONG:    __ ld  (V0, T0, 0); break;
    88     default:        ShouldNotReachHere();
    89   }
    91   __ li48(AT, (long)counter_addr);
    92   __ lw(AT, AT, 0);
    93   __ bne(T1, AT, slow);
    94   __ delayed()->nop();
    96   __ jr(RA);
    97   __ delayed()->nop();
    99   slowcase_entry_pclist[count++] = __ pc();
   100   __ bind (slow);
   101   address slow_case_addr;
   102   switch (type) {
   103     case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
   104     case T_BYTE:    slow_case_addr = jni_GetByteField_addr();    break;
   105     case T_CHAR:    slow_case_addr = jni_GetCharField_addr();    break;
   106     case T_SHORT:   slow_case_addr = jni_GetShortField_addr();   break;
   107     case T_INT:     slow_case_addr = jni_GetIntField_addr();     break;
   108     case T_LONG:    slow_case_addr = jni_GetLongField_addr();
   109   }
   110   __ jmp(slow_case_addr);
   111   __ delayed()->nop();
   113   __ flush ();
   115   return fast_entry;
   116 }
   118 address JNI_FastGetField::generate_fast_get_boolean_field() {
   119   return generate_fast_get_int_field0(T_BOOLEAN);
   120 }
   122 address JNI_FastGetField::generate_fast_get_byte_field() {
   123   return generate_fast_get_int_field0(T_BYTE);
   124 }
   126 address JNI_FastGetField::generate_fast_get_char_field() {
   127   return generate_fast_get_int_field0(T_CHAR);
   128 }
   130 address JNI_FastGetField::generate_fast_get_short_field() {
   131   return generate_fast_get_int_field0(T_SHORT);
   132 }
   134 address JNI_FastGetField::generate_fast_get_int_field() {
   135   return generate_fast_get_int_field0(T_INT);
   136 }
   138 address JNI_FastGetField::generate_fast_get_long_field() {
   139   return generate_fast_get_int_field0(T_LONG);
   140 /*
   141   const char *name = "jni_fast_GetLongField";
   142   ResourceMark rm;
   143   BufferBlob* b = BufferBlob::create(name, BUFFER_SIZE*wordSize);
   144   address fast_entry = b->instructions_begin();
   145   // CodeBuffer* cbuf = new CodeBuffer(fast_entry, b->instructions_size());
   146   CodeBuffer  cbuf (fast_entry, b->instructions_size());
   147   MacroAssembler* masm = new MacroAssembler(&cbuf);
   149   Label slow;
   151   //  return pc        RA
   152   //  jni env          A0
   153   //  obj              A1
   154   //  jfieldID         A2
   156   address counter_addr = SafepointSynchronize::safepoint_counter_addr();
   157   //__ move(AT, (int)counter_addr);
   158   //__ lw(T1, AT, 0);
   159   __ lui(AT, Assembler::split_high((intptr_t)counter_addr));
   160   __ lw(T1, AT, Assembler::split_low((intptr_t)counter_addr));
   161   __ andi(AT, T1, 1);	
   162   __ bne(AT, R0, slow);
   163   __ delayed()->nop();
   165   __ ld (A1, A1, 0);              // unbox, *obj
   166   __ shr(A2, 2);              		// offset
   167   __ dadd(A1, A1, A2);
   169   assert(count < LIST_CAPACITY-1, "LIST_CAPACITY too small");
   170   speculative_load_pclist[count++] = __ pc();
   171   __ ld(V0, A1, 0);							// eax
   172   speculative_load_pclist[count] = __ pc();
   173   __ ld(V1, A1, 8);
   175   __ lui(AT, Assembler::split_high((intptr_t)counter_addr));
   176   __ lw(AT, AT, Assembler::split_low((intptr_t)counter_addr));
   177   __ bne(T1, AT, slow);
   178   __ delayed()->nop();
   180   __ jr(RA);
   181   __ delayed()->nop();
   183   slowcase_entry_pclist[count-1] = __ pc();
   184   slowcase_entry_pclist[count++] = __ pc();
   185   __ bind (slow);
   186   address slow_case_addr = jni_GetLongField_addr();;
   187   // tail call
   188   __ jmp(slow_case_addr);
   189   __ delayed()->nop();
   191   __ flush();
   192   return fast_entry;
   193   */
   194 }
   196 address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
   197   const char *name;
   198   switch (type) {
   199     case T_FLOAT:     name = "jni_fast_GetFloatField";     break;
   200     case T_DOUBLE:    name = "jni_fast_GetDoubleField";    break;
   201     default:          ShouldNotReachHere();
   202   }
   203   ResourceMark rm;
   204   BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
   205     CodeBuffer cbuf(blob);
   206   MacroAssembler* masm = new MacroAssembler(&cbuf);
   207 address fast_entry = __ pc();
   209   Label slow;
   211 	//  return pc        RA
   212 	//  jni env          A0
   213 	//  obj              A1
   214 	//  jfieldID         A2
   216 	address counter_addr = SafepointSynchronize::safepoint_counter_addr();
   217 	//__ move(AT, (int)counter_addr);
   218 	//__ lw(T1, AT, 0);
   219 #ifdef _LP64
   220 	__ li48(AT, (intptr_t)counter_addr);
   221 	__ lw(T1, AT, 0);
   222 #else
   223 	__ lui(AT, Assembler::split_high((intptr_t)counter_addr));
   224 	__ lw(T1, AT, Assembler::split_low((intptr_t)counter_addr));
   225 #endif
   226 	__ andi(AT, T1, 1);
   227 	__ bne(AT, R0, slow);
   228 	__ delayed()->nop();	
   230 #ifdef _LP64
   231 	__ ld(A1, A1, 0);              // unbox, *obj
   232 #else
   233 	__ lw(A1, A1, 0);              // unbox, *obj
   234 #endif
   235 	__ shr(A2, 2);             		 // offset
   236 	__ add(A1, A1, A2);
   238 	assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
   239 	speculative_load_pclist[count] = __ pc();
   240 	switch (type) {
   241 		case T_FLOAT:  
   242 			__ lwc1(F0, A1, 0);
   243 			break;
   244 		case T_DOUBLE: 
   245 #ifdef _LP64
   246 			__ ldc1(F0, A1, 0);
   247 #else
   248 			__ lwc1(F0, A1, 0);
   249 			__ lwc1(F1, A1, 4);
   250 #endif
   251 			break;
   252 		default:       ShouldNotReachHere();
   253 	}
   255 #ifdef _LP64
   256 	__ li48(AT, (intptr_t)counter_addr);
   257 	__ lw(AT, AT, 0);
   258 #else
   259 	__ lui(AT, Assembler::split_high((intptr_t)counter_addr));
   260 	__ lw(AT, AT, Assembler::split_low((intptr_t)counter_addr));
   261 #endif
   262 	__ bne(T1, AT, slow);
   263 	__ delayed()->nop();
   265 	__ jr(RA);
   266 	__ delayed()->nop();
   269 	slowcase_entry_pclist[count++] = __ pc();
   270 	__ bind (slow);
   271 	address slow_case_addr;
   272 	switch (type) {
   273 		case T_FLOAT:  slow_case_addr = jni_GetFloatField_addr();  break;
   274 		case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break;
   275 		default:       ShouldNotReachHere();
   276 	}
   277 	__ jmp(slow_case_addr);
   278 	__ delayed()->nop();
   280 	__ flush ();
   281 	return fast_entry;
   282 }
   284 address JNI_FastGetField::generate_fast_get_float_field() {
   285   return generate_fast_get_float_field0(T_FLOAT);
   286 }
   288 address JNI_FastGetField::generate_fast_get_double_field() {
   289   return generate_fast_get_float_field0(T_DOUBLE);
   290 }

mercurial