< prev index next >

src/hotspot/share/opto/output.cpp

Print this page

        

@@ -69,28 +69,38 @@
   Block *broot = _cfg->get_root_block();
 
   const StartNode *start = entry->head()->as_Start();
 
   // Replace StartNode with prolog
-  MachPrologNode *prolog = new MachPrologNode();
+  Label verified_entry;
+  MachPrologNode* prolog = new MachPrologNode(&verified_entry);
   entry->map_node(prolog, 0);
   _cfg->map_node_to_block(prolog, entry);
   _cfg->unmap_node_from_block(start); // start is no longer in any block
 
   // Virtual methods need an unverified entry point
-
-  if( is_osr_compilation() ) {
-    if( PoisonOSREntry ) {
+  if (is_osr_compilation()) {
+    if (PoisonOSREntry) {
       // TODO: Should use a ShouldNotReachHereNode...
       _cfg->insert( broot, 0, new MachBreakpointNode() );
     }
   } else {
-    if( _method && !_method->flags().is_static() ) {
-      // Insert unvalidated entry point
-      _cfg->insert( broot, 0, new MachUEPNode() );
+    if (_method) {
+      if (_method->has_scalarized_args()) {
+        // Add entry point to unpack all value type arguments
+        _cfg->insert(broot, 0, new MachVEPNode(&verified_entry, /* verified */ true, /* receiver_only */ false));
+        if (!_method->is_static()) {
+          // Add verified/unverified entry points to only unpack value type receiver at interface calls
+          _cfg->insert(broot, 0, new MachVEPNode(&verified_entry, /* verified */ false, /* receiver_only */ false));
+          _cfg->insert(broot, 0, new MachVEPNode(&verified_entry, /* verified */ true,  /* receiver_only */ true));
+          _cfg->insert(broot, 0, new MachVEPNode(&verified_entry, /* verified */ false, /* receiver_only */ true));
+        }
+      } else if (!_method->is_static()) {
+        // Insert unvalidated entry point
+        _cfg->insert(broot, 0, new MachUEPNode());
+      }
     }
-
   }
 
   // Break before main entry point
   if ((_method && C->directive()->BreakAtExecuteOption) ||
       (OptoBreakpoint && is_method_compilation())       ||

@@ -122,10 +132,35 @@
 
   if (cb == NULL || failing()) {
     return;
   }
 
+  if (!is_osr_compilation() && _method && _method->has_scalarized_args()) {
+    // Compute the offsets of the entry points required by the value type calling convention
+    if (!_method->is_static()) {
+      // We have entries at the beginning of the method, implemented by the first 4 nodes.
+      // Entry                     (unverified) @ offset 0
+      // Verified_Value_Entry_RO
+      // Value_Entry               (unverified)
+      // Verified_Value_Entry
+      uint offset = 0;
+      _code_offsets.set_value(CodeOffsets::Entry, offset);
+
+      offset += ((MachVEPNode*)broot->get_node(0))->size(_regalloc);
+      _code_offsets.set_value(CodeOffsets::Verified_Value_Entry_RO, offset);
+
+      offset += ((MachVEPNode*)broot->get_node(1))->size(_regalloc);
+      _code_offsets.set_value(CodeOffsets::Value_Entry, offset);
+
+      offset += ((MachVEPNode*)broot->get_node(2))->size(_regalloc);
+      _code_offsets.set_value(CodeOffsets::Verified_Value_Entry, offset);
+    } else {
+      _code_offsets.set_value(CodeOffsets::Entry, -1); // will be patched later
+      _code_offsets.set_value(CodeOffsets::Verified_Value_Entry, 0);
+    }
+  }
+
   ScheduleAndBundle();
 
 #ifndef PRODUCT
   if (trace_opto_output()) {
     tty->print("\n---- After ScheduleAndBundle ----\n");

@@ -286,11 +321,13 @@
           reloc_size += CallStubImpl::reloc_call_trampoline();
 
           MachCallNode *mcall = mach->as_MachCall();
           // This destination address is NOT PC-relative
 
-          mcall->method_set((intptr_t)mcall->entry_point());
+          if (mcall->entry_point() != NULL) {
+            mcall->method_set((intptr_t)mcall->entry_point());
+          }
 
           if (mcall->is_MachCallJava() && mcall->as_MachCallJava()->_method) {
             stub_size  += CompiledStaticCall::to_interp_stub_size();
             reloc_size += CompiledStaticCall::reloc_to_interp_stub();
 #if INCLUDE_AOT

@@ -724,10 +761,11 @@
   MachCallNode      *mcall;
 
   int safepoint_pc_offset = current_offset;
   bool is_method_handle_invoke = false;
   bool return_oop = false;
+  bool return_vt = false;
 
   // Add the safepoint in the DebugInfoRecorder
   if( !mach->is_MachCall() ) {
     mcall = NULL;
     debug_info()->add_safepoint(safepoint_pc_offset, sfn->_oop_map);

@@ -741,13 +779,16 @@
         is_method_handle_invoke = true;
       }
     }
 
     // Check if a call returns an object.
-    if (mcall->returns_pointer()) {
+    if (mcall->returns_pointer() || mcall->returns_vt()) {
       return_oop = true;
     }
+    if (mcall->returns_vt()) {
+      return_vt = true;
+    }
     safepoint_pc_offset += mcall->ret_addr_offset();
     debug_info()->add_safepoint(safepoint_pc_offset, mcall->_oop_map);
   }
 
   // Loop over the JVMState list to add scope information

@@ -858,11 +899,11 @@
     assert(jvms->bci() >= InvocationEntryBci && jvms->bci() <= 0x10000, "must be a valid or entry BCI");
     assert(!jvms->should_reexecute() || depth == max_depth, "reexecute allowed only for the youngest");
     // Now we can describe the scope.
     methodHandle null_mh;
     bool rethrow_exception = false;
-    debug_info()->describe_scope(safepoint_pc_offset, null_mh, scope_method, jvms->bci(), jvms->should_reexecute(), rethrow_exception, is_method_handle_invoke, return_oop, locvals, expvals, monvals);
+    debug_info()->describe_scope(safepoint_pc_offset, null_mh, scope_method, jvms->bci(), jvms->should_reexecute(), rethrow_exception, is_method_handle_invoke, return_oop, return_vt, locvals, expvals, monvals);
   } // End jvms loop
 
   // Mark the end of the scope set.
   debug_info()->end_safepoint(safepoint_pc_offset);
 }

@@ -967,10 +1008,14 @@
 
   // Compute the byte offset where we can store the deopt pc.
   if (fixed_slots() != 0) {
     _orig_pc_slot_offset_in_bytes = _regalloc->reg2offset(OptoReg::stack2reg(_orig_pc_slot));
   }
+  if (C->needs_stack_repair()) {
+    // Compute the byte offset of the stack increment value
+    _sp_inc_slot_offset_in_bytes = _regalloc->reg2offset(OptoReg::stack2reg(_sp_inc_slot));
+  }
 
   // Compute prolog code size
   _method_size = 0;
   _frame_slots = OptoReg::reg2stack(_matcher->_old_SP)+_regalloc->_framesize;
 #if defined(IA64) && !defined(AIX)

@@ -1236,12 +1281,14 @@
 
         // Remember the start of the last call in a basic block
         if (is_mcall) {
           MachCallNode *mcall = mach->as_MachCall();
 
-          // This destination address is NOT PC-relative
-          mcall->method_set((intptr_t)mcall->entry_point());
+          if (mcall->entry_point() != NULL) {
+            // This destination address is NOT PC-relative
+            mcall->method_set((intptr_t)mcall->entry_point());
+          }
 
           // Save the return address
           call_returns[block->_pre_order] = current_offset + mcall->ret_addr_offset();
 
           if (mcall->is_MachCallLeaf()) {
< prev index next >