public inbox for java@gcc.gnu.org
 help / color / mirror / Atom feed
* CNI namespace
@ 2000-03-28 12:16 Paul Fisher
  2000-03-29 12:59 ` Per Bothner
  2000-04-01  0:00 ` Paul Fisher
  0 siblings, 2 replies; 28+ messages in thread
From: Paul Fisher @ 2000-03-28 12:16 UTC (permalink / raw)
  To: java-discuss

Has there been any thought into putting the CNI functions/datatypes
into their own namespace?  And would anyone object to such a change?

I'm continuing the work on the C++ CNI->JNI translation layer, and
such a change would create a cleaner solution to the problem of
conflicting CNI and JNI types.

Adding a CNI namespace would also allow the current name mangling to
go away.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-03-28 12:16 CNI namespace Paul Fisher
@ 2000-03-29 12:59 ` Per Bothner
  2000-03-29 14:59   ` Paul Fisher
                     ` (2 more replies)
  2000-04-01  0:00 ` Paul Fisher
  1 sibling, 3 replies; 28+ messages in thread
From: Per Bothner @ 2000-03-29 12:59 UTC (permalink / raw)
  To: java-discuss

Paul Fisher <pnfisher@redhat.com> writes:

> Has there been any thought into putting the CNI functions/datatypes
> into their own namespace?  And would anyone object to such a change?

It might make sense.  I'd like to see a more specific proposal.
However, note we do have a fair amount of existing code using the
JvXXX names.  Replacing JvXXX by (say) cni::XXX might be better C++
style, but is there enough of an advantage to make up for the work?

> I'm continuing the work on the C++ CNI->JNI translation layer, and
> such a change would create a cleaner solution to the problem of
> conflicting CNI and JNI types.

What is "the problem of conflicting CNI and JNI types"?

> Adding a CNI namespace would also allow the current name mangling to
> go away.

I'm not sure what is "the current name mangling".  We mangle
*Java* classes and methods, but using the same mangling as C++.
We don't want that to go away.  For CNI functions, some are
are extern "C" and some (by default) extern "C++".  We can make them
all extern "C", but I'm not sure how that would help.
-- 
	--Per Bothner
per@bothner.com   http://www.bothner.com/~per/

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-03-29 12:59 ` Per Bothner
@ 2000-03-29 14:59   ` Paul Fisher
  2000-03-29 15:50     ` Per Bothner
  2000-04-01  0:00     ` Paul Fisher
  2000-04-01  0:00   ` Per Bothner
  2000-04-03 12:15   ` Tom Tromey
  2 siblings, 2 replies; 28+ messages in thread
From: Paul Fisher @ 2000-03-29 14:59 UTC (permalink / raw)
  To: java-discuss

Per Bothner <per@bothner.com> writes:

> It might make sense.  I'd like to see a more specific proposal.

I'll work on one.

> Replacing JvXXX by (say) cni::XXX might be better C++ style, but is
> there enough of an advantage to make up for the work?

We would no longer be polluting the global namespace.  Replacing JvXXX
within gcj wouldn't be a lot of work.  For end users, we could create
a cnicompat.h that maps the JvXXX functions over to their namespace
counterparts.  In that way, we'd just treat JvXXX as being deprecated.

Tom mentioned that a namespace would be useful for a precise GC, but
I'm unsure of the details on this.

> What is "the problem of conflicting CNI and JNI types"?

I'm working on code that needs to manipulate CNI and JNI types at the
same time.  Both CNI and JNI stick conflicting typedefs into the
global namespace.  For instance, a CNI jarray is quite different from
a JNI jarray.  With a namespace, ::jarray can easily be used to refer
to the JNI type, and the CNI jarrary can be referred to as
cni::jarray, or, assuming that the cni namespace is `in use', just
jarrary.

> I'm not sure what is "the current name mangling".

The Jv, J, and j prefixes that are prepended to CNI routines and types
(with the exception of the primitive types).

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-03-29 14:59   ` Paul Fisher
@ 2000-03-29 15:50     ` Per Bothner
  2000-03-29 16:32       ` Paul Fisher
  2000-04-01  0:00       ` Per Bothner
  2000-04-01  0:00     ` Paul Fisher
  1 sibling, 2 replies; 28+ messages in thread
From: Per Bothner @ 2000-03-29 15:50 UTC (permalink / raw)
  To: java-discuss

Paul Fisher <pnfisher@redhat.com> writes:

> > What is "the problem of conflicting CNI and JNI types"?
> 
> I'm working on code that needs to manipulate CNI and JNI types at the
> same time.  Both CNI and JNI stick conflicting typedefs into the
> global namespace.  For instance, a CNI jarray is quite different from
> a JNI jarray.

How?  A JNI jarray is typedef to an unspecified pointer type.
A CNI jarray is a typedef to a specific pointer type.
I see no reason why the former can't be the same as the latter.

