Внутреннее представление объектов

Содержание

Слайд 2

Внутренний формат данных объекта. Внутренний формат данных объекта имеет сходство с

Внутренний формат данных объекта.

Внутренний формат данных объекта имеет сходство с внутренним

форматом записи.

Поля объекта записываются в порядке их описаний как непрерывная последовательность переменных.
Любое поле, унаследованное от родительского (порождающего) типа, записывается перед новыми полями, определенными в дочернем (порожденном) типе.

Слайд 3

Внутренний формат данных объекта. Если объектный тип определяет виртуальные методы, конструкторы

Внутренний формат данных объекта.

Если объектный тип определяет виртуальные методы, конструкторы или

деструкторы, то компилятор размещает в нем дополнительное поле данных.

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

Поле таблицы виртуальных методов располагается непосредственно после обычных полей объектного типа.

Если объектный тип наследует виртуальные методы, конструкторы или деструкторы, то он также наследует и поле ТВМ.

Благодаря чему дополнительное поле таблицы виртуальных методов не размещается.

Слайд 4

Внутренний формат данных объекта. Инициализация поля таблицы виртуальных методов экземпляра объекта

Внутренний формат данных объекта.

Инициализация поля таблицы виртуальных методов экземпляра объекта осуществляется

конструктором объектного типа.
Программа никогда не инициализирует поле таблицы виртуальных методов явно и
не имеет к нему доступа.
Слайд 5

Представление в сегменте данных объектов типов TPerson, TStaff и Tteacher. TPerson

Представление в сегменте данных объектов типов TPerson, TStaff и Tteacher.

TPerson
Name
Date
Rate
TBM
TStaff
Name
Date
Rate
TBM
Bonus
TTeacher
Name
Date
Rate
TBM
Bonus
Hours
HourRate

Слайд 6

Таблица виртуальных методов. Каждый объектный тип, содержащий или наследующий виртуальные методы,

Таблица виртуальных методов.

Каждый объектный тип, содержащий или наследующий виртуальные методы, конструкторы

или деструкторы, имеет таблицу виртуальных методов.

В таблице виртуальных методов запоминается инициализируемая часть сегмента данных программы.

Для каждого объектного типа
(но не для каждого экземпляра)
имеется только одна таблица виртуальных методов

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

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

Указатели на таблицы виртуальных методов также запоминаются автоматически в экземплярах объектных типов с помощью конструкторов.
Программа никогда не работает непосредственно с этими указателями.

Слайд 7

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

Таблица виртуальных методов.

Первое слово таблицы виртуальных методов содержит размер экземпляров соответствующего

объектного типа.

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

Слайд 8

Таблица виртуальных методов. Второе слово таблицы виртуальных методов содержит отрицательный размер

Таблица виртуальных методов.

Второе слово таблицы виртуальных методов содержит отрицательный размер экземпляров

соответствующего объектного типа.

Эта информация используется программой контроля вызовов виртуальных методов для выявления неинициализированных объектов (экземпляров, для которых не был произведен вызов конструктора) и для проверки правильности таблицы виртуальных методов.
Если разрешен контроль виртуального вызова с помощью директивы {$R+}, компилятор генерирует вызов подпрограммы контроля обращения к таблице виртуальных методов перед каждым вызовом виртуального метода.
Эта подпрограмма проверяет неравенство первого слова ТВМ нулю и равенство суммы первого и второго слов нулю.
Если каждая из проверок обнаруживает несовпадение, то генерируется ошибка выполнения с кодом 210.

Слайд 9

Таблица виртуальных методов. Разрешение проверок границ диапазонов и проверок вызовов виртуальных

Таблица виртуальных методов.

Разрешение проверок границ диапазонов и проверок вызовов виртуальных методов

замедляет выполнение программы и делает размер ЕХЕ-файла немного большим, поэтому рекомендуется использовать директиву {$R+} только во время отладки и переключать эту директиву в состояние {$R-} в окончательной версии программы.
Слайд 10

Таблица виртуальных методов. Третье слово ТВМ содержит смещение сегмента данных объектного

