Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test file too large issue fix #85

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4cd5409
Generate separate class for object methods
Nadeeshan96 Sep 12, 2023
c68d0ce
Fix split class method call
Nadeeshan96 Sep 13, 2023
3322a12
Remove unnecessary code
Nadeeshan96 Sep 13, 2023
40fba6f
Fix creating object split class
Nadeeshan96 Sep 13, 2023
b0ef3ad
Clean the code
Nadeeshan96 Sep 13, 2023
9c34aef
Fix setOnInitialization calls
Nadeeshan96 Sep 14, 2023
7850e4f
Merge branch 'master-file-too-large-41279' into fix-file-too-large-is…
Nadeeshan96 Sep 14, 2023
037d987
Merge branch 'master' into master-file-too-large-41279
Nadeeshan96 Sep 15, 2023
b487158
Change java bytecode version
Nadeeshan96 Sep 15, 2023
3dabad3
Merge branch 'master-file-too-large-41279' into fix-file-too-large-is…
Nadeeshan96 Sep 15, 2023
fad698e
Split object methods across multiple classes
Nadeeshan96 Sep 15, 2023
9f308d3
Fix error stacktrace
Nadeeshan96 Sep 15, 2023
1415350
Split class methods based on method count
Nadeeshan96 Sep 18, 2023
47b217b
Add test with too large files
Nadeeshan96 Sep 18, 2023
8f2d66f
Merge branch 'master' into master-file-too-large-41279
Nadeeshan96 Sep 19, 2023
cc45972
Merge branch 'master-file-too-large-41279' into fix-file-too-large-is…
Nadeeshan96 Sep 19, 2023
1b65578
Split all object methods
Nadeeshan96 Sep 19, 2023
d350412
Fix object split method local variable table
Nadeeshan96 Oct 3, 2023
d12187e
Merge branch 'master' into fix-file-too-large-issue-41279
Nadeeshan96 Oct 3, 2023
4569272
Merge branch 'master' into fix-file-too-large-issue-41279
Nadeeshan96 Oct 17, 2023
1da8144
Add local var table for split class original methods
Nadeeshan96 Oct 17, 2023
f83b85b
Disable normalizedCoverageClassTest
Nadeeshan96 Oct 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public class ErrorValue extends BError implements RefValue {
private final Object details;

private static final String GENERATE_OBJECT_CLASS_PREFIX = "$value$";
private static final String SPLIT_CLASS_SUFFIX_REGEX = "\\$split\\$\\d";
private static final String GENERATE_PKG_INIT = "___init_";
private static final String GENERATE_PKG_START = "___start_";
private static final String GENERATE_PKG_STOP = "___stop_";
Expand Down Expand Up @@ -441,7 +442,7 @@ private Optional<StackTraceElement> filterStackTraceElement(StackTraceElement st
}

private String cleanupClassName(String className) {
return className.replace(GENERATE_OBJECT_CLASS_PREFIX, "");
return className.replace(GENERATE_OBJECT_CLASS_PREFIX, "").replaceAll(SPLIT_CLASS_SUFFIX_REGEX, "");
}

private boolean isCompilerAddedName(String name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,11 @@ public static String getMethodDesc(List<BType> paramTypes, BType retType, BType
generateReturnType(retType);
}

public static String getMethodDesc(List<BType> paramTypes, BType retType, String attachedTypeClassName) {
return INITIAL_METHOD_DESC + "L" + attachedTypeClassName + ";" + populateMethodDesc(paramTypes) +
generateReturnType(retType);
}

public static String populateMethodDesc(List<BType> paramTypes) {
StringBuilder descBuilder = new StringBuilder();
for (BType type : paramTypes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ public class JvmConstants {

// code generation related constants.
public static final String MODULE_INIT_CLASS_NAME = "$_init";
public static final String OBJECT_SELF_INSTANCE = "self";
public static final String UNION_TYPE_CONSTANT_CLASS_NAME = "constants/$_union_type_constants";
public static final String ERROR_TYPE_CONSTANT_CLASS_NAME = "constants/$_error_type_constants";
public static final String TUPLE_TYPE_CONSTANT_CLASS_NAME = "constants/$_tuple_type_constants";
Expand Down Expand Up @@ -380,10 +381,12 @@ public class JvmConstants {
public static final String START_OF_HEADING_WITH_SEMICOLON = ":\u0001";
public static final String CREATE_INTEROP_ERROR_METHOD = "createInteropError";
public static final String LAMBDA_PREFIX = "$lambda$";
public static final String SPLIT_CLASS_SUFFIX = "$split$";
public static final String POPULATE_METHOD_PREFIX = "$populate";
public static final String ADD_METHOD = "add";
public static final String TEST_EXECUTION_STATE = "__gH7W16nQmp0TestExecState__";
public static final String GET_TEST_EXECUTION_STATE = "$getTestExecutionState";
public static final String STRAND_LOCAL_VARIABLE_NAME = "__strand";

// scheduler related constants
public static final String SCHEDULE_FUNCTION_METHOD = "scheduleFunction";
Expand Down Expand Up @@ -446,6 +449,7 @@ public class JvmConstants {
public static final int MAX_CALLS_PER_CLIENT_METHOD = 100;
public static final int MAX_CONSTANTS_PER_METHOD = 100;
public static final int MAX_CALLS_PER_FUNCTION_CALL_METHOD = 100;
public static final int MAX_METHOD_COUNT_PER_BALLERINA_OBJECT = 100;
/*
MAX_STRINGS_PER_METHOD is calculated as below.
No of instructions required for create ballerina string constant object = 12
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MAP_VALUE;
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MATH_UTILS;
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_INIT_CLASS_NAME;
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.OBJECT_SELF_INSTANCE;
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.OBJECT_TYPE_IMPL;
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.REG_EXP_FACTORY;
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.SHORT_VALUE;
Expand Down Expand Up @@ -432,7 +433,7 @@ public void generateVarLoad(MethodVisitor mv, BIRNode.BIRVariableDcl varDcl, int

switch (varDcl.kind) {
case SELF:
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, this.indexMap.get(OBJECT_SELF_INSTANCE));
return;
case CONSTANT:
case GLOBAL:
Expand Down Expand Up @@ -1517,7 +1518,7 @@ void generateObjectStoreIns(BIRNonTerminator.FieldAccess objectStoreIns) {
this.mv.visitTypeInsn(CHECKCAST, className);
visitKeyValueExpressions(objectStoreIns);
// invoke setOnInitialization() method
this.mv.visitMethodInsn(INVOKESPECIAL, className, "setOnInitialization",
this.mv.visitMethodInsn(INVOKEVIRTUAL, className, "setOnInitialization",
SET_ON_INIT, false);
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ private static void generateLockForVariable(ClassWriter cw) {
private static void generateStaticInitializer(ClassWriter cw, String className, BIRPackage birPackage,
boolean isInitClass, boolean serviceEPAvailable,
AsyncDataCollector asyncDataCollector,
JvmConstantsGen jvmConstantsGen, boolean isTestablePackage) {
JvmConstantsGen jvmConstantsGen) {
if (!isInitClass && asyncDataCollector.getStrandMetadata().isEmpty()) {
return;
}
Expand Down Expand Up @@ -432,7 +432,7 @@ private void generateModuleClasses(BIRPackage module, Map<String, byte[]> jarEnt
}
JvmCodeGenUtil.visitStrandMetadataFields(cw, asyncDataCollector.getStrandMetadata());
generateStaticInitializer(cw, moduleClass, module, isInitClass, serviceEPAvailable,
asyncDataCollector, jvmConstantsGen, isTestable);
asyncDataCollector, jvmConstantsGen);
cw.visitEnd();

byte[] bytes = getBytes(cw, module);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1274,7 +1274,6 @@ static String getStrandMetadataVarName(String typeName, String parentFunction) {
}

private void loadFpReturnType(BIROperand lhsOp) {

BType futureType = JvmCodeGenUtil.getImpliedType(lhsOp.variableDcl.type);
BType returnType = symbolTable.anyType;
if (futureType.tag == TypeTags.FUTURE) {
Expand All @@ -1289,12 +1288,10 @@ private int getJVMIndexOfVarRef(BIRNode.BIRVariableDcl varDcl) {
}

private void loadVar(BIRNode.BIRVariableDcl varDcl) {

jvmInstructionGen.generateVarLoad(this.mv, varDcl, this.getJVMIndexOfVarRef(varDcl));
}

private void storeToVar(BIRNode.BIRVariableDcl varDcl) {

jvmInstructionGen.generateVarStore(this.mv, varDcl, this.getJVMIndexOfVarRef(varDcl));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,11 @@
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.LOCK_VALUE;
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MAP_VALUE;
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MAP_VALUE_IMPL;
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MAX_METHOD_COUNT_PER_BALLERINA_OBJECT;
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.OBJECT;
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.POPULATE_INITIAL_VALUES_METHOD;
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.RECORD_INIT_WRAPPER_NAME;
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.SPLIT_CLASS_SUFFIX;
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND_CLASS;
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.TYPEDESC_CLASS_PREFIX;
import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.TYPEDESC_VALUE;
Expand Down Expand Up @@ -226,9 +228,8 @@ void generateValueClasses(Map<String, byte[]> jarEntries, JvmConstantsGen jvmCon
if (optionalTypeDef.type.tag == TypeTags.OBJECT &&
Symbols.isFlagOn(optionalTypeDef.type.tsymbol.flags, Flags.CLASS)) {
BObjectType objectType = (BObjectType) optionalTypeDef.type;
byte[] bytes = this.createObjectValueClass(objectType, className, optionalTypeDef, jvmConstantsGen
, asyncDataCollector);
jarEntries.put(className + ".class", bytes);
this.createObjectValueClasses(objectType, className, optionalTypeDef, jvmConstantsGen
, asyncDataCollector, jarEntries);
} else if (bType.tag == TypeTags.RECORD) {
BRecordType recordType = (BRecordType) bType;
byte[] bytes = this.createRecordValueClass(recordType, className, optionalTypeDef, jvmConstantsGen
Expand Down Expand Up @@ -591,8 +592,9 @@ private void createRecordPopulateInitialValuesMethod(ClassWriter cw, String clas
mv.visitEnd();
}

private byte[] createObjectValueClass(BObjectType objectType, String className, BIRNode.BIRTypeDefinition typeDef,
JvmConstantsGen jvmConstantsGen, AsyncDataCollector asyncDataCollector) {
private void createObjectValueClasses(BObjectType objectType, String className, BIRNode.BIRTypeDefinition typeDef,
JvmConstantsGen jvmConstantsGen, AsyncDataCollector asyncDataCollector,
Map<String, byte[]> jarEntries) {
ClassWriter cw = new BallerinaClassWriter(COMPUTE_FRAMES);
cw.visitSource(typeDef.pos.lineRange().fileName(), null);

Expand All @@ -607,8 +609,8 @@ private byte[] createObjectValueClass(BObjectType objectType, String className,

List<BIRNode.BIRFunction> attachedFuncs = typeDef.attachedFuncs;
if (attachedFuncs != null) {
this.createObjectMethods(cw, attachedFuncs, className, objectType, jvmTypeGen, jvmCastGen,
jvmConstantsGen, asyncDataCollector);
this.createObjectMethodsWithSplitClasses(cw, attachedFuncs, className, objectType, jvmTypeGen,
jvmCastGen, jvmConstantsGen, asyncDataCollector, typeDef, jarEntries);
}

this.createObjectInit(cw, fields, className);
Expand All @@ -619,9 +621,8 @@ private byte[] createObjectValueClass(BObjectType objectType, String className,
this.createLambdas(cw, asyncDataCollector, lambdaGen, className);
JvmCodeGenUtil.visitStrandMetadataFields(cw, asyncDataCollector.getStrandMetadata());
this.generateStaticInitializer(cw, className, module.packageID, asyncDataCollector);

cw.visitEnd();
return jvmPackageGen.getBytes(cw, typeDef);
jarEntries.put(className + ".class", jvmPackageGen.getBytes(cw, typeDef));
}

private void createObjectFields(ClassWriter cw, Map<String, BField> fields) {
Expand All @@ -639,16 +640,66 @@ private void createObjectFields(ClassWriter cw, Map<String, BField> fields) {
}
}

private void createObjectMethods(ClassWriter cw, List<BIRNode.BIRFunction> attachedFuncs, String moduleClassName,
private void createObjectMethods(ClassWriter cw, List<BIRFunction> attachedFuncs, String moduleClassName,
BObjectType currentObjectType, JvmTypeGen jvmTypeGen, JvmCastGen jvmCastGen,
JvmConstantsGen jvmConstantsGen, AsyncDataCollector asyncDataCollector) {

for (BIRNode.BIRFunction func : attachedFuncs) {
if (func == null) {
continue;
}
methodGen.generateMethod(func, cw, module, currentObjectType, moduleClassName,
jvmTypeGen, jvmCastGen, jvmConstantsGen, asyncDataCollector);
methodGen.generateMethod(func, cw, module, currentObjectType, moduleClassName, jvmTypeGen, jvmCastGen,
jvmConstantsGen, asyncDataCollector);
}
}

private void createObjectMethodsWithSplitClasses(ClassWriter cw, List<BIRFunction> attachedFuncs,
String moduleClassName, BObjectType currentObjectType,
JvmTypeGen jvmTypeGen, JvmCastGen jvmCastGen,
JvmConstantsGen jvmConstantsGen,
AsyncDataCollector asyncDataCollector,
BIRNode.BIRTypeDefinition typeDef,
Map<String, byte[]> jarEntries) {

int splitClassNum = 1;
ClassWriter splitCW = new BallerinaClassWriter(COMPUTE_FRAMES);
splitCW.visitSource(typeDef.pos.lineRange().fileName(), null);
String splitClassName = moduleClassName + SPLIT_CLASS_SUFFIX + splitClassNum;
splitCW.visit(V17, ACC_PUBLIC + ACC_SUPER, splitClassName, null, OBJECT, null);
JvmCodeGenUtil.generateDefaultConstructor(splitCW, OBJECT);
int methodCountPerSplitClass = 0;

for (BIRNode.BIRFunction func : attachedFuncs) {
if (func == null) {
continue;
}
if (func.name.value.contains("$init$")) {
methodGen.generateMethod(func, cw, module, currentObjectType, moduleClassName,
jvmTypeGen, jvmCastGen, jvmConstantsGen, asyncDataCollector);
continue;
}
methodGen.genJMethodWithBObjectMethodCall(func, cw, module, jvmTypeGen, jvmCastGen, jvmConstantsGen,
moduleClassName, asyncDataCollector, splitClassName);
methodGen.genJMethodForBFunc(func, splitCW, module, jvmTypeGen, jvmCastGen, jvmConstantsGen,
moduleClassName, currentObjectType, asyncDataCollector, true);
methodCountPerSplitClass++;
if (methodCountPerSplitClass == MAX_METHOD_COUNT_PER_BALLERINA_OBJECT) {
splitCW.visitEnd();
byte[] splitBytes = jvmPackageGen.getBytes(splitCW, typeDef);
jarEntries.put(splitClassName + ".class", splitBytes);
splitClassNum++;
splitCW = new BallerinaClassWriter(COMPUTE_FRAMES);
splitCW.visitSource(typeDef.pos.lineRange().fileName(), null);
splitClassName = moduleClassName + SPLIT_CLASS_SUFFIX + splitClassNum;
splitCW.visit(V17, ACC_PUBLIC + ACC_SUPER, splitClassName, null, OBJECT, null);
JvmCodeGenUtil.generateDefaultConstructor(splitCW, OBJECT);
methodCountPerSplitClass = 0;
}
}
if (methodCountPerSplitClass != 0) {
splitCW.visitEnd();
byte[] splitBytes = jvmPackageGen.getBytes(splitCW, typeDef);
jarEntries.put(splitClassName + ".class", splitBytes);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public static void genJMethodForBExternalFunc(BIRFunction birFunc, ClassWriter c
jvmCastGen, jvmConstantsGen, lambdaGenMetadata, types);
} else {
methodGen.genJMethodForBFunc(birFunc, cw, birModule, jvmTypeGen, jvmCastGen, jvmConstantsGen,
moduleClassName, attachedType, lambdaGenMetadata);
moduleClassName, attachedType, lambdaGenMetadata, false);
}
}

Expand Down
Loading
Loading