c 와 java 의 차이점
- 함수호출을 c 에서는 call procedure, java 에서는 invoke method
- 객체참조를 c 에서는 포인터, java 에서는 object reference
- c 에서는 메모리를 동적할당한 후에 명시적으로 해제해야하는 반면, java 에서는 사용자가 그렇지 않았을 때의 오류를 방지하기 위해 garbage collector가 참조되지 않는 힙 메모리를 정리한다. (full gc 등) 그래서 java 에서는 free 라는 예약어가 없다.
- c array 은 bound 검사를 하지 않는다. java 는 배열 선언 시 해당 배열에 대한 길이를 따로 저장하고, 범위를 초과하는 참조에 대해서 runtime 에 오류를 발생시킨다.
Java Bytecodes vs RISC-V instructions
- 컴파일을 간단하게 하기 위해서, JVM은 연산을 레지스터에서 하지 않는다. operands 를 스택에 푸쉬하고 계산한 후에 스택에서 팝한다.
- JVM 이 처음 설계될 당시 전체 코드 사이즈가 커질 것을 우려해, 개별 instruction 의 크기가 1~5 byte 로 다양하다. 반면 RISC-V instructions 은 4bytes 로 고정된 ISA 이다.
- JVM 에는 safety를 위한 기능을 내장한 명령어들이 있다. 예를 들어 array data transfer instructions는 첫번째 인자가 reference이면서 두번째 인자인 인덱스가 배열 바운드를 넘지 않도록 검사한다.
- garbage collector 가 모든 live pointers 를 찾을 수 있도록 JVM 은 주소를 계산하는 instruction 과 integer를 계산하는 instruction을 구분한다. 그래서 JVM 은 operand 만 봐도 주소인지 아닌지 알 수 있다. 반면 RISC-V 에서는 x10 레지스터를 보고 안에 주소값인지 integer 인지 구분할 수 없다.
- 힙 메모리에 배열을 할당하거나 메소드를 invoke 하는 등의 Java-specific instructions 이 존재한다.

Complie Java
컴파일된 .class 파일은 single class 에 대한 바이트코드로 되어있으며, 크게 table 과 pool 로 나눌 수 있다.
table 은 메소드들의 주소를 갖고 있고, pool 은 상수값들을 갖고 있어서 마치 symbol table 과 같은 역할을 한다. 이외에도 .class 파일은 부모 클래스 정보 등의 부가 정보도 포함한다.
// java code
while (save[i] == k)
i += 1;
/* java bytecode */
0 aload_3 // Push local variable 3 (save[]) onto stack
1 iload_1 // Push local variable 1 (i) onto stack
2 iaload // Put array element (save[i]) onto stack
3 iload_2 // Push local variable 2 (k) onto stack
4 if_icompne, Exit // Compare and exit if not equal
7 iinc, 1, 1 // Increment local variable 1 by 1 (i+=1)
10 go to 0 // Go to top of Loop (byte address 0)
/* java style RISC-V */
lw x5, 4(x25) // Temp reg x5 = length of array save
Loop:
blt x22, x0, IndexOutOfBounds // if i<0, goto Error
bge x22, x5, IndexOutOfBounds // if i>=length, goto Error
slli x10, x22, 2 // Temp reg x10 = i * 4
add x10, x10, x25 // x10 = address of save[i]
lw x9, 8(x10) // Temp reg x9 = save[i]
bne x9, x24, Exit // go to Exit if save[i] ≠ k
addi x22, x22, 1 // i = i + 1
beq x0, x0, Loop // go to Loop
Exit:
Invoking Methods in Java
- 객체를 가리키는 포인터가 null 은 아닌지 확인
- 해당 객체가 이용가능한 methods 의 정보를 갖고 있는 table 의 주소를 불러옴
- method 의 주소를 불러옴
- 리턴 레지스터에 다음 pc 값을 설정
- method 주소로 jump
아래와 같이 정렬하는 코드가 있을 때,
public class sort {
public static void sort (Comparable[] v) {
for (int i = 0; i < v.length; i += 1) {
for (int j = i – 1; j >= 0 && v[j].compareTo(v[j + 1]); j –= 1) {
swap(v, j);
}
}
protected static void swap(Comparable[] v, int k) {
Comparable temp = v[k];
v[k] = v[k+1];
v[k+1] = temp;
}
}
RISC-V 형태의 instructions 으로는 아래와 같이 나타낼 수 있다.
파란색 글씨는 JVM bytecode instructions 에 내장되어있는 부가기능들이다. (c에는 없는 기능이라고 보면 쉬울 듯)

