x86-64: tweak #+mark-region-gc for presumptive static space relocation

The main problem presented by #+mark-region-gc (or #-immobile-space) is use of
of hardwired addresses for linkage tables, both lisp and alien calling.
This patch remedies that by referencing linkage entries off NULL-TN.

Some immobile-space hacks are removed from the machine-independent pieces
of coreparse and instead done in a *-arch.c file which has a new function
named coreparse_alloc_space() that is intended to be customized as needed.
The basic implementation remains in coreparse for other architectures.

This change still does not actually allow relocating static space, and in fact
takes a step backwards by disabling the elf-sans-immobile test until I finish
relocatability. However in triaging the current state, I discovered a more
urgent concern: as static space is of variable size based on dynamic-space and
hence the GC card table size, and not made by allocate_hardwired_spaces(),
is it _less_ likely that the OS will place it as requested.
So that becomes the most important issue to resolve at the moment.
This commit is contained in:
Douglas Katzman 2025-04-12 22:03:24 -04:00
parent 2a2879e1ce
commit b219fb32f5
19 changed files with 260 additions and 135 deletions

View file

@ -13,10 +13,7 @@
#-sb-assembling ; avoid redefinition warning
(macrolet ((static-fun-addr (name)
#-immobile-code
`(progn
(inst mov rax-tn (thread-slot-ea sb-vm::thread-linkage-table-slot))
(ea (make-fixup ,name :linkage-cell) rax-tn))
#-immobile-code `(ea (make-fixup ,name :linkage-cell) null-tn)
;; Caution: this looks like it jumps to the linkage cell's address,
;; and that is indeed what it would do if it were not for the fact that
;; genesis recognizes that this isn't right, and instead does what you mean.

View file

@ -56,7 +56,7 @@
(define-alien-variable ("TEXT_SPACE_START" sb-vm:text-space-start) sb-kernel::os-vm-size-t)
#+immobile-space
#+(or x86-64 immobile-space)
(define-symbol-macro sb-vm:alien-linkage-space-start
(extern-alien "ALIEN_LINKAGE_SPACE_START" unsigned))

View file

@ -2380,12 +2380,15 @@ Legal values for OFFSET are -4, -8, -12, ..."
(sb-vm:fixup-code-object code-object after-header value kind flavor)
code-object)
(defun alien-linkage-table-note-symbol (symbol-name datap)
"Register a symbol and return its address in proto-linkage-table."
(sb-vm::alien-linkage-table-entry-address
(ensure-gethash (if datap (list symbol-name) symbol-name)
*cold-foreign-symbol-table*
(hash-table-count *cold-foreign-symbol-table*))))
(defun alien-linkage-table-note-symbol (symbol-name datap &optional (mode :address))
"Register a symbol and return its address or index in proto-linkage-table."
(let ((index
(ensure-gethash (if datap (list symbol-name) symbol-name)
*cold-foreign-symbol-table*
(hash-table-count *cold-foreign-symbol-table*))))
(case mode
(:address (sb-vm::alien-linkage-table-entry-address index))
(:index index))))
(defun foreign-symbols-to-core ()
(flet ((to-core (list transducer target-symbol)
@ -2993,6 +2996,10 @@ Legal values for OFFSET are -4, -8, -12, ..."
(:assembly-routine (lookup-assembler-reference name))
(:foreign (alien-linkage-table-note-symbol string nil))
(:foreign-dataref (alien-linkage-table-note-symbol string t))
(:alien-code-linkage-index
(alien-linkage-table-note-symbol string nil :index))
(:alien-data-linkage-index
(alien-linkage-table-note-symbol string t :index))
(:code-object (descriptor-bits code-obj))
#+sb-thread ; ENSURE-SYMBOL-TLS-INDEX isn't defined otherwise
(:symbol-tls-index (ensure-symbol-tls-index name))

View file

@ -82,7 +82,9 @@
((spaces (append `((read-only ,ro-space-size)
#+(and win32 x86-64)
(seh-data ,(symbol-value '+backend-page-bytes+) win64-seh-data-addr)
#-immobile-space (alien-linkage ,alien-linkage-space-size)
;; #+immobile-space implies a relocatable alien linkage space. And x86-64 always
;; has relocatable linkage tables
#-(or x86-64 immobile-space) (alien-linkage ,alien-linkage-space-size)
;; safepoint on 64-bit uses a relocatable trap page just below the card mark
;; table, which works nicely assuming a register is wired to the card table
#+(and sb-safepoint (not x86-64))

View file

@ -255,8 +255,8 @@
(:result-types system-area-pointer)
(:vop-var vop)
(:generator 2
#-immobile-space ; non-relocatable alien linkage table
(inst mov res (ea (make-fixup foreign-symbol :foreign-dataref)))
#-immobile-space
(inst mov res (ea (make-fixup foreign-symbol :alien-data-linkage-index) null-tn))
#+immobile-space ; relocatable alien linkage table
(cond ((code-immobile-p vop)
(inst mov res (rip-relative-ea (make-fixup foreign-symbol :foreign-dataref))))
@ -326,11 +326,11 @@
(:temporary (:sc unsigned-reg :offset r15-offset :from :eval :to :result) r15)
#+win32
(:ignore r15)
#+win32
(:temporary (:sc unsigned-reg :offset rbx-offset :from :eval :to :result) rbx)
(:ignore results)
(:vop-var vop)
(:generator 0
(progn rbx)
(emit-c-call vop rax c-symbol args varargsp
#+sb-safepoint pc-save
#+win32 rbx))
@ -392,7 +392,9 @@
(pseudo-atomic (:elide-if (not (call-out-pseudo-atomic-p vop)))
(inst call (if (tn-p fun)
fun
#-immobile-space (ea (make-fixup fun :foreign 8))
#-immobile-space
(progn (inst lea rbx-tn (ea (make-fixup fun :alien-code-linkage-index) null-tn))
rbx-tn)
#+immobile-space
(cond ((code-immobile-p vop) (make-fixup fun :foreign))
(t

View file

@ -51,6 +51,8 @@
:linkage-cell))))
(defun compute-linkage-cell (node name res)
#-immobile-space (inst lea res (ea (linkage-cell-fixup name node) null-tn))
#+immobile-space ; this is ironically worse than #-immobile-space
(cond ((code-immobile-p node)
(inst lea res (rip-relative-ea (linkage-cell-fixup name node))))
(t
@ -901,6 +903,9 @@
(inst* instruction (ea rax-tn)))
((code-immobile-p node)
(inst* instruction (rip-relative-ea (linkage-cell-fixup name node))))
#-immobile-space
(t (inst* instruction (ea (linkage-cell-fixup name node) null-tn)))
#+immobile-space ; again, this should not be worse than #-immobile-space, but it is
(t
;; get the linkage table base into RAX
(inst mov rax-tn (thread-slot-ea sb-vm::thread-linkage-table-slot))

View file

@ -3401,13 +3401,28 @@
(1- (ash 1 value)))
(:linkage-cell
(let ((index (ash value word-shift)))
#-immobile-space
(ecase kind
#+immobile-space (:rel32 (+ sb-vm::lisp-linkage-space-addr index))
(:abs32 ; implicitly has a base reg of NULL-TN
(let ((lt (+ (- sb-vm::alien-linkage-space-size)
(- (ash 1 (+ sb-vm::n-linkage-index-bits sb-vm:word-shift)))
(- sb-vm::nil-value-offset))))
(setf (signed-sap-ref-32 sap offset) (+ lt index)))
(return-from fixup-code-object)))
#+immobile-space
(ecase kind
(:rel32 (+ sb-vm::lisp-linkage-space-addr index))
(:abs32 index))))
(:assembly-routine
(if (eq kind :*abs32) (sb-vm::asm-routine-indirect-address value) value))
((:alien-code-linkage-index :alien-data-linkage-index)
(* value alien-linkage-table-entry-size))
#-immobile-space ; implicitly has a base reg of NULL-TN
(let ((lt (+ (- sb-vm::alien-linkage-space-size)
(- sb-vm::nil-value-offset)))
(index (* value alien-linkage-table-entry-size)))
(setf (signed-sap-ref-32 sap offset) (+ lt index))
(return-from fixup-code-object))
#+immobile-space (* value alien-linkage-table-entry-size))
(:layout-id ; layout IDs are signed quantities on x86-64
(setf (signed-sap-ref-32 sap offset) value)
(return-from fixup-code-object))

View file

@ -75,16 +75,15 @@
;;;; description of the target address space
;;; Static space:
;;;
;;; start |<- 4k ->|
;;; +----------------------|-------+---------+-----+--------+-
;;; | | asm | other | | |
;;; | other | code | popular | NIL | Safept | GC card
;;; | static | jmp | consts | | Trap | table
;;; | data | table | | | Page |
;;; +----------------------*-------+---------+-----+--------+-
;;; ^ freeptr end ^
;;; Linkage |
;;; Spaces | Static Space
;;; +--------------+----------------------|-------+---------+-----+--------+-
;;; | | | | asm | other | | |
;;; | Lisp | Alien | other | code | popular | NIL | Safept | GC card
;;; | | | static | jmp | consts | | Trap | table
;;; | 4 MB | 1 MB | data | table | | | Page |
;;; +--------------+----------------------*-------+---------+-----+--------+-
;;; ^ freeptr end ^
;;; R12 (GC-card-table-reg) = NIL
;;; R12 + 64 - lowtag_of(NIL) = GC cards
@ -136,16 +135,11 @@
(defconstant alien-linkage-table-growth-direction :up)
(defconstant alien-linkage-table-entry-size 16)
#+(and sb-xc-host (not immobile-space))
(defparameter lisp-linkage-space-addr #x1500000000) ; arbitrary
#+(and sb-xc-host immobile-space)
(progn
(defparameter lisp-linkage-space-addr
;; text space:
;; | ALIEN LINKAGE | LISP LINKAGE | CODE OBJECTS ...
;; |<------------->|<------------>| ....
(- text-space-start (* (ash 1 n-linkage-index-bits) 8)))
(defparameter alien-linkage-space-start (- lisp-linkage-space-addr alien-linkage-space-size)))
#+sb-xc-host
(progn (defparameter alien-linkage-space-start
(- (or #+immobile-space text-space-start static-space-start) alien-linkage-space-size))
(defparameter lisp-linkage-space-addr
(- alien-linkage-space-start (* 8 (ash 1 n-linkage-index-bits)))))
(defenum (:start 8)
halt-trap

View file

@ -498,6 +498,26 @@
(:qword (unboxed-constant-ref dstate addr disp))))
dstate))))))
;; Recognize [R12-disp] as a linkage table use (lisp or alien)
#-immobile-space
(when (and (eq (machine-ea-base value) sb-vm::card-table-reg)
(not (machine-ea-index value))
(minusp (machine-ea-disp value)))
(let* ((alien-end (- sb-vm::nil-value-offset))
(alien-start (- alien-end sb-vm:alien-linkage-space-size))
(lisp-start (- alien-start (ash 1 (+ sb-vm:n-linkage-index-bits 3))))
(disp (machine-ea-disp value)))
(cond ((<= lisp-start disp (1- alien-start))
(let ((name (linkage-addr->name (- disp lisp-start) :rel)))
(note (lambda (s) (format s "~S" name)) dstate))
(return-from print-mem-ref))
((<= alien-start disp (1- alien-end))
(let ((name (sb-impl::alien-linkage-index-to-name
(floor (- disp alien-start)
sb-vm:alien-linkage-table-entry-size))))
(note (lambda (s) (format s "&~A" name)) dstate))
(return-from print-mem-ref)))))
;; Recognize "[Rbase+disp]" as an alien linkage table reference if Rbase was
;; just loaded with the base address in the prior instruction.
(when (and (eql (machine-ea-base value)

View file

@ -327,3 +327,36 @@ void gcbarrier_patch_code(void* where, int nbits)
unsigned int mask = ~0x0000FC00; // 6 bits at position 10
*pc = (*pc & mask) | ((GENCGC_CARD_SHIFT + nbits - 1) << 10);
}
os_vm_address_t coreparse_alloc_space(int space_id, int attr,
os_vm_address_t addr, os_vm_size_t size)
{
__attribute__((unused)) int extra_request = 0;
#ifdef LISP_FEATURE_IMMOBILE_SPACE
if (space_id == IMMOBILE_TEXT_CORE_SPACE_ID) {
extra_request = ALIEN_LINKAGE_SPACE_SIZE;
size += extra_request;
addr -= extra_request; // try to put text space start where expected
}
#endif
if (size == 0) return addr;
#ifdef LISP_FEATURE_SB_SAFEPOINT
if (space_id == STATIC_CORE_SPACE_ID) {
// Allocate space for the safepoint page.
addr = os_alloc_gc_space(space_id, attr, addr - BACKEND_PAGE_BYTES, size + BACKEND_PAGE_BYTES) + BACKEND_PAGE_BYTES;
}
else
#endif
addr = os_alloc_gc_space(space_id, attr, addr, size);
if (!addr) lose("Can't allocate %#"OBJ_FMTX" bytes for space %d", size, space_id);
#ifdef LISP_FEATURE_IMMOBILE_SPACE
if (space_id == IMMOBILE_TEXT_CORE_SPACE_ID) {
ALIEN_LINKAGE_SPACE_START = (uword_t)addr;
addr += extra_request;
}
#endif
return addr;
}

View file

@ -678,36 +678,16 @@ void calc_immobile_space_bounds()
}
#endif
#ifdef LISP_FEATURE_LINKAGE_SPACE
#define LISP_LINKAGE_SPACE_SIZE (1<<(N_LINKAGE_INDEX_BITS+WORD_SHIFT))
#endif
#if defined LISP_FEATURE_IMMOBILE_SPACE && defined LISP_FEATURE_ARM64
#define LISP_LINKAGE_SPACE_SIZE 0
#endif
static os_vm_address_t reserve_space(int space_id, int attr,
os_vm_address_t addr, os_vm_size_t size)
#if defined LISP_FEATURE_X86_64 || defined LISP_FEATURE_ARM64
extern
os_vm_address_t coreparse_alloc_space(int space_id, int attr,
os_vm_address_t addr, os_vm_size_t size);
#else
static os_vm_address_t coreparse_alloc_space(int space_id, int attr,
os_vm_address_t addr, os_vm_size_t size)
{
#ifndef LISP_FEATURE_RELOCATABLE_STATIC_SPACE
/* temporary hack: spaces allocated by coreparse are assumed to be movable.
* immovable static space ought to have been reserved by allocate_hardwired_spaces()
* but it can't have been, because the allocation request must take into account the
* size of the GC card table, which isn't known until parsing the core.
* So this request has to be changed to not movable so that it fails if not
* placed as required */
if (space_id == STATIC_CORE_SPACE_ID) attr &= ~MOVABLE;
#endif
__attribute__((unused)) int extra_request = 0;
#ifdef LISP_FEATURE_IMMOBILE_SPACE
if (space_id == IMMOBILE_TEXT_CORE_SPACE_ID) {
extra_request = ALIEN_LINKAGE_SPACE_SIZE + LISP_LINKAGE_SPACE_SIZE;
size += extra_request;
addr -= extra_request; // compensate to try to put text space start where expected
}
#endif
if (size == 0) return addr;
// 64-bit already allocated a trap page when the GC card mark table was made
#if defined(LISP_FEATURE_SB_SAFEPOINT) && !defined(LISP_FEATURE_X86_64)
#ifdef LISP_FEATURE_SB_SAFEPOINT // this is only for 32-bit x86, I think
if (space_id == STATIC_CORE_SPACE_ID) {
// Allocate space for the safepoint page.
addr = os_alloc_gc_space(space_id, attr, addr - BACKEND_PAGE_BYTES, size + BACKEND_PAGE_BYTES) + BACKEND_PAGE_BYTES;
@ -716,15 +696,9 @@ static os_vm_address_t reserve_space(int space_id, int attr,
#endif
addr = os_alloc_gc_space(space_id, attr, addr, size);
if (!addr) lose("Can't allocate %#"OBJ_FMTX" bytes for space %d", size, space_id);
#ifdef LISP_FEATURE_IMMOBILE_SPACE
if (space_id == IMMOBILE_TEXT_CORE_SPACE_ID) {
ALIEN_LINKAGE_SPACE_START = (uword_t)addr;
linkage_space = (void*)((char*)addr + ALIEN_LINKAGE_SPACE_SIZE);
addr += extra_request;
}
#endif
return addr;
}
#endif
static __attribute__((unused)) uword_t corespace_checksum(uword_t* base, int nwords)
{
@ -772,13 +746,6 @@ process_directory(int count, struct ndir_entry *entry,
#endif
// unprotect the pages
os_protect((void*)TEXT_SPACE_START, text_space_size, OS_VM_PROT_ALL);
#ifdef LISP_FEATURE_IMMOBILE_SPACE
// ELF core without immobile space has alien linkage space below static space.
ALIEN_LINKAGE_SPACE_START =
(uword_t)os_alloc_gc_space(ALIEN_LINKAGE_TABLE_CORE_SPACE_ID, 0, 0,
ALIEN_LINKAGE_SPACE_SIZE);
#endif
}
#endif
@ -833,8 +800,8 @@ process_directory(int count, struct ndir_entry *entry,
#ifdef LISP_FEATURE_ASLR
addr = 0;
#endif
addr = (uword_t)reserve_space(id, sub_2gb_flag ? MOVABLE_LOW : MOVABLE,
(os_vm_address_t)addr, request);
addr = (uword_t)coreparse_alloc_space(id, sub_2gb_flag ? MOVABLE_LOW : MOVABLE,
(os_vm_address_t)addr, request);
switch (id) {
case PERMGEN_CORE_SPACE_ID:
PERMGEN_SPACE_START = addr;
@ -925,9 +892,6 @@ process_directory(int count, struct ndir_entry *entry,
#ifdef LISP_FEATURE_LINKAGE_SPACE
if (linkage_table_count) {
// Only #-immobile-space should allocate linkage space now,
// because otherwise it must be contiguous with text space.
if (linkage_space == 0) linkage_space = (void*)os_allocate(LISP_LINKAGE_SPACE_SIZE);
off_t filepos = file_offset + (1 + linkage_table_data_page) * os_vm_page_size;
gc_assert(os_reported_page_size);
// Linkage space is only 8-byte-aligned in an ELF core. It doesn't need more than that.
@ -1497,13 +1461,6 @@ load_core_file(char *file, os_vm_offset_t file_offset, int merge_core_pages)
if (stringlen != (sizeof build_id-1) || memcmp(ptr, build_id, stringlen))
lose("core was built for runtime \"%.*s\" but this is \"%s\"",
(int)stringlen, (char*)ptr, build_id);
#ifdef LISP_FEATURE_X86_64
spaces[STATIC_CORE_SPACE_ID].desired_size +=
# ifdef LISP_FEATURE_SB_SAFEPOINT
BACKEND_PAGE_BYTES + /* ridiculously oversized */
# endif
ALIGN_UP((1+gc_card_table_mask), os_reported_page_size);
#endif
break;
case STATIC_CONSTANTS_CORE_ENTRY_TYPE_CODE: {
int nwords = remaining_len;

View file

@ -58,9 +58,11 @@ lispobj *static_space_trailer_start;
lispobj *static_code_space_free_pointer;
#endif
#if defined LISP_FEATURE_X86_64 || defined LISP_FEATURE_IMMOBILE_SPACE
lispobj ALIEN_LINKAGE_SPACE_START;
#endif
#ifdef LISP_FEATURE_IMMOBILE_SPACE
lispobj *fixedobj_free_pointer;
lispobj ALIEN_LINKAGE_SPACE_START;
#endif
os_vm_address_t anon_dynamic_space_start;
// The end of immobile text mapped from disk, equivalently the starting address

View file

@ -110,9 +110,11 @@ extern lispobj *static_code_space_free_pointer;
#endif
extern lispobj *text_space_highwatermark;
#if defined LISP_FEATURE_X86_64 || defined LISP_FEATURE_IMMOBILE_SPACE
extern lispobj ALIEN_LINKAGE_SPACE_START;
#endif
#ifdef LISP_FEATURE_IMMOBILE_SPACE
extern lispobj *fixedobj_free_pointer;
extern lispobj ALIEN_LINKAGE_SPACE_START;
#endif
#define FIRST_USABLE_LINKAGE_ELT 1
extern lispobj *linkage_space;

View file

@ -92,11 +92,12 @@ bool allocate_hardwired_spaces(bool hard_failp)
unsigned size;
int id;
} preinit_spaces[] = {
#ifndef LISP_FEATURE_X86_64
// For x86-64, static space allocation request depends on dynamic space size,
// and linkage spaces (alien + lisp) are either placed at the start of
// text space if it exists, or below static space otherwise.
{ READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE, READ_ONLY_CORE_SPACE_ID },
#ifndef LISP_FEATURE_IMMOBILE_SPACE
{ ALIEN_LINKAGE_SPACE_START, ALIEN_LINKAGE_SPACE_SIZE, ALIEN_LINKAGE_TABLE_CORE_SPACE_ID },
#endif
#ifndef LISP_FEATURE_X86_64 // x86-64 static space allocation request depends on dynamic space size
{ STATIC_SPACE_START, STATIC_SPACE_SIZE, STATIC_CORE_SPACE_ID },
#endif
#ifdef LISP_FEATURE_DARWIN_JIT

View file

@ -37,6 +37,9 @@
#endif
#define ALIEN_LINKAGE_SPACE_END (ALIEN_LINKAGE_SPACE_START + ALIEN_LINKAGE_SPACE_SIZE)
#ifdef LISP_FEATURE_LINKAGE_SPACE
#define LISP_LINKAGE_SPACE_SIZE (1<<(N_LINKAGE_INDEX_BITS+WORD_SHIFT))
#endif
#if !defined(__ASSEMBLER__)
#include <stdbool.h>

View file

@ -784,4 +784,85 @@ lispobj call_into_lisp_first_time(lispobj fun, lispobj *args, int nargs) {
return call_into_lisp_first_time_(fun, args, nargs, get_sb_vm_thread());
}
/*
* On x86-64 we try to place the alien and lisp linkage tables in such a way
* that avoids extra load instructions when calling, but also allows those tables
* to be fully relocatable. It is best achieved by using PC-relative addressng,
* which works only for immobile text space. Failing that, we can place the
* linkage tables below NIL and use NIL-relative addressing.
* The core file makes no indication of the "effective size" of static space
* or text space, so we have to oversize them.
* It's a little confusing, so here are the possibilities:
*
* Supports | extra allocation amount
* Immobile | elfcode | text | static
* ---------|-----------------------------|-------------------------------------
* Yes | No | +AL +LL below | none
* Yes | Yes | n/a | +AL below, +GC cards above
* No | No | none | +AL+LL below, +GC cards above
* No | Yes | n/a | +AL below, +GC cards above
*
* AL = alien linkage
* LL = lisp linkage
* n/a means the call does not occur for that space
*
* For #+immobile-space we want to end up with text space having both linkage subspaces
* (unless code-in-ELF)
* | LISP LINKAGE | ALIEN LINKAGE | CODE OBJECTS ...
* |<------------>|<------------->| ....
* For code-in-ELF then the lisp linkage space was preallocated to a .bss section,
* so we only oversize the static space by the alien linkage space size.
* If there is no text space (i.e. for #-immobile-space) then the linkage tables
* are below static space.
*/
os_vm_address_t coreparse_alloc_space(int space_id, int attr,
os_vm_address_t addr, os_vm_size_t size)
{
if (size == 0) return addr;
/* temporary hack: spaces allocated by coreparse are assumed to be movable.
* immovable static space ought to have been reserved by allocate_hardwired_spaces()
* but it can't have been, because the allocation request must take into account the
* size of the GC card table, which isn't known until parsing the core.
* So this request has to be changed to not movable so that it fails if not
* placed as required */
if (space_id == STATIC_CORE_SPACE_ID) attr &= ~MOVABLE;
int extra_below = 0, extra_above = 0;
extern int lisp_code_in_elf();
#ifdef LISP_FEATURE_IMMOBILE_SPACE
# define LINKAGE_TABLE_CONTAINER IMMOBILE_TEXT_CORE_SPACE_ID
#else
# define LINKAGE_TABLE_CONTAINER STATIC_CORE_SPACE_ID
#endif
if (!lisp_code_in_elf()) { // a normal core
if (space_id == LINKAGE_TABLE_CONTAINER)
extra_below = LISP_LINKAGE_SPACE_SIZE + ALIEN_LINKAGE_SPACE_SIZE;
} else { // code-in-ELF core
if (space_id == STATIC_CORE_SPACE_ID)
extra_below = ALIEN_LINKAGE_SPACE_SIZE;
}
if (space_id == STATIC_CORE_SPACE_ID) {
extra_above =
# ifdef LISP_FEATURE_SB_SAFEPOINT // should just add 1 OS page but instead
BACKEND_PAGE_BYTES + // it's a ridiculously generous bump up
# endif
ALIGN_UP((1+gc_card_table_mask), os_reported_page_size);
}
addr -= extra_below; // endeavor to return the requested address as it was
size += extra_below + extra_above;
//fprintf(stderr, "requesting space for space_id %d, below=%x above=%x\n", space_id, extra_below, extra_above);
addr = os_alloc_gc_space(space_id, attr, addr, size);
if (!addr) lose("Can't allocate %#"OBJ_FMTX" bytes for space %d", size, space_id);
if (extra_below) { // it contains at least alien linkage if not also lisp linkage
if (extra_below > ALIEN_LINKAGE_SPACE_SIZE) linkage_space = (void*)addr;
addr += extra_below;
ALIEN_LINKAGE_SPACE_START = (uword_t)addr - ALIEN_LINKAGE_SPACE_SIZE;
}
return addr;
}
#include "x86-arch-shared.inc"

View file

@ -16,10 +16,10 @@
. ./subr.sh
run_sbcl <<EOF
#+(and linux x86-64 sb-thread)
(unless (member :immobile-space sb-impl:+internal-features+)
(exit :code 0)) ; proceed with test
(exit :code 2) ; otherwise skip the test
;#+(and linux x86-64 sb-thread)
;(unless (member :immobile-space sb-impl:+internal-features+)
; (exit :code 0)) ; proceed with test
(exit :code 2) ; otherwise skip the test
EOF
status=$?
if [ $status != 0 ]; then # test can't be executed

View file

@ -175,7 +175,7 @@
(c-call (find "os_deallocate" lines :test #'search)))
;; Depending on #+immobile-code it's either direct or memory indirect.
#+immobile-code (assert (search "CALL #x" c-call))
#-immobile-code (assert (search "CALL [#x" c-call))))
#-immobile-code (assert (search "LEA RBX, [R12-" c-call))))
(with-test (:name :set-symbol-value-imm)
(let (success)

View file

@ -145,10 +145,14 @@
;;; At execution time the function will have virtual address LOAD-ADDR.
#+x86-64
(defun list-textual-instructions (sap length core load-addr emit-cfi)
(let ((insts (simple-collect-inst-model sap length load-addr))
(alien-linkage-end
(+ (bounds-low (core-linkage-bounds core)) alien-linkage-space-size))
(result))
(let* ((insts (simple-collect-inst-model sap length load-addr))
(alien-linkage-bounds
(make-bounds (- (bounds-high (core-linkage-bounds core)) alien-linkage-space-size)
(bounds-high (core-linkage-bounds core))))
(lisp-linkage-bounds
(make-bounds (bounds-low (core-linkage-bounds core))
(bounds-low alien-linkage-bounds)))
(result))
(flet ((pc-relative-ea-p (x)
(when (consp x) (setq x (car x)))
(and (typep x 'machine-ea) (eq (machine-ea-base x) :rip)))
@ -167,40 +171,41 @@
(pc-relative-ea-p ea))
(cond ((and (integerp ea) (in-bounds-p ea (core-linkage-bounds core)))
(aver (eq (cadr inst) 'sb-x86-64-asm::call))
(aver (< ea alien-linkage-end)) ; CALL via alien linkage
(aver (in-bounds-p ea alien-linkage-bounds)) ; CALL via alien linkage
(aver (= inst-len 5))
(push (list* (car inst) 5 :call ea) result))
((pc-relative-ea-p ea)
(let* ((next-pc (+ load-addr (caadr insts)))
(ea (+ next-pc (ea-disp-of ea)))
(table-offset (- ea alien-linkage-end)))
(when (in-bounds-p ea (core-linkage-bounds core))
(cond ((< ea alien-linkage-end) ; alien linkage
(aver (= inst-len 7))
(let ((op (ecase (cadr inst)
(sb-x86-64-asm::mov :mov-gotpcrel)
(sb-x86-64-asm::lea :lea)))
(args (list ea (string-downcase (princ-to-string (third inst))))))
(push (list* (car inst) 7 op args) result)))
((eq (cadr inst) 'sb-x86-64-asm::lea)
(table-offset (- ea (bounds-low lisp-linkage-bounds))))
(cond ((in-bounds-p ea alien-linkage-bounds)
(aver (= inst-len 7))
(let ((op (ecase (cadr inst)
(sb-x86-64-asm::mov :mov-gotpcrel)
(sb-x86-64-asm::lea :lea)))
(args (list ea (string-downcase (princ-to-string (third inst))))))
(push (list* (car inst) 7 op args) result)))
((and (in-bounds-p ea lisp-linkage-bounds)
(eq (cadr inst) 'sb-x86-64-asm::lea))
;; Get ADDRESS of lisp linkage cell in stepping-enabled code
(aver (eq (third inst) (get-gpr :qword 0))) ; %rax
(aver (= inst-len 7))
(push (list* (car inst) 7 :lea (format nil "(fntbl+~d)(%rip),%rax"
table-offset))
result))
(t ; lisp CALL or JMP
(aver (= inst-len 6))
(let ((new-inst
(format nil "~a *(fntbl+~d)(%rip)"
(string-downcase (cadr inst))
table-offset)))
(push (list* (car inst) 6 :lispcall new-inst) result))))))))))))
(aver (eq (third inst) (get-gpr :qword 0))) ; %rax
(aver (= inst-len 7))
(push (list* (car inst) 7 :lea (format nil "(fntbl+~d)(%rip),%rax"
table-offset))
result))
((in-bounds-p ea lisp-linkage-bounds) ; lisp CALL or JMP
(aver (= inst-len 6))
(let ((new-inst
(format nil "~a *(fntbl+~d)(%rip)"
(string-downcase (cadr inst))
table-offset)))
(push (list* (car inst) 6 :lispcall new-inst) result)))))))))))
(nreverse result)))
(defun c-linkage-sym-from-addr (addr core)
(let ((entry-index (/ (- addr (bounds-low (core-linkage-bounds core)))
(core-alien-linkage-entry-size core))))
;; assumption: alien-linkage-table-growth-direction is :UP for the platform
(let* ((alien-ls-start (- (bounds-high (core-linkage-bounds core)) alien-linkage-space-size))
(entry-index (/ (- addr alien-ls-start) (core-alien-linkage-entry-size core))))
(setf (bit (core-alien-linkage-symbol-usedp core) entry-index) 1)
(let ((symbol (aref (core-alien-linkage-symbols core) entry-index)))
(if (listp symbol)
@ -1516,12 +1521,11 @@ lisp_fun_linkage_space: .zero ~:*~D
(%make-lisp-obj (logior (sap-int (sap+ (space-physaddr text-space spacemap)
code-offsets-vector-size))
other-pointer-lowtag)))
(alien-ls-start
(symbol-global-value
(find-target-symbol (package-id "SB-VM") "ALIEN-LINKAGE-SPACE-START"
spacemap)))
(alien-ls-start (- (space-addr (or text-space static-space))
alien-linkage-space-size))
(alien-ls-end (1- (+ alien-ls-start alien-linkage-space-size))))
(aver (<= (length *c-linkage-redirects*) (length c-linkage-vector)))
;; (format t "~&alien linkage range = ~x .. ~x~%" alien-ls-start alien-ls-end)
(dolist (x *c-linkage-redirects*)
(let* ((index (position (cdr x) (core-alien-linkage-symbols core)
:test (lambda (a b) (and (stringp b) (string= a b)))))