diff options
Diffstat (limited to 'gcc/java/decl.c')
-rw-r--r-- | gcc/java/decl.c | 87 |
1 files changed, 65 insertions, 22 deletions
diff --git a/gcc/java/decl.c b/gcc/java/decl.c index 5b693cb50f6..891e4dbe406 100644 --- a/gcc/java/decl.c +++ b/gcc/java/decl.c @@ -61,19 +61,31 @@ static tree create_primitive_vtable (const char *); static tree check_local_unnamed_variable (tree, tree, tree); static void parse_version (void); -/* Used when computing the ABI version. */ -#define GCJ_BINARYCOMPAT_ADDITION 5 -/* Used when defining a class that should be loaded by the bootstrap - loader. */ -#define GCJ_BOOTSTRAP_LOADER_ADDITION 1 +/* The following ABI flags are used in the high-order bits of the version + ID field. The version ID number itself should never be larger than + 0xfffff, so it should be safe to use top 12 bits for these flags. */ -/* The version of the BC ABI that we generate. At the moment we are - compatible with what shipped in GCC 4.0. This must be kept in sync - with parse_version(), libgcj, and reality (if the BC format - changes, this must change. */ +#define FLAG_BINARYCOMPAT_ABI (1<<31) /* Class is built with the BC-ABI. */ + +#define FLAG_BOOTSTRAP_LOADER (1<<30) /* Used when defining a class that + should be loaded by the bootstrap + loader. */ + +/* If an ABI change is made within a GCC release series, rendering current + binaries incompatible with the old runtimes, this number can be set to + enforce the compatibility rules. */ +#define MINOR_BINARYCOMPAT_ABI_VERSION 0 + +/* The runtime may recognize a variety of BC ABIs (objects generated by + different version of gcj), but will probably always require strict + matching for the ordinary (C++) ABI. */ + +/* The version ID of the BC ABI that we generate. This must be kept in + sync with parse_version(), libgcj, and reality (if the BC format changes, + this must change). */ #define GCJ_CURRENT_BC_ABI_VERSION \ - (4 * 10000 + 0 * 10 + GCJ_BINARYCOMPAT_ADDITION) + (4 * 100000 + 0 * 1000 + MINOR_BINARYCOMPAT_ABI_VERSION) /* The ABI version number. */ tree gcj_abi_version; @@ -613,18 +625,20 @@ parse_version (void) ++p; } - /* Implicit in this computation is the idea that we won't break the - old-style binary ABI in a sub-minor release (e.g., from 4.0.0 to - 4.0.1). */ - abi_version = 10000 * major + 10 * minor; - /* It is helpful to distinguish BC ABI from ordinary ABI at this - level, since at some point we will recognize a variety of BC ABIs - (objects generated by different version of gcj), but will - probably always require strict matching for ordinary ABI. */ if (flag_indirect_dispatch) - abi_version = GCJ_CURRENT_BC_ABI_VERSION; + { + abi_version = GCJ_CURRENT_BC_ABI_VERSION; + abi_version |= FLAG_BINARYCOMPAT_ABI; + } + else /* C++ ABI */ + { + /* Implicit in this computation is the idea that we won't break the + old-style binary ABI in a sub-minor release (e.g., from 4.0.0 to + 4.0.1). */ + abi_version = 100000 * major + 1000 * minor; + } if (flag_bootstrap_classes) - abi_version += GCJ_BOOTSTRAP_LOADER_ADDITION; + abi_version |= FLAG_BOOTSTRAP_LOADER; gcj_abi_version = build_int_cstu (ptr_type_node, abi_version); } @@ -2133,6 +2147,30 @@ java_mark_decl_local (tree decl) make_decl_rtl (decl); } +/* Given appropriate target support, G++ will emit hidden aliases for native + methods. Using this hidden name is required for proper operation of + _Jv_Method::ncode, but it doesn't hurt to use it everywhere. Look for + proper target support, then mark the method for aliasing. */ + +static void +java_mark_cni_decl_local (tree decl) +{ + /* Setting DECL_LOCAL_CNI_METHOD_P changes the behaviour of the mangler. + We expect that we should not yet have referenced this decl in a + context that requires it. Check this invariant even if we don't have + support for hidden aliases. */ + gcc_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)); + +#if !defined(HAVE_GAS_HIDDEN) || !defined(ASM_OUTPUT_DEF) + return; +#endif + + DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; + DECL_LOCAL_CNI_METHOD_P (decl) = 1; +} + +/* Use the preceeding two functions and mark all members of the class. */ + void java_mark_class_local (tree class) { @@ -2143,8 +2181,13 @@ java_mark_class_local (tree class) java_mark_decl_local (t); for (t = TYPE_METHODS (class); t ; t = TREE_CHAIN (t)) - if (!METHOD_ABSTRACT (t) && (!METHOD_NATIVE (t) || flag_jni)) - java_mark_decl_local (t); + if (!METHOD_ABSTRACT (t)) + { + if (METHOD_NATIVE (t) && !flag_jni) + java_mark_cni_decl_local (t); + else + java_mark_decl_local (t); + } } /* Add a statement to a compound_expr. */ |