jniFastGetField.hpp revision 1472
0N/A/*
1472N/A * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1472N/A * or visit www.oracle.com if you need additional information or have any
1472N/A * questions.
0N/A *
0N/A */
0N/A
0N/A// Basic logic of a fast version of jni_Get<Primitive>Field:
0N/A//
0N/A// (See safepoint.hpp for a description of _safepoint_counter)
0N/A//
0N/A// load _safepoint_counter into old_counter
0N/A// IF old_counter is odd THEN
0N/A// a safepoint is going on, return jni_GetXXXField
0N/A// ELSE
0N/A// load the primitive field value into result (speculatively)
0N/A// load _safepoint_counter into new_counter
0N/A// IF (old_counter == new_counter) THEN
0N/A// no safepoint happened during the field access, return result
0N/A// ELSE
0N/A// a safepoint might have happened in-between, return jni_GetXXXField()
0N/A// ENDIF
0N/A// ENDIF
0N/A//
0N/A// LoadLoad membars to maintain the load order may be necessary
0N/A// for some platforms.
0N/A//
0N/A// The fast versions don't check for pending suspension request.
0N/A// This is fine since it's totally read-only and doesn't create new race.
0N/A//
0N/A// There is a hypothetical safepoint counter wraparound. But it's not
0N/A// a practical concern.
0N/A
0N/Aclass JNI_FastGetField : AllStatic {
0N/A private:
0N/A enum { LIST_CAPACITY = 40 }; // a conservative number for the number of
0N/A // speculative loads on all the platforms
0N/A static address speculative_load_pclist [];
0N/A static address slowcase_entry_pclist [];
0N/A static int count;
0N/A
0N/A static address generate_fast_get_int_field0(BasicType type);
0N/A static address generate_fast_get_float_field0(BasicType type);
0N/A
0N/A public:
0N/A#if defined(_WINDOWS) && !defined(_WIN64)
0N/A static GetBooleanField_t jni_fast_GetBooleanField_fp;
0N/A static GetByteField_t jni_fast_GetByteField_fp;
0N/A static GetCharField_t jni_fast_GetCharField_fp;
0N/A static GetShortField_t jni_fast_GetShortField_fp;
0N/A static GetIntField_t jni_fast_GetIntField_fp;
0N/A static GetLongField_t jni_fast_GetLongField_fp;
0N/A static GetFloatField_t jni_fast_GetFloatField_fp;
0N/A static GetDoubleField_t jni_fast_GetDoubleField_fp;
0N/A#endif
0N/A
0N/A static address generate_fast_get_boolean_field();
0N/A static address generate_fast_get_byte_field();
0N/A static address generate_fast_get_char_field();
0N/A static address generate_fast_get_short_field();
0N/A static address generate_fast_get_int_field();
0N/A static address generate_fast_get_long_field();
0N/A static address generate_fast_get_float_field();
0N/A static address generate_fast_get_double_field();
0N/A
0N/A // If pc is in speculative_load_pclist, return the corresponding
0N/A // slow case entry pc. Otherwise, return -1.
0N/A // This is used by signal/exception handler to handle such case:
0N/A // After an even safepoint counter is loaded and a fast field access
0N/A // is about to begin, a GC kicks in and shrinks the heap. Then the
0N/A // field access may fault. The signal/exception handler needs to
0N/A // return to the slow case.
0N/A //
0N/A // The GC may decide to temporarily stuff some bad values into handles,
0N/A // for example, for debugging purpose, in which case we need the mapping also.
0N/A static address find_slowcase_pc(address pc);
0N/A};