Skip to content

Commit

Permalink
Merge branch 'main' into wip-witness-funcs
Browse files Browse the repository at this point in the history
  • Loading branch information
ktoso authored Jan 15, 2025
2 parents 3a396e2 + 84587b4 commit a67441a
Show file tree
Hide file tree
Showing 19 changed files with 421 additions and 54 deletions.
2 changes: 2 additions & 0 deletions Samples/SwiftKitSampleApp/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ let package = Package(
.target(
name: "MySwiftLibrary",
dependencies: [
.product(name: "JavaKit", package: "swift-java"),
.product(name: "JavaRuntime", package: "swift-java"),
.product(name: "SwiftKitSwift", package: "swift-java"),
],
exclude: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ public func globalTakeInt(i: Int) {
p("i:\(i)")
}

public func globalMakeInt() -> Int {
return 42
}

public func globalWriteString(string: String) -> Int {
return string.count
}

public func globalTakeIntInt(i: Int, j: Int) {
p("i:\(i), j:\(j)")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Swift.org project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import JavaKit
import JavaRuntime

@JavaClass("com.example.swift.HelloJava2Swift")
open class HelloJava2Swift: JavaObject {
}

extension JavaClass<HelloJava2Swift> {
}

/// Describes the Java `native` methods for ``HelloJava2Swift``.
///
/// To implement all of the `native` methods for HelloSwift in Swift,
/// extend HelloSwift to conform to this protocol and mark each
/// implementation of the protocol requirement with `@JavaMethod`.
protocol HelloJava2SwiftNativeMethods {
func jniWriteString(_ message: String) -> Int32
func jniGetInt() -> Int32
}

@JavaImplementation("com.example.swift.HelloJava2Swift")
extension HelloJava2Swift: HelloJava2SwiftNativeMethods {
@JavaMethod
func jniWriteString(_ message: String) -> Int32 {
return Int32(message.count)
}

@JavaMethod
func jniGetInt() -> Int32 {
return 12
}
}
11 changes: 11 additions & 0 deletions Samples/SwiftKitSampleApp/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,21 @@ application {
]
}

String jmhIncludes = findProperty("jmhIncludes")

jmh {
if (jmhIncludes != null) {
includes = [jmhIncludes]
}

jvmArgsAppend = [
"--enable-native-access=ALL-UNNAMED",

"-Djava.library.path=" +
(BuildUtils.javaLibraryPaths(rootDir) +
BuildUtils.javaLibraryPaths(project.projectDir)).join(":"),

// Enable tracing downcalls (to Swift)
"-Djextract.trace.downcalls=false"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,51 @@

package org.swift.swiftkit;

import java.util.concurrent.TimeUnit;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.infra.Blackhole;
import com.example.swift.HelloJava2Swift;
import com.example.swift.MySwiftLibrary;
import org.openjdk.jmh.annotations.*;

import com.example.swift.MySwiftClass;

@SuppressWarnings("unused")
import java.util.concurrent.TimeUnit;

@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 5, time = 200, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Fork(value = 3, jvmArgsAppend = { "--enable-native-access=ALL-UNNAMED" })
public class JavaToSwiftBenchmark {

@State(Scope.Benchmark)
public static class BenchmarkState {
ClosableSwiftArena arena;
MySwiftClass obj;

@Setup(Level.Trial)
public void beforeALl() {
System.loadLibrary("swiftCore");
System.loadLibrary("ExampleSwiftLibrary");

// Tune down debug statements so they don't fill up stdout
System.setProperty("jextract.trace.downcalls", "false");
public void beforeAll() {
arena = SwiftArena.ofConfined();
obj = new MySwiftClass(arena, 1, 2);
}

obj = new MySwiftClass(1, 2);
@TearDown(Level.Trial)
public void afterAll() {
arena.close();
}
}

@Benchmark @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS)
public void simpleSwiftApiCall(BenchmarkState state, Blackhole blackhole) {
blackhole.consume(state.obj.makeRandomIntMethod());
@Benchmark
public long jextract_getInt_ffm(BenchmarkState state) {
return MySwiftLibrary.globalMakeInt();
}

@Benchmark
public long getInt_global_jni(BenchmarkState state) {
return HelloJava2Swift.jniGetInt();
}

@Benchmark
public long getInt_member_ffi(BenchmarkState state) {
return state.obj.makeIntMethod();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Swift.org project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

package org.swift.swiftkit;

import com.example.swift.HelloJava2Swift;
import com.example.swift.MySwiftClass;
import com.example.swift.MySwiftLibrary;
import org.openjdk.jmh.annotations.*;

import java.lang.foreign.Arena;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 5, time = 200, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Thread)
@Fork(value = 2, jvmArgsAppend = {"--enable-native-access=ALL-UNNAMED"})
public class StringPassingBenchmark {

@Param({
"5",
"10",
"100",
"200"
})
public int stringLen;
public String string;

ClosableSwiftArena arena;
MySwiftClass obj;

@Setup(Level.Trial)
public void beforeAll() {
arena = SwiftArena.ofConfined();
obj = new MySwiftClass(arena, 1, 2);
string = makeString(stringLen);
}

@TearDown(Level.Trial)
public void afterAll() {
arena.close();
}

@Benchmark
public long writeString_global_fmm() {
return MySwiftLibrary.globalWriteString(string);
}

@Benchmark
public long writeString_global_jni() {
return HelloJava2Swift.jniWriteString(string);
}

@Benchmark
public long writeString_baseline() {
return string.length();
}

static String makeString(int size) {
var text =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut in augue ullamcorper, mattis lacus tincidunt, " +
"accumsan massa. Morbi gravida purus ut porttitor iaculis. Vestibulum lacinia, mi in tincidunt hendrerit," +
"lectus est placerat magna, vitae vestibulum nulla ligula at massa. Pellentesque nibh quam, pulvinar eu " +
"nunc congue, molestie molestie augue. Nam convallis consectetur velit, at dictum risus ullamcorper iaculis. " +
"Vestibulum lacinia nisi in elit consectetur vulputate. Praesent id odio tristique, tincidunt arcu et, convallis velit. " +
"Sed vitae pulvinar arcu. Curabitur euismod mattis dui in suscipit. Morbi aliquet facilisis vulputate. Phasellus " +
"non lectus dapibus, semper magna eu, aliquet magna. Suspendisse vel enim at augue luctus gravida. Suspendisse " +
"venenatis justo non accumsan sollicitudin. Suspendisse vitae ornare odio, id blandit nibh. Nulla facilisi. " +
"Nulla nulla orci, finibus nec luctus et, faucibus et ligula.";
return text.substring(0, size);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,8 @@ static void examples() {

System.out.println("DONE.");
}

public static native long jniWriteString(String str);
public static native long jniGetInt();

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

package com.example.swift;

import com.example.swift.MySwiftLibrary;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
Expand All @@ -27,6 +28,10 @@

public class MySwiftLibraryTest {

static {
System.loadLibrary(MySwiftLibrary.LIB_NAME);
}

@Test
void call_helloWorld() {
MySwiftLibrary.helloWorld();
Expand All @@ -41,6 +46,22 @@ void call_globalTakeInt() {
assertNotNull(MySwiftLibrary.globalTakeInt$address());
}

@Test
void call_writeString_jextract() {
var string = "Hello Swift!";
long reply = MySwiftLibrary.globalWriteString(string);

assertEquals(string.length(), reply);
}

@Test
void call_writeString_jni() {
var string = "Hello Swift!";
long reply = HelloJava2Swift.jniWriteString(string);

assertEquals(string.length(), reply);
}

@Test
@Disabled("Upcalls not yet implemented in new scheme")
@SuppressWarnings({"Convert2Lambda", "Convert2MethodRef"})
Expand Down
12 changes: 12 additions & 0 deletions Sources/JExtractSwift/ImportedDecls.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ public struct ImportedParam {
var effectiveName: String? {
firstName ?? secondName
}

var effectiveValueName: String {
secondName ?? firstName ?? "_"
}

// The Swift type as-is from the swift interface
var swiftType: String {
Expand All @@ -122,6 +126,14 @@ extension ImportedParam {
}
}

public enum ParameterVariant {
/// Used when declaring the "Swift thunks" we call through into Swift.
///
/// Some types need to be represented as raw pointers and recovered into
/// Swift types inside the thunks when we do this.
case cDeclThunk
}

// TODO: this is used in different contexts and needs a cleanup
// Perhaps this is "which parameter passing style"?
public enum SelfParameterVariant {
Expand Down
5 changes: 5 additions & 0 deletions Sources/JExtractSwift/JavaTypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ extension JavaType {
.class(package: "java.lang.foreign", name: "MemorySegment")
}

/// The description of the type java.lang.String.
static var javaLangString: JavaType {
.class(package: "java.lang", name: "String")
}

/// The description of the type java.lang.Runnable.
static var javaLangRunnable: JavaType {
.class(package: "java.lang", name: "Runnable")
Expand Down
Loading

0 comments on commit a67441a

Please sign in to comment.