From 45689dbfe6bc9561c07dbcf93b83d7dae3703b01 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 10 May 2010 01:38:34 -0400 Subject: [PATCH] compiler: simplify ##unbox-small/large-struct by emitting an ##unbox-any-c-ptr first --- basis/compiler/cfg/builder/alien/alien.factor | 5 ++++- .../cfg/instructions/instructions.factor | 4 ++-- basis/cpu/x86/32/32.factor | 16 +++++++-------- basis/cpu/x86/64/64.factor | 20 ++++++------------- vm/alien.cpp | 11 ---------- vm/alien.hpp | 1 - vm/vm.hpp | 1 - 7 files changed, 19 insertions(+), 39 deletions(-) diff --git a/basis/compiler/cfg/builder/alien/alien.factor b/basis/compiler/cfg/builder/alien/alien.factor index d098d665dc..bf674fa9b9 100644 --- a/basis/compiler/cfg/builder/alien/alien.factor +++ b/basis/compiler/cfg/builder/alien/alien.factor @@ -84,7 +84,9 @@ M: long-long-type unbox-parameter unboxer>> ##unbox-long-long ; M: struct-c-type unbox-parameter - [ ##unbox-large-struct ] [ base-type unbox-parameter ] if-value-struct ; + [ [ ^^unbox-any-c-ptr ] 2dip ##unbox-large-struct ] + [ base-type unbox-parameter ] + if-value-struct ; : unbox-parameters ( offset node -- ) parameters>> swap @@ -271,6 +273,7 @@ M: long-long-type unbox-return [ f ] dip unboxer>> ##unbox-long-long ; M: struct-c-type unbox-return + [ ^^unbox-any-c-ptr ] dip [ ##unbox-small-struct ] [ ##unbox-large-struct ] if-small-struct ; M: #alien-callback emit-node diff --git a/basis/compiler/cfg/instructions/instructions.factor b/basis/compiler/cfg/instructions/instructions.factor index ce63a03503..36e840fc9e 100644 --- a/basis/compiler/cfg/instructions/instructions.factor +++ b/basis/compiler/cfg/instructions/instructions.factor @@ -637,11 +637,11 @@ use: src/tagged-rep literal: n unboxer ; INSN: ##unbox-large-struct -use: src/tagged-rep +use: src/int-rep literal: n c-type ; INSN: ##unbox-small-struct -use: src/tagged-rep +use: src/int-rep literal: c-type ; INSN: ##prepare-box-struct ; diff --git a/basis/cpu/x86/32/32.factor b/basis/cpu/x86/32/32.factor index ab3ac4788e..bb091a2fe7 100755 --- a/basis/cpu/x86/32/32.factor +++ b/basis/cpu/x86/32/32.factor @@ -218,32 +218,30 @@ M:: x86.32 %unbox-long-long ( src n func -- ) ] when* ; M: x86 %unbox-small-struct ( src size -- ) - [ "alien_offset" call-unbox-func ] + [ [ EAX ] dip int-rep %copy ] [ heap-size 4 > [ EDX EAX 4 [+] MOV ] when EAX EAX [] MOV ] bi* ; M:: x86.32 %unbox-large-struct ( src n c-type -- ) - EAX src tagged-rep %copy - ! Compute destination address + EAX src int-rep %copy EDX n local@ LEA - 12 save-vm-ptr 8 stack@ c-type heap-size MOV - 4 stack@ EDX MOV - 0 stack@ EAX MOV - "to_value_struct" f %alien-invoke ; + 4 stack@ EAX MOV + 0 stack@ EDX MOV + "memcpy" "libc" load-library %alien-invoke ; M: x86.32 %alien-indirect ( src -- ) ?spill-slot CALL ; M: x86.32 %begin-callback ( -- ) 0 save-vm-ptr - ESP 4 [+] 0 MOV + 4 stack@ 0 MOV "begin_callback" f %alien-invoke ; M: x86.32 %alien-callback ( quot -- ) - EAX swap %load-reference + [ EAX ] dip %load-reference EAX quot-entry-point-offset [+] CALL ; M: x86.32 %end-callback ( -- ) diff --git a/basis/cpu/x86/64/64.factor b/basis/cpu/x86/64/64.factor index c55d02e654..8da9b6ac17 100644 --- a/basis/cpu/x86/64/64.factor +++ b/basis/cpu/x86/64/64.factor @@ -134,26 +134,18 @@ M:: x86.64 %unbox ( src n rep func -- ) } case ; M:: x86.64 %unbox-small-struct ( src c-type -- ) - param-reg-0 src tagged-rep %copy - param-reg-1 %mov-vm-ptr - "alien_offset" f %alien-invoke - ! Move alien_offset() return value to R11 so that we don't - ! clobber it. - R11 RAX MOV + ! Move src to R11 so that we don't clobber it. + R11 src int-rep %copy [ c-type flatten-struct-type [ %unbox-struct-field ] each-index ] with-return-regs ; M:: x86.64 %unbox-large-struct ( src n c-type -- ) - param-reg-0 src tagged-rep %copy - ! Load destination address into param-reg-1 - param-reg-1 n param@ LEA - ! Load structure size into param-reg-2 + param-reg-1 src int-rep %copy + param-reg-0 n param@ LEA param-reg-2 c-type heap-size MOV - param-reg-3 %mov-vm-ptr - ! Copy the struct to the C stack - "to_value_struct" f %alien-invoke ; + "memcpy" "libc" load-library %alien-invoke ; : load-return-value ( rep -- ) [ [ 0 ] dip reg-class-of cdecl param-reg ] @@ -226,7 +218,7 @@ M: x86.64 %begin-callback ( -- ) "begin_callback" f %alien-invoke ; M: x86.64 %alien-callback ( quot -- ) - param-reg-0 swap %load-reference + [ param-reg-0 ] dip %load-reference param-reg-0 quot-entry-point-offset [+] CALL ; M: x86.64 %end-callback ( -- ) diff --git a/vm/alien.cpp b/vm/alien.cpp index 5354c959ae..6d6199b6bc 100755 --- a/vm/alien.cpp +++ b/vm/alien.cpp @@ -187,17 +187,6 @@ VM_C_API char *alien_offset(cell obj, factor_vm *parent) return parent->alien_offset(obj); } -/* For FFI calls passing structs by value. Cannot allocate */ -void factor_vm::to_value_struct(cell src, void *dest, cell size) -{ - memcpy(dest,alien_offset(src),size); -} - -VM_C_API void to_value_struct(cell src, void *dest, cell size, factor_vm *parent) -{ - return parent->to_value_struct(src,dest,size); -} - /* For FFI callbacks receiving structs by value */ cell factor_vm::from_value_struct(void *src, cell size) { diff --git a/vm/alien.hpp b/vm/alien.hpp index add6f4ba72..2b530c6b83 100755 --- a/vm/alien.hpp +++ b/vm/alien.hpp @@ -4,7 +4,6 @@ namespace factor VM_C_API char *alien_offset(cell object, factor_vm *vm); VM_C_API char *pinned_alien_offset(cell object, factor_vm *vm); VM_C_API cell allot_alien(void *address, factor_vm *vm); -VM_C_API void to_value_struct(cell src, void *dest, cell size, factor_vm *vm); VM_C_API cell from_value_struct(void *src, cell size, factor_vm *vm); VM_C_API cell from_small_struct(cell x, cell y, cell size, factor_vm *vm); VM_C_API cell from_medium_struct(cell x1, cell x2, cell x3, cell x4, cell size, factor_vm *vm); diff --git a/vm/vm.hpp b/vm/vm.hpp index bfe105e67d..8a3ee56e27 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -615,7 +615,6 @@ struct factor_vm void primitive_dlclose(); void primitive_dll_validp(); char *alien_offset(cell obj); - void to_value_struct(cell src, void *dest, cell size); cell from_value_struct(void *src, cell size); cell from_small_struct(cell x, cell y, cell size); cell from_medium_struct(cell x1, cell x2, cell x3, cell x4, cell size);