xref: /netbsd-src/external/gpl3/binutils/dist/gprofng/src/ExpGroup.cc (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
1*cb63e24eSchristos /* Copyright (C) 2021-2024 Free Software Foundation, Inc.
24f645668Schristos    Contributed by Oracle.
34f645668Schristos 
44f645668Schristos    This file is part of GNU Binutils.
54f645668Schristos 
64f645668Schristos    This program is free software; you can redistribute it and/or modify
74f645668Schristos    it under the terms of the GNU General Public License as published by
84f645668Schristos    the Free Software Foundation; either version 3, or (at your option)
94f645668Schristos    any later version.
104f645668Schristos 
114f645668Schristos    This program is distributed in the hope that it will be useful,
124f645668Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
134f645668Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
144f645668Schristos    GNU General Public License for more details.
154f645668Schristos 
164f645668Schristos    You should have received a copy of the GNU General Public License
174f645668Schristos    along with this program; if not, write to the Free Software
184f645668Schristos    Foundation, 51 Franklin Street - Fifth Floor, Boston,
194f645668Schristos    MA 02110-1301, USA.  */
204f645668Schristos 
214f645668Schristos #include "config.h"
224f645668Schristos #include "util.h"
234f645668Schristos #include "ExpGroup.h"
244f645668Schristos #include "Experiment.h"
254f645668Schristos #include "LoadObject.h"
264f645668Schristos #include "DbeSession.h"
274f645668Schristos 
284f645668Schristos //////////////////////////////////////////////////////////
294f645668Schristos //  class ExpGroup
304f645668Schristos 
314f645668Schristos int ExpGroup::phaseCompareIdx = 0;
324f645668Schristos 
ExpGroup(char * nm)334f645668Schristos ExpGroup::ExpGroup (char *nm)
344f645668Schristos {
354f645668Schristos   name = dbe_strdup (nm);
364f645668Schristos   canonical_path (name);
374f645668Schristos   exps = new Vector<Experiment*>;
384f645668Schristos   founder = NULL;
394f645668Schristos   groupId = 0;
404f645668Schristos   phaseCompareIdx++;
414f645668Schristos   loadObjs = NULL;
424f645668Schristos   loadObjsMap = NULL;
434f645668Schristos }
444f645668Schristos 
~ExpGroup()454f645668Schristos ExpGroup::~ExpGroup ()
464f645668Schristos {
474f645668Schristos   phaseCompareIdx++;
484f645668Schristos   free (name);
494f645668Schristos   delete exps;
504f645668Schristos   delete loadObjs;
514f645668Schristos   delete loadObjsMap;
524f645668Schristos }
534f645668Schristos 
544f645668Schristos void
append(Experiment * exp)554f645668Schristos ExpGroup::append (Experiment *exp)
564f645668Schristos {
574f645668Schristos   for (int i = 0, sz = exps->size (); i < sz; i++)
584f645668Schristos     {
594f645668Schristos       Experiment *e = exps->fetch (i);
604f645668Schristos       if (exp == e)
614f645668Schristos 	return;
624f645668Schristos     }
634f645668Schristos   exps->append (exp);
644f645668Schristos   if (exps->size () == 1)
654f645668Schristos     founder = exp;
664f645668Schristos }
674f645668Schristos 
684f645668Schristos void
drop_experiment(Experiment * exp)694f645668Schristos ExpGroup::drop_experiment (Experiment *exp)
704f645668Schristos {
714f645668Schristos   for (int i = 0, sz = exps->size (); i < sz; i++)
724f645668Schristos     {
734f645668Schristos       Experiment *e = exps->fetch (i);
744f645668Schristos       if (exp == e)
754f645668Schristos 	{
764f645668Schristos 	  exps->remove (i);
774f645668Schristos 	  break;
784f645668Schristos 	}
794f645668Schristos     }
804f645668Schristos   if (founder == exp)
814f645668Schristos     founder = NULL;
824f645668Schristos }
834f645668Schristos 
844f645668Schristos Vector<Experiment*> *
get_founders()854f645668Schristos ExpGroup::get_founders ()
864f645668Schristos {
874f645668Schristos   Vector<Experiment*> *expList = NULL;
884f645668Schristos   for (int i = 0, sz = exps ? exps->size () : 0; i < sz; i++)
894f645668Schristos     {
904f645668Schristos       Experiment *exp = exps->fetch (i);
914f645668Schristos       if (exp->founder_exp == NULL)
924f645668Schristos 	{
934f645668Schristos 	  if (expList == NULL)
944f645668Schristos 	    expList = new Vector<Experiment*>;
954f645668Schristos 	  expList->append (exp);
964f645668Schristos 	}
974f645668Schristos     }
984f645668Schristos   return expList;
994f645668Schristos }
1004f645668Schristos 
1014f645668Schristos void
create_list_of_loadObjects()1024f645668Schristos ExpGroup::create_list_of_loadObjects ()
1034f645668Schristos {
1044f645668Schristos   if (loadObjs == NULL)
1054f645668Schristos     {
1064f645668Schristos       loadObjs = new Vector<LoadObject*>();
1074f645668Schristos       loadObjsMap = new DefaultMap<LoadObject*, int>();
1084f645668Schristos       for (int i = 0, sz = exps ? exps->size () : 0; i < sz; i++)
1094f645668Schristos 	{
1104f645668Schristos 	  Experiment *exp = exps->fetch (i);
1114f645668Schristos 	  for (int i1 = 0, sz1 = VecSize(exp->loadObjs); i1 < sz1; i1++)
1124f645668Schristos 	    {
1134f645668Schristos 	      LoadObject *lo = exp->loadObjs->fetch (i1);
1144f645668Schristos 	      if (!loadObjsMap->get (lo))
1154f645668Schristos 		{
1164f645668Schristos 		  loadObjs->append (lo);
1174f645668Schristos 		  loadObjsMap->put (lo, loadObjs->size ());
1184f645668Schristos 		}
1194f645668Schristos 	    }
1204f645668Schristos 	}
1214f645668Schristos     }
1224f645668Schristos }
1234f645668Schristos 
1244f645668Schristos LoadObject *
get_comparable_loadObject(LoadObject * lo)1254f645668Schristos ExpGroup::get_comparable_loadObject (LoadObject *lo)
1264f645668Schristos {
1274f645668Schristos   create_list_of_loadObjects ();
1284f645668Schristos   if (loadObjsMap->get (lo))
1294f645668Schristos     return lo;
1304f645668Schristos   if ((lo->flags & SEG_FLAG_EXE) != 0)
1314f645668Schristos     if (dbeSession->expGroups->size () == dbeSession->nexps ())
1324f645668Schristos       for (int i = 0, sz = loadObjs ? loadObjs->size () : 0; i < sz; i++)
1334f645668Schristos 	{
1344f645668Schristos 	  LoadObject *lobj = loadObjs->fetch (i);
1354f645668Schristos 	  if ((lobj->flags & SEG_FLAG_EXE) != 0)
1364f645668Schristos 	    return lobj;
1374f645668Schristos 	}
1384f645668Schristos 
1394f645668Schristos   long first_ind = -1;
1404f645668Schristos   char *bname = get_basename (lo->get_pathname ());
1414f645668Schristos   for (long i = 0, sz = loadObjs ? loadObjs->size () : 0; i < sz; i++)
1424f645668Schristos     {
1434f645668Schristos       LoadObject *lobj = loadObjs->get (i);
1444f645668Schristos       if (lobj->comparable_objs == NULL
1454f645668Schristos 	  && strcmp (bname, get_basename (lobj->get_pathname ())) == 0)
1464f645668Schristos 	{
1474f645668Schristos 	  if (lo->platform == lobj->platform)
1484f645668Schristos 	    {
1494f645668Schristos 	      if ((lo->flags & SEG_FLAG_DYNAMIC) != 0)
1504f645668Schristos 		{
1514f645668Schristos 		  if (dbe_strcmp (lo->firstExp->uarglist,
1524f645668Schristos 				  lobj->firstExp->uarglist) == 0)
1534f645668Schristos 		    return lobj;
1544f645668Schristos 		}
1554f645668Schristos 	      else
1564f645668Schristos 		return lobj;
1574f645668Schristos 	    }
1584f645668Schristos 	  if (first_ind == -1)
1594f645668Schristos 	    first_ind = i;
1604f645668Schristos 	}
1614f645668Schristos     }
1624f645668Schristos   return first_ind == -1 ? NULL : loadObjs->get (first_ind);
1634f645668Schristos }
164