/* * Transform Sel[method] to SymC[method] if possible. * (see opt_polymorphy in libfirm) */ static ir_node *transform_node_Sel2(ir_node *node) { ir_node *new_node; ir_entity *ent = get_Sel_entity(node); if (get_irp_phase_state() == phase_building) return node; if (!get_opt_dyn_meth_dispatch()) return node; if (!is_Method_type(get_entity_type(ent))) return node; ddispatch_binding bind = oo_get_entity_binding(ent); assert (bind != bind_unknown); if (bind == bind_static) return node; /* If we know the dynamic type, we can replace the Sel by a constant. */ ir_node *ptr = get_Sel_ptr(node); /* The address we select from. */ ir_type *dyn_tp = get_irn_typeinfo_type(ptr); if (dyn_tp != initial_type) { ir_entity *called_ent; /* We know which method will be called, no dispatch necessary. */ called_ent = resolve_ent_polymorphy(dyn_tp, ent); assert (! oo_get_method_is_abstract(called_ent)); assert (! oo_get_class_is_interface(get_entity_owner(called_ent))); new_node = copy_const_value(get_irn_dbg_info(node), get_atomic_ent_value(called_ent), get_nodes_block(node)); return new_node; } return node; }
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); }