[llvm-dev] Passing stack pointer to statepoint-gc

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

[llvm-dev] Passing stack pointer to statepoint-gc

David Jones via llvm-dev
Hi,

I'm trying to use the statepoint-example strategy to build a simple garbage collector. After using the PlaceSafepoints and RewriteStatepointsForGC passes, I can successfully generate a stack map in my binary and call into my runtime's gc poll.

As far as I can tell, I need the stack pointer at the point of the poll to find the correct frame in the stack map. I'm having trouble doing that.

One library I looked at online (statepoint-utils) simply defines a helper function written in assembly that pushes the RSP register to RDI before calling into the runtime, so that the runtime gc polling function can read it as a parameter.

I was trying to do the same thing except in llvm, so from my gc.safepoint_poll definition, I tried adding these lines:

declare void @runtime_safepoint_poll(i64)
declare i64 @llvm.read_register.i64(metadata) #1
!0 = !{!"rsp\00"}

; Read the stack pointer and pass it to our polling function (assumes x64)
define void @gc.safepoint_poll() {
  %stackpointer = call i64 @llvm.read_register.i64(metadata !0)
  call void @runtime_safepoint_poll(i64 %stackpointer)
  ret void
}

attributes #1 = { "gc-leaf-function" nounwind readnone }

Note that the target triple is x86_64-pc-windows-msvc.

When I test this, the values that come from reading RSP are never in the address space of the module. Like, not even close.

As far as I can tell, this should work, and I'm a little stymied as to why I'm getting back garbage. Do I misunderstand the read_register call here?

Thanks,
Jordan


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Passing stack pointer to statepoint-gc

David Jones via llvm-dev

Jordon,


First of all, StackMaps are keyed by PC, not by SP.  Each entry corresponds to given location within the generated code. 


This isn't something you want to do in generated code.  Your runtime should be responsible for this.  If you support stack walking or back traces for any purpose, you should already have the code to identify the PC for a suspended frame on the stack.


If you don't, the easiest approach will be to use a assembly stub between your generated code and your C/C++ runtime code which grabs the PC from the stack, and moves it into an argument register.


Philip


On 11/7/18 5:22 PM, Jordan Rudd via llvm-dev wrote:
Hi,

I'm trying to use the statepoint-example strategy to build a simple garbage collector. After using the PlaceSafepoints and RewriteStatepointsForGC passes, I can successfully generate a stack map in my binary and call into my runtime's gc poll.

As far as I can tell, I need the stack pointer at the point of the poll to find the correct frame in the stack map. I'm having trouble doing that.

One library I looked at online (statepoint-utils) simply defines a helper function written in assembly that pushes the RSP register to RDI before calling into the runtime, so that the runtime gc polling function can read it as a parameter.

I was trying to do the same thing except in llvm, so from my gc.safepoint_poll definition, I tried adding these lines:

declare void @runtime_safepoint_poll(i64)
declare i64 @llvm.read_register.i64(metadata) #1
!0 = !{!"rsp\00"}

; Read the stack pointer and pass it to our polling function (assumes x64)
define void @gc.safepoint_poll() {
  %stackpointer = call i64 @llvm.read_register.i64(metadata !0)
  call void @runtime_safepoint_poll(i64 %stackpointer)
  ret void
}

attributes #1 = { "gc-leaf-function" nounwind readnone }

Note that the target triple is x86_64-pc-windows-msvc.

When I test this, the values that come from reading RSP are never in the address space of the module. Like, not even close.

As far as I can tell, this should work, and I'm a little stymied as to why I'm getting back garbage. Do I misunderstand the read_register call here?

Thanks,
Jordan


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Passing stack pointer to statepoint-gc

David Jones via llvm-dev
Sorry, what does "PC" mean here?

From: Philip Reames <[hidden email]>
Sent: Thursday, November 8, 2018 7:27 AM
To: Jordan Rudd; [hidden email]
Subject: Re: [llvm-dev] Passing stack pointer to statepoint-gc
 

Jordon,


First of all, StackMaps are keyed by PC, not by SP.  Each entry corresponds to given location within the generated code. 


This isn't something you want to do in generated code.  Your runtime should be responsible for this.  If you support stack walking or back traces for any purpose, you should already have the code to identify the PC for a suspended frame on the stack.


If you don't, the easiest approach will be to use a assembly stub between your generated code and your C/C++ runtime code which grabs the PC from the stack, and moves it into an argument register.


Philip


On 11/7/18 5:22 PM, Jordan Rudd via llvm-dev wrote:
Hi,

I'm trying to use the statepoint-example strategy to build a simple garbage collector. After using the PlaceSafepoints and RewriteStatepointsForGC passes, I can successfully generate a stack map in my binary and call into my runtime's gc poll.

