8189916: Dynamic Constant support for Sparc
authorlfoltan
Fri, 04 May 2018 12:14:09 -0400
changeset 49987 e4b3cc56e2b2
parent 49986 29b840b16a96
child 50014 09cbe16c0662
child 56532 a594484f54db
8189916: Dynamic Constant support for Sparc Summary: Change to the template interpreter to support dynamic constant on Sparc. Reviewed-by: coleenp, psandoz
src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
src/hotspot/cpu/sparc/interp_masm_sparc.cpp
src/hotspot/cpu/sparc/templateTable_sparc.cpp
src/hotspot/cpu/x86/templateTable_x86.cpp
test/hotspot/jtreg/runtime/appcds/condy/CondyHelloTest.java
test/hotspot/jtreg/runtime/condy/BadBSMUseTest.java
test/hotspot/jtreg/runtime/condy/CondyBadBSMArrayTest.java
test/hotspot/jtreg/runtime/condy/CondyBadNameTypeTest.java
test/hotspot/jtreg/runtime/condy/CondyCFVCheckTest.java
test/hotspot/jtreg/runtime/condy/CondyLDCTest.java
test/hotspot/jtreg/runtime/condy/CondyNewInvokeSpecialTest.java
test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java
test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java
test/jdk/java/lang/invoke/condy/CondyWrongType.java
test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java
--- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp	Fri May 04 10:45:47 2018 -0400
+++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp	Fri May 04 12:14:09 2018 -0400
@@ -407,7 +407,7 @@
   __ bind(resolved);
 
   { // Check for the null sentinel.
-    // If we just called the VM, that already did the mapping for us,
+    // If we just called the VM, it already did the mapping for us,
     // but it's harmless to retry.
     Label notNull;
 
--- a/src/hotspot/cpu/sparc/interp_masm_sparc.cpp	Fri May 04 10:45:47 2018 -0400
+++ b/src/hotspot/cpu/sparc/interp_masm_sparc.cpp	Fri May 04 12:14:09 2018 -0400
@@ -753,6 +753,8 @@
   // Add in the index
   add(result, index, result);
   load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result, tmp);
+  // The resulting oop is null if the reference is not yet resolved.
+  // It is Universe::the_null_sentinel() if the reference resolved to NULL via condy.
 }
 
 
