[go-nuts] unnecessary zeroing in reflectdata.fillptrmask

2023-12-19 Thread Ge
Src: 
https://github.com/golang/go/blob/1d4b0b6236febe0646d8d7b0103da5d169f185cc/src/cmd/compile/internal/reflectdata/reflect.go#L1568-L1594

```
func dgcptrmask(t *types.Type, write bool) *obj.LSym {
...
ptrmask = make([]byte, n)
fillptrmask(t, ptrmask)
...
}

func fillptrmask(t *types.Type, ptrmask []byte) {
for i := range ptrmask {
ptrmask[i] = 0
}
...
}
```

The only caller of fillptrmask is dgcptrmask, so no need to initialize the 
ptrmask again.
And from the objdump result of the compiler binary it's not eliminated by 
DSE either.

```
➜  linux_amd64 go tool objdump -S ./compile| grep -A 30 "TEXT 
cmd/compile/internal/reflectdata.fillptrmask"
TEXT cmd/compile/internal/reflectdata.fillptrmask(SB) 
cmd/compile/internal/reflectdata/reflect.go
  0x719f40  493b6610CMPQ SP, 0x10(R14)
  0x719f44  0f868101JBE 0x71a0cb
  0x719f4a  55  PUSHQ BP
  0x719f4b  4889e5  MOVQ SP, BP
  0x719f4e  4883ec68SUBQ $0x68, SP
  0x719f52  48898c248800MOVQ CX, 0x88(SP)
  0x719f5a  48899c248000MOVQ BX, 0x80(SP)
  0x719f62  4889442460  MOVQ AX, 0x60(SP)
  0x719f67  4885c9  TESTQ CX, CX
  0x719f6a  7410JE 0x719f7c
  0x719f6c  4889d8  MOVQ BX, AX
  0x719f6f  4889cb  MOVQ CX, BX
  0x719f72  e8693ad6ff  CALL 
runtime.memclrNoHeapPointers(SB)
  0x719f77  488b442460  MOVQ 0x60(SP), AX
  0x719f7c  0f1f4000NOPL 0(AX)
  0x719f80  e81b74ebff  CALL 
cmd/compile/internal/types.PtrDataSize(SB)
  0x719f85  4885c0  TESTQ AX, AX
  0x719f88  0f8e9900JLE 0x71a027
  0x719f8e  488b94248800MOVQ 0x88(SP), DX
  0x719f96  4889d6  MOVQ DX, SI
  0x719f99  c1e203  SHLL $0x3, DX
  0x719f9c  8954243cMOVL DX, 0x3c(SP)
  0x719fa0  8d7a1f  LEAL 0x1f(DX), DI
  0x719fa3  c1ff1f  SARL $0x1f, DI
  0x719fa6  c1ef1b  SHRL $0x1b, DI
  0x719fa9  8d3cf7  LEAL 0(DI)(SI*8), DI
  0x719fac  8d7f1f  LEAL 0x1f(DI), DI
  0x719faf  c1ff05  SARL $0x5, DI
  0x719fb2  4863cf  MOVSXD DI, CX
  0x719fb5  48894c2450  MOVQ CX, 0x50(SP)
```





-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/6590d17a-146d-4961-8644-0e6c8bd49632n%40googlegroups.com.


Re: [go-nuts] Does anyone gets automatic response from 944677...@qq.com?

2022-02-12 Thread Ge
The owner of this mail account may not even use it now. Just block this 
email address.

在2022年2月11日星期五 UTC+8 22:02:11 写道:

