diff options
author | Jan Kotas <jkotas@microsoft.com> | 2018-05-04 10:40:28 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-04 10:40:28 -0700 |
commit | 37e643696f860094ca3182c87f1375540b9d704e (patch) | |
tree | 5a840c7743873ca6c46e64a89487989a95880887 /src/vm/object.h | |
parent | fac17ce1413c2d270eb52e958faf5e869bcd33a2 (diff) | |
download | coreclr-37e643696f860094ca3182c87f1375540b9d704e.tar.gz coreclr-37e643696f860094ca3182c87f1375540b9d704e.tar.bz2 coreclr-37e643696f860094ca3182c87f1375540b9d704e.zip |
Fix System.String over-allocation (#17876)
BaseSize for System.String was not set correctly. It caused unnecessary extra 8 bytes to be allocated at the end of strings that had `Length % 4 < 2` on 64-bit platforms.
This change makes affected strings proportionally cheaper. For example, `new string('a', 1)` in a long-running loop is 7% faster.
Diffstat (limited to 'src/vm/object.h')
-rw-r--r-- | src/vm/object.h | 20 |
1 files changed, 6 insertions, 14 deletions
diff --git a/src/vm/object.h b/src/vm/object.h index e3e6c12399..3dd1e26d63 100644 --- a/src/vm/object.h +++ b/src/vm/object.h @@ -914,7 +914,7 @@ typedef PTR_StringObject STRINGREF; * Special String implementation for performance. * * m_StringLength - Length of string in number of WCHARs - * m_Characters - The string buffer + * m_FirstChar - The string buffer * */ @@ -932,9 +932,6 @@ typedef PTR_StringObject STRINGREF; #define STRING_STATE_FAST_OPS 0x80000000 #define STRING_STATE_SPECIAL_SORT 0xC0000000 -#ifdef _MSC_VER -#pragma warning(disable : 4200) // disable zero-sized array warning -#endif class StringObject : public Object { #ifdef DACCESS_COMPILE @@ -947,11 +944,7 @@ class StringObject : public Object private: DWORD m_StringLength; - WCHAR m_Characters[0]; - // GC will see a StringObject like this: - // DWORD m_StringLength - // WCHAR m_Characters[0] - // DWORD m_OptionalPadding (this is an optional field and will appear based on need) + WCHAR m_FirstChar; public: VOID SetStringLength(DWORD len) { LIMITED_METHOD_CONTRACT; _ASSERTE(len >= 0); m_StringLength = len; } @@ -961,12 +954,11 @@ class StringObject : public Object ~StringObject() {LIMITED_METHOD_CONTRACT; } public: + static DWORD GetBaseSize(); static SIZE_T GetSize(DWORD stringLength); DWORD GetStringLength() { LIMITED_METHOD_DAC_CONTRACT; return( m_StringLength );} - WCHAR* GetBuffer() { LIMITED_METHOD_CONTRACT; _ASSERTE(this != nullptr); return (WCHAR*)( dac_cast<TADDR>(this) + offsetof(StringObject, m_Characters) ); } - WCHAR* GetBuffer(DWORD *pdwSize) { LIMITED_METHOD_CONTRACT; _ASSERTE((this != nullptr) && pdwSize); *pdwSize = GetStringLength(); return GetBuffer(); } - WCHAR* GetBufferNullable() { LIMITED_METHOD_CONTRACT; return( (this == nullptr) ? nullptr : (WCHAR*)( dac_cast<TADDR>(this) + offsetof(StringObject, m_Characters) ) ); } + WCHAR* GetBuffer() { LIMITED_METHOD_CONTRACT; _ASSERTE(this != nullptr); return (WCHAR*)( dac_cast<TADDR>(this) + offsetof(StringObject, m_FirstChar) ); } DWORD GetHighCharState() { WRAPPER_NO_CONTRACT; @@ -992,7 +984,7 @@ class StringObject : public Object static UINT GetBufferOffset() { LIMITED_METHOD_DAC_CONTRACT; - return (UINT)(offsetof(StringObject, m_Characters)); + return (UINT)(offsetof(StringObject, m_FirstChar)); } static UINT GetStringLengthOffset() { @@ -3329,7 +3321,7 @@ public: static inline void *Value(void *src, MethodTable *nullableMT) { Nullable *nullable = (Nullable *)src; - return nullable->ValueAddr(nullableMT); + return nullable->ValueAddr(nullableMT); } private: |