Skip to content

Conversation

@jdksjolen
Copy link
Contributor

@jdksjolen jdksjolen commented May 29, 2023

A final sweep of Hotspot to remove all re-added NULLs. With only 110 changes I'd appreciate if this was considered trivial.


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8309044: Replace NULL with nullptr, final sweep of hotspot code

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/14198/head:pull/14198
$ git checkout pull/14198

Update a local copy of the PR:
$ git checkout pull/14198
$ git pull https://git.openjdk.org/jdk.git pull/14198/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 14198

View PR using the GUI difftool:
$ git pr show -t 14198

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/14198.diff

Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented May 29, 2023

👋 Welcome back jsjolen! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented May 29, 2023

@jdksjolen The following labels will be automatically applied to this pull request:

  • graal
  • hotspot
  • serviceability
  • shenandoah

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing lists. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added graal graal-dev@openjdk.org serviceability serviceability-dev@openjdk.org hotspot hotspot-dev@openjdk.org shenandoah shenandoah-dev@openjdk.org labels May 29, 2023
Copy link
Contributor Author

@jdksjolen jdksjolen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of the stuff to actually keep.


void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &cbuf, methodHandle& method, jint pc_offset, JVMCI_TRAPS) {
NativeCall* call = NULL;
NativeCall* call = nullptr;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

T

// Check for proper post_call_nop
NativePostCallNop* nop = nativePostCallNop_at(call->next_instruction_address());
if (nop == NULL) {
if (nop == nullptr) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

T

__ ld_ptr(method, array_base_offset + in_bytes(ResolvedIndyEntry::method_offset()), cache);

// The invokedynamic is unresolved iff method is NULL
// The invokedynamic is unresolved iff method is null
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

T

// Make sure klass is 'reasonable', which is not zero.
__ load_klass(obj, obj, tmp1); // get klass
__ beqz(obj, error); // if klass is NULL it is broken
__ beqz(obj, error); // if klass is null it is broken
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

T

StubRoutines::_forward_exception_entry = generate_forward_exception();

if (UnsafeCopyMemory::_table == NULL) {
if (UnsafeCopyMemory::_table == nullptr) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

T

start_log();
} else {
// and leave xtty as nullptr
// and leave xtty as null
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

T

Comment on lines +765 to +771
assert(p->key() != nullptr, "p->key() is null");
if (p->readable()) {
// Print in two stages to avoid problems with long
// keys/values.
text->print_raw(p->key());
text->put('=');
assert(p->value() != nullptr, "p->value() is nullptr");
assert(p->value() != nullptr, "p->value() is null");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

T

Writer(const ARR& array)
: _array(const_cast<ARR&>(array)), _limit_ptr(nullptr), _position(0) {
// Note: if _limit_ptr is nullptr, the ARR& is never reassigned,
// Note: if _limit_ptr is null, the ARR& is never reassigned,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

T

// Utility methods

// Returns nullptr if 'c' it not found. This only works as long
// Returns null if 'c' it not found. This only works as long
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

T

static char _detail_msg[1024];

static Thread* _thread; // nullptr if it's native thread
static Thread* _thread; // null if it's native thread
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

T

@jdksjolen jdksjolen marked this pull request as ready for review May 29, 2023 10:55
@openjdk openjdk bot added the rfr Pull request is ready for review label May 29, 2023
@mlbridge
Copy link

mlbridge bot commented May 29, 2023

Webrevs

@offamitkumar
Copy link
Member

not a review, but would you like to check if these could replaced as well :-)

./cpu/ppc/macroAssembler_ppc.hpp:735:  void load_klass_check_null(Register dst, Register src, Label* is_null = NULL);
./cpu/ppc/stubGenerator_ppc.cpp:4700:    if (UnsafeCopyMemory::_table == NULL) {
./cpu/riscv/codeBuffer_riscv.cpp:74:  if (cb->stubs()->maybe_expand_to_ensure_remaining(total_requested_size) && cb->blob() == NULL) {
./share/include/jvm.h:423: * Find a class from a boot class loader. Returns NULL if class not found.
./share/include/cds.h:72:  char*   _mapped_base;       // Actually mapped address (NULL if this region is not mapped).
./share/opto/runtime.cpp:491:  fields[TypeFunc::Parms+0] = NULL; // void

Copy link
Member

@stefank stefank left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Though, I'd prefer if we could slightly tweak the following two print lines.

st->print(PTR_FORMAT " is a zaddress: ", untype(addr));

if (addr == zaddress::null) {
st->print_raw_cr("NULL");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer if this were left as either NULL or null.


if (addr == zaddress::null) {
st->print_raw_cr("NULL");
st->print_raw_cr("nullptr");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer if this were left as either NULL or null.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest: null

@openjdk
Copy link

openjdk bot commented May 29, 2023

@jdksjolen This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8309044: Replace NULL with nullptr, final sweep of hotspot code

Reviewed-by: stefank, dholmes, kvn, amitkumar

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 29 new commits pushed to the master branch:

  • 927a9ed: 8240774: [REDO] G1DirtyCardQueue destructor has useless flush
  • 119994f: 8308997: RISC-V: Sign extend when comparing 32-bit value with zero instead of testing the sign bit
  • 327733c: 8308986: Disable svc tests failing with virtual thread factory
  • 1e6770f: 8308341: JNI_GetCreatedJavaVMs returns a partially initialized JVM
  • cb40db0: 8309134: Augment test/langtools/tools/javac/versions/Versions.java for JDK 21 language changes
  • de7fd1c: 8307944: ClassFileDumper should only load java.nio.file.Path if enabled
  • 7891de3: 8297885: misc sun/security/pkcs11 tests timed out
  • 323d6ce: 8308960: Decouple internal Version and OperatingSystem classes
  • 1b8e6bf: 8308987: Update java.lang.Class to use javadoc snippets
  • 04b0e78: 8307648: java/net/httpclient/ExpectContinueTest.java timed out
  • ... and 19 more: https://git.openjdk.org/jdk/compare/70130d3b16e76364ede72dec421ed6e7c40467fe...master

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

➡️ To integrate this PR with the above commit message to the master branch, type /integrate in a new comment.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label May 29, 2023
Copy link
Member

@dholmes-ora dholmes-ora left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. A few suggested changes below.

Can we now poison NULL so it can't get reintroduced? Or would that potentially break standard headers?

Thanks

__ ld_ptr(method, array_base_offset + in_bytes(ResolvedIndyEntry::method_offset()), cache);

// The invokedynamic is unresolved iff method is NULL
// The invokedynamic is unresolved iff method is nullptr
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest: null

__ load_klass(obj, obj, tmp1); // get klass
__ testptr(obj, obj);
__ jcc(Assembler::zero, error); // if klass is NULL it is broken
__ jcc(Assembler::zero, error); // if klass is nullptr it is broken
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggest: null


if (addr == zaddress::null) {
st->print_raw_cr("NULL");
st->print_raw_cr("nullptr");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest: null


if (addr == zaddress::null) {
st->print_raw_cr("NULL");
st->print_raw_cr("nullptr");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest: null

\
develop(bool, InterceptOSException, false, \
"Start debugger when an implicit OS (e.g. nullptr) " \
"Start debugger when an implicit OS (e.g. null) " \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest: null pointer

@jdksjolen
Copy link
Contributor Author

Hi, thank you all for the suggestions! I've now applied them. I'll look at integrating tomorrow.

Copy link
Contributor

@vnkozlov vnkozlov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good.

Copy link
Member

@offamitkumar offamitkumar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing the comment. Looks Good :-)

@jdksjolen
Copy link
Contributor Author

Right, seems like the Windows CI fails at fetching JTReg. I'm merging this, thank you all for the reviews.

/integrate

@openjdk
Copy link

openjdk bot commented May 31, 2023

Going to push as commit 4f16161.
Since your change was applied there have been 30 commits pushed to the master branch:

  • 8823626: 8309048: Remove malloc locker test case
  • 927a9ed: 8240774: [REDO] G1DirtyCardQueue destructor has useless flush
  • 119994f: 8308997: RISC-V: Sign extend when comparing 32-bit value with zero instead of testing the sign bit
  • 327733c: 8308986: Disable svc tests failing with virtual thread factory
  • 1e6770f: 8308341: JNI_GetCreatedJavaVMs returns a partially initialized JVM
  • cb40db0: 8309134: Augment test/langtools/tools/javac/versions/Versions.java for JDK 21 language changes
  • de7fd1c: 8307944: ClassFileDumper should only load java.nio.file.Path if enabled
  • 7891de3: 8297885: misc sun/security/pkcs11 tests timed out
  • 323d6ce: 8308960: Decouple internal Version and OperatingSystem classes
  • 1b8e6bf: 8308987: Update java.lang.Class to use javadoc snippets
  • ... and 20 more: https://git.openjdk.org/jdk/compare/70130d3b16e76364ede72dec421ed6e7c40467fe...master

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot added the integrated Pull request has been integrated label May 31, 2023
@openjdk openjdk bot closed this May 31, 2023
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels May 31, 2023
@openjdk
Copy link

openjdk bot commented May 31, 2023

@jdksjolen Pushed as commit 4f16161.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

@TobiHartmann
Copy link
Member

What's the plan now to prevent re-introducing NULL?

@theRealAph
Copy link
Contributor

Can we now poison NULL so it can't get reintroduced? Or would that potentially break standard headers?

I'm sure it would. Maybe some changes to Skara?

@jdksjolen
Copy link
Contributor Author

What's the plan now to prevent re-introducing NULL?

Hi Tobias. The only plan in place is social, the reviewers have to look out for it. I am however researching how to do this through machine. I'm currently researching ways of preventing any re-introductions by machine. These include poisoning the NULL macro by re-defining it and finding a tool which is capable of parsing C++ code which is yet to go through the pre-processor.

@dougxc
Copy link
Member

dougxc commented Jun 1, 2023

It may be simpler to use simple grepping + an allow list. For example using ag and grep seems to catch the few remaining offenders:

> ag NULL src/hotspot/ --cpp | grep -v _NULL | grep -v NULL_ | grep -v -E '[A-Z]NULL' | grep -v -E '//.*NULL' | grep -v '"NULL"'
src/hotspot/cpu/ppc/macroAssembler_ppc.hpp:735:  void load_klass_check_null(Register dst, Register src, Label* is_null = NULL);
src/hotspot/cpu/ppc/stubGenerator_ppc.cpp:4700:    if (UnsafeCopyMemory::_table == NULL) {
src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp:191:    if (nop == NULL) {
src/hotspot/cpu/riscv/codeBuffer_riscv.cpp:74:  if (cb->stubs()->maybe_expand_to_ensure_remaining(total_requested_size) && cb->blob() == NULL) {
src/hotspot/cpu/riscv/stubGenerator_riscv.cpp:4019:    if (UnsafeCopyMemory::_table == NULL) {
src/hotspot/cpu/riscv/stubGenerator_riscv.cpp:4077:    if (bs_nm != NULL) {
src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp:125:  NativeCall* call = NULL;
src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp:158:    if (nop == NULL) {
src/hotspot/share/jfr/dcmd/jfrDcmds.hpp:162:    JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", NULL};
src/hotspot/share/jfr/dcmd/jfrDcmds.hpp:187:    JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", NULL};
src/hotspot/share/include/jvm.h:423: * Find a class from a boot class loader. Returns NULL if class not found.
src/hotspot/share/prims/jvmtiAgent.cpp:375:  const jint err = (*on_load_entry)(&main_vm, const_cast<char*>(agent->options()), NULL);
src/hotspot/share/prims/whitebox.cpp:1885:  if (cp->cache() == NULL) {
src/hotspot/share/prims/whitebox.cpp:1894:  if (cp->cache() == NULL) {
src/hotspot/share/classfile/stringTable.hpp:150:  static oop init_shared_table(const DumpedInternedStrings* dumped_interned_strings) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
src/hotspot/share/utilities/globalDefinitions_xlc.hpp:95:  #undef NULL
src/hotspot/share/utilities/globalDefinitions_xlc.hpp:96:  #define NULL 0L
src/hotspot/share/utilities/globalDefinitions_xlc.hpp:98:  #ifndef NULL
src/hotspot/share/utilities/globalDefinitions_xlc.hpp:99:    #define NULL 0
src/hotspot/share/cds/filemap.cpp:363:  assert(ent != NULL, "sanity");
src/hotspot/share/utilities/globalDefinitions_visCPP.hpp:65:#undef NULL
src/hotspot/share/utilities/globalDefinitions_visCPP.hpp:69:#define NULL 0LL
src/hotspot/share/utilities/globalDefinitions_visCPP.hpp:71:#ifndef NULL
src/hotspot/share/utilities/globalDefinitions_visCPP.hpp:72:#define NULL 0
src/hotspot/share/utilities/globalDefinitions.cpp:162:  static_assert(sizeof(NULL) == sizeof(char*), "NULL must be same size as pointer");
src/hotspot/share/adlc/output_c.cpp:279:  for (pipeline->_reslist.reset(); (resource = pipeline->_reslist.iter()) != NULL;) {
src/hotspot/share/adlc/output_c.cpp:305:  for (pipeline->_reslist.reset(); (resource = pipeline->_reslist.iter()) != NULL;) {
src/hotspot/share/adlc/output_c.cpp:368:  for (pipeline->_reslist.reset(); (resource = pipeline->_reslist.iter()) != NULL;) {
src/hotspot/share/adlc/output_c.cpp:393:  for (pipeline->_reslist.reset(); (resource = pipeline->_reslist.iter()) != NULL;) {
src/hotspot/share/adlc/output_c.cpp:1009:  for (_pipeline->_reslist.reset(); (resource = _pipeline->_reslist.iter()) != NULL;) {
src/hotspot/share/gc/x/xBarrierSet.inline.hpp:187:    return Raw::oop_arraycopy_in_heap(nullptr, 0, src, NULL, 0, dst, length);
src/hotspot/share/gc/x/xPageTable.inline.hpp:43:    if (entry != NULL && entry != _prev) {
src/hotspot/share/gc/x/xBarrier.cpp:242:  return NULL;
src/hotspot/share/oops/cpCache.cpp:888:  LogStream* log_stream = NULL;
src/hotspot/share/oops/cpCache.cpp:906:    assert(resolved_references->obj_at(appendix_index) == NULL, "init just once");
src/hotspot/share/oops/cpCache.cpp:914:  if (log_stream != NULL) {
src/hotspot/share/opto/runtime.cpp:491:  fields[TypeFunc::Parms+0] = NULL; // void
src/hotspot/share/jvmci/jvmciEnv.cpp:366:    if (ex != NULL) {

@TobiHartmann
Copy link
Member

I think if we just rely on reviews, NULLs will slip through again and we would need to have regular cleanup PRs.

Doug's idea seems simple enough to implement in Skara/jcheck. An alternative to whitelisting would be a warning in the offending PR or a requirement for "special approvement" of such changes (for example, via a Skara command).

sspitsyn

This comment was marked as resolved.

@TheShermanTanker
Copy link
Contributor

I'm an entire year late, but if poisoning NULL is desired, what about #pragma GCC poison?

@TheShermanTanker
Copy link
Contributor

For Visual C++, that would be #pragma deprecated("NULL")

To quote Microsoft:
"You can deprecate macro names. Place the macro name in quotes or else macro expansion will occur."

I have no idea how to achieve this with the xlc compiler

@kimbarrett
Copy link

I don't think #pragma GCC poison works for us. It would complain about a
system or library header that uses NULL and is included after the pragma.

MSVC's deprecation pragma might work for this, at least for shared and
Windows-specific code. I couldn't find a way to use it for FORBID_C_FUNCTION,
but the problems I encountered for that don't seem applicable in this case.

However, there are still a lot of NULL's left. All of the per-cpu .ad files,
and the jvmtiXXX.xsl files contain NULL's that will appear in the associated
generated code. Also, NULL usage in gtests doesn't seem to have been addressed
yet.

But it does look like there's been a bit of backsliding:
https://bugs.openjdk.org/browse/JDK-8324286

@TheShermanTanker
Copy link
Contributor

I don't think #pragma GCC poison works for us. It would complain about a
system or library header that uses NULL and is included after the pragma.

I see, that's a shame in that case

However, there are still a lot of NULL's left. All of the per-cpu .ad files, and the jvmtiXXX.xsl files contain NULL's that will appear in the associated generated code. Also, NULL usage in gtests doesn't seem to have been addressed yet.

But it does look like there's been a bit of backsliding: https://bugs.openjdk.org/browse/JDK-8324286

That's a little worrying, maybe the Style Guide's NULL section could be reworded since now most usages of NULL are nullptr? The .ad files and .xsl files are a bit of a problem though

MSVC's deprecation pragma might work for this, at least for shared and
Windows-specific code. I couldn't find a way to use it for FORBID_C_FUNCTION,
but the problems I encountered for that don't seem applicable in this case.

The deprecation pragma only works for macros and identifiers, it doesn't accept method signatures and would warn for every time a identifier is used, even in the method's declaration itself! Probably can't be used in FORBID_C_FUNCTION as mentioned above, but sounds good for a macro like NULL

I've also been trying to implement FORBID_C_FUNCTION and ALLOW_C_FUNCTION portably, speaking of it, but it hasn't been going great so far :/ #17387

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

graal graal-dev@openjdk.org hotspot hotspot-dev@openjdk.org integrated Pull request has been integrated serviceability serviceability-dev@openjdk.org shenandoah shenandoah-dev@openjdk.org

Development

Successfully merging this pull request may close these issues.