> Bad that this is not only my problem. Did anyone try to write to person 
> that set up this auto replay?
>
> piątek, 11 lutego 2022 o 14:56:10 UTC+1 ren...@ix.netcom.com napisał(a):
>
>> Same issue. Some one set up auto reply to message threads. 
>>
>> On Feb 11, 2022, at 6:36 AM, Kamil Ziemian  wrote:
>>
>> 
>>
>> Hello,
>>
>> I try to don't care about this response, but I see them one time to much. 
>> After most if not all my post here, I get email from 9446...@qq.com with 
>> title
>> "自动回复: [go-nuts]: title of the thread"
>> and content
>> "这是来自QQ邮箱的假期自动回复邮件。
>>  
>> 您好,我暂时无法亲自回复您的邮件。我将在最短的时间内尽快给您回复。谢谢。"
>> Gmail translate it to
>> "This is a holiday auto-reply email from QQ mailbox.
>>
>> Hello, I am temporarily unable to respond to your email in person. I will 
>> reply to you as soon as possible in the shortest possible time. thanks."
>>
>> It happens even if I gust open new thread, so no one other than me is 
>> involved in it. Does anyone else has this problem? And how I can solve it?
>>
>> Best,
>> Kamil
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/271ada26-1629-41e9-8bed-ac0b0fa2d5a9n%40googlegroups.com
>>  
>> 
>> .
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/25955ffc-dacb-4e97-b58a-ab6ebea9e877n%40googlegroups.com.


Re: [go-nuts] How GC trace stack objects

2021-11-04 Thread Ge

Thank you Ian for the great answer.
在2021年11月4日星期四 UTC+8 上午7:21:57 写道:

> On Wed, Nov 3, 2021 at 8:56 AM Ge  wrote:
> >
> > Hi, recently I was trying to figure out how GC marks stack objects and 
> found
> > some places of the implementation detail over my head.
> >
> > source:
> > ```
> > package main
> >
> > import "runtime"
> >
> > func main() {
> > x := make([]byte, 256*1024*1024)
> > runtime.GC() ← t1
> > x[0] = 2
> >
> > runtime.GC() ← t2
> > println("x released")
> > runtime.GC()
> > println("over")
> > }
> > ```
> >
> > The GC trace info was like this:
> > ```
> > ➜ gc GODEBUG=gctrace=1 ./largeslice
> > gc 1 @0.009s 0%: 0.051+0.27+0.005 ms clock, 0.40+0/0.18/0.034+0.040 ms 
> cpu, 256->256->256 MB, 257 MB goal, 8 P (forced)
> > gc 2 @0.010s 1%: 0.033+0.21+0.004 ms clock, 0.26+0/0.16/0.078+0.032 ms 
> cpu, 256->256->256 MB, 512 MB goal, 8 P (forced)
> > gc 3 @0.012s 1%: 0.019+0.091+0.003 ms clock, 0.15+0/0.15/0.047+0.024 ms 
> cpu, 256->256->0 MB, 512 MB goal, 8 P (forced)
> > x released
> > gc 4 @0.013s 1%: 0.014+0.11+0.004 ms clock, 0.11+0/0.13/0.058+0.036 ms 
> cpu, 0->0->0 MB, 4 MB goal, 8 P (forced)
> > over
> > ```
> > It seems that the slice x could be garbage collected after the last use 
> of it,
> > which feels so intelligent and a little confusing, since fucntion call 
> did't return yet,
> > and made me wondering how Golang dynamically identify these stack 
> objects.
> >
> > ```
> > // https://github.com/golang/go/blob/master/src/runtime/stack.go#L1246
> > func getStackMap(frame *stkframe, cache *pcvalueCache, debug bool) 
> (locals, args bitvector, objs []stackObjectRecord) {
> > ...
> > stkmap := (*stackmap)(funcdata(f, _FUNCDATA_LocalsPointerMaps))
> > ...
> > ```
> >
> > AFAIK stack pointer maps are got via getStackmap function, which
> > reads FUNCDATA info from gopclntab(not very sure about this) section.
> >
> > My question is that will GC get different stack maps at t1 and t2 ?
> > And if so how Golang implemented it, as GC stack scanning could happen
> > at any time, which means for different pc there maybe lot of possiblites
> > of stack maps.
>
> Yes, the GC will see a different map of live pointers on the stack at t1 
> and t2.
>
> A GC can occur at any point where a goroutine can be preempted. That
> means that the live pointer map has to be conservatively correct at
> all such points. I say conservatively correct because while it is
> essential that any live pointer be in the stack map, it is OK if a
> previously live pointer remains in the stack map even after it is no
> longer live. That will mean that the value stays live longer than
> necessary, but it otherwise doesn't matter. In practice the compiler
> builds stack maps that are correct at each function call. You can see
> the livemaps generated by the compiler if you build with
> -gcflags=-live=1.
>
> Ian
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/4790afc1-6dc2-4dee-abb9-61d2c67849b9n%40googlegroups.com.


