1 /*
   2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_RUNTIME_SIGNATURE_CC_HPP
  26 #define SHARE_RUNTIME_SIGNATURE_CC_HPP
  27 
  28 // Handling of scalarized Calling Convention
  29 #include "runtime/signature.hpp"
  30 
  31 class ScalarizedValueArgsStream : public StackObj {
  32   const GrowableArray<SigEntry>* _sig_cc;
  33   int _sig_cc_index;
  34   const VMRegPair* _regs_cc;
  35   int _regs_cc_count;
  36   int _regs_cc_index;
  37   int _vt;
  38   DEBUG_ONLY(bool _finished);
  39 public:
  40   ScalarizedValueArgsStream(const GrowableArray<SigEntry>* sig_cc, int sig_cc_index, VMRegPair* regs_cc, int regs_cc_count, int regs_cc_index) :
  41     _sig_cc(sig_cc), _sig_cc_index(sig_cc_index), _regs_cc(regs_cc), _regs_cc_count(regs_cc_count), _regs_cc_index(regs_cc_index) {
  42     assert(_sig_cc->at(_sig_cc_index)._bt == T_VALUETYPE, "should be at end delimiter");
  43     _vt = 1;
  44     DEBUG_ONLY(_finished = false);
  45   }
  46 
  47   bool next(VMRegPair& pair, BasicType& bt) {
  48     assert(!_finished, "sanity");
  49     do {
  50       _sig_cc_index++;
  51       bt = _sig_cc->at(_sig_cc_index)._bt;
  52       if (bt == T_VALUETYPE) {
  53         _vt++;
  54       } else if (bt == T_VOID &&
  55                  _sig_cc->at(_sig_cc_index-1)._bt != T_LONG &&
  56                  _sig_cc->at(_sig_cc_index-1)._bt != T_DOUBLE) {
  57         _vt--;
  58       } else if (SigEntry::is_reserved_entry(_sig_cc, _sig_cc_index)) {
  59         _regs_cc_index++;
  60       } else {
  61         assert(_regs_cc_index < _regs_cc_count, "must be");
  62         pair = _regs_cc[_regs_cc_index++];
  63         VMReg r1 = pair.first();
  64         VMReg r2 = pair.second();
  65 
  66         if (!r1->is_valid()) {
  67           assert(!r2->is_valid(), "must be invalid");
  68         } else {
  69           return true;
  70         }
  71       }
  72     } while (_vt != 0);
  73 
  74     DEBUG_ONLY(_finished = true);
  75     return false;
  76   }
  77 
  78   int sig_cc_index() {return _sig_cc_index;}
  79   int regs_cc_index() {return _regs_cc_index;}
  80 };
  81 
  82 #endif // SHARE_RUNTIME_SIGNATURE_CC_HPP