src/cpu/sparc/vm/jniFastGetField_sparc.cpp

Tue, 24 Jul 2012 10:51:00 -0700

author
twisti
date
Tue, 24 Jul 2012 10:51:00 -0700
changeset 3969
1d7922586cf6
parent 2314
f95d63e2154a
child 4323
f0c2369fda5a
permissions
-rw-r--r--

7023639: JSR 292 method handle invocation needs a fast path for compiled code
6984705: JSR 292 method handle creation should not go through JNI
Summary: remove assembly code for JDK 7 chained method handles
Reviewed-by: jrose, twisti, kvn, mhaupt
Contributed-by: John Rose <john.r.rose@oracle.com>, Christian Thalinger <christian.thalinger@oracle.com>, Michael Haupt <michael.haupt@oracle.com>

     1 /*
     2  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #include "precompiled.hpp"
    26 #include "assembler_sparc.inline.hpp"
    27 #include "memory/resourceArea.hpp"
    28 #include "prims/jniFastGetField.hpp"
    29 #include "prims/jvm_misc.hpp"
    30 #include "runtime/safepoint.hpp"
    32 // TSO ensures that loads are blocking and ordered with respect to
    33 // to earlier loads, so we don't need LoadLoad membars.
    35 #define __ masm->
    37 #define BUFFER_SIZE 30*sizeof(jint)
    39 // Common register usage:
    40 // O0: env
    41 // O1: obj
    42 // O2: jfieldID
    43 // O4: offset (O2 >> 2)
    44 // G4: old safepoint counter
    46 address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
    47   const char *name;
    48   switch (type) {
    49     case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
    50     case T_BYTE:    name = "jni_fast_GetByteField";    break;
    51     case T_CHAR:    name = "jni_fast_GetCharField";    break;
    52     case T_SHORT:   name = "jni_fast_GetShortField";   break;
    53     case T_INT:     name = "jni_fast_GetIntField";     break;
    54     default:        ShouldNotReachHere();
    55   }
    56   ResourceMark rm;
    57   BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
    58   CodeBuffer cbuf(blob);
    59   MacroAssembler* masm = new MacroAssembler(&cbuf);
    60   address fast_entry = __ pc();
    62   Label label1, label2;
    64   AddressLiteral cnt_addrlit(SafepointSynchronize::safepoint_counter_addr());
    65   __ sethi (cnt_addrlit, O3);
    66   Address cnt_addr(O3, cnt_addrlit.low10());
    67   __ ld (cnt_addr, G4);
    68   __ andcc (G4, 1, G0);
    69   __ br (Assembler::notZero, false, Assembler::pn, label1);
    70   __ delayed()->srl (O2, 2, O4);
    71   __ ld_ptr (O1, 0, O5);
    73   assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
    74   speculative_load_pclist[count] = __ pc();
    75   switch (type) {
    76     case T_BOOLEAN: __ ldub (O5, O4, G3);  break;
    77     case T_BYTE:    __ ldsb (O5, O4, G3);  break;
    78     case T_CHAR:    __ lduh (O5, O4, G3);  break;
    79     case T_SHORT:   __ ldsh (O5, O4, G3);  break;
    80     case T_INT:     __ ld (O5, O4, G3);    break;
    81     default:        ShouldNotReachHere();
    82   }
    84   __ ld (cnt_addr, O5);
    85   __ cmp (O5, G4);
    86   __ br (Assembler::notEqual, false, Assembler::pn, label2);
    87   __ delayed()->mov (O7, G1);
    88   __ retl ();
    89   __ delayed()->mov (G3, O0);
    91   slowcase_entry_pclist[count++] = __ pc();
    92   __ bind (label1);
    93   __ mov (O7, G1);
    95   address slow_case_addr;
    96   switch (type) {
    97     case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
    98     case T_BYTE:    slow_case_addr = jni_GetByteField_addr();    break;
    99     case T_CHAR:    slow_case_addr = jni_GetCharField_addr();    break;
   100     case T_SHORT:   slow_case_addr = jni_GetShortField_addr();   break;
   101     case T_INT:     slow_case_addr = jni_GetIntField_addr();     break;
   102     default:        ShouldNotReachHere();
   103   }
   104   __ bind (label2);
   105   __ call (slow_case_addr, relocInfo::none);
   106   __ delayed()->mov (G1, O7);
   108   __ flush ();
   110   return fast_entry;
   111 }
   113 address JNI_FastGetField::generate_fast_get_boolean_field() {
   114   return generate_fast_get_int_field0(T_BOOLEAN);
   115 }
   117 address JNI_FastGetField::generate_fast_get_byte_field() {
   118   return generate_fast_get_int_field0(T_BYTE);
   119 }
   121 address JNI_FastGetField::generate_fast_get_char_field() {
   122   return generate_fast_get_int_field0(T_CHAR);
   123 }
   125 address JNI_FastGetField::generate_fast_get_short_field() {
   126   return generate_fast_get_int_field0(T_SHORT);
   127 }
   129 address JNI_FastGetField::generate_fast_get_int_field() {
   130   return generate_fast_get_int_field0(T_INT);
   131 }
   133 address JNI_FastGetField::generate_fast_get_long_field() {
   134   const char *name = "jni_fast_GetLongField";
   135   ResourceMark rm;
   136   BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
   137   CodeBuffer cbuf(blob);
   138   MacroAssembler* masm = new MacroAssembler(&cbuf);
   139   address fast_entry = __ pc();
   141   Label label1, label2;
   143   AddressLiteral cnt_addrlit(SafepointSynchronize::safepoint_counter_addr());
   144   __ sethi (cnt_addrlit, G3);
   145   Address cnt_addr(G3, cnt_addrlit.low10());
   146   __ ld (cnt_addr, G4);
   147   __ andcc (G4, 1, G0);
   148   __ br (Assembler::notZero, false, Assembler::pn, label1);
   149   __ delayed()->srl (O2, 2, O4);
   150   __ ld_ptr (O1, 0, O5);
   151   __ add (O5, O4, O5);
   153 #ifndef _LP64
   154   assert(count < LIST_CAPACITY-1, "LIST_CAPACITY too small");
   155   speculative_load_pclist[count++] = __ pc();
   156   __ ld (O5, 0, G2);
   158   speculative_load_pclist[count] = __ pc();
   159   __ ld (O5, 4, O3);
   160 #else
   161   assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
   162   speculative_load_pclist[count] = __ pc();
   163   __ ldx (O5, 0, O3);
   164 #endif
   166   __ ld (cnt_addr, G1);
   167   __ cmp (G1, G4);
   168   __ br (Assembler::notEqual, false, Assembler::pn, label2);
   169   __ delayed()->mov (O7, G1);
   171 #ifndef _LP64
   172   __ mov (G2, O0);
   173   __ retl ();
   174   __ delayed()->mov (O3, O1);
   175 #else
   176   __ retl ();
   177   __ delayed()->mov (O3, O0);
   178 #endif
   180 #ifndef _LP64
   181   slowcase_entry_pclist[count-1] = __ pc();
   182   slowcase_entry_pclist[count++] = __ pc() ;
   183 #else
   184   slowcase_entry_pclist[count++] = __ pc();
   185 #endif
   187   __ bind (label1);
   188   __ mov (O7, G1);
   190   address slow_case_addr = jni_GetLongField_addr();
   191   __ bind (label2);
   192   __ call (slow_case_addr, relocInfo::none);
   193   __ delayed()->mov (G1, O7);
   195   __ flush ();
   197   return fast_entry;
   198 }
   200 address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
   201   const char *name;
   202   switch (type) {
   203     case T_FLOAT:  name = "jni_fast_GetFloatField";  break;
   204     case T_DOUBLE: name = "jni_fast_GetDoubleField"; break;
   205     default:       ShouldNotReachHere();
   206   }
   207   ResourceMark rm;
   208   BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
   209   CodeBuffer cbuf(blob);
   210   MacroAssembler* masm = new MacroAssembler(&cbuf);
   211   address fast_entry = __ pc();
   213   Label label1, label2;
   215   AddressLiteral cnt_addrlit(SafepointSynchronize::safepoint_counter_addr());
   216   __ sethi (cnt_addrlit, O3);
   217   Address cnt_addr(O3, cnt_addrlit.low10());
   218   __ ld (cnt_addr, G4);
   219   __ andcc (G4, 1, G0);
   220   __ br (Assembler::notZero, false, Assembler::pn, label1);
   221   __ delayed()->srl (O2, 2, O4);
   222   __ ld_ptr (O1, 0, O5);
   224   assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
   225   speculative_load_pclist[count] = __ pc();
   226   switch (type) {
   227     case T_FLOAT:  __ ldf (FloatRegisterImpl::S, O5, O4, F0); break;
   228     case T_DOUBLE: __ ldf (FloatRegisterImpl::D, O5, O4, F0); break;
   229     default:       ShouldNotReachHere();
   230   }
   232   __ ld (cnt_addr, O5);
   233   __ cmp (O5, G4);
   234   __ br (Assembler::notEqual, false, Assembler::pn, label2);
   235   __ delayed()->mov (O7, G1);
   237   __ retl ();
   238   __ delayed()-> nop ();
   240   slowcase_entry_pclist[count++] = __ pc();
   241   __ bind (label1);
   242   __ mov (O7, G1);
   244   address slow_case_addr;
   245   switch (type) {
   246     case T_FLOAT:  slow_case_addr = jni_GetFloatField_addr();  break;
   247     case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break;
   248     default:       ShouldNotReachHere();
   249   }
   250   __ bind (label2);
   251   __ call (slow_case_addr, relocInfo::none);
   252   __ delayed()->mov (G1, O7);
   254   __ flush ();
   256   return fast_entry;
   257 }
   259 address JNI_FastGetField::generate_fast_get_float_field() {
   260   return generate_fast_get_float_field0(T_FLOAT);
   261 }
   263 address JNI_FastGetField::generate_fast_get_double_field() {
   264   return generate_fast_get_float_field0(T_DOUBLE);
   265 }

mercurial