On 10/30/17 8:17 AM, David Holmes wrote:
On 30/10/2017 10:13 PM, coleen.phillim...@oracle.com wrote:
On 10/28/17 3:50 AM, David Holmes wrote:
Hi Coleen,

I've commented on the file location in response to Mandy's email.

The only issue I'm still concerned about is the JVM_MAXPATHLEN issue. I think it is a bug to define a JVM_MAXPATHLEN that is bigger than the platform MAXPATHLEN. I also would not want to see any change in behaviour because of this - so AIX and Solaris should not get a different JVM_MAXPATHLEN due to this refactoring change. So yes I think this needs to be ifdef'd for Linux and reluctantly (because it was a copy error) for OSX/BSD as well.

#if defined(AIX) || defined(SOLARIS)
#define JVM_MAXPATHLEN MAXPATHLEN
#else
// Hack: MAXPATHLEN is 4095 on some Linux and 4096 on others. This may
//       cause problems if JVM and the rest of JDK are built on different //       Linux releases. Here we define JVM_MAXPATHLEN to be MAXPATHLEN + 1,
//       so buffers declared in VM are always >= 4096.
#define JVM_MAXPATHLEN MAXPATHLEN + 1
#endif

Is this ok?

Yes - thanks. It preserves existing behaviour on the VM side at least. Time will tell if it messes anything up on the JDK side for Linux/OSX.

I don't want to wait for time so I'm investigating.

It's one use is:

