summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Forstall <brucefo@microsoft.com>2017-03-13 16:32:15 -0700
committerGitHub <noreply@github.com>2017-03-13 16:32:15 -0700
commitad8afe4f8c9537e8652ae35b301366d737bc1e04 (patch)
tree44fd7501fd93f2618b1ef0e4f8da38820b4715e6 /src
parent814a105864c35ca992ed1b332d72d9e6869519df (diff)
downloadcoreclr-ad8afe4f8c9537e8652ae35b301366d737bc1e04.tar.gz
coreclr-ad8afe4f8c9537e8652ae35b301366d737bc1e04.tar.bz2
coreclr-ad8afe4f8c9537e8652ae35b301366d737bc1e04.zip
Build Linux altjit for x86 and amd64 (#10120)
Enable Windows hosted, Linux target amd64 altjit With this change, we build a JIT that runs on Windows amd64 and targets Linux amd64, as an altjit named linuxnonjit.dll. This is useful for debugging, or generating asm code or diffs. You can even easily create Windows/non-Windows asm diffs (either to compare the asm, or compare the generated code size). For this to work, the JIT-EE interface method getSystemVAmd64PassStructInRegisterDescriptor() was changed to always be built in, by defining `FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF` in all AMD64 builds. The `_ITF` suffix indicates that this is functionality specific to implementing the JIT-EE interface contract. There were many places in the VM that used this interchangeably with `FEATURE_UNIX_AMD64_STRUCT_PASSING`. Now, `FEATURE_UNIX_AMD64_STRUCT_PASSING` means code in the VM needed to implement this feature, but not required to implement the JIT-EE interface contract. In particular, MethodTables compute and cache the "eightbyte" info of structs when loading a type. This is not done when only `FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF` is set, to avoid altering MethodTable behavior on non-Unix AMD64 builds. Instead, if `getSystemVAmd64PassStructInRegisterDescriptor()` is called on a non-Unix build (by the altjit), the `ClassifyEightBytes()` function is called, and nothing is cached. Hopefully (though it was hard for me to guarantee by observation), calling `ClassifyEightBytes()` does not have any side effects on MethodTables. It doesn't really matter, since if called for altjit, we don't care too much about running. The previously used `PLATFORM_UNIX` define is now insufficient. I introduced the `#define` macros `_HOST_UNIX_` to indicate the JIT being built will run on Unix, and `_TARGET_UNIX_` to indicate the JIT is generating code targeting Unix. Some things were converted to use the `UNIX_AMD64_ABI` define, which makes more sense.
Diffstat (limited to 'src')
-rw-r--r--src/debug/daccess/nidump.cpp4
-rw-r--r--src/jit/CMakeLists.txt7
-rw-r--r--src/jit/codegencommon.cpp2
-rw-r--r--src/jit/codegenlinear.h8
-rw-r--r--src/jit/codegenxarch.cpp18
-rw-r--r--src/jit/compiler.cpp10
-rw-r--r--src/jit/dll/CMakeLists.txt16
-rw-r--r--src/jit/ee_il_dll.cpp8
-rw-r--r--src/jit/emitxarch.cpp2
-rw-r--r--src/jit/jit.h32
-rw-r--r--src/jit/jitstd/type_traits.h5
-rw-r--r--src/jit/linuxnonjit/CMakeLists.txt71
-rw-r--r--src/jit/target.h20
-rw-r--r--src/jit/unwindamd64.cpp12
-rw-r--r--src/jit/utils.cpp6
-rw-r--r--src/jit/valuenum.h8
-rw-r--r--src/vm/callhelpers.cpp4
-rw-r--r--src/vm/class.h14
-rw-r--r--src/vm/jitinterface.cpp15
-rw-r--r--src/vm/methodtable.cpp2
-rw-r--r--src/vm/methodtable.h16
-rw-r--r--src/vm/methodtablebuilder.cpp16
-rw-r--r--src/vm/methodtablebuilder.h4
23 files changed, 196 insertions, 104 deletions
diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp
index b2663fe367..77c05b5801 100644
--- a/src/debug/daccess/nidump.cpp
+++ b/src/debug/daccess/nidump.cpp
@@ -5549,9 +5549,9 @@ NativeImageDumper::EnumMnemonics s_MTFlagsLow[] =
#if defined(FEATURE_HFA)
MTFLAG_ENTRY(IsHFA),
#endif // FEATURE_HFA
-#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
MTFLAG_ENTRY(IsRegStructPassed),
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
MTFLAG_ENTRY(IsByRefLike),
MTFLAG_ENTRY(UNUSED_ComponentSize_5),
MTFLAG_ENTRY(UNUSED_ComponentSize_6),
diff --git a/src/jit/CMakeLists.txt b/src/jit/CMakeLists.txt
index ea7de57233..8f2170dafa 100644
--- a/src/jit/CMakeLists.txt
+++ b/src/jit/CMakeLists.txt
@@ -4,9 +4,6 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include_directories("./jitstd")
include_directories("../inc")
-# Enable the following for UNIX altjit on Windows
-# add_definitions(-DALT_JIT)
-
if (CLR_CMAKE_TARGET_ARCH_AMD64 OR (CLR_CMAKE_TARGET_ARCH_I386 AND NOT CLR_CMAKE_PLATFORM_UNIX))
add_definitions(-DFEATURE_SIMD)
add_definitions(-DFEATURE_AVX_SUPPORT)
@@ -225,6 +222,10 @@ if ((CLR_CMAKE_PLATFORM_ARCH_I386 OR CLR_CMAKE_PLATFORM_ARCH_AMD64) AND WIN32)
# On x86, build RyuJIT/ARM32 cross-compiling altjit.
# On amd64, build RyuJIT/ARM64 cross-compiling altjit.
add_subdirectory(protononjit)
+
+ # Build Linux/x86-running-on-Windows altjit or
+ # Linux/AMD64-running-on-Windows altjit..
+ add_subdirectory(linuxnonjit)
endif ()
if (CLR_CMAKE_PLATFORM_ARCH_I386 AND WIN32)
diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp
index fde4a673e8..4a70b96f0b 100644
--- a/src/jit/codegencommon.cpp
+++ b/src/jit/codegencommon.cpp
@@ -9683,7 +9683,7 @@ void CodeGen::genFnEpilog(BasicBlock* block)
addrInfo.addr,
0, // argSize
EA_UNKNOWN // retSize
- FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(EA_UNKNOWN), // secondRetSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(EA_UNKNOWN), // secondRetSize
gcInfo.gcVarPtrSetCur,
gcInfo.gcRegGCrefSetCur,
gcInfo.gcRegByrefSetCur,
diff --git a/src/jit/codegenlinear.h b/src/jit/codegenlinear.h
index af545fe782..52b1f9ebe9 100644
--- a/src/jit/codegenlinear.h
+++ b/src/jit/codegenlinear.h
@@ -183,10 +183,10 @@ void genPutArgStkFieldList(GenTreePutArgStk* putArgStk);
void genPutStructArgStk(GenTreePutArgStk* treeNode);
-int genMove8IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
-int genMove4IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
-int genMove2IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
-int genMove1IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
+unsigned genMove8IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
+unsigned genMove4IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
+unsigned genMove2IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
+unsigned genMove1IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
void genStructPutArgRepMovs(GenTreePutArgStk* putArgStkNode);
void genStructPutArgUnroll(GenTreePutArgStk* putArgStkNode);
void genStoreRegToStackArg(var_types type, regNumber reg, int offset);
diff --git a/src/jit/codegenxarch.cpp b/src/jit/codegenxarch.cpp
index 7639e8bac1..4917e2cd9e 100644
--- a/src/jit/codegenxarch.cpp
+++ b/src/jit/codegenxarch.cpp
@@ -3225,7 +3225,7 @@ void CodeGen::genCodeForCpBlkRepMovs(GenTreeBlk* cpBlkNode)
// On x86, longTmpReg must be an xmm reg; on x64 it must be an integer register.
// This is checked by genStoreRegToStackArg.
//
-int CodeGen::genMove8IfNeeded(unsigned size, regNumber longTmpReg, GenTree* srcAddr, unsigned offset)
+unsigned CodeGen::genMove8IfNeeded(unsigned size, regNumber longTmpReg, GenTree* srcAddr, unsigned offset)
{
#ifdef _TARGET_X86_
instruction longMovIns = INS_movq;
@@ -3259,7 +3259,7 @@ int CodeGen::genMove8IfNeeded(unsigned size, regNumber longTmpReg, GenTree* srcA
// intTmpReg must be an integer register.
// This is checked by genStoreRegToStackArg.
//
-int CodeGen::genMove4IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
+unsigned CodeGen::genMove4IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
{
if ((size & 4) != 0)
{
@@ -3288,7 +3288,7 @@ int CodeGen::genMove4IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAd
// intTmpReg must be an integer register.
// This is checked by genStoreRegToStackArg.
//
-int CodeGen::genMove2IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
+unsigned CodeGen::genMove2IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
{
if ((size & 2) != 0)
{
@@ -3317,7 +3317,7 @@ int CodeGen::genMove2IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAd
// intTmpReg must be an integer register.
// This is checked by genStoreRegToStackArg.
//
-int CodeGen::genMove1IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
+unsigned CodeGen::genMove1IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
{
if ((size & 1) != 0)
@@ -3354,7 +3354,7 @@ void CodeGen::genStructPutArgUnroll(GenTreePutArgStk* putArgNode)
GenTreePtr dstAddr = putArgNode;
GenTreePtr src = putArgNode->gtOp.gtOp1;
- size_t size = putArgNode->getArgSize();
+ unsigned size = putArgNode->getArgSize();
assert(size <= CPBLK_UNROLL_LIMIT);
emitter* emit = getEmitter();
@@ -7183,7 +7183,7 @@ int CodeGenInterface::genSPtoFPdelta()
{
int delta;
-#ifdef PLATFORM_UNIX
+#ifdef UNIX_AMD64_ABI
// We require frame chaining on Unix to support native tool unwinding (such as
// unwinding by the native debugger). We have a CLR-only extension to the
@@ -7191,7 +7191,7 @@ int CodeGenInterface::genSPtoFPdelta()
// If Unix ever supports EnC, the RSP == RBP assumption will have to be reevaluated.
delta = genTotalFrameSize();
-#else // !PLATFORM_UNIX
+#else // !UNIX_AMD64_ABI
// As per Amd64 ABI, RBP offset from initial RSP can be between 0 and 240 if
// RBP needs to be reported in unwind codes. This case would arise for methods
@@ -7217,7 +7217,7 @@ int CodeGenInterface::genSPtoFPdelta()
delta = genTotalFrameSize();
}
-#endif // !PLATFORM_UNIX
+#endif // !UNIX_AMD64_ABI
return delta;
}
@@ -8525,7 +8525,7 @@ void CodeGen::genEmitHelperCall(unsigned helper, int argSize, emitAttr retSize,
INDEBUG_LDISASM_COMMA(nullptr) addr,
argSize,
retSize
- FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(EA_UNKNOWN),
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(EA_UNKNOWN),
gcInfo.gcVarPtrSetCur,
gcInfo.gcRegGCrefSetCur,
gcInfo.gcRegByrefSetCur,
diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp
index 423a044715..4e9c4b36c0 100644
--- a/src/jit/compiler.cpp
+++ b/src/jit/compiler.cpp
@@ -4990,11 +4990,11 @@ int Compiler::compCompile(CORINFO_METHOD_HANDLE methodHnd,
// with an ARM-targeting "altjit").
info.compMatchedVM = IMAGE_FILE_MACHINE_TARGET == info.compCompHnd->getExpectedTargetArchitecture();
-#if defined(ALT_JIT) && defined(UNIX_AMD64_ABI)
- // ToDo: This code is to allow us to run UNIX codegen on Windows for now. Remove when appropriate.
- // Make sure that the generated UNIX altjit code is skipped on Windows. The static jit codegen is used to run.
+#if (defined(_TARGET_UNIX_) && !defined(_HOST_UNIX_)) || (!defined(_TARGET_UNIX_) && defined(_HOST_UNIX_))
+ // The host and target platforms don't match. This info isn't handled by the existing
+ // getExpectedTargetArchitecture() JIT-EE interface method.
info.compMatchedVM = false;
-#endif // UNIX_AMD64_ABI
+#endif
#if COR_JIT_EE_VERSION > 460
compMaxUncheckedOffsetForNullObject = eeGetEEInfo()->maxUncheckedOffsetForNullObject;
@@ -5418,7 +5418,7 @@ void Compiler::compCompileFinish()
{
if (compJitHaltMethod())
{
-#if !defined(_TARGET_ARM64_) && !defined(PLATFORM_UNIX)
+#if !defined(_TARGET_ARM64_) && !defined(_HOST_UNIX_)
// TODO-ARM64-NYI: re-enable this when we have an OS that supports a pop-up dialog
// Don't do an assert, but just put up the dialog box so we get just-in-time debugger
diff --git a/src/jit/dll/CMakeLists.txt b/src/jit/dll/CMakeLists.txt
index 0e8f5bd3dd..6d247fe0d0 100644
--- a/src/jit/dll/CMakeLists.txt
+++ b/src/jit/dll/CMakeLists.txt
@@ -4,7 +4,6 @@ if(CLR_CMAKE_TARGET_ARCH_ARM)
add_definitions(-DLEGACY_BACKEND)
endif(CLR_CMAKE_TARGET_ARCH_ARM)
-# Disable the following for UNIX altjit on Windows
if(CLR_CMAKE_PLATFORM_UNIX)
add_compile_options(-fPIC)
@@ -19,19 +18,4 @@ else()
${SHARED_LIB_SOURCES}
${JIT_ARCH_SOURCES}
)
-# Disable up to here (see above) the following for UNIX altjit on Windows
-# Enable the following for UNIX altjit on Windows
-# add_library_clr(ClrJit
-# SHARED
-# ${SHARED_LIB_SOURCES}
-# )
-
-# Enable the following for UNIX altjit on Windows
-#target_link_libraries(ClrJit
-# utilcode
-# gcinfo
-# runtime_library
-# )
-
-# Disable the following for UNIX altjit on Windows
endif(CLR_CMAKE_PLATFORM_UNIX)
diff --git a/src/jit/ee_il_dll.cpp b/src/jit/ee_il_dll.cpp
index a29a3ef6b6..cfbc44cab6 100644
--- a/src/jit/ee_il_dll.cpp
+++ b/src/jit/ee_il_dll.cpp
@@ -20,7 +20,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "emit.h"
#include "corexcep.h"
-#if !defined(PLATFORM_UNIX)
+#if !defined(_HOST_UNIX_)
#include <io.h> // For _dup, _setmode
#include <fcntl.h> // For _O_TEXT
#include <errno.h> // For EINVAL
@@ -66,9 +66,9 @@ extern "C" void __stdcall jitStartup(ICorJitHost* jitHost)
assert(!JitConfig.isInitialized());
JitConfig.initialize(jitHost);
-#if defined(PLATFORM_UNIX)
+#if defined(_HOST_UNIX_)
jitstdout = procstdout();
-#else
+#else // !_HOST_UNIX_
if (jitstdout == nullptr)
{
int stdoutFd = _fileno(procstdout());
@@ -99,7 +99,7 @@ extern "C" void __stdcall jitStartup(ICorJitHost* jitHost)
{
jitstdout = procstdout();
}
-#endif // PLATFORM_UNIX
+#endif // !_HOST_UNIX_
#ifdef FEATURE_TRACELOGGING
JitTelemetry::NotifyDllProcessAttach();
diff --git a/src/jit/emitxarch.cpp b/src/jit/emitxarch.cpp
index f672913a3b..7d3b615e28 100644
--- a/src/jit/emitxarch.cpp
+++ b/src/jit/emitxarch.cpp
@@ -1665,7 +1665,7 @@ inline UNATIVE_OFFSET emitter::emitInsSizeSV(code_t code, int var, int dsp)
if (EBPbased)
{
-#if defined(_TARGET_AMD64_) && !defined(PLATFORM_UNIX)
+#if defined(_TARGET_AMD64_) && !defined(UNIX_AMD64_ABI)
// If localloc is not used, then ebp chaining is done and hence
// offset of locals will be at negative offsets, Otherwise offsets
// will be positive. In future, when RBP gets positioned in the
diff --git a/src/jit/jit.h b/src/jit/jit.h
index 05b154e15a..916b6802d7 100644
--- a/src/jit/jit.h
+++ b/src/jit/jit.h
@@ -172,6 +172,31 @@
#define _TARGET_ARMARCH_
#endif
+// If the UNIX_AMD64_ABI is defined make sure that _TARGET_AMD64_ is also defined.
+#if defined(UNIX_AMD64_ABI)
+#if !defined(_TARGET_AMD64_)
+#error When UNIX_AMD64_ABI is defined you must define _TARGET_AMD64_ defined as well.
+#endif
+#endif
+
+// If the UNIX_X86_ABI is defined make sure that _TARGET_X86_ is also defined.
+#if defined(UNIX_X86_ABI)
+#if !defined(_TARGET_X86_)
+#error When UNIX_X86_ABI is defined you must define _TARGET_X86_ defined as well.
+#endif
+#endif
+
+#if defined(PLATFORM_UNIX)
+#define _HOST_UNIX_
+#endif
+
+// Are we generating code to target Unix? This is true if we will run on Unix (_HOST_UNIX_ is defined).
+// It's also true if we are building an altjit targetting Unix, which we determine by checking if either
+// UNIX_AMD64_ABI or UNIX_X86_ABI is defined.
+#if defined(_HOST_UNIX_) || ((defined(UNIX_AMD64_ABI) || defined(UNIX_X86_ABI)) && defined(ALT_JIT))
+#define _TARGET_UNIX_
+#endif
+
// --------------------------------------------------------------------------------
// IMAGE_FILE_MACHINE_TARGET
// --------------------------------------------------------------------------------
@@ -190,7 +215,14 @@
// Include the AMD64 unwind codes when appropriate.
#if defined(_TARGET_AMD64_)
+// We need to temporarily set PLATFORM_UNIX, if necessary, to get the Unix-specific unwind codes.
+#if defined(_TARGET_UNIX_) && !defined(_HOST_UNIX_)
+#define PLATFORM_UNIX
+#endif
#include "win64unwind.h"
+#if defined(_TARGET_UNIX_) && !defined(_HOST_UNIX_)
+#undef PLATFORM_UNIX
+#endif
#endif
// Macros for defining strongly-typed enums. Use as follows:
diff --git a/src/jit/jitstd/type_traits.h b/src/jit/jitstd/type_traits.h
index 1e853e8cca..f0f8518c40 100644
--- a/src/jit/jitstd/type_traits.h
+++ b/src/jit/jitstd/type_traits.h
@@ -178,14 +178,15 @@ struct make_unsigned<int>
typedef unsigned int type;
};
-#ifndef PLATFORM_UNIX
+#ifndef _HOST_UNIX_
template<>
struct make_unsigned<long>
{
typedef unsigned long type;
};
-#endif // PLATFORM_UNIX
+
+#endif // !_HOST_UNIX_
template<>
struct make_unsigned<__int64>
diff --git a/src/jit/linuxnonjit/CMakeLists.txt b/src/jit/linuxnonjit/CMakeLists.txt
new file mode 100644
index 0000000000..87ec1e45c9
--- /dev/null
+++ b/src/jit/linuxnonjit/CMakeLists.txt
@@ -0,0 +1,71 @@
+project(linuxnonjit)
+
+add_definitions(-DALT_JIT)
+add_definitions(-DFEATURE_NO_HOST)
+add_definitions(-DSELF_NO_HOST)
+add_definitions(-DFEATURE_READYTORUN_COMPILER)
+remove_definitions(-DFEATURE_MERGE_JIT_AND_ENGINE)
+
+if (CLR_CMAKE_PLATFORM_ARCH_I386)
+ remove_definitions(-DFEATURE_SIMD)
+ remove_definitions(-DFEATURE_AVX_SUPPORT)
+ add_definitions(-DUNIX_X86_ABI)
+ set(JIT_ARCH_ALTJIT_SOURCES ${JIT_I386_SOURCES})
+elseif(CLR_CMAKE_PLATFORM_ARCH_AMD64)
+ add_definitions(-DUNIX_AMD64_ABI)
+ add_definitions(-DFEATURE_UNIX_AMD64_STRUCT_PASSING)
+ set(JIT_ARCH_ALTJIT_SOURCES ${JIT_AMD64_SOURCES})
+else()
+ clr_unknown_arch()
+endif()
+
+if(WIN32)
+ add_definitions(-DFX_VER_INTERNALNAME_STR=linuxnonjit.dll)
+endif(WIN32)
+
+add_library_clr(linuxnonjit
+ SHARED
+ ${SHARED_LIB_SOURCES}
+ ${JIT_ARCH_ALTJIT_SOURCES}
+)
+
+add_dependencies(linuxnonjit jit_exports)
+
+set_property(TARGET linuxnonjit APPEND_STRING PROPERTY LINK_FLAGS ${JIT_EXPORTS_LINKER_OPTION})
+set_property(TARGET linuxnonjit APPEND_STRING PROPERTY LINK_DEPENDS ${JIT_EXPORTS_FILE})
+
+set(RYUJIT_LINK_LIBRARIES
+ utilcodestaticnohost
+ gcinfo
+)
+
+if(CLR_CMAKE_PLATFORM_UNIX)
+ list(APPEND RYUJIT_LINK_LIBRARIES
+ mscorrc_debug
+ coreclrpal
+ palrt
+ )
+else()
+ list(APPEND RYUJIT_LINK_LIBRARIES
+ ${STATIC_MT_CRT_LIB}
+ ${STATIC_MT_VCRT_LIB}
+ kernel32.lib
+ advapi32.lib
+ ole32.lib
+ oleaut32.lib
+ uuid.lib
+ user32.lib
+ version.lib
+ shlwapi.lib
+ bcrypt.lib
+ crypt32.lib
+ RuntimeObject.lib
+ )
+endif(CLR_CMAKE_PLATFORM_UNIX)
+
+target_link_libraries(linuxnonjit
+ ${RYUJIT_LINK_LIBRARIES}
+)
+
+# add the install targets
+install_clr(linuxnonjit)
diff --git a/src/jit/target.h b/src/jit/target.h
index 2cee2c8554..a775186f26 100644
--- a/src/jit/target.h
+++ b/src/jit/target.h
@@ -6,25 +6,11 @@
#ifndef _TARGET_H_
#define _TARGET_H_
-// If the UNIX_AMD64_ABI is defined make sure that _TARGET_AMD64_ is also defined.
-#if defined(UNIX_AMD64_ABI)
-#if !defined(_TARGET_AMD64_)
-#error When UNIX_AMD64_ABI is defined you must define _TARGET_AMD64_ defined as well.
-#endif
-#endif
-
-// If the UNIX_X86_ABI is defined make sure that _TARGET_X86_ is also defined.
-#if defined(UNIX_X86_ABI)
-#if !defined(_TARGET_X86_)
-#error When UNIX_X86_ABI is defined you must define _TARGET_X86_ defined as well.
-#endif
-#endif
-
-#if (defined(FEATURE_CORECLR) && defined(PLATFORM_UNIX))
+#if defined(FEATURE_CORECLR) && defined(_TARGET_UNIX_)
#define FEATURE_VARARG 0
-#else // !(defined(FEATURE_CORECLR) && defined(PLATFORM_UNIX))
+#else // !(defined(FEATURE_CORECLR) && defined(_TARGET_UNIX_))
#define FEATURE_VARARG 1
-#endif // !(defined(FEATURE_CORECLR) && defined(PLATFORM_UNIX))
+#endif // !(defined(FEATURE_CORECLR) && defined(_TARGET_UNIX_))
/*****************************************************************************/
// The following are human readable names for the target architectures
diff --git a/src/jit/unwindamd64.cpp b/src/jit/unwindamd64.cpp
index 14eba8cb50..1b2baf6584 100644
--- a/src/jit/unwindamd64.cpp
+++ b/src/jit/unwindamd64.cpp
@@ -448,7 +448,7 @@ void Compiler::unwindSetFrameRegWindows(regNumber reg, unsigned offset)
func->unwindHeader.FrameRegister = (BYTE)reg;
-#ifdef PLATFORM_UNIX
+#ifdef UNIX_AMD64_ABI
if (offset > 240)
{
// On Unix only, we have a CLR-only extension to the AMD64 unwind codes: UWOP_SET_FPREG_LARGE.
@@ -467,7 +467,7 @@ void Compiler::unwindSetFrameRegWindows(regNumber reg, unsigned offset)
func->unwindHeader.FrameOffset = 15;
}
else
-#endif // PLATFORM_UNIX
+#endif // UNIX_AMD64_ABI
{
assert(func->unwindCodeSlot > sizeof(UNWIND_CODE));
UNWIND_CODE* code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
@@ -697,7 +697,7 @@ void DumpUnwindInfo(bool isHotCode,
pCode->CodeOffset, pCode->UnwindOp, pCode->OpInfo); // This should be zero
break;
-#ifdef PLATFORM_UNIX
+#ifdef UNIX_AMD64_ABI
case UWOP_SET_FPREG_LARGE:
printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SET_FPREG_LARGE (%u) OpInfo: Unused (%u)\n",
@@ -712,7 +712,7 @@ void DumpUnwindInfo(bool isHotCode,
}
break;
-#endif // PLATFORM_UNIX
+#endif // UNIX_AMD64_ABI
case UWOP_SAVE_NONVOL:
printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SAVE_NONVOL (%u) OpInfo: %s (%u)\n",
@@ -858,7 +858,7 @@ void Compiler::unwindReserveFuncHelper(FuncInfoDsc* func, bool isHotCode)
#ifdef UNIX_AMD64_ABI
if (generateCFIUnwindCodes())
{
- unwindCodeBytes = func->cfiCodes->size() * sizeof(CFI_CODE);
+ unwindCodeBytes = (DWORD)(func->cfiCodes->size() * sizeof(CFI_CODE));
}
else
#endif // UNIX_AMD64_ABI
@@ -956,7 +956,7 @@ void Compiler::unwindEmitFuncHelper(FuncInfoDsc* func, void* pHotCode, void* pCo
#ifdef UNIX_AMD64_ABI
if (generateCFIUnwindCodes())
{
- int size = func->cfiCodes->size();
+ DWORD size = (DWORD)func->cfiCodes->size();
if (size > 0)
{
unwindCodeBytes = size * sizeof(CFI_CODE);
diff --git a/src/jit/utils.cpp b/src/jit/utils.cpp
index bb76a730d9..e3654b0563 100644
--- a/src/jit/utils.cpp
+++ b/src/jit/utils.cpp
@@ -25,13 +25,13 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// same code for all platforms, hence it is here instead of in the targetXXX.cpp
// files.
-#ifdef PLATFORM_UNIX
+#ifdef _TARGET_UNIX_
// Should we distinguish Mac? Can we?
// Should we distinguish flavors of Unix? Can we?
const char* Target::g_tgtPlatformName = "Unix";
-#else // !PLATFORM_UNIX
+#else // !_TARGET_UNIX_
const char* Target::g_tgtPlatformName = "Windows";
-#endif // !PLATFORM_UNIX
+#endif // !_TARGET_UNIX_
/*****************************************************************************/
diff --git a/src/jit/valuenum.h b/src/jit/valuenum.h
index d434b81aff..2be48491df 100644
--- a/src/jit/valuenum.h
+++ b/src/jit/valuenum.h
@@ -678,9 +678,13 @@ private:
__fallthrough;
case TYP_BYREF:
-#ifndef PLATFORM_UNIX
+
+#ifdef _MSC_VER
+
assert(&typeid(T) == &typeid(size_t)); // We represent ref/byref constants as size_t's.
-#endif // PLATFORM_UNIX
+
+#endif // _MSC_VER
+
__fallthrough;
case TYP_INT:
diff --git a/src/vm/callhelpers.cpp b/src/vm/callhelpers.cpp
index 18c935a5b4..c575ee615d 100644
--- a/src/vm/callhelpers.cpp
+++ b/src/vm/callhelpers.cpp
@@ -434,7 +434,7 @@ void MethodDescCallSite::CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT *
#ifdef _DEBUG
{
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
// Validate that the return value is not too big for the buffer passed
if (m_pMD->GetMethodTable()->IsRegPassedStruct())
{
@@ -444,7 +444,7 @@ void MethodDescCallSite::CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT *
_ASSERTE(cbReturnValue >= thReturnValueType.GetSize());
}
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
// The metasig should be reset
_ASSERTE(m_methodSig.GetArgNum() == 0);
diff --git a/src/vm/class.h b/src/vm/class.h
index 756f6d5fc5..6c74377012 100644
--- a/src/vm/class.h
+++ b/src/vm/class.h
@@ -416,12 +416,12 @@ class EEClassLayoutInfo
e_ZERO_SIZED = 0x04,
// The size of the struct is explicitly specified in the meta-data.
e_HAS_EXPLICIT_SIZE = 0x08,
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
-#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF defined at the same time.
+#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING defined at the same time.
#endif // FEATURE_HFA
e_NATIVE_PASS_IN_REGISTERS = 0x10, // Flag wheter a native struct is passed in registers.
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
// HFA type of the unmanaged layout
e_R4_HFA = 0x10,
@@ -510,13 +510,13 @@ class EEClassLayoutInfo
return m_cbPackingSize;
}
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
bool IsNativeStructPassedInRegisters()
{
LIMITED_METHOD_CONTRACT;
return (m_bFlags & e_NATIVE_PASS_IN_REGISTERS) != 0;
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
bool IsNativeHFA()
@@ -570,13 +570,13 @@ class EEClassLayoutInfo
m_bFlags |= (hfaType == ELEMENT_TYPE_R4) ? e_R4_HFA : e_R8_HFA;
}
#endif
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
void SetNativeStructPassedInRegisters()
{
LIMITED_METHOD_CONTRACT;
m_bFlags |= e_NATIVE_PASS_IN_REGISTERS;
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
};
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index 45239c46b7..bdccdefd24 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -2448,15 +2448,28 @@ bool CEEInfo::getSystemVAmd64PassStructInRegisterDescriptor(
}
_ASSERTE(methodTablePtr != nullptr);
+ // If we have full support for FEATURE_UNIX_AMD64_STRUCT_PASSING, and not just the interface,
+ // then we've cached whether this is a reg passed struct in the MethodTable, computed during
+ // MethodTable construction. Otherwise, we are just building in the interface, and we haven't
+ // computed or cached anything, so we need to compute it now.
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
bool canPassInRegisters = useNativeLayout ? methodTablePtr->GetLayoutInfo()->IsNativeStructPassedInRegisters()
- : methodTablePtr->IsRegPassedStruct();
+ : methodTablePtr->IsRegPassedStruct();
+#else // !defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+ SystemVStructRegisterPassingHelper helper((unsigned int)th.GetSize());
+ bool canPassInRegisters = methodTablePtr->ClassifyEightBytes(&helper, 0, 0, useNativeLayout);
+#endif // !defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+
if (canPassInRegisters)
{
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
SystemVStructRegisterPassingHelper helper((unsigned int)th.GetSize());
bool result = methodTablePtr->ClassifyEightBytes(&helper, 0, 0, useNativeLayout);
// The answer must be true at this point.
_ASSERTE(result);
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+
structPassInRegDescPtr->passedInRegisters = true;
structPassInRegDescPtr->eightByteCount = helper.eightByteCount;
diff --git a/src/vm/methodtable.cpp b/src/vm/methodtable.cpp
index 2cc2ffe10e..21fab720f2 100644
--- a/src/vm/methodtable.cpp
+++ b/src/vm/methodtable.cpp
@@ -2980,7 +2980,7 @@ bool MethodTable::ClassifyEightBytesWithNativeLayout(SystemVStructRegisterPassin
}
// Assigns the classification types to the array with eightbyte types.
-void MethodTable::AssignClassifiedEightByteTypes(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel)
+void MethodTable::AssignClassifiedEightByteTypes(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel) const
{
static const size_t CLR_SYSTEMV_MAX_BYTES_TO_PASS_IN_REGISTERS = CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS * SYSTEMV_EIGHT_BYTE_SIZE_IN_BYTES;
static_assert_no_msg(CLR_SYSTEMV_MAX_BYTES_TO_PASS_IN_REGISTERS == SYSTEMV_MAX_NUM_FIELDS_IN_REGISTER_PASSED_STRUCT);
diff --git a/src/vm/methodtable.h b/src/vm/methodtable.h
index 6e04b8a783..d5cb5ba866 100644
--- a/src/vm/methodtable.h
+++ b/src/vm/methodtable.h
@@ -1070,7 +1070,7 @@ public:
private:
#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
- void AssignClassifiedEightByteTypes(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel);
+ void AssignClassifiedEightByteTypes(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel) const;
// Builds the internal data structures and classifies struct eightbytes for Amd System V calling convention.
bool ClassifyEightBytesWithManagedLayout(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel, unsigned int startOffsetOfStruct, bool isNativeStruct);
bool ClassifyEightBytesWithNativeLayout(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel, unsigned int startOffsetOfStruct, bool isNativeStruct);
@@ -2012,7 +2012,7 @@ public:
}
#endif // FEATURE_HFA
-#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
inline bool IsRegPassedStruct()
{
LIMITED_METHOD_CONTRACT;
@@ -2024,7 +2024,7 @@ public:
LIMITED_METHOD_CONTRACT;
SetFlag(enum_flag_IsRegStructPassed);
}
-#endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
+#endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
#ifdef FEATURE_HFA
@@ -3801,18 +3801,18 @@ private:
enum_flag_HasPreciseInitCctors = 0x00000400, // Do we need to run class constructors at allocation time? (Not perf important, could be moved to EEClass
#if defined(FEATURE_HFA)
-#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
-#error Can't define both FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+#error Can't define both FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING
#endif
enum_flag_IsHFA = 0x00000800, // This type is an HFA (Homogenous Floating-point Aggregate)
#endif // FEATURE_HFA
-#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
#if defined(FEATURE_HFA)
-#error Can't define both FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#error Can't define both FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING
#endif
enum_flag_IsRegStructPassed = 0x00000800, // This type is a System V register passed struct.
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
enum_flag_IsByRefLike = 0x00001000,
diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp
index fbf9246db5..7de35101ff 100644
--- a/src/vm/methodtablebuilder.cpp
+++ b/src/vm/methodtablebuilder.cpp
@@ -1839,23 +1839,23 @@ MethodTableBuilder::BuildMethodTableThrowing(
#ifdef FEATURE_HFA
CheckForHFA(pByValueClassCache);
#endif
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
-#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF defined at the same time.
+#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING defined at the same time.
#endif // FEATURE_HFA
SystemVAmd64CheckForPassStructInRegister();
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
}
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
-#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF defined at the same time.
+#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING defined at the same time.
#endif // FEATURE_HFA
if (HasLayout())
{
SystemVAmd64CheckForPassNativeStructInRegister();
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
if (HasLayout())
{
@@ -8224,7 +8224,7 @@ DWORD MethodTableBuilder::GetFieldSize(FieldDesc *pFD)
return (1 << (DWORD)(DWORD_PTR&)(pFD->m_pMTOfEnclosingClass));
}
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
// checks whether the struct is enregisterable.
void MethodTableBuilder::SystemVAmd64CheckForPassStructInRegister()
{
@@ -8309,7 +8309,7 @@ void MethodTableBuilder::StoreEightByteClassification(SystemVStructRegisterPassi
eeClass->SetEightByteClassification(helper->eightByteCount, helper->eightByteClassifications, helper->eightByteSizes);
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
//---------------------------------------------------------------------------------------
diff --git a/src/vm/methodtablebuilder.h b/src/vm/methodtablebuilder.h
index 8bfffcc6e0..2aa36836e7 100644
--- a/src/vm/methodtablebuilder.h
+++ b/src/vm/methodtablebuilder.h
@@ -2925,14 +2925,14 @@ private:
VOID CheckForNativeHFA();
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
// checks whether the struct is enregisterable.
void SystemVAmd64CheckForPassStructInRegister();
void SystemVAmd64CheckForPassNativeStructInRegister();
// Store the eightbyte classification into the EEClass
void StoreEightByteClassification(SystemVStructRegisterPassingHelper* helper);
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
// this accesses the field size which is temporarily stored in m_pMTOfEnclosingClass
// during class loading. Don't use any other time