Почему существует 4 отдельных байт-кода для выполнения статических / виртуальных / интерфейсных / специальных методов, когда этого достаточно? - PullRequest
1 голос
/ 15 марта 2011

Поскольку каждый вызов метода включает сигнатуру целевого метода, мне кажется, что шаг проверки класса мог бы определить, анализируя цель, вызывает ли она статический, виртуальный и т. Д., И делает ли это правильно?

Имеет ли 4-байтовые коды пустую трату 3-байтовых кодов, или это просто самодокументирование, если кто-то создает файл класса с помощью javap?

Ответы [ 6 ]

3 голосов
/ 15 марта 2011

Если вы говорите о invokeinterface, invokespecial, invokestatic и invokevirtual, между ними есть различия.Эффекты в стеке для начала.

2 голосов
/ 14 июня 2011

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

Test {
        public static void test(Test t) {
        // static method
    }
}

и где-то вызов этой статики с псевдобайтным кодом

push t
jmp Test.test(T)V

Теперь давайте предположим, что кто-то использует другой класс Test во время выполнения

Test {
    public void test(Test t) {
        // obj call
    }
}

В этом случае jmp Test.test(T)V все еще действует.Проблема в том, что это испортит стек.Два разных кода операции позволяют уловить время этой проблемы.

0 голосов
/ 12 июня 2015

Я думаю, что эта дискуссия была ненужной, так как у Java есть это дизайнерское решение. Не уверен, но вы, возможно, захотите взглянуть еще на то, что они называют конечными точками пользовательских данных: invokedynamic

0 голосов
/ 23 марта 2011

Как минимум invokespecial требуется, чтобы быть отдельной инструкцией, поскольку java позволяет явно вызывать супер реализацию переопределенного метода:

class Super {
    public void m() { }
}
class Sub {
    public void m() {
        super.m();
    }
}

Вызов в Sub должен быть invokespecialпоскольку в противном случае он просто вызвал бы себя и вышел из стека.

0 голосов
/ 22 марта 2011

вам нужны эти коды операций, потому что во время размещения ссылок на методы для байт-кода они содержат только символические ссылки на записи в пуле констант.Чтобы разрешить эти ссылки, вам нужно знать, какой тип нужно разрешить: например, разница между invokespecial и invokevirtual заключается в статической и динамической привязке.Для invokespecial вы выбираете тип ссылки, а не класс объекта.Эта информация не может быть получена без добавления компилятором специального кода операции, чтобы различать методы.В java код обычно связан динамически, что и заставляет эти коды операций.

0 голосов
/ 15 марта 2011

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

Утверждалось, что отдельные инструкции улучшают безопасность, уменьшая шансы сбить с толку ВМ.Не уверен, что меня это убедило.

...