summaryrefslogtreecommitdiff
path: root/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
diff options
context:
space:
mode:
authorTor Lillqvist <tlillqvist@novell.com>2011-01-28 18:24:01 +0200
committerTor Lillqvist <tlillqvist@novell.com>2011-01-28 18:41:07 +0200
commit75e02ab302970290758f121364b96cdafdc95b2e (patch)
tree469c08e94264565acb8dbe0e43097f6e6e25aa39 /bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
parent96b1611644da542b23eb0a78744be320eb2e8b54 (diff)
Let's use a shared privateSnippetExecutor() approach as on x64 Linux
It simplifies function table and unwinding info management, as those are now static for the privateSnippetExecutor() function in call.asm. Even if it is slightly ugly to have to poke in more instructions in codeSnippet(). Out privateSnippetExecutor() is much simpler than the x64 Linux one, thanks to the simpler calling convention.
Diffstat (limited to 'bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx')
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx135
1 files changed, 66 insertions, 69 deletions
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
index 22e0c7467e15..38d48241d02c 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
@@ -228,10 +228,12 @@ static inline typelib_TypeClass cpp2uno_call(
//==================================================================================================
extern "C" typelib_TypeClass cpp_vtable_call(
- sal_Int32 nFunctionIndex,
- sal_Int32 nVtableOffset,
+ sal_Int64 nOffsetAndIndex,
void ** pStack )
{
+ sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF);
+ sal_Int32 nVtableOffset = ((nOffsetAndIndex >> 32) & 0xFFFFFFFF);
+
// pStack points to space for return value, after which
// follows our return address (uninteresting) then the spilled
// integer or floating-point register parameters from the call to
@@ -372,89 +374,84 @@ extern "C" typelib_TypeClass cpp_vtable_call(
}
//==================================================================================================
-extern "C" {
-
-// These are actually addresses in the code compiled from codeSnippet.asm
-extern char
- fp_spill_templates,
- fp_spill_templates_end,
- trampoline_template,
- trampoline_template_function_table,
- trampoline_template_spill_params,
- trampoline_template_spill_params_end,
- trampoline_template_function_index,
- trampoline_template_vtable_offset,
- trampoline_template_cpp_vtable_call,
- trampoline_template_end;
-}
-// Just the code
-int const codeSnippetSize =
- (int) (&trampoline_template_end - &trampoline_template);
+int const codeSnippetSize = 48;
+
+extern "C" char privateSnippetExecutor;
// This function generates the code that acts as a proxy for the UNO function to be called.
// The generated code does the following:
-// - Save register parametrs.
+// - Spills register parameters on stack
+// - Loads functionIndex and vtableOffset into scratch registers
+// - Jumps to privateSnippetExecutor
unsigned char * codeSnippet(
unsigned char * code,
char param_kind[4],
- sal_Int32 functionIndex,
- sal_Int32 vtableOffset,
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
bool bHasHiddenParam )
{
- OSL_ASSERT( (&fp_spill_templates_end - &fp_spill_templates) ==
- (&trampoline_template_spill_params_end - &trampoline_template_spill_params) );
-
- OSL_ASSERT( ((&fp_spill_templates_end - &fp_spill_templates) / 4) * 4 ==
- (&fp_spill_templates_end - &fp_spill_templates) );
+ sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
+ unsigned char *p = code;
if ( bHasHiddenParam )
- functionIndex |= 0x80000000;
-
- int const one_spill_instruction_size =
- (int) ((&fp_spill_templates_end - &fp_spill_templates)) / 4;
+ nOffsetAndIndex |= 0x80000000;
- memcpy( code, &trampoline_template, codeSnippetSize );
-
- for (int i = 0; i < 4; ++i)
+ // Spill parameters
+ if ( param_kind[0] == CPPU_CURRENT_NAMESPACE::REGPARAM_INT )
{
- if ( param_kind[i] == CPPU_CURRENT_NAMESPACE::REGPARAM_FLT )
- {
- memcpy (&trampoline_template_spill_params + i*one_spill_instruction_size,
- &fp_spill_templates + i*one_spill_instruction_size,
- one_spill_instruction_size);
- }
+ // mov qword ptr 8[rsp], rcx
+ *p++ = 0x48; *p++ = 0x89; *p++ = 0x4C; *p++ = 0x24; *p++ = 0x08;
+ }
+ else
+ {
+ // movsd qword ptr 8[rsp], xmm0
+ *p++ = 0xF2; *p++ = 0x0F; *p++ = 0x11; *p++ = 0x44; *p++ = 0x24; *p++ = 0x08;
+ }
+ if ( param_kind[1] == CPPU_CURRENT_NAMESPACE::REGPARAM_INT )
+ {
+ // mov qword ptr 16[rsp], rdx
+ *p++ = 0x48; *p++ = 0x89; *p++ = 0x54; *p++ = 0x24; *p++ = 0x10;
}
+ else
+ {
+ // movsd qword ptr 16[rsp], xmm1
+ *p++ = 0xF2; *p++ = 0x0F; *p++ = 0x11; *p++ = 0x4C; *p++ = 0x24; *p++ = 0x10;
+ }
+ if ( param_kind[2] == CPPU_CURRENT_NAMESPACE::REGPARAM_INT )
+ {
+ // mov qword ptr 24[rsp], r8
+ *p++ = 0x4C; *p++ = 0x89; *p++ = 0x44; *p++ = 0x24; *p++ = 0x18;
+ }
+ else
+ {
+ // movsd qword ptr 24[rsp], xmm2
+ *p++ = 0xF2; *p++ = 0x0F; *p++ = 0x11; *p++ = 0x54; *p++ = 0x24; *p++ = 0x18;
+ }
+ if ( param_kind[3] == CPPU_CURRENT_NAMESPACE::REGPARAM_INT )
+ {
+ // mov qword ptr 32[rsp], r9
+ *p++ = 0x4C;*p++ = 0x89; *p++ = 0x4C; *p++ = 0x24; *p++ = 0x20;
+ }
+ else
+ {
+ // movsd qword ptr 32[rsp], xmm3
+ *p++ = 0xF2; *p++ = 0x0F; *p++ = 0x11; *p++ = 0x5C; *p++ = 0x24; *p++ = 0x20;
+ }
+
+ // mov rcx, nOffsetAndIndex
+ *p++ = 0x48; *p++ = 0xB9;
+ *((sal_uInt64 *)p) = nOffsetAndIndex; p += 8;
+
+ // mov r11, privateSnippetExecutor
+ *p++ = 0x49; *p++ = 0xBB;
+ *((void **)p) = &privateSnippetExecutor; p += 8;
+
+ // jmp r11
+ *p++ = 0x41; *p++ = 0xFF; *p++ = 0xE3;
- ((sal_uInt64*) (code + (&trampoline_template_function_index
- - &trampoline_template)))[-1] =
- functionIndex;
- ((sal_uInt64*) (code + (&trampoline_template_vtable_offset
- - &trampoline_template)))[-1] =
- vtableOffset;
- ((void**) (code + (&trampoline_template_cpp_vtable_call
- - &trampoline_template)))[-1] =
- cpp_vtable_call;
-
- // Add unwind data for the dynamically generated function by
- // calling RtlAddFunctionTable().
-
- // The unwind data is inside the function code, at a fixed offset
- // from the function start. See codeSnippet.asm. Actually this is
- // unnecessarily complex, we could as well just allocate the
- // function table dynamically. But it doesn't hurt either, I
- // think.
-
- // The real problem now is that we need to remove the unwind data
- // with RtlDeleteFunctionTable() in freeExec() in
- // vtablefactory.cxx. See comment there.
-
- RUNTIME_FUNCTION *pFunTable =
- (RUNTIME_FUNCTION *) (code + (&trampoline_template_function_table
- - &trampoline_template));
-
- RtlAddFunctionTable( pFunTable, 1, (DWORD64) code );
+ OSL_ASSERT( p < code + codeSnippetSize );
return code + codeSnippetSize;
}