compiler, runtime: Add type information to single object allocation.
authorIan Lance Taylor <ian@gcc.gnu.org>
Mon, 20 Oct 2014 19:12:44 +0000 (19:12 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Mon, 20 Oct 2014 19:12:44 +0000 (19:12 +0000)
From-SVN: r216490

gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/go.cc
gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/runtime.cc
gcc/go/gofrontend/runtime.def
gcc/go/gofrontend/statements.cc
gcc/go/gofrontend/types.cc
libgo/runtime/go-new.c

index df1650a172a6af6f877fd922018862f34de121b8..2f7bf2bbe16be18e85979236818f66b16096109c 100644 (file)
@@ -12170,7 +12170,7 @@ class Array_construction_expression : public Expression
   { return this->vals_ == NULL ? 0 : this->vals_->size(); }
 
 protected:
-  int
+  virtual int
   do_traverse(Traverse* traverse);
 
   bool
@@ -12495,11 +12495,33 @@ class Slice_construction_expression : public Array_construction_expression
     : Array_construction_expression(EXPRESSION_SLICE_CONSTRUCTION,
                                    type, indexes, vals, location),
       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:
   // Note that taking the address of a slice literal is invalid.
 
+  int
+  do_traverse(Traverse* traverse);
+
   Expression*
   do_copy()
   {
@@ -12518,6 +12540,19 @@ class Slice_construction_expression : public Array_construction_expression
   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.
 
 Bexpression*
@@ -12532,24 +12567,7 @@ Slice_construction_expression::do_get_backend(Translate_context* context)
 
   Location loc = this->location();
   Type* element_type = array_type->element_type();
-  if (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);
-    }
+  go_assert(this->valtype_ != NULL);
 
   Expression_list* vals = this->vals();
   if (this->vals() == NULL || this->vals()->empty())
@@ -14028,7 +14046,7 @@ class GC_symbol_expression : public Expression
  protected:
   Type*
   do_type()
-  { return Type::make_pointer_type(Type::make_void_type()); }
+  { return Type::lookup_integer_type("uintptr"); }
 
   bool
   do_is_immutable() const
index 1772623a9ce209ef00855e80e9af528e30ee1d49..7850e00a041f0c4babfbc8b2b74a7a47580a25b0 100644 (file)
@@ -96,9 +96,6 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
   // Create function descriptors as needed.
   ::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
   // correct.
   ::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.
   ::gogo->simplify_thunk_statements();
 
+  // Write out queued up functions for hash and comparison of types.
+  ::gogo->write_specific_type_functions();
+
   // Flatten the parse tree.
   ::gogo->flatten();
 
index 02a980607feed2e744a996f70435eb1377cc36b1..7c3ebce103c7128ebf0d07b533d1cd568bcc2faa 100644 (file)
@@ -4196,21 +4196,18 @@ Build_method_tables::type(Type* type)
 Expression*
 Gogo::allocate_memory(Type* type, Location location)
 {
-  Btype* btype = type->get_backend(this);
-  size_t size = this->backend()->type_size(btype);
-  mpz_t size_val;
-  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
-  // pointers that look like integers.
+  Expression* td = Expression::make_type_descriptor(type, location);
+  Expression* size =
+    Expression::make_type_info(type, Expression::TYPE_INFO_SIZE);
+
+  // If this package imports unsafe, then it may play games with
+  // 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();
   return Runtime::make_call((use_new_pointers
                             ? Runtime::NEW
                             : Runtime::NEW_NOPOINTERS),
-                            location, 1, size_expr);
+                           location, 2, td, size);
 }
 
 // Traversal class used to check for return statements.
index 811c8f5b79f1f9f0b8301e1cbfb09591fc0b5b23..4370a580fca2ad768769e7724cb30fb5a3247fc0 100644 (file)
@@ -82,6 +82,7 @@ static Type*
 runtime_function_type(Runtime_function_type bft)
 {
   go_assert(bft < NUMBER_OF_RUNTIME_FUNCTION_TYPES);
+  Type* any = Type::make_pointer_type(Type::make_void_type());
   if (runtime_function_types[bft] == NULL)
     {
       const Location bloc = Linemap::predeclared_location();
@@ -145,13 +146,11 @@ runtime_function_type(Runtime_function_type bft)
          break;
 
        case RFT_SLICE:
-         t = Type::make_array_type(Type::make_void_type(), NULL);
+         t = Type::make_array_type(any, NULL);
          break;
 
        case RFT_MAP:
-         t = Type::make_map_type(Type::make_void_type(),
-                                 Type::make_void_type(),
-                                 bloc);
+         t = Type::make_map_type(any, any, bloc);
          break;
 
        case RFT_MAPITER:
@@ -159,7 +158,7 @@ runtime_function_type(Runtime_function_type bft)
          break;
 
        case RFT_CHAN:
-         t = Type::make_channel_type(true, true, Type::make_void_type());
+         t = Type::make_channel_type(true, true, any);
          break;
 
        case RFT_IFACE:
index 8c6e82b226768469b78f09f39372d6027ec18a89..bec1cfc09ea0686dad30943398f51ca63d804405 100644 (file)
@@ -221,10 +221,10 @@ DEF_GO_RUNTIME(REGISTER_GC_ROOTS, "__go_register_gc_roots", P1(POINTER), R0())
 
 
 // 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.
-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.
index ccf5452371ddf14e9a0b2cc693a7494b80f30cfa..0478e2085885d6d597e8f38902b88c2f014625aa 100644 (file)
@@ -1878,7 +1878,7 @@ Inc_dec_statement::do_lower(Gogo*, Named_object*, Block*, Statement_inserter*)
 
   mpz_t oval;
   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);
 
   Operator op = this->is_inc_ ? OPERATOR_PLUSEQ : OPERATOR_MINUSEQ;
index 99b9421b36adb03dc1691ad2f334227cbe3de213..fb7ebee9423e5909a7c863286758bfdaa979b810 100644 (file)
@@ -1244,6 +1244,25 @@ Type::make_type_descriptor_var(Gogo* gogo)
       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);
 
   // Build the contents of the type descriptor.
@@ -1540,7 +1559,7 @@ Type::make_type_descriptor_type()
                                       "hash", uint32_type,
                                       "hashfn", uintptr_type,
                                       "equalfn", uintptr_type,
-                                      "gc", unsafe_pointer_type,
+                                      "gc", uintptr_type,
                                       "string", pointer_string_type,
                                       "", pointer_uncommon_type,
                                       "ptrToThis",
@@ -6027,7 +6046,6 @@ Array_type::write_hash_function(Gogo* gogo, Named_type* name,
   tref->set_is_lvalue();
   s = Statement::make_assignment_operation(OPERATOR_PLUSEQ, tref, ele_size,
                                           bloc);
-
   Block* statements = gogo->finish_block(bloc);
 
   for_range->add_statements(statements);
index 9d46706eaa417be4e0e33170e44b31eeb815b347..dad6efb30c0cc3f0c3dd00779334afb4fe203d4c 100644 (file)
 #include "malloc.h"
 
 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 *
-__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);
 }