Making Unsafe safer

Overview

If you use Unsafe directly, you risk crashing the JVM.  This happens when you access a page of memory which hasn’t been mapped and the result on Unix is a SIGSEG (if you access page 0) or SIGBUS (if you access another page which is not mapped).

Using MethodHandles

Wrapping Unsafe method with a MethodHandle is a possible solution. You can add code to Method Handles to check for a zero page access. e.g. unsigned_ptr < 4096. The reason you should add this to MethodHandle is that it makes it easier to optimise away this check.

Downside of this is that

  • You have to use MethodHandles which complicates the syntax and obscures what you are really doing.
  • It doesn’t work if you don’t
  • It doesn’t cover bus errors, nor could it as the mapping for the whole application is complex, and can change in any thread at any time.
  • Optimising away the bounds check requires some work to the optimiser which is yet to be proven.

Using Signals

If only there was some way to do this in the hardware already, and there is.  The CPU already checks if a page you attempt to access is valid and it throws an interrupt if the page is not in cache. This interrupt is turned into a signal if the OS cannot find/create a mapping for this cache miss.

If only there was a signal handler in the JVM already, and there is, this is what produces the crash report.

If only there was some way for an interrupt handler to trigger an error or exception back to the code which triggered it. Like Thread.currentThread().stop(e); (You get the idea)

Advantages

  • No additional work is required to perform the checking as it is already done by the CPU.
  • Minimal changes to the optimiser (if any).
  • Potentially work for signals produced from a range of source.
  • Using signals is a mature/old tech way of trapping runtime errors which pre-date Java.

Disadvantages

  • Single processing is likely to be a stop-the-world operation (no way to benchmark this in Java currently)
  • Even if it is not, it is likely to be much more expensive when an error is triggered.
  • You would have to change the signal handler which traditionally hasn’t been changed. i.e. there is much more experience of changing the optimiser.

Possible exceptions thrown

New exceptions could be thrown, however I suggest re-using existing exceptions.

Access to page 0 – NullPointerException

Accesses to page 0 (not just access of a NULL pointer) trigger a SIGSEG.  NPE is named after the access of a NULL pointer from C and it is perhaps more obvious to have a NPE for an access to a NULL pointer than a reference. i.e. it could have been called NullReferenceException since Java doesn’t have pointers.

Invalid Access – IndexOutOfBoundsException

Other candidates include BufferUnderflowException (if you are a page short of a mapped region), BufferOverflowException (if you are a page long of a mapped region).

Something these all have in common is that they are RuntimeException(s).  If a custom, more descriptive exception is raised, a RuntimeException might be consistent with existing throwables thrown.

Conclusion

A common trick to maximise performance is; don’t write in Java something your system is doing for you already.  In Chronicle we use the OS to do the asynchronous persistence to disk and it is more efficient and reliable than writing the same again in Java.  Similarly, trapping and handling invalid memory access would be more efficient and more robust if the facilities provided by the CPU and OS were re-used.

Generally speaking you would re-write OS features when each OS does things differently to support cross platform compatibility, but only a minimum required to do this.  This is why Java doesn’t have a thread scheduler and in relativity has little control over how threads are run.

Virtual memory handling is so old and standard, that major platforms all work basically the same way.

Reference: Making Unsafe safer from our JCG partner Peter Lawrey at the Vanilla Java blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


nine × = 72



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close