[Libreoffice-commits] core.git: 2 commits - formula/source include/formula include/rtl sal/inc sal/Library_sal.mk sal/osl sal/rtl sal/util sc/inc sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Thu Feb 27 18:30:23 PST 2014


 formula/source/core/api/vectortoken.cxx     |   29 +++++++++----
 include/formula/vectortoken.hxx             |   13 ++++--
 include/rtl/alloc.h                         |   24 +++++++++++
 sal/Library_sal.mk                          |    2 
 sal/inc/internal/oslmemory.h                |   30 ++++++++++++++
 sal/osl/unx/memory.c                        |   26 ++++++++++++
 sal/osl/w32/memory.c                        |   24 +++++++++++
 sal/rtl/alloc_global.cxx                    |   11 +++++
 sal/util/sal.map                            |    6 ++
 sc/inc/formulagroup.hxx                     |    4 +
 sc/inc/stlalgorithm.hxx                     |   60 ++++++++++++++++++++++++++++
 sc/source/core/data/grouptokenconverter.cxx |   12 ++---
 12 files changed, 222 insertions(+), 19 deletions(-)

New commits:
commit 03f7a342011a4f69cfcbec7af3e4f1a2e835618b
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Feb 26 16:29:27 2014 -0500

    Ensure that numeric array storage is aligned to 256-byte boundary.
    
    OpenCL devices require this else we would get a performance hit.
    
    Change-Id: I6b1db6320fa84f933b6446022a0fd02ba267bf21

diff --git a/include/rtl/alloc.h b/include/rtl/alloc.h
index 9d0b44e..f3459ba 100644
--- a/include/rtl/alloc.h
+++ b/include/rtl/alloc.h
@@ -96,6 +96,30 @@ SAL_DLLPUBLIC void SAL_CALL rtl_freeZeroMemory (
 ) SAL_THROW_EXTERN_C();
 
 
+/** Allocate memory.
+
+    A call to this function will return NULL upon the requested
+    memory size being either zero or larger than currently allocatable.
+
+    @param Alignment alignment in bytes.
+    @param  Bytes [in] memory size.
+    @return pointer to allocated memory.
+ */
+SAL_DLLPUBLIC void* SAL_CALL rtl_allocateAlinedMemory (
+    sal_Size Alignment,
+    sal_Size Bytes
+) SAL_THROW_EXTERN_C();
+
+
+/** Free memory allocated with rtl_allocateAlinedMemory.
+    @param  Ptr   [in] pointer to previously allocated memory.
+    @return none. Memory is released. Ptr is invalid.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_freeAlignedMemory (
+    void *   Ptr
+) SAL_THROW_EXTERN_C();
+
+
 /** Opaque rtl_arena_type.
  */
 typedef struct rtl_arena_st rtl_arena_type;
