浏览代码

Add the offset to the reference count field relative to Self to the VMT (which works better than adding it to the RTTI).

rtl/inc/objpash.inc, TVmt:
  + add a SizeInt field "vRefCountOfs" after "vMsgStrPtr"
compiler/ncgvmt.pas, TVMTWriter:
  * writevmt: use "refcount_field" of the class instance to write the offset to the reference count field to the VMT or 0 if the class isn't reference counted
compiler/symdef.pas, tobjectdef:
  * vmtmethodoffset: adjust the offset by the new SizeInt field

git-svn-id: branches/svenbarth/arc@28809 -
svenbarth 10 年之前
父节点
当前提交
eef2c1652f
共有 3 个文件被更改,包括 16 次插入5 次删除
  1. 10 0
      compiler/ncgvmt.pas
  2. 5 5
      compiler/symdef.pas
  3. 1 0
      rtl/inc/objpash.inc

+ 10 - 0
compiler/ncgvmt.pas

@@ -808,6 +808,7 @@ implementation
 {$endif WITHDMT}
          interfacetable : tasmlabel;
          templist : TAsmList;
+         offsetsym : tfieldvarsym;
       begin
 {$ifdef WITHDMT}
          dmtlabel:=gendmt;
@@ -915,6 +916,15 @@ implementation
               current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(strmessagetable))
             else
               current_asmdata.asmlists[al_globals].concat(Tai_const.Create_nil_dataptr);
+            if oo_is_reference_counted in _class.objectoptions then
+              begin
+                offsetsym:=tfieldvarsym(_class.refcount_field);
+                if not assigned(offsetsym) or (offsetsym.typ<>fieldvarsym) then
+                  internalerror(2014101201);
+                current_asmdata.asmlists[al_globals].concat(Tai_const.Create(aitconst_ptr,offsetsym.fieldoffset));
+              end
+            else
+              current_asmdata.asmlists[al_globals].concat(Tai_const.Create(aitconst_ptr,0));
           end;
          { write virtual methods }
          writevirtualmethods(current_asmdata.asmlists[al_globals]);

+ 5 - 5
compiler/symdef.pas

@@ -6407,8 +6407,8 @@ implementation
         { for offset of methods for classes, see rtl/inc/objpash.inc }
         case objecttype of
         odt_class:
-          { the +2*sizeof(pint) is size and -size }
-          vmtmethodoffset:=index*voidcodepointertype.size+10*voidpointertype.size+2*sizeof(pint);
+          { the +3*sizeof(pint) is size, -size and refcount offset }
+          vmtmethodoffset:=index*voidcodepointertype.size+10*voidpointertype.size+3*sizeof(pint);
         odt_helper,
         odt_objcclass,
         odt_objcprotocol:
@@ -6420,11 +6420,11 @@ implementation
           { invalid }
           vmtmethodoffset:=-1;
         else
-          { the +2*sizeof(pint) is size and -size }
+          { the +3*sizeof(pint) is size, -size and refcount offset }
 {$ifdef WITHDMT}
-          vmtmethodoffset:=index*voidcodepointertype.size+2*voidpointertype.size+2*sizeof(pint);
+          vmtmethodoffset:=index*voidcodepointertype.size+2*voidpointertype.size+3*sizeof(pint);
 {$else WITHDMT}
-          vmtmethodoffset:=index*voidcodepointertype.size+1*voidpointertype.size+2*sizeof(pint);
+          vmtmethodoffset:=index*voidcodepointertype.size+1*voidpointertype.size+3*sizeof(pint);
 {$endif WITHDMT}
         end;
       end;

+ 1 - 0
rtl/inc/objpash.inc

@@ -110,6 +110,7 @@
          vAutoTable: Pointer;
          vIntfTable: PInterfaceTable;
          vMsgStrPtr: pstringmessagetable;
+         vRefCountOfs: SizeInt;
          vDestroy: CodePointer;
          vNewInstance: CodePointer;
          vFreeInstance: CodePointer;