Столкнулся со следующей проблемой: есть код, вызывающий метод Assembly.GetCallingAssembly. Идея проста -- получаем вызвавшую сборку, а затем анализируем ее ресурсы и атрибуты. Все работало прекрасно и замечательно, пока в один прекрасный день при сборке в release не произошел inlining, в результате чего мы стали искать ресурсы совсем не там, где нужно.
Есть ли какие-то общепринятые способы решения этой проблемы? Хотелось бы запретить jitter-у делать inlining для некоторого отдельного метода. Конечно, можно просто сделать его достаточно длинным, но хотелось бы чего-то более правильного.
Кстати, в исходниках ротора есть забавный фрагмент:
// declaring a local var of this enum type and passing it by ref into a function that needs to do a
// stack crawl will both prevent inlining of the calle and pass an ESP point to stack crawl to
[Serializable]
internal enum StackCrawlMark
{
LookForMe = 0,
LookForMyCaller = 1,
LookForMyCallersCaller = 2
}
Этот StackCrawlMark дальше используется в Get[Calling/Executing]Assembly.
Здравствуйте, Mab, Вы писали:
Mab>Хотелось бы запретить jitter-у делать inlining для некоторого отдельного метода. Конечно, можно просто сделать его достаточно длинным, но хотелось бы чего-то более правильного.
Хм... можно унаследовать класс (в котором определен метод, что инлайнится) от MarshalByRefObject
... << RSDN@Home 1.1.3 stable >>
SAV>Хм... можно унаследовать класс (в котором определен метод, что инлайнится) от MarshalByRefObject
В качестве quickfix-а так и сделал, но вообще забавно...
Здравствуйте, Mab, Вы писали:
SAV>>Хм... можно унаследовать класс (в котором определен метод, что инлайнится) от MarshalByRefObject
Mab>В качестве quickfix-а так и сделал, но вообще забавно...
а что именно забавно?
... << RSDN@Home 1.1.3 stable >>
SAV>а что именно забавно?
Просто не ясно, какова получается строгая семантика у этого метода. Конечно, можно сказать, что это сборка, которая вызвала текущий метод с учетом inline-ов. Только пратическая польза от этого невелика. Ведь то, что сейчас не инлайнится, вполне может начать инлайниться в следующих версиях FW. Не все же классы от MBR наследовать
Здравствуйте, Mab, Вы писали:
Mab>Столкнулся со следующей проблемой: есть код, вызывающий метод Assembly.GetCallingAssembly. Идея проста -- получаем вызвавшую сборку, а затем анализируем ее ресурсы и атрибуты. Все работало прекрасно и замечательно, пока в один прекрасный день при сборке в release не произошел inlining, в результате чего мы стали искать ресурсы совсем не там, где нужно.
Mab>Есть ли какие-то общепринятые способы решения этой проблемы? Хотелось бы запретить jitter-у делать inlining для некоторого отдельного метода.
Не знаю, общепринятый-ли этот способ, но как вариант: пройтись по стэку до нахождения типа, отличного вашего:
Что-то типа след.:
Assembly GetCallingAssembly()
{
int MAX_SKIP_FRAMES = 10;
Type theCallingType = null;
int theSkipFrames = 1;
while (true)
{
if (theSkipFrames == MAX_SKIP_FRAMES) return null;
theCallingType = new StackFrame(theSkipFrames++).GetMethod().DeclaringType;
if (theCallingType != this.GetType()) break;
}
return theCallingType.Assembly;
}
Здравствуйте, Mab, Вы писали:
Mab>Хотелось бы запретить jitter-у делать inlining для некоторого отдельного метода.
[MethodImpl(MethodImplOptions.NoInlining)]
Mab>пока в один прекрасный день при сборке в release не произошел inlining, в результате чего мы стали искать ресурсы совсем не там, где нужно.
А ты точно знаешь, что дело в inline? По идее, GetCallingAssembly не должен от оптимизаций зависеть.
... << RSDN@Home 1.1.3 stable >>