[go-nuts] How GC trace stack objects

2021-11-03 Thread Ge
Hi, recently I was trying to figure out how GC marks stack objects and 
found 
some places of the implementation detail over my head.

source:
```
package main

import "runtime"

func main() {
x := make([]byte, 256*1024*1024)
runtime.GC()   ←t1
x[0] = 2

runtime.GC()←t2
println("x released")
runtime.GC()
println("over")
}
```

The GC trace info was like this: 
```
➜ gc GODEBUG=gctrace=1 ./largeslice
gc 1 @0.009s 0%: 0.051+0.27+0.005 ms clock, 0.40+0/0.18/0.034+0.040 ms cpu, 
256->256->256 MB, 257 MB goal, 8 P (forced)
gc 2 @0.010s 1%: 0.033+0.21+0.004 ms clock, 0.26+0/0.16/0.078+0.032 ms cpu, 
256->256->256 MB, 512 MB goal, 8 P (forced)
gc 3 @0.012s 1%: 0.019+0.091+0.003 ms clock, 0.15+0/0.15/0.047+0.024 ms 
cpu, 256->256->0 MB, 512 MB goal, 8 P (forced)
x released
gc 4 @0.013s 1%: 0.014+0.11+0.004 ms clock, 0.11+0/0.13/0.058+0.036 ms cpu, 
0->0->0 MB, 4 MB goal, 8 P (forced)
over
```
It seems that the slice x could be garbage collected after the last use of 
it,
which feels so intelligent and a little confusing, since fucntion call 
did't return yet,
and made me wondering how Golang dynamically identify these stack objects.

```
// https://github.com/golang/go/blob/master/src/runtime/stack.go#L1246
func getStackMap(frame *stkframe, cache *pcvalueCache, debug bool) (locals, 
args bitvector, objs []stackObjectRecord) 
{
...
stkmap := (*stackmap)(funcdata(f, _FUNCDATA_LocalsPointerMaps))
...
```

AFAIK stack pointer maps are got via getStackmap function, which
reads FUNCDATA info from gopclntab(not very sure about this) section. 

My question is that will GC get different stack maps at t1 and t2 ? 
And if so how Golang implemented it, as GC stack scanning could happen
 at any time, which means for different pc there maybe lot of possiblites
of stack maps.

Thanks
Ge


-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/feb05890-ff5c-4631-808c-05a8d23cc7d3n%40googlegroups.com.


Re: [go-nuts] defer and Go memory model

2021-05-13 Thread Ge
Thanks Jan and Axel, I may need to figure out go memory model and hardware 
memory model.

在2021年5月13日星期四 UTC+8 上午2:15:43 写道:

> On Wed, May 12, 2021 at 7:55 PM Ge  wrote:
>
> > Do you mean in following case if anthoer goroutine is observing A and B,
> > there is no possbility that A is 0 and B is 5? (assuming no other 
> synchronization here)
> >
> > ```
> > var A, B int
> > func try() {
> > defer func() { B = 5 }
> > A = 3
> > }
>
> There's no synchronization in this code, so other goroutines reading
> A or B w/o said synchronization may observe any values. Stalled,
> changing in wrong order, random..., you name it.
>
> But if has nothing to do with defer. The particular code is equal to
>
> var A, B int
> func try() {
> A = 3
> B = 5
> }
>
> with the set of problems as the version using defer.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/d388637b-91ce-4740-b58a-7061d84daea8n%40googlegroups.com.


Re: [go-nuts] defer and Go memory model

2021-05-12 Thread Ge
Thank you Jan, sorry for my bad english.
Do you mean in following case if anthoer goroutine is observing A and B, 
there is no possbility that A is 0 and B is 5? (assuming no other 
synchronization here)

```
var A, B int
func try() {
defer func() { B = 5 }
A = 3
}

Ge

在2021年5月12日星期三 UTC+8 下午10:48:43 写道:

> On Wed, May 12, 2021 at 4:38 PM Ge  wrote:
> >
> > According to https://golang.org/ref/spec#Defer_statements there is such 
> an expression:
> > `A "defer" statement invokes a function whose execution is deferred to 
> the moment the surrounding function returns`
> >
> > Does `defer` ensure happens-before behaviour with non-defer code?
>
> Happens before talks/defines properties/behavior of concurrently
> executing goroutines. The deferred function is executed in the same
> goroutine as its surrounding function. Any HB relations wrt other
> goroutines are the same as if the deferred function was not deferred
> but explicitly called before just returning from the surrounding
> function.
>
> > However x86 allows out-of-order execution happening across function 
> calls,
>
> OOE and other peculiar CPU tricks should not be observable by the Go
> program, modulo some side channel attacks.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/2bf8beb9-1927-4311-9c7c-32f880bded79n%40googlegroups.com.


[go-nuts] defer and Go memory model

2021-05-12 Thread Ge
According to https://golang.org/ref/spec#Defer_statements there is such an 
expression:
 * `A "defer" statement invokes a function whose execution is deferred to 
the moment the surrounding function returns`*

Does `defer` ensure  happens-before behaviour with non-defer code?
I have read https://golang.org/ref/mem but got nothing except this.
(It seems not clear to me about the meaning of `the order expressed by the 
program*`.*)

  `Within a single goroutine, the happens-before order is the order 
expressed by the program.`

In following case what I know is ③ happens before ①, 
but what about ②? Is it possible that ② is executed after
③ and ①?

```Go

var A, B, C int

func main() {
defer func()  { A = 4 } //①
B = 5 //②
defer func()   { C = 6 }   //③
}
```

Appendix:
1. The background: 
I was digging into the implementation of sync.Once and 
wonder if `defer atomic.StoreUint32(, 1)` in 
function doSlow could be replaced with `defer func() {o.done = 1}`.
```
func (o *Once) Do(f func()) {
  if atomic.LoadUint32() == 0 { 
o.doSlow(f)
  }
}

func (o *Once) doSlow(f func()) {
  o.m.Lock()
  defer o.m.Unlock()
  if o.done == 0 {
defer atomic.StoreUint32(, 1)
f()
  }
}
```

2. As I know, `defer` is implemented by inserting corresponding 
function calling before any exiting point(Eg. in x86 the ret 
instruction).

However x86 allows out-of-order execution happening across function 
calls,
and I'm not sure if it will happen in this case(f() and o.done has no 
dependency 
with each other so it is possible?).
If anyone knows I would appreciate for your clarification.

Thanks for your time.

Ge


-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/bf1987cf-2c06-46e3-bbc1-be91fb0f11een%40googlegroups.com.


[go-nuts] Re: meaning of SSA operation

2021-03-24 Thread Ge
Thank you, looking forward to new Go version with regabi.

在2021年3月25日星期四 UTC+8 上午12:04:39 写道:

> Also, be aware that work that we really hope lands in 1.17 will tinker 
> with all the call operations.
>
> The goal is to switch to an ABI that passes parameters to/from calls in 
> registers, and the way
> that ends up expressed in SSA is that first (and we do this part in 1.16) 
> the parameters to the 
> call will appear as inputs, and the results will be obtained with 
> OpSelectN.  The call will still
> receive and return a memory value, as last input and last element of 
> result.
>
> This is then lowered to a machine-agnostic level where some parameters are 
> stored in memory,
> the others in registers -- where the registers appear as inputs/outputs of 
> the call -- and then
> further lowered (simple OpCode rewrite) to machine-specific call 
> instructions.  The registers themselves
> are bound in the register allocator, by the "trick" of telling it that 
> Calls have only a single appropriate
> register for each of their inputs/outputs.
>
> This might look a little odd the first time you see it.
>
> And, also, the order in which the registers inputs/outputs are encoded is 
> not fixed; for compiler
> efficiency purposes, we *might* reorder them so that all the integer 
> registers come first, etc.
> (This would allow a lot more sharing of register masks.)
>
> This full change is likely only for amd64 in 1.17, then for other 
> architectures once we figure out
> the exact recipe.  It touches many parts of the compiler and runtime.
>
> On Wednesday, March 24, 2021 at 4:01:36 AM UTC-4 Ge wrote:
>
>> Thank you Keith for clarification. It's really of great help.
>>
>> Ge
>>
>> 在2021年3月24日星期三 UTC+8 上午7:45:13 写道:
>>
>>> On Tuesday, March 23, 2021 at 9:11:13 AM UTC-7 Ge wrote:
>>>
>>>>
>>>> Hi,
>>>> Recently I encountered a problem which seems to be related to SSA 
>>>> optimization 
>>>> and feels hard to figure out what some SSA operation means.
>>>>
>>>> Code:
>>>> case1:
>>>> func main() {
>>>> var x int
>>>> go func() {
>>>> for {   
>>>> x++  //no matter "-N" compile flags is specified or 
>>>> not, 'x++' will be optimized
>>>> }
>>>> }()
>>>> println(x)
>>>> }
>>>>
>>>> case2:
>>>> func main() {
>>>> var x int
>>>> go func() {
>>>> for {   
>>>> x++  
>>>> dummy()   // when empty function 'dummy' is added to this 
>>>> infinite loop, ''x++' stays last
>>>> }
>>>> }()
>>>> println(x)
>>>> }
>>>>
>>>> //go:noinline
>>>> func dummy() {
>>>> }
>>>>
>>>> I tried 'GOSSAFUNC=main.func1 go tool compile case2.go' and found the 
>>>> key point is
>>>> deadcode phase in SSA. Here is CFG before 'early deadcode' phase:
>>>>
>>>> ``` *ssaoptx.go*
>>>> 5  go func() {
>>>> 6  for {
>>>> 7  x++
>>>> 8  dummy()
>>>> 9  }
>>>> 10 }()
>>>> ```
>>>>
>>>> ``` *early copyelim*
>>>>
>>>>- b1:
>>>>- 
>>>>   - v1 (?) = InitMem 
>>>>   - v2 (?) = SP 
>>>>   - v3 (?) = SB 
>>>>   - v4 (?) = LocalAddr <**int> {} v2 v1
>>>>   - v5 (5) = Arg <*int> {} ([*int])
>>>>   - v9 (?) = Const64  [1]
>>>>- Plain → b2 (*+6*)
>>>>
>>>>
>>>>- b2: ← b1 b4
>>>>- 
>>>>   - v14 (7) = Phi  v1 v12
>>>>   - v15 (7) = Copy <*int> v5 ([*int])
>>>>- Plain → b3 (7)
>>>>
>>>>
>>>>- b3: ← b2
>>>>- 
>>>>   - v6 (7) = Copy <*int> v5 ([*int])
>>>>   - v7 (7) = Copy  v14
>>>>   - v8 (*+7*) = Load  v5 v14
>>>>   - v10 (7) = Add64  v8 v9
>>>>   - v11 (7) = Store  {int} v5 v10 v14
>>>>   - v12 (*+8*) = StaticCall  {"".dummy} v11
>>>>- Plain → b4 (8)
>>>>
>>>>
>>>>- b4: ← b3
>>>>- Plain → b2 (7)
>>>>
>>>>
>>>>-

[go-nuts] Re: meaning of SSA operation

2021-03-24 Thread Ge
Thank you Keith for clarification. It's really of great help.

Ge

在2021年3月24日星期三 UTC+8 上午7:45:13 写道:

> On Tuesday, March 23, 2021 at 9:11:13 AM UTC-7 Ge wrote:
>
>>
>> Hi,
>> Recently I encountered a problem which seems to be related to SSA 
>> optimization 
>> and feels hard to figure out what some SSA operation means.
>>
>> Code:
>> case1:
>> func main() {
>> var x int
>> go func() {
>> for {   
>> x++  //no matter "-N" compile flags is specified or 
>> not, 'x++' will be optimized
>> }
>> }()
>> println(x)
>> }
>>
>> case2:
>> func main() {
>> var x int
>> go func() {
>> for {   
>> x++  
>> dummy()   // when empty function 'dummy' is added to this 
>> infinite loop, ''x++' stays last
>> }
>> }()
>> println(x)
>> }
>>
>> //go:noinline
>> func dummy() {
>> }
>>
>> I tried 'GOSSAFUNC=main.func1 go tool compile case2.go' and found the key 
>> point is
>> deadcode phase in SSA. Here is CFG before 'early deadcode' phase:
>>
>> ``` *ssaoptx.go*
>> 5  go func() {
>> 6  for {
>> 7  x++
>> 8  dummy()
>> 9  }
>> 10 }()
>> ```
>>
>> ``` *early copyelim*
>>
>>- b1:
>>- 
>>   - v1 (?) = InitMem 
>>   - v2 (?) = SP 
>>   - v3 (?) = SB 
>>   - v4 (?) = LocalAddr <**int> {} v2 v1
>>   - v5 (5) = Arg <*int> {} ([*int])
>>   - v9 (?) = Const64  [1]
>>- Plain → b2 (*+6*)
>>
>>
>>- b2: ← b1 b4
>>- 
>>   - v14 (7) = Phi  v1 v12
>>   - v15 (7) = Copy <*int> v5 ([*int])
>>- Plain → b3 (7)
>>
>>
>>- b3: ← b2
>>- 
>>   - v6 (7) = Copy <*int> v5 ([*int])
>>   - v7 (7) = Copy  v14
>>   - v8 (*+7*) = Load  v5 v14
>>   - v10 (7) = Add64  v8 v9
>>   - v11 (7) = Store  {int} v5 v10 v14
>>   - v12 (*+8*) = StaticCall  {"".dummy} v11
>>- Plain → b4 (8)
>>
>>
>>- b4: ← b3
>>- Plain → b2 (7)
>>
>>
>>- b5:
>>- 
>>   - v13 (10) = Unknown 
>>- Ret v13
>>
>> ```
>> deadcode phase will traverse all blocks and find out the reachable blocks 
>> (In above example is b1,b2,b3,b4, while b5 is isolated block), Second it 
>> will
>> find out live values based on reachable blocks and eliminate dead values.
>>
>> The call of dummy function makes v8,v10,v11 all live so 'x++' isn't 
>> optimized.
>> I have read ssa/README.md but still had some questions.
>>
>> 1. The role of InitMem.
>>  It seems that every function starts with it, are some initialize 
>> work like 
>>  stack space allocation and named return values initialization done 
>> by it?
>>
>>
> Not really. Stack space and any zeroing required are done when generating 
> the preamble. They are not represented in SSA.
> InitMem is just the initial state of memory on entry to the function. It 
> does not generate any actual code.
>  
>
>> 2.  The meaning of 'v14 (7) = Phi  v1 v12'.
>>   It looks like v14 = Φ(v1, v12), but I don't know why InitMem and 
>> dummy function
>>   call will affect here.
>>
>> 3.  The meaning of of  StaticCall's argument .
>>   Some ssa operations are easy to understand,  for example,  
>>   'v8 (*+7*) = Load  v5 v14' means v8=Load(v5) and v14 is 
>> the memory statewhich implies this load operation must happens 
>> after v14 is determined.
>>
>>   That's all I know from README.md, but about other operations like 
>> StaticCall
>>I can't get enough information. Here is the relevant souce In 
>> genericOps.go:
>>```
>>   
>>  {name: "StaticCall", argLength: 1, aux: "CallOff", call: true}, 
>>   
>>  // call function aux.(*obj.LSym), arg0=memory.  auxint=arg size.  Returns 
>> memory.
>>   ```
>>   For 'v12 (*+8*) = StaticCall  {"".dummy} v11' the only 
>> argument is v11 but
>>   obviously v11 seems not the address of dummy function.
>>
>>
> The address of the target of the call is not stored in a separate SSA 
> value - it is encoded directly in the StaticCall Value (in the Aux field).
> Other types of calls (the indirect ones whose target must be 

[go-nuts] meaning of SSA operation

2021-03-23 Thread Ge

Hi,
Recently I encountered a problem which seems to be related to SSA 
optimization 
and feels hard to figure out what some SSA operation means.

Code:
case1:
func main() {
var x int
go func() {
for {   
x++  //no matter "-N" compile flags is specified or 
not, 'x++' will be optimized
}
}()
println(x)
}

case2:
func main() {
var x int
go func() {
for {   
x++  
dummy()   // when empty function 'dummy' is added to this 
infinite loop, ''x++' stays last
}
}()
println(x)
}

//go:noinline
func dummy() {
}

I tried 'GOSSAFUNC=main.func1 go tool compile case2.go' and found the key 
point is
deadcode phase in SSA. Here is CFG before 'early deadcode' phase:

``` *ssaoptx.go*
5  go func() {
6  for {
7  x++
8  dummy()
9  }
10 }()
```

``` *early copyelim*

   - b1:
   - 
  - v1 (?) = InitMem 
  - v2 (?) = SP 
  - v3 (?) = SB 
  - v4 (?) = LocalAddr <**int> {} v2 v1
  - v5 (5) = Arg <*int> {} ([*int])
  - v9 (?) = Const64  [1]
   - Plain → b2 (*+6*)


   - b2: ← b1 b4
   - 
  - v14 (7) = Phi  v1 v12
  - v15 (7) = Copy <*int> v5 ([*int])
   - Plain → b3 (7)


   - b3: ← b2
   - 
  - v6 (7) = Copy <*int> v5 ([*int])
  - v7 (7) = Copy  v14
  - v8 (*+7*) = Load  v5 v14
  - v10 (7) = Add64  v8 v9
  - v11 (7) = Store  {int} v5 v10 v14
  - v12 (*+8*) = StaticCall  {"".dummy} v11
   - Plain → b4 (8)


   - b4: ← b3
   - Plain → b2 (7)


   - b5:
   - 
  - v13 (10) = Unknown 
   - Ret v13

