From 3ffb43420667eb800f5e5e3f419a98befa2facbc Mon Sep 17 00:00:00 2001 From: JarrodCTaylor Date: Thu, 12 Dec 2024 08:52:59 -0600 Subject: [PATCH] [CLJ-2891] Move constant initialization into nested classes --- src/jvm/clojure/lang/Compiler.java | 165 +++++++++++++++-------------- 1 file changed, 83 insertions(+), 82 deletions(-) diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 6324456fa1..877920add5 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -4786,6 +4786,7 @@ public final int constantsID(){ private DynamicClassLoader loader; private byte[] bytecode; + private Map constFieldBytecode; public ObjExpr(Object tag){ this.tag = tag; @@ -5096,14 +5097,7 @@ void compile(String superName, String[] interfaceNames, boolean oneTimeUse) thro emitStatics(cv); emitMethods(cv); - //static fields for constants - for(int i = 0; i < constants.count(); i++) - { - if(usedConstants.contains(i)) - cv.visitField(ACC_PUBLIC + ACC_FINAL - + ACC_STATIC, constantName(i), constantType(i).getDescriptor(), - null, null); - } + emitConstantFields(cv); //static fields for lookup sites for(int i = 0; i < keywordCallsites.count(); i++) @@ -5124,11 +5118,6 @@ void compile(String superName, String[] interfaceNames, boolean oneTimeUse) thro clinitgen.visitCode(); clinitgen.visitLineNumber(line, clinitgen.mark()); - if(constants.count() > 0) - { - emitConstants(clinitgen); - } - if(keywordCallsites.count() > 0) emitKeywordCallsites(clinitgen); @@ -5183,8 +5172,16 @@ void compile(String superName, String[] interfaceNames, boolean oneTimeUse) thro cv.visitEnd(); bytecode = cw.toByteArray(); - if(RT.booleanCast(COMPILE_FILES.deref())) + if(RT.booleanCast(COMPILE_FILES.deref())) { writeClassFile(internalName, bytecode); + if (constFieldBytecode != null) { + for (Map.Entry entry : constFieldBytecode.entrySet()) { + String constName = entry.getKey(); + byte[] constBytecode = entry.getValue(); + writeClassFile(constName, constBytecode); + } + } + } // else // getCompiledClass(); } @@ -5438,26 +5435,62 @@ else if(value instanceof Pattern) } } + public static final int INITS_PER = 100; - void emitConstants(GeneratorAdapter clinitgen){ - try - { - Var.pushThreadBindings(RT.map(RT.PRINT_DUP, RT.T)); + void emitConstantFields(ClassVisitor cv) throws IOException { + if (constants.count() > 0) { + Map tempFieldBytecode = new HashMap<>(); + int numInits = constants.count() / INITS_PER; + if (constants.count() % INITS_PER != 0) + ++numInits; - for(int i = 0; i < constants.count(); i++) - { - if(usedConstants.contains(i)) - { - emitValue(constants.nth(i), clinitgen); - clinitgen.checkCast(constantType(i)); - clinitgen.putStatic(objtype, constantName(i), constantType(i)); - } + for (int n = 0; n < numInits; n++) { + int containerStart = n * INITS_PER; + Type inner_type = constantContainer(containerStart); + + cv.visitInnerClass(inner_type.getInternalName(), + objtype.getInternalName(), + constantContainerName(containerStart), + ACC_STATIC + ACC_FINAL); + + ClassWriter inner_cw = classWriter(); + ClassVisitor inner_cv = inner_cw; + inner_cv.visit(V1_8, ACC_PUBLIC + ACC_SUPER, inner_type.getInternalName(), null, "java/lang/Object", null); + + //static fields for constants + for (int i = n * INITS_PER; i < constants.count() && i < (n + 1) * INITS_PER; i++) { + if (usedConstants.contains(i)) + inner_cv.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, constantName(i), constantType(i).getDescriptor(), + null, null); } + + GeneratorAdapter clinitgen = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, + Method.getMethod("void ()"), + null, + null, + inner_cv); + + clinitgen.visitCode(); + try { + Var.pushThreadBindings(RT.map(RT.PRINT_DUP, RT.T)); + + for (int i = n * INITS_PER; i < constants.count() && i < (n + 1) * INITS_PER; i++) { + if (usedConstants.contains(i)) { + emitValue(constants.nth(i), clinitgen); + clinitgen.checkCast(constantType(i)); + clinitgen.putStatic(constantContainer(i), constantName(i), constantType(i)); + } + } + } finally { + Var.popThreadBindings(); + } + clinitgen.returnValue(); + clinitgen.endMethod(); + inner_cv.visitEnd(); + tempFieldBytecode.put(inner_type.getInternalName(), inner_cw.toByteArray()); } - finally - { - Var.popThreadBindings(); - } + constFieldBytecode = tempFieldBytecode; + } } boolean isMutable(LocalBinding lb){ @@ -5500,6 +5533,10 @@ synchronized Class getCompiledClass(){ // else { loader = (DynamicClassLoader) LOADER.deref(); + if (constFieldBytecode != null) + constFieldBytecode.forEach((constName, constBytecode) -> { + loader.defineClass(constName.replace("/", "."), constBytecode, src); + }); compiledClass = loader.defineClass(name, bytecode, src); } return compiledClass; @@ -5650,7 +5687,7 @@ private void emitLocal(GeneratorAdapter gen, LocalBinding lb, boolean clear){ { // System.out.println("use: " + rep); } - } + } } else { @@ -5722,9 +5759,16 @@ public void emitKeyword(GeneratorAdapter gen, Keyword k){ public void emitConstant(GeneratorAdapter gen, int id){ usedConstants = (IPersistentSet) usedConstants.cons(id); - gen.getStatic(objtype, constantName(id), constantType(id)); + gen.getStatic(constantContainer(id), constantName(id), constantType(id)); } + public Type constantContainer(int id) { + return Type.getObjectType(objtype.getInternalName() + "$" + constantContainerName(id)); + } + + public String constantContainerName(int id) { + return "ID_" + (id / INITS_PER); + } String constantName(int id){ return CONST_PREFIX + id; @@ -8332,48 +8376,7 @@ CONSTANT_IDS, new IdentityHashMap(), gen.returnValue(); gen.endMethod(); - //static fields for constants - for(int i = 0; i < objx.constants.count(); i++) - { - if(objx.usedConstants.contains(i)) - cv.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, objx.constantName(i), objx.constantType(i).getDescriptor(), - null, null); - } - - final int INITS_PER = 100; - int numInits = objx.constants.count() / INITS_PER; - if(objx.constants.count() % INITS_PER != 0) - ++numInits; - - for(int n = 0;n 0) -// { -// objx.emitConstants(clinitgen); -// } - for(int n = 0;n entry : objx.constFieldBytecode.entrySet()) { + String constName = entry.getKey(); + byte[] constBytecode = entry.getValue(); + writeClassFile(constName, constBytecode); + } + writeClassFile(objx.internalName, cw.toByteArray()); } catch(LispReader.ReaderException e) { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy