Commit 9ad091e1 authored by Rob Pike's avatar Rob Pike

gob: eliminate two more allocations in decode.

- just an oversight; we were reallocating a buffer.
- use unsafe to avoid allocating storage for a string twice.

R=rsc
CC=golang-dev
https://golang.org/cl/4290056
parent 2ca46a78
...@@ -41,11 +41,11 @@ func (dec *Decoder) newDecoderState(buf *bytes.Buffer) *decoderState { ...@@ -41,11 +41,11 @@ func (dec *Decoder) newDecoderState(buf *bytes.Buffer) *decoderState {
if d == nil { if d == nil {
d = new(decoderState) d = new(decoderState)
d.dec = dec d.dec = dec
d.buf = make([]byte, uint64Size)
} else { } else {
dec.freeList = d.next dec.freeList = d.next
} }
d.b = buf d.b = buf
d.buf = make([]byte, uint64Size)
return d return d
} }
...@@ -412,7 +412,14 @@ func decString(i *decInstr, state *decoderState, p unsafe.Pointer) { ...@@ -412,7 +412,14 @@ func decString(i *decInstr, state *decoderState, p unsafe.Pointer) {
} }
b := make([]byte, state.decodeUint()) b := make([]byte, state.decodeUint())
state.b.Read(b) state.b.Read(b)
*(*string)(p) = string(b) // It would be a shame to do the obvious thing here,
// *(*string)(p) = string(b)
// because we've already allocated the storage and this would
// allocate again and copy. So we do this ugly hack, which is even
// even more unsafe than it looks as it depends the memory
// representation of a string matching the beginning of the memory
// representation of a byte slice (a byte slice is longer).
*(*string)(p) = *(*string)(unsafe.Pointer(&b))
} }
// ignoreUint8Array skips over the data for a byte slice value with no destination. // ignoreUint8Array skips over the data for a byte slice value with no destination.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment