@@ -635,33 +635,60 @@ type tag_metrics = {
635
635
payload_align: ValueRef
636
636
} ;
637
637
638
- // Returns the real size of the given type for the current target .
639
- fn llsize_of_real ( cx: @crate_ctxt, t: TypeRef ) -> uint {
638
+ // Returns the number of bytes clobbered by a Store to this type .
639
+ fn llsize_of_store ( cx: @crate_ctxt, t: TypeRef ) -> uint {
640
640
ret llvm:: LLVMStoreSizeOfType ( cx. td. lltd, t) as uint;
641
641
}
642
642
643
+ // Returns the number of bytes between successive elements of type T in an
644
+ // array of T. This is the "ABI" size. It includes any ABI-mandated padding.
643
645
fn llsize_of_alloc( cx: @crate_ctxt, t: TypeRef ) -> uint {
644
646
ret llvm:: LLVMABISizeOfType ( cx. td. lltd, t) as uint;
645
647
}
646
648
649
+ // Returns, as near as we can figure, the "real" size of a type. As in, the
650
+ // bits in this number of bytes actually carry data related to the datum
651
+ // with the type. Not junk, padding, accidentally-damaged words, or
652
+ // whatever. Rounds up to the nearest byte though, so if you have a 1-bit
653
+ // value, we return 1 here, not 0. Most of rustc works in bytes.
654
+ fn llsize_of_real( cx: @crate_ctxt, t: TypeRef ) -> uint {
655
+ let nbits = llvm:: LLVMSizeOfTypeInBits ( cx. td. lltd, t) as uint;
656
+ if nbits & 7 u != 0 u {
657
+ // Not an even number of bytes, spills into "next" byte.
658
+ 1 u + ( nbits >> 3 )
659
+ } else {
660
+ nbits >> 3
661
+ }
662
+ }
663
+
664
+ // Returns the "default" size of t, which is calculated by casting null to a
665
+ // *T and then doing gep(1) on it and measuring the result. Really, look in
666
+ // the LLVM sources. It does that. So this is likely similar to the ABI size
667
+ // (i.e. including alignment-padding), but goodness knows which alignment it
668
+ // winds up using. Probably the ABI one? Not recommended.
669
+ fn llsize_of( cx: @crate_ctxt, t: TypeRef ) -> ValueRef {
670
+ ret llvm:: LLVMConstIntCast ( lib:: llvm:: llvm:: LLVMSizeOf ( t) , cx. int_type,
671
+ False ) ;
672
+ }
673
+
647
674
// Returns the preferred alignment of the given type for the current target.
648
675
// The preffered alignment may be larger than the alignment used when
649
- // packing the type into structs
676
+ // packing the type into structs. This will be used for things like
677
+ // allocations inside a stack frame, which LLVM has a free hand in.
650
678
fn llalign_of_pref( cx: @crate_ctxt, t: TypeRef ) -> uint {
651
679
ret llvm:: LLVMPreferredAlignmentOfType ( cx. td. lltd, t) as uint;
652
680
}
653
681
654
682
// Returns the minimum alignment of a type required by the plattform.
655
- // This is the alignment that will be used for struct fields.
683
+ // This is the alignment that will be used for struct fields, arrays,
684
+ // and similar ABI-mandated things.
656
685
fn llalign_of_min( cx: @crate_ctxt, t: TypeRef ) -> uint {
657
686
ret llvm:: LLVMABIAlignmentOfType ( cx. td. lltd, t) as uint;
658
687
}
659
688
660
- fn llsize_of( cx: @crate_ctxt, t: TypeRef ) -> ValueRef {
661
- ret llvm:: LLVMConstIntCast ( lib:: llvm:: llvm:: LLVMSizeOf ( t) , cx. int_type,
662
- False ) ;
663
- }
664
-
689
+ // Returns the "default" alignment of t, which is calculated by casting
690
+ // null to a record containing a single-bit followed by a t value, then
691
+ // doing gep(0,1) to get at the trailing (and presumably padded) t cell.
665
692
fn llalign_of( cx: @crate_ctxt, t: TypeRef ) -> ValueRef {
666
693
ret llvm:: LLVMConstIntCast ( lib:: llvm:: llvm:: LLVMAlignOf ( t) , cx. int_type,
667
694
False ) ;
0 commit comments