diff --git a/core/src/main/java/org/jruby/ir/interpreter/ExitableInterpreterEngine.java b/core/src/main/java/org/jruby/ir/interpreter/ExitableInterpreterEngine.java index cb6138044018..6ffa7e8824b1 100644 --- a/core/src/main/java/org/jruby/ir/interpreter/ExitableInterpreterEngine.java +++ b/core/src/main/java/org/jruby/ir/interpreter/ExitableInterpreterEngine.java @@ -70,7 +70,7 @@ public ExitableReturn interpret(ThreadContext context, Block block, IRubyObject StaticScope currScope = interpreterContext.getStaticScope(); DynamicScope currDynScope = context.getCurrentScope(); - int[] rescuePCs = interpreterContext.getRescueIPCs(); + InterpreterContext.RescueTable rescuePCs = interpreterContext.getRescueIPCs(); // Init profiling this scope boolean debug = IRRuntimeHelpers.isDebug(); @@ -95,7 +95,7 @@ public ExitableReturn interpret(ThreadContext context, Block block, IRubyObject Operation operation = instr.getOperation(); if (debug) { - Interpreter.LOG.info("I: " + ipc + ", R: " + rescuePCs[ipc] + " - " + instr + ">"); + Interpreter.LOG.info("I: " + ipc + ", R: " + rescuePCs.get(ipc) + " - " + instr + ">"); Interpreter.interpInstrsCount++; } else if (profile) { Profiler.instrTick(operation); @@ -150,7 +150,7 @@ public ExitableReturn interpret(ThreadContext context, Block block, IRubyObject } catch (Throwable t) { if (debug) extractToMethodToAvoidC2Crash(instr, t); - ipc = rescuePCs == null ? -1 : rescuePCs[ipc]; + ipc = rescuePCs == null ? -1 : rescuePCs.get(ipc); if (debug) { Interpreter.LOG.info("in : " + interpreterContext.getScope() + ", caught Java throwable: " + t + "; excepting instr: " + instr); diff --git a/core/src/main/java/org/jruby/ir/interpreter/FullInterpreterContext.java b/core/src/main/java/org/jruby/ir/interpreter/FullInterpreterContext.java index bbc2e9998c73..febfef6e0be5 100644 --- a/core/src/main/java/org/jruby/ir/interpreter/FullInterpreterContext.java +++ b/core/src/main/java/org/jruby/ir/interpreter/FullInterpreterContext.java @@ -154,7 +154,9 @@ public void generateInstructionsForInterpretation() { } } - this.rescueIPCs = rescueIPCs; + checkRescueIPCs(rescueIPCs); + + this.rescueIPCs = new RescueTable(rescueIPCs); this.instructions = linearizedInstrArray; // System.out.println("SCOPE: " + getScope().getId()); @@ -222,9 +224,9 @@ public FullInterpreterContext duplicate() { public int determineRPC(int ipc) { - int length = rescueIPCs.length; + int length = rescueIPCs.size(); for (int i = 0; i + 1 < length; i += 2) { - if (ipc <= rescueIPCs[i]) return rescueIPCs[i + 1]; + if (ipc <= rescueIPCs.get(i)) return rescueIPCs.get(i + 1); } throw new RuntimeException("BUG: no RPC found for " + getFileName() + ":" + getName() + ":" + ipc); diff --git a/core/src/main/java/org/jruby/ir/interpreter/InterpreterContext.java b/core/src/main/java/org/jruby/ir/interpreter/InterpreterContext.java index 2ec9b3b6d638..56528de76b96 100644 --- a/core/src/main/java/org/jruby/ir/interpreter/InterpreterContext.java +++ b/core/src/main/java/org/jruby/ir/interpreter/InterpreterContext.java @@ -35,7 +35,7 @@ public class InterpreterContext { // Contains pairs of values. The first value is number of instrs in this range + number of instrs before // this range. The second number is the rescuePC. getRescuePC(ipc) will walk this list and first odd value // less than this value will be the rpc. - protected volatile int[] rescueIPCs = null; + protected volatile RescueTable rescueIPCs = null; // Cached computed fields protected boolean hasExplicitCallProtocol; // Only can be true in Full+ @@ -125,12 +125,34 @@ private Instr[] prepareBuildInstructions(List instructions) { rescueIPCs[ipc] = rpc; } - this.rescueIPCs = rescueIPCs; + checkRescueIPCs(rescueIPCs); + + this.rescueIPCs = new RescueTable(rescueIPCs); return linearizedInstrArray; } - public int[] getRescueIPCs() { + public static class RescueTable { + final int[] table; + public RescueTable(int[] table) { + this.table = table; + } + public int get(int i) { + return table[i]; + } + + public int size() { + return table.length; + } + } + + static void checkRescueIPCs(int[] rescueIPCs) { + for (int i = 0; i < rescueIPCs.length; i++) { + if (rescueIPCs[i] == 0) throw new RuntimeException("BUG: there should never be zero IPCs in the rescue table"); + } + } + + public RescueTable getRescueIPCs() { return rescueIPCs; } diff --git a/core/src/main/java/org/jruby/ir/interpreter/StartupInterpreterEngine.java b/core/src/main/java/org/jruby/ir/interpreter/StartupInterpreterEngine.java index 04c8384dbbf8..3473fcd7b57d 100644 --- a/core/src/main/java/org/jruby/ir/interpreter/StartupInterpreterEngine.java +++ b/core/src/main/java/org/jruby/ir/interpreter/StartupInterpreterEngine.java @@ -42,7 +42,7 @@ public IRubyObject interpret(ThreadContext context, Block block, IRubyObject sel StaticScope currScope = interpreterContext.getStaticScope(); DynamicScope currDynScope = context.getCurrentScope(); - int[] rescuePCs = interpreterContext.getRescueIPCs(); + InterpreterContext.RescueTable rescuePCs = interpreterContext.getRescueIPCs(); // Init profiling this scope boolean debug = IRRuntimeHelpers.isDebug(); @@ -55,7 +55,7 @@ public IRubyObject interpret(ThreadContext context, Block block, IRubyObject sel Operation operation = instr.getOperation(); if (debug) { - Interpreter.LOG.info("I: " + ipc + ", R: " + rescuePCs[ipc] + " - " + instr + ">"); + Interpreter.LOG.info("I: " + ipc + ", R: " + rescuePCs.get(ipc) + " - " + instr + ">"); Interpreter.interpInstrsCount++; } else if (profile) { Profiler.instrTick(operation); @@ -109,7 +109,7 @@ public IRubyObject interpret(ThreadContext context, Block block, IRubyObject sel } catch (Throwable t) { if (debug) extractToMethodToAvoidC2Crash(instr, t); - ipc = rescuePCs == null ? -1 : rescuePCs[ipc]; + ipc = rescuePCs == null ? -1 : rescuePCs.get(ipc); if (debug) { Interpreter.LOG.info("in : " + interpreterContext.getScope() + ", caught Java throwable: " + t + "; excepting instr: " + instr);