Convert this: peculiarities of cross-platform mobile game development at Vizor
Convert this: peculiarities of cross-platform mobile game development at Vizor
Who am I ?
Previously at:
«Unity3D глазами программиста графики»
DevGamm! Минск, осень 2014.
Роман Чеховский
• Архитектор мобильного движка Vizor
Games.
• 4+ лет опыта работы с графикой,
мобильными играми, и движками.
• Работал с Unity3D, UE, Cocos2D, libgdx,
Urho3D, Ogre3D, Adobe flash, Irrlicht,
проприетарными технологиями.
• Развивался в процессе разработки проекта.
• Кроссплатформенный:
Windows, OS X, Linux – JDK.
Android 4.0+, iOS – Native
(conversion).
• Первый релиз – “Зомби Инфо” – Апрель
2013.
• Множество структурных и функциональных
оптимизаций для мобильных устройств.
• Data-driven насколько это возможно.
• Смычка с API устройств через бриджи на
С++.
Cобственный мобильный
движок
–
• Много runtime-проверок.
• Отсутствие значимых типов,
• Отсутствие делегатов.
• Отсутствие обобщенных типов
во время выполнения.
• Издержки на сборку мусора.
• Нет среды выполнения на iOS.
Java как язык разработки
+
• Типобезопасность.
• Отсутствие pointer
arithmetic.
• Большая стандартная
библиотека.
• Средства выразительности.
• Автоматическая сборка
мусора.
• Приемлемая
производительность.
jMonkeyEngine
1 http://jmonkeyengine.org - jMonkeyEngine official site
2 https://libgdx.badlogicgames.com - ligGDX official site
Коллекции
! Error(x, y): java: generic array creation
1. Не могут содержать примитивы
решение: Не изобретать своих коллекций для ссылочных
типов.
решение: IntArrayList, FloatArrayList, IntIntHashMap, etc, не реализующие iterator().
3. Присутствует type erasure и издержки на приведение типов в run-
timeрешение: Насколько это возможно, ускорить cast и instanceof на runtime-
уровне.
2. Нельзя инстанциировать generic array
public class ArrayList0<T> extends ...
{
private T[] objects;
public ArrayList0(int capacity)
{
objects = new T[capacity];
}
// и так далее
}
public class ArrayList1<T> extends ...
{
private T[] elements;
public ArrayList1(Class<T> klass, int capacity)
{
elements = java.lang.reflect.Array.newInstance(
klass,
capacity
);
}
// и так далее
}
Значимые типы
1. Их нет :(
List<Vertex3D> vs = new ArrayList<>();
for (int i = 0; i < ...; ++i)
vs.add(new Vertex3D());
context.setStreamSource(vs);
• Колоссальные расходы на инстанциирование
• Footprint объектов
2. …но с этим можно жить :)
public class Vertex3DModel extends VertexModel
{
VertexElem position = VertexElem.POSITION3F;
VertexElem rotation = VertexElem.ROTATION4F;
VertexElem scale = VertexElem.SCALE3F;
}
• Невыровненная память
Vertex3DModel m = new Vertex3DModel();
VertexArray vs = new VertexArray(m);
for (int i = 0; i < ...; ++i)
vs.add(...);
context.setStreamSource(vs);
• Данные хранятся в виде float[]
• Инты кладем используя floatToRawIntBits()
• Байты упаковыаем в int’ы
• Значительный overhead для GC
Проблемы: Факты:
• Double-precision пока без необходим
public class Vertex3D extends Vertex
{
Vector3 position = new Vector3();
Quaternion rotation = new Quaternion();
Vector3 scale = new Vector3();
}
Performanc
e
Apple
iOS
Java -
проблемы
JNI-бриджинг AOT-компиляцияКонверсия кода
J2ObjC RoboVM
3 https://github.com/google/j2objc - j2ObjC github repo
4 https://github.com/robovm/robovm - RoboVM github repo
j2cpp2 Java DesktopNative plug-ins
Конвертер -
требования
• Конверсия исходного кода на java в С++ 11.
• Совместимость с java 1.8 (lambdas, method
references).
• Высокая скорость конверсии на многоядерном
железе.
• Читаемость и отлаживаемость сгенерированного
кода.
Конвертер: AST
*.java Compilatio
n
unit
Concurrenc
ypackage com.vizor.data;
class A<T> extends ... implements ...
{
private T[] field;
public A(T[] data)
{
field = data;
}
/** Выводит на экран i’й аргумент
* @param i индекс
*/
public void foo(int arg)
{
System.out.println(field[arg]);
}
}
5
Lexer Parser+
5 https://github.com/javaparser/javaparser - javaparser library github repo
Class Declaration
MethodsExtension
Class Name
Class Name
Method Declaration
Method Name Comment
Method Body
Assignment Invocation
ValueTarget Target Method
name
Конвертер:
CST
Compilatio
n
unit
FP
Visitor
SP
Visitor
TP
Visitor
CST
project
Concurrenc
y
Write
Atomicity
@Override
protected int foo()
{
String msg = “Hello” + “world”;
int n = 0;
for (int i = 0; i < msg.length(); ++i)
{
if (msg.charAt(i) == ‘o’)
n++;
}
return n;
}
Method: com.vizor.B.foo():int
overrides com.vizor.A.foo():int
Class: java.lang.String
Method: java.lang.String.length():int
Method: java.lang.String.charAt(int):char
Method: java.lang.String.append(S):S
В AST указания типа - строки
Конвертер: Visitors
1. FP Visitor – Объявления классов, интерфейсов, перечислений.
2. SP Visitor – Конструкторы, поля, методы, константы перечислений.
3. TP Visitor – Циклы, блоки кода, операторы, вызовы методов и
приведения типов.
• СST Project – база знаний о связях в AST.
• Информация о типах собирается в bulk type cache.
• Помечаются ссылки на использованные типы, переопределенные
методы, etc.
• Помечаются ссылки на вызываемые методы и использованные поля.
• На следующем этапе код обрабатывается процессорами.
Конвертер: Процессоры
1.Var Args remover
2.Generics remover
3.Anonymous class remover
4.Inner class remover
5.Nested class remover
6.For Each remover
7.Auto boxing remover
8.Enum remover
9.Conflicting names renamer
10.Method return type fixer
11.Method redeclaration fixer
12.String finalizer
13.Explicit constructor call adder
class ShapeBuilder {
public Shape build() {
....
}
class CircleBuilder extends ShapeBuilder {
@Override
public Circle build() {
....
}
CircleBuilder cb = new CircleBuilder();
Circle c = cb.build();
Method redeclaration fixer:
class CircleBuilder extends ShapeBuilder {
@Override
public Shape build() {
....
}
CircleBuilder cb = new CircleBuilder();
Circle c = (Circle)cb.build();
Конвертер:
Печать
CST
project
HPP
Printer
CPP
Printer
method prototypes
class declarations
class definition
using types
fields
method bodies
#include files
statics init
A.hpp A.cpp
HPP
Printer
CPP
Printer
B.hpp B.cpp
HPP
Printer
CPP
Printer
C.hpp C.cpp
A B C … Z
A (class) B (class) C (class)
Thread Pool
Конвертер: Showcase
public static void unique(List<? extends Item> list)
{
Iterator<? extends Item> it = list.iterator();
int count = 0;
while (it.hasNext())
{
Item object = it.next();
for (int i = 0; i < count; i++)
{
Item o = list.get(i);
if (o.id.equals(object.id))
{
it.remove();
count--;
break;
}
}
count++;
}
}
jvmtypes::jvoid Item::unique(List* list)
{
Iterator* it = list->iterator();
jvmtypes::jint count = 0;
while (it->hasNext())
{
Item* object = (jCAST<Item>(it->next()));
for (jvmtypes::jint i = 0; i < count; i++)
{
Item* o = (jCAST<Item>(list->get(i)));
if (o->id->equals(object->id))
{
it->remove();
count--;
break;
}
}
count++;
}
}
List<GameObject> l = new ArrayList<>(42);
// ...
GameObject o = l.get(0);
List l = new ArrayList(42);
// ...
GameObject o = (GameObject) l.get(0);
NEW java/util/ArrayList
DUP
INVOKESPECIAL java/util/ArrayList.<init> ()V
ASTORE 1
ALOAD 1
ICONST_0
INVOKEINTERFACE java/util/List.get (I)Ljava/lang/Object
CHECKCAST com/vizor/mobile/engine/GameObject
ASTORE 2
List* vectors = ArrayList::$alloc()->$ctor_ArrayList(42);
// ...
GameObject* v = static_cast<GameObject*>(vectors->get(0));
Type erasure
Такого простого приведения типа очевидно недостаточно. Почему?
public class GameObject extends ? implements ?
class GameObject : public Entity, public Serializable, public virtual Object
java.lang.Object
com.vizor.Entityjava.lang.Serializable
com.vizor.GameObject
<<implements>> <<extends>>
virtual inheritancevirtual inheritance
Virtual inheritance
static_cast - статическое преобразование c проверкой в compile time.
! Cannot cast ‘Base *' to ‘Derived *' via virtual base ‘Base'
reinterpret_cast - смена представления указателя или ссылки без каких бы то ни было проверок или гарантий ни
в compile time, ни в runtime.
Type traits
dynamic_cast – динамическое преобразование указателя или ссылки с проверкой в runtime.
Медленный, требует опцию -frtti
Object* o = ->ctor_GameObject(...);
ADDRESSADDRESS + THUNK
GameObject::$alloc()
“INVOKESPECIAL”
Таким образом суть каста сводится к убиранию этого adjusment’a c с проверкой достижимости.
java.lang.Object
java.lang.Serializable
com.vizor.Entity
com.vizor.GameObject
6 http://www.programering.com/a/MDOxgTNwATM.html - memory layout for dynamic objects
Object* o = new GameObject();
GameObject* go = dynamic_cast<GameObject>(o);
std::cout << (uintptr_t)o; // 0x10000010
std::cout << (uintptr_t)go; // 0x10000000
o != go
jCAST
GameObject* o = jCAST<GameObject>(o); ->
return (GameObject*)o->$cast_to(GameObject::CLASS_ID);
void* $getPointer()
{
return this;
}
void* $castTo(const int to)
{
switch (to)
{
case GameObject::CLASS_ID:
return GameObject::$getPointer()
case Serializable::CLASS_ID:
return Serializable::$getPointer();
case Entity::CLASS_ID:
return Entity::$getPointer();
case Object::CLASS_ID:
return Object::$getPointer();
default:
return 0;
}
}
7 http://www.drdobbs.com/cpp/multiple-inheritance-considered-useful - dynamic_cast trough vtable
0
10000000
20000000
30000000
40000000
50000000
60000000
dynamic_cast jCAST
5-10X speed-up on real hardware
1. Java, на самом деле, подходит как язык для
написания движка, с принятием во внимание её
особенностей.
Выводы:
2. Любая проблема может быть достойно решена на
архитектурном уровне.
3. Индустрия показывает, что конверсия кода –
перспективное решение, к которому разработчики
прибегают всё чаще.
Спасибо за внимание!
Вопросы…?

More Related Content

PPTX
C#. От основ к эффективному коду
PPTX
Bytecode
PDF
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
PDF
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
PPTX
Ciklum .NET Saturday - Introduction to TypeScript
PPTX
NetworkUA - 2012 - Introduction TypeScript
PDF
Объектно-ориентированное программирование. Лекции 9 и 10
PDF
Андрей Карпов, Приватные байки от разработчиков анализатора кода
C#. От основ к эффективному коду
Bytecode
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
Ciklum .NET Saturday - Introduction to TypeScript
NetworkUA - 2012 - Introduction TypeScript
Объектно-ориентированное программирование. Лекции 9 и 10
Андрей Карпов, Приватные байки от разработчиков анализатора кода

What's hot (20)

PPTX
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
PDF
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
PDF
Об особенностях использования значимых типов в .NET
PPTX
Статический анализ кода
PPTX
Александр Фокин, Рефлексия в C++
PDF
Объектно-ориентированное программирование. Лекция 5 и 6
PPTX
PDF
Лекция 12. Быстрее, Python, ещё быстрее.
PDF
Объектно-ориентированное программирование. Лекция 7 и 8.
PDF
Антон Полухин, Немного о Boost
PDF
C++ refelection and cats
PDF
Фундаментальные основы разработки под iOS. Павел Тайкало
PDF
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
PPT
Talks on collections
PDF
Лекция 10. Классы 2.
PDF
Лекция 2. Всё, что вы хотели знать о функциях в Python.
PDF
Объектное и прототипное программирование в Javascript
PPTX
Funny JS #2
PDF
AlgoCollections (RUS)
PDF
хитрости выведения типов
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Об особенностях использования значимых типов в .NET
Статический анализ кода
Александр Фокин, Рефлексия в C++
Объектно-ориентированное программирование. Лекция 5 и 6
Лекция 12. Быстрее, Python, ещё быстрее.
Объектно-ориентированное программирование. Лекция 7 и 8.
Антон Полухин, Немного о Boost
C++ refelection and cats
Фундаментальные основы разработки под iOS. Павел Тайкало
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Talks on collections
Лекция 10. Классы 2.
Лекция 2. Всё, что вы хотели знать о функциях в Python.
Объектное и прототипное программирование в Javascript
Funny JS #2
AlgoCollections (RUS)
хитрости выведения типов
Ad

Similar to Convert this: peculiarities of cross-platform mobile game development at Vizor (20)

PDF
08 - Java. Java-классы: взгляд изнутри
PDF
Java осень 2014 занятие 6
PPT
Куда уходит память?
PDF
TeaVM: dead code elimination and devirtualization
PPTX
СИ++ УМЕР. ДА ЗДРАВСТВУЕТ СИ++
PPTX
Wargaming.net: Архитектура современных 3D движков
PDF
Joker 2016 - Bytecode 101
PPTX
Подружили CLR и JVM в Project Rider
PPTX
Андрей Акиньшин
PPTX
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
PDF
Java осень 2013 лекция 7
PDF
C++ Базовый. Занятие 14.
PDF
Tricky Java Generics
PPTX
C++ в играх, больших и не очень
PPTX
Классы и объекты в Java
PPTX
Статический и динамический полиморфизм в C++, Дмитрий Леванов
PPTX
Статический и динамический полиморфизм в C++, Дмитрий Леванов
PPTX
Паттерны 64-битных ошибок в играх
PPTX
Static code analysis of the projects built on Unreal Engine
PPTX
Статический анализ кода проектов, построенных на движке Unreal Engine
08 - Java. Java-классы: взгляд изнутри
Java осень 2014 занятие 6
Куда уходит память?
TeaVM: dead code elimination and devirtualization
СИ++ УМЕР. ДА ЗДРАВСТВУЕТ СИ++
Wargaming.net: Архитектура современных 3D движков
Joker 2016 - Bytecode 101
Подружили CLR и JVM в Project Rider
Андрей Акиньшин
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
Java осень 2013 лекция 7
C++ Базовый. Занятие 14.
Tricky Java Generics
C++ в играх, больших и не очень
Классы и объекты в Java
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Паттерны 64-битных ошибок в играх
Static code analysis of the projects built on Unreal Engine
Статический анализ кода проектов, построенных на движке Unreal Engine
Ad

More from DevGAMM Conference (20)

PPTX
The art of small steps, or how to make sound for games in conditions of war /...
PPTX
Breaking up with FMOD - Why we ended things and embraced Metasounds / Daniel ...
PPTX
How Audio Objects Improve Spatial Accuracy / Mads Maretty Sønderup (Audiokine...
PPTX
Why indie developers should consider hyper-casual right now / Igor Gurenyov (...
PPTX
AI / ML for Indies / Tyler Coleman (Retora Games)
PDF
Agility is the Key: Power Up Your GameDev Project Management with Agile Pract...
PPTX
New PR Tech and AI Tools for 2023: A Game Changer for Outreach / Kirill Perev...
PDF
Playable Ads - Revolutionizing mobile games advertising / Jakub Kukuryk (Popc...
PDF
Creative Collaboration: Managing an Art Team / Nastassia Radzivonava (Glera G...
PDF
From Local to Global: Unleashing the Power of Payments / Jan Kuhlmannn (Xsolla)
PDF
Strategies and case studies to grow LTV in 2023 / Julia Iljuk (Balancy)
PDF
Why is ASO not working in 2023 and how to change it? / Olena Vedmedenko (Keya...
PDF
How to increase wishlists & game sales from China? Growth marketing tactics &...
PDF
Turkish Gaming Industry and HR Insights / Mustafa Mert EFE (Zindhu)
PDF
Building an Awesome Creative Team from Scratch, Capable of Scaling Up / Sasha...
PPTX
Seven Reasons Why Your LiveOps Is Not Performing / Alexander Devyaterikov (Be...
PDF
The Power of Game and Music Collaborations: Reaching and Engaging the Masses ...
PPTX
Branded Content: How to overcome players' immunity to advertising / Alex Brod...
PPTX
Resurrecting Chasm: The Rift - A Source-less Remastering Journey / Gennadii P...
PPTX
How NOT to do showcase events: Behind the scenes of Midnight Show / Andrew Ko...
The art of small steps, or how to make sound for games in conditions of war /...
Breaking up with FMOD - Why we ended things and embraced Metasounds / Daniel ...
How Audio Objects Improve Spatial Accuracy / Mads Maretty Sønderup (Audiokine...
Why indie developers should consider hyper-casual right now / Igor Gurenyov (...
AI / ML for Indies / Tyler Coleman (Retora Games)
Agility is the Key: Power Up Your GameDev Project Management with Agile Pract...
New PR Tech and AI Tools for 2023: A Game Changer for Outreach / Kirill Perev...
Playable Ads - Revolutionizing mobile games advertising / Jakub Kukuryk (Popc...
Creative Collaboration: Managing an Art Team / Nastassia Radzivonava (Glera G...
From Local to Global: Unleashing the Power of Payments / Jan Kuhlmannn (Xsolla)
Strategies and case studies to grow LTV in 2023 / Julia Iljuk (Balancy)
Why is ASO not working in 2023 and how to change it? / Olena Vedmedenko (Keya...
How to increase wishlists & game sales from China? Growth marketing tactics &...
Turkish Gaming Industry and HR Insights / Mustafa Mert EFE (Zindhu)
Building an Awesome Creative Team from Scratch, Capable of Scaling Up / Sasha...
Seven Reasons Why Your LiveOps Is Not Performing / Alexander Devyaterikov (Be...
The Power of Game and Music Collaborations: Reaching and Engaging the Masses ...
Branded Content: How to overcome players' immunity to advertising / Alex Brod...
Resurrecting Chasm: The Rift - A Source-less Remastering Journey / Gennadii P...
How NOT to do showcase events: Behind the scenes of Midnight Show / Andrew Ko...

Convert this: peculiarities of cross-platform mobile game development at Vizor

  • 3. Who am I ? Previously at: «Unity3D глазами программиста графики» DevGamm! Минск, осень 2014. Роман Чеховский • Архитектор мобильного движка Vizor Games. • 4+ лет опыта работы с графикой, мобильными играми, и движками. • Работал с Unity3D, UE, Cocos2D, libgdx, Urho3D, Ogre3D, Adobe flash, Irrlicht, проприетарными технологиями.
  • 4. • Развивался в процессе разработки проекта. • Кроссплатформенный: Windows, OS X, Linux – JDK. Android 4.0+, iOS – Native (conversion). • Первый релиз – “Зомби Инфо” – Апрель 2013. • Множество структурных и функциональных оптимизаций для мобильных устройств. • Data-driven насколько это возможно. • Смычка с API устройств через бриджи на С++. Cобственный мобильный движок
  • 5. – • Много runtime-проверок. • Отсутствие значимых типов, • Отсутствие делегатов. • Отсутствие обобщенных типов во время выполнения. • Издержки на сборку мусора. • Нет среды выполнения на iOS. Java как язык разработки + • Типобезопасность. • Отсутствие pointer arithmetic. • Большая стандартная библиотека. • Средства выразительности. • Автоматическая сборка мусора. • Приемлемая производительность. jMonkeyEngine 1 http://jmonkeyengine.org - jMonkeyEngine official site 2 https://libgdx.badlogicgames.com - ligGDX official site
  • 6. Коллекции ! Error(x, y): java: generic array creation 1. Не могут содержать примитивы решение: Не изобретать своих коллекций для ссылочных типов. решение: IntArrayList, FloatArrayList, IntIntHashMap, etc, не реализующие iterator(). 3. Присутствует type erasure и издержки на приведение типов в run- timeрешение: Насколько это возможно, ускорить cast и instanceof на runtime- уровне. 2. Нельзя инстанциировать generic array public class ArrayList0<T> extends ... { private T[] objects; public ArrayList0(int capacity) { objects = new T[capacity]; } // и так далее } public class ArrayList1<T> extends ... { private T[] elements; public ArrayList1(Class<T> klass, int capacity) { elements = java.lang.reflect.Array.newInstance( klass, capacity ); } // и так далее }
  • 7. Значимые типы 1. Их нет :( List<Vertex3D> vs = new ArrayList<>(); for (int i = 0; i < ...; ++i) vs.add(new Vertex3D()); context.setStreamSource(vs); • Колоссальные расходы на инстанциирование • Footprint объектов 2. …но с этим можно жить :) public class Vertex3DModel extends VertexModel { VertexElem position = VertexElem.POSITION3F; VertexElem rotation = VertexElem.ROTATION4F; VertexElem scale = VertexElem.SCALE3F; } • Невыровненная память Vertex3DModel m = new Vertex3DModel(); VertexArray vs = new VertexArray(m); for (int i = 0; i < ...; ++i) vs.add(...); context.setStreamSource(vs); • Данные хранятся в виде float[] • Инты кладем используя floatToRawIntBits() • Байты упаковыаем в int’ы • Значительный overhead для GC Проблемы: Факты: • Double-precision пока без необходим public class Vertex3D extends Vertex { Vector3 position = new Vector3(); Quaternion rotation = new Quaternion(); Vector3 scale = new Vector3(); }
  • 8. Performanc e Apple iOS Java - проблемы JNI-бриджинг AOT-компиляцияКонверсия кода J2ObjC RoboVM 3 https://github.com/google/j2objc - j2ObjC github repo 4 https://github.com/robovm/robovm - RoboVM github repo j2cpp2 Java DesktopNative plug-ins
  • 9. Конвертер - требования • Конверсия исходного кода на java в С++ 11. • Совместимость с java 1.8 (lambdas, method references). • Высокая скорость конверсии на многоядерном железе. • Читаемость и отлаживаемость сгенерированного кода.
  • 10. Конвертер: AST *.java Compilatio n unit Concurrenc ypackage com.vizor.data; class A<T> extends ... implements ... { private T[] field; public A(T[] data) { field = data; } /** Выводит на экран i’й аргумент * @param i индекс */ public void foo(int arg) { System.out.println(field[arg]); } } 5 Lexer Parser+ 5 https://github.com/javaparser/javaparser - javaparser library github repo Class Declaration MethodsExtension Class Name Class Name Method Declaration Method Name Comment Method Body Assignment Invocation ValueTarget Target Method name
  • 11. Конвертер: CST Compilatio n unit FP Visitor SP Visitor TP Visitor CST project Concurrenc y Write Atomicity @Override protected int foo() { String msg = “Hello” + “world”; int n = 0; for (int i = 0; i < msg.length(); ++i) { if (msg.charAt(i) == ‘o’) n++; } return n; } Method: com.vizor.B.foo():int overrides com.vizor.A.foo():int Class: java.lang.String Method: java.lang.String.length():int Method: java.lang.String.charAt(int):char Method: java.lang.String.append(S):S В AST указания типа - строки
  • 12. Конвертер: Visitors 1. FP Visitor – Объявления классов, интерфейсов, перечислений. 2. SP Visitor – Конструкторы, поля, методы, константы перечислений. 3. TP Visitor – Циклы, блоки кода, операторы, вызовы методов и приведения типов. • СST Project – база знаний о связях в AST. • Информация о типах собирается в bulk type cache. • Помечаются ссылки на использованные типы, переопределенные методы, etc. • Помечаются ссылки на вызываемые методы и использованные поля. • На следующем этапе код обрабатывается процессорами.
  • 13. Конвертер: Процессоры 1.Var Args remover 2.Generics remover 3.Anonymous class remover 4.Inner class remover 5.Nested class remover 6.For Each remover 7.Auto boxing remover 8.Enum remover 9.Conflicting names renamer 10.Method return type fixer 11.Method redeclaration fixer 12.String finalizer 13.Explicit constructor call adder class ShapeBuilder { public Shape build() { .... } class CircleBuilder extends ShapeBuilder { @Override public Circle build() { .... } CircleBuilder cb = new CircleBuilder(); Circle c = cb.build(); Method redeclaration fixer: class CircleBuilder extends ShapeBuilder { @Override public Shape build() { .... } CircleBuilder cb = new CircleBuilder(); Circle c = (Circle)cb.build();
  • 14. Конвертер: Печать CST project HPP Printer CPP Printer method prototypes class declarations class definition using types fields method bodies #include files statics init A.hpp A.cpp HPP Printer CPP Printer B.hpp B.cpp HPP Printer CPP Printer C.hpp C.cpp A B C … Z A (class) B (class) C (class) Thread Pool
  • 15. Конвертер: Showcase public static void unique(List<? extends Item> list) { Iterator<? extends Item> it = list.iterator(); int count = 0; while (it.hasNext()) { Item object = it.next(); for (int i = 0; i < count; i++) { Item o = list.get(i); if (o.id.equals(object.id)) { it.remove(); count--; break; } } count++; } } jvmtypes::jvoid Item::unique(List* list) { Iterator* it = list->iterator(); jvmtypes::jint count = 0; while (it->hasNext()) { Item* object = (jCAST<Item>(it->next())); for (jvmtypes::jint i = 0; i < count; i++) { Item* o = (jCAST<Item>(list->get(i))); if (o->id->equals(object->id)) { it->remove(); count--; break; } } count++; } }
  • 16. List<GameObject> l = new ArrayList<>(42); // ... GameObject o = l.get(0); List l = new ArrayList(42); // ... GameObject o = (GameObject) l.get(0); NEW java/util/ArrayList DUP INVOKESPECIAL java/util/ArrayList.<init> ()V ASTORE 1 ALOAD 1 ICONST_0 INVOKEINTERFACE java/util/List.get (I)Ljava/lang/Object CHECKCAST com/vizor/mobile/engine/GameObject ASTORE 2 List* vectors = ArrayList::$alloc()->$ctor_ArrayList(42); // ... GameObject* v = static_cast<GameObject*>(vectors->get(0)); Type erasure Такого простого приведения типа очевидно недостаточно. Почему?
  • 17. public class GameObject extends ? implements ? class GameObject : public Entity, public Serializable, public virtual Object java.lang.Object com.vizor.Entityjava.lang.Serializable com.vizor.GameObject <<implements>> <<extends>> virtual inheritancevirtual inheritance Virtual inheritance static_cast - статическое преобразование c проверкой в compile time. ! Cannot cast ‘Base *' to ‘Derived *' via virtual base ‘Base' reinterpret_cast - смена представления указателя или ссылки без каких бы то ни было проверок или гарантий ни в compile time, ни в runtime.
  • 18. Type traits dynamic_cast – динамическое преобразование указателя или ссылки с проверкой в runtime. Медленный, требует опцию -frtti Object* o = ->ctor_GameObject(...); ADDRESSADDRESS + THUNK GameObject::$alloc() “INVOKESPECIAL” Таким образом суть каста сводится к убиранию этого adjusment’a c с проверкой достижимости. java.lang.Object java.lang.Serializable com.vizor.Entity com.vizor.GameObject 6 http://www.programering.com/a/MDOxgTNwATM.html - memory layout for dynamic objects Object* o = new GameObject(); GameObject* go = dynamic_cast<GameObject>(o); std::cout << (uintptr_t)o; // 0x10000010 std::cout << (uintptr_t)go; // 0x10000000 o != go
  • 19. jCAST GameObject* o = jCAST<GameObject>(o); -> return (GameObject*)o->$cast_to(GameObject::CLASS_ID); void* $getPointer() { return this; } void* $castTo(const int to) { switch (to) { case GameObject::CLASS_ID: return GameObject::$getPointer() case Serializable::CLASS_ID: return Serializable::$getPointer(); case Entity::CLASS_ID: return Entity::$getPointer(); case Object::CLASS_ID: return Object::$getPointer(); default: return 0; } } 7 http://www.drdobbs.com/cpp/multiple-inheritance-considered-useful - dynamic_cast trough vtable 0 10000000 20000000 30000000 40000000 50000000 60000000 dynamic_cast jCAST 5-10X speed-up on real hardware
  • 20. 1. Java, на самом деле, подходит как язык для написания движка, с принятием во внимание её особенностей. Выводы: 2. Любая проблема может быть достойно решена на архитектурном уровне. 3. Индустрия показывает, что конверсия кода – перспективное решение, к которому разработчики прибегают всё чаще.

Editor's Notes

  • #2: Перелистай за минуту до начала
  • #5: Наш собственный движок развивался в процессе разработки нашего первого мобильного приложения – Зомби Инфо, которое вышло на Android в Апреле 2013 года. (НЕ ГОВОРИ ПРО ДЖАВУ)
  • #6: Картинка про дженерики «она или есть или её нет совсем»
  • #7: Как же буферы? Да, мы используем буферы, однако сейчас речь идет о масштабируемых коллекциях, размер буферов фиксирован.
  • #11: АСД – это (в нашем случае) дерево, представляющее класса программы, его узлы являются по мере удаленности от корня всё более и более простыми операциями языка. Листья в конечном счете являются константами и переменными.
  • #12: Абстрактного синтаксического дерева недостаточно, чтобы произвести над кодом все необходимые нам преобразования. В этом коде представлен простой метод foo(). Нам, знакомым с семантикой языка Java, известно, что такое String и судя по аннотации @Override мы знаем, что этот метод что-то переопределяет. Однако в АST указания типа – строки. Мы не можем, даже исходя из априори валидного и проверенного чем-то за нас java-кода исходть из того что каждая из конструкций в этом методе семантически верна, так как парсер гарантировал нам отсутствие лишь синтаксических ошибок. (КЛИКАЮ ДАЛЬШЕ – РАССКАЗЫВАЮ ЧТО ТУТ И КАК)
  • #18: Мы не знаем какие классы он наследует и какие интерфейсы реализует
  • #19: TODO: Рассказать, почему я не хочу RTTI (размер бинарника, облегчает Мы не знаем какие классы он наследует и какие интерфейсы реализует
  • #20: Вместо динамик каста используем метод jCASTб Сразу предупреждаю, что тесты выполнены профессиональными… спортсменами в условиях, приближенных к реальному миру. Чему это может научить? Но если Вы УЖЕ (зачем-то) готовы продвигать свою технологию и отвечать за нее – используйте своё имеющееся, пусть и непростое положение по максимуму.