compiler, runtime: Add type information to single object allocation.
From-SVN: r216490
This commit is contained in:
parent
7b28fa2c6b
commit
0f2aeaa817
|
@ -12170,7 +12170,7 @@ class Array_construction_expression : public Expression
|
||||||
{ return this->vals_ == NULL ? 0 : this->vals_->size(); }
|
{ return this->vals_ == NULL ? 0 : this->vals_->size(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int
|
virtual int
|
||||||
do_traverse(Traverse* traverse);
|
do_traverse(Traverse* traverse);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -12495,11 +12495,33 @@ class Slice_construction_expression : public Array_construction_expression
|
||||||
: Array_construction_expression(EXPRESSION_SLICE_CONSTRUCTION,
|
: Array_construction_expression(EXPRESSION_SLICE_CONSTRUCTION,
|
||||||
type, indexes, vals, location),
|
type, indexes, vals, location),
|
||||||
valtype_(NULL)
|
valtype_(NULL)
|
||||||
{ go_assert(type->is_slice_type()); }
|
{
|
||||||
|
go_assert(type->is_slice_type());
|
||||||
|
|
||||||
|
mpz_t lenval;
|
||||||
|
Expression* length;
|
||||||
|
if (vals == NULL || vals->empty())
|
||||||
|
mpz_init_set_ui(lenval, 0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (this->indexes() == NULL)
|
||||||
|
mpz_init_set_ui(lenval, vals->size());
|
||||||
|
else
|
||||||
|
mpz_init_set_ui(lenval, indexes->back() + 1);
|
||||||
|
}
|
||||||
|
Type* int_type = Type::lookup_integer_type("int");
|
||||||
|
length = Expression::make_integer(&lenval, int_type, location);
|
||||||
|
mpz_clear(lenval);
|
||||||
|
Type* element_type = type->array_type()->element_type();
|
||||||
|
this->valtype_ = Type::make_array_type(element_type, length);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Note that taking the address of a slice literal is invalid.
|
// Note that taking the address of a slice literal is invalid.
|
||||||
|
|
||||||
|
int
|
||||||
|
do_traverse(Traverse* traverse);
|
||||||
|
|
||||||
Expression*
|
Expression*
|
||||||
do_copy()
|
do_copy()
|
||||||
{
|
{
|
||||||
|
@ -12518,6 +12540,19 @@ class Slice_construction_expression : public Array_construction_expression
|
||||||
Type* valtype_;
|
Type* valtype_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Traversal.
|
||||||
|
|
||||||
|
int
|
||||||
|
Slice_construction_expression::do_traverse(Traverse* traverse)
|
||||||
|
{
|
||||||
|
if (this->Array_construction_expression::do_traverse(traverse)
|
||||||
|
== TRAVERSE_EXIT)
|
||||||
|
return TRAVERSE_EXIT;
|
||||||
|
if (Type::traverse(this->valtype_, traverse) == TRAVERSE_EXIT)
|
||||||
|
return TRAVERSE_EXIT;
|
||||||
|
return TRAVERSE_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
// Return the backend representation for constructing a slice.
|
// Return the backend representation for constructing a slice.
|
||||||
|
|
||||||
Bexpression*
|
Bexpression*
|
||||||
|
@ -12532,24 +12567,7 @@ Slice_construction_expression::do_get_backend(Translate_context* context)
|
||||||
|
|
||||||
Location loc = this->location();
|
Location loc = this->location();
|
||||||
Type* element_type = array_type->element_type();
|
Type* element_type = array_type->element_type();
|
||||||
if (this->valtype_ == NULL)
|
go_assert(this->valtype_ != NULL);
|
||||||
{
|
|
||||||
mpz_t lenval;
|
|
||||||
Expression* length;
|
|
||||||
if (this->vals() == NULL || this->vals()->empty())
|
|
||||||
mpz_init_set_ui(lenval, 0);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (this->indexes() == NULL)
|
|
||||||
mpz_init_set_ui(lenval, this->vals()->size());
|
|
||||||
else
|
|
||||||
mpz_init_set_ui(lenval, this->indexes()->back() + 1);
|
|
||||||
}
|
|
||||||
Type* int_type = Type::lookup_integer_type("int");
|
|
||||||
length = Expression::make_integer(&lenval, int_type, loc);
|
|
||||||
mpz_clear(lenval);
|
|
||||||
this->valtype_ = Type::make_array_type(element_type, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression_list* vals = this->vals();
|
Expression_list* vals = this->vals();
|
||||||
if (this->vals() == NULL || this->vals()->empty())
|
if (this->vals() == NULL || this->vals()->empty())
|
||||||
|
@ -14028,7 +14046,7 @@ class GC_symbol_expression : public Expression
|
||||||
protected:
|
protected:
|
||||||
Type*
|
Type*
|
||||||
do_type()
|
do_type()
|
||||||
{ return Type::make_pointer_type(Type::make_void_type()); }
|
{ return Type::lookup_integer_type("uintptr"); }
|
||||||
|
|
||||||
bool
|
bool
|
||||||
do_is_immutable() const
|
do_is_immutable() const
|
||||||
|
|
|
@ -96,9 +96,6 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
|
||||||
// Create function descriptors as needed.
|
// Create function descriptors as needed.
|
||||||
::gogo->create_function_descriptors();
|
::gogo->create_function_descriptors();
|
||||||
|
|
||||||
// Write out queued up functions for hash and comparison of types.
|
|
||||||
::gogo->write_specific_type_functions();
|
|
||||||
|
|
||||||
// Now that we have seen all the names, verify that types are
|
// Now that we have seen all the names, verify that types are
|
||||||
// correct.
|
// correct.
|
||||||
::gogo->verify_types();
|
::gogo->verify_types();
|
||||||
|
@ -130,6 +127,9 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
|
||||||
// Convert complicated go and defer statements into simpler ones.
|
// Convert complicated go and defer statements into simpler ones.
|
||||||
::gogo->simplify_thunk_statements();
|
::gogo->simplify_thunk_statements();
|
||||||
|
|
||||||
|
// Write out queued up functions for hash and comparison of types.
|
||||||
|
::gogo->write_specific_type_functions();
|
||||||
|
|
||||||
// Flatten the parse tree.
|
// Flatten the parse tree.
|
||||||
::gogo->flatten();
|
::gogo->flatten();
|
||||||
|
|
||||||
|
|
|
@ -4196,21 +4196,18 @@ Build_method_tables::type(Type* type)
|
||||||
Expression*
|
Expression*
|
||||||
Gogo::allocate_memory(Type* type, Location location)
|
Gogo::allocate_memory(Type* type, Location location)
|
||||||
{
|
{
|
||||||
Btype* btype = type->get_backend(this);
|
Expression* td = Expression::make_type_descriptor(type, location);
|
||||||
size_t size = this->backend()->type_size(btype);
|
Expression* size =
|
||||||
mpz_t size_val;
|
Expression::make_type_info(type, Expression::TYPE_INFO_SIZE);
|
||||||
mpz_init_set_ui(size_val, size);
|
|
||||||
Type* uintptr = Type::lookup_integer_type("uintptr");
|
|
||||||
Expression* size_expr =
|
|
||||||
Expression::make_integer(&size_val, uintptr, location);
|
|
||||||
|
|
||||||
// If the package imports unsafe, then it may play games with
|
// If this package imports unsafe, then it may play games with
|
||||||
// pointers that look like integers.
|
// pointers that look like integers. We should be able to determine
|
||||||
|
// whether or not to use new pointers in libgo/go-new.c. FIXME.
|
||||||
bool use_new_pointers = this->imported_unsafe_ || type->has_pointer();
|
bool use_new_pointers = this->imported_unsafe_ || type->has_pointer();
|
||||||
return Runtime::make_call((use_new_pointers
|
return Runtime::make_call((use_new_pointers
|
||||||
? Runtime::NEW
|
? Runtime::NEW
|
||||||
: Runtime::NEW_NOPOINTERS),
|
: Runtime::NEW_NOPOINTERS),
|
||||||
location, 1, size_expr);
|
location, 2, td, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Traversal class used to check for return statements.
|
// Traversal class used to check for return statements.
|
||||||
|
|
|
@ -82,6 +82,7 @@ static Type*
|
||||||
runtime_function_type(Runtime_function_type bft)
|
runtime_function_type(Runtime_function_type bft)
|
||||||
{
|
{
|
||||||
go_assert(bft < NUMBER_OF_RUNTIME_FUNCTION_TYPES);
|
go_assert(bft < NUMBER_OF_RUNTIME_FUNCTION_TYPES);
|
||||||
|
Type* any = Type::make_pointer_type(Type::make_void_type());
|
||||||
if (runtime_function_types[bft] == NULL)
|
if (runtime_function_types[bft] == NULL)
|
||||||
{
|
{
|
||||||
const Location bloc = Linemap::predeclared_location();
|
const Location bloc = Linemap::predeclared_location();
|
||||||
|
@ -145,13 +146,11 @@ runtime_function_type(Runtime_function_type bft)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RFT_SLICE:
|
case RFT_SLICE:
|
||||||
t = Type::make_array_type(Type::make_void_type(), NULL);
|
t = Type::make_array_type(any, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RFT_MAP:
|
case RFT_MAP:
|
||||||
t = Type::make_map_type(Type::make_void_type(),
|
t = Type::make_map_type(any, any, bloc);
|
||||||
Type::make_void_type(),
|
|
||||||
bloc);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RFT_MAPITER:
|
case RFT_MAPITER:
|
||||||
|
@ -159,7 +158,7 @@ runtime_function_type(Runtime_function_type bft)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RFT_CHAN:
|
case RFT_CHAN:
|
||||||
t = Type::make_channel_type(true, true, Type::make_void_type());
|
t = Type::make_channel_type(true, true, any);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RFT_IFACE:
|
case RFT_IFACE:
|
||||||
|
|
|
@ -221,10 +221,10 @@ DEF_GO_RUNTIME(REGISTER_GC_ROOTS, "__go_register_gc_roots", P1(POINTER), R0())
|
||||||
|
|
||||||
|
|
||||||
// Allocate memory.
|
// Allocate memory.
|
||||||
DEF_GO_RUNTIME(NEW, "__go_new", P1(UINTPTR), R1(POINTER))
|
DEF_GO_RUNTIME(NEW, "__go_new", P2(TYPE, UINTPTR), R1(POINTER))
|
||||||
|
|
||||||
// Allocate memory which can not contain pointers.
|
// Allocate memory which can not contain pointers.
|
||||||
DEF_GO_RUNTIME(NEW_NOPOINTERS, "__go_new_nopointers", P1(UINTPTR), R1(POINTER))
|
DEF_GO_RUNTIME(NEW_NOPOINTERS, "__go_new_nopointers", P2(TYPE, UINTPTR), R1(POINTER))
|
||||||
|
|
||||||
|
|
||||||
// Start a new goroutine.
|
// Start a new goroutine.
|
||||||
|
|
|
@ -1878,7 +1878,7 @@ Inc_dec_statement::do_lower(Gogo*, Named_object*, Block*, Statement_inserter*)
|
||||||
|
|
||||||
mpz_t oval;
|
mpz_t oval;
|
||||||
mpz_init_set_ui(oval, 1UL);
|
mpz_init_set_ui(oval, 1UL);
|
||||||
Expression* oexpr = Expression::make_integer(&oval, NULL, loc);
|
Expression* oexpr = Expression::make_integer(&oval, this->expr_->type(), loc);
|
||||||
mpz_clear(oval);
|
mpz_clear(oval);
|
||||||
|
|
||||||
Operator op = this->is_inc_ ? OPERATOR_PLUSEQ : OPERATOR_MINUSEQ;
|
Operator op = this->is_inc_ ? OPERATOR_PLUSEQ : OPERATOR_MINUSEQ;
|
||||||
|
|
|
@ -1244,6 +1244,25 @@ Type::make_type_descriptor_var(Gogo* gogo)
|
||||||
phash = &ins.first->second;
|
phash = &ins.first->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The type descriptor symbol for the unsafe.Pointer type is defined in
|
||||||
|
// libgo/go-unsafe-pointer.c, so we just return a reference to that
|
||||||
|
// symbol if necessary.
|
||||||
|
if (this->is_unsafe_pointer_type())
|
||||||
|
{
|
||||||
|
Location bloc = Linemap::predeclared_location();
|
||||||
|
|
||||||
|
Type* td_type = Type::make_type_descriptor_type();
|
||||||
|
Btype* td_btype = td_type->get_backend(gogo);
|
||||||
|
this->type_descriptor_var_ =
|
||||||
|
gogo->backend()->immutable_struct_reference("__go_tdn_unsafe.Pointer",
|
||||||
|
td_btype,
|
||||||
|
bloc);
|
||||||
|
|
||||||
|
if (phash != NULL)
|
||||||
|
*phash = this->type_descriptor_var_;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::string var_name = this->type_descriptor_var_name(gogo, nt);
|
std::string var_name = this->type_descriptor_var_name(gogo, nt);
|
||||||
|
|
||||||
// Build the contents of the type descriptor.
|
// Build the contents of the type descriptor.
|
||||||
|
@ -1540,7 +1559,7 @@ Type::make_type_descriptor_type()
|
||||||
"hash", uint32_type,
|
"hash", uint32_type,
|
||||||
"hashfn", uintptr_type,
|
"hashfn", uintptr_type,
|
||||||
"equalfn", uintptr_type,
|
"equalfn", uintptr_type,
|
||||||
"gc", unsafe_pointer_type,
|
"gc", uintptr_type,
|
||||||
"string", pointer_string_type,
|
"string", pointer_string_type,
|
||||||
"", pointer_uncommon_type,
|
"", pointer_uncommon_type,
|
||||||
"ptrToThis",
|
"ptrToThis",
|
||||||
|
@ -6027,7 +6046,6 @@ Array_type::write_hash_function(Gogo* gogo, Named_type* name,
|
||||||
tref->set_is_lvalue();
|
tref->set_is_lvalue();
|
||||||
s = Statement::make_assignment_operation(OPERATOR_PLUSEQ, tref, ele_size,
|
s = Statement::make_assignment_operation(OPERATOR_PLUSEQ, tref, ele_size,
|
||||||
bloc);
|
bloc);
|
||||||
|
|
||||||
Block* statements = gogo->finish_block(bloc);
|
Block* statements = gogo->finish_block(bloc);
|
||||||
|
|
||||||
for_range->add_statements(statements);
|
for_range->add_statements(statements);
|
||||||
|
|
|
@ -10,13 +10,17 @@
|
||||||
#include "malloc.h"
|
#include "malloc.h"
|
||||||
|
|
||||||
void *
|
void *
|
||||||
__go_new (uintptr_t size)
|
__go_new (const struct __go_type_descriptor *td, uintptr_t size)
|
||||||
{
|
{
|
||||||
return runtime_mallocgc (size, 0, 0);
|
return runtime_mallocgc (size,
|
||||||
|
(uintptr) td | TypeInfo_SingleObject,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
__go_new_nopointers (uintptr_t size)
|
__go_new_nopointers (const struct __go_type_descriptor *td, uintptr_t size)
|
||||||
{
|
{
|
||||||
return runtime_mallocgc (size, 0, FlagNoScan);
|
return runtime_mallocgc (size,
|
||||||
|
(uintptr) td | TypeInfo_SingleObject,
|
||||||
|
FlagNoScan);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue