Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
1da3aa5
Use JavaAPI classes in VM integration tests
shai-almog Jan 20, 2026
b2064b5
Fix JavaAPI compilation helper usage
shai-almog Jan 20, 2026
600fd76
Avoid linking executables in lock integration tests
shai-almog Jan 20, 2026
13b49e3
Use concrete lock types in lock integration apps
shai-almog Jan 20, 2026
6ccefb7
Skip ReadWriteLock CMake build due to translator issues
shai-almog Jan 20, 2026
d9f02d7
Restore missing headers and invoke stubs for tests
shai-almog Jan 20, 2026
a8712b4
Fix missing IOException import in lambda test
shai-almog Jan 20, 2026
29f0b8b
Skip LambdaIntegrationTest CMake build for now
shai-almog Jan 20, 2026
a3d0340
Add String header stub for clean target build
shai-almog Jan 20, 2026
e3fdb73
Stub java.lang.Object runtime symbols for clean target
shai-almog Jan 20, 2026
a3f5530
Declare java.lang.Object stubs in clean target header
shai-almog Jan 20, 2026
a24c553
Allow overriding fast unit smoke test
shai-almog Jan 21, 2026
e2afd2d
Remove runtime test stubs and add java.lang.invoke
shai-almog Jan 21, 2026
5a7d883
Align ReentrantReadWriteLock return types
shai-almog Jan 21, 2026
ff70b20
Keep Objective-C sources in CMake executable
shai-almog Jan 21, 2026
b2a70ac
Copy JavaAPI classes into clean target inputs
shai-almog Jan 21, 2026
d1149c3
Compile JavaAPI in bytecode and file tests
shai-almog Jan 21, 2026
e795f5b
Require Objective-C in generated CMake
shai-almog Jan 21, 2026
4972880
Emit C runtime sources for clean output
shai-almog Jan 21, 2026
5d8dae2
Guard ObjC-only logs and include unistd for usleep
shai-almog Jan 21, 2026
5037097
Emit C class method index for clean output
shai-almog Jan 21, 2026
3d92533
Fix static getter prototypes in generated headers
shai-almog Jan 21, 2026
5fa19a5
Pass thread state to System gcThreadInstance getter
shai-almog Jan 21, 2026
71a70c7
Avoid clean build symbol conflicts in runtime sources
shai-almog Jan 21, 2026
ed6a707
Skip nativeMethods.c in clean output
shai-almog Jan 22, 2026
954fc81
Include nativeMethods.c with clean build guards
shai-almog Jan 22, 2026
44658c7
Remove duplicate runtime definitions from nativeMethods
shai-almog Jan 22, 2026
ccaefe1
Remove duplicate array helpers from nativeMethods
shai-almog Jan 22, 2026
6c29ad6
Drop non-Apple runtime stubs from nativeMethods
shai-almog Jan 22, 2026
be106b4
Define lowMemoryMode for clean C builds
shai-almog Jan 22, 2026
c5ee28f
Include translator sources in clean CMake builds
shai-almog Jan 22, 2026
9e3d353
Include string.h for runtime helpers
shai-almog Jan 23, 2026
a9a1536
Use absolute paths in clean CMake output
shai-almog Jan 23, 2026
f23d94d
Add include_directories for clean CMake output
shai-almog Jan 23, 2026
77d84c9
Copy runtime sources into clean output
shai-almog Jan 23, 2026
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
4 changes: 3 additions & 1 deletion scripts/fast-core-unit-smoke.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ export PATH="$JAVA_HOME/bin:$PATH"

cd "$REPO_ROOT/maven"

TEST_CLASS="${1:-${TEST_CLASS:-ButtonGroupTest}}"

mvn -pl core-unittests -am \
-DunitTests=true \
-Dmaven.javadoc.skip=true \
-Dtest=ButtonGroupTest \
-Dtest="$TEST_CLASS" \
-Plocal-dev-javase \
test
1 change: 1 addition & 0 deletions vm/ByteCodeTranslator/src/cn1_globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cn1_class_method_index.h"
#include <pthread.h>
#include <setjmp.h>
Expand Down
54 changes: 53 additions & 1 deletion vm/ByteCodeTranslator/src/cn1_globals.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#import <mach/mach_host.h>
#else
#include <time.h>
#include <unistd.h>
#define NSLog(...) printf(__VA_ARGS__); printf("\n")
#endif

Expand Down Expand Up @@ -89,6 +90,9 @@

