2012-05-12 2 views
7

В java-байт-код Почему приемник сначала вставляется в стек, а затем все параметры? Кажется, я помню, что это было связано с эффективностью.Байт-код Java этого порядка и параметры в стеке

Это верно как для вызовов методов, так и для полей настроек.

Метод вызова

class X { 

    int p(int a) { 
     //Do something 
    } 
    int main() { 
     int ret = p(1); 
    } 

} 

Основной метод компилирует:

aload_0 // Load this onto the stack 
iconst_1 // Load constant 1 onto the stack 
invokevirtual <int p(int)> from class X 

Установка поля:

class X { 
    int x; 
    int main() { 
     x = 1; 
    } 

} 

Основной метод компилирует в:

aload_0 // Load this onto the stack 
iconst_1 // Load constant 1 onto the stack 
putfield <int x> from class X 
+0

Думаю, что я понял это, но я не могу ответить, поскольку у меня недостаточно очков! –

+0

Это одно из вопросов «без дела». Интересно, но ответ не имеет практического применения ... если вы не планируете создание нового набора инструкций байткода. –

+1

ваша точка есть? Изучение того, как работает компьютер, является вопросом «праздного любопытства» для большинства. –

ответ

1

толкания первого имеет преимущество в том

  • целевого метода может использовать более плотные «aload0» байткода (меньше , если бы это было гораздо позже, в списке параметров и пришлось использовать параметрической версии байт-код aload. Поскольку «это» часто упоминается в методах доступа как к полю, так и к методу, это приводит к улучшению реальной плотности кода.
  • Часто бывает, что каскадный метод отправляется как «foo.bar(). baz() Когда bar() возвращается, будущее «это» для .baz() волшебным образом уже в нужном месте на , если вы упорядочиваете вещи, как это было сделано на Java.
+0

Эти ответы правдоподобны, но на самом деле байт-коды скомпилированы в собственный код, и ни одно из этих преимуществ не разыгрывается, как только это произойдет. –

+0

Это неверно для второй точки на большинстве архитектур RISC, таких как POWER, где оба параметра и возвращаемые значения фактически находятся в регистре. Правильно выстроить их правильно (return -> arg 0) работает очень хорошо и улучшает производительность. Кроме того, в первом случае, в то время как 1 байт не так уж и много, JVM часто должен поддерживать байт-коды в памяти (пересмотреть класс и т. Д. Из JVMTI) и скомпилировать все сохраненные 1 байты по тысячам классов добавляет к нетривиальной памяти. –

+0

Вы предполагаете, что макет виртуального стека в модели байт-кода похож на физический стек, используемый компилированным кодом JIT. Можете ли вы обосновать это предположение? Использование Re-памяти, сохранение десятков или сотен тысяч байтов байт-кода >> является тривиальным ... на машинах с гигабайтами физической памяти. Кроме того, как только байт-коды составлены JIT, они могут быть собраны в мусор. (Я не уверен, что они ...) И оптимизация для дела JVMTI кажется вроде бессмысленной. –

1

Вы спрашиваете, почему это толкает вообще? В обоих случаях вы получаете доступ к тому, что принадлежит экземпляру класса, поэтому this должен быть частью этого процесса.

Вы спрашиваете, почему это толкается первым? Просто соглашение Java. Я думаю, что всегда удобно иметь this, независимо от того, что может последовать.

+0

Просить последнего. Примеры ясно показывают, что я знаю, почему это происходит. Вот почему я думал, но это не позволило мне опубликовать. Это не похоже на эффективность, поскольку я уверен, что мне сказали, что это так. Гипотетически, даже если это было последним, вы все равно должны были бы разрешить его положение статически при компиляции. Я не могу придумать ничего, что могло бы означать, что вы не можете, хотя я знаю только очень простые конструкции JVM. –

Смежные вопросы