Skip to content

Commit

Permalink
[Local GC] Implement loader protocol for a standalone GC (dotnet#14663)
Browse files Browse the repository at this point in the history
* First cut of the load protocol

* Implement for non-standalone GC

* Initial working implementation

* First steps towards not using GetProcAddress when not using a standalone GC

* Factor out loading routines into standalone and non-standalone cases

* Remove the FEATURE_STANDALONE_GC_ONLY build

* Code cleanup and comments

* Comments for the version numbers

* Use more appropriate type for config string

* add GC_LOAD_STATUS_BEFORE_START to disambiguate failures before the start of the load and failures at the beginning of the load

* FEATURE_STANDALONE_GC on by default

* Implement YieldProcessor and MemoryBarrier for arm and arm64

* Remove missed FEATURE_STANDALONE_GC feature check
  • Loading branch information
swgillespie authored Oct 27, 2017
1 parent fb4af6c commit bd34249
Show file tree
Hide file tree
Showing 16 changed files with 404 additions and 289 deletions.
4 changes: 0 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -599,10 +599,6 @@ if(FEATURE_STANDALONE_GC)
add_subdirectory(src/gc)
endif(FEATURE_STANDALONE_GC)

if(FEATURE_STANDALONE_GC_ONLY)
add_definitions(-DFEATURE_STANDALONE_GC_ONLY)
endif(FEATURE_STANDALONE_GC_ONLY)

if (CLR_CMAKE_PLATFORM_UNIX)
include_directories("src/pal/inc")
include_directories("src/pal/inc/rt")
Expand Down
17 changes: 1 addition & 16 deletions build.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,6 @@ set __BuildArchArm64=0
set __BuildTypeDebug=0
set __BuildTypeChecked=0
set __BuildTypeRelease=0
set __BuildStandaloneGC="-DFEATURE_STANDALONE_GC=0"
set __BuildStandaloneGCOnly="-DFEATURE_STANDALONE_GC_ONLY=0"

set __PgoInstrument=0
set __PgoOptimize=1
Expand Down Expand Up @@ -177,12 +175,6 @@ if /i "%1" == "-enforcepgo" (set __EnforcePgo=1&set processedArgs=!proc
if /i "%1" == "-nopgooptimize" (set __PgoOptimize=0&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "-ibcinstrument" (set __IbcTuning=/Tuning&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "-toolset_dir" (set __ToolsetDir=%2&set __PassThroughArgs=%__PassThroughArgs% %2&set processedArgs=!processedArgs! %1 %2&shift&shift&goto Arg_Loop)
if /i "%1" == "-buildstandalonegc" (
set __BuildStandaloneGC="-DFEATURE_STANDALONE_GC=1"
set __BuildStandaloneGCOnly="-DFEATURE_STANDALONE_GC_ONLY=1"
set processedArgs=!processedArgs! %1
shift&goto Arg_Loop
)

REM TODO these are deprecated remove them eventually
REM don't add more, use the - syntax instead
Expand All @@ -205,12 +197,6 @@ if /i "%1" == "nopgooptimize" (set __PgoOptimize=0&set processedArgs=!proc
if /i "%1" == "enforcepgo" (set __EnforcePgo=1&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "ibcinstrument" (set __IbcTuning=/Tuning&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "toolset_dir" (set __ToolsetDir=%2&set __PassThroughArgs=%__PassThroughArgs% %2&set processedArgs=!processedArgs! %1 %2&shift&shift&goto Arg_Loop)
if /i "%1" == "buildstandalonegc" (
set __BuildStandaloneGC="-DFEATURE_STANDALONE_GC=1"
set __BuildStandaloneGCOnly="-DFEATURE_STANDALONE_GC_ONLY=1"
set processedArgs=!processedArgs! %1
shift&goto Arg_Loop
)

@REM The following can be deleted once the CI system that passes it is updated to not pass it.
if /i "%1" == "altjitcrossgen" (set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
Expand Down Expand Up @@ -405,7 +391,7 @@ if %__BuildNative% EQU 1 (

pushd "%__IntermediatesDir%"
set __ExtraCmakeArgs=!___SDKVersion! "-DCLR_CMAKE_TARGET_OS=%__BuildOs%" "-DCLR_CMAKE_PACKAGES_DIR=%__PackagesDir%" "-DCLR_CMAKE_PGO_INSTRUMENT=%__PgoInstrument%" "-DCLR_CMAKE_OPTDATA_VERSION=%__PgoOptDataVersion%" "-DCLR_CMAKE_PGO_OPTIMIZE=%__PgoOptimize%"
call "%__SourceDir%\pal\tools\gen-buildsys-win.bat" "%__ProjectDir%" %__VSVersion% %__BuildArch% %__BuildStandaloneGC% %__BuildStandaloneGCOnly% !__ExtraCmakeArgs!
call "%__SourceDir%\pal\tools\gen-buildsys-win.bat" "%__ProjectDir%" %__VSVersion% %__BuildArch% !__ExtraCmakeArgs!
@if defined _echo @echo on
popd

Expand Down Expand Up @@ -805,7 +791,6 @@ echo -skipnative: skip building native components ^(default: native components a
echo -skiptests: skip building tests ^(default: tests are built^).
echo -skipbuildpackages: skip building nuget packages ^(default: packages are built^).
echo -skiprestoreoptdata: skip restoring optimization data used by profile-based optimizations.
echo -buildstandalonegc: builds the GC in a standalone mode.
echo -skiprestore: skip restoring packages ^(default: packages are restored during build^).
echo -disableoss: Disable Open Source Signing for System.Private.CoreLib.
echo -priority=^<N^> : specify a set of test that will be built and run, with priority N.
Expand Down
4 changes: 0 additions & 4 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ usage()
echo "-ignorewarnings - do not treat warnings as errors"
echo "-cmakeargs - user-settable additional arguments passed to CMake."
echo "-bindir - output directory (defaults to $__ProjectRoot/bin)"
echo "-buildstandalonegc - builds the GC in a standalone mode. Can't be used with \"cmakeargs\"."
echo "-msbuildonunsupportedplatform - build managed binaries even if distro is not officially supported."
echo "-numproc - set the number of build processes."
exit 1
Expand Down Expand Up @@ -859,9 +858,6 @@ while :; do
exit 1
fi
;;
buildstandalonegc|-buildstandalonegc)
__cmakeargs="$__cmakeargs -DFEATURE_STANDALONE_GC=1 -DFEATURE_STANDALONE_GC_ONLY=1"
;;
msbuildonunsupportedplatform|-msbuildonunsupportedplatform)
__msbuildonunsupportedplatform=1
;;
Expand Down
8 changes: 3 additions & 5 deletions clrfeatures.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ if(CLR_CMAKE_TARGET_TIZEN_LINUX)
set(FEATURE_GDBJIT_LANGID_CS 1)
endif()

if(FEATURE_STANDALONE_GC_ONLY)
set(FEATURE_EVENT_TRACE 0)
set(FEATURE_APPDOMAIN_RESOURCE_MONITORING 0)
endif()

if(NOT DEFINED FEATURE_EVENT_TRACE)
if (WIN32)
set(FEATURE_EVENT_TRACE 1)
Expand Down Expand Up @@ -46,3 +41,6 @@ if(NOT DEFINED FEATURE_APPDOMAIN_RESOURCE_MONITORING)
set(FEATURE_APPDOMAIN_RESOURCE_MONITORING 1)
endif(NOT DEFINED FEATURE_APPDOMAIN_RESOURCE_MONITORING)

if(NOT DEFINED FEATURE_STANDALONE_GC)
set(FEATURE_STANDALONE_GC 1)
endif(NOT DEFINED FEATURE_STANDALONE_GC)
26 changes: 22 additions & 4 deletions src/gc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
set(CMAKE_INCLUDE_CURRENT_DIR ON)

# Local GC meta-issue: https://github.com/dotnet/coreclr/issues/11518

# https://github.com/dotnet/coreclr/issues/11514
remove_definitions(-DFEATURE_EVENT_TRACE=1)

# https://github.com/dotnet/coreclr/issues/11517
remove_definitions(-DFEATURE_APPDOMAIN_RESOURCE_MONITORING)

# https://github.com/dotnet/coreclr/issues/11516
remove_definitions(-DSTRESS_HEAP)

# https://github.com/dotnet/coreclr/issues/11519
remove_definitions(-DWRITE_BARRIER_CHECK)

# https://github.com/dotnet/coreclr/issues/14701
add_definitions(-DFEATURE_REDHAWK)

set( GC_SOURCES
gcconfig.cpp
gccommon.cpp
Expand All @@ -14,6 +31,7 @@ set( GC_SOURCES
gchandletable.cpp
gceesvr.cpp
gceewks.cpp
gcload.cpp
handletablecache.cpp)

if(CLR_CMAKE_PLATFORM_UNIX)
Expand All @@ -40,13 +58,13 @@ endif(WIN32)

convert_to_absolute_path(GC_SOURCES ${GC_SOURCES})

add_library_clr(gc SHARED ${GC_SOURCES})
target_link_libraries(gc ${GC_LINK_LIBRARIES})
install_clr(gc)
add_library_clr(clrgc SHARED ${GC_SOURCES})
target_link_libraries(clrgc ${GC_LINK_LIBRARIES})
install_clr(clrgc)

if(CLR_CMAKE_PLATFORM_UNIX)
add_compile_options(-fPIC)
# dprintf causes many warnings
# dprintf causes many warnings (https://github.com/dotnet/coreclr/issues/13367)
add_compile_options(-Wno-format)
endif(CLR_CMAKE_PLATFORM_UNIX)

Expand Down
12 changes: 10 additions & 2 deletions src/gc/env/gcenv.base.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
#include <intrin.h>
#endif // _MSC_VER

#define FEATURE_REDHAWK 1

#define REDHAWK_PALIMPORT extern "C"
#define REDHAWK_PALAPI __stdcall

Expand Down Expand Up @@ -208,6 +206,16 @@ typedef DWORD (WINAPI *PTHREAD_START_ROUTINE)(void* lpThreadParameter);

#endif // defined(__i386__) || defined(__x86_64__)

#ifdef __aarch64__
#define YieldProcessor() asm volatile ("yield")
#define MemoryBarrier __sync_synchronize
#endif // __aarch64__

#ifdef __arm__
#define YieldProcessor()
#define MemoryBarrier __sync_synchronize
#endif // __arm__

#endif // _MSC_VER

#ifdef _MSC_VER
Expand Down
103 changes: 0 additions & 103 deletions src/gc/gccommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,107 +114,4 @@ void record_changed_seg (uint8_t* start, uint8_t* end,
}
}

namespace WKS
{
extern void PopulateDacVars(GcDacVars* dacVars);
}

namespace SVR
{
extern void PopulateDacVars(GcDacVars* dacVars);
}

extern void PopulateHandleTableDacVars(GcDacVars* dacVars);

//------------------------------------------------------------------
// Externally-facing GC symbols, used to initialize the GC
// -----------------------------------------------------------------

#ifdef _MSC_VER
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __attribute__ ((visibility ("default")))
#endif // _MSC_VER

#ifdef BUILD_AS_STANDALONE
#define GC_API extern "C" DLLEXPORT
#else
#define GC_API extern "C"
#endif // BUILD_AS_STANDALONE

GC_API
bool
InitializeGarbageCollector(
/* In */ IGCToCLR* clrToGC,
/* Out */ IGCHeap** gcHeap,
/* Out */ IGCHandleManager** gcHandleManager,
/* Out */ GcDacVars* gcDacVars
)
{
LIMITED_METHOD_CONTRACT;

IGCHeapInternal* heap;

assert(gcDacVars != nullptr);
assert(gcHeap != nullptr);
assert(gcHandleManager != nullptr);

#ifdef BUILD_AS_STANDALONE
assert(clrToGC != nullptr);
g_theGCToCLR = clrToGC;
#else
UNREFERENCED_PARAMETER(clrToGC);
assert(clrToGC == nullptr);
#endif

// Initialize GCConfig before anything else - initialization of our
// various components may want to query the current configuration.
GCConfig::Initialize();
if (!GCToOSInterface::Initialize())
{
return false;
}

IGCHandleManager* handleManager = CreateGCHandleManager();
if (handleManager == nullptr)
{
return false;
}

#ifdef FEATURE_SVR_GC
if (GCConfig::GetServerGC())
{
#ifdef WRITE_BARRIER_CHECK
g_GCShadow = 0;
g_GCShadowEnd = 0;
#endif // WRITE_BARRIER_CHECK

g_gc_heap_type = GC_HEAP_SVR;
heap = SVR::CreateGCHeap();
SVR::PopulateDacVars(gcDacVars);
}
else
{
g_gc_heap_type = GC_HEAP_WKS;
heap = WKS::CreateGCHeap();
WKS::PopulateDacVars(gcDacVars);
}
#else
g_gc_heap_type = GC_HEAP_WKS;
heap = WKS::CreateGCHeap();
WKS::PopulateDacVars(gcDacVars);
#endif

PopulateHandleTableDacVars(gcDacVars);
if (heap == nullptr)
{
return false;
}

g_theGCHeap = heap;
*gcHandleManager = handleManager;
*gcHeap = heap;
return true;
}

#endif // !DACCESS_COMPILE
43 changes: 29 additions & 14 deletions src/gc/gcinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@
#ifndef _GC_INTERFACE_H_
#define _GC_INTERFACE_H_

// The major version of the GC/EE interface. Breaking changes to this interface
// require bumps in the major version number.
#define GC_INTERFACE_MAJOR_VERSION 1

// The minor version of the GC/EE interface. Non-breaking changes are required
// to bump the minor version number. GCs and EEs with minor version number
// mismatches can still interopate correctly, with some care.
#define GC_INTERFACE_MINOR_VERSION 1

struct ScanContext;
struct gc_alloc_context;
class CrawlFrame;
Expand Down Expand Up @@ -174,20 +183,6 @@ class Object;
class IGCHeap;
class IGCHandleManager;

// The function that initialzes the garbage collector.
// Should only be called once: here, during EE startup.
// Returns true if the initialization was successful, false otherwise.
typedef bool (*InitializeGarbageCollectorFunction)(
/* In */ IGCToCLR*,
/* Out */ IGCHeap**,
/* Out */ IGCHandleManager**,
/* Out */ GcDacVars*
);

// The name of the function that initializes the garbage collector,
// to be used as an argument to GetProcAddress.
#define INITIALIZE_GC_FUNCTION_NAME "InitializeGarbageCollector"

#ifdef WRITE_BARRIER_CHECK
//always defined, but should be 0 in Server GC
extern uint8_t* g_GCShadow;
Expand Down Expand Up @@ -871,4 +866,24 @@ struct ScanContext
}
};

// These types are used as part of the loader protocol between the EE
// and the GC.
struct VersionInfo {
uint32_t MajorVersion;
uint32_t MinorVersion;
uint32_t BuildVersion;
const char* Name;
};

typedef void (*GC_VersionInfoFunction)(
/* Out */ VersionInfo*
);

typedef HRESULT (*GC_InitializeFunction)(
/* In */ IGCToCLR*,
/* Out */ IGCHeap**,
/* Out */ IGCHandleManager**,
/* Out */ GcDacVars*
);

#endif // _GC_INTERFACE_H_
Loading

0 comments on commit bd34249

Please sign in to comment.