Таблица виртуальных методов.

Третье слово ТВМ содержит смещение сегмента данных объектного типа

в таблице динамических методов (ТДМ) или 0, если объект не содержит динамических методов.
Слайд 11

Таблица виртуальных методов. Четвертое слово ТВМ резервируется и всегда равно 0.

Таблица виртуальных методов.

Четвертое слово ТВМ резервируется и всегда равно 0.

Слайд 12

Таблица виртуальных методов. Начиная со смещения 8, следует список 32-разрядных указателей

Таблица виртуальных методов.

Начиная со смещения 8,
следует список 32-разрядных указателей методов.


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

Слайд 13

Пример размещения таблиц виртуальных методов типов TStaff и TTeacher TBM TStaff

Пример размещения таблиц виртуальных методов типов TStaff и TTeacher

TBM TStaff
16
-16
0
0
TStaff.Done
TStaff.GetSum
TStaff.ShowSum
TStaff.ShowAll
TBM

TTeacher
16
-16
0
0
TTeacher.Done
TTeacher.GetSum
TTeacher.ShowSum
TTeacher.ShowAll

одно слово памяти

два слова памяти

Слайд 14

Таблица виртуальных методов. Конструкторы объектных типов содержат специальный код, который запоминает

Таблица виртуальных методов.

Конструкторы объектных типов содержат специальный код, который запоминает смещение

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

Например:

Пусть у нас имеется
экземпляр S типа TStaff и
экземпляр Т типа Ттеасher

вызов S.Init будет автоматически записывать смещение таблицы виртуальных методов типа TStaff в поле таблицы виртуальных методов экземпляра S
а вызов T.Init точно так же запишет смещение таблицы виртуальных методов типа ТТеасher в поле таблицы виртуальных методов экземпляра Т.

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

Таким образом, при необходимости конструктор может выполнить вызов виртуального метода.

Слайд 15

Функции для работы с таблицей виртуальных методов. Для непосредственной работы с

Функции для работы с таблицей виртуальных методов.

Для непосредственной работы с ТВМ

используются две функции
FUNCTION SizeOf(Obj):WORD;
FUNCTION TypeOf(Obj):POINTER;
Слайд 16

Функции для работы с таблицей виртуальных методов. Примененная к экземпляру объектного

Функции для работы с таблицей виртуальных методов.

Примененная к экземпляру объектного типа,

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

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

Функция TypeOf возвращает указатель на таблицу виртуальных методов объектного типа.

Функция TypeOf принимает единственный параметр, который может быть либо идентификатором объектного типа, либо экземпляром объектного типа.
В обоих случаях результат типа POINTER является указателем на таблицу виртуальных методов объектного типа.
TypeOf может применяться только к объектным типам, имеющим таблицы виртуальных методов.
Применение этой функции к другим типам приведет к ошибке.

Слайд 17

Функции для работы с таблицей виртуальных методов. Функция TypeOf может использоваться

Функции для работы с таблицей виртуальных методов.

Функция TypeOf может использоваться для

проверки фактического типа экземпляра.

Например:
IF TypeOf(Self) = TypeOf(TPerson) THEN ...;

Слайд 18

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

Таблица динамических методов.

Таблица виртуальных методов объектного типа содержит для каждого описанного

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

Таблица динамических методов. Динамические методы обеспечивают в таких ситуациях альтернативу. Для

Таблица динамических методов.

Динамические методы обеспечивают в таких ситуациях альтернативу.
Для динамических методов

вводится новый формат таблицы методов и новый способ обработки вызовов методов с поздним связыванием.
Вместо кодирования всех методов объектного типа с поздним связыванием в таблице динамических методов (ТДМ) кодируются только те методы, которые были в объектном типе переопределены.
Если в производных типах переопределяются только некоторые из большого числа методов с поздним связыванием, формат таблицы динамических методов использует меньшее пространство, чем формат таблицы виртуальных методов.
Слайд 20

Таблица динамических методов. Переопределим типы TStaff и Ттеасher следующим образом: TStaff

Таблица динамических методов.

