@@ -29,11 +29,20 @@ import "C"
2929import (
3030 "bytes"
3131 "io"
32+ "sync"
3233 "unsafe"
3334)
3435
3536var newlineSep = []byte ("\n " )
3637
38+ var cstrPool = sync.Pool {
39+ New : func () any {
40+ // 1024: github.com/golang/mobile/blob/2553ed8ce2/internal/mobileinit/mobileinit_android.go#L52
41+ b := make ([]byte , 0 , 1024 )
42+ return & b
43+ },
44+ }
45+
3746// ctag is the logcat tag used for all log output.
3847var ctag = C .CString ("Firestack" )
3948
@@ -59,18 +68,31 @@ func NewAndroidConsole() Console {
5968
6069// Log implements Console.
6170func (a * xlog ) Log (level LogLevel , msg Logmsg ) {
62- cstr := C .CString ((string )(msg ))
63- C .__android_log_write (androidPriority (level ), ctag , cstr )
64- C .free (unsafe .Pointer (cstr ))
71+ if len (msg ) <= 0 {
72+ return
73+ }
74+
75+ ptr , _ := cstrPool .Get ().(* []byte )
76+ buf := * ptr
77+ buf = buf [:cap (buf )]
78+
79+ // trunc buf to n or n+1: go.dev/play/p/LlNycbtMsF0
80+ n := copy (buf , msg )
81+ term := min (n , len (buf )- 1 )
82+ buf [term ] = 0 // null terminator
83+ buf = buf [:term + 1 ]
84+
85+ C .__android_log_write (androidPriority (level ), ctag , (* C .char )(unsafe .Pointer (& buf [0 ])))
86+
87+ * ptr = buf [:0 ]
88+ cstrPool .Put (ptr )
6589}
6690
6791func (a * xlog ) Write (p []byte ) (n int , err error ) {
6892 p = bytes .TrimRight (p , "\n \r " )
6993 for line := range bytes .SplitSeq (p , newlineSep ) {
7094 lvl , msg := splitmsg (line )
71- if len (msg ) > 0 {
72- a .Log (lvl , msg )
73- }
95+ a .Log (lvl , msg )
7496 }
7597 return len (p ), nil
7698}
0 commit comments