diff --git a/sal/Library_sal.mk b/sal/Library_sal.mk
index cbc52a7..6b16426 100644
--- a/sal/Library_sal.mk
+++ b/sal/Library_sal.mk
@@ -168,6 +168,7 @@ $(eval $(call gb_Library_add_exception_objects,sal,\
         $(if $(filter DESKTOP,$(BUILD_TYPE)), sal/osl/unx/salinit) \
 ))
 $(eval $(call gb_Library_add_cobjects,sal,\
+	sal/osl/unx/memory \
 	sal/osl/unx/mutex \
 	sal/osl/unx/nlsupport \
 	sal/osl/unx/pipe \
@@ -253,6 +254,7 @@ $(eval $(call gb_Library_add_cobjects,sal,\
 	sal/osl/w32/dllentry \
 	sal/osl/w32/file_error \
 	sal/osl/w32/interlck \
+	sal/osl/w32/memory \
 	sal/osl/w32/mutex \
 	sal/osl/w32/nlsupport \
 	sal/osl/w32/pipe \
diff --git a/sal/inc/internal/oslmemory.h b/sal/inc/internal/oslmemory.h
new file mode 100644
index 0000000..8ef094a
--- /dev/null
+++ b/sal/inc/internal/oslmemory.h
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SAL_INTERNAL_OSLMEMORY_H
+#define INCLUDED_SAL_INTERNAL_OSLMEMORY_H
+
+#include <sal/saldllapi.h>
+#include <sal/types.h>
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+void* osl_aligned_alloc( sal_Size align, sal_Size size );
+
+void osl_aligned_free( void* p );
+
+#if defined __cplusplus
+}
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/osl/unx/memory.c b/sal/osl/unx/memory.c
new file mode 100644
index 0000000..a70bc16
--- /dev/null
+++ b/sal/osl/unx/memory.c
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <internal/oslmemory.h>
+
+#include <stdlib.h>
+
+void* osl_aligned_alloc( sal_Size align, sal_Size size )
+{
+    void* ptr;
+    int err = posix_memalign(&ptr, align, size);
+    return err ? NULL : ptr;
+}
+
+void osl_aligned_free( void* p )
+{
+    free(p);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/osl/w32/memory.c b/sal/osl/w32/memory.c
new file mode 100644
index 0000000..279a168
--- /dev/null
+++ b/sal/osl/w32/memory.c
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <internal/oslmemory.h>
+
+#include <malloc.h>
+
+void* osl_aligned_alloc( sal_Size align, sal_Size size )
+{
+    return _aligned_malloc(size, align);
+}
+
+void osl_aligned_free( void* p )
+{
+    _aligned_free(p);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/rtl/alloc_global.cxx b/sal/rtl/alloc_global.cxx
index 07cded3..4108333 100644
--- a/sal/rtl/alloc_global.cxx
+++ b/sal/rtl/alloc_global.cxx
@@ -27,6 +27,7 @@
 #include <stdio.h>
 
 #include "internal/rtllifecycle.h"
+#include <internal/oslmemory.h>
 
 AllocMode alloc_mode = AMode_UNSET;
 
@@ -378,6 +379,16 @@ void SAL_CALL rtl_freeZeroMemory (void * p, sal_Size n) SAL_THROW_EXTERN_C()
     }
 }
 
+void* SAL_CALL rtl_allocateAlinedMemory (sal_Size Alignment, sal_Size Bytes) SAL_THROW_EXTERN_C()
+{
+    return osl_aligned_alloc(Alignment, Bytes);
+}
+
+void SAL_CALL rtl_freeAlignedMemory (void* Ptr) SAL_THROW_EXTERN_C()
+{
+    osl_aligned_free(Ptr);
+}
+
 /* ================================================================= */
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/util/sal.map b/sal/util/sal.map
index 1456d6d..f63f38b 100644
--- a/sal/util/sal.map
+++ b/sal/util/sal.map
@@ -670,6 +670,12 @@ LIBO_UDK_4.2 { # symbols available in >= LibO 4.2
         rtl_ustr_toUInt32;
 } LIBO_UDK_4.1;
 
+LIBO_UDK_4.3 { # symbols available in >= LibO 4.3
+    global:
+        rtl_allocateAlinedMemory;
+        rtl_freeAlignedMemory;
+} LIBO_UDK_4.2;
+
 PRIVATE_1.0 {
     global:
         osl_detail_ObjectRegistry_storeAddresses;
diff --git a/sc/inc/formulagroup.hxx b/sc/inc/formulagroup.hxx
index 3834e49..602c4a4 100644
--- a/sc/inc/formulagroup.hxx
+++ b/sc/inc/formulagroup.hxx
@@ -13,6 +13,7 @@
 #include "address.hxx"
 #include "types.hxx"
 #include "platforminfo.hxx"
+#include <stlalgorithm.hxx>
 
 #include "svl/sharedstringpool.hxx"
 
@@ -28,7 +29,8 @@ namespace sc {
 
 struct FormulaGroupContext : boost::noncopyable
 {
-    typedef std::vector<double> NumArrayType;
+    typedef AlignedAllocator<double,256> DoubleAllocType;
+    typedef std::vector<double, DoubleAllocType> NumArrayType;
     typedef std::vector<rtl_uString*> StrArrayType;
     typedef boost::ptr_vector<NumArrayType> NumArrayStoreType;
     typedef boost::ptr_vector<StrArrayType> StrArrayStoreType;
diff --git a/sc/inc/stlalgorithm.hxx b/sc/inc/stlalgorithm.hxx
index fb5509f..37d7ba8 100644
--- a/sc/inc/stlalgorithm.hxx
+++ b/sc/inc/stlalgorithm.hxx
@@ -11,6 +11,9 @@
 #define __SC_STLALGORITHM_HXX__
 
 #include <functional>
+#include <limits>
+
+#include <rtl/alloc.h>
 
 /**
  * Function object to allow deleting instances stored in STL containers as
@@ -25,6 +28,63 @@ struct ScDeleteObjectByPtr : public ::std::unary_function<T*, void>
     }
 };
 
+namespace sc {
+
+/**
+ * Custom allocator for STL container to ensure that the base address of
+ * allocated storage is aligned to a specified boundary.
+ */
+template<typename T, size_t _Alignment>
+class AlignedAllocator
+{
+public:
+    typedef T value_type;
+    typedef size_t size_type;
+    typedef std::ptrdiff_t difference_type;
+
+    typedef T* pointer;
+    typedef const T* const_pointer;
+    typedef T* void_pointer;
+
+    typedef T& reference;
+    typedef const T& const_reference;
+
+    template<typename _Type2>
+    struct rebind
+    {
+        typedef AlignedAllocator<_Type2,_Alignment> other;
+    };
+
+    AlignedAllocator() {}
+    ~AlignedAllocator() {}
+
+    template<typename _Type2>
+    AlignedAllocator(const AlignedAllocator<_Type2,_Alignment>&) {}
+
+    void construct(T* p, const value_type& val) { new(p) value_type(val); }
+    void destroy(T* p) { p->~value_type(); }
+
+    size_type max_size() const
+    {
+        return std::numeric_limits<size_type>::max() / sizeof(value_type);
+    }
+
+    bool operator== (const AlignedAllocator&) const { return true; }
+    bool operator!= (const AlignedAllocator&) const { return false; }
+
+    pointer allocate(size_type n)
+    {
+        return (pointer)rtl_allocateAlinedMemory(_Alignment, n*sizeof(value_type));
+    }
+
+    void deallocate(pointer p, size_type)
+    {
+        rtl_freeAlignedMemory(p);
+    }
+};
+
+}
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 6ef6dd0122b8e44d8547ec31f40def42173e4e41
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Feb 26 14:32:57 2014 -0500

    Store the length of originally requested array size prior to trimming.
    
    This change adds GetRequestedArrayLength() method to both single and double
    vector ref tokens, which returns the length of the requested array size prior
    to trimming of the trailing empty cell region.
    
    Change-Id: Iaba96fa2ea4ff3c8bccb0bc86fa4f1525e2f45fb

diff --git a/formula/source/core/api/vectortoken.cxx b/formula/source/core/api/vectortoken.cxx
index 961eda6..57476f4 100644
--- a/formula/source/core/api/vectortoken.cxx
+++ b/formula/source/core/api/vectortoken.cxx
@@ -22,15 +22,15 @@ bool VectorRefArray::isValid() const
     return mpNumericArray || mpStringArray;
 }
 
-SingleVectorRefToken::SingleVectorRefToken( const double* pArray, size_t nLength ) :
-    FormulaToken(svSingleVectorRef, ocPush), maArray(pArray), mnArrayLength(nLength) {}
+SingleVectorRefToken::SingleVectorRefToken( const double* pArray, size_t nReqLength, size_t nArrayLength ) :
+    FormulaToken(svSingleVectorRef, ocPush), maArray(pArray), mnRequestedLength(nReqLength), mnArrayLength(nArrayLength) {}
 
-SingleVectorRefToken::SingleVectorRefToken( const VectorRefArray& rArray, size_t nLength ) :
-    FormulaToken(svSingleVectorRef, ocPush), maArray(rArray), mnArrayLength(nLength) {}
+SingleVectorRefToken::SingleVectorRefToken( const VectorRefArray& rArray, size_t nReqLength, size_t nArrayLength ) :
+    FormulaToken(svSingleVectorRef, ocPush), maArray(rArray), mnRequestedLength(nReqLength), mnArrayLength(nArrayLength) {}
 
 FormulaToken* SingleVectorRefToken::Clone() const
 {
-    return new SingleVectorRefToken(maArray, mnArrayLength);
+    return new SingleVectorRefToken(maArray, mnRequestedLength, mnArrayLength);
 }
 
 const VectorRefArray& SingleVectorRefToken::GetArray() const
@@ -38,19 +38,27 @@ const VectorRefArray& SingleVectorRefToken::GetArray() const
     return maArray;
 }
 
+size_t SingleVectorRefToken::GetRequestedArrayLength() const
+{
+    return mnRequestedLength;
+}
+
 size_t SingleVectorRefToken::GetArrayLength() const
 {
     return mnArrayLength;
 }
 
 DoubleVectorRefToken::DoubleVectorRefToken(
-    const std::vector<VectorRefArray>& rArrays, size_t nArrayLength, size_t nRefRowSize, bool bStartFixed, bool bEndFixed ) :
+    const std::vector<VectorRefArray>& rArrays, size_t nReqLength, size_t nArrayLength,
+    size_t nRefRowSize, bool bStartFixed, bool bEndFixed ) :
     FormulaToken(svDoubleVectorRef, ocPush),
-    maArrays(rArrays), mnArrayLength(nArrayLength), mnRefRowSize(nRefRowSize), mbStartFixed(bStartFixed), mbEndFixed(bEndFixed) {}
+    maArrays(rArrays), mnRequestedLength(nReqLength), mnArrayLength(nArrayLength),
+    mnRefRowSize(nRefRowSize), mbStartFixed(bStartFixed), mbEndFixed(bEndFixed) {}
 
 FormulaToken* DoubleVectorRefToken::Clone() const
 {
-    return new DoubleVectorRefToken(maArrays, mnArrayLength, mnRefRowSize, mbStartFixed, mbEndFixed);
+    return new DoubleVectorRefToken(
+        maArrays, mnRequestedLength, mnArrayLength, mnRefRowSize, mbStartFixed, mbEndFixed);
 }
 
 const std::vector<VectorRefArray>& DoubleVectorRefToken::GetArrays() const
@@ -58,6 +66,11 @@ const std::vector<VectorRefArray>& DoubleVectorRefToken::GetArrays() const
     return maArrays;
 }
 
+size_t DoubleVectorRefToken::GetRequestedArrayLength() const
+{
+    return mnRequestedLength;
+}
+
 size_t DoubleVectorRefToken::GetArrayLength() const
 {
     return mnArrayLength;
diff --git a/include/formula/vectortoken.hxx b/include/formula/vectortoken.hxx
index f04fef4..5fa596b 100644
--- a/include/formula/vectortoken.hxx
+++ b/include/formula/vectortoken.hxx
@@ -52,15 +52,17 @@ struct FORMULA_DLLPUBLIC VectorRefArray
 class FORMULA_DLLPUBLIC SingleVectorRefToken : public FormulaToken
 {
     VectorRefArray maArray;
+    size_t mnRequestedLength;
     size_t mnArrayLength;
 
 public:
-    SingleVectorRefToken( const double* pArray, size_t nLength );
-    SingleVectorRefToken( const VectorRefArray& rArray, size_t nLength );
+    SingleVectorRefToken( const double* pArray, size_t nReqLength, size_t nArrayLength );
+    SingleVectorRefToken( const VectorRefArray& rArray, size_t nReqLength, size_t nArrayLength );
 
     virtual FormulaToken* Clone() const;
 
     const VectorRefArray& GetArray() const;
+    size_t GetRequestedArrayLength() const;
     size_t GetArrayLength() const;
 };
 
@@ -72,7 +74,8 @@ class FORMULA_DLLPUBLIC DoubleVectorRefToken : public FormulaToken
 {
     std::vector<VectorRefArray> maArrays;
 
-    size_t mnArrayLength; /// length of all arrays.
+    size_t mnRequestedLength; /// requested length of all arrays which include trailing empty region.
+    size_t mnArrayLength; /// length of all arrays which does not include trailing empty region.
     size_t mnRefRowSize; /// original reference row size. The row size may
                          /// change as it goes down the array if either the
                          /// stard or end position is fixed.
@@ -82,11 +85,13 @@ class FORMULA_DLLPUBLIC DoubleVectorRefToken : public FormulaToken
 
 public:
     DoubleVectorRefToken(
-        const std::vector<VectorRefArray>& rArrays, size_t nArrayLength, size_t nRefRowSize, bool bStartFixed, bool bEndFixed );
+        const std::vector<VectorRefArray>& rArrays, size_t nReqLength, size_t nArrayLength,
+        size_t nRefRowSize, bool bStartFixed, bool bEndFixed );
 
     virtual FormulaToken* Clone() const;
 
     const std::vector<VectorRefArray>& GetArrays() const;
+    size_t GetRequestedArrayLength() const;
     size_t GetArrayLength() const;
     size_t GetRefRowSize() const;
     bool IsStartFixed() const;
diff --git a/sc/source/core/data/grouptokenconverter.cxx b/sc/source/core/data/grouptokenconverter.cxx
index b295fee..47585fd 100644
--- a/sc/source/core/data/grouptokenconverter.cxx
+++ b/sc/source/core/data/grouptokenconverter.cxx
@@ -110,17 +110,16 @@ bool ScGroupTokenConverter::convert(ScTokenArray& rCode)
                         return false;
 
                     // Trim data array length to actual data range.
-                    nLen = trimLength(aRefPos.Tab(), aRefPos.Col(), aRefPos.Col(), aRefPos.Row(), nLen);
-
+                    SCROW nTrimLen = trimLength(aRefPos.Tab(), aRefPos.Col(), aRefPos.Col(), aRefPos.Row(), nLen);
                     // Fetch double array guarantees that the length of the
                     // returned array equals or greater than the requested
                     // length.
 
                     formula::VectorRefArray aArray;
-                    if (nLen)
-                        aArray = mrDoc.FetchVectorRefArray(aRefPos, nLen);
+                    if (nTrimLen)
+                        aArray = mrDoc.FetchVectorRefArray(aRefPos, nTrimLen);
 
-                    formula::SingleVectorRefToken aTok(aArray, nLen);
+                    formula::SingleVectorRefToken aTok(aArray, nLen, nTrimLen);
                     mrGroupTokens.AddToken(aTok);
                 }
                 else
@@ -179,6 +178,7 @@ bool ScGroupTokenConverter::convert(ScTokenArray& rCode)
                 }
 
                 // Trim trailing empty rows.
+                SCROW nRequestedLength = nArrayLength; // keep the original length.
                 nArrayLength = trimLength(aRefPos.Tab(), aAbs.aStart.Col(), aAbs.aEnd.Col(), aRefPos.Row(), nArrayLength);
 
                 for (SCCOL i = aAbs.aStart.Col(); i <= aAbs.aEnd.Col(); ++i)
@@ -191,7 +191,7 @@ bool ScGroupTokenConverter::convert(ScTokenArray& rCode)
                     aArrays.push_back(aArray);
                 }
 
-                formula::DoubleVectorRefToken aTok(aArrays, nArrayLength, nRefRowSize, bAbsFirst, bAbsLast);
+                formula::DoubleVectorRefToken aTok(aArrays, nRequestedLength, nArrayLength, nRefRowSize, bAbsFirst, bAbsLast);
                 mrGroupTokens.AddToken(aTok);
             }
             break;


More information about the Libreoffice-commits mailing list