Java_java_io_UnixFileSystem_canonicalize0(JNIEnv *env, jobject this,
...
        char canonicalPath[JVM_MAXPATHLEN];
        if (canonicalize((char *)path,
                         canonicalPath, JVM_MAXPATHLEN) < 0) {
            JNU_ThrowIOExceptionWithLastError(env, "Bad pathname");

Which goes to:

canonicalize_md.c

canonicalize(char *original, char *resolved, int len)
    if (len < PATH_MAX) {
        errno = EINVAL;
        return -1;
    }


So this should fail every time.

sys/param.h:# define MAXPATHLEN    PATH_MAX

I haven't found any tests for it.

I don't know why Java_java_io_UnixFileSystem uses JVM_MAXPATHLEN since it's not calling the JVM interface as far as I can tell.    I think it should be changed to PATH_MAX.

?
Coleen

David

thanks,
Coleen

Thanks,
David

On 28/10/2017 12:08 AM, coleen.phillim...@oracle.com wrote:


On 10/27/17 9:37 AM, David Holmes wrote:
On 27/10/2017 10:13 PM, coleen.phillim...@oracle.com wrote:


On 10/27/17 3:23 AM, David Holmes wrote:
Hi Coleen,

Thanks for tackling this.

Summary: removed hotspot version of jvm*h and jni*h files

Can you update the bug synopsis to show it covers both sets of files please.

I hate to start with this (and it took me quite a while to realize it) but as Mandy pointed out jvm.h is not an exported interface from the JDK to the outside world (so not subject to CSR review), but is a private interface between the JVM and the JDK libraries. So I think really jvm.h belongs in the hotspot sources where it was, while jni.h belongs in the exported JDK sources. In which case the bulk of your changes to the hotspot files would not be needed - sorry.

Maybe someone can make that decision and change at a later date. The point of this change is that there is now only one of these files that is shared.  I don't think jvm.h and the jvm_md.h belong on the hotspot sources for the jdk to find them in some random prims and os dependent directories.

The one file that is needed is a hotspot file - jvm.h defines the interface that hotspot exports via jvm.cpp.

If you leave jvm.h in hotspot/prims then a very large chunk of your boilerplate changes are not needed. The JDK code doesn't care what the name of the directory is - whatever it is just gets added as a -I directive (the JDK code will include "jvm.h" not "prims/jvm.h" the way hotspot sources do.

This isn't something we want to change back or move again later. Whatever we do now we live with.

I think it belongs with jni.h and I think the core libraries group would agree.   It seems more natural there than buried in the hotspot prims directory.  I guess this is on hold while we have this debate.   Sigh.

Actually with -I directives, changing to jvm.h from prims/jvm.h would still work.   Maybe we should change the name to jvm.hpp since it's jvm.cpp though?   Or maybe just have two divergent copies and close this as WNF.


I'm happy to withdraw the CSR.  We generally use the CSR process to add and remove JVM_ interfaces even though they're a private interface in case some other JVM/JDK combination relies on them. The changes to these files are very minor though and not likely to cause any even theoretical incompatibility, so I'll withdraw it.

Moving on ...

First to address the initial comments/query you had:

The JDK windows jni_md.h file defined jint as long and the hotspot
windows jni_x86.h as int. I had to choose the jdk version since it's the public version, so there are changes to the hotspot files for this.

On Windows int and long are always the same as it uses ILP32 or LLP64 (not LP64 like *nix platforms). So either choice should be fine. That said there are some odd casting issues I comment on below. Does the VS compiler complain about mixing int and long in expressions?

Yes, it does even though int and long are the same representation.

And what an absolute mess that makes. :(


Generally I changed the code to use 'int' rather than 'jint' where the
surrounding API didn't insist on consistently using java types. We
should mostly be using C++ types within hotspot except in interfaces to
native/JNI code.

I think you pulled too hard on a few threads here and things are starting to unravel. There are numerous cases I refer to below where either the cast seems unnecessary/inappropriate or else highlights a bunch of additional changes that also need to be made. The fan out from this could be horrendous. Unless you actually get some kind of error - and I'd like to understand the details of those - I would not suggest making these changes as part of this work.

I didn't make any change unless there was was an error. I have 100 failed JPRT jobs to confirm!  I eventually got a Windows system to compile and test this on. Actually some of the changes came out better.  Cases where we use jint as a bool simply turned to int. We do not have an overload for bool for cmpxchg.

That's unfortunate - ditto for OrderAccess.


Looking through I have a quite a few queries/comments - apologies in advance as I know how tedious this is:

make/hotspot/lib/CompileLibjsig.gmk
src/java.base/solaris/native/libjsig/jsig.c

Took a while to figure out why the include was needed. :) As a follow up I suggest just deleting the -I include directive, delete the Solaris-only definition of JSIG_VERSION_1_4_1, and delete everything to do with JVM_get_libjsig_version. It is all obsolete.

Can I patch up jsig in a separate RFE?  I don't remember why this broke so I simply moved JSIG #define.  Is jsig obsolete? Removing JVM_* definitions generally requires a CSR.

I did say "As a follow up". jsig is not obsolete but the jsig versioning code, only used by Solaris, is.


---

src/hotspot/cpu/arm/interp_masm_arm.cpp

Why did you need to add the jvm.h include?


   tbz(Raccess_flags, JVM_ACC_SYNCHRONIZED_BIT, unlocked);

Okay. I'm not going to try and figure out how this code found this before.

---

src/hotspot/os/windows/os_windows.cpp.

The type of process_exiting should be uint to match the DWORD of GetCurrentThreadID. Then you should need any casts. Also you missed this jint cast:

3796         process_exiting != (jint)GetCurrentThreadId()) {

Yes, that's better to change process_exiting to a DWORD.  It needs a DWORD cast to 0 in the cmpxchg.

         Atomic::cmpxchg(GetCurrentThreadId(), &process_exiting, (DWORD)0);

These templates are picky.

Yes - their inability to deal with literals is extremely frustrating.


---

src/hotspot/share/c1/c1_Canonicalizer.hpp

  43 #ifdef _WINDOWS
  44   // jint is defined as long in jni_md.h, so convert from int to jint
  45   void set_constant(int x) { set_constant((jint)x); }
  46 #endif

Why is this necessary? int and long are the same on Windows. The whole point is that jint hides the underlying type, so where does this go wrong?

No, they are not the same types even though they have the same representation!

This is truly unfortunate.


---

src/hotspot/share/c1/c1_LinearScan.cpp

 ConstantIntValue((jint)0);

why is this cast needed? what causes the ambiguity? (If this was a template I'd understand ;-) ). Also didn't you change that constructor to take an int anyway - not that I think it should - see below.

Yes, it caused an ambiguity.  0 matches 'int' but it doesn't match 'long' better than any pointer type.  So this cast is needed.

But you changed the constructor to take an int!

 class ConstantIntValue: public ScopeValue {
  private:
-  jint _value;
+  int _value;
  public:
-  ConstantIntValue(jint value)         { _value = value; }
+  ConstantIntValue(int value)          { _value = value; }



Okay I removed this cast.

---

src/hotspot/share/ci/ciReplay.cpp

793         jint* dims = NEW_RESOURCE_ARRAY(jint, rank);

why should this be jint?

To avoid a cast from int* to jint* in the line below:

          value = kelem->multi_allocate(rank, dims, CHECK);



---

src/hotspot/share/classfile/altHashing.cpp

Okay this looks more consistent with jint.

Yes.  I translated this from some native code iirc.

---

src/hotspot/share/code/debugInfo.hpp

These changes seem wrong. We have:

ConstantLongValue(jlong value)
ConstantDoubleValue(jdouble value)

so we should have:

ConstantIntValue(jint value)

Again, there are multiple call sites with '0', which match int trivially but are confused with long.  It's less consistent I agree but better to not cast all the call sites.

This is really making a mess of the APIs - they should be a jint but we declare them int because of a 0 casting problem. Can't we just use 0L?

There aren't that many casts.  You're right, that would have been better in some places.


---

src/hotspot/share/code/relocInfo.cpp

Change seems unnecessary - int32_t is fine


No, int32_t doesn't match the calls below it.  They all assume _lo and _hi are jint.
---

src/hotspot/share/compiler/compileBroker.cpp
src/hotspot/share/compiler/compileBroker.hpp

I see a complete mix of int and jint in this class, so why make the one change you did ??

This is another case of using jint as a flag with cmpxchg. The templates for cmpxchg want the types to match and 0 and 1 are essentially 'int'.  This is a lot cleaner this way.

<sigh>


---

src/hotspot/share/jvmci/jvmciCompilerToVM.cpp

1700     tty->write((char*) start, MIN2(length, (jint)O_BUFLEN));

why did you need to add the jint cast? It's used without any cast on the next two lines:

1701     length -= O_BUFLEN;
1702     offset += O_BUFLEN;


There's a conversion from O_BUFLEN from int to long in 1701 and 1702.   MIN2 is a template that wants the types to match exactly.

$%^%$! templates!

??

---

src/hotspot/share/jvmci/jvmciRuntime.cpp

Looking around this code it seems very confused about types - eg the previous function is declared jboolean yet returns a jint on one path! It isn't clear to me if the return type is what should be changed or the parameter type? I would just leave this alone.

I can't leave it alone because it doesn't compile that way. This was the minimal change and yea, does look a bit inconsistent.

---

src/hotspot/share/opto/mulnode.cpp

Okay TypeInt has jint parts, so the remaining int32_t declarations (A, B, C, D) should also be jint.

Yes.  c2 uses jint types.

---

src/hotspot/share/opto/parse3.cpp

I agree with the changes you made, but then:

 419     jint dim_con = find_int_con(length[j], -1);

should also be changed.

And obviously MultiArrayExpandLimit should be defined as int not intx!

Everything in globals.hpp is intx.  That's a thread that I don't want to pull on!

We still have that limitation? <double sigh>

Changed dim_con to int.

---

src/hotspot/share/opto/phaseX.cpp

I can see that intcon(jint i) is consistent with longcon(jlong l), but the use of "i" in the code is more consistent with int than jint.

huh?  really?

---

src/hotspot/share/opto/type.cpp

1505 int TypeInt::hash(void) const {
1506   return java_add(java_add(_lo, _hi), java_add((jint)_widen, (jint)Type::Int));
1507 }

I can see that the (jint) casts you added make sense, but then the whole function should be returning jint not int. Ditto the other hash functions.

I'm not messing with this, this is the minimal in type fixing that I'm going to do here.

<sigh>


---

src/hotspot/share/prims/jni.cpp

I think vm_created should be a bool. In fact all the fields you changed are logically bools - do Atomics work for bool now?

No, they do not.   I had thought bool would be better originally too.

---

src/hotspot/share/prims/jvm.cpp

is_attachable is the terminology used in the JDK code.

Well the JDK version had is_attach_supported() as the flag name so I used that in this one place.

---

src/hotspot/share/prims/jvmtiEnvBase.cpp
src/hotspot/share/prims/jvmtiImpl.cpp

Are you making parameters consistent with the fields they initialize?

They're consistent with the declarations now.

---

src/hotspot/share/prims/jvmtiTagMap.cpp

There is a mix of int and jint for slot in this code. You fixed some, but this remains:

2440 inline bool CallbackInvoker::report_stack_ref_root(jlong thread_tag,
2441 jlong tid,
2442 jint depth,
2443 jmethodID method,
2444 jlocation bci,
2445 jint slot,

Right for consistency with the declarations.

---

src/hotspot/share/runtime/perfData.cpp

Callers pass both jint and int, so param type seems arbitrary.

They are, but importantly they match the declarations.

---

src/hotspot/share/runtime/perfMemory.cpp
src/hotspot/share/runtime/perfMemory.hpp

PerfMemory::_initialized should ideally be a bool - can OrderAccess handle that now?

Nope.

---

src/java.base/share/native/include/jvm.h

Not clear why the jio functions are not also JNICALL ?

They are now.  The JDK version didn't have JNICALL.  JVM needs JNICALL.  I can't tell you why JDK didn't need JNICALL linkage.

?? JVM currently does not have JNICALL. But they are declared as "extern C".

This was a compilation error on Windows with JDK.   Maybe the C code in the JDK doesn't complain about linkage differences. I'll have to go back and figure this out then.


---

src/java.base/unix/native/include/jni_md.h

There is no need to special case ARM. The differences in the existing code were for LTO support and that is now irrelevant.

See discussion with Magnus.   We still build ARM for jdk10/hs so I needed this conditional or of course I wouldn't have added it.  We can remove it with LTO support.

Those builds are gone - this is obsolete. But yes all LTO can be removed later if you wish. Just trying to simplify things now.


---

src/java.base/unix/native/include/jvm_md.h

I know you've just copied this across, but it seems wrong to me:

 57 // Hack: MAXPATHLEN is 4095 on some Linux and 4096 on others. This may   58 //       cause problems if JVM and the rest of JDK are built on different   59 //       Linux releases. Here we define JVM_MAXPATHLEN to be MAXPATHLEN + 1,
  60 //       so buffers declared in VM are always >= 4096.
  61 #define JVM_MAXPATHLEN MAXPATHLEN + 1

It doesn't make sense to me to define an internal "max path length" that can _exceed_ the platform max!

That aside there's no support for building different parts of the JDK on different platforms and then bringing them together. And in any case I would think the real problem would be building on a platform that uses 4096 and running on one that uses 4095!

But that aside this is a Linux hack and should be guarded by ifdef LINUX. (I doubt BSD needs it, the bsd file is just a copy of the linux one - the JDK macosx version does the right thing). Solaris and AIX should stay as-is at MAXPATHLEN.

All of the unix platforms had MAXPATHLEN+1.  I'll leave it for now and we can investigate that further.

I see the following existing code:

src/java.base/unix/native/include/jvm_md.h:

#define JVM_MAXPATHLEN MAXPATHLEN

src/java.base/macosx/native/include/jvm_md.h

#define JVM_MAXPATHLEN MAXPATHLEN

src/hotspot/os/aix/jvm_aix.h

#define JVM_MAXPATHLEN MAXPATHLEN

src/hotspot/os/bsd/jvm_bsd.h

#define JVM_MAXPATHLEN MAXPATHLEN + 1  // blindly copied from Linux version

src/hotspot/os/linux/jvm_linux.h

#define JVM_MAXPATHLEN MAXPATHLEN + 1

src/hotspot/os/solaris/jvm_solaris.h

#define JVM_MAXPATHLEN MAXPATHLEN

This is a linux only hack (if you ignore the blind copy from linux into the BSD code in the VM).

Oh, thanks, so should I add a bunch of ifdefs then?  Or do you think having MAXPATHLEN + 1 will really break the other platforms?  Do you really see this as a problem or are you just pointing out inconsistency?


 86 #define ASYNC_SIGNAL     SIGJVM2

This only exists on Solaris so I think should be in #ifdef SOLARIS, to make that clear.

Ok.  I'll add this.

---

src/java.base/windows/native/include/jvm_md.h

Given the differences between the two versions either something has been broken or "extern C" declarations are not needed :)

Well, they are needed for Hotspot to build and do not prevent jdk from building.  I don't know what was broken.

We really need to understand this better. Maybe related to the map files that expose the symbols. ??

They're needed because the JDK files are written mostly in C and that doesn't complain about the linkage difference. Hotspot files are in C++ which does complain.



---

That was a really painful way to spend most of my Friday. TGIF! :)

Thanks for going through it.  See comments inline for changes. Generating a webrev takes hours so I'm not going to do that unless you insist.

An incremental webrev shouldn't take long - right? You're a mq maestro now. :)

Well I generally trash a repository whenever I use mq but sure.

If you can reasonably produce an incremental webrev once you've settled on all the comments/issues that would be good.

Ok, sure.

Coleen

Thanks,
David

Thanks,
Coleen



Thanks,
David
-----


On 27/10/2017 6:44 AM, coleen.phillim...@oracle.com wrote:
  Hi Magnus,

Thank you for reviewing this.   I have a new version that takes out the hack in globalDefinitions.hpp and adds casts to src/hotspot/share/opto/type.cpp instead.

Also some fixes from Martin at SAP.

open webrev at http://cr.openjdk.java.net/~coleenp/8189610.02/webrev

see below.

On 10/26/17 5:57 AM, Magnus Ihse Bursie wrote:
Coleen,

Thank you for addressing this!

On 2017-10-25 18:49, coleen.phillim...@oracle.com wrote:
Summary: removed hotspot version of jvm*h and jni*h files

Mostly used sed to remove prims/jvm.h and move #include "jvm.h" after precompiled.h, so if you have repetitive stress wrist issues don't click on most of these files.

There were more issues to resolve, however.  The JDK windows jni_md.h file defined jint as long and the hotspot windows jni_x86.h as int. I had to choose the jdk version since it's the public version, so there are changes to the hotspot files for this. Generally I changed the code to use 'int' rather than 'jint' where the surrounding API didn't insist on consistently using java types. We should mostly be using C++ types within hotspot except in interfaces to native/JNI code.  There are a couple of hacks in places where adding multiple jint casts was too painful.

Tested with JPRT and tier2-4 (in progress).

open webrev at http://cr.openjdk.java.net/~coleenp/8189610.01/webrev

Looks great!

Just a few comments:

* src/java.base/unix/native/include/jni_md.h:

I don't think the externally_visible attribute should be there for arm. I know this was the case for the corresponding hotspot file for arm, but that was techically incorrect. The proper dependency here is that externally_visible should be in all JNIEXPORT if and only if we're building with JVM feature "link-time-opt". Traditionally, that feature been enabled when building arm32 builds, and only then, so there's been a (coincidentally) connection here. Nowadays, Oracle does not care about the arm32 builds, and I'm not sure if anyone else is building them with link-time-opt enabled.

It does seem wrong to me to export this behavior in the public jni_md.h file, though. I think the correct way to solve this, if we should continue supporting link-time-opt is to make sure this attribute is set for exported hotspot functions. If it's still needed, that is. A quick googling seems to indicate that visibility("default") might be enough in modern gcc's.

A third option is to remove the support for link-time-opt entirely, if it's not really used.

I didn't know how to change this since we are still building ARM with the jdk10/hs repository, and ARM needed this change.  I could wait until we bring down the jdk10/master changes that remove the ARM build and remove this conditional before I push. Or we could file an RFE to remove link-time-opt (?) and remove it then?


* src/java.base/unix/native/include/jvm_md.h and src/java.base/windows/native/include/jvm_md.h:

These files define a public API, and contain non-trivial changes. I suspect you should file a CSR request. (Even though I realize you're only matching the header file with the reality.)


I filed the CSR.   Waiting for the next steps.

Thanks,
Coleen

/Magnus

bug link https://bugs.openjdk.java.net/browse/JDK-8189610

I have a script to update copyright files on commit.

Thanks to Magnus and ErikJ for the makefile changes.

Thanks,
Coleen







Reply via email to