As far as I can tell, I need the stack pointer at the point of the poll to find the correct frame in the stack map. I'm having trouble doing that.

One library I looked at online (statepoint-utils) simply defines a helper function written in assembly that pushes the RSP register to RDI before calling into the runtime, so that the runtime gc polling function can read it as a parameter.

I was trying to do the same thing except in llvm, so from my gc.safepoint_poll definition, I tried adding these lines:

declare void @runtime_safepoint_poll(i64)
declare i64 @llvm.read_register.i64(metadata) #1
!0 = !{!"rsp\00"}

; Read the stack pointer and pass it to our polling function (assumes x64)
define void @gc.safepoint_poll() {
  %stackpointer = call i64 @llvm.read_register.i64(metadata !0)
  call void @runtime_safepoint_poll(i64 %stackpointer)
  ret void
}

attributes #1 = { "gc-leaf-function" nounwind readnone }

Note that the target triple is x86_64-pc-windows-msvc.

When I test this, the values that come from reading RSP are never in the address space of the module. Like, not even close.

As far as I can tell, this should work, and I'm a little stymied as to why I'm getting back garbage. Do I misunderstand the read_register call here?

Thanks,
Jordan


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Passing stack pointer to statepoint-gc

David Jones via llvm-dev
Program counter?

From: llvm-dev <[hidden email]> on behalf of Jordan Rudd via llvm-dev <[hidden email]>
Sent: Thursday, November 8, 2018 10:47 AM
To: Philip Reames; [hidden email]
Subject: Re: [llvm-dev] Passing stack pointer to statepoint-gc
 
Sorry, what does "PC" mean here?

From: Philip Reames <[hidden email]>
Sent: Thursday, November 8, 2018 7:27 AM
To: Jordan Rudd; [hidden email]
Subject: Re: [llvm-dev] Passing stack pointer to statepoint-gc
 

Jordon,


First of all, StackMaps are keyed by PC, not by SP.  Each entry corresponds to given location within the generated code. 


This isn't something you want to do in generated code.  Your runtime should be responsible for this.  If you support stack walking or back traces for any purpose, you should already have the code to identify the PC for a suspended frame on the stack.


If you don't, the easiest approach will be to use a assembly stub between your generated code and your C/C++ runtime code which grabs the PC from the stack, and moves it into an argument register.


Philip


On 11/7/18 5:22 PM, Jordan Rudd via llvm-dev wrote:
Hi,

I'm trying to use the statepoint-example strategy to build a simple garbage collector. After using the PlaceSafepoints and RewriteStatepointsForGC passes, I can successfully generate a stack map in my binary and call into my runtime's gc poll.

As far as I can tell, I need the stack pointer at the point of the poll to find the correct frame in the stack map. I'm having trouble doing that.

One library I looked at online (statepoint-utils) simply defines a helper function written in assembly that pushes the RSP register to RDI before calling into the runtime, so that the runtime gc polling function can read it as a parameter.

I was trying to do the same thing except in llvm, so from my gc.safepoint_poll definition, I tried adding these lines:

declare void @runtime_safepoint_poll(i64)
declare i64 @llvm.read_register.i64(metadata) #1
!0 = !{!"rsp\00"}

; Read the stack pointer and pass it to our polling function (assumes x64)
define void @gc.safepoint_poll() {
  %stackpointer = call i64 @llvm.read_register.i64(metadata !0)
  call void @runtime_safepoint_poll(i64 %stackpointer)
  ret void
}

attributes #1 = { "gc-leaf-function" nounwind readnone }

Note that the target triple is x86_64-pc-windows-msvc.

When I test this, the values that come from reading RSP are never in the address space of the module. Like, not even close.

As far as I can tell, this should work, and I'm a little stymied as to why I'm getting back garbage. Do I misunderstand the read_register call here?

Thanks,
Jordan


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Passing stack pointer to statepoint-gc

David Jones via llvm-dev
On x86_64, PC is called RIP.
I'm not sure if Clang supports it, but on GCC you can use:
__builtin_extract_return_addr(__builtin_return_address(0))


On Thu, Nov 8, 2018, 10:48 Jordan Rudd via llvm-dev <[hidden email] wrote:
Program counter?

From: llvm-dev <[hidden email]> on behalf of Jordan Rudd via llvm-dev <[hidden email]>
Sent: Thursday, November 8, 2018 10:47 AM
To: Philip Reames; [hidden email]
Subject: Re: [llvm-dev] Passing stack pointer to statepoint-gc
 
Sorry, what does "PC" mean here?

From: Philip Reames <[hidden email]>
Sent: Thursday, November 8, 2018 7:27 AM
To: Jordan Rudd; [hidden email]
Subject: Re: [llvm-dev] Passing stack pointer to statepoint-gc
 

Jordon,


