From dc444418d919b72f7744a521cc898252f3f355df Mon Sep 17 00:00:00 2001 From: Todd Neal Date: Mon, 17 Apr 2017 18:46:09 -0500 Subject: [PATCH] cmd/internal: remove duplicate pathToPrefix function goobj.importPathToPrefix is 3x faster than gc.pathToPrefix so rename and move it to cmd/internal/objabi which is already imported by both goobj and gc. Change-Id: I10eda5bce95ef6d5d888818c5c47258c2833ea45 Reviewed-on: https://go-review.googlesource.com/40875 Run-TryBot: Todd Neal TryBot-Result: Gobot Gobot Reviewed-by: Matthew Dempsky --- src/cmd/compile/fmt_test.go | 1 - src/cmd/compile/internal/gc/subr.go | 30 +------------------- src/cmd/internal/goobj/read.go | 41 +--------------------------- src/cmd/internal/goobj/read_test.go | 28 ------------------- src/cmd/internal/objabi/path.go | 41 ++++++++++++++++++++++++++++ src/cmd/internal/objabi/path_test.go | 33 ++++++++++++++++++++++ src/cmd/link/internal/ld/data.go | 2 +- src/cmd/link/internal/ld/lib.go | 35 ++---------------------- src/cmd/link/internal/ld/objfile.go | 8 +++--- 9 files changed, 84 insertions(+), 135 deletions(-) delete mode 100644 src/cmd/internal/goobj/read_test.go create mode 100644 src/cmd/internal/objabi/path.go create mode 100644 src/cmd/internal/objabi/path_test.go diff --git a/src/cmd/compile/fmt_test.go b/src/cmd/compile/fmt_test.go index a36c625bdb..5163bee0e6 100644 --- a/src/cmd/compile/fmt_test.go +++ b/src/cmd/compile/fmt_test.go @@ -606,7 +606,6 @@ var knownFormats = map[string]string{ "[]cmd/compile/internal/ssa.ID %v": "", "[]string %v": "", "bool %v": "", - "byte %02x": "", "byte %08b": "", "byte %c": "", "cmd/compile/internal/arm.shift %d": "", diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go index cda650b055..f840c470fb 100644 --- a/src/cmd/compile/internal/gc/subr.go +++ b/src/cmd/compile/internal/gc/subr.go @@ -5,7 +5,6 @@ package gc import ( - "bytes" "cmd/compile/internal/types" "cmd/internal/objabi" "cmd/internal/src" @@ -1958,33 +1957,6 @@ func ngotype(n *Node) *types.Sym { return nil } -// Convert raw string to the prefix that will be used in the symbol -// table. All control characters, space, '%' and '"', as well as -// non-7-bit clean bytes turn into %xx. The period needs escaping -// only in the last segment of the path, and it makes for happier -// users if we escape that as little as possible. -// -// If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too. -func pathtoprefix(s string) string { - slash := strings.LastIndex(s, "/") - for i := 0; i < len(s); i++ { - c := s[i] - if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { - var buf bytes.Buffer - for i := 0; i < len(s); i++ { - c := s[i] - if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { - fmt.Fprintf(&buf, "%%%02x", c) - continue - } - buf.WriteByte(c) - } - return buf.String() - } - } - return s -} - var pkgMap = make(map[string]*types.Pkg) var pkgs []*types.Pkg @@ -1995,7 +1967,7 @@ func mkpkg(path string) *types.Pkg { p := new(types.Pkg) p.Path = path - p.Prefix = pathtoprefix(path) + p.Prefix = objabi.PathToPrefix(path) p.Syms = make(map[string]*types.Sym) pkgMap[path] = p pkgs = append(pkgs, p) diff --git a/src/cmd/internal/goobj/read.go b/src/cmd/internal/goobj/read.go index 5ed1a4163c..b68fe02eb3 100644 --- a/src/cmd/internal/goobj/read.go +++ b/src/cmd/internal/goobj/read.go @@ -159,45 +159,6 @@ type objReader struct { pkgprefix string } -// importPathToPrefix returns the prefix that will be used in the -// final symbol table for the given import path. -// We escape '%', '"', all control characters and non-ASCII bytes, -// and any '.' after the final slash. -// -// See ../../../cmd/ld/lib.c:/^pathtoprefix and -// ../../../cmd/gc/subr.c:/^pathtoprefix. -func importPathToPrefix(s string) string { - // find index of last slash, if any, or else -1. - // used for determining whether an index is after the last slash. - slash := strings.LastIndex(s, "/") - - // check for chars that need escaping - n := 0 - for r := 0; r < len(s); r++ { - if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F { - n++ - } - } - - // quick exit - if n == 0 { - return s - } - - // escape - const hex = "0123456789abcdef" - p := make([]byte, 0, len(s)+2*n) - for r := 0; r < len(s); r++ { - if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F { - p = append(p, '%', hex[c>>4], hex[c&0xF]) - } else { - p = append(p, c) - } - } - - return string(p) -} - // init initializes r to read package p from f. func (r *objReader) init(f io.ReadSeeker, p *Package) { r.f = f @@ -206,7 +167,7 @@ func (r *objReader) init(f io.ReadSeeker, p *Package) { r.limit, _ = f.Seek(0, io.SeekEnd) f.Seek(r.offset, io.SeekStart) r.b = bufio.NewReader(f) - r.pkgprefix = importPathToPrefix(p.ImportPath) + "." + r.pkgprefix = objabi.PathToPrefix(p.ImportPath) + "." } // error records that an error occurred. diff --git a/src/cmd/internal/goobj/read_test.go b/src/cmd/internal/goobj/read_test.go deleted file mode 100644 index ff165e842d..0000000000 --- a/src/cmd/internal/goobj/read_test.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2013 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 goobj - -import "testing" - -var importPathToPrefixTests = []struct { - in string - out string -}{ - {"runtime", "runtime"}, - {"sync/atomic", "sync/atomic"}, - {"golang.org/x/tools/godoc", "golang.org/x/tools/godoc"}, - {"foo.bar/baz.quux", "foo.bar/baz%2equux"}, - {"", ""}, - {"%foo%bar", "%25foo%25bar"}, - {"\x01\x00\x7F☺", "%01%00%7f%e2%98%ba"}, -} - -func TestImportPathToPrefix(t *testing.T) { - for _, tt := range importPathToPrefixTests { - if out := importPathToPrefix(tt.in); out != tt.out { - t.Errorf("importPathToPrefix(%q) = %q, want %q", tt.in, out, tt.out) - } - } -} diff --git a/src/cmd/internal/objabi/path.go b/src/cmd/internal/objabi/path.go new file mode 100644 index 0000000000..2a42179a36 --- /dev/null +++ b/src/cmd/internal/objabi/path.go @@ -0,0 +1,41 @@ +// Copyright 2017 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 objabi + +import "strings" + +// PathToPrefix converts raw string to the prefix that will be used in the +// symbol table. All control characters, space, '%' and '"', as well as +// non-7-bit clean bytes turn into %xx. The period needs escaping only in the +// last segment of the path, and it makes for happier users if we escape that as +// little as possible. +func PathToPrefix(s string) string { + slash := strings.LastIndex(s, "/") + // check for chars that need escaping + n := 0 + for r := 0; r < len(s); r++ { + if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F { + n++ + } + } + + // quick exit + if n == 0 { + return s + } + + // escape + const hex = "0123456789abcdef" + p := make([]byte, 0, len(s)+2*n) + for r := 0; r < len(s); r++ { + if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F { + p = append(p, '%', hex[c>>4], hex[c&0xF]) + } else { + p = append(p, c) + } + } + + return string(p) +} diff --git a/src/cmd/internal/objabi/path_test.go b/src/cmd/internal/objabi/path_test.go new file mode 100644 index 0000000000..05d7fb436e --- /dev/null +++ b/src/cmd/internal/objabi/path_test.go @@ -0,0 +1,33 @@ +// Copyright 2017 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 objabi + +import "testing" + +func TestPathToPrefix(t *testing.T) { + tests := []struct { + Path string + Expected string + }{{"foo/bar/v1", "foo/bar/v1"}, + {"foo/bar/v.1", "foo/bar/v%2e1"}, + {"f.o.o/b.a.r/v1", "f.o.o/b.a.r/v1"}, + {"f.o.o/b.a.r/v.1", "f.o.o/b.a.r/v%2e1"}, + {"f.o.o/b.a.r/v..1", "f.o.o/b.a.r/v%2e%2e1"}, + {"f.o.o/b.a.r/v..1.", "f.o.o/b.a.r/v%2e%2e1%2e"}, + {"f.o.o/b.a.r/v%1", "f.o.o/b.a.r/v%251"}, + {"runtime", "runtime"}, + {"sync/atomic", "sync/atomic"}, + {"golang.org/x/tools/godoc", "golang.org/x/tools/godoc"}, + {"foo.bar/baz.quux", "foo.bar/baz%2equux"}, + {"", ""}, + {"%foo%bar", "%25foo%25bar"}, + {"\x01\x00\x7F☺", "%01%00%7f%e2%98%ba"}, + } + for _, tc := range tests { + if got := PathToPrefix(tc.Path); got != tc.Expected { + t.Errorf("expected PathToPrefix(%s) = %s, got %s", tc.Path, tc.Expected, got) + } + } +} diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index f75614f006..45a968e40f 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -1059,7 +1059,7 @@ func addstrdata1(ctxt *Link, arg string) { if eq < 0 || dot < 0 { Exitf("-X flag requires argument of the form importpath.name=value") } - addstrdata(ctxt, pathtoprefix(arg[:dot])+arg[dot:eq], arg[eq+1:]) + addstrdata(ctxt, objabi.PathToPrefix(arg[:dot])+arg[dot:eq], arg[eq+1:]) } func addstrdata(ctxt *Link, name string, value string) { diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 303d0b9304..5bb9c05382 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -651,7 +651,7 @@ func (ctxt *Link) loadlib() { // first containing package that the linker loads). canonicalize // it here to the package with which it will be laid down // in text. - s.File = pathtoprefix(lib.Pkg) + s.File = objabi.PathToPrefix(lib.Pkg) } } } @@ -752,7 +752,7 @@ func genhash(ctxt *Link, lib *Library) { } func objfile(ctxt *Link, lib *Library) { - pkg := pathtoprefix(lib.Pkg) + pkg := objabi.PathToPrefix(lib.Pkg) if ctxt.Debugvlog > 1 { ctxt.Logf("%5.2f ldobj: %s (%s)\n", Cputime(), lib.File, pkg) @@ -1312,7 +1312,7 @@ func hostlinkArchArgs() []string { // compiled by a non-Go compiler) it returns the Hostobj pointer. If // it is a Go object, it returns nil. func ldobj(ctxt *Link, f *bio.Reader, lib *Library, length int64, pn string, file string, whence int) *Hostobj { - pkg := pathtoprefix(lib.Pkg) + pkg := objabi.PathToPrefix(lib.Pkg) eof := f.Offset() + length start := f.Offset() @@ -1572,35 +1572,6 @@ func ldshlibsyms(ctxt *Link, shlib string) { ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdataAddresses: gcdataAddresses}) } -// Copied from ../gc/subr.c:/^pathtoprefix; must stay in sync. -/* - * Convert raw string to the prefix that will be used in the symbol table. - * Invalid bytes turn into %xx. Right now the only bytes that need - * escaping are %, ., and ", but we escape all control characters too. - * - * If you edit this, edit ../gc/subr.c:/^pathtoprefix too. - * If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too. - */ -func pathtoprefix(s string) string { - slash := strings.LastIndex(s, "/") - for i := 0; i < len(s); i++ { - c := s[i] - if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { - var buf bytes.Buffer - for i := 0; i < len(s); i++ { - c := s[i] - if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { - fmt.Fprintf(&buf, "%%%02x", c) - continue - } - buf.WriteByte(c) - } - return buf.String() - } - } - return s -} - func addsection(seg *Segment, name string, rwx int) *Section { sect := new(Section) sect.Rwx = uint8(rwx) diff --git a/src/cmd/link/internal/ld/objfile.go b/src/cmd/link/internal/ld/objfile.go index d543b12b2b..a78ca0606d 100644 --- a/src/cmd/link/internal/ld/objfile.go +++ b/src/cmd/link/internal/ld/objfile.go @@ -68,7 +68,7 @@ func LoadObjFile(ctxt *Link, f *bio.Reader, lib *Library, length int64, pn strin } func (r *objReader) loadObjFile() { - pkg := pathtoprefix(r.lib.Pkg) + pkg := objabi.PathToPrefix(r.lib.Pkg) // Magic header var buf [8]uint8 @@ -168,7 +168,7 @@ func (r *objReader) readSym() { typ := r.readSymIndex() data := r.readData() nreloc := r.readInt() - pkg := pathtoprefix(r.lib.Pkg) + pkg := objabi.PathToPrefix(r.lib.Pkg) isdup := false var dup *Symbol @@ -345,7 +345,7 @@ func (r *objReader) patchDWARFName(s *Symbol) { if p == -1 { return } - pkgprefix := []byte(pathtoprefix(r.lib.Pkg) + ".") + pkgprefix := []byte(objabi.PathToPrefix(r.lib.Pkg) + ".") patched := bytes.Replace(s.P[:e], emptyPkg, pkgprefix, -1) s.P = append(patched, s.P[e:]...) @@ -478,7 +478,7 @@ func (r *objReader) readData() []byte { // readSymName reads a symbol name, replacing all "". with pkg. func (r *objReader) readSymName() string { - pkg := pathtoprefix(r.lib.Pkg) + pkg := objabi.PathToPrefix(r.lib.Pkg) n := r.readInt() if n == 0 { r.readInt64() -- 2.48.1