/** * Perform some fixups for variadic functions. * To make the rest of the frontend code easier to understand we add * "dummy" parameters until the number of parameters transmitted in registers. * (because otherwise the backend wouldn't store the value of the register * parameters into memory for the VLA magic) */ static bool sparc_variadic_fixups(ir_graph *const irg, calling_convention_t *const cconv) { ir_entity *entity = get_irg_entity(irg); ir_type *mtp = get_entity_type(entity); if (!is_method_variadic(mtp)) return false; if (cconv->n_param_regs >= SPARC_N_PARAM_REGS) return false; size_t const n_params = get_method_n_params(mtp); size_t const n_ress = get_method_n_ress(mtp); size_t const new_n_params = n_params + (SPARC_N_PARAM_REGS - cconv->n_param_regs); unsigned const cc_mask = get_method_calling_convention(mtp); mtp_additional_properties const props = get_method_additional_properties(mtp); ir_type *const new_mtp = new_type_method(new_n_params, n_ress, true, cc_mask, props); type_dbg_info *const dbgi = get_type_dbg_info(mtp); set_type_dbg_info(new_mtp, dbgi); for (size_t i = 0; i < n_ress; ++i) { ir_type *type = get_method_res_type(mtp, i); set_method_res_type(new_mtp, i, type); } for (size_t i = 0; i < n_params; ++i) { ir_type *type = get_method_param_type(mtp, i); set_method_param_type(new_mtp, i, type); } ir_type *const frame_type = get_irg_frame_type(irg); ir_mode *const gp_reg_mode = sparc_reg_classes[CLASS_sparc_gp].mode; ir_type *const gp_reg_type = get_type_for_mode(gp_reg_mode); for (size_t i = n_params; i < new_n_params; ++i) { set_method_param_type(new_mtp, i, gp_reg_type); new_parameter_entity(frame_type, i, gp_reg_type); } set_entity_type(entity, new_mtp); return true; }
void gcji_setup_rtti_entity(class_t *cls, ir_type *type) { ir_entity *rtti_entity = oo_get_class_rtti_entity(type); assert(type_java_lang_class != NULL); set_entity_type(rtti_entity, type_java_lang_class); ir_entity *name_ent = gcji_emit_utf8_const( cls->constants[cls->constants[cls->this_class]->classref.name_index], 1); uint16_t accflags = cls->access_flags; ir_entity *method_table = emit_method_table(type); ir_entity *field_table = emit_field_table(type); ir_graph *ccode = get_const_code_irg(); ir_node *size_in_bytes = new_r_Size(ccode, mode_int, type); int16_t field_count = cls->n_fields; int16_t static_field_count = 0; for (int16_t i = 0; i < field_count; i++) { if ((cls->fields[i]->access_flags & ACCESS_FLAG_STATIC) != 0) ++static_field_count; } ir_entity *superclass_rtti = NULL; if (get_class_n_supertypes(type) > 0) { ir_type *superclass = get_class_supertype(type, 0); /* TODO: search for first non-interface instead of taking the * first one and hoping it is a non-interface */ assert(!oo_get_class_is_interface(superclass)); superclass_rtti = gcji_get_rtti_entity(superclass); } ir_node *vtable_init = get_vtable_ref(type); int16_t interface_count = cls->n_interfaces; ir_entity *interfaces = emit_interface_table(type); // w/o slots 0=rtti. see lower_oo.c int16_t vtable_method_count = oo_get_class_vtable_size(type) - (ddispatch_get_index_of_first_method() - ddispatch_get_vptr_points_to_index()); ir_node *class_vtable = get_vtable_ref(type_java_lang_class); /* initializer for base class java.lang.Object */ ir_initializer_t *base_init = create_initializer_compound(1); set_compound_init_node(base_init, 0, class_vtable); /* initializer for java.lang.Class */ unsigned NUM_FIELDS = 39; ir_initializer_t *init = create_initializer_compound(NUM_FIELDS); size_t f = 0; set_initializer_compound_value(init, f++, base_init); set_compound_init_num(init, f++, mode_P, 407000); set_compound_init_entref(init, f++, name_ent); set_compound_init_num(init, f++, mode_ushort, accflags); set_compound_init_entref(init, f++, superclass_rtti); // _Jv_Constants inlined. not sure if this is needed for compiled code. set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_entref(init, f++, method_table); set_compound_init_num(init, f++, mode_short, cls->n_methods); set_compound_init_num(init, f++, mode_short, vtable_method_count); set_compound_init_entref(init, f++, field_table); set_compound_init_node(init, f++, size_in_bytes); set_compound_init_num(init, f++, mode_short, field_count); set_compound_init_num(init, f++, mode_short, static_field_count); set_compound_init_node(init, f++, vtable_init); // most of the following fields are set at runtime during the class linking. set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_entref(init, f++, interfaces); set_compound_init_null(init, f++); set_compound_init_num(init, f++, mode_short, interface_count); set_compound_init_num(init, f++, mode_byte, 1); // state set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); // engine set_compound_init_null(init, f++); assert(f == NUM_FIELDS); set_entity_initializer(rtti_entity, init); set_entity_alignment(rtti_entity, 32); add_pointer_in_jcr_segment(rtti_entity); }