From da245b03d80644c22b011acba31acacb880d8327 Mon Sep 17 00:00:00 2001 From: Bernhard Urban Date: Tue, 31 Jul 2012 22:22:28 +0200 Subject: [PATCH] maxlocals: store it in new data type RawMethod, with MapBB & Co we need that information, in order to reserve enough memory on the stack (was hardcoded so far) --- Mate/BasicBlocks.hs | 29 ++++++++++++++++++----------- Mate/ClassPool.hs | 8 ++++---- Mate/MethodPool.hs | 7 ++++--- Mate/MethodPool.hs-boot | 2 +- Mate/Types.hs | 4 ++++ Mate/X86CodeGen.hs | 13 +++++++------ 6 files changed, 38 insertions(+), 25 deletions(-) diff --git a/Mate/BasicBlocks.hs b/Mate/BasicBlocks.hs index fbb61f7..2a8ac22 100644 --- a/Mate/BasicBlocks.hs +++ b/Mate/BasicBlocks.hs @@ -3,9 +3,10 @@ #include "debug.h" module Mate.BasicBlocks( BlockID, - BasicBlock (..), - BBEnd (..), + BasicBlock, + BBEnd, MapBB, + Method, #ifdef DBG_BB printMapBB, #endif @@ -37,9 +38,8 @@ type OffIns = (Offset, Instruction) #ifdef DBG_BB -printMapBB :: Maybe MapBB -> IO () -printMapBB Nothing = putStrLn "No BasicBlock" -printMapBB (Just hmap) = do +printMapBB :: MapBB -> IO () +printMapBB hmap = do putStr "BlockIDs: " let keys = M.keys hmap mapM_ (putStr . (flip (++)) ", " . show) keys @@ -87,13 +87,15 @@ test_04 = testInstance "./tests/Fac.class" "fac" #endif -parseMethod :: Class Direct -> B.ByteString -> MethodSignature -> IO (Maybe MapBB) +parseMethod :: Class Direct -> B.ByteString -> MethodSignature -> IO (Maybe RawMethod) parseMethod cls method sig = do let maybe_bb = testCFG $ lookupMethodSig method sig cls let msig = methodSignature $ classMethods cls !! 1 printfBb "BB: analysing \"%s\"\n" $ toString (method `B.append` ": " `B.append` encode msig) #ifdef DBG_BB - printMapBB maybe_bb + case maybe_bb of + Just m -> printMapBB $ rawMapBB m + Nothing -> return () #endif -- small example how to get information about -- exceptions of a method @@ -101,15 +103,20 @@ parseMethod cls method sig = do let (Just m) = lookupMethodSig method sig cls case attrByName m "Code" of Nothing -> printfBb "exception: no handler for this method\n" - Just exceptionstream -> printfBb "exception: \"%s\"\n" (show $ codeExceptions $ decodeMethod exceptionstream) + Just exceptionstream -> do + printfBb "exception: \"%s\"\n" (show $ codeExceptions $ decodeMethod exceptionstream) return maybe_bb -testCFG :: Maybe (Method Direct) -> Maybe MapBB +testCFG :: Maybe (Method Direct) -> Maybe RawMethod testCFG m = do m' <- m - bytecode <- attrByName m' "Code" - return $ buildCFG $ codeInstructions $ decodeMethod bytecode + codeseg <- attrByName m' "Code" + let decoded = decodeMethod codeseg + let mapbb = buildCFG $ codeInstructions decoded + let locals = fromIntegral (codeMaxLocals decoded) + let stacks = fromIntegral (codeStackSize decoded) + return $ RawMethod mapbb locals stacks buildCFG :: [Instruction] -> MapBB diff --git a/Mate/ClassPool.hs b/Mate/ClassPool.hs index 8788e75..ae6ce44 100644 --- a/Mate/ClassPool.hs +++ b/Mate/ClassPool.hs @@ -254,11 +254,11 @@ loadAndInitClass path = do -- execute class initializer case lookupMethod "" (ciFile ci) of Just m -> do - hmap <- parseMethod (ciFile ci) "" $ MethodSignature [] ReturnsVoid - case hmap of - Just hmap' -> do + method <- parseMethod (ciFile ci) "" $ MethodSignature [] ReturnsVoid + case method of + Just rawmethod -> do let mi = MethodInfo "" path (methodSignature m) - entry <- compileBB hmap' mi + entry <- compileBB rawmethod mi addMethodRef entry mi [path] printfCp "executing static initializer from %s now\n" (toString path) executeFuncPtr entry diff --git a/Mate/MethodPool.hs b/Mate/MethodPool.hs index 7f0779c..508ff11 100644 --- a/Mate/MethodPool.hs +++ b/Mate/MethodPool.hs @@ -131,18 +131,19 @@ addMethodRef entry (MethodInfo mmname _ msig) clsnames = do setMethodMap $ mmap `M.union` newmap -compileBB :: MapBB -> MethodInfo -> IO Word32 -compileBB hmap methodinfo = do +compileBB :: RawMethod -> MethodInfo -> IO Word32 +compileBB rawmethod methodinfo = do tmap <- getTrapMap cls <- getClassFile (methClassName methodinfo) - let ebb = emitFromBB (methName methodinfo) (methSignature methodinfo) cls hmap + let ebb = emitFromBB (methName methodinfo) (methSignature methodinfo) cls rawmethod (_, Right right) <- runCodeGen ebb () () let ((entry, _, _, new_tmap), _) = right setTrapMap $ tmap `M.union` new_tmap -- prefers elements in tmap printfJit "generated code of \"%s\" from \"%s\":\n" (toString $ methName methodinfo) (toString $ methClassName methodinfo) + printfJit "\tstacksize: 0x%04x, locals: 0x%04x\n" (rawStackSize rawmethod) (rawLocals rawmethod) mapM_ (printfJit "%s\n" . showAtt) (snd right) printfJit "\n\n" -- UNCOMMENT NEXT LINES FOR GDB FUN diff --git a/Mate/MethodPool.hs-boot b/Mate/MethodPool.hs-boot index f17cfb4..9392619 100644 --- a/Mate/MethodPool.hs-boot +++ b/Mate/MethodPool.hs-boot @@ -9,5 +9,5 @@ import Mate.Types addMethodRef :: Word32 -> MethodInfo -> [B.ByteString] -> IO () -compileBB :: MapBB -> MethodInfo -> IO Word32 +compileBB :: RawMethod -> MethodInfo -> IO Word32 executeFuncPtr :: Word32 -> IO () diff --git a/Mate/Types.hs b/Mate/Types.hs index dbf7e73..1978bb3 100644 --- a/Mate/Types.hs +++ b/Mate/Types.hs @@ -25,6 +25,10 @@ data BBEnd = Return | FallThrough BlockID | OneTarget BlockID | TwoTarget BlockI type MapBB = M.Map BlockID BasicBlock +data RawMethod = RawMethod { + rawMapBB :: MapBB, + rawLocals :: Int, + rawStackSize :: Int } -- Word32 = point of method call in generated code diff --git a/Mate/X86CodeGen.hs b/Mate/X86CodeGen.hs index 8b3c39f..c2c336f 100644 --- a/Mate/X86CodeGen.hs +++ b/Mate/X86CodeGen.hs @@ -46,23 +46,23 @@ type BBStarts = M.Map BlockID Int type CompileInfo = (EntryPoint, BBStarts, Int, TrapMap) -emitFromBB :: B.ByteString -> MethodSignature -> Class Direct -> MapBB -> CodeGen e s (CompileInfo, [Instruction]) -emitFromBB method sig cls hmap = do +emitFromBB :: B.ByteString -> MethodSignature -> Class Direct -> RawMethod -> CodeGen e s (CompileInfo, [Instruction]) +emitFromBB methodname sig cls method = do let keys = M.keys hmap llmap <- mapM (newNamedLabel . (++) "bb_" . show) keys let lmap = zip keys llmap ep <- getEntryPoint push ebp mov ebp esp - -- TODO(bernhard): determine a reasonable value. - -- e.g. (locals used) * 4 - sub esp (0x60 :: Word32) + sub esp (fromIntegral ((rawLocals method) * 4) :: Word32) (calls, bbstarts) <- efBB (0, hmap M.! 0) M.empty M.empty lmap d <- disassemble end <- getCodeOffset return ((ep, bbstarts, end, calls), d) where + hmap = rawMapBB method + getLabel :: BlockID -> [(BlockID, Label)] -> Label getLabel _ [] = error "label not found!" getLabel i ((x,l):xs) = if i==x then l else getLabel i xs @@ -358,10 +358,11 @@ emitFromBB method sig cls hmap = do cArgs_ :: IMM -> Word8 cArgs_ x = case x of I0 -> 0; I1 -> 1; I2 -> 2; I3 -> 3 + -- TODO: factor this out to `compileBB' thisMethodArgCnt :: Word32 thisMethodArgCnt = isNonStatic + fromIntegral (length args) where - m = fromJust $ lookupMethodSig method sig cls + m = fromJust $ lookupMethodSig methodname sig cls (MethodSignature args _) = sig isNonStatic = if S.member ACC_STATIC (methodAccessFlags m) then 0 else 1 -- one argument for the this pointer -- 2.25.1