Что такое стек операнда?
Я читаю о архитектуре JVM. Сегодня я читал о концепции Операнда. Согласно статье:
Стек операнда используется во время выполнения команд байтового кода аналогично тому, что регистры общего назначения используются в основном процессоре.
Я не могу понять: что такое стеки Операнда и как он работает в jvm?
Ответы
Ответ 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, часы и т.д.), Не может быть различимых различий.