compiler, runtime: copy string code from Go 1.7
authorIan Lance Taylor <ian@gcc.gnu.org>
Wed, 12 Oct 2016 18:17:52 +0000 (18:17 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Wed, 12 Oct 2016 18:17:52 +0000 (18:17 +0000)
    Add compiler support for turning concatenating strings into a call to
    a runtime function that takes the appropriate number of arguments.

    Rename some local variables in mgc0.c to avoid macros that the new
    rune.go causes to appear in runtime.inc.

    Reviewed-on: https://go-review.googlesource.com/30827

From-SVN: r241074

24 files changed:
gcc/go/gofrontend/MERGE
gcc/go/gofrontend/escape.cc
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/expressions.h
gcc/go/gofrontend/runtime.cc
gcc/go/gofrontend/runtime.def
libgo/Makefile.am
libgo/Makefile.in
libgo/go/runtime/error.go
libgo/go/runtime/rune.go [new file with mode: 0644]
libgo/go/runtime/string.go [new file with mode: 0644]
libgo/go/runtime/string_test.go
libgo/go/runtime/stubs.go
libgo/runtime/go-byte-array-to-string.c [deleted file]
libgo/runtime/go-int-array-to-string.c [deleted file]
libgo/runtime/go-int-to-string.c [deleted file]
libgo/runtime/go-rune.c [deleted file]
libgo/runtime/go-string-to-byte-array.c [deleted file]
libgo/runtime/go-string-to-int-array.c [deleted file]
libgo/runtime/go-strplus.c [deleted file]
libgo/runtime/malloc.h
libgo/runtime/mgc0.c
libgo/runtime/runtime.h
libgo/runtime/string.goc [deleted file]

index a6ea428fbe6f2f652d54f7b44689b09d74f0ab5a..9c1ed014fc31009d4939e8dc4afd28c7331c1f3d 100644 (file)
@@ -1,4 +1,4 @@
-c18d9f0e7270144ebd1f67d85995f434bbdab0b0
+f38ba8837a0c961e18d982930e192132870f3836
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index 732af77a1a114305e1668f4152036eb6708938fb..73be757d8476c1bd5038ce201cc174097c98561e 100644 (file)
@@ -1233,13 +1233,17 @@ Escape_analysis_assign::expression(Expression** pexpr)
              case Runtime::MAKESLICE2:
              case Runtime::MAKESLICE1BIG:
              case Runtime::MAKESLICE2BIG:
-             case Runtime::BYTE_ARRAY_TO_STRING:
-             case Runtime::INT_ARRAY_TO_STRING:
-             case Runtime::STRING_TO_BYTE_ARRAY:
-             case Runtime::STRING_TO_INT_ARRAY:
-             case Runtime::STRING_PLUS:
+             case Runtime::SLICEBYTETOSTRING:
+             case Runtime::SLICERUNETOSTRING:
+             case Runtime::STRINGTOSLICEBYTE:
+             case Runtime::STRINGTOSLICERUNE:
+             case Runtime::CONCATSTRINGS:
+             case Runtime::CONCATSTRING2:
+             case Runtime::CONCATSTRING3:
+             case Runtime::CONCATSTRING4:
+             case Runtime::CONCATSTRING5:
              case Runtime::CONSTRUCT_MAP:
-             case Runtime::INT_TO_STRING:
+             case Runtime::INTSTRING:
                {
                  Node* runtime_node = Node::make_node(fe);
                  this->context_->track(runtime_node);
@@ -1842,21 +1846,25 @@ Escape_analysis_assign::assign(Node* dst, Node* src)
                  case Runtime::MAKESLICE1BIG:
                  case Runtime::MAKESLICE2BIG:
                    // DST = make(...).
-                 case Runtime::BYTE_ARRAY_TO_STRING:
+                 case Runtime::SLICEBYTETOSTRING:
                    // DST = string([]byte{...}).
-                 case Runtime::INT_ARRAY_TO_STRING:
+                 case Runtime::SLICERUNETOSTRING:
                    // DST = string([]int{...}).
-                 case Runtime::STRING_TO_BYTE_ARRAY:
+                 case Runtime::STRINGTOSLICEBYTE:
                    // DST = []byte(str).
-                 case Runtime::STRING_TO_INT_ARRAY:
-                   // DST = []int(str).
-                 case Runtime::STRING_PLUS:
+                 case Runtime::STRINGTOSLICERUNE:
+                   // DST = []rune(str).
+                 case Runtime::CONCATSTRINGS:
+                 case Runtime::CONCATSTRING2:
+                 case Runtime::CONCATSTRING3:
+                 case Runtime::CONCATSTRING4:
+                 case Runtime::CONCATSTRING5:
                    // DST = str1 + str2
                  case Runtime::CONSTRUCT_MAP:
                    // When building a map literal's backend representation.
                    // Likely never seen here and covered in
                    // Expression::EXPRESSION_MAP_CONSTRUCTION.
-                 case Runtime::INT_TO_STRING:
+                 case Runtime::INTSTRING:
                    // DST = string(i).
                  case Runtime::IFACEE2E2:
                  case Runtime::IFACEI2E2:
@@ -2614,13 +2622,17 @@ Escape_analysis_flood::flood(Level level, Node* dst, Node* src,
                    case Runtime::MAKESLICE2:
                    case Runtime::MAKESLICE1BIG:
                    case Runtime::MAKESLICE2BIG:
-                   case Runtime::BYTE_ARRAY_TO_STRING:
-                   case Runtime::INT_ARRAY_TO_STRING:
-                   case Runtime::STRING_TO_BYTE_ARRAY:
-                   case Runtime::STRING_TO_INT_ARRAY:
-                   case Runtime::STRING_PLUS:
+                   case Runtime::SLICEBYTETOSTRING:
+                   case Runtime::SLICERUNETOSTRING:
+                   case Runtime::STRINGTOSLICEBYTE:
+                   case Runtime::STRINGTOSLICERUNE:
+                   case Runtime::CONCATSTRINGS:
+                   case Runtime::CONCATSTRING2:
+                   case Runtime::CONCATSTRING3:
+                   case Runtime::CONCATSTRING4:
+                   case Runtime::CONCATSTRING5:
                    case Runtime::CONSTRUCT_MAP:
-                   case Runtime::INT_TO_STRING:
+                   case Runtime::INTSTRING:
                    case Runtime::CONVERT_INTERFACE:
                      // All runtime calls that involve allocation of memory
                      // except new.  Runtime::NEW gets lowered into an
index 4f8a519f4fdacc2ebd1fcfeecbe8f039f442f90e..40c8a4e2df7bb46fde77646741cfa012dda2e08b 100644 (file)
@@ -3419,7 +3419,8 @@ Type_conversion_expression::do_get_backend(Translate_context* context)
        }
 
       Expression* i2s_expr =
-          Runtime::make_call(Runtime::INT_TO_STRING, loc, 1, this->expr_);
+          Runtime::make_call(Runtime::INTSTRING, loc, 2,
+                            Expression::make_nil(loc), this->expr_);
       return Expression::make_cast(type, i2s_expr, loc)->get_backend(context);
     }
   else if (type->is_string_type() && expr_type->is_slice_type())
@@ -3431,16 +3432,14 @@ Type_conversion_expression::do_get_backend(Translate_context* context)
 
       Runtime::Function code;
       if (e->integer_type()->is_byte())
-        code = Runtime::BYTE_ARRAY_TO_STRING;
+        code = Runtime::SLICEBYTETOSTRING;
       else
         {
           go_assert(e->integer_type()->is_rune());
-          code = Runtime::INT_ARRAY_TO_STRING;
+          code = Runtime::SLICERUNETOSTRING;
         }
-      Expression* valptr = a->get_value_pointer(gogo, this->expr_);
-      Expression* len = a->get_length(gogo, this->expr_);
-      return Runtime::make_call(code, loc, 2, valptr,
-                               len)->get_backend(context);
+      return Runtime::make_call(code, loc, 2, Expression::make_nil(loc),
+                               this->expr_)->get_backend(context);
     }
   else if (type->is_slice_type() && expr_type->is_string_type())
     {
@@ -3449,13 +3448,15 @@ Type_conversion_expression::do_get_backend(Translate_context* context)
 
       Runtime::Function code;
       if (e->integer_type()->is_byte())
-       code = Runtime::STRING_TO_BYTE_ARRAY;
+       code = Runtime::STRINGTOSLICEBYTE;
       else
        {
          go_assert(e->integer_type()->is_rune());
-         code = Runtime::STRING_TO_INT_ARRAY;
+         code = Runtime::STRINGTOSLICERUNE;
        }
-      Expression* s2a = Runtime::make_call(code, loc, 1, this->expr_);
+      Expression* s2a = Runtime::make_call(code, loc, 2,
+                                          Expression::make_nil(loc),
+                                          this->expr_);
       return Expression::make_unsafe_cast(type, s2a, loc)->get_backend(context);
     }
   else if (type->is_numeric_type())
@@ -5068,6 +5069,31 @@ Binary_expression::do_lower(Gogo* gogo, Named_object*,
        return this->lower_interface_value_comparison(gogo, inserter);
     }
 
+  // Lower string concatenation to String_concat_expression, so that
+  // we can group sequences of string additions.
+  if (this->left_->type()->is_string_type() && this->op_ == OPERATOR_PLUS)
+    {
+      Expression_list* exprs;
+      String_concat_expression* left_sce =
+       this->left_->string_concat_expression();
+      if (left_sce != NULL)
+       exprs = left_sce->exprs();
+      else
+       {
+         exprs = new Expression_list();
+         exprs->push_back(this->left_);
+       }
+
+      String_concat_expression* right_sce =
+       this->right_->string_concat_expression();
+      if (right_sce != NULL)
+       exprs->append(right_sce->exprs());
+      else
+       exprs->push_back(this->right_);
+
+      return Expression::make_string_concat(exprs);
+    }
+
   return this;
 }
 
@@ -5277,25 +5303,6 @@ Binary_expression::do_flatten(Gogo* gogo, Named_object*,
     }
 
   Temporary_statement* temp;
-  if (this->left_->type()->is_string_type()
-      && this->op_ == OPERATOR_PLUS)
-    {
-      if (!this->left_->is_variable()
-         && !this->left_->is_constant())
-        {
-          temp = Statement::make_temporary(NULL, this->left_, loc);
-          inserter->insert(temp);
-          this->left_ = Expression::make_temporary_reference(temp, loc);
-        }
-      if (!this->right_->is_variable()
-         && !this->right_->is_constant())
-        {
-          temp =
-              Statement::make_temporary(this->left_->type(), this->right_, loc);
-          this->right_ = Expression::make_temporary_reference(temp, loc);
-          inserter->insert(temp);
-        }
-    }
 
   Type* left_type = this->left_->type();
   bool is_shift_op = (this->op_ == OPERATOR_LSHIFT
@@ -5792,14 +5799,9 @@ Binary_expression::do_get_backend(Translate_context* context)
       go_unreachable();
     }
 
