Minimum Stack Usage

Общий размер локальных переменных в функции с учетом вложенных областей плюс максимальное использование стека от callees

Описание

Эта метрика указывается только в анализе Code Prover.

Эта метрика обеспечивает оптимистическую оценку использования стека функцией. В отличие от метрического Maximum Stack Usage, эта метрика учитывает вложенные возможности. Например, если переменные определены в двух взаимоисключающих ветвях условного оператора, метрика считает, что пространство стека, выделенное переменным в одной ветви, может быть повторно использовано в другой ветви.

Метрика является суммой этих размеров в байтах:

  • Lower Estimate of Local Variable Size.

  • Максимальное значение из использования стека функций callees. В расчете используется минимальное использование стека каждой тележки.

    Например, в этом примере минимальное использование стека func совпадает с минимальным использованием стека func1 или func2, в зависимости от того, что больше.

    void func(void) {
        func1();
        func2();
    }

    Если вызовы функций находятся в разных ветвях условного оператора, эта метрика рассматривает ветвь с наименьшим использованием стека.

    Анализ делает оценку размера стека позже, когда он разрешил, какие вызовы функции на самом деле происходят. Например, если вызов функции происходит в недоступном коде, размер стека не учитывает вызов. Анализ также может учитывать вызовы через указатели на функцию.

Фактическое использование стека может отличаться от метрического значения.

  • Некоторые переменные хранятся в регистрах вместо в стеке.

  • Ваш компилятор выполняет переменный анализ жизни, чтобы включить определенную оптимизацию памяти. При оценке этой метрики Polyspace® не рассматривает эти оптимизации.

  • Ваш компилятор использует дополнительную память во время вызова функции. Например, компиляторы хранят адрес, на который возвращается выполнение после вызова функции. При оценке этой метрики Polyspace не рассматривает это скрытое использование памяти.

Однако метрика предоставляет разумную оценку использования стека.

Чтобы определить размеры основных типов, программное обеспечение использует ваши спецификации для Target processor type (-target). Метрика учитывает #pragma pack директивы в вашем коде.

Примеры

расширить все

double func2(int);


double func(int status) {
    double res = func2(status);
    return res;
}


double func2(int status) {
    double res;
    if(status == 0) {
      int temp;    
      res = 0.0;
    }
   else {
      double temp;
      res = 1.0;
    }
   return res;
}

В этом примере, принимая четыре байта для int и восемь байтов для doubleминимальное использование стека:

  • func2: 28 байт

    Это значение включает размеры его параметра (4 байта), локальную переменную res (8 байт), одна из двух локальных переменных temp (8 байт) и возвращаемое значение (8 байт).

    Метрика принимает во внимание, что первый temp больше не живет, когда второй temp задан. Он использует переменную temp с типом данных double потому что его размер больше.

  • func: 48 байт

    Это значение включает в себя размеры его параметра, локальной переменной resи возвращаемое значение, в общей сложности 20 байт. Это значение включает 28 байтов минимального использования стека по его вызову, func2.

void func1(int);
void func2(void);



void func(int status) {
    func1(status);
    func2();
}


void func1(int status) {
    if(status == 0) {
      int val;
    }
    else {
      double val2;
    }
}


void func2(void) {
    double val;
}

В этом примере, принимая четыре байта для int и восемь байтов для doubleминимальное использование стека:

  • func1: 12 байт

    Это значение включает размеры его параметра (4 байта) и больше из двух локальных переменных, в этом случае val2 (8 байт).

  • func2: 8 байт

  • func: 16 байт

    Это значение включает размеры его параметра (4 байта) и максимум использования стека func1 и func2 (12 байт).

void func1(void);
void func2(void);



void func(int status) {
    if(status==0)
        func1();
    else
        func2();
}


void func1(void) {
    double val;
}


void func2(void) {
    int val;
}

В этом примере, принимая четыре байта для int и восемь байтов для doubleминимальное использование стека:

  • func1: 8 байт

  • func2: 4 байта

  • func: 8 байт

    Это значение включает размеры его параметра (4 байта) и минимальное использование стека из двух ветвей (4 байта).

#include <stdarg.h>


void fun_vararg(int x, ...) {
  va_list ap;
  va_start(ap, x);
  int i;
  for (i=0; i<x; i++) {
    int j = va_arg(ap, int);
  }
  va_end(ap);
}



void call_fun_vararg1(void) {
  long long int l = 0;
  fun_vararg(3, 4, 5, 6, l);
}



void call_fun_vararg2(void) {
  fun_vararg(1,0);
}

В этой функции fun_vararg является функцией с переменным количеством параметров. Минимальное использование стека fun_vararg принимает во внимание вызов на fun_vararg с минимальным количеством аргументов. Вызов с минимальным количеством аргументов является вызовом в call_fun_vararg2 с двумя аргументами (один для фиксированного параметра и один для переменного параметра). Минимальное использование стека:

  • fun_vararg: 20 байт.

    Это значение учитывает:

    • Размер фиксированного параметра x (4 байта).

    • Размеры параметров переменной от вызова с минимальным количеством параметров. В этом вызове существует только один аргумент переменной типа int (4 байта).

    • Размеры локальных переменных i, j и ap (12 байт). Размер va_list переменная использует размер указателя, заданный в цели (в данном случае, 4 байта).

  • call_fun_vararg1: 44 байта.

    Это значение учитывает:

    • Использование размера стека fun_vararg с пятью аргументами (36 байт, из которых 12 байт для локальных размеров переменной и 20 байт для фиксированных и переменных параметров fun_vararg).

    • Размер локальной переменной l (8 байт).

  • call_fun_vararg2: 20 байт.

    Начиная с call_fun_vararg2 не имеет локальных переменных, это значение совпадает с использованием стека fun_vararg с двумя аргументами (20 байт).

Метрическая информация

Группа: Функция
Акроним: MIN_STACK
ЕГО Метрика: Нет
Введенный в R2017b