[aarch64-port-dev ] RFR: Add fast accessors and java.lang.ref.Reference.get
Edward Nevill
edward.nevill at linaro.org
Fri Oct 17 15:18:59 UTC 2014
Hi,
Yes, fast accessors were removed in jdk9, however the java.lang.ref.Reference.get intrinsic is still present in both jdk8 and jdk9.
The patch below adds just the java.lang.ref.Reference.get intrinsic.
The reason I believe this is important is because I am not convinced that the G1GC implementation is correct without it as I cannot see how the SATB buffer gets updated without a special purpose intrinsic like this.
C1 and C2 both have special purpose code to handle updating the SATB buffer on java.language.Reference.get, and I think we need the same in the template interpreter.
Tested with hotspot JTreg -Xint -XX:+UseG1GC.
Ok to push to jdk8 and 9?
Ed.
On Thu, 2014-10-09 at 21:08 -0700, dean long wrote:
> FYI, I believe fast accessors were removed in jdk9.
>
> https://bugs.openjdk.java.net/browse/JDK-8003426
>
> dl
>
> On 10/9/2014 1:32 AM, Edward Nevill wrote:
> > Hi,
> >
> > The following patch adds support for fast accessors and java.lang.ref.Reference.get to the template interpreter.
> >
> > This probably doesn't add a great deal to overall performance but I think it is worthwhile including for completeness.
> >
> > Tested with hotspot jtreg.
> >
> > Best regards,
> > Ed.
> >
--- CUT HERE ---
# HG changeset patch
# User Edward Nevill edward.nevill at linaro.org
# Date 1413559012 -3600
# Fri Oct 17 16:16:52 2014 +0100
# Node ID b581f52e36b3f02b7e47fda48821ee1f14708e69
# Parent 7b8991391eaeb60bd7e816653e6772997e718326
Add java.lang.ref.Reference.get intrinsic to template interpreter
diff -r 7b8991391eae -r b581f52e36b3 src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp
--- a/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp Thu Oct 16 13:33:13 2014 +0100
+++ b/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp Fri Oct 17 16:16:52 2014 +0100
@@ -669,7 +669,78 @@
// Method entry for java.lang.ref.Reference.get.
address InterpreterGenerator::generate_Reference_get_entry(void) {
- return NULL;
+#if INCLUDE_ALL_GCS
+ // Code: _aload_0, _getfield, _areturn
+ // parameter size = 1
+ //
+ // The code that gets generated by this routine is split into 2 parts:
+ // 1. The "intrinsified" code for G1 (or any SATB based GC),
+ // 2. The slow path - which is an expansion of the regular method entry.
+ //
+ // Notes:-
+ // * In the G1 code we do not check whether we need to block for
+ // a safepoint. If G1 is enabled then we must execute the specialized
+ // code for Reference.get (except when the Reference object is null)
+ // so that we can log the value in the referent field with an SATB
+ // update buffer.
+ // If the code for the getfield template is modified so that the
+ // G1 pre-barrier code is executed when the current method is
+ // Reference.get() then going through the normal method entry
+ // will be fine.
+ // * The G1 code can, however, check the receiver object (the instance
+ // of java.lang.Reference) and jump to the slow path if null. If the
+ // Reference object is null then we obviously cannot fetch the referent
+ // and so we don't need to call the G1 pre-barrier. Thus we can use the
+ // regular method entry code to generate the NPE.
+ //
+ // This code is based on generate_accessor_enty.
+ //
+ // rmethod: Method*
+ // r13: senderSP must preserve for slow path, set SP to it on fast path
+
+ address entry = __ pc();
+
+ const int referent_offset = java_lang_ref_Reference::referent_offset;
+ guarantee(referent_offset > 0, "referent offset not initialized");
+
+ if (UseG1GC) {
+ Label slow_path;
+ const Register local_0 = c_rarg0;
+ // Check if local 0 != NULL
+ // If the receiver is null then it is OK to jump to the slow path.
+ __ ldr(local_0, Address(esp, 0));
+ __ cbz(local_0, slow_path);
+
+
+ // Load the value of the referent field.
+ const Address field_address(local_0, referent_offset);
+ __ load_heap_oop(local_0, field_address);
+
+ // Generate the G1 pre-barrier code to log the value of
+ // the referent field in an SATB buffer.
+ __ enter(); // g1_write may call runtime
+ __ g1_write_barrier_pre(noreg /* obj */,
+ local_0 /* pre_val */,
+ rthread /* thread */,
+ rscratch2 /* tmp */,
+ true /* tosca_live */,
+ true /* expand_call */);
+ __ leave();
+ // areturn
+ __ andr(sp, r13, -16); // done with stack
+ __ ret(lr);
+
+ // generate a vanilla interpreter entry as the slow path
+ __ bind(slow_path);
+ (void) generate_normal_entry(false);
+
+ return entry;
+ }
+#endif // INCLUDE_ALL_GCS
+
+ // If G1 is not enabled then attempt to go through the accessor entry point
+ // Reference.get is an accessor
+ return generate_accessor_entry();
}
/**
--- CUT HERE ---
More information about the aarch64-port-dev
mailing list