* tree.h (build_int_cst): New, sign extended constant. (build_int_cstu): New, zero extended constant. (build_int_cst_wide): Renamed from build_int_cst. * tree.c (build_int_cst, build_int_cstu): New. (build_int_cst_wide): Renamed from build_int_cst. (make_vector_type, build_common_tree_nodes, build_common_tree_nodes_2): Adjust build_int_cst calls. * builtins.c (expand_builtin_prefetch, expand_builtin_strstr, expand_builtin_strpbrk, expand_builtin_fputs, build_string_literal, expand_builtin_printf, expand_builtin_sprintf, fold_builtin_classify_type, fold_builtin_lround, fold_builtin_bitop, fold_builtin_isascii, fold_builtin_toascii, fold_builtin_isdigit, simplify_builtin_strstr, simplify_builtin_strpbrk, fold_builtin_fputs, simplify_builtin_sprintf): Likewise. * c-common.c (start_fname_decls, fix_string_type, shorten_compare, DEF_ATTR_INT): Likewise. * c-decl.c (complete_array_type, check_bitfield_type_and_width): Likewise. * c-lex.c (interpret_integer, lex_charconst): Likewise. * c-parse.in (primary) <TYPES_COMPATIBLE_P> Likewise. * c-pretty-print.c (pp_c_integer_constant): Likewise. * c-typeck.c (really_start_incremental_init, push_init_level, set_nonincremental_init_from_string): Likewise. * calls.c (load_register_parameters): Likewise. convert.c (convert_to_pointer): Likewise. coverage.c (coverage_counter_alloc, tree_coverage_counter_ref, build_fn_info_type, build_fn_info_value, build_ctr_info_value, build_gcov_info): Likewise. * except.c (init_eh, assign_filter_values): Likewise. * expmed.c (store_fixed_bit_field, extract_bit_field, extract_fixed_bit_field, extract_split_bit_field, expand_shift, expand_mult_const, expand_mult_highpart_adjust, extract_high_half, expand_sdiv_pow2, expand_divmod, make_tree): Likewise. * expr.c (convert_move, emit_group_load, emit_group_store, expand_assignment, store_constructor, store_field, expand_expr_real_1, reduce_to_bit_field_precision): Likewise. fold-const.c (force_fit_type, int_const_binop, fold_convert_const, invert_truthvalue, optimize_bit_field_compare, decode_field_reference, all_ones_mask_p, constant_boolean_node, fold_div_compare, fold, fold_read_from_constant_string, fold_negate_const, fold_abs_const, fold_not_const, round_up, round_down): Likewise. * function.c (assign_parm_setup_block): Likewise. * stmt.c (shift_return_value, expand_case, estimate_case_costs): Likewise. * stor-layout.c (layout_type, initialize_sizetypes, set_min_and_max_values_for_integral_type): Likewise. * tree-chrec.c (chrec_fold_multiply_poly_poly, reset_evolution_in_loop): Likewise. * tree-chrec.h (build_polynomial_chrec): Likewise. * tree-complex.c (build_replicated_const): Likewise. * tree-eh.c (honor_protect_cleanup_actions, lower_try_finally_onedest, lower_try_finally_copy, lower_try_finally_switch): Likewise. * tree-mudflap.c (mf_build_string, mx_register_decls, mudflap_register_call, mudflap_enqueue_constant): Likewise. * tree-nested.c (get_trampoline_type, get_nl_goto_field): Likewise. * tree-pretty-print.c (dump_generic_node): Likewise. * tree-ssa-ccp.c (widen_bitfield, maybe_fold_offset_to_array_ref): Likewise. * tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Likewise. * tree-ssa-loop-niter.c (number_of_iterations_cond, loop_niter_by_eval, upper_bound_in_type, lower_bound_in_type): Likewise. * tree-ssa-loop-ivcanon.c (create_canonical_iv, canonicalize_loop_induction_variables): Likewise. * tree-vectorizer.c (vect_create_index_for_array_ref, vect_transform_loop_bound, vect_compute_data_ref_alignment): Likewise. * config/alpha/alpha.c (alpha_initialize_trampoline, alpha_va_start, alpha_gimplify_va_arg_1): Likewise. * config/arm/arm.c (arm_get_cookie_size): Likewise. * config/c4x/c4x.c (c4x_gimplify_va_arg_expr): Likewise. * config/i386/i386.c (ix86_va_start, ix86_gimplify_va_arg): Likewise. * config/ia64/ia64.c (ia64_gimplify_va_arg): Likewise. * config/mips/mips.c (mips_build_builtin_va_list, mips_va_start, mips_gimplify_va_arg_expr): Likewise. * config/pa/pa.c (hppa_gimplify_va_arg_expr): Likewise. * config/rs6000/rs6000.c (rs6000_va_start, rs6000_gimplify_va_arg, add_compiler_branch_island): Likewise. * config/s390/s390.c (s390_va_start): Likewise. * config/sh/sh.c (sh_va_start): Likewise. * config/stormy16/stormy16.c (xstormy16_expand_builtin_va_start): Likewise. * config/xtensa/xtensa.c (xtensa_va_start, xtensa_gimplify_va_arg_expr): Likewise. * objc/objc-act.c (build_objc_string_object, build_objc_symtab_template, init_def_list, init_objc_symtab, init_module_descriptor, generate_static_references, build_selector_translation_table, get_proto_encoding, build_typed_selector_reference, build_selector_reference, build_next_objc_exception_stuff, build_method_prototype_list_template, generate_descriptor_table, generate_protocols, build_protocol_initializer, build_ivar_list_template, build_method_list_template, build_ivar_list_initializer, generate_ivars_list, generate_dispatch_table, generate_protocol_list, build_category_initializer, build_shared_structure_initializer, generate_shared_structures, handle_impent, generate_objc_image_info): Likewise. 2004-04-25 Paolo Bonzini <bonzini@gnu.org> * cfglayout.c (duplicate_insn_chain): Remove references to NOTE_INSN_LOOP_VTOP and NOTE_INSN_LOOP_CONT. * cfgloop.h (struct loop): Remove fields vtop, cont and cont_dominator. * cfgrtl.c (rtl_delete_block): Remove handling of NOTE_INSN_LOOP_CONT. * final.c (final_scan_insn): Remove references to NOTE_INSN_LOOP_VTOP and NOTE_INSN_LOOP_CONT. * insn-notes.def (NOTE_INSN_LOOP_VTOP, NOTE_INSN_LOOP_CONT): Remove. * jump.c (squeeze_notes): Remove references to NOTE_INSN_LOOP_VTOP and NOTE_INSN_LOOP_CONT. * loop.c (scan_loops, find_and_verify_loops, for_each_insn_in_loop, check_dbra_loop, loop_dump_aux): Remove references to removed notes and fields. * reorg.c (mostly_true_jump): Do not rely on NOTE_INSN_LOOP_VTOPs. * unroll.c (unroll_loop, copy_loop_body, loop_iterations): Remove references to removed notes and fields. (subtract_reg_term, ujump_to_loop_cont): Remove. From-SVN: r86544
231 lines
6.9 KiB
C
231 lines
6.9 KiB
C
/* Functions related to the Boehm garbage collector.
|
|
Copyright (C) 2000, 2003 Free Software Foundation, Inc.
|
|
|
|
This file is part of GCC.
|
|
|
|
GCC is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
|
|
GCC is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GCC; see the file COPYING. If not, write to
|
|
the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
Boston, MA 02111-1307, USA.
|
|
|
|
Java and all Java-based marks are trademarks or registered trademarks
|
|
of Sun Microsystems, Inc. in the United States and other countries.
|
|
The Free Software Foundation is independent of Sun Microsystems, Inc. */
|
|
|
|
/* Written by Tom Tromey <tromey@cygnus.com>. */
|
|
|
|
#include <config.h>
|
|
|
|
#include "system.h"
|
|
#include "coretypes.h"
|
|
#include "tm.h"
|
|
#include "tree.h"
|
|
#include "java-tree.h"
|
|
#include "parse.h"
|
|
#include "toplev.h"
|
|
|
|
static void mark_reference_fields (tree, unsigned HOST_WIDE_INT *,
|
|
unsigned HOST_WIDE_INT *, unsigned int,
|
|
int *, int *, int *, HOST_WIDE_INT *);
|
|
static void set_bit (unsigned HOST_WIDE_INT *, unsigned HOST_WIDE_INT *,
|
|
unsigned int);
|
|
|
|
/* Treat two HOST_WIDE_INT's as a contiguous bitmap, with bit 0 being
|
|
the least significant. This function sets bit N in the bitmap. */
|
|
static void
|
|
set_bit (unsigned HOST_WIDE_INT *low, unsigned HOST_WIDE_INT *high,
|
|
unsigned int n)
|
|
{
|
|
unsigned HOST_WIDE_INT *which;
|
|
|
|
if (n >= HOST_BITS_PER_WIDE_INT)
|
|
{
|
|
n -= HOST_BITS_PER_WIDE_INT;
|
|
which = high;
|
|
}
|
|
else
|
|
which = low;
|
|
|
|
*which |= (unsigned HOST_WIDE_INT) 1 << n;
|
|
}
|
|
|
|
/* Recursively mark reference fields. */
|
|
static void
|
|
mark_reference_fields (tree field,
|
|
unsigned HOST_WIDE_INT *low,
|
|
unsigned HOST_WIDE_INT *high,
|
|
unsigned int ubit,
|
|
int *pointer_after_end,
|
|
int *all_bits_set,
|
|
int *last_set_index,
|
|
HOST_WIDE_INT *last_view_index)
|
|
{
|
|
/* See if we have fields from our superclass. */
|
|
if (DECL_NAME (field) == NULL_TREE)
|
|
{
|
|
mark_reference_fields (TYPE_FIELDS (TREE_TYPE (field)),
|
|
low, high, ubit,
|
|
pointer_after_end, all_bits_set,
|
|
last_set_index, last_view_index);
|
|
field = TREE_CHAIN (field);
|
|
}
|
|
|
|
for (; field != NULL_TREE; field = TREE_CHAIN (field))
|
|
{
|
|
HOST_WIDE_INT offset;
|
|
HOST_WIDE_INT size_bytes;
|
|
|
|
if (FIELD_STATIC (field))
|
|
continue;
|
|
|
|
offset = int_byte_position (field);
|
|
size_bytes = int_size_in_bytes (TREE_TYPE (field));
|
|
if (JREFERENCE_TYPE_P (TREE_TYPE (field))
|
|
/* An `object' of type gnu.gcj.RawData is actually non-Java
|
|
data. */
|
|
&& TREE_TYPE (field) != rawdata_ptr_type_node)
|
|
{
|
|
unsigned int count;
|
|
unsigned int size_words;
|
|
unsigned int i;
|
|
|
|
/* If this reference slot appears to overlay a slot we think
|
|
we already covered, then we are doomed. */
|
|
if (offset <= *last_view_index)
|
|
abort ();
|
|
|
|
count = offset * BITS_PER_UNIT / POINTER_SIZE;
|
|
size_words = size_bytes * BITS_PER_UNIT / POINTER_SIZE;
|
|
|
|
*last_set_index = count;
|
|
|
|
/* First word in object corresponds to most significant byte of
|
|
bitmap.
|
|
|
|
In the case of a multiple-word record, we set pointer
|
|
bits for all words in the record. This is conservative, but the
|
|
size_words != 1 case is impossible in regular java code. */
|
|
for (i = 0; i < size_words; ++i)
|
|
set_bit (low, high, ubit - count - i - 1);
|
|
|
|
if (count >= ubit - 2)
|
|
*pointer_after_end = 1;
|
|
|
|
/* If we saw a non-reference field earlier, then we can't
|
|
use the count representation. We keep track of that in
|
|
*ALL_BITS_SET. */
|
|
if (! *all_bits_set)
|
|
*all_bits_set = -1;
|
|
}
|
|
else if (*all_bits_set > 0)
|
|
*all_bits_set = 0;
|
|
|
|
*last_view_index = offset;
|
|
}
|
|
}
|
|
|
|
/* Return the marking bitmap for the class TYPE. For now this is a
|
|
single word describing the type. */
|
|
tree
|
|
get_boehm_type_descriptor (tree type)
|
|
{
|
|
unsigned int count, log2_size, ubit;
|
|
int bit;
|
|
int all_bits_set = 1;
|
|
int last_set_index = 0;
|
|
HOST_WIDE_INT last_view_index = -1;
|
|
int pointer_after_end = 0;
|
|
unsigned HOST_WIDE_INT low = 0, high = 0;
|
|
tree field, value, value_type;
|
|
|
|
/* If the GC wasn't requested, just use a null pointer. */
|
|
if (! flag_use_boehm_gc)
|
|
return null_pointer_node;
|
|
|
|
value_type = java_type_for_mode (ptr_mode, 1);
|
|
/* If we have a type of unknown size, use a proc. */
|
|
if (int_size_in_bytes (type) == -1)
|
|
goto procedure_object_descriptor;
|
|
|
|
bit = POINTER_SIZE / BITS_PER_UNIT;
|
|
/* The size of this node has to be known. And, we only support 32
|
|
and 64 bit targets, so we need to know that the log2 is one of
|
|
our values. */
|
|
log2_size = exact_log2 (bit);
|
|
if (bit == -1 || (log2_size != 2 && log2_size != 3))
|
|
{
|
|
/* This means the GC isn't supported. We should probably
|
|
abort or give an error. Instead, for now, we just silently
|
|
revert. FIXME. */
|
|
return null_pointer_node;
|
|
}
|
|
bit *= BITS_PER_UNIT;
|
|
|
|
/* Warning avoidance. */
|
|
ubit = (unsigned int) bit;
|
|
|
|
if (type == class_type_node)
|
|
goto procedure_object_descriptor;
|
|
|
|
field = TYPE_FIELDS (type);
|
|
mark_reference_fields (field, &low, &high, ubit,
|
|
&pointer_after_end, &all_bits_set,
|
|
&last_set_index, &last_view_index);
|
|
|
|
/* If the object is all pointers, or if the part with pointers fits
|
|
in our bitmap, then we are ok. Otherwise we have to allocate it
|
|
a different way. */
|
|
if (all_bits_set != -1)
|
|
{
|
|
/* In this case the initial part of the object is all reference
|
|
fields, and the end of the object is all non-reference
|
|
fields. We represent the mark as a count of the fields,
|
|
shifted. In the GC the computation looks something like
|
|
this:
|
|
value = DS_LENGTH | WORDS_TO_BYTES (last_set_index + 1);
|
|
DS_LENGTH is 0.
|
|
WORDS_TO_BYTES shifts by log2(bytes-per-pointer). */
|
|
count = 0;
|
|
low = 0;
|
|
high = 0;
|
|
++last_set_index;
|
|
while (last_set_index)
|
|
{
|
|
if ((last_set_index & 1))
|
|
set_bit (&low, &high, log2_size + count);
|
|
last_set_index >>= 1;
|
|
++count;
|
|
}
|
|
value = build_int_cst_wide (value_type, low, high);
|
|
}
|
|
else if (! pointer_after_end)
|
|
{
|
|
/* Bottom two bits for bitmap mark type are 01. */
|
|
set_bit (&low, &high, 0);
|
|
value = build_int_cst_wide (value_type, low, high);
|
|
}
|
|
else
|
|
{
|
|
/* Compute a procedure-based object descriptor. We know that our
|
|
`kind' is 0, and `env' is likewise 0, so we have a simple
|
|
computation. From the GC sources:
|
|
(((((env) << LOG_MAX_MARK_PROCS) | (proc_index)) << DS_TAG_BITS) \
|
|
| DS_PROC)
|
|
Here DS_PROC == 2. */
|
|
procedure_object_descriptor:
|
|
value = build_int_cst (value_type, 2);
|
|
}
|
|
|
|
return value;
|
|
}
|