> With a namespace, ::jarray can easily be used to refer
> to the JNI type, and the CNI jarrary can be referred to as
> cni::jarray, or, assuming that the cni namespace is `in use', just
> jarrary.

So why can't these be the same type?  That was the plan.
-- 
	--Per Bothner
per@bothner.com   http://www.bothner.com/~per/

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-03-29 15:50     ` Per Bothner
@ 2000-03-29 16:32       ` Paul Fisher
  2000-03-29 17:00         ` Per Bothner
  2000-04-01  0:00         ` Paul Fisher
  2000-04-01  0:00       ` Per Bothner
  1 sibling, 2 replies; 28+ messages in thread
From: Paul Fisher @ 2000-03-29 16:32 UTC (permalink / raw)
  To: java-discuss

Per Bothner <per@bothner.com> writes:

> How?  A JNI jarray is typedef to an unspecified pointer type.
> A CNI jarray is a typedef to a specific pointer type.
> I see no reason why the former can't be the same as the latter.

Given "jarray foo", in CNI, foo->length is valid, in JNI it is not.

I need to deal with CNI and JNI jarrarys at the same time.  That is, I
need to be able to include both jni.h and cni.h and not have typedefs
conflict.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-03-29 16:32       ` Paul Fisher
@ 2000-03-29 17:00         ` Per Bothner
  2000-04-01  0:00           ` Per Bothner
  2000-04-03 12:17           ` Tom Tromey
  2000-04-01  0:00         ` Paul Fisher
  1 sibling, 2 replies; 28+ messages in thread
From: Per Bothner @ 2000-03-29 17:00 UTC (permalink / raw)
  To: java-discuss

Paul Fisher <pnfisher@redhat.com> writes:

> Given "jarray foo", in CNI, foo->length is valid, in JNI it is not.

So?  I'm not seeing the problem.  In JNI, you use GetArrayLength.

> I need to deal with CNI and JNI jarrarys at the same time.  That is, I
> need to be able to include both jni.h and cni.h and not have typedefs
> conflict.

They don't conflict!  If they do, it's a bug in jni.h or cni.h,
since they both are part of libgcj

Is the problem they libgcj's cni.h conflicts with Sun's jni.h?
But I don't see why you want to include both of those at the same time.
I can see that you might want to write native code that can be
compiled either:
(a) portably, using any jni.h file, including either libgcj's or Sun's; or
(b) efficiently, using the cni.h interface.
We want to do this in a way that doesn't clutter up the source files
too much, so we may want to include jni.h even in case (b).  But in that
case, you have to use the libgcj jni.h, not Sun's.

Again, I may be missing what you're trying to do.

(As suggested earlier, we could sacrifice some portability in favor of
simpler source files, by requiring the use of g++, but with a flag
to generate the JNI ABI.  Then the binaries can be used with any
Java VM, but you need non-portable tools to generate the binaries.)
--
	--Per Bothner
per@bothner.com   http://www.bothner.com/~per/

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-03-29 17:00         ` Per Bothner
@ 2000-04-01  0:00           ` Per Bothner
  2000-04-03 12:17           ` Tom Tromey
  1 sibling, 0 replies; 28+ messages in thread
From: Per Bothner @ 2000-04-01  0:00 UTC (permalink / raw)
  To: java-discuss

Paul Fisher <pnfisher@redhat.com> writes:

> Given "jarray foo", in CNI, foo->length is valid, in JNI it is not.

So?  I'm not seeing the problem.  In JNI, you use GetArrayLength.

> I need to deal with CNI and JNI jarrarys at the same time.  That is, I
> need to be able to include both jni.h and cni.h and not have typedefs
> conflict.

They don't conflict!  If they do, it's a bug in jni.h or cni.h,
since they both are part of libgcj

Is the problem they libgcj's cni.h conflicts with Sun's jni.h?
But I don't see why you want to include both of those at the same time.
I can see that you might want to write native code that can be
compiled either:
(a) portably, using any jni.h file, including either libgcj's or Sun's; or
(b) efficiently, using the cni.h interface.
We want to do this in a way that doesn't clutter up the source files
too much, so we may want to include jni.h even in case (b).  But in that
case, you have to use the libgcj jni.h, not Sun's.

Again, I may be missing what you're trying to do.

(As suggested earlier, we could sacrifice some portability in favor of
simpler source files, by requiring the use of g++, but with a flag
to generate the JNI ABI.  Then the binaries can be used with any
Java VM, but you need non-portable tools to generate the binaries.)
--
	--Per Bothner
per@bothner.com   http://www.bothner.com/~per/

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-03-29 12:59 ` Per Bothner
  2000-03-29 14:59   ` Paul Fisher
@ 2000-04-01  0:00   ` Per Bothner
  2000-04-03 12:15   ` Tom Tromey
  2 siblings, 0 replies; 28+ messages in thread
From: Per Bothner @ 2000-04-01  0:00 UTC (permalink / raw)
  To: java-discuss

Paul Fisher <pnfisher@redhat.com> writes:

> Has there been any thought into putting the CNI functions/datatypes
> into their own namespace?  And would anyone object to such a change?

It might make sense.  I'd like to see a more specific proposal.
However, note we do have a fair amount of existing code using the
JvXXX names.  Replacing JvXXX by (say) cni::XXX might be better C++
style, but is there enough of an advantage to make up for the work?

> I'm continuing the work on the C++ CNI->JNI translation layer, and
> such a change would create a cleaner solution to the problem of
> conflicting CNI and JNI types.

What is "the problem of conflicting CNI and JNI types"?

> Adding a CNI namespace would also allow the current name mangling to
> go away.

I'm not sure what is "the current name mangling".  We mangle
*Java* classes and methods, but using the same mangling as C++.
We don't want that to go away.  For CNI functions, some are
are extern "C" and some (by default) extern "C++".  We can make them
all extern "C", but I'm not sure how that would help.
-- 
	--Per Bothner
per@bothner.com   http://www.bothner.com/~per/

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-03-29 15:50     ` Per Bothner
  2000-03-29 16:32       ` Paul Fisher
@ 2000-04-01  0:00       ` Per Bothner
  1 sibling, 0 replies; 28+ messages in thread
From: Per Bothner @ 2000-04-01  0:00 UTC (permalink / raw)
  To: java-discuss

Paul Fisher <pnfisher@redhat.com> writes:

> > What is "the problem of conflicting CNI and JNI types"?
> 
> I'm working on code that needs to manipulate CNI and JNI types at the
> same time.  Both CNI and JNI stick conflicting typedefs into the
> global namespace.  For instance, a CNI jarray is quite different from
> a JNI jarray.

How?  A JNI jarray is typedef to an unspecified pointer type.
A CNI jarray is a typedef to a specific pointer type.
I see no reason why the former can't be the same as the latter.

> With a namespace, ::jarray can easily be used to refer
> to the JNI type, and the CNI jarrary can be referred to as
> cni::jarray, or, assuming that the cni namespace is `in use', just
> jarrary.

So why can't these be the same type?  That was the plan.
-- 
	--Per Bothner
per@bothner.com   http://www.bothner.com/~per/

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-03-29 14:59   ` Paul Fisher
  2000-03-29 15:50     ` Per Bothner
@ 2000-04-01  0:00     ` Paul Fisher
  1 sibling, 0 replies; 28+ messages in thread
From: Paul Fisher @ 2000-04-01  0:00 UTC (permalink / raw)
  To: java-discuss

Per Bothner <per@bothner.com> writes:

> It might make sense.  I'd like to see a more specific proposal.

I'll work on one.

> Replacing JvXXX by (say) cni::XXX might be better C++ style, but is
> there enough of an advantage to make up for the work?

We would no longer be polluting the global namespace.  Replacing JvXXX
within gcj wouldn't be a lot of work.  For end users, we could create
a cnicompat.h that maps the JvXXX functions over to their namespace
counterparts.  In that way, we'd just treat JvXXX as being deprecated.

Tom mentioned that a namespace would be useful for a precise GC, but
I'm unsure of the details on this.

> What is "the problem of conflicting CNI and JNI types"?

I'm working on code that needs to manipulate CNI and JNI types at the
same time.  Both CNI and JNI stick conflicting typedefs into the
global namespace.  For instance, a CNI jarray is quite different from
a JNI jarray.  With a namespace, ::jarray can easily be used to refer
to the JNI type, and the CNI jarrary can be referred to as
cni::jarray, or, assuming that the cni namespace is `in use', just
jarrary.

> I'm not sure what is "the current name mangling".

The Jv, J, and j prefixes that are prepended to CNI routines and types
(with the exception of the primitive types).

^ permalink raw reply	[flat|nested] 28+ messages in thread

* CNI namespace
  2000-03-28 12:16 CNI namespace Paul Fisher
  2000-03-29 12:59 ` Per Bothner
@ 2000-04-01  0:00 ` Paul Fisher
  1 sibling, 0 replies; 28+ messages in thread
From: Paul Fisher @ 2000-04-01  0:00 UTC (permalink / raw)
  To: java-discuss

Has there been any thought into putting the CNI functions/datatypes
into their own namespace?  And would anyone object to such a change?

I'm continuing the work on the C++ CNI->JNI translation layer, and
such a change would create a cleaner solution to the problem of
conflicting CNI and JNI types.

Adding a CNI namespace would also allow the current name mangling to
go away.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-03-29 16:32       ` Paul Fisher
  2000-03-29 17:00         ` Per Bothner
