bind: do not generate unused Seq objects
Updates golang/go#12619 Change-Id: Ie851795580c82ade3ee70bdb3945b23ca72f57e0 Reviewed-on: https://go-review.googlesource.com/17866 Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
This commit is contained in:
parent
f85352c0f7
commit
ab6091a309
|
@ -87,10 +87,9 @@ public void call(int code, go.Seq in, go.Seq out) {
|
||||||
g.Printf("public void set%s(%s v) {\n", f.Name(), g.javaType(f.Type()))
|
g.Printf("public void set%s(%s v) {\n", f.Name(), g.javaType(f.Type()))
|
||||||
g.Indent()
|
g.Indent()
|
||||||
g.Printf("Seq in = new Seq();\n")
|
g.Printf("Seq in = new Seq();\n")
|
||||||
g.Printf("Seq out = new Seq();\n")
|
|
||||||
g.Printf("in.writeRef(ref);\n")
|
g.Printf("in.writeRef(ref);\n")
|
||||||
g.Printf("in.write%s;\n", seqWrite(f.Type(), "v"))
|
g.Printf("in.write%s;\n", seqWrite(f.Type(), "v"))
|
||||||
g.Printf("Seq.send(DESCRIPTOR, FIELD_%s_SET, in, out);\n", f.Name())
|
g.Printf("Seq.send(DESCRIPTOR, FIELD_%s_SET, in, null);\n", f.Name())
|
||||||
g.Outdent()
|
g.Outdent()
|
||||||
g.Printf("}\n\n")
|
g.Printf("}\n\n")
|
||||||
}
|
}
|
||||||
|
@ -467,9 +466,8 @@ func (g *javaGen) genVar(o *types.Var) {
|
||||||
g.Printf("public static void set%s(%s v) {\n", o.Name(), jType)
|
g.Printf("public static void set%s(%s v) {\n", o.Name(), jType)
|
||||||
g.Indent()
|
g.Indent()
|
||||||
g.Printf("Seq in = new Seq();\n")
|
g.Printf("Seq in = new Seq();\n")
|
||||||
g.Printf("Seq out = new Seq();\n")
|
|
||||||
g.Printf("in.write%s;\n", seqWrite(o.Type(), "v"))
|
g.Printf("in.write%s;\n", seqWrite(o.Type(), "v"))
|
||||||
g.Printf("Seq.send(%q, 1, in, out);\n", varDesc)
|
g.Printf("Seq.send(%q, 1, in, null);\n", varDesc)
|
||||||
g.Outdent()
|
g.Outdent()
|
||||||
g.Printf("}\n")
|
g.Printf("}\n")
|
||||||
g.Printf("\n")
|
g.Printf("\n")
|
||||||
|
@ -477,9 +475,8 @@ func (g *javaGen) genVar(o *types.Var) {
|
||||||
// getter
|
// getter
|
||||||
g.Printf("public static %s get%s() {\n", jType, o.Name())
|
g.Printf("public static %s get%s() {\n", jType, o.Name())
|
||||||
g.Indent()
|
g.Indent()
|
||||||
g.Printf("Seq in = new Seq();\n")
|
|
||||||
g.Printf("Seq out = new Seq();\n")
|
g.Printf("Seq out = new Seq();\n")
|
||||||
g.Printf("Seq.send(%q, 2, in, out);\n", varDesc)
|
g.Printf("Seq.send(%q, 2, null, out);\n", varDesc)
|
||||||
g.Printf("%s ", jType)
|
g.Printf("%s ", jType)
|
||||||
g.genRead("v", "out", o.Type())
|
g.genRead("v", "out", o.Type())
|
||||||
g.Printf("return v;\n")
|
g.Printf("return v;\n")
|
||||||
|
@ -498,8 +495,8 @@ func (g *javaGen) genFunc(o *types.Func, method bool) {
|
||||||
|
|
||||||
g.Printf(" {\n")
|
g.Printf(" {\n")
|
||||||
g.Indent()
|
g.Indent()
|
||||||
g.Printf("go.Seq _in = new go.Seq();\n")
|
g.Printf("go.Seq _in = null;\n")
|
||||||
g.Printf("go.Seq _out = new go.Seq();\n")
|
g.Printf("go.Seq _out = null;\n")
|
||||||
|
|
||||||
returnsError := false
|
returnsError := false
|
||||||
var resultType types.Type
|
var resultType types.Type
|
||||||
|
@ -511,15 +508,21 @@ func (g *javaGen) genFunc(o *types.Func, method bool) {
|
||||||
returnsError = true
|
returnsError = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if resultType != nil || returnsError {
|
||||||
|
g.Printf("_out = new go.Seq();\n")
|
||||||
|
}
|
||||||
if resultType != nil {
|
if resultType != nil {
|
||||||
t := g.javaType(resultType)
|
t := g.javaType(resultType)
|
||||||
g.Printf("%s _result;\n", t)
|
g.Printf("%s _result;\n", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
params := sig.Params()
|
||||||
|
if method || params.Len() > 0 {
|
||||||
|
g.Printf("_in = new go.Seq();\n")
|
||||||
|
}
|
||||||
if method {
|
if method {
|
||||||
g.Printf("_in.writeRef(ref);\n")
|
g.Printf("_in.writeRef(ref);\n")
|
||||||
}
|
}
|
||||||
params := sig.Params()
|
|
||||||
for i := 0; i < params.Len(); i++ {
|
for i := 0; i < params.Len(); i++ {
|
||||||
p := params.At(i)
|
p := params.At(i)
|
||||||
g.Printf("_in.write%s;\n", seqWrite(p.Type(), paramName(params, i)))
|
g.Printf("_in.write%s;\n", seqWrite(p.Type(), paramName(params, i)))
|
||||||
|
|
|
@ -77,6 +77,9 @@ static mem *mem_ensure(mem *m, uint32_t size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static mem *mem_get(JNIEnv *env, jobject obj) {
|
static mem *mem_get(JNIEnv *env, jobject obj) {
|
||||||
|
if (obj == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
// Storage space for pointer is always 64-bits, even on 32-bit
|
// Storage space for pointer is always 64-bits, even on 32-bit
|
||||||
// machines. Cast to uintptr_t to avoid -Wint-to-pointer-cast.
|
// machines. Cast to uintptr_t to avoid -Wint-to-pointer-cast.
|
||||||
return (mem*)(uintptr_t)(*env)->GetLongField(env, obj, memptr_id);
|
return (mem*)(uintptr_t)(*env)->GetLongField(env, obj, memptr_id);
|
||||||
|
@ -400,13 +403,20 @@ Java_go_Seq_destroyRef(JNIEnv *env, jclass clazz, jint refnum) {
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
Java_go_Seq_send(JNIEnv *env, jclass clazz, jstring descriptor, jint code, jobject src_obj, jobject dst_obj) {
|
Java_go_Seq_send(JNIEnv *env, jclass clazz, jstring descriptor, jint code, jobject src_obj, jobject dst_obj) {
|
||||||
|
uint8_t* req = NULL;
|
||||||
|
size_t reqlen = 0;
|
||||||
mem *src = mem_get(env, src_obj);
|
mem *src = mem_get(env, src_obj);
|
||||||
if (src == NULL) {
|
if (src != NULL) {
|
||||||
LOG_FATAL("send src is NULL");
|
req = src->buf;
|
||||||
|
reqlen = src->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t** res = NULL;
|
||||||
|
size_t* reslen = NULL;
|
||||||
mem *dst = mem_get(env, dst_obj);
|
mem *dst = mem_get(env, dst_obj);
|
||||||
if (dst == NULL) {
|
if (dst != NULL) {
|
||||||
LOG_FATAL("send dst is NULL");
|
res = &dst->buf;
|
||||||
|
reslen = &dst->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
GoString desc;
|
GoString desc;
|
||||||
|
@ -415,9 +425,13 @@ Java_go_Seq_send(JNIEnv *env, jclass clazz, jstring descriptor, jint code, jobje
|
||||||
LOG_FATAL("send GetStringUTFChars failed");
|
LOG_FATAL("send GetStringUTFChars failed");
|
||||||
}
|
}
|
||||||
desc.n = (*env)->GetStringUTFLength(env, descriptor);
|
desc.n = (*env)->GetStringUTFLength(env, descriptor);
|
||||||
Send(desc, (GoInt)code, src->buf, src->len, &dst->buf, &dst->len);
|
|
||||||
|
Send(desc, (GoInt)code, req, reqlen, res, reslen);
|
||||||
(*env)->ReleaseStringUTFChars(env, descriptor, desc.p);
|
(*env)->ReleaseStringUTFChars(env, descriptor, desc.p);
|
||||||
unpin_arrays(env, src); // assume 'src' is no longer needed.
|
|
||||||
|
if (src != NULL) {
|
||||||
|
unpin_arrays(env, src); // assume 'src' is no longer needed.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
|
|
|
@ -31,18 +31,26 @@ func Send(descriptor string, code int, req *C.uint8_t, reqlen C.size_t, res **C.
|
||||||
if fn == nil {
|
if fn == nil {
|
||||||
panic(fmt.Sprintf("invalid descriptor(%s) and code(0x%x)", descriptor, code))
|
panic(fmt.Sprintf("invalid descriptor(%s) and code(0x%x)", descriptor, code))
|
||||||
}
|
}
|
||||||
in := new(seq.Buffer)
|
|
||||||
if reqlen > 0 {
|
|
||||||
in.Data = (*[maxSliceLen]byte)(unsafe.Pointer(req))[:reqlen]
|
|
||||||
}
|
|
||||||
out := new(seq.Buffer)
|
|
||||||
fn(out, in)
|
|
||||||
// BUG(hyangah): the function returning a go byte slice (so fn writes a pointer into 'out') is unsafe.
|
|
||||||
// After fn is complete here, Go runtime is free to collect or move the pointed byte slice
|
|
||||||
// contents. (Explicitly calling runtime.GC here will surface the problem?)
|
|
||||||
// Without pinning support from Go side, it will be hard to fix it without extra copying.
|
|
||||||
|
|
||||||
seqToBuf(res, reslen, out)
|
var in, out *seq.Buffer
|
||||||
|
if req != nil && reqlen > 0 {
|
||||||
|
in = &seq.Buffer{
|
||||||
|
Data: (*[maxSliceLen]byte)(unsafe.Pointer(req))[:reqlen],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if res != nil {
|
||||||
|
out = new(seq.Buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn(out, in)
|
||||||
|
|
||||||
|
if res != nil {
|
||||||
|
// BUG(hyangah): the function returning a go byte slice (so fn writes a pointer into 'out') is unsafe.
|
||||||
|
// After fn is complete here, Go runtime is free to collect or move the pointed byte slice
|
||||||
|
// contents. (Explicitly calling runtime.GC here will surface the problem?)
|
||||||
|
// Without pinning support from Go side, it will be hard to fix it without extra copying.
|
||||||
|
seqToBuf(res, reslen, out)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DestroyRef is called by Java to inform Go it is done with a reference.
|
// DestroyRef is called by Java to inform Go it is done with a reference.
|
||||||
|
|
Loading…
Reference in New Issue