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

Сообщение protect variables от 05.03.2016 3:15

Изменено 05.03.2016 3:29 c-smile

есть имплментация script virtual machine.

Эта VM использует moving garbage collector, т.е. объекты гуляют по памяти когда происходит GC.

Вот пример кода

typedef uint64 value; // for object contains pointer to memory

value csf_native_function(VM* c, value obj, value p1, value p2) {

  if( !cs_is_string(p1) )
    p1 = cs_allocate_string(c, ' ', 256); // may cause GC()
  // obj, p1, p2 could be wrong at this point due to GC in the line above
  return csf_other_func(c, obj, p1, p2);
}


Т.к. cs_allocate_string() может вызывать GC() то значения obj, p1, p2 могут быть не валидными —
указывать на старые локации объектов.

Решаю эту проблему с помощью специадьного RAII объекта PROTECT:

value csf_native_function(VM* c, value obj, value p1, value p2) {
  PROTECT(c, obj, p1, p2);
  if( !cs_is_string(p1) )
    p1 = cs_allocate_string(c, ' ', 256); // may cause GC()
  // obj, p1, p2 could be wrong at this point due to GC in the line above
  return csf_other_func(c, obj, p1, p2);
}


Этот protect фактически делает следующее:

cs_push_var_address(c, &obj);
cs_push_var_address(c, &p1);
cs_push_var_address(c, &p2);

...

// at destructor
cs_pop_var_addresses(c,3)


Проблема в том что это PROTECT() нужно задавать явно. Иногда ошибаюсь и ловить проблему приходится долго и нудно.

Хочется построить что-то типа консервативного GC чтобы шерстил С/C++ стек на предмет чего-то похожего на pointers.
Но что-то мне говорит что ничего хорошего их этого не получится. Всякие там оптимизации, размещение переменных в регистрах и прочая.

Что-то еще можно придумть на эту тему? Приветствуются идеи любой степени сумашествия.
protect variables
есть имплментация script virtual machine.

Эта VM использует moving garbage collector, т.е. объекты гуляют по памяти когда происходит GC.

Вот пример кода

typedef uint64 value; // if object then contains pointer to memory

value csf_native_function(VM* c, value obj, value p1, value p2) {

  if( !cs_is_string(p1) )
    p1 = cs_allocate_string(c, ' ', 256); // may cause GC()
  // obj, p1, p2 could be wrong at this point due to GC in the line above
  return csf_other_func(c, obj, p1, p2);
}


Т.к. cs_allocate_string() может вызывать GC() то значения obj, p1, p2 могут быть не валидными —
указывать на старые локации объектов.

Решаю эту проблему с помощью специадьного RAII объекта PROTECT:

value csf_native_function(VM* c, value obj, value p1, value p2) {
  PROTECT(c, obj, p1, p2);
  if( !cs_is_string(p1) )
    p1 = cs_allocate_string(c, ' ', 256); // may cause GC()
  // obj, p1, p2 could be wrong at this point due to GC in the line above
  return csf_other_func(c, obj, p1, p2);
}


Этот protect фактически делает следующее:

cs_push_var_address(c, &obj);
cs_push_var_address(c, &p1);
cs_push_var_address(c, &p2);

...

// at destructor
cs_pop_var_addresses(c,3)


Проблема в том что это PROTECT() нужно задавать явно. Иногда ошибаюсь и ловить проблему приходится долго и нудно.

Хочется построить что-то типа консервативного GC чтобы шерстил С/C++ стек на предмет чего-то похожего на pointers.
Но что-то мне говорит что ничего хорошего их этого не получится. Всякие там оптимизации, размещение переменных в регистрах и прочая.

Что-то еще можно придумть на эту тему? Приветствуются идеи любой степени сумашествия.