1 /*
   2  * Copyright (c) 2004, 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  */
  24 
  25 // Basic logic of a fast version of jni_Get<Primitive>Field:
  26 //
  27 // (See safepoint.hpp for a description of _safepoint_counter)
  28 //
  29 // load _safepoint_counter into old_counter
  30 // IF old_counter is odd THEN
  31 //   a safepoint is going on, return jni_GetXXXField
  32 // ELSE
  33 //   load the primitive field value into result (speculatively)
  34 //   load _safepoint_counter into new_counter
  35 //   IF (old_counter == new_counter) THEN
  36 //     no safepoint happened during the field access, return result
  37 //   ELSE
  38 //     a safepoint might have happened in-between, return jni_GetXXXField()
  39 //   ENDIF
  40 // ENDIF
  41 //
  42 // LoadLoad membars to maintain the load order may be necessary
  43 // for some platforms.
  44 //
  45 // The fast versions don't check for pending suspension request.
  46 // This is fine since it's totally read-only and doesn't create new race.
  47 //
  48 // There is a hypothetical safepoint counter wraparound. But it's not
  49 // a practical concern.
  50 
  51 class JNI_FastGetField : AllStatic {
  52  private:
  53   enum { LIST_CAPACITY = 40 };      // a conservative number for the number of
  54                                     // speculative loads on all the platforms
  55   static address speculative_load_pclist [];
  56   static address slowcase_entry_pclist   [];
  57   static int     count;
  58 
  59   static address generate_fast_get_int_field0(BasicType type);
  60   static address generate_fast_get_float_field0(BasicType type);
  61 
  62  public:
  63 #if defined(_WINDOWS) && !defined(_WIN64)
  64   static GetBooleanField_t jni_fast_GetBooleanField_fp;
  65   static GetByteField_t    jni_fast_GetByteField_fp;
  66   static GetCharField_t    jni_fast_GetCharField_fp;
  67   static GetShortField_t   jni_fast_GetShortField_fp;
  68   static GetIntField_t     jni_fast_GetIntField_fp;
  69   static GetLongField_t    jni_fast_GetLongField_fp;
  70   static GetFloatField_t   jni_fast_GetFloatField_fp;
  71   static GetDoubleField_t  jni_fast_GetDoubleField_fp;
  72 #endif
  73 
  74   static address generate_fast_get_boolean_field();
  75   static address generate_fast_get_byte_field();
  76   static address generate_fast_get_char_field();
  77   static address generate_fast_get_short_field();
  78   static address generate_fast_get_int_field();
  79   static address generate_fast_get_long_field();
  80   static address generate_fast_get_float_field();
  81   static address generate_fast_get_double_field();
  82 
  83   // If pc is in speculative_load_pclist, return the corresponding
  84   // slow case entry pc. Otherwise, return -1.
  85   // This is used by signal/exception handler to handle such case:
  86   // After an even safepoint counter is loaded and a fast field access
  87   // is about to begin, a GC kicks in and shrinks the heap. Then the
  88   // field access may fault. The signal/exception handler needs to
  89   // return to the slow case.
  90   //
  91   // The GC may decide to temporarily stuff some bad values into handles,
  92   // for example, for debugging purpose, in which case we need the mapping also.
  93   static address find_slowcase_pc(address pc);
  94 };