Skip to content
This repository has been archived by the owner on Mar 15, 2022. It is now read-only.

Commit

Permalink
Implement GC-Table generation
Browse files Browse the repository at this point in the history
Translate GcInfo from __llvm.stackmaps section to
CoreCLR GCInfo Encoding.

Testing:
1) We can now build and a few tests in a precise-GC environment.
   The correctness of generated GCInfo is verified by:
   a) Examining the GcInfo dump in the debugger (SOS) and comparing
      it against the assembly dump.
   b) Stepping through the debugger and watch it scan through the
      reported GC-Roots.
   c) The execution crashes for the same functions if the liveness
      information is not reported.

2) The execution crashes if we try to build MsCorLib for precise-GC.
There are a few known issues (as noted in the comments) and the
remaining issues need to be fixed via debugging.

3) The standard LLILC testig is still done using conservative-gc
So, no testing impact is expected for the lab. A separate test-leg will
be added to run tests with precise-GC.

Fixes #31
  • Loading branch information
swaroop-sridhar committed Jul 8, 2015
1 parent a4c4bc7 commit 514f121
Show file tree
Hide file tree
Showing 12 changed files with 447 additions and 35 deletions.
44 changes: 42 additions & 2 deletions include/GcInfo/GcInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,54 @@
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Wrapper that includes all GcInfo related headers
/// \brief GCInfo Generator for LLILC
///
//===----------------------------------------------------------------------===//

#ifndef GCINFO_H
#define GCINFO_H

#define STANDALONE_BUILD
#include "gcinfoencoder.h"
#include "jitpch.h"
#include "LLILCJit.h"

class GcInfoAllocator;
class GcInfoEncoder;

/// \brief This is the translator from LLVM's GC StackMaps
/// to CoreCLR's GcInfo encoding.
class GCInfo {
public:
/// Construct a GCInfo object
/// \param JitCtx Context record for the method's jit request.
/// \param StackMapData A pointer to the .llvm_stackmaps section
/// loaded in memory
/// \param CodeBlkStart Start address of the Code section block
GCInfo(LLILCJitContext *JitCtx, uint8_t *StackMapData, uint8_t *CodeBlkStart,
GcInfoAllocator *Allocator);

/// Emit GC Info to the EE using GcInfoEncoder.
void emitGCInfo();

/// Destructor -- delete allocated memory
~GCInfo();

private:
void encodeHeader();
void encodeLiveness();
void emitEncoding();

const LLILCJitContext *JitContext;
const uint8_t *CodeBlockStart;
const uint8_t *LLVMStackMapData;
GcInfoEncoder Encoder;
bool EmitLogs;

#if defined(PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED)
size_t NumCallSites;
unsigned *CallSites;
BYTE *CallSiteSizes;
#endif // defined(PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED)
};

#endif // GCINFO_H
51 changes: 51 additions & 0 deletions include/GcInfo/Target.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//===---- include/gcinfo/target.h -------------------------------*- C++ -*-===//
//
// LLILC
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license.
// See LICENSE file in the project root for full license information.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Target specific definitions for GCInfo generation
///
//===----------------------------------------------------------------------===//

#ifndef GCINFO_TARGET_H
#define GCINFO_TARGET_H

#include "global.h"

#if (defined(_TARGET_X86_) || defined(_TARGET_X64_) || defined(_TARGET_AMD64_))

// Define DWARF encodings for registers
// Size variants (ex: AL,AH,AX,EAX,RAX) all get the same Dwarf register number

#define DW_RAX 0
#define DW_RBX 3
#define DW_RCX 2
#define DW_RDX 1
#define DW_RSI 4
#define DW_RDI 5
#define DW_RBP 6
#define DW_RSP 7
#define DW_RIP 16
#define DW_R8 8
#define DW_R9 9
#define DW_R10 10
#define DW_R11 11
#define DW_R12 12
#define DW_R13 13
#define DW_R14 14
#define DW_R15 15

#define DW_FRAME_POINTER DW_RBP
#define DW_STACK_POINTER DW_RSP

#else
#error GCTables not implemented for this target
#endif // defined(_TARGET_X86_ || _TARGET_X64_ || _TARGET_AMD64_)

