mruby의 JIT에서 메소드 재정의를 처리하는 방법
mruby의 JIT는 코드의 자체 재기록을 구사함으로써 속도를 떨어뜨리지 않고 재정의에 대처하고 있습니다. 그러나 메모리 효율이 나쁘기 때문에 빈번한 다시 쓰기에는 적합하지 않습니다.
mruby의 JIT에서는 이런 식으로 생성 코드를 관리하고 있습니다. 이 경우는 메소드 foo의 경우입니다.
entry table이라는 것이 있고, RITE VM의 명령마다 대응하는 기계어 코드의 주소가 들어 있습니다. Tracing JIT이므로 프로그램이 모두 기계어로 되어 있는 보증은 없기 때문에, 이것을 보고 대응하는 기계어 명령이 있으면 거기에 점프 한다고 하는 구조가 되고 있습니다. 대응하는 기계어가 없는 경우는 0이 들어갑니다.
이제 메소드 foo를 다시 정의해 봅시다. 이 경우, 이미 곳곳에 foo의 호출이 흩어져 있어 이대로는 낡은 코드가 계속 사용되어 버립니다.
덧붙여서 mruby의 JIT에서는 call 명령이 아닌 jmp 명령을 사용하여 메소드 호출을합니다. 반환 대상은 callinfo에 저장됩니다.
재정의 시 이전에 정의된 명령어는 다음과 같이 다시 작성됩니다.
reset_caller는 이 무효화된 메소드를 호출한 블록이나 메소드의 생성된 기계어도 무효화하는 함수입니다. callinfo를 참조하면 caller의 irep를 취할 수 있으므로 이런 예술이 가능합니다.
reset_caller(mrb_reset_caller)의 정의는 여기에 있습니다.
mrb_reset_caller는 런처에서 레지스터에 들어있는 mrb_state 구조체 (esi)와 pc (ebx)를 꺼내 mrb_reset_caller_aux에 인수로 전달하는 것을하고 있습니다. 실제 작업은 mrb_reset_caller_aux가 수행합니다.
이렇게 패치 된 원래의 메소드를 호출하면 호출자가 reset_caller에 의해 지워집니다.
예쁘게 지워졌습니다. 이제 이 블록에서 원래의 기계어를 호출하지 않습니다. 실행 빈도가 높으면 즉시 새로운 메소드 정의의 기계어가 생성될 것입니다.
얼마나 많은 장소에서 불려도 똑같이 클리어되므로 문제 없습니다.
Reference
이 문제에 관하여(mruby의 JIT에서 메소드 재정의를 처리하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/miura1729/items/1ab49d34acf3e9e447f8텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)