unicode/norm: move sync.Once check out of loop

Follow-up to CL 127926.

The recompMap map is only used by func combine, which only has one
caller. Move the sync.Once.Do call that populates the map out of func
combine up to its sole caller.

I wasn't actually able to measure a difference with this, but
it seems better to do one-time work outside of a loop.

And I verified that combine is still inlined, even with the nil check+panic.

./composition.go:501:24: inlining call to combine

Change-Id: I6929af1de5f068051ef00cf0938b880ff87e1ce4
Reviewed-on: https://go-review.googlesource.com/128575
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Kevin Burke <kev@inburke.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/unicode/norm/composition.go b/unicode/norm/composition.go
index 9f37ef0..e2087bc 100644
--- a/unicode/norm/composition.go
+++ b/unicode/norm/composition.go
@@ -461,6 +461,10 @@
 // It should only be used to recompose a single segment, as it will not
 // handle alternations between Hangul and non-Hangul characters correctly.
 func (rb *reorderBuffer) compose() {
+	// Lazily load the map used by the combine func below, but do
+	// it outside of the loop.
+	recompMapOnce.Do(buildRecompMap)
+
 	// UAX #15, section X5 , including Corrigendum #5
 	// "In any character sequence beginning with starter S, a character C is
 	//  blocked from S if and only if there is some character B between S
diff --git a/unicode/norm/forminfo.go b/unicode/norm/forminfo.go
index f7fbf86..526c703 100644
--- a/unicode/norm/forminfo.go
+++ b/unicode/norm/forminfo.go
@@ -199,9 +199,14 @@
 // Note that the recomposition map for NFC and NFKC are identical.
 
 // combine returns the combined rune or 0 if it doesn't exist.
+//
+// The caller is responsible for calling
+// recompMapOnce.Do(buildRecompMap) sometime before this is called.
 func combine(a, b rune) rune {
 	key := uint32(uint16(a))<<16 + uint32(uint16(b))
-	recompMapOnce.Do(buildRecompMap)
+	if recompMap == nil {
+		panic("caller error") // see func comment
+	}
 	return recompMap[key]
 }