--- a/src/hotspot/cpu/sparc/templateTable_sparc.cpp	Fri May 04 10:45:47 2018 -0400
+++ b/src/hotspot/cpu/sparc/templateTable_sparc.cpp	Fri May 04 12:14:09 2018 -0400
@@ -256,7 +256,7 @@
 
 void TemplateTable::ldc(bool wide) {
   transition(vtos, vtos);
-  Label call_ldc, notInt, isString, notString, notClass, exit;
+  Label call_ldc, notInt, isString, notString, notClass, notFloat, exit;
 
   if (wide) {
     __ get_2_byte_integer_at_bcp(1, G3_scratch, O1, InterpreterMacroAssembler::Unsigned);
@@ -286,7 +286,8 @@
   __ set(wide, O1);
   call_VM(Otos_i, CAST_FROM_FN_PTR(address, InterpreterRuntime::ldc), O1);
   __ push(atos);
-  __ ba_short(exit);
+  __ ba(exit);
+  __ delayed()->nop();
 
   __ bind(notClass);
  // __ add(O0, base_offset, O0);
@@ -296,19 +297,30 @@
   __ delayed()->cmp(O2, JVM_CONSTANT_String);
   __ ld(O0, O1, Otos_i);
   __ push(itos);
-  __ ba_short(exit);
+  __ ba(exit);
+  __ delayed()->nop();
 
   __ bind(notInt);
  // __ cmp(O2, JVM_CONSTANT_String);
   __ brx(Assembler::notEqual, true, Assembler::pt, notString);
-  __ delayed()->ldf(FloatRegisterImpl::S, O0, O1, Ftos_f);
+  __ delayed()->cmp(O2, JVM_CONSTANT_Float);
   __ bind(isString);
   __ stop("string should be rewritten to fast_aldc");
-  __ ba_short(exit);
+  __ ba(exit);
+  __ delayed()->nop();
 
   __ bind(notString);
- // __ ldf(FloatRegisterImpl::S, O0, O1, Ftos_f);
+ //__ cmp(O2, JVM_CONSTANT_Float);
+  __ brx(Assembler::notEqual, true, Assembler::pt, notFloat);
+  __ delayed()->nop();
+  __ ldf(FloatRegisterImpl::S, O0, O1, Ftos_f);
   __ push(ftos);
+  __ ba(exit);
+  __ delayed()->nop();
+
+  // assume the tag is for condy; if not, the VM runtime will tell us
+  __ bind(notFloat);
+  condy_helper(exit);
 
   __ bind(exit);
 }
@@ -336,12 +348,27 @@
   // first time invocation - must resolve first
   __ call_VM(Otos_i, entry, O1);
   __ bind(resolved);
+
+  { // Check for the null sentinel.
+    // If we just called the VM, it already did the mapping for us,
+    // but it's harmless to retry.
+    Label notNull;
+    __ set(ExternalAddress((address)Universe::the_null_sentinel_addr()), G3_scratch);
+    __ ld_ptr(G3_scratch, 0, G3_scratch);
+    __ cmp(G3_scratch, Otos_i);
+    __ br(Assembler::notEqual, true, Assembler::pt, notNull);
+    __ delayed()->nop();
+    __ clr(Otos_i);  // NULL object reference
+    __ bind(notNull);
+  }
+
+  // Safe to call with 0 result
   __ verify_oop(Otos_i);
 }
 
 void TemplateTable::ldc2_w() {
   transition(vtos, vtos);
-  Label Long, exit;
+  Label notDouble, notLong, exit;
 
   __ get_2_byte_integer_at_bcp(1, G3_scratch, O1, InterpreterMacroAssembler::Unsigned);
   __ get_cpool_and_tags(O0, O2);
@@ -355,7 +382,7 @@
   __ sll(O1, LogBytesPerWord, O1);
   __ add(O0, O1, G3_scratch);
 
-  __ cmp_and_brx_short(O2, JVM_CONSTANT_Double, Assembler::notEqual, Assembler::pt, Long);
+  __ cmp_and_brx_short(O2, JVM_CONSTANT_Double, Assembler::notEqual, Assembler::pt, notDouble);
   // A double can be placed at word-aligned locations in the constant pool.
   // Check out Conversions.java for an example.
   // Also ConstantPool::header_size() is 20, which makes it very difficult
@@ -364,9 +391,127 @@
   __ push(dtos);
   __ ba_short(exit);
 
-  __ bind(Long);
+  __ bind(notDouble);
+  __ cmp_and_brx_short(O2, JVM_CONSTANT_Long, Assembler::notEqual, Assembler::pt, notLong);
   __ ldx(G3_scratch, base_offset, Otos_l);
   __ push(ltos);
+  __ ba_short(exit);
+
+  __ bind(notLong);
+  condy_helper(exit);
+
+  __ bind(exit);
+}
+
+void TemplateTable::condy_helper(Label& exit) {
+  Register Robj = Otos_i;
+  Register Roffset = G4_scratch;
+  Register Rflags = G1_scratch;
+
+  address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);
+
+  __ set((int)bytecode(), O1);
+  __ call_VM(Robj, entry, O1);
+
+  // Get vm_result_2 has flags = (tos, off) using format CPCE::_flags
+  __ get_vm_result_2(G3_scratch);
+
+  // Get offset
+  __ set((int)ConstantPoolCacheEntry::field_index_mask, Roffset);
+  __ and3(G3_scratch, Roffset, Roffset);
+
+  // compute type
+  __ srl(G3_scratch, ConstantPoolCacheEntry::tos_state_shift, Rflags);
+  // Make sure we don't need to mask Rflags after the above shift
+  ConstantPoolCacheEntry::verify_tos_state_shift();
+
+  switch (bytecode()) {
+  case Bytecodes::_ldc:
+  case Bytecodes::_ldc_w:
+    {
+      // tos in (itos, ftos, stos, btos, ctos, ztos)
+      Label notInt, notFloat, notShort, notByte, notChar, notBool;
+      __ cmp(Rflags, itos);
+      __ br(Assembler::notEqual, false, Assembler::pt, notInt);
+      __ delayed()->cmp(Rflags, ftos);
+      // itos
+      __ ld(Robj, Roffset, Otos_i);
+      __ push(itos);
+      __ ba_short(exit);
+
+      __ bind(notInt);
+      __ br(Assembler::notEqual, false, Assembler::pt, notFloat);
+      __ delayed()->cmp(Rflags, stos);
+      // ftos
+      __ ldf(FloatRegisterImpl::S, Robj, Roffset, Ftos_f);
+      __ push(ftos);
+      __ ba_short(exit);
+
+      __ bind(notFloat);
+      __ br(Assembler::notEqual, false, Assembler::pt, notShort);
+      __ delayed()->cmp(Rflags, btos);
+      // stos
+      __ ldsh(Robj, Roffset, Otos_i);
+      __ push(itos);
+      __ ba_short(exit);
+
+      __ bind(notShort);
+      __ br(Assembler::notEqual, false, Assembler::pt, notByte);
+      __ delayed()->cmp(Rflags, ctos);
+      // btos
+      __ ldsb(Robj, Roffset, Otos_i);
+      __ push(itos);
+      __ ba_short(exit);
+
+      __ bind(notByte);
+      __ br(Assembler::notEqual, false, Assembler::pt, notChar);
+      __ delayed()->cmp(Rflags, ztos);
+      // ctos
+      __ lduh(Robj, Roffset, Otos_i);
+      __ push(itos);
+      __ ba_short(exit);
+
+      __ bind(notChar);
+      __ br(Assembler::notEqual, false, Assembler::pt, notBool);
+      __ delayed()->nop();
+      // ztos
+      __ ldsb(Robj, Roffset, Otos_i);
+      __ push(itos);
+      __ ba_short(exit);
+
+      __ bind(notBool);
+      break;
+    }
+
+  case Bytecodes::_ldc2_w:
+    {
+      Label notLong, notDouble;
+      __ cmp(Rflags, ltos);
+      __ br(Assembler::notEqual, false, Assembler::pt, notLong);
+      __ delayed()->cmp(Rflags, dtos);
+      // ltos
+      // load must be atomic
+      __ ld_long(Robj, Roffset, Otos_l);
+      __ push(ltos);
+      __ ba_short(exit);
+
+      __ bind(notLong);
+      __ br(Assembler::notEqual, false, Assembler::pt, notDouble);
+      __ delayed()->nop();
+      // dtos
+      __ ldf(FloatRegisterImpl::D, Robj, Roffset, Ftos_d);
+      __ push(dtos);
+      __ ba_short(exit);
+
+      __ bind(notDouble);
+      break;
+    }
+
+  default:
+    ShouldNotReachHere();
+  }
+
+  __ stop("bad ldc/condy");
 
   __ bind(exit);
 }
