Информация об изменениях

Сообщение Re[3]: protect variables от 09.03.2016 1:35

Изменено 09.03.2016 1:49 Evgeny.Panasyuk

Здравствуйте, c-smile, Вы писали:

CS>аргументы или перменные — не важно.

CS>Они все на стеке лежат если рассматривать идеальную "C машину".

Не идеальную, а простую.

CS>Практика показывает что не всегда на стеке, а например в регистрах.

CS>Не сильно хочется влазить в специфику процессоров или компиляторов. Сейчас оно компилируется всем что шевелится, т.е. чистый и незамутнённый C/C++.
CS>Но если без этого никак то придётся наверное.

Даже если будешь некроссплатформенно сканировать регистры и стек, то проблема с консервативностью всё равно останется

CS>В принципе я могу текущую VM* положить в TLS если это поможет. Чтобы не таскать параметр для PROTECT например.


Либо через TLS, либо через быструю маску по адресу — проблема доп параметра решается. Ещё есть какие-нибудь барьеры для использовании RAII обёрток?

P.S. В SpiderMonkey используются именно RAII обёртки:

All GC thing pointers stored on the stack (i.e., local variables and parameters to functions) must use the JS::Rooted<T> class.
...
SpiderMonkey makes it easy to remember to use JS::Rooted<T> types instead of a raw pointer because all of the API methods that may GC take a JS::Handle<T>, as described below.
...
All GC thing pointers that are parameters to a function must be wrapped in JS::Handle<T>. A JS::Handle<T> is a reference to a JS::Rooted<T>. All JS::Handle<T> are created implicitly by referencing a JS::Rooted<T>: It is not valid to create a JS::Handle<T> manually. Like JS::Rooted<T>, a JS::Handle<T> can be used as if it were the underlying pointer.

Since only a JS::Rooted<T> will cast to a JS::Handle<T>, the compiler will enforce correct rooting of any parameters passed to a function that may trigger GC. JS::Handle<T> exists because creating and destroying a JS::Rooted<T> is not free (though it only costs a few cycles). Thus, it makes more sense to only root the GC thing once and reuse it through an indirect reference. Like a reference, a JS::Handle is immutable: it can only ever refer to the JS::Rooted<T> that it was created for.

Вот релевантный код — там например строится интрузивный стек из Rooted.
Re[3]: protect variables
Здравствуйте, c-smile, Вы писали:

CS>аргументы или перменные — не важно.

CS>Они все на стеке лежат если рассматривать идеальную "C машину".

Не идеальную, а простую.

CS>Практика показывает что не всегда на стеке, а например в регистрах.

CS>Не сильно хочется влазить в специфику процессоров или компиляторов. Сейчас оно компилируется всем что шевелится, т.е. чистый и незамутнённый C/C++.
CS>Но если без этого никак то придётся наверное.

Даже если будешь некроссплатформенно сканировать регистры и стек, то проблема с консервативностью всё равно останется

CS>В принципе я могу текущую VM* положить в TLS если это поможет. Чтобы не таскать параметр для PROTECT например.


Либо через TLS, либо через быструю маску по адресу — проблема доп параметра решается. Ещё есть какие-нибудь барьеры для использования RAII обёрток?

P.S. В SpiderMonkey используются именно RAII обёртки:

All GC thing pointers stored on the stack (i.e., local variables and parameters to functions) must use the JS::Rooted<T> class.
...
SpiderMonkey makes it easy to remember to use JS::Rooted<T> types instead of a raw pointer because all of the API methods that may GC take a JS::Handle<T>, as described below.
...
All GC thing pointers that are parameters to a function must be wrapped in JS::Handle<T>. A JS::Handle<T> is a reference to a JS::Rooted<T>. All JS::Handle<T> are created implicitly by referencing a JS::Rooted<T>: It is not valid to create a JS::Handle<T> manually. Like JS::Rooted<T>, a JS::Handle<T> can be used as if it were the underlying pointer.

Since only a JS::Rooted<T> will cast to a JS::Handle<T>, the compiler will enforce correct rooting of any parameters passed to a function that may trigger GC. JS::Handle<T> exists because creating and destroying a JS::Rooted<T> is not free (though it only costs a few cycles). Thus, it makes more sense to only root the GC thing once and reuse it through an indirect reference. Like a reference, a JS::Handle is immutable: it can only ever refer to the JS::Rooted<T> that it was created for.

Вот релевантный код — там например строится интрузивный стек из Rooted.