@ 2000-04-01  0:00         ` Paul Fisher
  1 sibling, 0 replies; 28+ messages in thread
From: Paul Fisher @ 2000-04-01  0:00 UTC (permalink / raw)
  To: java-discuss

Per Bothner <per@bothner.com> writes:

> How?  A JNI jarray is typedef to an unspecified pointer type.
> A CNI jarray is a typedef to a specific pointer type.
> I see no reason why the former can't be the same as the latter.

Given "jarray foo", in CNI, foo->length is valid, in JNI it is not.

I need to deal with CNI and JNI jarrarys at the same time.  That is, I
need to be able to include both jni.h and cni.h and not have typedefs
conflict.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-03-29 12:59 ` Per Bothner
  2000-03-29 14:59   ` Paul Fisher
  2000-04-01  0:00   ` Per Bothner
@ 2000-04-03 12:15   ` Tom Tromey
  2000-04-03 12:59     ` Per Bothner
  2 siblings, 1 reply; 28+ messages in thread
From: Tom Tromey @ 2000-04-03 12:15 UTC (permalink / raw)
  To: Per Bothner; +Cc: java-discuss

>> I'm continuing the work on the C++ CNI->JNI translation layer, and
>> such a change would create a cleaner solution to the problem of
>> conflicting CNI and JNI types.

Per> What is "the problem of conflicting CNI and JNI types"?

In some situations it is useful for a CNI "jobject" and a JNI
"jobject" to be different.  For instance, this is the case if we have
a precise, copying collector that doesn't have the ability to lock
down an object.

For primitive types I'm not so concerned.  The definitions we use
there preserve source and binary compatibility.

Tom

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-03-29 17:00         ` Per Bothner
  2000-04-01  0:00           ` Per Bothner
@ 2000-04-03 12:17           ` Tom Tromey
  2000-04-03 12:56             ` Per Bothner
  1 sibling, 1 reply; 28+ messages in thread
From: Tom Tromey @ 2000-04-03 12:17 UTC (permalink / raw)
  To: Per Bothner; +Cc: java-discuss

>> Given "jarray foo", in CNI, foo->length is valid, in JNI it is not.

Per> So?  I'm not seeing the problem.  In JNI, you use GetArrayLength.

My understanding is that Paul wants to write a wrapper class which
looks like a CNI jarray but acts like a JNI array.

Per> (As suggested earlier, we could sacrifice some portability in
Per> favor of simpler source files, by requiring the use of g++, but
Per> with a flag to generate the JNI ABI.  Then the binaries can be
Per> used with any Java VM, but you need non-portable tools to
Per> generate the binaries.)

The current plan is to use Paul's wrapper class idea.
Changing g++ would work, but there is nobody to do the actual
implementation.  (And, in my estimation, it is unlikely that the g++
maintainers would accept the patch in any case.)

Tom

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-04-03 12:17           ` Tom Tromey
@ 2000-04-03 12:56             ` Per Bothner
  2000-04-03 22:13               ` Paul Fisher
  0 siblings, 1 reply; 28+ messages in thread
From: Per Bothner @ 2000-04-03 12:56 UTC (permalink / raw)
  To: Tom Tromey; +Cc: java-discuss

Tom Tromey <tromey@cygnus.com> writes:

> The current plan is to use Paul's wrapper class idea.
> Changing g++ would work, but there is nobody to do the actual
> implementation.  (And, in my estimation, it is unlikely that the g++
> maintainers would accept the patch in any case.)

Paul sent me some private email, which didn't really explain the
idea.  For one thing, I don't see how the JNIEnv can get passed.
Do you have a pointer to the "wrapper class" idea?

A hybrid idea:  Modify gcc to to implement __builtin_jnienv().
This get the JNIEnv environment.  This would only be valid in
native method that has a JNIEnv parameter *or* in a function
that gets inlined into the latter.  Similarly, __builtin_jthis
gets the "this" paramater passed to a native metod.

Next change gcjh so:
class Foo
{
  int x;
  Foo f(double y);
}

gets emitted as:
class Foo : public java::lang::Object
{
  jint x;
#ifdef CNI
  inline jint get$x() { return x; }
  inline void set$x(jint n) { x = n; }
  Foo* f(jdouble y);
#else
  static jfieldID x$fieldID = 0;
  static jmethodID f = 0;
  static jclass Foo$class = 0;
  inline jint get$x() {
    JNIEnv *env = *__builtin_jni_env();
    if (Foo$class == 0) Foo$class = ...;
    if (x$fieldID == 0)
      jfieldID = (*env)->GetFieldID(env, Foo$class, "x", "I");
    return (*env)->GetIntField(env, __builtin_jthis(), x$fieldID);
    
  }
  inline void set$x(jint n) { ... }
  inline Foo* f(jdouble y) {
    JNIEnv *env = *__builtin_jni_env();
    if (Foo$class == 0) Foo$class = ...;
    if (f$methodId == 0) f$methodId = ...;
    return (*env)->CallObjectMethod(env, __builtin_jthis(), f$methodId, y);
  }
#endif
}

This requires fairly minimal changes to g++.  It requires that
inline methods get inlined in the g++ front-end, *before* __builtin_xxx
is expanded.  However, I believe that is now the case, thanks to
Mark Mitchell's work.  In addition, we need to implement a few
builtin functions like __builtin_jnienv and __builtin_jthis in g++,
but this a fairly localized and should have no impact on the rest of
g++.

It does mean that code meant to work for bothy jni and cni has to
use get$x and set$x pseudo-methods instead of using x directly.
-- 
	--Per Bothner
per@bothner.com   http://www.bothner.com/~per/

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-04-03 12:15   ` Tom Tromey
@ 2000-04-03 12:59     ` Per Bothner
  2000-04-03 14:01       ` ks
  0 siblings, 1 reply; 28+ messages in thread
From: Per Bothner @ 2000-04-03 12:59 UTC (permalink / raw)
  To: Tom Tromey; +Cc: java-discuss

Tom Tromey <tromey@cygnus.com> writes:

> In some situations it is useful for a CNI "jobject" and a JNI
> "jobject" to be different.  For instance, this is the case if we have
> a precise, copying collector that doesn't have the ability to lock
> down an object.

I don't get it.  How does having two kinds of jobject help?
-- 
	--Per Bothner
per@bothner.com   http://www.bothner.com/~per/

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-04-03 12:59     ` Per Bothner
@ 2000-04-03 14:01       ` ks
  2000-04-03 14:08         ` Per Bothner
  0 siblings, 1 reply; 28+ messages in thread
From: ks @ 2000-04-03 14:01 UTC (permalink / raw)
  To: per, tromey; +Cc: java-discuss

Wouldn't one need to get locks, while for the other getting locks would
be just pure overhead?

On Mon, Apr 03, 2000 at 12:56:30PM -0700, per@bothner.com wrote:
> Tom Tromey <tromey@cygnus.com> writes:
> 
> > In some situations it is useful for a CNI "jobject" and a JNI
> > "jobject" to be different.  For instance, this is the case if we have
> > a precise, copying collector that doesn't have the ability to lock
> > down an object.
> 
> I don't get it.  How does having two kinds of jobject help?
> -- 
> 	--Per Bothner
> per@bothner.com   http://www.bothner.com/~per/

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-04-03 14:01       ` ks
@ 2000-04-03 14:08         ` Per Bothner
  2000-04-05 15:09           ` Tom Tromey
  0 siblings, 1 reply; 28+ messages in thread
From: Per Bothner @ 2000-04-03 14:08 UTC (permalink / raw)
  To: ks; +Cc: java-discuss

ks@micky.rgv.hp.com writes:

> Wouldn't one need to get locks, while for the other getting locks would
> be just pure overhead?

Huh?  I suspect you misunderstood Tom's comment.

I wrote:
> I don't get it.  How does having two kinds of jobject help?

I thought of one possibility:  You have a jni jobject that is some
kind of indirect handle, while for cni jobject (assuming you have
a gc-aware G++) you can use the java::lang"::Object pointer directly.
-- 
	--Per Bothner
per@bothner.com   http://www.bothner.com/~per/

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-04-03 12:56             ` Per Bothner
@ 2000-04-03 22:13               ` Paul Fisher
  2000-04-04  9:36                 ` Cedric Berger
  0 siblings, 1 reply; 28+ messages in thread
From: Paul Fisher @ 2000-04-03 22:13 UTC (permalink / raw)
  To: java-discuss

Per Bothner <per@bothner.com> writes:

> Paul sent me some private email, which didn't really explain the
> idea.  For one thing, I don't see how the JNIEnv can get passed.

Sorry for the delay in replying -- been sick of late.

The JNIEnv and jobject (this) is passed into a function from the
foreign VM, so it's always around for calling member functions and
accessing fields.  When it's not possible to pass around the JNIEnv
(ie. when calling a non-member function), it can be simply retrieved
as thread local data.  No changes to g++ should be necessary.

gcjh could be modified to churn out appropriate code to handle calling
CNI functions from JNI entry points, and Java functions via JNI from
CNI entry points.

For example, a native routine for Object.hashCode () written in CNI,
and a Java routine for Object.equals (), gcjh might generate code that
looks something like:

class Object
{
  static jmethodID *method_ids;

  jobject obj;
  JNIEnv *env;
  
 public:
  Object (JNIEnv *env, jobject obj);
  
  int hashCode ();
  jboolean equals (Object *o);
};

// foreign VM JNI entry point -- passes in JNIEnv and `this'
jint
Java_java_lang_Object_hashCode (JNIEnv *env, jobject obj)
{
  Object o = Object (env, obj);
  return o.hashCode ();
}

// user written CNI routine
jint
hashCode ()
{
  return 1;
}

// turns a CNI/Java call into a JNI/Java call
jboolean
Object::equals (Object *o)
{
  if (!method_ids[EQUALS_ID])
    {
      method_ids[EQUALS_ID] =
        env->GetMethodID (env->FindClass ("java/lang/Object"),
                             "equals", "(Ljava/lang/Object;)Z");
    }

  return env->CallBooleanMethod (obj, method_ids[EQUALS_ID], o->obj);
}

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-04-03 22:13               ` Paul Fisher
@ 2000-04-04  9:36                 ` Cedric Berger
  2000-04-04 10:32                   ` Paul Fisher
  0 siblings, 1 reply; 28+ messages in thread
From: Cedric Berger @ 2000-04-04  9:36 UTC (permalink / raw)
  To: Paul Fisher; +Cc: java-discuss

Paul Fisher wrote:

> Per Bothner <per@bothner.com> writes:
>
> > Paul sent me some private email, which didn't really explain the
> > idea.  For one thing, I don't see how the JNIEnv can get passed.
>
> Sorry for the delay in replying -- been sick of late.
>
> The JNIEnv and jobject (this) is passed into a function from the
> foreign VM, so it's always around for calling member functions and
> accessing fields.  When it's not possible to pass around the JNIEnv
> (ie. when calling a non-member function), it can be simply retrieved
> as thread local data.  No changes to g++ should be necessary.
>

...

>
> class Object
> {
>   static jmethodID *method_ids;
>
>   jobject obj;
>   JNIEnv *env;

You cannot store JNIEnv in an object, because this pointer is different
for each thread. So if two threads access the same object, CRASH.

In another end, retrieving JNIEnv is very easy if the VM use JNI/1.2:
simply call
-  jint GetEnv(JavaVM *vm, void **env, jint version);
and that's it.
you just have to have a global variable to store the vm pointer.

When I deal with native functions and JNI, I define a function that looks
like:

JNIEnv *jni_get_env() {
  extern JavaVM *java_vm;
  JNIEnv *env;
   int err = GetEnv(java_vm, &env, JNI_VERSION_1_2);
   if(err == JNI_EDETACHED) {
      struct JavaVMAttachArgs args = { JNI_VERSION_1_2 };
       err = AttachCurrentThread(java_vm, &env, &args);
    }
    assert(err == JNI_OK);
    return env;
}

Cedric

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-04-04  9:36                 ` Cedric Berger
@ 2000-04-04 10:32                   ` Paul Fisher
  2000-04-04 11:18                     ` Cedric Berger
  0 siblings, 1 reply; 28+ messages in thread
From: Paul Fisher @ 2000-04-04 10:32 UTC (permalink / raw)
  To: java-discuss

Cedric Berger <cedric@wireless-networks.com> writes:

> You cannot store JNIEnv in an object, because this pointer is
> different for each thread. So if two threads access the same object,
> CRASH.

The object, or rather more of a proxy object, is created when the
foreign VM calls a JNI function.  The proxy object exists until the
JNI function returns, which is always in the context of a single
thread.  So each JNI invocation creates a new proxy object for `this',
along with any other proxy objects that become necessary as execution
continues.

> When I deal with native functions and JNI, I define a function that
> looks like:

That could be used as an alternative to storing each JNIEnv as thread
local data, but we need something that will work with 1.1 VMs.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-04-04 10:32                   ` Paul Fisher
@ 2000-04-04 11:18                     ` Cedric Berger
  2000-04-04 16:22                       ` Paul Fisher
  2000-04-04 16:27                       ` Paul Fisher
  0 siblings, 2 replies; 28+ messages in thread
From: Cedric Berger @ 2000-04-04 11:18 UTC (permalink / raw)
  To: Paul Fisher; +Cc: java-discuss

Thanks for the explanation, I understand better now what you
plan to do.

There is still one situation where I'm not sure I understand how
it will work: what will append if you keep an object "outside
the VM" for longer than a function call, for instance, i'v used
the following mechanism some time ago:

class Packet {
   Packet(int query);
   void setResponse(int i);
   int getResponse();
   int getQuery();
}
class NativeQueue {
    native void send(Packet p);
    native Packet receive();
}
class ReceiveThread(NativeQueue q) {
   public void run() {
      for(;;) {
         Packet p = q.receive();
         switch(p.getQuery()) {
             ...
         }
      }
   }
}
public stratic void main()
{
   NativeQueue q = new NativeQueue();
   (new NativeThread(q)).start();
   Packet p = new Packet(36);
   nativeQueue.enqueue(p);
   ...
}

What will appends with the Packet class when it's
"outside" the VM? how will a native thread call it's
setResponse() method? will there be more than
one wrapper around Packet?

Cedric






Paul Fisher wrote:

> Cedric Berger <cedric@wireless-networks.com> writes:
>
> > You cannot store JNIEnv in an object, because this pointer is
> > different for each thread. So if two threads access the same object,
> > CRASH.
>
> The object, or rather more of a proxy object, is created when the
> foreign VM calls a JNI function.  The proxy object exists until the
> JNI function returns, which is always in the context of a single
> thread.  So each JNI invocation creates a new proxy object for `this',
> along with any other proxy objects that become necessary as execution
> continues.
>
> > When I deal with native functions and JNI, I define a function that
> > looks like:
>
> That could be used as an alternative to storing each JNIEnv as thread
> local data, but we need something that will work with 1.1 VMs.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-04-04 11:18                     ` Cedric Berger
@ 2000-04-04 16:22                       ` Paul Fisher
  2000-04-04 16:27                       ` Paul Fisher
  1 sibling, 0 replies; 28+ messages in thread
From: Paul Fisher @ 2000-04-04 16:22 UTC (permalink / raw)
  To: java-discuss

Cedric Berger <cedric@wireless-networks.com> writes:

> class NativeQueue {
>     native void send(Packet p);
>     native Packet receive();
> }
> class ReceiveThread(NativeQueue q) {
>    public void run() {
>       for(;;) {
>          Packet p = q.receive();
>          switch(p.getQuery()) {
>              ...
>          }
>       }
>    }
> }
> public stratic void main()
> {
>    NativeQueue q = new NativeQueue();
>    (new NativeThread(q)).start();
>    Packet p = new Packet(36);
>    nativeQueue.enqueue(p);
>    ...
> }
> 
> What will appends with the Packet class when it's
> "outside" the VM? how will a native thread call it's
> setResponse() method? will there be more than
> one wrapper around Packet?
> 
> Cedric
> 
> 
> 
> 
> 
> 
> Paul Fisher wrote:
> 
> > Cedric Berger <cedric@wireless-networks.com> writes:
> >
> > > You cannot store JNIEnv in an object, because this pointer is
> > > different for each thread. So if two threads access the same object,
> > > CRASH.
> >
> > The object, or rather more of a proxy object, is created when the
> > foreign VM calls a JNI function.  The proxy object exists until the
> > JNI function returns, which is always in the context of a single
> > thread.  So each JNI invocation creates a new proxy object for `this',
> > along with any other proxy objects that become necessary as execution
> > continues.
> >
> > > When I deal with native functions and JNI, I define a function that
> > > looks like:
> >
> > That could be used as an alternative to storing each JNIEnv as thread
> > local data, but we need something that will work with 1.1 VMs.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-04-04 11:18                     ` Cedric Berger
  2000-04-04 16:22                       ` Paul Fisher
@ 2000-04-04 16:27                       ` Paul Fisher
  2000-04-05 12:05                         ` Cedric Berger
  1 sibling, 1 reply; 28+ messages in thread
From: Paul Fisher @ 2000-04-04 16:27 UTC (permalink / raw)
  To: java-discuss

Erm.  Ignore the previous message.  Fingers slipped.  Sorry. :-)

Cedric Berger <cedric@wireless-networks.com> writes:

> class NativeQueue {
>     native void send(Packet p);
>     native Packet receive();
> }

[...]

> will there be more than one wrapper around Packet?

Each call to "send" or "receive" would result in a different proxy
object being created.  So yes, there could be two different threads
both dealing on the same object, but there would be a different proxy
object for each thread that was off in native-land -- in effect, more
than one wrapper around Packet would exist at the same time, each with
a different JNIEnv.

If this doesn't answer your question, let me know.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-04-04 16:27                       ` Paul Fisher
@ 2000-04-05 12:05                         ` Cedric Berger
  2000-04-05 15:09                           ` Tom Tromey
  0 siblings, 1 reply; 28+ messages in thread
From: Cedric Berger @ 2000-04-05 12:05 UTC (permalink / raw)
  To: Paul Fisher; +Cc: java-discuss

Paul Fisher wrote:

> Cedric Berger <cedric@wireless-networks.com> writes:
>
> > class NativeQueue {
> >     native void send(Packet p);
> >     native Packet receive();
> > }
>
> [...]
>
> > will there be more than one wrapper around Packet?
>
> Each call to "send" or "receive" would result in a different proxy
> object being created.  So yes, there could be two different threads
> both dealing on the same object, but there would be a different proxy
> object for each thread that was off in native-land -- in effect, more
> than one wrapper around Packet would exist at the same time, each with
> a different JNIEnv.
>
> If this doesn't answer your question, let me know.

Ok, but then how will look the CNI functions if you want to store
Packet on a global native variable (or a queue, or whatever),
for example:

Packet *_global_variable;
NativeQueue::send(Packet *p) {
   _global_variable = p;
}
Packet *NativeQueue::receive() {
  return _global_variable;
}

since Packet is a wrapper-class, this won't work, right?