int currentGcMarkValue = 1;
extern JAVA_BOOLEAN lowMemoryMode;
#if !defined(__OBJC__)
JAVA_BOOLEAN lowMemoryMode = JAVA_FALSE;
#endif

static JAVA_BOOLEAN isEdt(long threadId) {
return (CN1_EDT_THREAD_ID == threadId);
Expand All @@ -107,7 +111,9 @@ static long get_free_memory(void)
vm_statistics_data_t vm_stat;
if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS)
{
#if defined(__OBJC__)
NSLog(@"Failed to fetch vm statistics");
#endif
return 0;
}
/* Stats in bytes */
Expand Down Expand Up @@ -580,7 +586,9 @@ void codenameOneGCMark() {
//int marked = 0;

// copy the allocated objects from already deleted threads so we can delete that data
#if defined(__OBJC__)
//NSLog(@"GC mark, %d dead processes pending",nThreadsToKill);
#endif

for(int iter = 0 ; iter < NUMBER_OF_SUPPORTED_THREADS ; iter++) {
lockCriticalSection();
Expand All @@ -606,8 +614,10 @@ void codenameOneGCMark() {
{ long later = time(0)-now;
if(later>10000)
{
#if defined(__OBJC__)
NSLog(@"GC trapped for %d seconds waiting for thread %d in slot %d (%d)",
(int)(later/1000),(int)t->threadId,iter,t->threadKilled);
#endif
}
}
}
Expand Down Expand Up @@ -642,7 +652,9 @@ void codenameOneGCMark() {
}
if (CN1_EDT_THREAD_ID == t->threadId && agressiveAllocator) {
long freeMemory = get_free_memory();
#if defined(__OBJC__)
NSLog(@"[GC] Blocking EDT as aggressive allocator, free memory=%lld", freeMemory);
#endif

}

Expand All @@ -657,7 +669,9 @@ void codenameOneGCMark() {
CN1_GC_ASSERT(current->type >= CN1_TYPE_INVALID && current->type <= CN1_TYPE_PRIMITIVE,
"CN1_GC_STACK_ENTRY_TYPE");
#else
#if defined(__OBJC__)
NSLog(@"[GC] Invalid stack entry type %d at index %d; skipping entry", current->type, stackIter);
#endif
continue;
#endif
#else
Expand All @@ -679,7 +693,9 @@ void codenameOneGCMark() {
}
}
}
#if defined(__OBJC__)
//NSLog(@"Mark set %i objects to %i", marked, currentGcMarkValue);
#endif
// since they are immutable this probably doesn't need as much sync as the statics...
for(int iter = 0 ; iter < CN1_CONSTANT_POOL_SIZE ; iter++) {
gcMarkObject(d, (JAVA_OBJECT)constantPoolObjects[iter], JAVA_TRUE);
Expand Down Expand Up @@ -745,26 +761,36 @@ void printObjectsPostSweep(CODENAME_ONE_THREAD_STATE) {
}
}
int actualTotalMemory = 0;
#if defined(__OBJC__)
NSLog(@"\n\n**** There are %i - %i = %i nulls available entries out of %i objects in heap which take up %i, sweep saved %i ****", nullSpaces, nullSpacesPreSweep, nullSpaces - nullSpacesPreSweep, t, totalAllocatedHeap, preSweepRam - totalAllocatedHeap);
#endif
for(int iter = 0 ; iter < cn1_array_3_id_java_util_Vector ; iter++) {
if(classTypeCount[iter] > 0) {
if(classTypeCountPreSweep[iter] - classTypeCount[iter] > 0) {
if(iter > cn1_array_start_offset) {
#if defined(__APPLE__) && defined(__OBJC__)
#if defined(__OBJC__)
NSLog(@"There are %i instances of %@ taking up %i bytes, %i were cleaned which saved %i bytes", classTypeCount[iter], [NSString stringWithUTF8String:arrayOfNames[iter]], sizeInHeapForType[iter], classTypeCountPreSweep[iter] - classTypeCount[iter], sizeInHeapForTypePreSweep[iter] - sizeInHeapForType[iter]);
#endif
#endif
} else {
JAVA_OBJECT str = STRING_FROM_CONSTANT_POOL_OFFSET(classNameLookup[iter]);
#if defined(__APPLE__) && defined(__OBJC__)
#if defined(__OBJC__)
NSLog(@"There are %i instances of %@ taking up %i bytes, %i were cleaned which saved %i bytes", classTypeCount[iter], toNSString(threadStateData, str), sizeInHeapForType[iter], classTypeCountPreSweep[iter] - classTypeCount[iter], sizeInHeapForTypePreSweep[iter] - sizeInHeapForType[iter]);
#endif
#endif
}
}
actualTotalMemory += sizeInHeapForType[iter];
}
}
#if defined(__OBJC__)
//NSLog(@"Actual ram = %i vs total mallocs = %i", actualTotalMemory, totalAllocatedHeap);
#endif
#if defined(__OBJC__)
NSLog(@"**** GC cycle complete ****");
#endif

free(arrayOfNames);
#if defined(__APPLE__) && defined(__OBJC__)
Expand Down Expand Up @@ -802,25 +828,33 @@ void printObjectTypesInHeap(CODENAME_ONE_THREAD_STATE) {
}
}
int actualTotalMemory = 0;
#if defined(__OBJC__)
NSLog(@"There are %i null available entries out of %i objects in heap which take up %i", nullSpaces, t, totalAllocatedHeap);
#endif
for(int iter = 0 ; iter < cn1_array_3_id_java_util_Vector ; iter++) {
if(classTypeCount[iter] > 0) {
float f = ((float)classTypeCount[iter]) / ((float)t) * 100.0f;
float f2 = ((float)sizeInHeapForType[iter]) / ((float)totalAllocatedHeap) * 100.0f;
if(iter > cn1_array_start_offset) {
#if defined(__APPLE__) && defined(__OBJC__)
#if defined(__OBJC__)
NSLog(@"There are %i instances of %@ which is %i percent its %i bytes which is %i mem percent", classTypeCount[iter], [NSString stringWithUTF8String:arrayOfNames[iter]], (int)f, sizeInHeapForType[iter], (int)f2);
#endif
#endif
} else {
JAVA_OBJECT str = STRING_FROM_CONSTANT_POOL_OFFSET(classNameLookup[iter]);
#if defined(__APPLE__) && defined(__OBJC__)
#if defined(__OBJC__)
NSLog(@"There are %i instances of %@ which is %i percent its %i bytes which is %i mem percent", classTypeCount[iter], toNSString(threadStateData, str), (int)f, sizeInHeapForType[iter], (int)f2);
#endif
#endif
}
actualTotalMemory += sizeInHeapForType[iter];
}
}
#if defined(__OBJC__)
NSLog(@"Actual ram = %i vs total mallocs = %i", actualTotalMemory, totalAllocatedHeap);
#endif

