[BridgeJS] Pass String parameters unretained by default
When calling a JS function through BridgeJS with String parameters, every String is
- lowered by calling
_swift_js_make_js_string - which decodes and retains in JS object store (new entry, new ref = 1)
- the object store ref is passed as wasm parameter
- the JS thunk immediately get the object and releases (count--, remove from store)
this is very wasteful, and makes retain the number one bottleneck in current ElementaryUI performance benchmarks.
Example:
@JSFunction func hello(_ v: String) throws // generates func _$hello(_ v: String) throws(JSException) -> Void { let vValue = v.bridgeJSLowerParameter() bjs_hello(vValue) if let error = _swift_js_take_exception() { throw error } }
function bjs_hello(v) { try { const vObject = swift.memory.getObject(v); swift.memory.release(v); imports.hello(vObject); } catch (error) { setException(error); } }
I suggest:
- passing
Stringalways "in-line" (ie: as address + length) without retaining in the JSmemorystore - still support
JSStringby-ref to control Swift caller caching (ie: retain once and use same ref multiple times)