-  if (left_type->is_string_type())
-    {
-      go_assert(this->op_ == OPERATOR_PLUS);
-      Expression* string_plus =
-          Runtime::make_call(Runtime::STRING_PLUS, loc, 2,
-                             this->left_, this->right_);
-      return string_plus->get_backend(context);
-    }
+  // The only binary operation for string is +, and that should have
+  // been converted to a String_concat_expression in do_lower.
+  go_assert(!left_type->is_string_type());
 
   // For complex division Go might want slightly different results than the
   // backend implementation provides, so we have our own runtime routine.
@@ -6294,6 +6296,182 @@ Expression::comparison(Translate_context* context, Type* result_type,
   return ret;
 }
 
+// Class String_concat_expression.
+
+bool
+String_concat_expression::do_is_constant() const
+{
+  for (Expression_list::const_iterator pe = this->exprs_->begin();
+       pe != this->exprs_->end();
+       ++pe)
+    {
+      if (!(*pe)->is_constant())
+       return false;
+    }
+  return true;
+}
+
+bool
+String_concat_expression::do_is_immutable() const
+{
+  for (Expression_list::const_iterator pe = this->exprs_->begin();
+       pe != this->exprs_->end();
+       ++pe)
+    {
+      if (!(*pe)->is_immutable())
+       return false;
+    }
+  return true;
+}
+
+Type*
+String_concat_expression::do_type()
+{
+  Type* t = this->exprs_->front()->type();
+  Expression_list::iterator pe = this->exprs_->begin();
+  ++pe;
+  for (; pe != this->exprs_->end(); ++pe)
+    {
+      Type* t1;
+      if (!Binary_expression::operation_type(OPERATOR_PLUS, t,
+                                            (*pe)->type(),
+                                            &t1))
+       return Type::make_error_type();
+      t = t1;
+    }
+  return t;
+}
+
+void
+String_concat_expression::do_determine_type(const Type_context* context)
+{
+  Type_context subcontext(*context);
+  for (Expression_list::iterator pe = this->exprs_->begin();
+       pe != this->exprs_->end();
+       ++pe)
+    {
+      Type* t = (*pe)->type();
+      if (!t->is_abstract())
+       {
+         subcontext.type = t;
+         break;
+       }
+    }
+  if (subcontext.type == NULL)
+    subcontext.type = this->exprs_->front()->type();
+  for (Expression_list::iterator pe = this->exprs_->begin();
+       pe != this->exprs_->end();
+       ++pe)
+    (*pe)->determine_type(&subcontext);
+}
+
+void
+String_concat_expression::do_check_types(Gogo*)
+{
+  if (this->is_error_expression())
+    return;
+  Type* t = this->exprs_->front()->type();
+  if (t->is_error())
+    {
+      this->set_is_error();
+      return;
+    }
+  Expression_list::iterator pe = this->exprs_->begin();
+  ++pe;
+  for (; pe != this->exprs_->end(); ++pe)
+    {
+      Type* t1 = (*pe)->type();
+      if (!Type::are_compatible_for_binop(t, t1))
+       {
+         this->report_error("incompatible types in binary expression");
+         return;
+       }
+      if (!Binary_expression::check_operator_type(OPERATOR_PLUS, t, t1,
+                                                 this->location()))
+       {
+         this->set_is_error();
+         return;
+       }
+    }
+}
+
+Expression*
+String_concat_expression::do_flatten(Gogo*, Named_object*,
+                                    Statement_inserter*)
+{
+  if (this->is_error_expression())
+    return this;
+  Location loc = this->location();
+  Type* type = this->type();
+  Expression* nil_arg = Expression::make_nil(loc);
+  Expression* call;
+  switch (this->exprs_->size())
+    {
+    case 0: case 1:
+      go_unreachable();
+
+    case 2: case 3: case 4: case 5:
+      {
+       Expression* len = Expression::make_integer_ul(this->exprs_->size(),
+                                                     NULL, loc);
+       Array_type* arg_type = Type::make_array_type(type, len);
+       arg_type->set_is_array_incomparable();
+       Expression* arg =
+         Expression::make_array_composite_literal(arg_type, this->exprs_,
+                                                  loc);
+       Runtime::Function code;
+       switch (this->exprs_->size())
+         {
+         default:
+           go_unreachable();
+         case 2:
+           code = Runtime::CONCATSTRING2;
+           break;
+         case 3:
+           code = Runtime::CONCATSTRING3;
+           break;
+         case 4:
+           code = Runtime::CONCATSTRING4;
+           break;
+         case 5:
+           code = Runtime::CONCATSTRING5;
+           break;
+         }
+       call = Runtime::make_call(code, loc, 2, nil_arg, arg);
+      }
+      break;
+
+    default:
+      {
+       Type* arg_type = Type::make_array_type(type, NULL);
+       Slice_construction_expression* sce =
+         Expression::make_slice_composite_literal(arg_type, this->exprs_,
+                                                  loc);
+       sce->set_storage_does_not_escape();
+       call = Runtime::make_call(Runtime::CONCATSTRINGS, loc, 2, nil_arg,
+                                 sce);
+      }
+      break;
+    }
+
+  return Expression::make_cast(type, call, loc);
+}
+
+void
+String_concat_expression::do_dump_expression(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->ostream() << "concat(";
+  ast_dump_context->dump_expression_list(this->exprs_, false);
+  ast_dump_context->ostream() << ")";
+}
+
+Expression*
+Expression::make_string_concat(Expression_list* exprs)
+{
+  return new String_concat_expression(exprs);
+}
+
 // Class Bound_method_expression.
 
 // Traversal.
index 6db6eddc52984cd5f76568886d6abb25bb00026f..11614c3c3e64ca3a943fd6e2a87a666b0ddabc6f 100644 (file)
@@ -37,6 +37,7 @@ class Type_conversion_expression;
 class Unsafe_type_conversion_expression;
 class Unary_expression;
 class Binary_expression;
+class String_concat_expression;
 class Call_expression;
 class Call_result_expression;
 class Func_expression;
@@ -85,6 +86,7 @@ class Expression
     EXPRESSION_TYPE,
     EXPRESSION_UNARY,
     EXPRESSION_BINARY,
+    EXPRESSION_STRING_CONCAT,
     EXPRESSION_CONST_REFERENCE,
     EXPRESSION_VAR_REFERENCE,
     EXPRESSION_ENCLOSED_VAR_REFERENCE,
@@ -160,6 +162,10 @@ class Expression
   static Expression*
   make_binary(Operator, Expression*, Expression*, Location);
 
+  // Make a string concatenation expression.
+  static Expression*
+  make_string_concat(Expression_list*);
+
   // Make a reference to a constant in an expression.
   static Expression*
   make_const_reference(Named_object*, Location);
@@ -620,6 +626,14 @@ class Expression
   binary_expression()
   { return this->convert<Binary_expression, EXPRESSION_BINARY>(); }
 
+  // If this is a string concatenation expression, return the
+  // String_concat_expression structure.  Otherwise, return NULL.
+  String_concat_expression*
+  string_concat_expression()
+  {
+    return this->convert<String_concat_expression, EXPRESSION_STRING_CONCAT>();
+  }
+
   // If this is a call expression, return the Call_expression
   // structure.  Otherwise, return NULL.  This is a controlled dynamic
   // cast.
@@ -1877,6 +1891,13 @@ class Binary_expression : public Expression
   static bool
   check_operator_type(Operator op, Type* type, Type* otype, Location);
 
+  // Set *RESULT_TYPE to the resulting type when OP is applied to
+  // operands of type LEFT_TYPE and RIGHT_TYPE.  Return true on
+  // success, false on failure.
+  static bool
+  operation_type(Operator op, Type* left_type, Type* right_type,
+                Type** result_type);
+
  protected:
   int
   do_traverse(Traverse* traverse);
@@ -1927,10 +1948,6 @@ class Binary_expression : public Expression
   do_dump_expression(Ast_dump_context*) const;
 
  private:
-  static bool
-  operation_type(Operator op, Type* left_type, Type* right_type,
-                Type** result_type);
-
   static bool
   cmp_to_bool(Operator op, int cmp);
 
@@ -1980,6 +1997,69 @@ class Binary_expression : public Expression
   Type* type_;
 };
 
+// A string concatenation expression.  This is a sequence of strings
+// added together.  It is created when lowering Binary_expression.
+
+class String_concat_expression : public Expression
+{
+ public:
+  String_concat_expression(Expression_list* exprs)
+    : Expression(EXPRESSION_STRING_CONCAT, exprs->front()->location()),
+      exprs_(exprs)
+  { }
+
+  // Return the list of string expressions to be concatenated.
+  Expression_list*
+  exprs()
+  { return this->exprs_; }
+
+ protected:
+  int
+  do_traverse(Traverse* traverse)
+  { return this->exprs_->traverse(traverse); }
+
+  Expression*
+  do_lower(Gogo*, Named_object*, Statement_inserter*, int)
+  { return this; }
+
+  Expression*
+  do_flatten(Gogo*, Named_object*, Statement_inserter*);
+
+  bool
+  do_is_constant() const;
+
+  bool
+  do_is_immutable() const;
+
+  Type*
+  do_type();
+
+  void
+  do_determine_type(const Type_context*);
+
+  void
+  do_check_types(Gogo*);
+
+  Expression*
+  do_copy()
+  { return Expression::make_string_concat(this->exprs_->copy()); }
+
+  Bexpression*
+  do_get_backend(Translate_context*)
+  { go_unreachable(); }
+
+  void
+  do_export(Export*) const
+  { go_unreachable(); }
+
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
+ private:
+  // The string expressions to concatenate.
+  Expression_list* exprs_;
+};
+
 // A call expression.  The go statement needs to dig inside this.
 
 class Call_expression : public Expression
index 98678f4adea47ef6d7f0a84da089937481a2b7d7..4072920b9d25f4a1d41d58b7c88445aaa462754f 100644 (file)
@@ -64,6 +64,14 @@ enum Runtime_function_type
   RFT_FUNC_PTR,
   // Pointer to Go type descriptor.
   RFT_TYPE,
+  // [2]string.
+  RFT_ARRAY2STRING,
+  // [3]string.
+  RFT_ARRAY3STRING,
+  // [4]string.
+  RFT_ARRAY4STRING,
+  // [5]string.
+  RFT_ARRAY5STRING,
 
   NUMBER_OF_RUNTIME_FUNCTION_TYPES
 };
@@ -180,6 +188,30 @@ runtime_function_type(Runtime_function_type bft)
        case RFT_TYPE:
          t = Type::make_type_descriptor_ptr_type();
          break;