```
deadcode phase will traverse all blocks and find out the reachable blocks 
(In above example is b1,b2,b3,b4, while b5 is isolated block), Second it 
will
find out live values based on reachable blocks and eliminate dead values.

The call of dummy function makes v8,v10,v11 all live so 'x++' isn't 
optimized.
I have read ssa/README.md but still had some questions.

1. The role of InitMem.
 It seems that every function starts with it, are some initialize work 
like 
 stack space allocation and named return values initialization done by 
it?

2.  The meaning of 'v14 (7) = Phi  v1 v12'.
  It looks like v14 = Φ(v1, v12), but I don't know why InitMem and 
dummy function
  call will affect here.

3.  The meaning of of  StaticCall's argument .
  Some ssa operations are easy to understand,  for example,  
  'v8 (*+7*) = Load  v5 v14' means v8=Load(v5) and v14 is the 
memory statewhich implies this load operation must happens 
after v14 is determined.

  That's all I know from README.md, but about other operations like 
StaticCall
   I can't get enough information. Here is the relevant souce In 
genericOps.go:
   ```
   {name: "StaticCall", argLength: 1, aux: "CallOff", call: true}, 
  
 // call function aux.(*obj.LSym), arg0=memory.  auxint=arg size.  Returns 
memory.
  ```
  For 'v12 (*+8*) = StaticCall  {"".dummy} v11' the only argument 
is v11 but
  obviously v11 seems not the address of dummy function.

4.  As threre are other incomprehensible ssa operations except InitMem, 
Phi, ... ,
  Is there any documents which can help understanding?
 
'Thanks for you time.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/2d078627-62d6-4885-9c53-9bc9f5629d90n%40googlegroups.com.


Re: [go-nuts] How does isAsyncSafePoint check preemptable?

2020-08-07 Thread Ge

Thanks. clear now.
在2020年8月7日星期五 UTC+8 上午1:00:51 写道:

> On Thu, Aug 6, 2020 at 7:49 AM HailangGe  wrote:
> >
> > Recently I was trying to understand how asynchronous preemption is 
> implemented in Go 1.14 and
> > basically figured out the call chain.
> >
> > sysmon
> > ↓
> > retake
> > ↓
> > preemptone
> > ↓
> > preemptM
> > ↓
> > signalM(mp, sigPreempt) //send SIGURG to mp
> > ↓
> > doSigPreempt(signal handler) //if isAsyncSafePoint returns true, it will 
> go on to preempt
> > ↓
> > ctxt.pushCall(funcPC(asyncPreempt))
> > ↓
> > asyncPreempt
> > ↓
> > asyncPreempt2
> > ↓
> > mcall(preemptPark) or mcall(gopreempt_m)
> >
> > And I wrote a simple program to verify:
> > ```Go
> > func main() {
> > var wg sync.WaitGroup
> > wg.Add(30)
> > for i := 0; i < 30; i++ {
> > go func() {
> > defer wg.Done()
> > t := 0
> > for i := 0; i < 1e8; i++ {
> > t += 2
> > }
> > }()
> > }
> > wg.Wait()
> > }
> > ```
> >
> > As we know general purpose registers RAX/RBX/... are not included in 
> goroutine context.
>
> That is true but it doesn't matter. asyncPreempt is a GOARCH-specific
> routine that saves all registers. When the preempted goroutine is
> resumed, it will return through asyncPreempt and the registers will be
> restored before continuing with execution.
>
>
>
>
> > My problem is how Go judges which instruction is preemptable? is it 
> determined at compile time?
>
> There are other, less common, cases where preemption is not permitted,
> and, yes, those are marked by the compiler and checked by
> isAsyncSafePoint.
>
> Ian
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/3838126a-107f-4b90-a275-b915ac2ee148n%40googlegroups.com.


Re: [go-nuts] front-end post a body, back-end use gin.Context BindJSON but fail

2018-11-21 Thread ge . sf . chn
thanks,you are right, i got it at that night.

在 2018年11月9日星期五 UTC+8下午10:14:14,Burak Serdar写道:
>
> On Fri, Nov 9, 2018 at 6:35 AM > wrote: 
> > 
> > front-end info 
> > //body struct 
> > type Bucket struct { 
> >Name  string  `json:"name"` 
> >KeyId string  `json:"key_id"` 
> >KeySecret string  `json:"key_secret"` 
> >Header*Header `json:"header"` 
> >Property  int `json:"property"` 
> > } 
> > 
> > type Header struct { 
> >CacheControl int64 `json:"cache_control"` 
> > } 
> > //my post request body 
> > 
> {"name":"g","key_id":"221bce6492eba70f","key_secret":"6eb80603e85842542f9736eb13b7e3","header":{"cache_control":"10"},"property":"0"}
>  
>
>
> "cache_control":"10" is a string. If you want to unmarshal an int, 
> this should've been "cache_control":10 (without the quotes) 
>
> Or, change the Header.CacheControl to string. 
>
> > 
> > Name 
> > front-end 
> > back-end error when do 
> /usr/local/Cellar/go/1.10.3/libexec/src/encoding/json/decode.go:171 
> cache_control is string not int 
> > 
> > 
> > 
> > 
> > 
> > -- 
> > You received this message because you are subscribed to the Google 
> Groups "golang-nuts" group. 
> > To unsubscribe from this group and stop receiving emails from it, send 
> an email to golang-nuts...@googlegroups.com . 
> > For more options, visit https://groups.google.com/d/optout. 
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.