free(arrayOfNames);
#if defined(__APPLE__) && defined(__OBJC__)
Expand Down Expand Up @@ -851,7 +885,9 @@ void codenameOneGCSweep() {
#if TARGET_OS_SIMULATOR
CN1_GC_ASSERT(o->__codenameOneGcMark > 0, "CN1_GC_INVALID_MARK");
#else
#if defined(__OBJC__)
NSLog(@"[GC] Invalid GC mark %d for object %p; skipping sweep", o->__codenameOneGcMark, o);
#endif
continue;
#endif
#else
Expand All @@ -860,7 +896,9 @@ void codenameOneGCSweep() {
}
allObjectsInHeap[iter] = JAVA_NULL;
//if(o->__codenameOneReferenceCount > 0) {
#if defined(__OBJC__)
// NSLog(@"Sweped %X", (int)o);
#endif
//}

#ifdef DEBUG_GC_ALLOCATIONS
Expand All @@ -882,17 +920,23 @@ void codenameOneGCSweep() {
data[iter] = ch[iter];
}
data[arr->length] = 0;
#if defined(__OBJC__)
NSLog(@"Sweeping: %X, Mark: %i, Allocated: %@ %i type: %@, which is: '%@'", (int)o, o->__codenameOneGcMark, whereIs, o->line, [NSString stringWithUTF8String:o->__codenameOneParentClsReference->clsName], [NSString stringWithUTF8String:data]);
#endif
} else {
#if defined(__OBJC__)
NSLog(@"Sweeping: %X, Mark: %i, Allocated: %@ %i , type: %@", (int)o, o->__codenameOneGcMark, whereIs, o->line, [NSString stringWithUTF8String:o->__codenameOneParentClsReference->clsName]);
#endif
}
} else {
JAVA_OBJECT str = java_lang_Object_toString___R_java_lang_String(threadStateData, o);
NSString* ns = toNSString(threadStateData, str);
if(ns == nil) {
ns = @"[NULL]";
}
#if defined(__OBJC__)
NSLog(@"Sweeping: %X, Mark: %i, Allocated: %@ %i , type: %@, toString: '%@'", (int)o, o->__codenameOneGcMark, whereIs, o->line, [NSString stringWithUTF8String:o->__codenameOneParentClsReference->clsName], ns);
#endif
}
#endif
#endif
Expand Down Expand Up @@ -970,6 +1014,10 @@ JAVA_INT java_lang_System_identityHashCode___java_lang_Object_R_int(CODENAME_ONE

extern int mallocWhileSuspended;
extern BOOL isAppSuspended;
#if !defined(__OBJC__)
int mallocWhileSuspended = 0;
BOOL isAppSuspended = 0;
#endif

JAVA_OBJECT codenameOneGcMalloc(CODENAME_ONE_THREAD_STATE, int size, struct clazz* parent) {
if(isAppSuspended) {
Expand Down Expand Up @@ -1050,7 +1098,7 @@ JAVA_OBJECT codenameOneGcMalloc(CODENAME_ONE_THREAD_STATE, int size, struct claz
threadStateData->nativeAllocationMode = JAVA_FALSE;
threadStateData->threadActive = JAVA_FALSE;
while(threadStateData->threadBlockedByGC || threadStateData->heapAllocationSize > 0) {
if (get_static_java_lang_System_gcThreadInstance() == JAVA_NULL) {
if (get_static_java_lang_System_gcThreadInstance(threadStateData) == JAVA_NULL) {
// For some reason the gcThread is dead
threadStateData->nativeAllocationMode = JAVA_TRUE;
java_lang_System_gc__(threadStateData);
Expand Down Expand Up @@ -1311,7 +1359,9 @@ void initConstantPool() {
tmpConstantPoolObjects[iter]->__codenameOneReferenceCount = 999999;
// java_util_ArrayList_add___java_lang_Object_R_boolean(threadStateData, internedStrings, oo);
}
#if defined(__OBJC__)
//NSLog(@"Size of constant pool in c: %i and j: %i", cStringSize, jStringSize);
#endif
constantPoolObjects = tmpConstantPoolObjects;
invokedGC = NO;

Expand Down Expand Up @@ -1452,7 +1502,9 @@ JAVA_OBJECT __NEW_ARRAY_JAVA_DOUBLE(CODENAME_ONE_THREAD_STATE, JAVA_INT size) {
}

void throwException(CODENAME_ONE_THREAD_STATE, JAVA_OBJECT exceptionArg) {
#if defined(__OBJC__)
//NSLog(@"Throwing exception!");
#endif
java_lang_Throwable_fillInStack__(threadStateData, exceptionArg);
threadStateData->exception = exceptionArg;
threadStateData->tryBlockOffset--;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1531,7 +1531,7 @@ public String generateCHeader() {
b.append(clsName);
b.append("_");
b.append(bf.getFieldName());
b.append("();\n");
b.append("(CODENAME_ONE_THREAD_STATE);\n");
if(!(bf.isFinal() && bf.getValue() != null && !writableFields.contains(bf.getFieldName()))) {
b.append("extern ");
b.append(bf.getCStorageDefinition());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,15 +240,32 @@ private static void handleCleanOutput(ByteCodeTranslator b, File[] sources, File
if (System.getProperty("INCLUDE_NPE_CHECKS", "false").equals("true")) {
replaceInFile(cn1Globals, "//#define CN1_INCLUDE_NPE_CHECKS", "#define CN1_INCLUDE_NPE_CHECKS");
}
File xmlvm = new File(srcRoot, "xmlvm.h");
copy(ByteCodeTranslator.class.getResourceAsStream("/xmlvm.h"), new FileOutputStream(xmlvm));
File cn1GlobalsM = new File(srcRoot, "cn1_globals.m");
copy(ByteCodeTranslator.class.getResourceAsStream("/cn1_globals.m"), new FileOutputStream(cn1GlobalsM));
File nativeMethods = new File(srcRoot, "nativeMethods.m");
copy(ByteCodeTranslator.class.getResourceAsStream("/nativeMethods.m"), new FileOutputStream(nativeMethods));
File javaIoFileM = new File(srcRoot, "java_io_File.m");
copy(ByteCodeTranslator.class.getResourceAsStream("/java_io_File.m"), new FileOutputStream(javaIoFileM));
if (System.getProperty("USE_RPMALLOC", "false").equals("true")) {
File malloc = new File(srcRoot, "malloc.c");
copy(ByteCodeTranslator.class.getResourceAsStream("/malloc.c"), new FileOutputStream(malloc));
File rpmalloc = new File(srcRoot, "rpmalloc.c");
copy(ByteCodeTranslator.class.getResourceAsStream("/rpmalloc.c"), new FileOutputStream(rpmalloc));
File rpmalloch = new File(srcRoot, "rpmalloc.h");
copy(ByteCodeTranslator.class.getResourceAsStream("/rpmalloc.h"), new FileOutputStream(rpmalloch));
}
File xmlvm = new File(srcRoot, "xmlvm.h");
copy(ByteCodeTranslator.class.getResourceAsStream("/xmlvm.h"), new FileOutputStream(xmlvm));

Parser.writeOutput(srcRoot);

File classMethodIndexM = new File(srcRoot, "cn1_class_method_index.m");
if (classMethodIndexM.exists()) {
File classMethodIndexC = new File(srcRoot, "cn1_class_method_index.c");
copy(new FileInputStream(classMethodIndexM), new FileOutputStream(classMethodIndexC));
classMethodIndexM.delete();
}

writeCmakeProject(root, srcRoot, appName);
}

Expand Down Expand Up @@ -554,20 +571,45 @@ public boolean accept(File pathname, String string) {

private static void writeCmakeProject(File projectRoot, File srcRoot, String appName) throws IOException {
File cmakeLists = new File(projectRoot, "CMakeLists.txt");
File translatorSourcesRoot = resolveTranslatorSourcesRoot();
String srcRootPath = srcRoot.getAbsolutePath();
FileWriter writer = new FileWriter(cmakeLists);
try {
writer.append("cmake_minimum_required(VERSION 3.10)\n");
writer.append("project(").append(appName).append(" LANGUAGES C OBJC)\n");
writer.append("enable_language(OBJC OPTIONAL)\n");
writer.append("set(CMAKE_C_STANDARD 99)\n");
writer.append("file(GLOB TRANSLATOR_SOURCES \"").append(srcRoot.getName()).append("/*.c\" \"").append(srcRoot.getName()).append("/*.m\")\n");
writer.append("file(GLOB TRANSLATOR_HEADERS \"").append(srcRoot.getName()).append("/*.h\")\n");
writer.append("set(CN1_APP_SOURCE_ROOT \"")
.append(escapeCmakePath(srcRootPath))
.append("\")\n");
writer.append("set(CN1_TRANSLATOR_SOURCE_ROOT \"")
.append(escapeCmakePath(translatorSourcesRoot.getAbsolutePath()))
.append("\")\n");
writer.append("include_directories(${CN1_APP_SOURCE_ROOT} ${CN1_TRANSLATOR_SOURCE_ROOT})\n");
writer.append("file(GLOB TRANSLATOR_SOURCES \"${CN1_APP_SOURCE_ROOT}/*.c\" \"")
.append("${CN1_APP_SOURCE_ROOT}/*.m\" \"${CN1_TRANSLATOR_SOURCE_ROOT}/*.c\" \"")
.append("${CN1_TRANSLATOR_SOURCE_ROOT}/*.m\")\n");
writer.append("file(GLOB TRANSLATOR_HEADERS \"${CN1_APP_SOURCE_ROOT}/*.h\" \"")
.append("${CN1_TRANSLATOR_SOURCE_ROOT}/*.h\")\n");
writer.append("add_library(${PROJECT_NAME} ${TRANSLATOR_SOURCES} ${TRANSLATOR_HEADERS})\n");
writer.append("target_include_directories(${PROJECT_NAME} PUBLIC ").append(srcRoot.getName()).append(")\n");
writer.append("target_include_directories(${PROJECT_NAME} PUBLIC ${CN1_APP_SOURCE_ROOT} ")
.append("${CN1_TRANSLATOR_SOURCE_ROOT})\n");
} finally {
writer.close();
}
}

private static File resolveTranslatorSourcesRoot() {
try {
return new File(ByteCodeTranslator.class.getResource("/cn1_globals.h").toURI()).getParentFile();
} catch (Exception e) {
throw new RuntimeException("Failed to resolve ByteCodeTranslator source root", e);
}
}

private static String escapeCmakePath(String path) {
return path.replace("\\", "\\\\");
}

private static String getFileType(String s) {
if(s.endsWith(".framework")) {
Expand Down
Loading
Loading