From 0f7111240b95bc34553584edbced7bcc25778a08 Mon Sep 17 00:00:00 2001 From: "Flavio S. Glock" Date: Fri, 6 Mar 2026 13:57:00 +0100 Subject: [PATCH] Simplify LOAD_STRING and LOAD_BYTE_STRING interpreter opcodes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove redundant cache-check optimization that compared the existing register value before allocating. Benchmarking on ExifTool CanonRaw.t showed no measurable difference — the String.equals() cost offsets the saved allocation. Also improve LOAD_BYTE_STRING javadoc in Opcodes.java. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin --- .../backend/bytecode/BytecodeInterpreter.java | 17 ++--------------- .../perlonjava/backend/bytecode/Opcodes.java | 7 +++++-- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/perlonjava/backend/bytecode/BytecodeInterpreter.java b/src/main/java/org/perlonjava/backend/bytecode/BytecodeInterpreter.java index 5c2a7d16a..e7792cbf6 100644 --- a/src/main/java/org/perlonjava/backend/bytecode/BytecodeInterpreter.java +++ b/src/main/java/org/perlonjava/backend/bytecode/BytecodeInterpreter.java @@ -229,26 +229,13 @@ public static RuntimeList execute(InterpretedCode code, RuntimeArray args, int c case Opcodes.LOAD_STRING -> { int rd = bytecode[pc++]; int strIndex = bytecode[pc++]; - String s = code.stringPool[strIndex]; - RuntimeBase existing = registers[rd]; - if (!(existing instanceof RuntimeScalar rs - && rs.type == RuntimeScalarType.STRING - && s.equals(rs.value))) { - registers[rd] = new RuntimeScalar(s); - } + registers[rd] = new RuntimeScalar(code.stringPool[strIndex]); } case Opcodes.LOAD_BYTE_STRING -> { int rd = bytecode[pc++]; int strIndex = bytecode[pc++]; - String s = code.stringPool[strIndex]; - RuntimeBase existing = registers[rd]; - if (existing instanceof RuntimeScalar rs - && rs.type == RuntimeScalarType.BYTE_STRING - && s.equals(rs.value)) { - break; - } - RuntimeScalar bs = new RuntimeScalar(s); + RuntimeScalar bs = new RuntimeScalar(code.stringPool[strIndex]); bs.type = RuntimeScalarType.BYTE_STRING; registers[rd] = bs; } diff --git a/src/main/java/org/perlonjava/backend/bytecode/Opcodes.java b/src/main/java/org/perlonjava/backend/bytecode/Opcodes.java index cde25ef02..b5282ce18 100644 --- a/src/main/java/org/perlonjava/backend/bytecode/Opcodes.java +++ b/src/main/java/org/perlonjava/backend/bytecode/Opcodes.java @@ -1803,8 +1803,11 @@ public class Opcodes { public static final short SET_FROM_LIST = 371; /** - * Load byte string: rd = new RuntimeScalar(stringPool[index]) with BYTE_STRING type. - * Used for string literals under `no utf8` (the default). + * Load a non-UTF-8 string constant into a register. + * Creates a RuntimeScalar with BYTE_STRING type (Perl's default string encoding, + * equivalent to Latin-1/ISO-8859-1). This is the most common opcode in typical + * Perl programs — it loads hash keys, string literals, and identifiers. + * Compare with LOAD_STRING which loads UTF-8 flagged strings (from `use utf8` scope). * Format: LOAD_BYTE_STRING rd strIndex */ public static final short LOAD_BYTE_STRING = 372;