--- a/src/hotspot/cpu/x86/templateTable_x86.cpp	Fri May 04 10:45:47 2018 -0400
+++ b/src/hotspot/cpu/x86/templateTable_x86.cpp	Fri May 04 12:14:09 2018 -0400
@@ -442,7 +442,7 @@
   __ bind(resolved);
 
   { // Check for the null sentinel.
-    // If we just called the VM, that already did the mapping for us,
+    // If we just called the VM, it already did the mapping for us,
     // but it's harmless to retry.
     Label notNull;
     ExternalAddress null_sentinel((address)Universe::the_null_sentinel_addr());
--- a/test/hotspot/jtreg/runtime/appcds/condy/CondyHelloTest.java	Fri May 04 10:45:47 2018 -0400
+++ b/test/hotspot/jtreg/runtime/appcds/condy/CondyHelloTest.java	Fri May 04 12:14:09 2018 -0400
@@ -24,7 +24,7 @@
 /*
  * @test
  * @summary Make sure CDS works with a minimal test case that uses a CONSTANT_Dynamic constant-pool entry
- * @requires (os.arch != "sparcv9") & (vm.cds)
+ * @requires (vm.cds)
  * @modules java.base/jdk.internal.misc
  * @library /test/lib /test/hotspot/jtreg/runtime/appcds
  * @build CondyHello
--- a/test/hotspot/jtreg/runtime/condy/BadBSMUseTest.java	Fri May 04 10:45:47 2018 -0400
+++ b/test/hotspot/jtreg/runtime/condy/BadBSMUseTest.java	Fri May 04 12:14:09 2018 -0400
@@ -25,7 +25,6 @@
  * @test
  * @bug 8186211
  * @summary CONSTANT_Dynamic_info structure's tries to use a BSM index whose signature is for an invokedynamic and vice versa.
- * @requires os.arch != "sparcv9"
  * @modules java.base/jdk.internal.misc
  * @library /test/lib
  * @compile CondyUsesIndyBSM.jcod
--- a/test/hotspot/jtreg/runtime/condy/CondyBadBSMArrayTest.java	Fri May 04 10:45:47 2018 -0400
+++ b/test/hotspot/jtreg/runtime/condy/CondyBadBSMArrayTest.java	Fri May 04 12:14:09 2018 -0400
@@ -25,7 +25,6 @@
  * @test
  * @bug 8186211
  * @summary CONSTANT_Dynamic_info structure present with various bad BSM index, BSM array attribute checks.
- * @requires os.arch != "sparcv9"
  * @compile CondyBadBSMIndex.jcod
  * @compile CondyEmptyBSMArray1.jcod
  * @compile CondyNoBSMArray.jcod
--- a/test/hotspot/jtreg/runtime/condy/CondyBadNameTypeTest.java	Fri May 04 10:45:47 2018 -0400
+++ b/test/hotspot/jtreg/runtime/condy/CondyBadNameTypeTest.java	Fri May 04 12:14:09 2018 -0400
@@ -25,7 +25,6 @@
  * @test
  * @bug 8186211
  * @summary CONSTANT_Dynamic_info structure's name_and_type_index item does not point at CONSANT_NameAndType_info
- * @requires os.arch != "sparcv9"
  * @compile CondyBadNameType.jcod
  * @run main/othervm -Xverify:all CondyBadNameTypeTest
  */
--- a/test/hotspot/jtreg/runtime/condy/CondyCFVCheckTest.java	Fri May 04 10:45:47 2018 -0400
+++ b/test/hotspot/jtreg/runtime/condy/CondyCFVCheckTest.java	Fri May 04 12:14:09 2018 -0400
@@ -25,7 +25,6 @@
  * @test
  * @bug 8186211
  * @summary CONSTANT_Dynamic_info structure present within an unsupported class file version.
- * @requires os.arch != "sparcv9"
  * @compile CondyCFVCheck.jcod
  * @run main/othervm -Xverify:all CondyCFVCheckTest
  */
--- a/test/hotspot/jtreg/runtime/condy/CondyLDCTest.java	Fri May 04 10:45:47 2018 -0400
+++ b/test/hotspot/jtreg/runtime/condy/CondyLDCTest.java	Fri May 04 12:14:09 2018 -0400
@@ -25,7 +25,6 @@
  * @test
  * @bug 8186211
  * @summary Tests various ldc, ldc_w, ldc2_w instructions of CONSTANT_Dynamic.
- * @requires os.arch != "sparcv9"
  * @modules java.base/jdk.internal.misc
  * @library /test/lib
  * @compile CondyUseLDC_W.jasm
--- a/test/hotspot/jtreg/runtime/condy/CondyNewInvokeSpecialTest.java	Fri May 04 10:45:47 2018 -0400
+++ b/test/hotspot/jtreg/runtime/condy/CondyNewInvokeSpecialTest.java	Fri May 04 12:14:09 2018 -0400
@@ -25,7 +25,6 @@
  * @test
  * @bug 8186211
  * @summary Test CONSTANT_Dynamic where the BSM is invoked via a REF_newInvokeSpecial.
- * @requires os.arch != "sparcv9"
  * @modules java.base/jdk.internal.misc
  * @library /test/lib
  * @compile CondyNewInvokeSpecial.jasm
--- a/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java	Fri May 04 10:45:47 2018 -0400
+++ b/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java	Fri May 04 12:14:09 2018 -0400
@@ -25,7 +25,6 @@
  * @test
  * @bug 8186211
  * @summary Test basic invocation of multiple ldc's of the same dynamic constant that fail resolution
- * @requires os.arch != "sparcv9"
  * @library /lib/testlibrary/bytecode /java/lang/invoke/common
  * @build jdk.experimental.bytecode.BasicClassBuilder
  * @run testng CondyRepeatFailedResolution
--- a/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java	Fri May 04 10:45:47 2018 -0400
+++ b/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java	Fri May 04 12:14:09 2018 -0400
@@ -25,7 +25,6 @@
  * @test
  * @bug 8186046
  * @summary Test for condy BSMs returning primitive values or null
- * @requires os.arch != "sparcv9"
  * @library /lib/testlibrary/bytecode
  * @build jdk.experimental.bytecode.BasicClassBuilder
  * @run testng CondyReturnPrimitiveTest
--- a/test/jdk/java/lang/invoke/condy/CondyWrongType.java	Fri May 04 10:45:47 2018 -0400
+++ b/test/jdk/java/lang/invoke/condy/CondyWrongType.java	Fri May 04 12:14:09 2018 -0400
@@ -25,7 +25,6 @@
  * @test
  * @bug 8186046
  * @summary Test bootstrap methods returning the wrong type
- * @requires os.arch != "sparcv9"
  * @library /lib/testlibrary/bytecode /java/lang/invoke/common
  * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper
  * @run testng CondyWrongType
--- a/test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java	Fri May 04 10:45:47 2018 -0400
+++ b/test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java	Fri May 04 12:14:09 2018 -0400
@@ -25,7 +25,6 @@
  * @test
  * @bug 8186046 8195694
  * @summary Test dynamic constant bootstraps
- * @requires os.arch != "sparcv9"
  * @library /lib/testlibrary/bytecode /java/lang/invoke/common
  * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper
  * @run testng ConstantBootstrapsTest