Подтвердить что ты не робот

Что такое стек операнда?

Я читаю о архитектуре JVM. Сегодня я читал о концепции Операнда. Согласно статье:

Стек операнда используется во время выполнения команд байтового кода аналогично тому, что регистры общего назначения используются в основном процессоре.

Я не могу понять: что такое стеки Операнда и как он работает в jvm?

4b9b3361

Ответ 1

Это то, как различные индивидуальные операции байт-кода получают свой вклад и как они обеспечивают их вывод.

Например, рассмотрим операцию iadd, которая добавляет два int вместе. Чтобы использовать его, вы нажимаете два значения в стеке и затем используете его:

iload_0     # Push the value from local variable 0 onto the stack
iload_1     # Push the value from local variable 1 onto the stack
iadd        # Pops those off the stack, adds them, and pushes the result

Теперь верхнее значение в стеке является суммой этих двух локальных переменных. Следующая операция может занять это верхнее значение стека и сохранить его где-нибудь, или мы можем нажать другое значение в стеке, чтобы сделать что-то еще.

Предположим, вы хотите добавить три значения вместе. Стек делает это легко:

iload_0     # Push the value from local variable 0 onto the stack
iload_1     # Push the value from local variable 1 onto the stack
iadd        # Pops those off the stack, adds them, and pushes the result
iload_2     # Push the value from local variable 2 onto the stack
iadd        # Pops those off the stack, adds them, and pushes the result

Теперь верхнее значение в стеке является результатом объединения этих трех локальных переменных.

Посмотрите на этот второй пример более подробно:

Предположим:

  • Стек пуста для начала (что почти никогда не является истинным, но нам все равно, что на нем, прежде чем мы начнем)
  • Локальная переменная 0 содержит 27
  • Локальная переменная 1 содержит 10
  • Локальная переменная 2 содержит 5

Итак, изначально:

+-------+
| stack |
+-------+
+-------+

Тогда выполняем

iload_0     # Push the value from local variable 0 onto the stack

Теперь мы имеем

+-------+
| stack |
+-------+
|   27  |
+-------+

Далее

iload_1     # Push the value from local variable 1 onto the stack
+-------+
| stack |
+-------+
|   10  |
|   27  |
+-------+

Теперь добавим:

iadd        # Pops those off the stack, adds them, and pushes the result

Он "выталкивает" 10 и 27 со стека, складывает их и выталкивает результат (37). Теперь мы имеем:

+-------+
| stack |
+-------+
|   37  |
+-------+

Время для нашего третьего int:

iload_2     # Push the value from local variable 2 onto the stack
+-------+
| stack |
+-------+
|    5  |
|   37  |
+-------+

Мы делаем второй iadd:

iadd        # Pops those off the stack, adds them, and pushes the result

Это дает нам:

+-------+
| stack |
+-------+
|   42  |
+-------+

(Это, конечно, Ответ на конечный вопрос о жизни Вселенной и обо всем.)

Ответ 2

Операндовый стек содержит операнд, используемый операторами для выполнения операций. Каждая запись в стеке операнда может содержать значение любого типа виртуальной машины Java.

Из спецификаций JVM,

Инструкции Java Virtual Machine берут операнды из операнда стек, работать с ними и возвращать результат обратно в операнд стек. Стек операнда также используется для подготовки параметров, которые должны быть передаются методам и получают результаты метода.

Например, команда iadd добавит два целочисленных значения, поэтому он вытащит два верхних целочисленных значения из стека операндов и вытолкнет результат в стек операнда после добавления их.

Для получения более подробной информации вы можете проверить JVMS # 2.5: области данных времени выполнения

Обобщая его в контексте стека операндов,

    _______________________________
   |        _____________________  |
   |       |         + --------+ | |
   |  JVM  |         | Operand | | | 
   | Stack |  FRAME  |  Stack  | | |
   |       |         +---------+ | |
   |       |_____________________| |
   |_______________________________|
  • JVM поддерживает многопоточную среду исполнения. Каждый поток исполнение имеет свой собственный стек виртуальной машины Java (JVM Stack), созданный одновременно с созданием потоков.
  • Этот стек виртуальной машины Java хранит фреймы. Кадр содержит данные, частичные результаты, возвращаемые значения метода и выполняет динамическую компоновку.
  • Каждый кадр содержит стек, называемый стеком операнда, который содержит значения операндов типов JVM. Глубина стека операндов определяется во время компиляции и обновляется операторами.

Ответ 3

Но не мог точно понять, что это такое и как он работает в jvm?

JVM определяет виртуальный компьютер, а набор команд этого компьютера основан на стеке. Это означает, что инструкции в наборе команд JVM обычно будут вытолкнуть и поместить операнды из стека. Так, например,

  • команда load может извлекать значение из локальной переменной, переменной экземпляра или переменной класса и вставлять ее в стек операнда,
  • арифметическая команда выдает значения из стека операндов, выполняет вычисление и возвращает результат обратно в стек, а
  • инструкция магазина выдает значение из стека и сохраняет его...

@Ответ T.J.Crowder дает более конкретный пример в деталях.

Как реализован стек операнда, зависит от платформы, и зависит от того, интерпретируется ли код или компилируется ли JIT.

  • В интерпретируемом случае стек операнда, вероятно, представляет собой массив, который управляется кодом интерпретатора. Микропроцессы push и pop будут реализованы примерно так:

        stack[top++] = value;
    

    и

        value = stack[--top];
    
  • Когда код JIT скомпилирован, последовательности инструкций байт-кода преобразуются в нативные последовательности команд, которые достигают того же, что и байт-коды. Расположение стека операндов сопоставляется либо с коренными регистрами, либо с ячейками памяти; например в текущем исходном фрейме стека. Отображение включает в себя различные оптимизации, которые направлены на использование регистров (быстрый) в предпочтении памяти (медленнее).

    Таким образом, в JIT-компилированном случае стек операнда больше не имеет ясного физического существования, но общее поведение скомпилированной программы такое же, как если бы стек операнда существовал 1.


1 - На самом деле, при использовании модели памяти Java это может быть совсем не то же самое. Тем не менее, модель памяти оставляет четкую границу в отношении различий. И в случае однопоточного вычисления, которое не взаимодействует с внешним (например, I/O, часы и т.д.), Не может быть различимых различий.