Cedric

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-04-03 14:08         ` Per Bothner
@ 2000-04-05 15:09           ` Tom Tromey
  0 siblings, 0 replies; 28+ messages in thread
From: Tom Tromey @ 2000-04-05 15:09 UTC (permalink / raw)
  To: Per Bothner; +Cc: ks, java-discuss

Per> I thought of one possibility: You have a jni jobject that is some
Per> kind of indirect handle, while for cni jobject (assuming you have
Per> a gc-aware G++) you can use the java::lang"::Object pointer
Per> directly.

Yeah, that's it.

Tom

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-04-05 12:05                         ` Cedric Berger
@ 2000-04-05 15:09                           ` Tom Tromey
  2000-04-06 10:08                             ` Cedric Berger
  0 siblings, 1 reply; 28+ messages in thread
From: Tom Tromey @ 2000-04-05 15:09 UTC (permalink / raw)
  To: Cedric Berger; +Cc: Paul Fisher, java-discuss

>>>>> "Cedric" == Cedric Berger <cedric@wireless-networks.com> writes:

Cedric> Ok, but then how will look the CNI functions if you want to
Cedric> store Packet on a global native variable (or a queue, or
Cedric> whatever), for example:

We don't really know.

Right now you can get away with doing this, if the global variable is
in the data section, because the GC scans the data section.

I doubt we want to rely on that long-term.  Instead we'll probably add
some sort of root-marking call you can make.  Perhaps we can do this
in such a way that the JNI mode will create a GlobalRef for you.

Remember that Paul's approach is really only going to be used for JNI
compatibility, where required.  In general we'll still recommend using
CNI with gcj.  And, in fact, libgcj will continue to use it.  The JNI
compatibility will only be used when building Classpath against a
non-gcj VM.

Tom

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: CNI namespace
  2000-04-05 15:09                           ` Tom Tromey
@ 2000-04-06 10:08                             ` Cedric Berger
  0 siblings, 0 replies; 28+ messages in thread
From: Cedric Berger @ 2000-04-06 10:08 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Paul Fisher, java-discuss

Tom Tromey wrote:

> >>>>> "Cedric" == Cedric Berger <cedric@wireless-networks.com> writes:
>
> Cedric> Ok, but then how will look the CNI functions if you want to
> Cedric> store Packet on a global native variable (or a queue, or
> Cedric> whatever), for example:
>
> We don't really know.
>
> Right now you can get away with doing this, if the global variable is
> in the data section, because the GC scans the data section.

I was also concerned by the fact that - if I understand correctly ?? -
Packet in my example would be a proxy class allocated by gcjh
somewhere on the stack and would become invalid as soon as send()
retruns to the VM.

> I doubt we want to rely on that long-term.  Instead we'll probably add
> some sort of root-marking call you can make.  Perhaps we can do this
> in such a way that the JNI mode will create a GlobalRef for you.
>
> Remember that Paul's approach is really only going to be used for JNI
> compatibility, where required.  In general we'll still recommend using
> CNI with gcj.  And, in fact, libgcj will continue to use it.  The JNI
> compatibility will only be used when building Classpath against a
> non-gcj VM.
>
> Tom

Yes, but I really like Paul's wrapper approach and I'm sure that if it
works well, I will also use gcjh outside of GCJ context, for programming
native methods for Sun's or IBM's VM, because the wrappers do
all the tedious job of retrieving objects ID, members, ...
Continue the good job!!

Cedric

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2000-04-06 10:08 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-03-28 12:16 CNI namespace Paul Fisher
2000-03-29 12:59 ` Per Bothner
2000-03-29 14:59   ` Paul Fisher
2000-03-29 15:50     ` Per Bothner
2000-03-29 16:32       ` Paul Fisher
2000-03-29 17:00         ` Per Bothner
2000-04-01  0:00           ` Per Bothner
2000-04-03 12:17           ` Tom Tromey
2000-04-03 12:56             ` Per Bothner
2000-04-03 22:13               ` Paul Fisher
2000-04-04  9:36                 ` Cedric Berger
2000-04-04 10:32                   ` Paul Fisher
2000-04-04 11:18                     ` Cedric Berger
2000-04-04 16:22                       ` Paul Fisher
2000-04-04 16:27                       ` Paul Fisher
2000-04-05 12:05                         ` Cedric Berger
2000-04-05 15:09                           ` Tom Tromey
2000-04-06 10:08                             ` Cedric Berger
2000-04-01  0:00         ` Paul Fisher
2000-04-01  0:00       ` Per Bothner
2000-04-01  0:00     ` Paul Fisher
2000-04-01  0:00   ` Per Bothner
2000-04-03 12:15   ` Tom Tromey
2000-04-03 12:59     ` Per Bothner
2000-04-03 14:01       ` ks
2000-04-03 14:08         ` Per Bothner
2000-04-05 15:09           ` Tom Tromey
2000-04-01  0:00 ` Paul Fisher

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).