CrownyJIT 잔여 3종 배선 — FP지역루프·중첩루프·CALL잎함수 (완주)
개요
2026-07-05 직전 세션(루프 백엣지 JIT 완주, 전역var만)이 남긴 과제 3종을 모두 배선.
전부
차등검증 게이트(채택 전 네이티브 vs 인터프리터 bit-identical, 불일치=영구 BAIL) 통과분만 채택.
공유
crownyc.c/
crownyc 무수정·무재빌드(타임스탬프 20:01 그대로). 산출물
crownyc-jit 별도.
무엇을 배선했나 (증분 3종, 순서대로)
① FP상대 지역변수 루프 (완주)
- 함수 내부
동안 루프의 지역변수 접근 LOAD_FP(80); DATA off; ADD(81); LOAD/STORE 패턴 인식.
bare LOAD_FP; LOAD = FP+0. 표현식스택에 센티넬 FPBASE/FPADDR:<off>로 추적, 산술 피연산자로 새면 BAIL.
- 주소 종류 분리: ABS(전역 절대주소, baking) vs FP(frame_ptr 상대, 디스패치 시점 계산).
프레임마다 frame_ptr가 달라 baking 금지 →
cj_abs(slot,i)가 채택·게이트·디스패치마다
frame_ptr+off 재계산.
- 네이티브 함수 시그니처에
long fpbase 추가(전역var는 무시). cj_tkind[][] 배열로 kind 저장.
② 중첩 루프 (완주 — 내부 독립 JIT)
- 외곽 루프 영역은 내부 백엣지(내부헤더로 점프)를 포함 → 단일 canonical shape 위반 → 외곽 BAIL(안전).
- 내부 루프는 자기 헤더pc로 독립 관측·채택 → 반복의 대부분이 내부라 실효 가속(코드 변경 없이 ①로 성립).
- 전역·FP지역 중첩 모두 byte-identical 실증.
③ CALL 잎(leaf)함수 인라인 (완주 — 순수·단일인자 한정)
cj_note_call을 실제 CALL(opcode 247)에 배선 → 함수주소별 호출빈도 계측(calls/fns 통계).
- 루프 트랜스파일러가 CALL(247)을 인라인: 타깃이 순수(전역write無)+단일인자+단일반환+내부CALL/루프無 잎함수면
cj_transpile_leaf가 C 함수로 변환해 루프 본문에 인라인 → 드라이버 루프 전체가 네이티브.
- 잎함수 검증은 별도 게이트 불필요 — 기존 루프 메모리-diff 게이트가 인라인 결과까지 bit-identical 검증(오류=출력 무오염).
- 비순수/다인자/루프포함 함수는 BAIL(안전) → 인터프리터. (그런 함수는 내부 루프가 ①로 별도 가속됨.)
신규 커널 벤치 (전부 인터프리터와 BYTE-IDENTICAL)
| 커널 | 인터프리터 | JIT | 배속 | 출력 |
|---|
① 함수내 FP지역 루프 10M s+=(i*i)/7 | 21.2s | native 520ms | ~40x | ✅ -35421475230 |
② 중첩(전역) 3000×3000 s+=(i*j)/7 | 5.06s | 0.13s(user) | ~39x | ✅ 66633528046 |
| ② 중첩(FP지역, 함수내) 3000×3000 | 13.2s | 0.15s(user) | ~88x | ✅ 66633528046 |
③ 잎함수 인라인 1M f(i)=(i*i+i)/7 드라이버루프 | 1.84s | native 34ms | 큼 | ✅ -24726390113 |
- ②는 내부 루프 헤더가 독립 JIT되어 outer iteration마다 native_fires(2997회).
- ③은 잎함수가 드라이버 루프에 인라인되어 루프 전체 네이티브(leaves_inlined=1).
회귀 (4종, 단일 write stdin, base==jitoff==jiton 전부 IDENTICAL)
| 프로그램 | 입력 | 결과 |
|---|
| 크라우니코드뇌 | 0 1 1 0 0 | ✅ IDENTICAL |
| 래칫판정 | 0 55 60 5 | ✅ IDENTICAL |
| 작업구분 | 0+포트 상태 조회해줘 | ✅ IDENTICAL |
| 브레인결재 | 0 안건C 85 4 2 0 | ✅ IDENTICAL |
- JIT-off
crownyc-jit == 공유
crownyc (드리프트 0, 3종 재확인).
실서비스 가속 실증
- 웹서버v2.한선: 정수 루프 0개(
동안/반복문 0) → I/O·문자열 바운드 → JIT 미발동(효과 0%). 서버형 실증.
- KPS지수.한선: 루프는 있으나 소형(임계 10000 미도달, calls=10) → 미채택(0%).
- finance 복리 재투자 시뮬(실도메인 컴퓨트, 스칼라정수): 200k 시나리오 × 60기간 복리누적.
인터프리터
14.36s → JIT 0.62s(user), ~23x, byte-identical
236800000.
내부 FP지역 루프(복리누적)가 임계 도달 후 채택, 199834회 native fire.
- 정직한 결론: 크라우니 실서비스는 대부분 I/O·문자열·맵 바운드라 서버 요청경로엔 JIT 효과 0%.
JIT의 실가치는 서비스에 박힌
스칼라 정수 수치커널(금융 복리·통계·수론·신호)로, 거기선 20~90x·무오염.
관련 파일 (전부 /Users/ef/CrownyOS/crownyc/)
crownyc_jit_hot.c — ★트랜스파일러 본체. 증분3종 추가: FP주소분류(cj_addr_expr/cj_abs/cj_tkind), 잎인라인(cj_transpile_leaf), CALL 카운팅(cj_note_call).
crownyc_jitmain.c — crownyc.c 복사본. CALL(247)에 cj_note_call 배선 1줄 추가. 빌드: cc -O2 -o crownyc-jit crownyc_jitmain.c -framework Security -framework CoreFoundation
crownyc-jit — 산출 바이너리(별도).
crownyc_jit_hot.한선 — 판정 로직 한선씨 동반본(증분3종 판정함수 추가: 주소분류/중첩판정/잎인라인판정).
crownyc.c / crownyc — 공유, 무손상(20:01 타임스탬프 그대로).
남은 작업 (다음 세션 인수인계)
- 다인자 잎함수 인라인: 현재 nargs≤1만. 다인자는 caller 인자 순서↔함수 param pull 순서 매핑 필요.
- 비순수 잎함수(전역write 있는 함수) 인라인: 전역 write를 루프 taddr 집합에 병합해야(게이트가 커버).
- for 루프(반복문) / 복수 탈출가드: 현재 단일 JMPIFN 가드 + 단일 백엣지 canonical shape만.
- 비교 GT/GE/EQ opcode 확장: 현재 LT(165)만. 확장 시 게이트 재검증.
- 손익분기 게이팅: cc 컴파일 지연(~0.1s) 대비 루프 반복수 임계 튜닝(짧은 루프는 미채택이 유리).
- 자족 JIT(copy-and-patch): 소비자앱용(cc 불필요) 별도 트랙.
안전수칙 준수
- 공유
crownyc.c/crownyc 무수정·무재빌드. 산출물 crownyc-jit 별도.
- 기본 오프(opt-in CROWNY_JIT). 부팅 self-test + 런타임 차등검증 게이트 이중 안전.
- 새 지원영역(FP/중첩/잎인라인) 전부 동일 게이트 통과분만 채택 — 트랜스파일 버그는 출력 무오염(BAIL=인터프리터).
- 데몬·커밋·영속인프라 생성 없음.