#endif // GCINFO_TARGET_H
17 changes: 16 additions & 1 deletion include/Jit/EEMemoryManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class EEMemoryManager : public RTDyldMemoryManager {
/// \param C Jit context for the method being jitted.
EEMemoryManager(LLILCJitContext *C)
: Context(C), HotCodeBlock(nullptr), ColdCodeBlock(nullptr),
ReadOnlyDataBlock(nullptr) {}
ReadOnlyDataBlock(nullptr), StackMapBlock(nullptr) {}

/// Destroy an \p EEMemoryManager
~EEMemoryManager() override;
Expand Down Expand Up @@ -127,11 +127,26 @@ class EEMemoryManager : public RTDyldMemoryManager {
void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,
size_t Size) override;

/// \brief Get the LLVM Stackmap section if allocated.
///
/// Returns a pointer to the .llvm_stackmaps section
/// if it is already loaded into memory.

uint8_t *getStackMapSection() { return StackMapBlock; }

/// \brief Get the HotCode section if allocated.
///
/// Returns a pointer to the HotCode section
/// if it is already loaded into memory.

uint8_t *getHotCodeBlock() { return HotCodeBlock; }

private:
LLILCJitContext *Context; ///< LLVM context for types, etc.
uint8_t *HotCodeBlock; ///< Memory to hold the hot method code.
uint8_t *ColdCodeBlock; ///< Memory to hold the cold method code.
uint8_t *ReadOnlyDataBlock; ///< Memory to hold the readonly data.
uint8_t *StackMapBlock; ///< Memory to hold the readonly StackMap
uint8_t *ReadOnlyDataUnallocated; ///< Address of unallocated part of RO data.
};
} // namespace llvm
Expand Down
13 changes: 5 additions & 8 deletions include/Jit/LLILCJit.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#define LLILC_JIT_H

#include "Pal/LLILCPal.h"
#include "options.h"
#include "Reader/options.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/IR/LLVMContext.h"
Expand Down Expand Up @@ -110,9 +110,10 @@ struct LLILCJitContext {

/// \name Jit output sizes
//@{
uint32_t HotCodeSize = 0; ///< Size of hot code section in bytes.
uint32_t ColdCodeSize = 0; ///< Size of cold code section in bytes.
uint32_t ReadOnlyDataSize = 0; ///< Size of readonly data ref'd from code.
uintptr_t HotCodeSize = 0; ///< Size of hot code section in bytes.
uintptr_t ColdCodeSize = 0; ///< Size of cold code section in bytes.
uintptr_t ReadOnlyDataSize = 0; ///< Size of readonly data ref'd from code.
uintptr_t StackMapSize = 0; ///< Size of readonly Stackmap section.
//@}
};

Expand Down Expand Up @@ -240,10 +241,6 @@ class LLILCJit : public ICorJitCompiler {
/// \returns \p true if the conversion was successful.
bool readMethod(LLILCJitContext *JitContext);

/// Output GC info to the EE.
/// \param JitContext Context record for the method's jit request.
void outputGCInfo(LLILCJitContext *JitContext);

public:
/// A pointer to the singleton jit instance.
static LLILCJit *TheJit;
Expand Down
7 changes: 6 additions & 1 deletion include/Jit/jitoptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,14 @@ class JitOptions : public Options {

/// \brief Set DoTailCallOpt based on environment variable.
///
/// \returns true if COMPLUS_TAILCALLOPT is set in the environment set.
/// \returns true if COMPLUS_TAILCALLOPT is set in the environment.
static bool queryDoTailCallOpt(LLILCJitContext &JitContext);

/// \brief Set LogGcInfo based on environment variable.
///
/// \returns true if COMPLUS_JitGCInfoLogging is set in the environment.
static bool queryLogGcInfo(LLILCJitContext &JitContext);

public:
bool IsAltJit; ///< True if running as the alternative JIT.

Expand Down
1 change: 1 addition & 0 deletions include/Reader/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,6 @@ struct Options {
bool UseConservativeGC; ///< True if the environment is set to use CGC.
bool DoInsertStatepoints; ///< True if the environment calls for statepoints.
bool DoTailCallOpt; ///< Tail call optimization.
bool LogGcInfo; ///< Generate GCInfo Translation logs
};
#endif // OPTIONS_H
1 change: 1 addition & 0 deletions lib/GcInfo/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ add_llilcjit_library(GcInfo
STATIC
${CORECLR_GCINFO}/gcinfoencoder.cpp
GcInfoUtil.cpp
GcInfo.cpp
)
Loading

0 comments on commit 514f121

Please sign in to comment.