summaryrefslogtreecommitdiff
path: root/src/vm/gccover.h
diff options
context:
space:
mode:
authordotnet-bot <dotnet-bot@microsoft.com>2015-01-30 14:14:42 -0800
committerdotnet-bot <dotnet-bot@microsoft.com>2015-01-30 14:14:42 -0800
commitef1e2ab328087c61a6878c1e84f4fc5d710aebce (patch)
treedee1bbb89e9d722e16b0d1485e3cdd1b6c8e2cfa /src/vm/gccover.h
downloadcoreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.gz
coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.bz2
coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.zip
Initial commit to populate CoreCLR repo
[tfs-changeset: 1407945]
Diffstat (limited to 'src/vm/gccover.h')
-rw-r--r--src/vm/gccover.h112
1 files changed, 112 insertions, 0 deletions
diff --git a/src/vm/gccover.h b/src/vm/gccover.h
new file mode 100644
index 0000000000..2fa6868196
--- /dev/null
+++ b/src/vm/gccover.h
@@ -0,0 +1,112 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+
+
+#ifndef __GCCOVER_H__
+#define __GCCOVER_H__
+
+#ifdef HAVE_GCCOVER
+
+/****************************************************************************/
+/* GCCOverageInfo holds the state of which instructions have been visited by
+ a GC and which ones have not */
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4200 ) // zero-sized array
+#endif // _MSC_VER
+
+class GCCoverageInfo {
+public:
+ IJitManager::MethodRegionInfo methodRegion;
+ BYTE* curInstr; // The last instruction that was able to execute
+ MethodDesc* lastMD; // Used to quickly figure out the culprite
+
+ // Following 6 variables are for prolog / epilog walking coverage
+ ICodeManager* codeMan; // CodeMan for this method
+ void* gcInfo; // gcInfo for this method
+
+ Thread* callerThread; // Thread associated with context callerRegs
+ T_CONTEXT callerRegs; // register state when method was entered
+ unsigned gcCount; // GC count at the time we caputured the regs
+ bool doingEpilogChecks; // are we doing epilog unwind checks? (do we care about callerRegs?)
+
+ enum { hasExecutedSize = 4 };
+ unsigned hasExecuted[hasExecutedSize];
+ unsigned totalCount;
+
+ union
+ {
+ BYTE savedCode[0]; // really variable sized
+ // Note that DAC doesn't marshal the entire byte array automatically.
+ // Any client of this field needs to get the TADDR of this field and
+ // marshal over the bytes properly.
+ };
+
+ // Sloppy bitsets (will wrap, and not threadsafe) but best effort is OK
+ // since we just need half decent coverage.
+ BOOL IsBitSetForOffset(unsigned offset) {
+ unsigned dword = hasExecuted[(offset >> 5) % hasExecutedSize];
+ return(dword & (1 << (offset & 0x1F)));
+ }
+
+ void SetBitForOffset(unsigned offset) {
+ unsigned* dword = &hasExecuted[(offset >> 5) % hasExecutedSize];
+ *dword |= (1 << (offset & 0x1F)) ;
+ }
+
+ void SprinkleBreakpoints(BYTE * saveAddr, PCODE codeStart, size_t codeSize, size_t regionOffsetAdj, BOOL fZapped);
+
+};
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif // _MSC_VER
+
+
+#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
+
+#define INTERRUPT_INSTR 0xF4 // X86 HLT instruction (any 1 byte illegal instruction will do)
+#define INTERRUPT_INSTR_CALL 0xFA // X86 CLI instruction
+#define INTERRUPT_INSTR_PROTECT_RET 0xFB // X86 STI instruction
+
+#elif defined(_TARGET_ARM_)
+
+// 16-bit illegal instructions which will cause exception and cause
+// control to go to GcStress codepath
+#define INTERRUPT_INSTR 0xde00
+#define INTERRUPT_INSTR_CALL 0xde01
+#define INTERRUPT_INSTR_PROTECT_RET 0xde02
+
+// 32-bit illegal instructions. It is necessary to replace a 16-bit instruction
+// with a 16-bit illegal instruction, and a 32-bit instruction with a 32-bit
+// illegal instruction, to make GC stress with the "IT" instruction work, since
+// it counts the number of instructions that follow it, so we can't change that
+// number by replacing a 32-bit instruction with a 16-bit illegal instruction
+// followed by 16 bits of junk that might end up being a legal instruction.
+// Use the "Permanently UNDEFINED" section in the "ARM Architecture Reference Manual",
+// section A6.3.4 "Branches and miscellaneous control" table.
+// Note that we write these as a single 32-bit write, not two 16-bit writes, so the values
+// need to be arranged as the ARM decoder wants them, with the high-order halfword first
+// (in little-endian order).
+#define INTERRUPT_INSTR_32 0xa001f7f0 // 0xf7f0a001
+#define INTERRUPT_INSTR_CALL_32 0xa002f7f0 // 0xf7f0a002
+#define INTERRUPT_INSTR_PROTECT_RET_32 0xa003f7f0 // 0xf7f0a003
+
+#elif defined(_TARGET_ARM64_)
+
+// The following encodings are undefined. They fall into section C4.5.8 - Data processing (2 source) of
+// "Arm Architecture Reference Manual ARMv8"
+//
+#define INTERRUPT_INSTR 0xBADC0DE0
+#define INTERRUPT_INSTR_CALL 0xBADC0DE1
+#define INTERRUPT_INSTR_PROTECT_RET 0xBADC0DE2
+
+#endif // _TARGET_*
+
+#endif // HAVE_GCCOVER
+
+#endif // !__GCCOVER_H__