Переопределим типы TStaff и Ттеасher следующим образом:

TStaff = OBJECT(TPerson);


Bonus : REAL;
CONSTRUCTOR Init(Nm,Dt :STRING; Rt,Bn :REAL);
DESTRUCTOR Done; VIRTUAL;
FUNCTION GetSum : REAL; VIRTUAL 10;
PROCEDURE ShowSum; VIRTUAL 20;
PROCEDURE ShowAll; VIRTUAL 30;
end;
TTeacher = OBJECT(TStaff)
Hours : WORD;
HourRate : REAL;
CONSTRUCTOR Init(Nm,Dt :STRING; Rt,Bn,Hrt :REAL; Hr :WORD);
DESTRUCTOR Done; VIRTUAL;
FUNCTION GetSum:REAL; VIRTUAL 10;
PROCEDURE ShowAll; VIRTUAL 30;
END;
Слайд 21

Схемы таблиц виртуальных и динамических методов для TStaff TBM TStaff 4

Схемы таблиц виртуальных и динамических методов для TStaff

TBM TStaff
4
-4
Смещение ТДМ

TStaff
0
TStaff.Done
ТДМ TStaff
0
Кэшируемый индекс
Кэшируемое смещение
3
10
20
30
TStaff.GetSum
TStaff.ShowSum
TStaff.ShowAll

одно слово памяти

два слова памяти

Слайд 22

Схемы таблиц виртуальных и динамических методов для ТТеаcher TBM TTeacher 4

Схемы таблиц виртуальных и динамических методов для ТТеаcher

TBM TTeacher
4
-4
Смещение ТДМ TTeacher


0
TTeacher.Done
ТДМ TTeacher
Смещение ТДМ TStaff
Кэшируемый индекс
Кэшируемое смещение
2
10
30
TTeacher.GetSum
TTeacher.ShowAll

одно слово памяти

два слова памяти

Слайд 23

Таблица динамических методов. Первое слово Содержит смещение в сегменте данных родительской

Таблица динамических методов.

Первое слово

Содержит смещение в сегменте данных родительской таблицы динамических

методов или 0, если родительская таблица динамических методов отсутствует.

Второе и третье слова

Используются в кэш-буфере просмотра динамических методов и будут рассмотрены далее.

Четвертое слово

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

Слайд 24

Таблица динамических методов. Объектный тип имеет таблицу динамических методов только, если

Таблица динамических методов.

Объектный тип имеет таблицу динамических методов только, если в

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

Вызов статических методов. Статические методы используют те же соглашения о вызовах,

Вызов статических методов.

Статические методы используют те же соглашения о вызовах, что

и обычные процедуры и функции,
за исключением того, что каждый метод имеет неявный дополнительный параметр Self, который соответствует параметру-переменной того же типа, что и объектный тип данного метода.

Параметр Self всегда передается последним и имеет вид 32-разрядного указателя на экземпляр, из которого вызывается метод.

Слайд 26

Вызов статических методов. Например: в типе Tperson определим процедуру ShowName введем

Вызов статических методов.

Например:

в типе Tperson определим процедуру ShowName
введем переменную Person типа

^TPerson,
Теперь вызов Person^.ShowName будет кодироваться следующим образом:

les DI, Person; {загрузить Person в ES:DI}
push ES; {передать как параметр Self}
push DI;
call TPerson.ShowName; {непосредственный вызов ShowName}

Слайд 27

Вызов статических методов. При возврате метод должен удалить параметр Self из

Вызов статических методов.

При возврате метод должен удалить параметр Self из стека

точно так же, как он удаляет обычные параметры.
Методы всегда используют дальний тип вызова, независимо от состояния директивы $F компилятора.
Слайд 28

Вызов виртуальных методов. Для вызова виртуального метода компилятор генерирует код, который:

Вызов виртуальных методов.

Для вызова виртуального метода компилятор генерирует код, который:
выбирает адрес

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

Например, для переменной Staff типа PStaff вызов Staff.GetSum будет генерировать следующий код:

les DI, Staff; {загрузить Staff в ES:DI}
push ES; {передать как параметр Self}
push DI;
mov DI,ES:[DI+6]; {извлечь смещение ТВМ из поля ТВМ}
call DWORD PTR [DI+12]; {вызвать запись ТВМ для GetSum}

Слайд 29

Вызов виртуальных методов. Правила совместимости для объектных типов позволяют Staff указывать

Вызов виртуальных методов.

Правила совместимости для объектных типов позволяют Staff указывать на

TStaff и на ТТеасher или на любых других потомков TStaff.

Если просмотреть приведенные ранее таблицы виртуальных методов TStaff и ТТеасher, можно увидеть, что для типа TStaff точка входа со смещением 12 в таблице виртуальных методов указывает на TStaff.GetSum.

Таким образом, в зависимости от фактического типа Staff во время вызова инструкция CALL вызывает либо TStaff.GetSum, либо ТТеасher.GetSum, либо метод любого другого потомка TStaff.

Слайд 30

Вызов динамических методов. Обработка вызова динамического метода более сложная и требует

Вызов динамических методов.

Обработка вызова динамического метода более сложная и требует больше

времени, чем вызов виртуального метода

Вместо использования инструкции CALL для вызова через указатель метода по статическому смещению в ТВМ, таблица динамических методов объектного типа и таблица динамических методов его предка должны просматриваться в поиске "самого верхнего" вхождения индекса конкретного динамического метода, а вызов затем должен выполняться через соответствующий указатель метода.

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

Слайд 31

Вызов динамических методов. Если бы метод GetSum типа TStaff описывался как

Вызов динамических методов.

Если бы метод GetSum типа TStaff описывался как динамический

метод с индексом 10, то вызов Staff^.Getsum, где Staff имеет тип PStaff, привел бы к генерации следующего кода:
les DI,Staff; {загрузить Staff в ED:DI}
push ES; {передать как параметр Self}
push DI;
mov DI,ES:[di+6];
{извлечь смещение ТДМ из поля ТВМ}
mov AX,10;
{загрузить в АХ индекс динамического метода}
call Dispatch;
{вызов подпрограммы обработки вызовов}
Слайд 32

Вызов динамических методов.

Вызов динамических методов.

Слайд 33

Вызов динамических методов.

Вызов динамических методов.

Слайд 34

Вызов динамических методов. Несмотря на использование кэширования и хорошо оптимизированной подпрограммы

Вызов динамических методов.

Несмотря на использование кэширования и хорошо оптимизированной подпрограммы обработки

вызовов,
обработка вызова динамического метода может потребовать значительно больше времени, чем вызов виртуального метода.

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

Слайд 35

Вызов конструкторов и деструкторов. Конструкторы и деструкторы используют те же соглашения

Вызов конструкторов и деструкторов.

Конструкторы и деструкторы используют те же соглашения о

вызовах, что и обычные методы, за исключением того, что дополнительный параметр размером в слово, называемый параметром ТВМ, передается через стек непосредственно перед параметром Self.

Для конструкторов параметр ТВМ содержит смещение таблицы виртуальных методов для запоминания в поле таблицы виртуальных методов параметра Self, чтобы его инициализировать.

Слайд 36

Вызов конструкторов и деструкторов. Если конструктор вызывается для размещения динамического объекта

Вызов конструкторов и деструкторов.

Если конструктор вызывается для размещения динамического объекта с

помощью расширенного синтаксиса стандартной процедуры New, через параметр Self передается указатель NIL.

Это заставляет конструктор размещать новый динамический объект, адрес которого передается вызывающей программе через DX:AX при возврате из конструктора.
Если конструктор не может разместить объект, то в DX:АХ возвращается пустой указатель NIL.

Слайд 37

Вызов конструкторов и деструкторов. Если конструктор вызывается с использованием собственного идентификатора

Вызов конструкторов и деструкторов.

Если конструктор вызывается с использованием собственного идентификатора метода


(т.е. идентификатора типа объекта, за которым следуют точка и идентификатор метода),
то в параметре таблицы виртуальных методов передается нулевое значение.

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