Browse Source

* Get rid of using pdynarraytypeinfo, instead treat rtti as distinct 'header' and 'data' parts. In variants unit, use rtti declarations from typinfo directly. In system unit, declare private tdynarraytypedata record which (like typinfo.TTypeData) is not packed on alignment-sensitive targets. This simplifies code and removes scary pointer manipulations, should also yield better code on aligned targets.

git-svn-id: trunk@20106 -
sergei 13 years ago
parent
commit
a8fe9601de
2 changed files with 36 additions and 54 deletions
  1. 24 26
      rtl/inc/dynarr.inc
  2. 12 28
      rtl/inc/variants.pp

+ 24 - 26
rtl/inc/dynarr.inc

@@ -24,6 +24,16 @@ type
       high : tdynarrayindex;
       high : tdynarrayindex;
    end;
    end;
 
 
+   pdynarraytypedata = ^tdynarraytypedata;
+   tdynarraytypedata =
+{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
+   packed
+{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
+   record
+     elSize : PtrUInt;
+     elType2 : Pointer;
+     varType : Longint;
+   end;
 
 
 procedure fpc_dynarray_rangecheck(p : pointer;i : tdynarrayindex);[Public,Alias:'FPC_DYNARRAY_RANGECHECK']; compilerproc;
 procedure fpc_dynarray_rangecheck(p : pointer;i : tdynarrayindex);[Public,Alias:'FPC_DYNARRAY_RANGECHECK']; compilerproc;
   begin
   begin
@@ -52,21 +62,15 @@ function fpc_dynarray_high(p : pointer) : tdynarrayindex;[Public,Alias:'FPC_DYNA
 
 
 { releases and finalizes the data of a dyn. array and sets p to nil }
 { releases and finalizes the data of a dyn. array and sets p to nil }
 procedure fpc_dynarray_clear_internal(p : pointer;ti : pointer);
 procedure fpc_dynarray_clear_internal(p : pointer;ti : pointer);
-  var
-    eletype : pdynarraytypeinfo;
   begin
   begin
      if p=nil then
      if p=nil then
        exit;
        exit;
 
 
      { skip kind and name }
      { skip kind and name }
-     inc(pointer(ti),ord(pdynarraytypeinfo(ti)^.namelen)+2);
-
-     ti:=aligntoptr(ti);
-
-     eletype:=pdynarraytypeinfo(pointer(pdynarraytypeinfo(pointer(ti)+sizeof(sizeint)))^);
+     ti:=aligntoptr(ti+2+PByte(ti)[1]);
 
 
      { finalize all data }
      { finalize all data }
-     int_finalizearray(p+sizeof(tdynarray),eletype,pdynarray(p)^.high+1);
+     int_finalizearray(p+sizeof(tdynarray),pdynarraytypedata(ti)^.elType2,pdynarray(p)^.high+1);
 
 
      { release the data }
      { release the data }
      freemem(p);
      freemem(p);
@@ -104,7 +108,7 @@ procedure fpc_dynarray_decr_ref(var p : pointer;ti : pointer); [Public,Alias:'FP
      { should we remove the array? }
      { should we remove the array? }
      if declocked(realp^.refcount) then
      if declocked(realp^.refcount) then
        begin
        begin
-         fpc_dynarray_clear_internal(realp,pdynarraytypeinfo(ti));
+         fpc_dynarray_clear_internal(realp,ti);
          p := nil;
          p := nil;
        end;
        end;
   end;
   end;
@@ -144,21 +148,17 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
      { contains the "fixed" pointers where the refcount }
      { contains the "fixed" pointers where the refcount }
      { and high are at positive offsets                 }
      { and high are at positive offsets                 }
      realp,newp : pdynarray;
      realp,newp : pdynarray;
-     ti : pdynarraytypeinfo;
+     ti : pointer;
      updatep: boolean;
      updatep: boolean;
      elesize : sizeint;
      elesize : sizeint;
-     eletype : pdynarraytypeinfo;
+     eletype : pointer;
 
 
   begin
   begin
-     ti:=pdynarraytypeinfo(pti);
-
      { skip kind and name }
      { skip kind and name }
-     inc(pointer(ti),ord(pdynarraytypeinfo(ti)^.namelen)+2);
-
-     ti:=aligntoptr(ti);
+     ti:=aligntoptr(Pointer(pti)+2+PByte(pti)[1]);
 
 
-     elesize:=psizeint(ti)^;
-     eletype:=pdynarraytypeinfo(pointer(pdynarraytypeinfo(pointer(ti)+sizeof(sizeint)))^);
+     elesize:=pdynarraytypedata(ti)^.elSize;
+     eletype:=pdynarraytypedata(ti)^.elType2;
 
 
      { determine new memory size }
      { determine new memory size }
      size:=elesize*dims[0]+sizeof(tdynarray);
      size:=elesize*dims[0]+sizeof(tdynarray);
@@ -187,7 +187,7 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
                if dims[0]<0 then
                if dims[0]<0 then
                  HandleErrorFrame(201,get_frame);
                  HandleErrorFrame(201,get_frame);
                if declocked(realp^.refcount) then
                if declocked(realp^.refcount) then
-                 fpc_dynarray_clear_internal(realp,pdynarraytypeinfo(pti));
+                 fpc_dynarray_clear_internal(realp,pti);
                p:=nil;
                p:=nil;
                exit;
                exit;
             end;
             end;
@@ -217,7 +217,7 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
                { if the array is now removed             }
                { if the array is now removed             }
                { fpc_dynarray_decr_ref(p,ti); }
                { fpc_dynarray_decr_ref(p,ti); }
                if declocked(realp^.refcount) then
                if declocked(realp^.refcount) then
-                 fpc_dynarray_clear_internal(realp,pdynarraytypeinfo(ti));
+                 fpc_dynarray_clear_internal(realp,pti);
             end
             end
           else if dims[0]<>realp^.high+1 then
           else if dims[0]<>realp^.high+1 then
             begin
             begin
@@ -282,7 +282,7 @@ function fpc_dynarray_copy(psrc : pointer;ti : pointer;
     i,size : longint;
     i,size : longint;
     highidx : tdynarrayindex;
     highidx : tdynarrayindex;
     elesize : sizeint;
     elesize : sizeint;
-    eletype : pdynarraytypeinfo;
+    eletype : pointer;
     pdest : pointer;
     pdest : pointer;
   begin
   begin
      highidx:=lowidx+count-1;
      highidx:=lowidx+count-1;
@@ -292,12 +292,10 @@ function fpc_dynarray_copy(psrc : pointer;ti : pointer;
        exit;
        exit;
      realpsrc:=pdynarray(psrc-sizeof(tdynarray));
      realpsrc:=pdynarray(psrc-sizeof(tdynarray));
      { skip kind and name }
      { skip kind and name }
-     inc(pointer(ti),ord(pdynarraytypeinfo(ti)^.namelen)+2);
-
-     ti:=aligntoptr(ti);
+     ti:=aligntoptr(ti+2+PByte(ti)[1]);
 
 
-     elesize:=psizeint(ti)^;
-     eletype:=pdynarraytypeinfo(pointer(pdynarraytypeinfo(pointer(ti)+sizeof(sizeint)))^);
+     elesize:=pdynarraytypedata(ti)^.elSize;
+     eletype:=pdynarraytypedata(ti)^.elType2;
 
 
      { -1, -1 (highidx=lowidx-1-1=-3) is used to copy the whole array like a:=copy(b);, so
      { -1, -1 (highidx=lowidx-1-1=-3) is used to copy the whole array like a:=copy(b);, so
        update the lowidx and highidx with the values from psrc }
        update the lowidx and highidx with the values from psrc }

+ 12 - 28
rtl/inc/variants.pp

@@ -511,13 +511,13 @@ type
     positions : tdynarraypositions;
     positions : tdynarraypositions;
     Dims : SizeInt;
     Dims : SizeInt;
     data : Pointer;
     data : Pointer;
-    constructor init(d : Pointer;p : pdynarraytypeinfo;_dims: SizeInt;b : tdynarraybounds);
+    constructor init(d : Pointer;typeInfo : Pointer;_dims: SizeInt;b : tdynarraybounds);
     function next : Boolean;
     function next : Boolean;
     destructor done;
     destructor done;
   end;
   end;
 
 
 
 
-constructor tdynarrayiter.init(d : Pointer;p : pdynarraytypeinfo;_dims: SizeInt;b : tdynarraybounds);
+constructor tdynarrayiter.init(d : Pointer;typeInfo : Pointer;_dims: SizeInt;b : tdynarraybounds);
   var
   var
     i : sizeint;
     i : sizeint;
   begin
   begin
@@ -534,16 +534,10 @@ constructor tdynarrayiter.init(d : Pointer;p : pdynarraytypeinfo;_dims: SizeInt;
         if i>0 then
         if i>0 then
           positions[i]:=Pointer(positions[i-1]^);
           positions[i]:=Pointer(positions[i-1]^);
         { skip kind and name }
         { skip kind and name }
-        inc(Pointer(p),ord(pdynarraytypeinfo(p)^.namelen)+2);
+        typeInfo:=aligntoptr(typeInfo+2+Length(PTypeInfo(typeInfo)^.Name));
 
 
-        p:=AlignToPtr(p);
-
-        elesize[i]:=psizeint(p)^;
-
-        { skip elesize }
-        inc(Pointer(p),SizeOf(sizeint));
-
-        p:=pdynarraytypeinfo(ppointer(p)^);
+        elesize[i]:=PTypeData(typeInfo)^.elSize;
+        typeInfo:=PTypeData(typeInfo)^.elType2;
       end;
       end;
     data:=positions[Dims-1];
     data:=positions[Dims-1];
   end;
   end;
@@ -819,12 +813,11 @@ begin
 
 
   { get TypeInfo of second level }
   { get TypeInfo of second level }
   { skip kind and name }
   { skip kind and name }
-  inc(Pointer(TypeInfo),ord(pdynarraytypeinfo(TypeInfo)^.namelen)+2);
-  TypeInfo:=AlignToPtr(TypeInfo);
-  TypeInfo:=ppointer(TypeInfo+SizeOf(sizeint))^;
+  TypeInfo:=aligntoptr(TypeInfo+2+Length(PTypeInfo(TypeInfo)^.Name));
+  TypeInfo:=PTypeData(TypeInfo)^.elType2;
 
 
   { check recursively? }
   { check recursively? }
-  if assigned(pdynarraytypeinfo(TypeInfo)) and (pdynarraytypeinfo(TypeInfo)^.kind=byte(tkDynArray)) then
+  if assigned(TypeInfo) and (PTypeInfo(TypeInfo)^.kind=tkDynArray) then
     begin
     begin
       { set to dimension of first element }
       { set to dimension of first element }
       arraysize:=psizeint(ppointer(p)^-SizeOf(sizeint))^;
       arraysize:=psizeint(ppointer(p)^-SizeOf(sizeint))^;
@@ -3371,22 +3364,13 @@ function DynArrayGetVariantInfo(p : Pointer; var Dims : sizeint) : sizeint;
   begin
   begin
     Result:=varNull;
     Result:=varNull;
     { skip kind and name }
     { skip kind and name }
-    inc(Pointer(p),ord(pdynarraytypeinfo(p)^.namelen)+2);
-
-    p:=AlignToPtr(p);
-
-    { skip elesize }
-    inc(p,SizeOf(sizeint));
+    p:=aligntoptr(p+2+Length(PTypeInfo(p)^.Name));
 
 
     { search recursive? }
     { search recursive? }
-    if pdynarraytypeinfo(ppointer(p)^)^.kind=21{tkDynArr} then
-      Result:=DynArrayGetVariantInfo(ppointer(p)^,Dims)
+    if PTypeInfo(PTypeData(p)^.elType2)^.kind=tkDynArray then
+      Result:=DynArrayGetVariantInfo(PTypeData(p)^.elType2,Dims)
     else
     else
-      begin
-        { skip dynarraytypeinfo }
-        inc(p,SizeOf(pdynarraytypeinfo));
-        Result:=plongint(p)^;
-      end;
+      Result:=PTypeData(p)^.varType;
     inc(Dims);
     inc(Dims);
   end;
   end;