public GCRefMapBuilder(TargetDetails target, bool relocsOnly) { _target = target; _pendingByte = 0; _bits = 0; _pos = 0; Builder = new ObjectDataBuilder(target, relocsOnly); _transitionBlock = TransitionBlock.FromTarget(target); }
public GCRefMapBuilder(NodeFactory factory, bool relocsOnly) { _factory = factory; _pendingByte = 0; _bits = 0; _pos = 0; Builder = new ObjectDataBuilder(factory, relocsOnly); _transitionBlock = TransitionBlock.FromTarget(factory.Target); }
public void GetCallRefMap(MethodDesc method, bool isUnboxingStub) { TransitionBlock transitionBlock = TransitionBlock.FromTarget(method.Context.Target); MethodSignature signature = method.Signature; bool hasThis = (signature.Flags & MethodSignatureFlags.Static) == 0; // This pointer is omitted for string constructors bool fCtorOfVariableSizedObject = hasThis && method.OwningType.IsString && method.IsConstructor; if (fCtorOfVariableSizedObject) { hasThis = false; } bool isVarArg = false; TypeHandle returnType = new TypeHandle(signature.ReturnType); TypeHandle[] parameterTypes = new TypeHandle[signature.Length]; for (int parameterIndex = 0; parameterIndex < parameterTypes.Length; parameterIndex++) { parameterTypes[parameterIndex] = new TypeHandle(signature[parameterIndex]); } CallingConventions callingConventions = (hasThis ? CallingConventions.ManagedInstance : CallingConventions.ManagedStatic); bool hasParamType = method.RequiresInstArg() && !isUnboxingStub; // On X86 the Array address method doesn't use IL stubs, and instead has a custom calling convention if ((method.Context.Target.Architecture == TargetArchitecture.X86) && method.IsArrayAddressMethod()) { hasParamType = true; } bool extraFunctionPointerArg = false; bool[] forcedByRefParams = new bool[parameterTypes.Length]; bool skipFirstArg = false; bool extraObjectFirstArg = false; ArgIteratorData argIteratorData = new ArgIteratorData(hasThis, isVarArg, parameterTypes, returnType); ArgIterator argit = new ArgIterator( method.Context, argIteratorData, callingConventions, hasParamType, extraFunctionPointerArg, forcedByRefParams, skipFirstArg, extraObjectFirstArg); int nStackBytes = argit.SizeOfFrameArgumentArray(); // Allocate a fake stack CORCOMPILE_GCREFMAP_TOKENS[] fakeStack = new CORCOMPILE_GCREFMAP_TOKENS[transitionBlock.SizeOfTransitionBlock + nStackBytes]; // Fill it in FakeGcScanRoots(method, argit, fakeStack, isUnboxingStub); // Encode the ref map uint nStackSlots; if (_target.Architecture == TargetArchitecture.X86) { uint cbStackPop = argit.CbStackPop(); WriteStackPop(cbStackPop / (uint)_target.PointerSize); nStackSlots = (uint)(nStackBytes / _target.PointerSize + _transitionBlock.NumArgumentRegisters); } else { nStackSlots = (uint)((transitionBlock.SizeOfTransitionBlock + nStackBytes - _transitionBlock.OffsetOfFirstGCRefMapSlot) / _target.PointerSize); } for (uint pos = 0; pos < nStackSlots; pos++) { int offset = _transitionBlock.OffsetFromGCRefMapPos(checked ((int)pos)); CORCOMPILE_GCREFMAP_TOKENS token = fakeStack[offset]; if (token != CORCOMPILE_GCREFMAP_TOKENS.GCREFMAP_SKIP) { WriteToken(pos, (byte)token); } } Flush(); }
public void GetCallRefMap(MethodDesc method) { TransitionBlock transitionBlock = TransitionBlock.FromTarget(method.Context.Target); bool hasThis = (method.Signature.Flags & MethodSignatureFlags.Static) == 0; bool isVarArg = false; TypeHandle returnType = new TypeHandle(method.Signature.ReturnType); TypeHandle[] parameterTypes = new TypeHandle[method.Signature.Length]; for (int parameterIndex = 0; parameterIndex < parameterTypes.Length; parameterIndex++) { parameterTypes[parameterIndex] = new TypeHandle(method.Signature[parameterIndex]); } CallingConventions callingConventions = (hasThis ? CallingConventions.ManagedInstance : CallingConventions.ManagedStatic); bool hasParamType = method.GetCanonMethodTarget(CanonicalFormKind.Specific).RequiresInstArg(); bool extraFunctionPointerArg = false; bool[] forcedByRefParams = new bool[parameterTypes.Length]; bool skipFirstArg = false; bool extraObjectFirstArg = false; ArgIteratorData argIteratorData = new ArgIteratorData(hasThis, isVarArg, parameterTypes, returnType); ArgIterator argit = new ArgIterator( method.Context, argIteratorData, callingConventions, hasParamType, extraFunctionPointerArg, forcedByRefParams, skipFirstArg, extraObjectFirstArg); int nStackBytes = argit.SizeOfFrameArgumentArray(); // Allocate a fake stack CORCOMPILE_GCREFMAP_TOKENS[] fakeStack = new CORCOMPILE_GCREFMAP_TOKENS[transitionBlock.SizeOfTransitionBlock + nStackBytes]; // Fill it in FakeGcScanRoots(method, argit, fakeStack); // Encode the ref map uint nStackSlots; if (_target.Architecture == TargetArchitecture.X86) { uint cbStackPop = argit.CbStackPop(); WriteStackPop(cbStackPop / (uint)_target.PointerSize); nStackSlots = (uint)(nStackBytes / _target.PointerSize + _transitionBlock.NumArgumentRegisters); } else { nStackSlots = (uint)((transitionBlock.SizeOfTransitionBlock + nStackBytes - _transitionBlock.OffsetOfFirstGCRefMapSlot) / _target.PointerSize); } for (uint pos = 0; pos < nStackSlots; pos++) { int ofs; if (_target.Architecture == TargetArchitecture.X86) { ofs = (int)(pos < _transitionBlock.NumArgumentRegisters ? _transitionBlock.OffsetOfArgumentRegisters + _transitionBlock.SizeOfArgumentRegisters - (pos + 1) * _target.PointerSize : _transitionBlock.OffsetOfArgs + (pos - _transitionBlock.NumArgumentRegisters) * _target.PointerSize); } else { ofs = (int)(_transitionBlock.OffsetOfFirstGCRefMapSlot + pos * _target.PointerSize); } CORCOMPILE_GCREFMAP_TOKENS token = fakeStack[ofs]; if (token != CORCOMPILE_GCREFMAP_TOKENS.GCREFMAP_SKIP) { WriteToken(pos, (byte)token); } } Flush(); }