瀏覽代碼

* use separate pools for obj-c strings and string references

git-svn-id: branches/objc@13670 -
Jonas Maebe 16 年之前
父節點
當前提交
ab8e119c3e
共有 6 個文件被更改,包括 81 次插入47 次删除
  1. 1 0
      .gitattributes
  2. 4 3
      compiler/aasmdata.pas
  3. 4 4
      compiler/ncgmem.pas
  4. 4 4
      compiler/ncgobjc.pas
  5. 38 36
      compiler/objcgutl.pas
  6. 30 0
      tests/test/tobjc17.pp

+ 1 - 0
.gitattributes

@@ -8224,6 +8224,7 @@ tests/test/tobjc13.pp svneol=native#text/plain
 tests/test/tobjc14.pp svneol=native#text/plain
 tests/test/tobjc15.pp svneol=native#text/plain
 tests/test/tobjc16.pp svneol=native#text/plain
+tests/test/tobjc17.pp svneol=native#text/plain
 tests/test/tobjc2.pp svneol=native#text/plain
 tests/test/tobjc3.pp svneol=native#text/plain
 tests/test/tobjc4.pp svneol=native#text/plain

+ 4 - 3
compiler/aasmdata.pas

@@ -82,10 +82,11 @@ interface
          sp_ansistr,
          sp_widestr,
          sp_unicodestr,
-         sp_objcmetaclass,
+         sp_objcclassnamerefs,
+         sp_varnamerefs,
+         sp_objcclassnames,
          sp_objcvarnames,
-         sp_objcvartypes,
-         sp_objcclassnames
+         sp_objcvartypes
       );
       
     const

+ 4 - 4
compiler/ncgmem.pas

@@ -115,12 +115,12 @@ implementation
              else
                begin
                  { find/add necessary classref/classname pool entries }
-                 if current_asmdata.ConstPools[sp_objcmetaclass]=nil then
-                   current_asmdata.ConstPools[sp_objcmetaclass]:=THashSet.Create(64, True, False);
-                 pool:=current_asmdata.ConstPools[sp_objcmetaclass];
+                 if current_asmdata.ConstPools[sp_objcclassnamerefs]=nil then
+                   current_asmdata.ConstPools[sp_objcclassnamerefs]:=THashSet.Create(64, True, False);
+                 pool:=current_asmdata.ConstPools[sp_objcclassnamerefs];
                  typename:=left.resultdef.gettypename;
                  entry:=pool.FindOrAdd(@typename[1],length(typename));
-                 objcfinishstringrefpoolentry(entry,sec_objc_cls_refs,sec_objc_class_names);
+                 objcfinishstringrefpoolentry(entry,sp_objcclassnames,sec_objc_cls_refs,sec_objc_class_names);
                  reference_reset_symbol(href,tasmlabel(entry^.Data),0,sizeof(pint));
                  cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,location.register);
                end;

+ 4 - 4
compiler/ncgobjc.pas

@@ -61,9 +61,9 @@ procedure tcgobjcselectornode.pass_generate_code;
     name   : pshortstring;
     pc     : pchar;
   begin
-    if current_asmdata.ConstPools[sp_objcvarnames]=nil then
-      current_asmdata.ConstPools[sp_objcvarnames]:=THashSet.Create(64, True, False);
-    pool:=current_asmdata.ConstPools[sp_objcvarnames];
+    if current_asmdata.ConstPools[sp_varnamerefs]=nil then
+      current_asmdata.ConstPools[sp_varnamerefs]:=THashSet.Create(64, True, False);
+    pool:=current_asmdata.ConstPools[sp_varnamerefs];
 
     case left.nodetype of
       loadn:
@@ -83,7 +83,7 @@ procedure tcgobjcselectornode.pass_generate_code;
         internalerror(2009030701);
     end;
 
-    objcfinishstringrefpoolentry(entry,sec_objc_message_refs,sec_objc_meth_var_names);
+    objcfinishstringrefpoolentry(entry,sp_objcvarnames,sec_objc_message_refs,sec_objc_meth_var_names);
 
     location_reset_ref(location,LOC_CREFERENCE,def_cgsize(resultdef),sizeof(pint));
     location.reference.symbol:=tasmlabel(entry^.Data);

+ 38 - 36
compiler/objcgutl.pas

@@ -29,10 +29,10 @@ interface
 
   uses
     cclasses,
-    aasmbase,
+    aasmbase,aasmdata,
     symbase;
 
-  procedure objcfinishstringrefpoolentry(entry: phashsetitem; refsec, stringsec: tasmsectiontype);
+  procedure objcfinishstringrefpoolentry(entry: phashsetitem; stringpool: tconstpooltype; refsec, stringsec: tasmsectiontype);
 
   procedure MaybeGenerateObjectiveCImageInfo(globalst, localst: tsymtable);
 
@@ -42,7 +42,7 @@ implementation
   uses
     globtype,globals,
     systems,