First of all, StackMaps are keyed by PC, not by SP.  Each entry corresponds to given location within the generated code. 


This isn't something you want to do in generated code.  Your runtime should be responsible for this.  If you support stack walking or back traces for any purpose, you should already have the code to identify the PC for a suspended frame on the stack.


If you don't, the easiest approach will be to use a assembly stub between your generated code and your C/C++ runtime code which grabs the PC from the stack, and moves it into an argument register.


Philip


On 11/7/18 5:22 PM, Jordan Rudd via llvm-dev wrote:
Hi,

I'm trying to use the statepoint-example strategy to build a simple garbage collector. After using the PlaceSafepoints and RewriteStatepointsForGC passes, I can successfully generate a stack map in my binary and call into my runtime's gc poll.

As far as I can tell, I need the stack pointer at the point of the poll to find the correct frame in the stack map. I'm having trouble doing that.

One library I looked at online (statepoint-utils) simply defines a helper function written in assembly that pushes the RSP register to RDI before calling into the runtime, so that the runtime gc polling function can read it as a parameter.

I was trying to do the same thing except in llvm, so from my gc.safepoint_poll definition, I tried adding these lines:

declare void @runtime_safepoint_poll(i64)
declare i64 @llvm.read_register.i64(metadata) #1
!0 = !{!"rsp\00"}

; Read the stack pointer and pass it to our polling function (assumes x64)
define void @gc.safepoint_poll() {
  %stackpointer = call i64 @llvm.read_register.i64(metadata !0)
  call void @runtime_safepoint_poll(i64 %stackpointer)
  ret void
}

attributes #1 = { "gc-leaf-function" nounwind readnone }

Note that the target triple is x86_64-pc-windows-msvc.

When I test this, the values that come from reading RSP are never in the address space of the module. Like, not even close.

As far as I can tell, this should work, and I'm a little stymied as to why I'm getting back garbage. Do I misunderstand the read_register call here?

Thanks,
Jordan


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Passing stack pointer to statepoint-gc

David Jones via llvm-dev
In reply to this post by David Jones via llvm-dev

Yes, program counter.  Also known as instruction pointer.  On X86-64, RIP register.


Philip


On 11/8/18 10:48 AM, Jordan Rudd wrote:
Program counter?

From: llvm-dev [hidden email] on behalf of Jordan Rudd via llvm-dev [hidden email]
Sent: Thursday, November 8, 2018 10:47 AM
To: Philip Reames; [hidden email]
Subject: Re: [llvm-dev] Passing stack pointer to statepoint-gc
 
Sorry, what does "PC" mean here?

From: Philip Reames [hidden email]
Sent: Thursday, November 8, 2018 7:27 AM
To: Jordan Rudd; [hidden email]
Subject: Re: [llvm-dev] Passing stack pointer to statepoint-gc
 

Jordon,


First of all, StackMaps are keyed by PC, not by SP.  Each entry corresponds to given location within the generated code. 


This isn't something you want to do in generated code.  Your runtime should be responsible for this.  If you support stack walking or back traces for any purpose, you should already have the code to identify the PC for a suspended frame on the stack.


If you don't, the easiest approach will be to use a assembly stub between your generated code and your C/C++ runtime code which grabs the PC from the stack, and moves it into an argument register.


Philip


On 11/7/18 5:22 PM, Jordan Rudd via llvm-dev wrote:
Hi,

I'm trying to use the statepoint-example strategy to build a simple garbage collector. After using the PlaceSafepoints and RewriteStatepointsForGC passes, I can successfully generate a stack map in my binary and call into my runtime's gc poll.

As far as I can tell, I need the stack pointer at the point of the poll to find the correct frame in the stack map. I'm having trouble doing that.

One library I looked at online (statepoint-utils) simply defines a helper function written in assembly that pushes the RSP register to RDI before calling into the runtime, so that the runtime gc polling function can read it as a parameter.

I was trying to do the same thing except in llvm, so from my gc.safepoint_poll definition, I tried adding these lines:

declare void @runtime_safepoint_poll(i64)
declare i64 @llvm.read_register.i64(metadata) #1
!0 = !{!"rsp\00"}

; Read the stack pointer and pass it to our polling function (assumes x64)
define void @gc.safepoint_poll() {
  %stackpointer = call i64 @llvm.read_register.i64(metadata !0)
  call void @runtime_safepoint_poll(i64 %stackpointer)
  ret void
}

attributes #1 = { "gc-leaf-function" nounwind readnone }

Note that the target triple is x86_64-pc-windows-msvc.

When I test this, the values that come from reading RSP are never in the address space of the module. Like, not even close.

As far as I can tell, this should work, and I'm a little stymied as to why I'm getting back garbage. Do I misunderstand the read_register call here?

Thanks,
Jordan


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev