Example #1
0
File: ooopt.c Project: Selujo/liboo
/*
 * 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;
}
Example #2
0
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);
}