rt: Inline get_sp_limit/set_sp_limit/get_sp for x86_64.
This commit is contained in:
parent
f54adca7c9
commit
d1778767cc
29
src/rt/arch/arm/sp.h
Normal file
29
src/rt/arch/arm/sp.h
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Getting the stack pointer and getting/setting sp limit.
|
||||
|
||||
#ifndef SP_H
|
||||
#define SP_H
|
||||
|
||||
#include "../../rust_globals.h"
|
||||
|
||||
// Gets a pointer to the vicinity of the current stack pointer
|
||||
extern "C" uintptr_t get_sp();
|
||||
|
||||
// Gets the pointer to the end of the Rust stack from a platform-
|
||||
// specific location in the thread control block
|
||||
extern "C" CDECL uintptr_t get_sp_limit();
|
||||
|
||||
// Records the pointer to the end of the Rust stack in a platform-
|
||||
// specific location in the thread control block
|
||||
extern "C" CDECL void record_sp_limit(void *limit);
|
||||
|
||||
#endif
|
29
src/rt/arch/i386/sp.h
Normal file
29
src/rt/arch/i386/sp.h
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Getting the stack pointer and getting/setting sp limit.
|
||||
|
||||
#ifndef SP_H
|
||||
#define SP_H
|
||||
|
||||
#include "../../rust_globals.h"
|
||||
|
||||
// Gets a pointer to the vicinity of the current stack pointer
|
||||
extern "C" uintptr_t get_sp();
|
||||
|
||||
// Gets the pointer to the end of the Rust stack from a platform-
|
||||
// specific location in the thread control block
|
||||
extern "C" CDECL uintptr_t get_sp_limit();
|
||||
|
||||
// Records the pointer to the end of the Rust stack in a platform-
|
||||
// specific location in the thread control block
|
||||
extern "C" CDECL void record_sp_limit(void *limit);
|
||||
|
||||
#endif
|
29
src/rt/arch/mips/sp.h
Normal file
29
src/rt/arch/mips/sp.h
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Getting the stack pointer and getting/setting sp limit.
|
||||
|
||||
#ifndef SP_H
|
||||
#define SP_H
|
||||
|
||||
#include "../../rust_globals.h"
|
||||
|
||||
// Gets a pointer to the vicinity of the current stack pointer
|
||||
extern "C" uintptr_t get_sp();
|
||||
|
||||
// Gets the pointer to the end of the Rust stack from a platform-
|
||||
// specific location in the thread control block
|
||||
extern "C" CDECL uintptr_t get_sp_limit();
|
||||
|
||||
// Records the pointer to the end of the Rust stack in a platform-
|
||||
// specific location in the thread control block
|
||||
extern "C" CDECL void record_sp_limit(void *limit);
|
||||
|
||||
#endif
|
@ -1,52 +0,0 @@
|
||||
.text
|
||||
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
#define RECORD_SP_LIMIT _record_sp_limit
|
||||
#define GET_SP_LIMIT _get_sp_limit
|
||||
#define GET_SP _get_sp
|
||||
#else
|
||||
#define RECORD_SP_LIMIT record_sp_limit
|
||||
#define GET_SP_LIMIT get_sp_limit
|
||||
#define GET_SP get_sp
|
||||
#endif
|
||||
|
||||
.globl RECORD_SP_LIMIT
|
||||
.globl GET_SP_LIMIT
|
||||
.globl GET_SP
|
||||
|
||||
#if defined(__linux__)
|
||||
RECORD_SP_LIMIT:
|
||||
movq %rdi, %fs:112
|
||||
ret
|
||||
#elif defined(__APPLE__)
|
||||
RECORD_SP_LIMIT:
|
||||
movq $0x60+90*8, %rsi
|
||||
movq %rdi, %gs:(%rsi)
|
||||
ret
|
||||
#elif defined(__FreeBSD__)
|
||||
RECORD_SP_LIMIT:
|
||||
movq %rdi, %fs:24
|
||||
ret
|
||||
#else
|
||||
RECORD_SP_LIMIT:
|
||||
ret
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
GET_SP_LIMIT:
|
||||
movq %fs:112, %rax
|
||||
ret
|
||||
#elif defined(__APPLE__)
|
||||
GET_SP_LIMIT:
|
||||
movq $0x60+90*8, %rsi
|
||||
movq %gs:(%rsi), %rax
|
||||
ret
|
||||
#elif defined(__FreeBSD__)
|
||||
GET_SP_LIMIT:
|
||||
movq %fs:24, %rax
|
||||
ret
|
||||
#endif
|
||||
|
||||
GET_SP:
|
||||
movq %rsp, %rax
|
||||
ret
|
71
src/rt/arch/x86_64/sp.h
Normal file
71
src/rt/arch/x86_64/sp.h
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Getting the stack pointer and getting/setting sp limit.
|
||||
|
||||
#ifndef SP_H
|
||||
#define SP_H
|
||||
|
||||
#include "../../rust_globals.h"
|
||||
|
||||
// Gets a pointer to the vicinity of the current stack pointer
|
||||
extern "C" ALWAYS_INLINE uintptr_t get_sp() {
|
||||
uintptr_t sp;
|
||||
asm volatile (
|
||||
"movq %%rsp, %0"
|
||||
: "=m"(sp));
|
||||
return sp;
|
||||
}
|
||||
|
||||
// Gets the pointer to the end of the Rust stack from a platform-
|
||||
// specific location in the thread control block
|
||||
extern "C" CDECL ALWAYS_INLINE uintptr_t get_sp_limit() {
|
||||
uintptr_t limit;
|
||||
|
||||
#if defined(__linux__)
|
||||
asm volatile (
|
||||
"movq %%fs:112, %0"
|
||||
: "=r"(limit));
|
||||
#elif defined(__APPLE__)
|
||||
asm volatile (
|
||||
"movq $0x60+90*8, %%rsi\n\t"
|
||||
"movq %%gs:(%%rsi), %0"
|
||||
: "=r"(limit)
|
||||
:: "rsi");
|
||||
#elif defined(__FreeBSD__)
|
||||
asm volatile (
|
||||
"movq %%fs:24, %0"
|
||||
: "=r"(limit));
|
||||
#endif
|
||||
|
||||
return limit;
|
||||
}
|
||||
|
||||
// Records the pointer to the end of the Rust stack in a platform-
|
||||
// specific location in the thread control block
|
||||
extern "C" CDECL ALWAYS_INLINE void record_sp_limit(void *limit) {
|
||||
#if defined(__linux__)
|
||||
asm volatile (
|
||||
"movq %0, %%fs:112"
|
||||
:: "r"(limit));
|
||||
#elif defined(__APPLE__)
|
||||
asm volatile (
|
||||
"movq $0x60+90*8, %%rsi\n\t"
|
||||
"movq %0, %%gs:(%%rsi)"
|
||||
:: "r"(limit)
|
||||
: "rsi");
|
||||
#elif defined(__FreeBSD__)
|
||||
asm volatile (
|
||||
"movq %0, %%fs:24"
|
||||
:: "r"(limit));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
@ -11,6 +11,22 @@
|
||||
#ifndef RUST_GLOBALS_H
|
||||
#define RUST_GLOBALS_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
#define INLINE inline
|
||||
#elif defined(_MSC_VER) || defined(__GNUC__)
|
||||
#define INLINE __inline__
|
||||
#else
|
||||
#define INLINE inline
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define ALWAYS_INLINE __attribute((always_inline)) INLINE
|
||||
#elif defined(_MSC_VER)
|
||||
#define ALWAYS_INLINE __forceinline
|
||||
#else
|
||||
#define ALWAYS_INLINE INLINE
|
||||
#endif
|
||||
|
||||
#ifndef __STDC_LIMIT_MACROS
|
||||
#define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
|
@ -118,6 +118,7 @@
|
||||
#include "rust_stack.h"
|
||||
#include "rust_type.h"
|
||||
#include "rust_sched_loop.h"
|
||||
#include "sp.h"
|
||||
|
||||
// The amount of extra space at the end of each stack segment, available
|
||||
// to the rt, compiler and dynamic linker for running small functions
|
||||
@ -419,15 +420,6 @@ template <typename T> struct task_owned {
|
||||
}
|
||||
};
|
||||
|
||||
// This stuff is on the stack-switching fast path
|
||||
|
||||
// Records the pointer to the end of the Rust stack in a platform-
|
||||
// specific location in the thread control block
|
||||
extern "C" CDECL void record_sp_limit(void *limit);
|
||||
extern "C" CDECL uintptr_t get_sp_limit();
|
||||
// Gets a pointer to the vicinity of the current stack pointer
|
||||
extern "C" uintptr_t get_sp();
|
||||
|
||||
// This is the function that switches between the C and the Rust stack by
|
||||
// calling another function with a single void* argument while changing the
|
||||
// stack pointer. It has a funny name because gdb doesn't normally like to
|
||||
@ -600,9 +592,6 @@ rust_task::prev_stack() {
|
||||
record_stack_limit();
|
||||
}
|
||||
|
||||
extern "C" CDECL void
|
||||
record_sp_limit(void *limit);
|
||||
|
||||
// The LLVM-generated segmented-stack function prolog compares the amount of
|
||||
// stack needed for each frame to the end-of-stack pointer stored in the
|
||||
// TCB. As an optimization, when the frame size is less than 256 bytes, it
|
||||
|
Loading…
x
Reference in New Issue
Block a user