GROOVY-4337: Generated createCallSiteArray is too big for JVM
git-svn-id: http://svn.codehaus.org/groovy/branches/GROOVY_1_6_X@20677 a5544e8c-8a19-0410-ba12-f9af4593a198
diff --git a/src/main/org/codehaus/groovy/classgen/AsmClassGenerator.java b/src/main/org/codehaus/groovy/classgen/AsmClassGenerator.java
index 62a19c8..483ce7a 100644
--- a/src/main/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -334,28 +334,56 @@
mv.visitEnd();
}
- private void generateCreateCallSiteArray() {
- MethodVisitor mv = cv.visitMethod(ACC_PRIVATE+ACC_SYNTHETIC+ACC_STATIC,"$createCallSiteArray", "()Lorg/codehaus/groovy/runtime/callsite/CallSiteArray;", null, null);
- mv.visitCode();
- mv.visitTypeInsn(NEW, "org/codehaus/groovy/runtime/callsite/CallSiteArray");
- mv.visitInsn(DUP);
- mv.visitFieldInsn(GETSTATIC, internalClassName, "$ownClass", "Ljava/lang/Class;");
-
- final int size = callSites.size();
- mv.visitLdcInsn(size);
- mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
- for (int i = 0; i < size; i++) {
- mv.visitInsn(DUP);
- mv.visitLdcInsn(i);
- mv.visitLdcInsn(callSites.get(i));
- mv.visitInsn(AASTORE);
+ private void generateCreateCallSiteArray() {
+ List<String> callSiteInitMethods = new LinkedList<String>();
+ int index = 0;
+ int methodIndex = 0;
+ final int size = callSites.size();
+ final int maxArrayInit = 5000;
+ // create array initialization methods
+ while (index < size) {
+ methodIndex++;
+ String methodName = "$createCallSiteArray_" + methodIndex;
+ callSiteInitMethods.add(methodName);
+ MethodVisitor mv = cv.visitMethod(ACC_PRIVATE+ACC_SYNTHETIC+ACC_STATIC, methodName, "([Ljava/lang/String;)V", null, null);
+ mv.visitCode();
+ int methodLimit = size;
+ // check if the next block is over the max allowed
+ if ((methodLimit - index) > maxArrayInit) {
+ methodLimit = index + maxArrayInit;
+ }
+ for (; index < methodLimit; index++) {
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitLdcInsn(index);
+ mv.visitLdcInsn(callSites.get(index));
+ mv.visitInsn(AASTORE);
+ }
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(2,1);
+ mv.visitEnd();
}
+ // create base createCallSiteArray method
+ mv = cv.visitMethod(ACC_PRIVATE+ACC_SYNTHETIC+ACC_STATIC,"$createCallSiteArray", "()Lorg/codehaus/groovy/runtime/callsite/CallSiteArray;", null, null);
+ mv.visitCode();
+ mv.visitLdcInsn(size);
+ mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
+ mv.visitVarInsn(ASTORE, 0);
+ for (String methodName : callSiteInitMethods) {
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESTATIC,internalClassName,methodName,"([Ljava/lang/String;)V");
+ }
- mv.visitMethodInsn(INVOKESPECIAL, "org/codehaus/groovy/runtime/callsite/CallSiteArray", "<init>", "(Ljava/lang/Class;[Ljava/lang/String;)V");
- mv.visitInsn(ARETURN);
- mv.visitMaxs(0,0);
- mv.visitEnd();
- }
+ mv.visitTypeInsn(NEW, "org/codehaus/groovy/runtime/callsite/CallSiteArray");
+ mv.visitInsn(DUP);
+ mv.visitFieldInsn(GETSTATIC, internalClassName, "$ownClass", "Ljava/lang/Class;");
+
+ mv.visitVarInsn(ALOAD, 0);
+
+ mv.visitMethodInsn(INVOKESPECIAL, "org/codehaus/groovy/runtime/callsite/CallSiteArray", "<init>", "(Ljava/lang/Class;[Ljava/lang/String;)V");
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(0,0);
+ mv.visitEnd();
+ }
public void visitGenericType(GenericsType genericsType) {
ClassNode type = genericsType.getType();