+
+       case RFT_ARRAY2STRING:
+         t = Type::make_array_type(Type::make_string_type(),
+                                   Expression::make_integer_ul(2, NULL,
+                                                               bloc));
+         break;
+
+       case RFT_ARRAY3STRING:
+         t = Type::make_array_type(Type::make_string_type(),
+                                   Expression::make_integer_ul(3, NULL,
+                                                               bloc));
+         break;
+
+       case RFT_ARRAY4STRING:
+         t = Type::make_array_type(Type::make_string_type(),
+                                   Expression::make_integer_ul(4, NULL,
+                                                               bloc));
+         break;
+
+       case RFT_ARRAY5STRING:
+         t = Type::make_array_type(Type::make_string_type(),
+                                   Expression::make_integer_ul(5, NULL,
+                                                               bloc));
+         break;
        }
 
       runtime_function_types[bft] = t;
@@ -226,6 +258,10 @@ convert_to_runtime_function_type(Runtime_function_type bft, Expression* e,
     case RFT_CHAN:
     case RFT_IFACE:
     case RFT_EFACE:
+    case RFT_ARRAY2STRING:
+    case RFT_ARRAY3STRING:
+    case RFT_ARRAY4STRING:
+    case RFT_ARRAY5STRING:
       return Expression::make_unsafe_cast(runtime_function_type(bft), e, loc);
 
     case RFT_TYPE:
index e7edfa652f36fbb20653ebbeed1b153820c22b04..4e4c3e3a85833a818d113e6eb9f4e87785df0c1a 100644 (file)
@@ -38,8 +38,17 @@ DEF_GO_RUNTIME(STRINGITER, "runtime.stringiter", P2(STRING, INT), R1(INT))
 DEF_GO_RUNTIME(STRINGITER2, "runtime.stringiter2", P2(STRING, INT),
               R2(INT, RUNE))
 
-// Concatenate two strings.
-DEF_GO_RUNTIME(STRING_PLUS, "__go_string_plus", P2(STRING, STRING), R1(STRING))
+// Concatenate strings.
+DEF_GO_RUNTIME(CONCATSTRINGS, "runtime.concatstrings", P2(POINTER, SLICE),
+              R1(STRING))
+DEF_GO_RUNTIME(CONCATSTRING2, "runtime.concatstring2",
+              P2(POINTER, ARRAY2STRING), R1(STRING))
+DEF_GO_RUNTIME(CONCATSTRING3, "runtime.concatstring3",
+              P2(POINTER, ARRAY3STRING), R1(STRING))
+DEF_GO_RUNTIME(CONCATSTRING4, "runtime.concatstring4",
+              P2(POINTER, ARRAY4STRING), R1(STRING))
+DEF_GO_RUNTIME(CONCATSTRING5, "runtime.concatstring5",
+              P2(POINTER, ARRAY5STRING), R1(STRING))
 
 // Compare two strings.
 DEF_GO_RUNTIME(STRCMP, "__go_strcmp", P2(STRING, STRING), R1(INT))
@@ -49,23 +58,23 @@ DEF_GO_RUNTIME(STRING_SLICE, "__go_string_slice", P3(STRING, INT, INT),
               R1(STRING))
 
 // Convert an integer to a string.
-DEF_GO_RUNTIME(INT_TO_STRING, "__go_int_to_string", P1(INT), R1(STRING))
+DEF_GO_RUNTIME(INTSTRING, "runtime.intstring", P2(POINTER, INT64), R1(STRING))
 
-// Convert a byte array to a string.
-DEF_GO_RUNTIME(BYTE_ARRAY_TO_STRING, "__go_byte_array_to_string",
-              P2(POINTER, INT), R1(STRING))
+// Convert a []byte to a string.
+DEF_GO_RUNTIME(SLICEBYTETOSTRING, "runtime.slicebytetostring",
+              P2(POINTER, SLICE), R1(STRING))
 
-// Convert an int array to a string.
-DEF_GO_RUNTIME(INT_ARRAY_TO_STRING, "__go_int_array_to_string",
-              P2(POINTER, INT), R1(STRING))
+// Convert a []rune to a string.
+DEF_GO_RUNTIME(SLICERUNETOSTRING, "runtime.slicerunetostring",
+              P2(POINTER, SLICE), R1(STRING))
 
-// Convert a string to a byte slice.
-DEF_GO_RUNTIME(STRING_TO_BYTE_ARRAY, "__go_string_to_byte_array",
-              P1(STRING), R1(SLICE))
+// Convert a string to a []byte.
+DEF_GO_RUNTIME(STRINGTOSLICEBYTE, "runtime.stringtoslicebyte",
+              P2(POINTER, STRING), R1(SLICE))
 
-// Convert a string to an int slice.
-DEF_GO_RUNTIME(STRING_TO_INT_ARRAY, "__go_string_to_int_array",
-              P1(STRING), R1(SLICE))
+// Convert a string to a []rune.
+DEF_GO_RUNTIME(STRINGTOSLICERUNE, "runtime.stringtoslicerune",
+              P2(POINTER, STRING), R1(SLICE))
 
 
 // Complex division.
index d37bb68ba9c90f9338f87698f619de3ad81a7824..be5b0cac19c1996c65b4b521998709c13d09ce4c 100644 (file)
@@ -441,7 +441,6 @@ runtime_files = \
        runtime/go-append.c \
        runtime/go-assert.c \
        runtime/go-assert-interface.c \
-       runtime/go-byte-array-to-string.c \
        runtime/go-breakpoint.c \
        runtime/go-caller.c \
        runtime/go-callers.c \
@@ -458,8 +457,6 @@ runtime_files = \
        runtime/go-eface-val-compare.c \
        runtime/go-ffi.c \
        runtime/go-fieldtrack.c \
-       runtime/go-int-array-to-string.c \
-       runtime/go-int-to-string.c \
        runtime/go-interface-compare.c \
        runtime/go-interface-eface-compare.c \
        runtime/go-interface-val-compare.c \
@@ -476,14 +473,10 @@ runtime_files = \
        runtime/go-panic.c \
        runtime/go-recover.c \
        runtime/go-reflect-call.c \
-       runtime/go-rune.c \
        runtime/go-runtime-error.c \
        runtime/go-setenv.c \
        runtime/go-signal.c \
        runtime/go-strcmp.c \
-       runtime/go-string-to-byte-array.c \
-       runtime/go-string-to-int-array.c \
-       runtime/go-strplus.c \
        runtime/go-strslice.c \
        runtime/go-traceback.c \
        runtime/go-type-complex.c \
@@ -529,7 +522,6 @@ runtime_files = \
        reflect.c \
        runtime1.c \
        sigqueue.c \
-       string.c \
        time.c \
        $(runtime_getncpu_file)
 
index 8493333290ca8ee3f52ddc021a37e43ba059f337..6797a349bad083668129bf9efc83506b98df9411 100644 (file)
@@ -241,32 +241,29 @@ libgo_llgo_la_DEPENDENCIES = $(am__DEPENDENCIES_4)
 @LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@   getncpu-bsd.lo
 @LIBGO_IS_LINUX_TRUE@am__objects_5 = getncpu-linux.lo
 am__objects_6 = go-append.lo go-assert.lo go-assert-interface.lo \
-       go-byte-array-to-string.lo go-breakpoint.lo go-caller.lo \
-       go-callers.lo go-can-convert-interface.lo go-cdiv.lo go-cgo.lo \
+       go-breakpoint.lo go-caller.lo go-callers.lo \
+       go-can-convert-interface.lo go-cdiv.lo go-cgo.lo \
        go-check-interface.lo go-construct-map.lo \
        go-convert-interface.lo go-copy.lo go-defer.lo \
        go-deferred-recover.lo go-eface-compare.lo \
        go-eface-val-compare.lo go-ffi.lo go-fieldtrack.lo \
-       go-int-array-to-string.lo go-int-to-string.lo \
        go-interface-compare.lo go-interface-eface-compare.lo \
        go-interface-val-compare.lo go-make-slice.lo go-matherr.lo \
        go-memclr.lo go-memcmp.lo go-memequal.lo go-memmove.lo \
        go-nanotime.lo go-now.lo go-new.lo go-nosys.lo go-panic.lo \
-       go-recover.lo go-reflect-call.lo go-rune.lo \
-       go-runtime-error.lo go-setenv.lo go-signal.lo go-strcmp.lo \
-       go-string-to-byte-array.lo go-string-to-int-array.lo \
-       go-strplus.lo go-strslice.lo go-traceback.lo \
-       go-type-complex.lo go-type-eface.lo go-type-float.lo \
-       go-type-identity.lo go-type-interface.lo go-type-string.lo \
-       go-typedesc-equal.lo go-unsafe-new.lo go-unsafe-newarray.lo \
-       go-unsafe-pointer.lo go-unsetenv.lo go-unwind.lo go-varargs.lo \
-       env_posix.lo heapdump.lo mcache.lo mcentral.lo \
-       $(am__objects_1) mfixalloc.lo mgc0.lo mheap.lo msize.lo \
-       $(am__objects_2) panic.lo parfor.lo print.lo proc.lo \
+       go-recover.lo go-reflect-call.lo go-runtime-error.lo \
+       go-setenv.lo go-signal.lo go-strcmp.lo go-strslice.lo \
+       go-traceback.lo go-type-complex.lo go-type-eface.lo \
+       go-type-float.lo go-type-identity.lo go-type-interface.lo \
+       go-type-string.lo go-typedesc-equal.lo go-unsafe-new.lo \
+       go-unsafe-newarray.lo go-unsafe-pointer.lo go-unsetenv.lo \
+       go-unwind.lo go-varargs.lo env_posix.lo heapdump.lo mcache.lo \
+       mcentral.lo $(am__objects_1) mfixalloc.lo mgc0.lo mheap.lo \
+       msize.lo $(am__objects_2) panic.lo parfor.lo print.lo proc.lo \
        runtime.lo signal_unix.lo thread.lo $(am__objects_3) yield.lo \
        $(am__objects_4) cpuprof.lo go-iface.lo lfstack.lo malloc.lo \
        mprof.lo netpoll.lo rdebug.lo reflect.lo runtime1.lo \
-       sigqueue.lo string.lo time.lo $(am__objects_5)
+       sigqueue.lo time.lo $(am__objects_5)
 am_libgo_llgo_la_OBJECTS = $(am__objects_6)
 libgo_llgo_la_OBJECTS = $(am_libgo_llgo_la_OBJECTS)
 libgo_llgo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -843,7 +840,6 @@ runtime_files = \
        runtime/go-append.c \
        runtime/go-assert.c \
        runtime/go-assert-interface.c \
-       runtime/go-byte-array-to-string.c \
        runtime/go-breakpoint.c \
        runtime/go-caller.c \
        runtime/go-callers.c \
@@ -860,8 +856,6 @@ runtime_files = \
        runtime/go-eface-val-compare.c \
        runtime/go-ffi.c \
        runtime/go-fieldtrack.c \
-       runtime/go-int-array-to-string.c \
-       runtime/go-int-to-string.c \
        runtime/go-interface-compare.c \
        runtime/go-interface-eface-compare.c \
        runtime/go-interface-val-compare.c \
@@ -878,14 +872,10 @@ runtime_files = \
        runtime/go-panic.c \
        runtime/go-recover.c \
        runtime/go-reflect-call.c \
-       runtime/go-rune.c \
        runtime/go-runtime-error.c \
        runtime/go-setenv.c \
        runtime/go-signal.c \
        runtime/go-strcmp.c \
-       runtime/go-string-to-byte-array.c \
-       runtime/go-string-to-int-array.c \
-       runtime/go-strplus.c \
        runtime/go-strslice.c \
        runtime/go-traceback.c \
        runtime/go-type-complex.c \
@@ -931,7 +921,6 @@ runtime_files = \
        reflect.c \
        runtime1.c \
        sigqueue.c \
-       string.c \
        time.c \
        $(runtime_getncpu_file)
 
@@ -1569,7 +1558,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-assert-interface.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-assert.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-breakpoint.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-byte-array-to-string.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-caller.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-callers.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-can-convert-interface.Plo@am__quote@
@@ -1586,8 +1574,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-ffi.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-fieldtrack.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-iface.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-int-array-to-string.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-int-to-string.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-interface-compare.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-interface-eface-compare.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-interface-val-compare.Plo@am__quote@
@@ -1604,14 +1590,10 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-panic.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-recover.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-reflect-call.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-rune.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-runtime-error.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-setenv.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-signal.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-strcmp.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-string-to-byte-array.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-string-to-int-array.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-strplus.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-strslice.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-traceback.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-type-complex.Plo@am__quote@
@@ -1657,7 +1639,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/runtime1.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signal_unix.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sigqueue.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread-linux.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread-sema.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread.Plo@am__quote@
@@ -1748,13 +1729,6 @@ go-assert-interface.lo: runtime/go-assert-interface.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-assert-interface.lo `test -f 'runtime/go-assert-interface.c' || echo '$(srcdir)/'`runtime/go-assert-interface.c
 
-go-byte-array-to-string.lo: runtime/go-byte-array-to-string.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-byte-array-to-string.lo -MD -MP -MF $(DEPDIR)/go-byte-array-to-string.Tpo -c -o go-byte-array-to-string.lo `test -f 'runtime/go-byte-array-to-string.c' || echo '$(srcdir)/'`runtime/go-byte-array-to-string.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/go-byte-array-to-string.Tpo $(DEPDIR)/go-byte-array-to-string.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/go-byte-array-to-string.c' object='go-byte-array-to-string.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-byte-array-to-string.lo `test -f 'runtime/go-byte-array-to-string.c' || echo '$(srcdir)/'`runtime/go-byte-array-to-string.c
-
 go-breakpoint.lo: runtime/go-breakpoint.c
 @am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-breakpoint.lo -MD -MP -MF $(DEPDIR)/go-breakpoint.Tpo -c -o go-breakpoint.lo `test -f 'runtime/go-breakpoint.c' || echo '$(srcdir)/'`runtime/go-breakpoint.c
 @am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/go-breakpoint.Tpo $(DEPDIR)/go-breakpoint.Plo
@@ -1867,20 +1841,6 @@ go-fieldtrack.lo: runtime/go-fieldtrack.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-fieldtrack.lo `test -f 'runtime/go-fieldtrack.c' || echo '$(srcdir)/'`runtime/go-fieldtrack.c
 
-go-int-array-to-string.lo: runtime/go-int-array-to-string.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-int-array-to-string.lo -MD -MP -MF $(DEPDIR)/go-int-array-to-string.Tpo -c -o go-int-array-to-string.lo `test -f 'runtime/go-int-array-to-string.c' || echo '$(srcdir)/'`runtime/go-int-array-to-string.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/go-int-array-to-string.Tpo $(DEPDIR)/go-int-array-to-string.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/go-int-array-to-string.c' object='go-int-array-to-string.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-int-array-to-string.lo `test -f 'runtime/go-int-array-to-string.c' || echo '$(srcdir)/'`runtime/go-int-array-to-string.c
-
-go-int-to-string.lo: runtime/go-int-to-string.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-int-to-string.lo -MD -MP -MF $(DEPDIR)/go-int-to-string.Tpo -c -o go-int-to-string.lo `test -f 'runtime/go-int-to-string.c' || echo '$(srcdir)/'`runtime/go-int-to-string.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/go-int-to-string.Tpo $(DEPDIR)/go-int-to-string.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/go-int-to-string.c' object='go-int-to-string.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-int-to-string.lo `test -f 'runtime/go-int-to-string.c' || echo '$(srcdir)/'`runtime/go-int-to-string.c
-
 go-interface-compare.lo: runtime/go-interface-compare.c
 @am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-interface-compare.lo -MD -MP -MF $(DEPDIR)/go-interface-compare.Tpo -c -o go-interface-compare.lo `test -f 'runtime/go-interface-compare.c' || echo '$(srcdir)/'`runtime/go-interface-compare.c
 @am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/go-interface-compare.Tpo $(DEPDIR)/go-interface-compare.Plo
@@ -1993,13 +1953,6 @@ go-reflect-call.lo: runtime/go-reflect-call.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-reflect-call.lo `test -f 'runtime/go-reflect-call.c' || echo '$(srcdir)/'`runtime/go-reflect-call.c
 
-go-rune.lo: runtime/go-rune.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-rune.lo -MD -MP -MF $(DEPDIR)/go-rune.Tpo -c -o go-rune.lo `test -f 'runtime/go-rune.c' || echo '$(srcdir)/'`runtime/go-rune.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/go-rune.Tpo $(DEPDIR)/go-rune.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/go-rune.c' object='go-rune.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-rune.lo `test -f 'runtime/go-rune.c' || echo '$(srcdir)/'`runtime/go-rune.c
-
 go-runtime-error.lo: runtime/go-runtime-error.c
 @am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-runtime-error.lo -MD -MP -MF $(DEPDIR)/go-runtime-error.Tpo -c -o go-runtime-error.lo `test -f 'runtime/go-runtime-error.c' || echo '$(srcdir)/'`runtime/go-runtime-error.c
 @am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/go-runtime-error.Tpo $(DEPDIR)/go-runtime-error.Plo
@@ -2028,27 +1981,6 @@ go-strcmp.lo: runtime/go-strcmp.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-strcmp.lo `test -f 'runtime/go-strcmp.c' || echo '$(srcdir)/'`runtime/go-strcmp.c
 
-go-string-to-byte-array.lo: runtime/go-string-to-byte-array.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-string-to-byte-array.lo -MD -MP -MF $(DEPDIR)/go-string-to-byte-array.Tpo -c -o go-string-to-byte-array.lo `test -f 'runtime/go-string-to-byte-array.c' || echo '$(srcdir)/'`runtime/go-string-to-byte-array.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/go-string-to-byte-array.Tpo $(DEPDIR)/go-string-to-byte-array.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/go-string-to-byte-array.c' object='go-string-to-byte-array.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-string-to-byte-array.lo `test -f 'runtime/go-string-to-byte-array.c' || echo '$(srcdir)/'`runtime/go-string-to-byte-array.c
-
-go-string-to-int-array.lo: runtime/go-string-to-int-array.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-string-to-int-array.lo -MD -MP -MF $(DEPDIR)/go-string-to-int-array.Tpo -c -o go-string-to-int-array.lo `test -f 'runtime/go-string-to-int-array.c' || echo '$(srcdir)/'`runtime/go-string-to-int-array.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/go-string-to-int-array.Tpo $(DEPDIR)/go-string-to-int-array.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/go-string-to-int-array.c' object='go-string-to-int-array.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-string-to-int-array.lo `test -f 'runtime/go-string-to-int-array.c' || echo '$(srcdir)/'`runtime/go-string-to-int-array.c
-
-go-strplus.lo: runtime/go-strplus.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-strplus.lo -MD -MP -MF $(DEPDIR)/go-strplus.Tpo -c -o go-strplus.lo `test -f 'runtime/go-strplus.c' || echo '$(srcdir)/'`runtime/go-strplus.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/go-strplus.Tpo $(DEPDIR)/go-strplus.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/go-strplus.c' object='go-strplus.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-strplus.lo `test -f 'runtime/go-strplus.c' || echo '$(srcdir)/'`runtime/go-strplus.c
-
 go-strslice.lo: runtime/go-strslice.c
 @am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-strslice.lo -MD -MP -MF $(DEPDIR)/go-strslice.Tpo -c -o go-strslice.lo `test -f 'runtime/go-strslice.c' || echo '$(srcdir)/'`runtime/go-strslice.c
 @am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/go-strslice.Tpo $(DEPDIR)/go-strslice.Plo
index b9c73655255ebdde2c5e5ae66af67cdac95b17f6..36830016a5b43d1025a468f605fc60bda2e36982 100644 (file)
@@ -4,6 +4,8 @@
 
 package runtime
 
+import "unsafe"
+
 // The Error interface identifies a run time error.
 type Error interface {
        error
@@ -107,10 +109,8 @@ type errorCString struct{ cstr uintptr }
 
 func (e errorCString) RuntimeError() {}
 
-func cstringToGo(uintptr) string
-
 func (e errorCString) Error() string {
-       return "runtime error: " + cstringToGo(e.cstr)
+       return "runtime error: " + gostringnocopy((*byte)(unsafe.Pointer(e.cstr)))
 }
 
 // For calling from C.
diff --git a/libgo/go/runtime/rune.go b/libgo/go/runtime/rune.go
new file mode 100644 (file)
index 0000000..99c38e0
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * The authors of this software are Rob Pike and Ken Thompson.
+ *              Copyright (c) 2002 by Lucent Technologies.
+ *              Portions Copyright 2009 The Go Authors. All rights reserved.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ */
+
+/*
+ * This code is copied, with slight editing due to type differences,
+ * from a subset of ../lib9/utf/rune.c [which no longer exists]
+ */
+
+package runtime
+
+const (
+       bit1 = 7
+       bitx = 6
+       bit2 = 5
+       bit3 = 4
+       bit4 = 3
+       bit5 = 2
+
+       t1 = ((1 << (bit1 + 1)) - 1) ^ 0xFF /* 0000 0000 */
+       tx = ((1 << (bitx + 1)) - 1) ^ 0xFF /* 1000 0000 */
+       t2 = ((1 << (bit2 + 1)) - 1) ^ 0xFF /* 1100 0000 */
+       t3 = ((1 << (bit3 + 1)) - 1) ^ 0xFF /* 1110 0000 */
+       t4 = ((1 << (bit4 + 1)) - 1) ^ 0xFF /* 1111 0000 */
+       t5 = ((1 << (bit5 + 1)) - 1) ^ 0xFF /* 1111 1000 */
+
+       rune1 = (1 << (bit1 + 0*bitx)) - 1 /* 0000 0000 0111 1111 */
+       rune2 = (1 << (bit2 + 1*bitx)) - 1 /* 0000 0111 1111 1111 */
+       rune3 = (1 << (bit3 + 2*bitx)) - 1 /* 1111 1111 1111 1111 */
+       rune4 = (1 << (bit4 + 3*bitx)) - 1 /* 0001 1111 1111 1111 1111 1111 */
+
+       maskx = (1 << bitx) - 1 /* 0011 1111 */
+       testx = maskx ^ 0xFF    /* 1100 0000 */
+
+       runeerror = 0xFFFD
+       runeself  = 0x80
+
+       surrogateMin = 0xD800
+       surrogateMax = 0xDFFF
+
+       bad = runeerror
+
+       runemax = 0x10FFFF /* maximum rune value */
+)
+
+/*
+ * Modified by Wei-Hwa Huang, Google Inc., on 2004-09-24
+ * This is a slower but "safe" version of the old chartorune
+ * that works on strings that are not necessarily null-terminated.
+ *
+ * If you know for sure that your string is null-terminated,
+ * chartorune will be a bit faster.
+ *
+ * It is guaranteed not to attempt to access "length"
+ * past the incoming pointer.  This is to avoid
+ * possible access violations.  If the string appears to be
+ * well-formed but incomplete (i.e., to get the whole Rune
+ * we'd need to read past str+length) then we'll set the Rune
+ * to Bad and return 0.
+ *
+ * Note that if we have decoding problems for other
+ * reasons, we return 1 instead of 0.
+ */
+func charntorune(s string) (rune, int) {
+       /* When we're not allowed to read anything */
+       if len(s) <= 0 {
+               return bad, 1
+       }
+
+       /*
+        * one character sequence (7-bit value)
+        *      00000-0007F => T1
+        */
+       c := s[0]
+       if c < tx {
+               return rune(c), 1
+       }
+
+       // If we can't read more than one character we must stop
+       if len(s) <= 1 {
+               return bad, 1
+       }
+
+       /*
+        * two character sequence (11-bit value)
+        *      0080-07FF => t2 tx
+        */
+       c1 := s[1] ^ tx
+       if (c1 & testx) != 0 {
+               return bad, 1
+       }
+       if c < t3 {
+               if c < t2 {
+                       return bad, 1
+               }
+               l := ((rune(c) << bitx) | rune(c1)) & rune2
+               if l <= rune1 {
+                       return bad, 1
+               }
+               return l, 2
+       }
+
+       // If we can't read more than two characters we must stop
+       if len(s) <= 2 {
+               return bad, 1
+       }
+
+       /*
+        * three character sequence (16-bit value)
+        *      0800-FFFF => t3 tx tx
+        */
+       c2 := s[2] ^ tx
+       if (c2 & testx) != 0 {
+               return bad, 1
+       }
+       if c < t4 {
+               l := ((((rune(c) << bitx) | rune(c1)) << bitx) | rune(c2)) & rune3
+               if l <= rune2 {
+                       return bad, 1
+               }
+               if surrogateMin <= l && l <= surrogateMax {
+                       return bad, 1
+               }
+               return l, 3
+       }
+
+       if len(s) <= 3 {
+               return bad, 1
+       }
+
+       /*
+        * four character sequence (21-bit value)
+        *      10000-1FFFFF => t4 tx tx tx
+        */
+       c3 := s[3] ^ tx
+       if (c3 & testx) != 0 {
+               return bad, 1
+       }
+       if c < t5 {
+               l := ((((((rune(c) << bitx) | rune(c1)) << bitx) | rune(c2)) << bitx) | rune(c3)) & rune4
+               if l <= rune3 || l > runemax {
+                       return bad, 1
+               }
+               return l, 4
+       }
+
+       // Support for 5-byte or longer UTF-8 would go here, but
+       // since we don't have that, we'll just return bad.
+       return bad, 1
+}
+
+// runetochar converts r to bytes and writes the result to str.
+// returns the number of bytes generated.
+func runetochar(str []byte, r rune) int {
+       /* runes are signed, so convert to unsigned for range check. */
+       c := uint32(r)
+       /*
+        * one character sequence
+        *      00000-0007F => 00-7F
+        */
+       if c <= rune1 {
+               str[0] = byte(c)
+               return 1
+       }
+       /*
+        * two character sequence
+        *      0080-07FF => t2 tx
+        */
+       if c <= rune2 {
+               str[0] = byte(t2 | (c >> (1 * bitx)))
+               str[1] = byte(tx | (c & maskx))
+               return 2
+       }
+
+       /*
+        * If the rune is out of range or a surrogate half, convert it to the error rune.
+        * Do this test here because the error rune encodes to three bytes.
+        * Doing it earlier would duplicate work, since an out of range
+        * rune wouldn't have fit in one or two bytes.
+        */
+       if c > runemax {
+               c = runeerror
+       }
+       if surrogateMin <= c && c <= surrogateMax {
+               c = runeerror
+       }
+
+       /*
+        * three character sequence
+        *      0800-FFFF => t3 tx tx
+        */
+       if c <= rune3 {
+               str[0] = byte(t3 | (c >> (2 * bitx)))
+               str[1] = byte(tx | ((c >> (1 * bitx)) & maskx))
+               str[2] = byte(tx | (c & maskx))
+               return 3
+       }
+
+       /*
+        * four character sequence (21-bit value)
+        *     10000-1FFFFF => t4 tx tx tx
+        */
+       str[0] = byte(t4 | (c >> (3 * bitx)))
+       str[1] = byte(tx | ((c >> (2 * bitx)) & maskx))
+       str[2] = byte(tx | ((c >> (1 * bitx)) & maskx))
+       str[3] = byte(tx | (c & maskx))
+       return 4
+}
diff --git a/libgo/go/runtime/string.go b/libgo/go/runtime/string.go
new file mode 100644 (file)
index 0000000..5df3aa3
--- /dev/null
@@ -0,0 +1,446 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import (
+       "unsafe"
+)
+
+// For gccgo, use go:linkname to rename compiler-called functions to
+// themselves, so that the compiler will export them.
+//
+//go:linkname concatstrings runtime.concatstrings
+//go:linkname concatstring2 runtime.concatstring2
+//go:linkname concatstring3 runtime.concatstring3
+//go:linkname concatstring4 runtime.concatstring4
+//go:linkname concatstring5 runtime.concatstring5
+//go:linkname slicebytetostring runtime.slicebytetostring
+//go:linkname slicebytetostringtmp runtime.slicebytetostringtmp
+//go:linkname stringtoslicebyte runtime.stringtoslicebyte
+//go:linkname stringtoslicebytetmp runtime.stringtoslicebytetmp
+//go:linkname stringtoslicerune runtime.stringtoslicerune
+//go:linkname slicerunetostring runtime.slicerunetostring
+//go:linkname intstring runtime.intstring
+//go:linkname stringiter runtime.stringiter
+//go:linkname stringiter2 runtime.stringiter2
+// Temporary for C code to call:
+//go:linkname gostringnocopy runtime.gostringnocopy
+//go:linkname findnull runtime.findnull
+
+// The constant is known to the compiler.
+// There is no fundamental theory behind this number.
+const tmpStringBufSize = 32
+
+type tmpBuf [tmpStringBufSize]byte
+
+// concatstrings implements a Go string concatenation x+y+z+...
+// The operands are passed in the slice a.
+// If buf != nil, the compiler has determined that the result does not
+// escape the calling function, so the string data can be stored in buf
+// if small enough.
+func concatstrings(buf *tmpBuf, a []string) string {
+       // idx := 0
+       l := 0
+       count := 0
+       for _, x := range a {
+               n := len(x)
+               if n == 0 {
+                       continue
+               }
+               if l+n < l {
+                       throw("string concatenation too long")
+               }
+               l += n
+               count++
+               // idx = i
+       }
+       if count == 0 {
+               return ""
+       }
+
+       // If there is just one string and either it is not on the stack
+       // or our result does not escape the calling frame (buf != nil),
+       // then we can return that string directly.
+       // Commented out for gccgo--no implementation of stringDataOnStack.
+       // if count == 1 && (buf != nil || !stringDataOnStack(a[idx])) {
+       //      return a[idx]
+       // }
+       s, b := rawstringtmp(buf, l)
+       l = 0
+       for _, x := range a {
+               copy(b[l:], x)
+               l += len(x)
+       }
+       return s
+}
+
+func concatstring2(buf *tmpBuf, a [2]string) string {
+       return concatstrings(buf, a[:])
+}
+
+func concatstring3(buf *tmpBuf, a [3]string) string {
+       return concatstrings(buf, a[:])
+}
+
+func concatstring4(buf *tmpBuf, a [4]string) string {
+       return concatstrings(buf, a[:])
+}
+
+func concatstring5(buf *tmpBuf, a [5]string) string {
+       return concatstrings(buf, a[:])
+}
+
+// Buf is a fixed-size buffer for the result,
+// it is not nil if the result does not escape.
+func slicebytetostring(buf *tmpBuf, b []byte) string {
+       l := len(b)
+       if l == 0 {
+               // Turns out to be a relatively common case.
+               // Consider that you want to parse out data between parens in "foo()bar",
+               // you find the indices and convert the subslice to string.
+               return ""
+       }
+       if raceenabled && l > 0 {
+               racereadrangepc(unsafe.Pointer(&b[0]),
+                       uintptr(l),
+                       getcallerpc(unsafe.Pointer(&buf)),
+                       funcPC(slicebytetostring))
+       }
+       if msanenabled && l > 0 {
+               msanread(unsafe.Pointer(&b[0]), uintptr(l))
+       }
+       s, c := rawstringtmp(buf, l)
+       copy(c, b)
+       return s
+}
+
+func rawstringtmp(buf *tmpBuf, l int) (s string, b []byte) {
+       if buf != nil && l <= len(buf) {
+               b = buf[:l]
+               s = slicebytetostringtmp(b)
+       } else {
+               s, b = rawstring(l)
+       }
+       return
+}
+
+func slicebytetostringtmp(b []byte) string {
+       // Return a "string" referring to the actual []byte bytes.
+       // This is only for use by internal compiler optimizations
+       // that know that the string form will be discarded before
+       // the calling goroutine could possibly modify the original
+       // slice or synchronize with another goroutine.
+       // First such case is a m[string(k)] lookup where
+       // m is a string-keyed map and k is a []byte.
+       // Second such case is "<"+string(b)+">" concatenation where b is []byte.
+       // Third such case is string(b)=="foo" comparison where b is []byte.
+
+       if raceenabled && len(b) > 0 {
+               racereadrangepc(unsafe.Pointer(&b[0]),
+                       uintptr(len(b)),
+                       getcallerpc(unsafe.Pointer(&b)),
+                       funcPC(slicebytetostringtmp))
+       }
+       if msanenabled && len(b) > 0 {
+               msanread(unsafe.Pointer(&b[0]), uintptr(len(b)))
+       }
+       return *(*string)(unsafe.Pointer(&b))
+}
+
+func stringtoslicebyte(buf *tmpBuf, s string) []byte {
+       var b []byte
+       if buf != nil && len(s) <= len(buf) {
+               *buf = tmpBuf{}
+               b = buf[:len(s)]
+       } else {
+               b = rawbyteslice(len(s))
+       }
+       copy(b, s)
+       return b
+}
+
+func stringtoslicebytetmp(s string) []byte {
+       // Return a slice referring to the actual string bytes.
+       // This is only for use by internal compiler optimizations
+       // that know that the slice won't be mutated.
+       // The only such case today is:
+       // for i, c := range []byte(str)
+
+       str := stringStructOf(&s)
+       ret := slice{array: str.str, len: str.len, cap: str.len}
+       return *(*[]byte)(unsafe.Pointer(&ret))
+}
+
+func stringtoslicerune(buf *[tmpStringBufSize]rune, s string) []rune {
+       // two passes.
+       // unlike slicerunetostring, no race because strings are immutable.
+       n := 0
+       t := s
+       for len(s) > 0 {
+               _, k := charntorune(s)
+               s = s[k:]
+               n++
+       }
+       var a []rune
+       if buf != nil && n <= len(buf) {
+               *buf = [tmpStringBufSize]rune{}
+               a = buf[:n]
+       } else {
+               a = rawruneslice(n)
+       }
+       n = 0
+       for len(t) > 0 {
+               r, k := charntorune(t)
+               t = t[k:]
+               a[n] = r
+               n++
+       }
+       return a
+}
+
+func slicerunetostring(buf *tmpBuf, a []rune) string {
+       if raceenabled && len(a) > 0 {
+               racereadrangepc(unsafe.Pointer(&a[0]),
+                       uintptr(len(a))*unsafe.Sizeof(a[0]),
+                       getcallerpc(unsafe.Pointer(&buf)),
+                       funcPC(slicerunetostring))
+       }
+       if msanenabled && len(a) > 0 {
+               msanread(unsafe.Pointer(&a[0]), uintptr(len(a))*unsafe.Sizeof(a[0]))
+       }
+       var dum [4]byte
+       size1 := 0
+       for _, r := range a {
+               size1 += runetochar(dum[:], r)
+       }
+       s, b := rawstringtmp(buf, size1+3)
+       size2 := 0
+       for _, r := range a {
+               // check for race
+               if size2 >= size1 {
+                       break
+               }
+               size2 += runetochar(b[size2:], r)
+       }
+       return s[:size2]
+}
+
+type stringStruct struct {
+       str unsafe.Pointer
+       len int
+}
+
+// Variant with *byte pointer type for DWARF debugging.
+type stringStructDWARF struct {
+       str *byte
+       len int
+}
+
+func stringStructOf(sp *string) *stringStruct {
+       return (*stringStruct)(unsafe.Pointer(sp))
+}
+
+func intstring(buf *[4]byte, v int64) string {
+       var s string
+       var b []byte
+       if buf != nil {
+               b = buf[:]
+               s = slicebytetostringtmp(b)
+       } else {
+               s, b = rawstring(4)
+       }
+       if int64(rune(v)) != v {
+               v = runeerror
+       }
+       n := runetochar(b, rune(v))
+       return s[:n]
+}
+
+// stringiter returns the index of the next
+// rune after the rune that starts at s[k].
+func stringiter(s string, k int) int {
+       if k >= len(s) {
+               // 0 is end of iteration
+               return 0
+       }
+
+       c := s[k]
+       if c < runeself {
+               return k + 1
+       }
+
+       // multi-char rune
+       _, n := charntorune(s[k:])
+       return k + n
+}
+
+// stringiter2 returns the rune that starts at s[k]
+// and the index where the next rune starts.
+func stringiter2(s string, k int) (int, rune) {
+       if k >= len(s) {
+               // 0 is end of iteration
+               return 0, 0
+       }
+
+       c := s[k]
+       if c < runeself {
+               return k + 1, rune(c)
+       }
+
+       // multi-char rune
+       r, n := charntorune(s[k:])
+       return k + n, r
+}
+
+// rawstring allocates storage for a new string. The returned
+// string and byte slice both refer to the same storage.
+// The storage is not zeroed. Callers should use
+// b to set the string contents and then drop b.
+func rawstring(size int) (s string, b []byte) {
+       p := mallocgc(uintptr(size), nil, false)
+
+       stringStructOf(&s).str = p
+       stringStructOf(&s).len = size
+
+       *(*slice)(unsafe.Pointer(&b)) = slice{p, size, size}
+       return
+}
+
+// rawbyteslice allocates a new byte slice. The byte slice is not zeroed.
+func rawbyteslice(size int) (b []byte) {
+       cap := roundupsize(uintptr(size))
+       p := mallocgc(cap, nil, false)
+       if cap != uintptr(size) {
+               memclr(add(p, uintptr(size)), cap-uintptr(size))
+       }
+
+       *(*slice)(unsafe.Pointer(&b)) = slice{p, size, int(cap)}
+       return
+}
+
+// rawruneslice allocates a new rune slice. The rune slice is not zeroed.
+func rawruneslice(size int) (b []rune) {
+       if uintptr(size) > _MaxMem/4 {
+               throw("out of memory")
+       }
+       mem := roundupsize(uintptr(size) * 4)
+       p := mallocgc(mem, nil, false)
+       if mem != uintptr(size)*4 {
+               memclr(add(p, uintptr(size)*4), mem-uintptr(size)*4)
+       }
+
+       *(*slice)(unsafe.Pointer(&b)) = slice{p, size, int(mem / 4)}
+       return
+}
+
+// used by cmd/cgo
+func gobytes(p *byte, n int) []byte {
+       if n == 0 {
+               return make([]byte, 0)
+       }
+       x := make([]byte, n)
+       memmove(unsafe.Pointer(&x[0]), unsafe.Pointer(p), uintptr(n))
+       return x
+}
+
+func gostring(p *byte) string {
+       l := findnull(p)
+       if l == 0 {
+               return ""
+       }
+       s, b := rawstring(l)
+       memmove(unsafe.Pointer(&b[0]), unsafe.Pointer(p), uintptr(l))
+       return s
+}
+
+func gostringn(p *byte, l int) string {
+       if l == 0 {
+               return ""
+       }
+       s, b := rawstring(l)
+       memmove(unsafe.Pointer(&b[0]), unsafe.Pointer(p), uintptr(l))
+       return s
+}
+
+func index(s, t string) int {
+       if len(t) == 0 {
+               return 0
+       }
+       for i := 0; i < len(s); i++ {
+               if s[i] == t[0] && hasprefix(s[i:], t) {
+                       return i
+               }
+       }
+       return -1
+}
+
+func contains(s, t string) bool {
+       return index(s, t) >= 0
+}
+
+func hasprefix(s, t string) bool {
+       return len(s) >= len(t) && s[:len(t)] == t
+}
+
+func atoi(s string) int {
+       n := 0
+       for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+               n = n*10 + int(s[0]) - '0'
+               s = s[1:]
+       }
+       return n
+}
+
+//go:nosplit
+func findnull(s *byte) int {
+       if s == nil {
+               return 0
+       }
+       p := (*[_MaxMem/2 - 1]byte)(unsafe.Pointer(s))
+       l := 0
+       for p[l] != 0 {
+               l++
+       }
+       return l
+}
+
+func findnullw(s *uint16) int {
+       if s == nil {
+               return 0
+       }
+       p := (*[_MaxMem/2/2 - 1]uint16)(unsafe.Pointer(s))
+       l := 0
+       for p[l] != 0 {
+               l++
+       }
+       return l
+}
+
+//go:nosplit
+func gostringnocopy(str *byte) string {
+       ss := stringStruct{str: unsafe.Pointer(str), len: findnull(str)}
+       s := *(*string)(unsafe.Pointer(&ss))
+       return s
+}
+
+func gostringw(strw *uint16) string {
+       var buf [8]byte
+       str := (*[_MaxMem/2/2 - 1]uint16)(unsafe.Pointer(strw))
+       n1 := 0
+       for i := 0; str[i] != 0; i++ {
+               n1 += runetochar(buf[:], rune(str[i]))
+       }
+       s, b := rawstring(n1 + 4)
+       n2 := 0
+       for i := 0; str[i] != 0; i++ {
+               // check for race
+               if n2 >= n1 {
+                       break
+               }
+               n2 += runetochar(b[n2:], rune(str[i]))
+       }
+       b[n2] = 0 // for luck
+       return s[:n2]
+}
index f9411c00161ce630f243df2631634dad2b155df6..11fa454a5a8bf8dceb6e0bc7dd3bdd6a31f3e6f1 100644 (file)
@@ -223,7 +223,9 @@ func TestIntStringAllocs(t *testing.T) {
                        t.Fatalf("bad")
                }
        })
-       if n != 0 {
+       // was n != 0, changed for gccgo, which currently does one
+       // allocation for each call to string(unknown).
+       if n > 2 {
                t.Fatalf("want 0 allocs, got %v", n)
        }
 }
index f014610841f38de86706918c59a4b5d46718c258..d598a0afc4f0c66fb9f47dd94c15dcbb7ea49bc4 100644 (file)
@@ -250,17 +250,6 @@ func typedmemmove(typ *_type, dst, src unsafe.Pointer) {
        memmove(dst, src, typ.size)
 }
 
-// Here for gccgo unless and until we port string.go.
-type stringStruct struct {
-       str unsafe.Pointer
-       len int
-}
-
-// Here for gccgo unless and until we port string.go.
-func stringStructOf(sp *string) *stringStruct {
-       return (*stringStruct)(unsafe.Pointer(sp))
-}
-
 // Here for gccgo unless and until we port slice.go.
 type slice struct {
        array unsafe.Pointer
@@ -286,76 +275,6 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer {
        return c_mallocgc(size, uintptr(unsafe.Pointer(typ)), flag)
 }
 
-// Here for gccgo unless and until we port string.go.
-func rawstring(size int) (p unsafe.Pointer, s string) {
-       p = mallocgc(uintptr(size), nil, false)
-
-       (*(*stringStruct)(unsafe.Pointer(&s))).str = p
-       (*(*stringStruct)(unsafe.Pointer(&s))).len = size
-
-       return
-}
-
-// Here for gccgo unless and until we port string.go.
-func gostring(p *byte) string {
-       l := findnull(p)
-       if l == 0 {
-               return ""
-       }
-       m, s := rawstring(l)
-       memmove(m, unsafe.Pointer(p), uintptr(l))
-       return s
-}
-
-// Here for gccgo unless and until we port string.go.
-func index(s, t string) int {
-       if len(t) == 0 {
-               return 0
-       }
-       for i := 0; i < len(s); i++ {
-               if s[i] == t[0] && hasprefix(s[i:], t) {
-                       return i
-               }
-       }
-       return -1
-}
-
-// Here for gccgo unless and until we port string.go.
-func hasprefix(s, t string) bool {
-       return len(s) >= len(t) && s[:len(t)] == t
-}
-
-// Here for gccgo unless and until we port string.go.
-//go:nosplit
-func findnull(s *byte) int {
-       if s == nil {
-               return 0
-       }
-       p := (*[_MaxMem/2 - 1]byte)(unsafe.Pointer(s))
-       l := 0
-       for p[l] != 0 {
-               l++
-       }
-       return l
-}
-
-// Here for gccgo unless and until we port string.go.
-//go:nosplit
-func gostringnocopy(str *byte) string {
-       ss := stringStruct{str: unsafe.Pointer(str), len: findnull(str)}
-       return *(*string)(unsafe.Pointer(&ss))
-}
-
-// Here for gccgo unless and until we port string.go.
-func atoi(s string) int {
-       n := 0
-       for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
-               n = n*10 + int(s[0]) - '0'
-               s = s[1:]
-       }
-       return n
-}
-
 // Here for gccgo until we port mgc.go.
 var writeBarrier struct {
        enabled bool   // compiler emits a check of this before calling write barrier
@@ -445,3 +364,6 @@ func releaseSudog(s *sudog) {
 
 // Temporary hack for gccgo until we port the garbage collector.
 func typeBitsBulkBarrier(typ *_type, p, size uintptr) {}
+
+// Here for gccgo until we port msize.go.
+func roundupsize(uintptr) uintptr
diff --git a/libgo/runtime/go-byte-array-to-string.c b/libgo/runtime/go-byte-array-to-string.c
deleted file mode 100644 (file)
index 088b786..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* go-byte-array-to-string.c -- convert an array of bytes to a string in Go.
-
-   Copyright 2009 The Go Authors. All rights reserved.
-   Use of this source code is governed by a BSD-style
-   license that can be found in the LICENSE file.  */
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-String
-__go_byte_array_to_string (const void* p, intgo len)
-{
-  const unsigned char *bytes;
-  unsigned char *retdata;
-  String ret;
-
-  bytes = (const unsigned char *) p;
-  retdata = runtime_mallocgc ((uintptr) len, 0, FlagNoScan);
-  __builtin_memcpy (retdata, bytes, len);
-  ret.str = retdata;
-  ret.len = len;
-  return ret;
-}
diff --git a/libgo/runtime/go-int-array-to-string.c b/libgo/runtime/go-int-array-to-string.c
deleted file mode 100644 (file)
index f372131..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/* go-int-array-to-string.c -- convert an array of ints to a string in Go.
-
-   Copyright 2009 The Go Authors. All rights reserved.
-   Use of this source code is governed by a BSD-style
-   license that can be found in the LICENSE file.  */
-
-#include "go-assert.h"
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-String
-__go_int_array_to_string (const void* p, intgo len)
-{
-  const int32 *ints;
-  intgo slen;
-  intgo i;
-  unsigned char *retdata;
-  String ret;
-  unsigned char *s;
-
-  ints = (const int32 *) p;
-
-  slen = 0;
-  for (i = 0; i < len; ++i)
-    {
-      int32 v;
-
-      v = ints[i];
-
-      if (v < 0 || v > 0x10ffff)
-       v = 0xfffd;
-      else if (0xd800 <= v && v <= 0xdfff)
-       v = 0xfffd;
-
-      if (v <= 0x7f)
-       slen += 1;
-      else if (v <= 0x7ff)
-       slen += 2;
-      else if (v <= 0xffff)
-       slen += 3;
-      else
-       slen += 4;
-    }
-
-  retdata = runtime_mallocgc ((uintptr) slen, 0, FlagNoScan);
-  ret.str = retdata;
-  ret.len = slen;
-
-  s = retdata;
-  for (i = 0; i < len; ++i)
-    {
-      int32 v;
-
-      v = ints[i];
-
-      /* If V is out of range for UTF-8, substitute the replacement
-        character.  */
-      if (v < 0 || v > 0x10ffff)
-       v = 0xfffd;
-      else if (0xd800 <= v && v <= 0xdfff)
-       v = 0xfffd;
-
-      if (v <= 0x7f)
-       *s++ = v;
-      else if (v <= 0x7ff)
-       {
-         *s++ = 0xc0 | ((v >> 6) & 0x1f);
-         *s++ = 0x80 | (v & 0x3f);
-       }
-      else if (v <= 0xffff)
-       {
-         *s++ = 0xe0 | ((v >> 12) & 0xf);
-         *s++ = 0x80 | ((v >> 6) & 0x3f);
-         *s++ = 0x80 | (v & 0x3f);
-       }
-      else
-       {
-         *s++ = 0xf0 | ((v >> 18) & 0x7);
-         *s++ = 0x80 | ((v >> 12) & 0x3f);
-         *s++ = 0x80 | ((v >> 6) & 0x3f);
-         *s++ = 0x80 | (v & 0x3f);
-       }
-    }
-
-  __go_assert (s - retdata == slen);
-
-  return ret;
-}
diff --git a/libgo/runtime/go-int-to-string.c b/libgo/runtime/go-int-to-string.c
deleted file mode 100644 (file)
index d90b1dd..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* go-int-to-string.c -- convert an integer to a string in Go.
-
-   Copyright 2009 The Go Authors. All rights reserved.
-   Use of this source code is governed by a BSD-style
-   license that can be found in the LICENSE file.  */
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-String
-__go_int_to_string (intgo v)
-{
-  char buf[4];
-  int len;
-  unsigned char *retdata;
-  String ret;
-
-  /* A negative value is not valid UTF-8; turn it into the replacement
-     character.  */
-  if (v < 0)
-    v = 0xfffd;
-
-  if (v <= 0x7f)
-    {
-      buf[0] = v;
-      len = 1;
-    }
-  else if (v <= 0x7ff)
-    {
-      buf[0] = 0xc0 + (v >> 6);
-      buf[1] = 0x80 + (v & 0x3f);
-      len = 2;
-    }
-  else
-    {
-      /* If the value is out of range for UTF-8, turn it into the
-        "replacement character".  */
-      if (v > 0x10ffff)
-       v = 0xfffd;
-      /* If the value is a surrogate pair, which is invalid in UTF-8,
-        turn it into the replacement character.  */
-      if (v >= 0xd800 && v < 0xe000)
-       v = 0xfffd;
-
-      if (v <= 0xffff)
-       {
-         buf[0] = 0xe0 + (v >> 12);
-         buf[1] = 0x80 + ((v >> 6) & 0x3f);
-         buf[2] = 0x80 + (v & 0x3f);
-         len = 3;
-       }
-      else
-       {
-         buf[0] = 0xf0 + (v >> 18);
-         buf[1] = 0x80 + ((v >> 12) & 0x3f);
-         buf[2] = 0x80 + ((v >> 6) & 0x3f);
-         buf[3] = 0x80 + (v & 0x3f);
-         len = 4;
-       }
-    }
-
-  retdata = runtime_mallocgc (len, 0, FlagNoScan);
-  __builtin_memcpy (retdata, buf, len);
-  ret.str = retdata;
-  ret.len = len;
-
-  return ret;
-}
diff --git a/libgo/runtime/go-rune.c b/libgo/runtime/go-rune.c
deleted file mode 100644 (file)
index 4c65e21..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/* go-rune.c -- rune functions for Go.
-
-   Copyright 2009, 2010 The Go Authors. All rights reserved.
-   Use of this source code is governed by a BSD-style
-   license that can be found in the LICENSE file.  */
-
-#include <stddef.h>
-
-#include "runtime.h"
-#include "go-string.h"
-
-/* Get a character from the UTF-8 string STR, of length LEN.  Store
-   the Unicode character, if any, in *RUNE.  Return the number of
-   characters used from STR.  */
-
-int
-__go_get_rune (const unsigned char *str, size_t len, int32 *rune)
-{
-  int c, c1, c2, c3, l;
-
-  /* Default to the "replacement character".  */
-  *rune = 0xfffd;
-
-  if (len <= 0)
-    return 1;
-
-  c = *str;
-  if (c <= 0x7f)
-    {
-      *rune = c;
-      return 1;
-    }
-
-  if (len <= 1)
-    return 1;
-
-  c1 = str[1];
-  if ((c & 0xe0) == 0xc0
-      && (c1 & 0xc0) == 0x80)
-    {
-      l = (((c & 0x1f) << 6) + (c1 & 0x3f));
-      if (l <= 0x7f)
-       return 1;
-      *rune = l;
-      return 2;
-    }
-
-  if (len <= 2)
-    return 1;
-
-  c2 = str[2];
-  if ((c & 0xf0) == 0xe0
-      && (c1 & 0xc0) == 0x80
-      && (c2 & 0xc0) == 0x80)
-    {
-      l = (((c & 0xf) << 12)
-          + ((c1 & 0x3f) << 6)
-          + (c2 & 0x3f));
-
-      if (l <= 0x7ff)
-       return 1;
-
-      if (l >= 0xd800 && l < 0xe000)
-       {
-         /* Invalid surrogate half; return replace character.  */
-         return 1;
-       }
-
-      *rune = l;
-
-      return 3;
-    }
-
-  if (len <= 3)
-    return 1;
-
-  c3 = str[3];
-  if ((c & 0xf8) == 0xf0
-      && (c1 & 0xc0) == 0x80
-      && (c2 & 0xc0) == 0x80
-      && (c3 & 0xc0) == 0x80)
-    {
-      l = (((c & 0x7) << 18)
-          + ((c1 & 0x3f) << 12)
-          + ((c2 & 0x3f) << 6)
-          + (c3 & 0x3f));
-
-      if (l <= 0xffff || l > 0x10ffff)
-       return 1;
-
-      *rune = l;
-      return 4;
-    }
-
-  /* Invalid encoding.  Return 1 so that we advance.  */
-  return 1;
-}
diff --git a/libgo/runtime/go-string-to-byte-array.c b/libgo/runtime/go-string-to-byte-array.c
deleted file mode 100644 (file)
index 61591eb..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* go-string-to-byte-array.c -- convert a string to an array of bytes in Go.
-
-   Copyright 2010 The Go Authors. All rights reserved.
-   Use of this source code is governed by a BSD-style
-   license that can be found in the LICENSE file.  */
-
-#include "runtime.h"
-#include "array.h"
-#include "arch.h"
-#include "malloc.h"
-
-struct __go_open_array
-__go_string_to_byte_array (String str)
-{
-  uintptr cap;
-  unsigned char *data;
-  struct __go_open_array ret;
-
-  cap = runtime_roundupsize (str.len);
-  data = (unsigned char *) runtime_mallocgc (cap, 0, FlagNoScan | FlagNoZero);
-  __builtin_memcpy (data, str.str, str.len);
-  if (cap != (uintptr) str.len)
-    __builtin_memset (data + str.len, 0, cap - (uintptr) str.len);
-  ret.__values = (void *) data;
-  ret.__count = str.len;
-  ret.__capacity = str.len;
-  return ret;
-}
diff --git a/libgo/runtime/go-string-to-int-array.c b/libgo/runtime/go-string-to-int-array.c
deleted file mode 100644 (file)
index 5546889..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* go-string-to-int-array.c -- convert a string to an array of ints in Go.
-
-   Copyright 2010 The Go Authors. All rights reserved.
-   Use of this source code is governed by a BSD-style
-   license that can be found in the LICENSE file.  */
-
-#include "runtime.h"
-#include "go-alloc.h"
-#include "go-string.h"
-#include "array.h"
-#include "arch.h"
-#include "malloc.h"
-
-struct __go_open_array
-__go_string_to_int_array (String str)
-{
-  size_t c;
-  const unsigned char *p;
-  const unsigned char *pend;
-  uintptr mem;
-  uint32_t *data;
-  uint32_t *pd;
-  struct __go_open_array ret;
-
-  c = 0;
-  p = str.str;
-  pend = p + str.len;
-  while (p < pend)
-    {
-      int rune;
-
-      ++c;
-      p += __go_get_rune (p, pend - p, &rune);
-    }
-
-  if (c > MaxMem / sizeof (uint32_t))
-    runtime_throw ("out of memory");
-
-  mem = runtime_roundupsize (c * sizeof (uint32_t));
-  data = (uint32_t *) runtime_mallocgc (mem, 0, FlagNoScan | FlagNoZero);
-  p = str.str;
-  pd = data;
-  while (p < pend)
-    {
-      int rune;
-
-      p += __go_get_rune (p, pend - p, &rune);
-      *pd++ = rune;
-    }
-  if (mem > (uintptr) c * sizeof (uint32_t))
-    __builtin_memset (data + c, 0, mem - (uintptr) c * sizeof (uint32_t));
-  ret.__values = (void *) data;
-  ret.__count = c;
-  ret.__capacity = (intgo) (mem / sizeof (uint32_t));
-  return ret;
-}
diff --git a/libgo/runtime/go-strplus.c b/libgo/runtime/go-strplus.c
deleted file mode 100644 (file)
index 13915e3..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* go-strplus.c -- the go string append function.
-
-   Copyright 2009 The Go Authors. All rights reserved.
-   Use of this source code is governed by a BSD-style
-   license that can be found in the LICENSE file.  */
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-String
-__go_string_plus (String s1, String s2)
-{
-  int len;
-  byte *retdata;
-  String ret;
-
-  if (s1.len == 0)
-    return s2;
-  else if (s2.len == 0)
-    return s1;
-
-  len = s1.len + s2.len;
-  retdata = runtime_mallocgc (len, 0, FlagNoScan | FlagNoZero);
-  __builtin_memcpy (retdata, s1.str, s1.len);
-  __builtin_memcpy (retdata + s1.len, s2.str, s2.len);
-  ret.str = retdata;
-  ret.len = len;
-  return ret;
-}
index 1efbbbeb1021e493c962840d7bf1fdd4d3756462..b2dbf900c01b6f4852e346e5c306977e5948a204 100644 (file)
@@ -285,7 +285,8 @@ void        runtime_updatememstats(GCStats *stats);
 //     making new objects in class i
 
 int32  runtime_SizeToClass(int32);
-uintptr        runtime_roundupsize(uintptr);
+uintptr        runtime_roundupsize(uintptr)
+  __asm__(GOSYM_PREFIX "runtime.roundupsize");
 extern int32   runtime_class_to_size[_NumSizeClasses];
 extern int32   runtime_class_to_allocnpages[_NumSizeClasses];
 extern int8    runtime_size_to_class8[1024/8 + 1];
index ac6e396de55716a6fcfc6e805027be594d54bd66..00448215c917ce06c3e0873811fbf33a0633891e 100644 (file)
@@ -2216,7 +2216,7 @@ static void
 gc(struct gc_args *args)
 {
        M *m;
-       int64 t0, t1, t2, t3, t4;
+       int64 tm0, tm1, tm2, tm3, tm4;
        uint64 heap0, heap1, obj, ninstr;
        GCStats stats;
        uint32 i;
@@ -2228,7 +2228,7 @@ gc(struct gc_args *args)
                runtime_tracegc();
 
        m->traceback = 2;
-       t0 = args->start_time;
+       tm0 = args->start_time;
        work.tstart = args->start_time; 
 
        if(CollectStats)
@@ -2239,9 +2239,9 @@ gc(struct gc_args *args)
                work.markfor = runtime_parforalloc(MaxGcproc);
        m->locks--;
 
-       t1 = 0;
+       tm1 = 0;
        if(runtime_debug.gctrace)
-               t1 = runtime_nanotime();
+               tm1 = runtime_nanotime();
 
        // Sweep what is not sweeped by bgsweep.
        while(runtime_sweepone() != (uintptr)-1)
@@ -2256,17 +2256,17 @@ gc(struct gc_args *args)
                runtime_helpgc(work.nproc);
        }
 
-       t2 = 0;
+       tm2 = 0;
        if(runtime_debug.gctrace)
-               t2 = runtime_nanotime();
+               tm2 = runtime_nanotime();
 
        gchelperstart();
        runtime_parfordo(work.markfor);
        scanblock(nil, true);
 
-       t3 = 0;
+       tm3 = 0;
        if(runtime_debug.gctrace)
-               t3 = runtime_nanotime();
+               tm3 = runtime_nanotime();
 
        bufferList[m->helpgc].busy = 0;
        if(work.nproc > 1)
@@ -2280,14 +2280,14 @@ gc(struct gc_args *args)
        // concurrent/lazy sweep will reduce this number while discovering new garbage
        mstats.next_gc = mstats.heap_alloc+(mstats.heap_alloc-runtime_stacks_sys)*gcpercent/100;
 
-       t4 = runtime_nanotime();
+       tm4 = runtime_nanotime();
        mstats.last_gc = runtime_unixnanotime();  // must be Unix time to make sense to user
-       mstats.pause_ns[mstats.numgc%nelem(mstats.pause_ns)] = t4 - t0;
+       mstats.pause_ns[mstats.numgc%nelem(mstats.pause_ns)] = tm4 - tm0;
        mstats.pause_end[mstats.numgc%nelem(mstats.pause_end)] = mstats.last_gc;
-       mstats.pause_total_ns += t4 - t0;
+       mstats.pause_total_ns += tm4 - tm0;
        mstats.numgc++;
        if(mstats.debuggc)
-               runtime_printf("pause %D\n", t4-t0);
+               runtime_printf("pause %D\n", tm4-tm0);
 
        if(runtime_debug.gctrace) {
                heap1 = mstats.heap_alloc;
@@ -2305,7 +2305,7 @@ gc(struct gc_args *args)
                runtime_printf("gc%d(%d): %D+%D+%D+%D us, %D -> %D MB, %D (%D-%D) objects,"
                                " %d/%d/%d sweeps,"
                                " %D(%D) handoff, %D(%D) steal, %D/%D/%D yields\n",
-                       mstats.numgc, work.nproc, (t1-t0)/1000, (t2-t1)/1000, (t3-t2)/1000, (t4-t3)/1000,
+                       mstats.numgc, work.nproc, (tm1-tm0)/1000, (tm2-tm1)/1000, (tm3-tm2)/1000, (tm4-tm3)/1000,
                        heap0>>20, heap1>>20, obj,
                        mstats.nmalloc, mstats.nfree,
                        sweep.nspan, gcstats.nbgsweep, gcstats.npausesweep,
index 69d2f5a7b2f6153021136371489bb808bc1fea64..8c12265447dc361706222f9d2064ddd589736563 100644 (file)
@@ -307,8 +307,8 @@ extern      bool    runtime_isarchive;
 #define runtime_strcmp(s1, s2) __builtin_strcmp((s1), (s2))
 #define runtime_strncmp(s1, s2, n) __builtin_strncmp((s1), (s2), (n))
 #define runtime_strstr(s1, s2) __builtin_strstr((s1), (s2))
-intgo  runtime_findnull(const byte*);
-intgo  runtime_findnullw(const uint16*);
+intgo  runtime_findnull(const byte*)
+  __asm__ (GOSYM_PREFIX "runtime.findnull");
 
 void   runtime_gogo(G*);
 struct __go_func_type;
@@ -328,8 +328,8 @@ int32       runtime_snprintf(byte*, int32, const char*, ...);
 #define runtime_mcmp(a, b, s) __builtin_memcmp((a), (b), (s))
 #define runtime_memmove(a, b, s) __builtin_memmove((a), (b), (s))
 void*  runtime_mal(uintptr);
-String runtime_gostring(const byte*);
-String runtime_gostringnocopy(const byte*);
+String runtime_gostringnocopy(const byte*)
+  __asm__ (GOSYM_PREFIX "runtime.gostringnocopy");
 void   runtime_schedinit(void);
 void   runtime_initsig(bool);
 void   runtime_sigenable(uint32 sig);
diff --git a/libgo/runtime/string.goc b/libgo/runtime/string.goc
deleted file mode 100644 (file)
index 0ad180b..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2009, 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-#include "go-string.h"
-
-#define charntorune(pv, str, len) __go_get_rune(str, len, pv)
-
-const String   runtime_emptystring;
-
-intgo
-runtime_findnull(const byte *s)
-{
-       if(s == nil)
-               return 0;
-       return __builtin_strlen((const char*) s);
-}
-
-intgo
-runtime_findnullw(const uint16 *s)
-{
-       intgo l;
-
-       if(s == nil)
-               return 0;
-       for(l=0; s[l]!=0; l++)
-               ;
-       return l;
-}
-
-static String
-gostringsize(intgo l, byte** pmem)
-{
-       String s;
-       byte *mem;
-
-       if(l == 0) {
-               *pmem = nil;
-               return runtime_emptystring;
-       }
-       mem = runtime_mallocgc(l, 0, FlagNoScan|FlagNoZero);
-       s.str = mem;
-       s.len = l;
-       *pmem = mem;
-       return s;
-}
-
-String
-runtime_gostring(const byte *str)
-{
-       intgo l;
-       String s;
-       byte *mem;
-
-       l = runtime_findnull(str);
-       s = gostringsize(l, &mem);
-       runtime_memmove(mem, str, l);
-       return s;
-}
-
-String
-runtime_gostringnocopy(const byte *str)
-{
-       String s;
-       
-       s.str = str;
-       s.len = runtime_findnull(str);
-       return s;
-}
-
-func cstringToGo(str *byte) (s String) {
-       s = runtime_gostringnocopy(str);
-}
-
-enum
-{
-       Runeself        = 0x80,
-};
-
-func stringiter(s String, k int) (retk int) {
-       int32 l;
-
-       if(k >= s.len) {
-               // retk=0 is end of iteration
-               retk = 0;
-               goto out;
-       }
-
-       l = s.str[k];
-       if(l < Runeself) {
-               retk = k+1;
-               goto out;
-       }
-
-       // multi-char rune
-       retk = k + charntorune(&l, s.str+k, s.len-k);
-
-out:
-}
-
-func stringiter2(s String, k int) (retk int, retv int32) {
-       if(k >= s.len) {
-               // retk=0 is end of iteration
-               retk = 0;
-               retv = 0;
-               goto out;
-       }
-
-       retv = s.str[k];
-       if(retv < Runeself) {
-               retk = k+1;
-               goto out;
-       }
-
-       // multi-char rune
-       retk = k + charntorune(&retv, s.str+k, s.len-k);
-
-out:
-}