-    aasmdata,aasmtai,
+    aasmtai,
     cgbase,cgutils,
     objcutil,
     symconst,symtype,symsym,symdef,symtable,
@@ -53,38 +53,7 @@ implementation
                        String section helpers
 *******************************************************************}
 
-procedure objcfinishstringrefpoolentry(entry: phashsetitem; refsec, stringsec: tasmsectiontype);
-  var
-    reflab,
-    strlab : tasmlabel;
-    pc     : pchar;
-  begin
-    { have we already generated this selector? }
-    if not assigned(entry^.Data) then
-      begin
-        { create new one
-          (no getdatalabel, because these labels have to be local)
-        }
-        current_asmdata.getlabel(reflab,alt_data);
-        current_asmdata.getlabel(strlab,alt_data);
-        entry^.Data:=reflab;
-        getmem(pc,entry^.keylength+1);
-        move(entry^.key^,pc^,entry^.keylength);
-        pc[entry^.keylength]:=#0;
-        { add a pointer to the message name in the string references section }
-        new_section(current_asmdata.asmlists[al_objc_pools],refsec,reflab.name,sizeof(pint));
-        current_asmdata.asmlists[al_objc_pools].concat(Tai_label.Create(reflab));
-        current_asmdata.asmlists[al_objc_pools].concat(Tai_const.Create_sym(strlab));
-
-        { and now add the message name to the associated strings section }
-        new_section(current_asmdata.asmlists[al_objc_pools],stringsec,strlab.name,sizeof(pint));
-        current_asmdata.asmlists[al_objc_pools].concat(Tai_label.Create(strlab));
-        current_asmdata.asmlists[al_objc_pools].concat(Tai_string.Create_pchar(pc,entry^.keylength+1));
-    end;
-  end;
-
-
-function objcreatestringpoolentry(const s: string; pooltype: tconstpooltype; stringsec: tasmsectiontype): TAsmSymbol;
+function objcreatestringpoolentryintern(p: pchar; len: longint; pooltype: tconstpooltype; stringsec: tasmsectiontype): TAsmSymbol;
   var
     entry  : PHashSetItem;
     strlab : tasmlabel;
@@ -95,7 +64,7 @@ function objcreatestringpoolentry(const s: string; pooltype: tconstpooltype; str
        current_asmdata.ConstPools[pooltype]:=THashSet.Create(64, True, False);
     pool := current_asmdata.constpools[pooltype];
 
-    entry:=pool.FindOrAdd(@s[1],length(s));
+    entry:=pool.FindOrAdd(p,len);
     if not assigned(entry^.data) then
       begin
         { create new entry }
@@ -116,6 +85,39 @@ function objcreatestringpoolentry(const s: string; pooltype: tconstpooltype; str
   end;
 
 
+procedure objcfinishstringrefpoolentry(entry: phashsetitem; stringpool: tconstpooltype; refsec, stringsec: tasmsectiontype);
+  var
+    reflab : tasmlabel;
+    strlab : tasmsymbol;
+    pc     : pchar;
+  begin
+    { have we already generated a reference for this string entry? }
+    if not assigned(entry^.Data) then
+      begin
+        { no, add the string to the associated strings section }
+        strlab:=objcreatestringpoolentryintern(pchar(entry^.key),entry^.keylength,stringpool,stringsec);
+
+        { and now finish the reference }
+        current_asmdata.getlabel(reflab,alt_data);
+        entry^.Data:=reflab;
+        getmem(pc,entry^.keylength+1);
+        move(entry^.key^,pc^,entry^.keylength);
+        pc[entry^.keylength]:=#0;
+        { add a pointer to the message name in the string references section }
+        new_section(current_asmdata.asmlists[al_objc_pools],refsec,reflab.name,sizeof(pint));
+        current_asmdata.asmlists[al_objc_pools].concat(Tai_label.Create(reflab));
+        current_asmdata.asmlists[al_objc_pools].concat(Tai_const.Create_sym(strlab));
+    end;
+  end;
+
+
+
+function objcreatestringpoolentry(const s: string; pooltype: tconstpooltype; stringsec: tasmsectiontype): TAsmSymbol;
+  begin
+    result:=objcreatestringpoolentryintern(@s[1],length(s),pooltype,stringsec);
+  end;
+
+
 {******************************************************************
                         RTTI generation
 *******************************************************************}

+ 30 - 0
tests/test/tobjc17.pp

@@ -0,0 +1,30 @@
+{ %target=darwin }
+{ %cpu=powerpc,i386 }
+
+program project1;
+
+{$mode objfpc}{$H+}
+{$modeswitch objectivec1}
+type
+ MyObject = objcclass(NSObject)
+ private
+   data : Integer;
+ public
+   procedure setData_(aData: Integer); message 'setData:';
+ end;
+
+procedure MyObject.setData_(aData: Integer);
+begin
+ data := aData;
+end;
+
+var
+ m : MyObject;
+
+begin
+ m := MyObject.alloc;
+ m.setData_(5);
+ if (m.data<>5) then
+   halt(1);
+ m.release;
+end.