* src/vm/jit/code.c (code_get_stack_frame_size): Implement stack alignment
[cacao.git] / src / vm / jit / code.c
index 73403110aebeaf7fd450371cd0b0b13b42801f17..dc7cd96c6cbf78341564d8e11e61924d4658df5d 100644 (file)
    IN:
        m................method to create a new codeinfo for
 
-   Note: codeinfo.m is set to m, all other fields are zeroed.
+   The following fields are set in codeinfo:
+       m
+          isleafmethod
+   all other fields are zeroed
 
    RETURN VALUE:
        a new, initialized codeinfo, or
@@ -67,6 +70,7 @@ codeinfo *code_codeinfo_new(methodinfo *m)
        memset(code,0,sizeof(codeinfo));
 
        code->m = m;
+       code->isleafmethod = m->isleafmethod; /* XXX will be moved to codeinfo */
        
        return code;
 }
@@ -87,6 +91,9 @@ codeinfo *code_codeinfo_new(methodinfo *m)
 
 int code_get_sync_slot_count(codeinfo *code)
 {
+#ifdef USE_THREADS
+       int count;
+       
        assert(code);
 
        if (!checksync)
@@ -95,18 +102,39 @@ int code_get_sync_slot_count(codeinfo *code)
        if (!(code->m->flags & ACC_SYNCHRONIZED))
                return 0;
 
-       /* XXX generalize to all archs */
+       count = 1;
+
 #ifdef HAS_4BYTE_STACKSLOT
-       return (IS_2_WORD_TYPE(code->m->parseddesc->returntype.type)) ? 2 : 1;
-#else
-       return 1;
+       /* long and double need 2 4-byte slots */
+       if (IS_2_WORD_TYPE(code->m->parseddesc->returntype.type))
+               count++;
+#endif
+
+#if defined(__POWERPC__)
+       /* powerpc needs an extra slot */
+       count++;
 #endif
+
+       return count;
+
+#else /* !USE_THREADS */
+       
+       return 0;
+
+#endif /* USE_THREADS */
 }
 
 /* code_get_stack_frame_size ***************************************************
 
    Return the number of stack slots that the stack frame of the given code
    comprises.
+
+   IMPORTANT: The return value does *not* include the saved return address 
+              slot, although it is part of non-leaf stack frames on RISC
+                         architectures. The rationale behind this is that the saved
+                         return address is never moved or changed by replacement, and
+                         this way CISC and RISC architectures can be treated the same.
+                         (See also doc/stack_frames.txt.)
    
    IN:
        code.............the codeinfo of the code in question
@@ -123,15 +151,39 @@ int code_get_stack_frame_size(codeinfo *code)
        
        assert(code);
 
-       /* XXX generalize to all archs */
+       /* slots allocated by register allocator plus saved registers */
+
 #ifdef HAS_4BYTE_STACKSLOT
        count = code->memuse + code->savedintcount + 2*code->savedfltcount;
 #else
        count = code->memuse + code->savedintcount + code->savedfltcount;
 #endif
 
+       /* add slots needed in synchronized methods */
+
        count += code_get_sync_slot_count(code);
 
+       /* keep stack aligned */
+
+#if defined(__X86_64__)
+       /* the x86_64 codegen only aligns the stack in non-leaf methods */
+       if (!code->isleafmethod || opt_verbosecall)
+               count |= 1; /* even when return address is added */
+#endif
+
+       /* XXX align stack on alpha */
+#if defined(__MIPS__)
+       if (code->isleafmethod)
+               count = (count + 1) & ~1;
+       else
+               count |= 1; /* even when return address is added */
+#endif
+
+#if defined(__POWERPC__)
+       /* keep stack 16-byte aligned */
+       count = (count + 3) & ~3;
+#endif
+
        return count;
 }