Every instruction that is added to the code of a method may have changed the size of the operand stack, which could mean that the variable containing the maximum number of words on the operand stack may have to be updated. To check if it has to be updated, I created a variable st_size in the Code attribute that keeps track of the current number of words on the operand stack. I also created an array indexed by the opcodes of the instructions that contains all the changes in stack for every instruction. Every time an instruction is added, the change in stack is looked up in the array and added to or subtracted from the variable st_size. After that is checked if the current number of words on the operand stack is larger than the value of the variable containing the maximum number of words on the operand stack. If this is so, the maximum number of words on the stack is updated.
There are some instructions that have no constant change in stack, for example the invokestatic instruction to invoke a static method where the parameters are popped from the operand stack. For these instructions the minimum change in stack is in the array, and if there is more change in stack, you have to count that yourself, so this can be added or subtracted in addition to the minimum change in stack.