objectformat: one word after mtable in object layout
authorBernhard Urban <lewurm@gmail.com>
Mon, 27 Aug 2012 11:10:17 +0000 (13:10 +0200)
committerBernhard Urban <lewurm@gmail.com>
Mon, 27 Aug 2012 11:10:17 +0000 (13:10 +0200)
also use ptrSize in ClassPool

Mate/ClassPool.hs
Mate/NativeSizes.hs
Mate/Strings.hs
Mate/X86CodeGen.hs
ffi/native.c

index 849f1a1f1d06be03e22216ffb63a1d79efa02b8d..c99478a17e0930a7c3bab71c6f70cf986d1739b6 100644 (file)
@@ -89,7 +89,8 @@ getObjectSize path = do
   -- TODO(bernhard): correct sizes for different types...
   let fsize = fromIntegral $ M.size $ ciFieldMap ci
   -- one slot for "method-table-ptr"
   -- TODO(bernhard): correct sizes for different types...
   let fsize = fromIntegral $ M.size $ ciFieldMap ci
   -- one slot for "method-table-ptr"
-  return $ (1 + fsize) * ptrSize
+  -- one slot for GC-data
+  return $ (2 + fsize) * ptrSize
 
 getStaticFieldAddr :: CPtrdiff -> IO CPtrdiff
 getStaticFieldAddr from = do
 
 getStaticFieldAddr :: CPtrdiff -> IO CPtrdiff
 getStaticFieldAddr from = do
@@ -137,7 +138,7 @@ readClass path = do
       -- TODO(bernhard): we have some duplicates in immap (i.e. some
       --                 entries have the same offset), so we could
       --                 save some memory here.
       -- TODO(bernhard): we have some duplicates in immap (i.e. some
       --                 entries have the same offset), so we could
       --                 save some memory here.
-      iftable <- mallocClassData ((4*) $ M.size immap)
+      iftable <- mallocClassData ((ptrSize*) $ M.size immap)
       let wn_iftable = fromIntegral $ ptrToIntPtr iftable :: NativeWord
       -- store interface-table at offset 0 in method-table
       pokeElemOff (intPtrToPtr $ fromIntegral mbase) 0 wn_iftable
       let wn_iftable = fromIntegral $ ptrToIntPtr iftable :: NativeWord
       -- store interface-table at offset 0 in method-table
       pokeElemOff (intPtrToPtr $ fromIntegral mbase) 0 wn_iftable
@@ -183,7 +184,7 @@ loadInterface path = do
       -- load map again, because there could be new entries now
       -- due to loading superinterfaces
       imap' <- getInterfaceMap
       -- load map again, because there could be new entries now
       -- due to loading superinterfaces
       imap' <- getInterfaceMap
-      let max_off = fromIntegral $ M.size immap * 4
+      let max_off = fromIntegral $ M.size immap * ptrSize
       -- create index of methods by this interface
       let mm = zipbase max_off (classMethods cfile)
 
       -- create index of methods by this interface
       let mm = zipbase max_off (classMethods cfile)
 
@@ -198,7 +199,7 @@ loadInterface path = do
       setInterfaceMethodMap $ M.fromList sm `M.union` M.fromList mm `M.union` immap
       setInterfaceMap $ M.insert path cfile imap'
   where
       setInterfaceMethodMap $ M.fromList sm `M.union` M.fromList mm `M.union` immap
       setInterfaceMap $ M.insert path cfile imap'
   where
-    zipbase base = zipWith (\x y -> (entry y, x + base)) [0,4..]
+    zipbase base = zipWith (\x y -> (entry y, x + base)) [0,ptrSize..]
     entry = getname path
     getname p y = p `B.append` methodName y `B.append` encode (methodSignature y)
 
     entry = getname path
     getname p y = p `B.append` methodName y `B.append` encode (methodSignature y)
 
@@ -210,14 +211,14 @@ calculateFields cf superclass = do
     let (sfields, ifields) = partition (S.member ACC_STATIC . fieldAccessFlags) (classFields cf)
 
     let sc_sm = getsupermap superclass ciStaticMap
     let (sfields, ifields) = partition (S.member ACC_STATIC . fieldAccessFlags) (classFields cf)
 
     let sc_sm = getsupermap superclass ciStaticMap
-    staticbase <- mallocClassData $ fromIntegral (length sfields) * 4
+    staticbase <- mallocClassData $ fromIntegral (length sfields) * ptrSize
     let sm = zipbase (fromIntegral $ ptrToIntPtr staticbase) sfields
     -- new fields "overwrite" old ones, if they have the same name
     let staticmap = sm `M.union` sc_sm
 
     let sc_im = getsupermap superclass ciFieldMap
     let sm = zipbase (fromIntegral $ ptrToIntPtr staticbase) sfields
     -- new fields "overwrite" old ones, if they have the same name
     let staticmap = sm `M.union` sc_sm
 
     let sc_im = getsupermap superclass ciFieldMap
-    -- "+ 4" for the method table pointer
-    let max_off = (4+) $ fromIntegral $ M.size sc_im * 4
+    -- "+ (2*ptrsize)" for the method table pointer and GC data
+    let max_off = (+ (2*ptrSize)) $ fromIntegral $ M.size sc_im * ptrSize
     let im = zipbase max_off ifields
     -- new fields "overwrite" old ones, if they have the same name
     let fieldmap = im `M.union` sc_im
     let im = zipbase max_off ifields
     -- new fields "overwrite" old ones, if they have the same name
     let fieldmap = im `M.union` sc_im
@@ -225,7 +226,7 @@ calculateFields cf superclass = do
     return (staticmap, fieldmap)
   where
     zipbase :: Int32 -> [Field Direct] -> FieldMap
     return (staticmap, fieldmap)
   where
     zipbase :: Int32 -> [Field Direct] -> FieldMap
-    zipbase base = foldr (\(x,y) -> M.insert (fieldName y) (x + base)) M.empty . zip [0,4..]
+    zipbase base = foldr (\(x,y) -> M.insert (fieldName y) (x + base)) M.empty . zip [0,ptrSize..]
 
 -- helper
 getsupermap :: Maybe ClassInfo -> (ClassInfo -> FieldMap) -> FieldMap
 
 -- helper
 getsupermap :: Maybe ClassInfo -> (ClassInfo -> FieldMap) -> FieldMap
@@ -239,14 +240,14 @@ calculateMethodMap cf superclass = do
                          ((/=) "<init>" . methodName) x)
                   (classMethods cf)
     let sc_mm = getsupermap superclass ciMethodMap
                          ((/=) "<init>" . methodName) x)
                   (classMethods cf)
     let sc_mm = getsupermap superclass ciMethodMap
-    let max_off = fromIntegral $ M.size sc_mm * 4
+    let max_off = fromIntegral $ M.size sc_mm * ptrSize
     let mm = zipbase max_off methods
     let methodmap = M.fromList mm `M.union` sc_mm
 
     -- (+1): one slot for the interface-table-ptr
     let mm = zipbase max_off methods
     let methodmap = M.fromList mm `M.union` sc_mm
 
     -- (+1): one slot for the interface-table-ptr
-    methodbase <- mallocClassData (((+1) $ fromIntegral $ M.size methodmap) * 4)
+    methodbase <- mallocClassData (((+1) $ fromIntegral $ M.size methodmap) * ptrSize)
     return (methodmap, fromIntegral $ ptrToIntPtr methodbase)
     return (methodmap, fromIntegral $ ptrToIntPtr methodbase)
-  where zipbase base = zipWith (\x y -> (entry y, x + base)) [0,4..]
+  where zipbase base = zipWith (\x y -> (entry y, x + base)) [0,ptrSize..]
           where entry y = methodName y `B.append` encode (methodSignature y)
 
 
           where entry y = methodName y `B.append` encode (methodSignature y)
 
 
index 5e8795b46f158967db8d2e8ee72bdadbee7da25c..57e5a0a3d01abf158a9ac8eabb7a778f49042c23 100644 (file)
@@ -3,7 +3,7 @@ module Mate.NativeSizes where
 
 import Data.Word
 
 
 import Data.Word
 
-ptrSize, longSize :: NativeWord
+ptrSize, longSize :: Num a => a
 #if defined(ARCH_X86)
 ptrSize = 4
 longSize = 8
 #if defined(ARCH_X86)
 ptrSize = 4
 longSize = 8
index bb2bc8907f71139a9cfd2c712c70e93a7a03dd3a..254adb2283628f8e65d255d0f605350c5cc3dd7e 100644 (file)
@@ -37,11 +37,11 @@ allocateJavaString str = do
    -  this -+
    -        |
    -        v
    -  this -+
    -        |
    -        v
-   -  +-------------+-------+-------+----------------+--------+
-   -  | MethodTable | value | count | cachedhashcode | offset |
-   -  +-------------+-------+-------+----------------+--------+
-   -        |           |
-   -        |           +------------+
+   -  +-------------+---------+-------+-------+----------------+--------+
+   -  | MethodTable | GC Data | value | count | cachedhashcode | offset |
+   -  +-------------+---------+-------+-------+----------------+--------+
+   -        |                     |
+   -        |                     +--+
    -        v                        v
    -  java/lang/String           +--------+--------+--------+-----+------------------+
    -                             | length | str[0] | str[1] | ... | str [length - 1] |
    -        v                        v
    -  java/lang/String           +--------+--------+--------+-----+------------------+
    -                             | length | str[0] | str[1] | ... | str [length - 1] |
@@ -51,7 +51,7 @@ allocateJavaString str = do
    -}
   -- build object layout
   fsize <- getObjectSize "java/lang/String"
    -}
   -- build object layout
   fsize <- getObjectSize "java/lang/String"
-  printfStr $ printf "string: fsize: %d (should be 4 * 5)\n" fsize
+  printfStr $ printf "string: fsize: %d (should be 4 * 6)\n" fsize
   tblptr <- mallocObjectUnmanaged $ fromIntegral fsize
   let ptr = intPtrToPtr (fromIntegral tblptr) :: Ptr CPtrdiff
   mtbl <- getMethodTable "java/lang/String"
   tblptr <- mallocObjectUnmanaged $ fromIntegral fsize
   let ptr = intPtrToPtr (fromIntegral tblptr) :: Ptr CPtrdiff
   mtbl <- getMethodTable "java/lang/String"
@@ -69,13 +69,15 @@ allocateJavaString str = do
   let newstr_length = castPtr newstr :: Ptr CPtrdiff
   poke newstr_length $ fromIntegral strlen
 
   let newstr_length = castPtr newstr :: Ptr CPtrdiff
   poke newstr_length $ fromIntegral strlen
 
+  -- set GC Data (TODO)
+  poke (plusPtr ptr 0x4) (0 :: CPtrdiff)
   -- set value pointer
   -- set value pointer
-  poke (plusPtr ptr 4) (fromIntegral (ptrToIntPtr newstr) :: CPtrdiff)
+  poke (plusPtr ptr 0x8) (fromIntegral (ptrToIntPtr newstr) :: CPtrdiff)
   -- set count field
   -- set count field
-  poke (plusPtr ptr 8) (fromIntegral strlen :: CPtrdiff)
+  poke (plusPtr ptr 0xc) (fromIntegral strlen :: CPtrdiff)
   -- set hash code (TODO)
   -- set hash code (TODO)
-  poke (plusPtr ptr 12) (0 :: CPtrdiff)
+  poke (plusPtr ptr 0x10) (0 :: CPtrdiff)
   -- set offset
   -- set offset
-  poke (plusPtr ptr 16) (0 :: CPtrdiff)
+  poke (plusPtr ptr 0x14) (0 :: CPtrdiff)
 
   return $ fromIntegral tblptr
 
   return $ fromIntegral tblptr
