260 likes | 746 Views
JVM Architecture. Local storage area Randomly accessible Just like standard RAM Stores variables (eg. an array) Have to specify address to load/store data Stack of operands Grows dynamically like the MIPS stack Abstraction : can access only the top element
E N D
JVM Architecture • Local storage area • Randomly accessible • Just like standard RAM • Stores variables (eg. an array) • Have to specify address to load/store data • Stack of operands • Grows dynamically like the MIPS stack • Abstraction : can access only the top element • Serves two purposes: 1. Call stack (like MIPS stack)(you don’t worry about this for the simulation because you have no function calls to handle) 2. Operand stack (like MIPS registers)(this is what you need to implement) • Program -- Java bytecodes • Variable length instructions • STORE/PUSH : operands come from instruction • LOAD/POP : operands come from stack • Arithmetic : operands come from stack • Branch/Goto : operands from stack, offset from instruction Ashish Sabharwal
JVM Instructions • Four categories • Arithmetic • Stack • Memory • Branch/jump • All immediates are 8-bit or 16-bit, stored as 32-bits • 8-bit: consider immed as a signed 8-bit number • 16-bit: consider immedhi_immedlotogether as a signed 16-bit number • For simulation, we store immediates as 32-bit numbers Why ? • Implementation: 1. Read immediate value (8-bit or 16-bit) 2. Sign extend it to 32 bits (done by decode stage) 3. Then use normal MIPS instructions to simulate JVM instruction • Semantically, each instruction has zero or one argument • 2 argument bytes just denote a 16-bit argument • Execute stage should be able to assume 1 argument passed as 32-bit sign-extended parameter Ashish Sabharwal
JVM Instructions (cont’d) • Each instruction can be implemented in terms of 4 basic operations: • POP <value> return top <value>; decrement JVM stack pointer • PUSH <value> increment stack pointer; store <value> onto stack • PUSH * <value> increment stack pointer; load value from memory_base + 4*<value> onto stack(4*<value> because we store every argument as 4 bytes) • Add offset to JVM PC(JVM PC is just the address of the current bytecode)(Offset here is the number of bytes, not bytecodes) • All you need to do is • Implement these four operations • Expand each instruction in terms of these operations eg. IADD : POP v1, POP v2, PUSH (v1+v2) • For those using sample solutionJust fill in appropriate things in handler routines • Assume • There will be no overflows/underflows • All JVM programs will have a valid offset(remember offset is number of bytes, not bytecodes) Ashish Sabharwal
JVM Programming • Write a JVM function that, given two addresses, adds the variables at these addresses and returns the result on the stack. C Prototype: int sum(int* x, int* y); • Before calling the JVM routine, you main function initializes JVM memory with the correct data • # fill JVM memory/stack with data • la $t0, memory # load memory_base • sw 25, 0($t0) # x = 0, *x = 25 • sw 15, 4($t0) # y = 1, *y = 15 # y is a word address for our JVM implementation # Therefore, y = 1 and not 4, though it is actually stored at # offset 4 • la $t1, stack # load stack_base • subi $t1, $t1, 8 # arguments to sum # go on JVM stack • sw 0, 0($t1) # x (word address) • sw 1, 4($t1) # y (word address) • # fill in arguments for the JVM procedure • …….. • # call your JVM routine • jal JVM • # print value at the top of stack • …….. Ashish Sabharwal
JVM programming (cont’d) • First write your JVM function in terms of symbolic instructions: • # stack starts with {y, x} • IALOAD # load *x # stack = {y, *x} • ISTORE 8 # store *x in local memory # stack = {y} • IALOAD # load *y # stack = {*y} • ILOAD 8 # stack = {*y, *x} • IADD # stack = {*x + *y} • END • Now convert each of these into actual bytecodes • 0x2e, 0x36, 0x08, 0x2e, 0x15, 0x08, 0x60, 0x00 Ashish Sabharwal