changeset 49061:9a3653ec77d7 lworld

Interpreter fixes for bytecode rewriting and withfield bugs
author fparain
date Tue, 13 Mar 2018 16:19:18 +0100
parents 59f715d4cca6
children b2ef243da446
files src/hotspot/cpu/x86/templateTable_x86.cpp src/hotspot/share/interpreter/interpreterRuntime.cpp
diffstat 2 files changed, 17 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/cpu/x86/templateTable_x86.cpp	Tue Mar 13 15:36:21 2018 +0530
+++ b/src/hotspot/cpu/x86/templateTable_x86.cpp	Tue Mar 13 16:19:18 2018 +0100
@@ -3065,21 +3065,21 @@
     Label nonnull, notFlattenable;
     pop_and_check_object(obj);
     __ load_heap_oop(rax, field);
-    __ testptr(rax, rax);
-    __ jcc(Assembler::notZero, nonnull);
     __ movl(rscratch1, flags2);
     __ shrl(rscratch1, ConstantPoolCacheEntry::is_flattenable_field_shift);
     __ andl(rscratch1, 0x1);
     __ testl(rscratch1, rscratch1);
     __ jcc(Assembler::zero, notFlattenable);
+    __ testptr(rax, rax);
+    __ jcc(Assembler::notZero, nonnull);
     __ andl(flags2, ConstantPoolCacheEntry::field_index_mask);
     __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::uninitialized_instance_value_field),
                obj, flags2);
     __ verify_oop(rax);
+    __ bind(nonnull);
     __ push(atos);
     __ jmp(atosDone); // skipping rewriting
     __ bind(notFlattenable);
-    __ bind(nonnull);
     __ push(atos);
   }
 
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp	Tue Mar 13 15:36:21 2018 +0530
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp	Tue Mar 13 16:19:18 2018 +0100
@@ -290,15 +290,20 @@
       vklass->data_for_oop(new_value_h()), in_heap, false);
 
   // Updating the field specified in arguments
-  if (field_type == T_OBJECT || field_type == T_ARRAY) {
+  if (field_type == T_ARRAY) {
     oop aoop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
-    assert(aoop == NULL || (oopDesc::is_oop(aoop) && (!aoop->is_value())),"argument must be a reference type");
+    assert(aoop == NULL || oopDesc::is_oop(aoop),"argument must be a reference type");
     if (in_heap) {
       new_value_h()->obj_field_put(field_offset, aoop);
     } else {
       new_value_h()->obj_field_put_raw(field_offset, aoop);
     }
-  } else if (field_type == T_VALUETYPE) {
+  } else if (field_type == T_OBJECT) {
+    // Logic below is optimized
+    // Null checks for non flattenable fields have already be performed in the assembly template
+    // of the interpreter, which reduces the number of possible cases:
+    // 1 - flattened or not flattened
+    // 2 - if not flattened: argument is buffered (value) or in heap (value and objects)
     if (cp_entry->is_flattened()) {
       Klass* field_k = vklass->get_value_field_klass(field_index);
       ValueKlass* field_vk = ValueKlass::cast(field_k);
@@ -307,9 +312,11 @@
       assert(field_vk == vt_oop->klass(), "Must match");
       field_vk->value_store(field_vk->data_for_oop(vt_oop),
           ((char*)(oopDesc*)new_value_h()) + field_offset, in_heap, false);
-    } else {
+    } else { // not flattened
       oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
-      assert(voop != NULL || (oopDesc::is_oop(voop) && (voop->is_value())),"argument must be a value type");
+      assert(voop != NULL || !cp_entry->is_flattenable(),
+             "NULL checks for non flattenable fields must have been performed in interpreter assembly template");
+      assert(voop == NULL || oopDesc::is_oop(voop),"checking argument");
       if (VTBuffer::is_in_vt_buffer(voop)) {
         // new value field is currently allocated in a TLVB, a heap allocated
         // copy must be created because a field must never point to a TLVB allocated value
@@ -324,7 +331,7 @@
         } else {
           new_value_h()->obj_field_put_raw(field_offset, field_copy_h());
         }
-      } else {
+      } else { // not buffered
         if (in_heap) {
           new_value_h()->obj_field_put(field_offset, voop);
         } else {
@@ -332,7 +339,7 @@
         }
       }
     }
-  } else {
+  } else { // not T_OBJECT nor T_ARRAY
     intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx);
     copy_primitive_argument(addr, new_value_h, field_offset, field_type);
   }