index 9abe1f4cb0ff17bd9b9ca46787cb4fe4f1ca52dc..1097e8565035257771068e76e3b9291ae0819c68 100644 (file)
@@ -11,6 +11,7 @@ import Data.List (genericLength)
 import qualified Data.Map as M
 import qualified Data.ByteString.Lazy as B
 import Control.Monad
 import qualified Data.Map as M
 import qualified Data.ByteString.Lazy as B
 import Control.Monad
+import Control.Applicative
 
 import Foreign hiding (xor)
 import Foreign.C.Types
 
 import Foreign hiding (xor)
 import Foreign.C.Types
@@ -178,8 +179,8 @@ emitFromBB cls method = do
       emit32 (0x9090ffff :: Word32); nop; nop
       let patcher reip = do
             let (cname, fname) = buildFieldOffset cls x
       emit32 (0x9090ffff :: Word32); nop; nop
       let patcher reip = do
             let (cname, fname) = buildFieldOffset cls x
-            offset <- liftIO $ getFieldOffset cname fname
-            push32_rel_eax (Disp (fromIntegral offset)) -- get field
+            offset <- liftIO $ fromIntegral <$> getFieldOffset cname fname
+            push32_rel_eax (Disp offset) -- get field
             return reip
       return $ Just (trapaddr, ObjectField patcher)
     emit' (PUTFIELD x) = do
             return reip
       return $ Just (trapaddr, ObjectField patcher)
     emit' (PUTFIELD x) = do
@@ -190,8 +191,8 @@ emitFromBB cls method = do
       emit32 (0x9090ffff :: Word32); nop; nop
       let patcher reip = do
             let (cname, fname) = buildFieldOffset cls x
       emit32 (0x9090ffff :: Word32); nop; nop
       let patcher reip = do
             let (cname, fname) = buildFieldOffset cls x
-            offset <- liftIO $ getFieldOffset cname fname
-            mov32_rel_ebx_eax (Disp (fromIntegral offset)) -- set field
+            offset <- liftIO $ fromIntegral <$> getFieldOffset cname fname
+            mov32_rel_ebx_eax (Disp offset) -- set field
             return reip
       return $ Just (trapaddr, ObjectField patcher)
 
             return reip
       return $ Just (trapaddr, ObjectField patcher)
 
@@ -215,12 +216,14 @@ emitFromBB cls method = do
       callMalloc
       -- 0x13371337 is just a placeholder; will be replaced with mtable ptr
       mov (Disp 0, eax) (0x13371337 :: Word32)
       callMalloc
       -- 0x13371337 is just a placeholder; will be replaced with mtable ptr
       mov (Disp 0, eax) (0x13371337 :: Word32)
+      mov (Disp 4, eax) (0x1337babe :: Word32)
       let patcher reip = do
             objsize <- liftIO $ getObjectSize objname
             push32 objsize
             callMalloc
             mtable <- liftIO $ getMethodTable objname
             mov (Disp 0, eax) mtable
       let patcher reip = do
             objsize <- liftIO $ getObjectSize objname
             push32 objsize
             callMalloc
             mtable <- liftIO $ getMethodTable objname
             mov (Disp 0, eax) mtable
+            mov (Disp 4, eax) (0x1337babe :: Word32)
             return reip
       return $ Just (trapaddr, NewObject patcher)
 
             return reip
       return $ Just (trapaddr, NewObject patcher)
 
index 7374405b7fbe172c8384494d9f88615707e8dfab..45964b77f701a067273b3cb945e8b4d9d402e885 100644 (file)
@@ -48,11 +48,13 @@ void java_io_PrintStream__printf___I_V(int a)
 
 struct integer {
        unsigned int method_table_ptr;
 
 struct integer {
        unsigned int method_table_ptr;
+       unsigned int gc_data;
        int value;
 };
 
 struct string {
        unsigned int method_table_ptr;
        int value;
 };
 
 struct string {
        unsigned int method_table_ptr;
+       unsigned int gc_data;
        struct chararray *value;
 };
 
        struct chararray *value;
 };