Skip to content

Commit

Permalink
Merge 648611d into dd7f176
Browse files Browse the repository at this point in the history
  • Loading branch information
beru authored Aug 10, 2019
2 parents dd7f176 + 648611d commit f0f6203
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 10 deletions.
4 changes: 4 additions & 0 deletions sakura/sakura.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalOptions>/FAsu /Fa$(IntDir) /source-charset:utf-8 /execution-charset:shift_jis %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>comctl32.lib;Imm32.lib;mpr.lib;imagehlp.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
Expand Down Expand Up @@ -143,6 +144,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalOptions>/FAsu /Fa$(IntDir) /source-charset:utf-8 /execution-charset:shift_jis %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>comctl32.lib;Imm32.lib;mpr.lib;imagehlp.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
Expand Down Expand Up @@ -181,6 +183,7 @@
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<AdditionalOptions>/FAsu /Fa$(IntDir) /source-charset:utf-8 /execution-charset:shift_jis %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>comctl32.lib;Imm32.lib;mpr.lib;imagehlp.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
Expand Down Expand Up @@ -219,6 +222,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalOptions>/FAsu /Fa$(IntDir) /source-charset:utf-8 /execution-charset:shift_jis %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>comctl32.lib;Imm32.lib;mpr.lib;imagehlp.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
Expand Down
13 changes: 9 additions & 4 deletions sakura_core/doc/layout/CLayoutMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "charset/charcode.h"
#include "mem/CMemory.h"/// 2002/2/10 aroka
#include "mem/CMemoryIterator.h" // 2006.07.29 genta
#include "mem/CPoolResource.h"
#include "view/CViewFont.h"
#include "view/CTextMetrics.h"
#include "basis/SakuraBasis.h"
Expand All @@ -36,7 +37,9 @@
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //

CLayoutMgr::CLayoutMgr()
: m_getIndentOffset( &CLayoutMgr::getIndentOffset_Normal ) // Oct. 1, 2002 genta // Nov. 16, 2002 メンバー関数ポインタにはクラス名が必要
: m_getIndentOffset( &CLayoutMgr::getIndentOffset_Normal ), // Oct. 1, 2002 genta // Nov. 16, 2002 メンバー関数ポインタにはクラス名が必要
m_layoutMemRes(new CPoolResource<CLayout>())
//m_layoutMemRes(new std::pmr::unsynchronized_pool_resource()) // メモリ使用量が大きい為に使用しないで、CPoolResource を代わりに使う
{
m_pcDocLineMgr = NULL;
m_pTypeConfig = NULL;
Expand Down Expand Up @@ -95,7 +98,8 @@ void CLayoutMgr::_Empty()
CLayout* pLayout = m_pLayoutTop;
while( pLayout ){
CLayout* pLayoutNext = pLayout->GetNextLayout();
delete pLayout;
pLayout->~CLayout();
m_layoutMemRes->deallocate(pLayout, sizeof(CLayout), alignof(CLayout));
pLayout = pLayoutNext;
}
}
Expand Down Expand Up @@ -381,7 +385,7 @@ CLayout* CLayoutMgr::CreateLayout(
CLayoutColorInfo* colorInfo
)
{
CLayout* pLayout = new CLayout(
CLayout* pLayout = new (m_layoutMemRes->allocate(sizeof(CLayout))) CLayout(
pCDocLine,
ptLogicPos,
nLength,
Expand Down Expand Up @@ -589,7 +593,8 @@ CLayout* CLayoutMgr::DeleteLayoutAsLogical(
DEBUG_TRACE( _T("バグバグ\n") );
}

delete pLayout;
pLayout->~CLayout();
m_layoutMemRes->deallocate(pLayout, sizeof(CLayout), alignof(CLayout));

m_nLines--; /* 全物理行数 */
if( NULL == pLayoutNext ){
Expand Down
3 changes: 2 additions & 1 deletion sakura_core/doc/layout/CLayoutMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include <Windows.h>// 2002/2/10 aroka
#include <vector>
#include <memory_resource>
#include "doc/CDocListener.h"
#include "_main/global.h"// 2002/2/10 aroka
#include "basis/SakuraBasis.h"
Expand All @@ -37,7 +38,6 @@
#include "util/design_template.h"

class CBregexp;// 2002/2/10 aroka
class CLayout;// 2002/2/10 aroka
class CDocLineMgr;// 2002/2/10 aroka
class CDocLine;// 2002/2/10 aroka
class CMemory;// 2002/2/10 aroka
Expand Down Expand Up @@ -399,6 +399,7 @@ class CLayoutMgr : public CProgressSubject
//実データ
CLayout* m_pLayoutTop;
CLayout* m_pLayoutBot;
std::unique_ptr<std::pmr::memory_resource> m_layoutMemRes;

//タイプ別設定
const STypeConfig* m_pTypeConfig;
Expand Down
15 changes: 11 additions & 4 deletions sakura_core/doc/logic/CDocLineMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
// May 15, 2000 genta
#include "CEol.h"
#include "mem/CMemory.h"// 2002/2/10 aroka
#include "mem/CPoolResource.h"

#include "io/CFileLoad.h" // 2002/08/30 Moca
#include "io/CIoBridge.h"
Expand All @@ -52,6 +53,10 @@
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //

CDocLineMgr::CDocLineMgr()
:
m_docLineMemRes(new CPoolResource<CDocLine>())
//m_docLineMemRes(new std::pmr::unsynchronized_pool_resource()) // メモリ使用量が大きい為に使用しないで、CPoolResource を代わりに使う

{
_Init();
}
Expand All @@ -68,15 +73,15 @@ CDocLineMgr::~CDocLineMgr()
//! pPosの直前に新しい行を挿入
CDocLine* CDocLineMgr::InsertNewLine(CDocLine* pPos)
{
CDocLine* pcDocLineNew = new CDocLine;
CDocLine* pcDocLineNew = new (m_docLineMemRes->allocate(sizeof(CDocLine))) CDocLine();
_InsertBeforePos(pcDocLineNew,pPos);
return pcDocLineNew;
}

//! 最下部に新しい行を挿入
CDocLine* CDocLineMgr::AddNewLine()
{
CDocLine* pcDocLineNew = new CDocLine;
CDocLine* pcDocLineNew = new (m_docLineMemRes->allocate(sizeof(CDocLine))) CDocLine();
_PushBottom(pcDocLineNew);
return pcDocLineNew;
}
Expand All @@ -87,7 +92,8 @@ void CDocLineMgr::DeleteAllLine()
CDocLine* pDocLine = m_pDocLineTop;
while( pDocLine ){
CDocLine* pDocLineNext = pDocLine->GetNextLine();
delete pDocLine;
pDocLine->~CDocLine();
m_docLineMemRes->deallocate(pDocLine, sizeof(CDocLine));
pDocLine = pDocLineNext;
}
_Init();
Expand Down Expand Up @@ -118,7 +124,8 @@ void CDocLineMgr::DeleteLine( CDocLine* pcDocLineDel )
}

//データ削除
delete pcDocLineDel;
pcDocLineDel->~CDocLine();
m_docLineMemRes->deallocate(pcDocLineDel, sizeof(CDocLine));

//行数減算
m_nLines--;
Expand Down
4 changes: 3 additions & 1 deletion sakura_core/doc/logic/CDocLineMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@
#define _CDOCLINEMGR_H_

#include <Windows.h>
#include <memory_resource>
#include "_main/global.h" // 2002/2/10 aroka
#include "basis/SakuraBasis.h"
#include "util/design_template.h"
#include "COpe.h"
#include "CDocLine.h"

class CDocLine; // 2002/2/10 aroka
class CBregexp; // 2002/2/10 aroka

struct DocLineReplaceArg {
Expand Down Expand Up @@ -89,6 +90,7 @@ class CDocLineMgr{
CDocLine* m_pDocLineTop; //!< 最初の行
CDocLine* m_pDocLineBot; //!< 最後の行(※1行しかない場合はm_pDocLineTopと等しくなる)
CLogicInt m_nLines; //!< 全行数
std::unique_ptr<std::pmr::memory_resource> m_docLineMemRes;

public:
//$$ kobake注: 以下、絶対に切り離したい(最低切り離せなくても、変数の意味をコメントで明確に記すべき)変数群
Expand Down
136 changes: 136 additions & 0 deletions sakura_core/mem/CPoolResource.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
Copyright (C) 2018-2019 Sakura Editor Organization
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such,
and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/

#ifndef SAKURA_CPOOLRESOURCE_H_
#define SAKURA_CPOOLRESOURCE_H_

#include <memory_resource>
#include <Windows.h>

// std::pmr::unsynchronized_pool_resource だとメモリ使用量が大きい為、自前実装を用意
// T : 要素型
template <typename T>
class CPoolResource : public std::pmr::memory_resource
{
public:
CPoolResource()
{
// 始めのブロックをメモリ確保
AllocateBlock();
}

virtual ~CPoolResource()
{
// メモリ確保した領域の連結リストを辿って全てのブロック分のメモリ解放
Node* curr = m_currentBlock;
while (curr) {
Node* next = curr->next;
VirtualFree(curr, 0, MEM_RELEASE);
curr = next;
}
}

protected:
// 要素のメモリ確保処理、要素の領域のポインタを返す
// bytes と alignment 引数は使用しない、template 引数の型で静的に決定する
void* do_allocate([[maybe_unused]] std::size_t bytes,
[[maybe_unused]] std::size_t alignment) override
{
// メモリ確保時には未割当領域から使用していく
if (m_unassignedNode) {
T* ret = reinterpret_cast<T*>(m_unassignedNode);
m_unassignedNode = m_unassignedNode->next;
return ret;
}
else {
// 未割当領域が無い場合は、ブロックの中から切り出す
// 現在のブロックに新規確保するNodeサイズ分の領域が余っていない場合は新規のブロックを確保
Node* blockEnd = reinterpret_cast<Node*>(reinterpret_cast<char*>(m_currentBlock) + BlockSize);
if (m_currentNode + 1 >= blockEnd) {
AllocateBlock();
}
// 要素の領域のポインタを返すと同時にポインタを次に進めて切り出す位置を更新する
return reinterpret_cast<T*>(m_currentNode++);
}
}

// メモリ解放処理、要素の領域のポインタを受け取る
// 第1引数には、do_allocate メソッドで返したポインタを渡す事
// bytes と alignment 引数は使用しない、template 引数の型で静的に決定する
void do_deallocate(void* p,
[[maybe_unused]] std::size_t bytes,
[[maybe_unused]] std::size_t alignment) override
{
if (p) {
// メモリ解放した領域を未割当領域として自己参照共用体の片方向連結リストで繋げる
// 次回のメモリ確保時にその領域を再利用する
Node* next = m_unassignedNode;
m_unassignedNode = reinterpret_cast<Node*>(p);
m_unassignedNode->next = next;
}
}

bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override
{
return this == &other;
}

private:
static constexpr size_t BlockSize = 1024 * 64; // VirtualAlloc を使用する為このサイズ

// 共用体を使う事で要素型と自己参照用のポインタを同じ領域に割り当てる
// 共用体のサイズは各メンバを格納できるサイズになる事を利用する
union Node {
~Node() {}
T element; // 要素型
Node* next; // ブロックのヘッダの場合は、次のブロックに繋がる
// 解放後の未割当領域の場合は次の未割当領域に繋がる
};

static_assert(2 * sizeof(Node) <= BlockSize, "sizeof(T) too big.");

// 呼び出しの度にメモリの動的確保を細かく行う事を避ける為に、一括でブロック領域を確保
// ブロックの先頭(head)にはブロックの連結用のポインタが配置され、残る領域(body)には要素が記録される
void AllocateBlock()
{
char* buff = reinterpret_cast<char*>(VirtualAlloc(NULL, BlockSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE));
Node* next = m_currentBlock;
// ブロック領域の先頭(head)はNodeのポインタとして扱い、以前に作成したブロックに連結する
m_currentBlock = reinterpret_cast<Node*>(buff);
m_currentBlock->next = next;

// ブロック領域の残る部分は要素の領域とするが、アライメントを取る
void* body = buff + sizeof(Node*);
size_t space = BlockSize - sizeof(Node*);
body = std::align(alignof(Node), sizeof(Node), body, space);
assert(body);
m_currentNode = reinterpret_cast<Node*>(body);
}

Node* m_unassignedNode = nullptr; // 未割当領域の先頭
Node* m_currentBlock = nullptr; // 現在のブロック
Node* m_currentNode = nullptr; // 要素確保処理時に現在のブロックの中から切り出すNodeを指すポインタ、メモリ確保時に未割当領域が無い場合はここを使う
};

#endif /* SAKURA_CPOOLRESOURCE_H_ */

0 comments on commit f0f6203

Please sign in to comment.