Commit b1e64585 authored by Rob Pike's avatar Rob Pike

move dereference code out of the ops and into the interpreter loops.

R=rsc
DELTA=574  (40 added, 149 deleted, 385 changed)
OCL=31017
CL=31019
parent c701af8c
This diff is collapsed.
......@@ -4,6 +4,9 @@
package gob
// TODO(rsc): When garbage collector changes, revisit
// the allocations in this file that use unsafe.Pointer.
import (
"gob";
"io";
......@@ -57,9 +60,12 @@ func DecodeInt(state *DecState) int64 {
return int64(x >> 1)
}
type decInstr struct
type decOp func(i *decInstr, state *DecState, p unsafe.Pointer);
// The 'instructions' of the decoding machine
type decInstr struct {
op func(i *decInstr, state *DecState);
op decOp;
field int; // field number
indir int; // how many pointer indirections to reach the value in the struct
offset uintptr; // offset in the structure of the field to encode
......@@ -84,14 +90,10 @@ func decIndirect(p unsafe.Pointer, indir int) unsafe.Pointer {
return p
}
func decBool(i *decInstr, state *DecState) {
p := unsafe.Pointer(state.base+i.offset);
func decBool(i *decInstr, state *DecState, p unsafe.Pointer) {
if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int));
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(bool));
p = *(*unsafe.Pointer)(p);
}
}
......@@ -101,12 +103,8 @@ func decBool(i *decInstr, state *DecState) {
}
}
func decInt(i *decInstr, state *DecState) {
p := unsafe.Pointer(state.base+i.offset);
func decInt(i *decInstr, state *DecState, p unsafe.Pointer) {
if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int));
p = *(*unsafe.Pointer)(p);
......@@ -118,14 +116,10 @@ func decInt(i *decInstr, state *DecState) {
}
}
func decUint(i *decInstr, state *DecState) {
p := unsafe.Pointer(state.base+i.offset);
func decUint(i *decInstr, state *DecState, p unsafe.Pointer) {
if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int));
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(uint));
p = *(*unsafe.Pointer)(p);
}
}
......@@ -135,14 +129,10 @@ func decUint(i *decInstr, state *DecState) {
}
}
func decInt8(i *decInstr, state *DecState) {
p := unsafe.Pointer(state.base+i.offset);
func decInt8(i *decInstr, state *DecState, p unsafe.Pointer) {
if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int));
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int8));
p = *(*unsafe.Pointer)(p);
}
}
......@@ -152,14 +142,10 @@ func decInt8(i *decInstr, state *DecState) {
}
}
func decUint8(i *decInstr, state *DecState) {
p := unsafe.Pointer(state.base+i.offset);
func decUint8(i *decInstr, state *DecState, p unsafe.Pointer) {
if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int));
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(uint8));
p = *(*unsafe.Pointer)(p);
}
}
......@@ -169,14 +155,10 @@ func decUint8(i *decInstr, state *DecState) {
}
}
func decInt16(i *decInstr, state *DecState) {
p := unsafe.Pointer(state.base+i.offset);
func decInt16(i *decInstr, state *DecState, p unsafe.Pointer) {
if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int));
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int16));
p = *(*unsafe.Pointer)(p);
}
}
......@@ -186,14 +168,10 @@ func decInt16(i *decInstr, state *DecState) {
}
}
func decUint16(i *decInstr, state *DecState) {
p := unsafe.Pointer(state.base+i.offset);
func decUint16(i *decInstr, state *DecState, p unsafe.Pointer) {
if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int));
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(uint16));
p = *(*unsafe.Pointer)(p);
}
}
......@@ -203,14 +181,10 @@ func decUint16(i *decInstr, state *DecState) {
}
}
func decInt32(i *decInstr, state *DecState) {
p := unsafe.Pointer(state.base+i.offset);
func decInt32(i *decInstr, state *DecState, p unsafe.Pointer) {
if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int));
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int32));
p = *(*unsafe.Pointer)(p);
}
}
......@@ -220,14 +194,10 @@ func decInt32(i *decInstr, state *DecState) {
}
}
func decUint32(i *decInstr, state *DecState) {
p := unsafe.Pointer(state.base+i.offset);
func decUint32(i *decInstr, state *DecState, p unsafe.Pointer) {
if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int));
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(uint32));
p = *(*unsafe.Pointer)(p);
}
}
......@@ -237,14 +207,10 @@ func decUint32(i *decInstr, state *DecState) {
}
}
func decInt64(i *decInstr, state *DecState) {
p := unsafe.Pointer(state.base+i.offset);
func decInt64(i *decInstr, state *DecState, p unsafe.Pointer) {
if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int));
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int64));
p = *(*unsafe.Pointer)(p);
}
}
......@@ -254,14 +220,10 @@ func decInt64(i *decInstr, state *DecState) {
}
}
func decUint64(i *decInstr, state *DecState) {
p := unsafe.Pointer(state.base+i.offset);
func decUint64(i *decInstr, state *DecState, p unsafe.Pointer) {
if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int));
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(uint64));
p = *(*unsafe.Pointer)(p);
}
}
......@@ -286,14 +248,10 @@ func floatFromBits(u uint64) float64 {
return math.Float64frombits(v);
}
func decFloat(i *decInstr, state *DecState) {
p := unsafe.Pointer(state.base+i.offset);
func decFloat(i *decInstr, state *DecState, p unsafe.Pointer) {
if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int));
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(float));
p = *(*unsafe.Pointer)(p);
}
}
......@@ -303,14 +261,10 @@ func decFloat(i *decInstr, state *DecState) {
}
}
func decFloat32(i *decInstr, state *DecState) {
p := unsafe.Pointer(state.base+i.offset);
func decFloat32(i *decInstr, state *DecState, p unsafe.Pointer) {
if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int));
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(float32));
p = *(*unsafe.Pointer)(p);
}
}
......@@ -320,14 +274,10 @@ func decFloat32(i *decInstr, state *DecState) {
}
}
func decFloat64(i *decInstr, state *DecState) {
p := unsafe.Pointer(state.base+i.offset);
func decFloat64(i *decInstr, state *DecState, p unsafe.Pointer) {
if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int));
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(float64));
p = *(*unsafe.Pointer)(p);
}
}
......@@ -346,7 +296,7 @@ type decEngine struct {
}
var decEngineMap = make(map[reflect.Type] *decEngine)
var decOp = map[int] func(*decInstr, *DecState) {
var decOpMap = map[int] decOp {
reflect.BoolKind: decBool,
reflect.IntKind: decInt,
reflect.Int8Kind: decInt8,
......@@ -386,7 +336,7 @@ func compileDec(rt reflect.Type, typ Type) *decEngine {
ftyp = pt.Sub();
indir++;
}
op, ok := decOp[ftyp.Kind()];
op, ok := decOpMap[ftyp.Kind()];
if !ok {
panicln("can't handle decode for type", ftyp.String());
}
......@@ -424,7 +374,11 @@ func (engine *decEngine) decode(r io.Reader, v reflect.Value) os.Error {
panicln("TODO(r): need to handle unknown data");
}
instr := &engine.instr[fieldnum];
instr.op(instr, state);
p := unsafe.Pointer(state.base+instr.offset);
if instr.indir > 1 {
p = decIndirect(p, instr.indir);
}
instr.op(instr, state, p);
state.fieldnum = fieldnum;
}
return state.err
......
......@@ -60,9 +60,12 @@ func EncodeInt(state *EncState, i int64){
EncodeUint(state, uint64(x))
}
type encInstr struct
type encOp func(i *encInstr, state *EncState, p unsafe.Pointer)
// The 'instructions' of the encoding machine
type encInstr struct {
op func(i *encInstr, state *EncState);
op encOp;
field int; // field number
indir int; // how many pointer indirections to reach the value in the struct
offset uintptr; // offset in the structure of the field to encode
......@@ -84,13 +87,7 @@ func encIndirect(p unsafe.Pointer, indir int) unsafe.Pointer {
return p
}
func encBool(i *encInstr, state *EncState) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
func encBool(i *encInstr, state *EncState, p unsafe.Pointer) {
b := *(*bool)(p);
if b {
EncodeUint(state, uint64(i.field - state.fieldnum));
......@@ -98,13 +95,7 @@ func encBool(i *encInstr, state *EncState) {
}
}
func encInt(i *encInstr, state *EncState) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
func encInt(i *encInstr, state *EncState, p unsafe.Pointer) {
v := int64(*(*int)(p));
if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum));
......@@ -112,13 +103,7 @@ func encInt(i *encInstr, state *EncState) {
}
}
func encUint(i *encInstr, state *EncState) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
func encUint(i *encInstr, state *EncState, p unsafe.Pointer) {
v := uint64(*(*uint)(p));
if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum));
......@@ -126,13 +111,7 @@ func encUint(i *encInstr, state *EncState) {
}
}
func encInt8(i *encInstr, state *EncState) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
func encInt8(i *encInstr, state *EncState, p unsafe.Pointer) {
v := int64(*(*int8)(p));
if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum));
......@@ -140,13 +119,7 @@ func encInt8(i *encInstr, state *EncState) {
}
}
func encUint8(i *encInstr, state *EncState) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
func encUint8(i *encInstr, state *EncState, p unsafe.Pointer) {
v := uint64(*(*uint8)(p));
if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum));
......@@ -154,13 +127,7 @@ func encUint8(i *encInstr, state *EncState) {
}
}
func encInt16(i *encInstr, state *EncState) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
func encInt16(i *encInstr, state *EncState, p unsafe.Pointer) {
v := int64(*(*int16)(p));
if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum));
......@@ -168,13 +135,7 @@ func encInt16(i *encInstr, state *EncState) {
}
}
func encUint16(i *encInstr, state *EncState) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
func encUint16(i *encInstr, state *EncState, p unsafe.Pointer) {
v := uint64(*(*uint16)(p));
if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum));
......@@ -182,13 +143,7 @@ func encUint16(i *encInstr, state *EncState) {
}
}
func encInt32(i *encInstr, state *EncState) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
func encInt32(i *encInstr, state *EncState, p unsafe.Pointer) {
v := int64(*(*int32)(p));
if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum));
......@@ -196,13 +151,7 @@ func encInt32(i *encInstr, state *EncState) {
}
}
func encUint32(i *encInstr, state *EncState) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
func encUint32(i *encInstr, state *EncState, p unsafe.Pointer) {
v := uint64(*(*uint32)(p));
if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum));
......@@ -210,13 +159,7 @@ func encUint32(i *encInstr, state *EncState) {
}
}
func encInt64(i *encInstr, state *EncState) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
func encInt64(i *encInstr, state *EncState, p unsafe.Pointer) {
v := *(*int64)(p);
if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum));
......@@ -224,13 +167,7 @@ func encInt64(i *encInstr, state *EncState) {
}
}
func encUint64(i *encInstr, state *EncState) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
func encUint64(i *encInstr, state *EncState, p unsafe.Pointer) {
v := *(*uint64)(p);
if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum));
......@@ -254,13 +191,7 @@ func floatBits(f float64) uint64 {
return v;
}
func encFloat(i *encInstr, state *EncState) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
func encFloat(i *encInstr, state *EncState, p unsafe.Pointer) {
f := float(*(*float)(p));
if f != 0 {
v := floatBits(float64(f));
......@@ -269,13 +200,7 @@ func encFloat(i *encInstr, state *EncState) {
}
}
func encFloat32(i *encInstr, state *EncState) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
func encFloat32(i *encInstr, state *EncState, p unsafe.Pointer) {
f := float32(*(*float32)(p));
if f != 0 {
v := floatBits(float64(f));
......@@ -284,13 +209,7 @@ func encFloat32(i *encInstr, state *EncState) {
}
}
func encFloat64(i *encInstr, state *EncState) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
func encFloat64(i *encInstr, state *EncState, p unsafe.Pointer) {
f := *(*float64)(p);
if f != 0 {
v := floatBits(f);
......@@ -300,7 +219,7 @@ func encFloat64(i *encInstr, state *EncState) {
}
// The end of a struct is marked by a delta field number of 0.
func encStructTerminator(i *encInstr, state *EncState) {
func encStructTerminator(i *encInstr, state *EncState, p unsafe.Pointer) {
EncodeUint(state, 0);
}
......@@ -313,7 +232,7 @@ type encEngine struct {
}
var encEngineMap = make(map[reflect.Type] *encEngine)
var encOp = map[int] func(*encInstr, *EncState) {
var encOpMap = map[int] encOp {
reflect.BoolKind: encBool,
reflect.IntKind: encInt,
reflect.Int8Kind: encInt8,
......@@ -352,7 +271,7 @@ func compileEnc(rt reflect.Type, typ Type) *encEngine {
ftyp = pt.Sub();
indir++;
}
op, ok := encOp[ftyp.Kind()];
op, ok := encOpMap[ftyp.Kind()];
if !ok {
panicln("encode can't handle type", ftyp.String());
}
......@@ -383,7 +302,14 @@ func (engine *encEngine) encode(w io.Writer, v reflect.Value) os.Error {
state.fieldnum = -1;
for i := 0; i < len(engine.instr); i++ {
instr := &engine.instr[i];
instr.op(instr, state);
p := unsafe.Pointer(state.base+instr.offset);
if instr.indir > 0 {
if p = encIndirect(p, instr.indir); p == nil {
state.fieldnum = i;
continue
}
}
instr.op(instr, state, p);
if state.err != nil {
break
}
......
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