diff options
author | MITSUNARI Shigeo <[email protected]> | 2018-10-29 16:29:57 +0900 |
---|---|---|
committer | MITSUNARI Shigeo <[email protected]> | 2018-10-29 16:29:57 +0900 |
commit | d09a230fbc03c88d80ff91d20dc790a04acd2256 (patch) | |
tree | 5b58a0dd953218c9eb1ce397c8b613eb67af681d | |
parent | 973e85970876c380b46a09a43b7865efa4a3d650 (diff) | |
download | xbyak-5.75.tar.gz xbyak-5.75.zip |
unlink Label when LabelManager is destroyedv5.75
-rw-r--r-- | readme.md | 3 | ||||
-rw-r--r-- | readme.txt | 3 | ||||
-rw-r--r-- | test/jmp.cpp | 51 | ||||
-rw-r--r-- | xbyak/xbyak.h | 47 | ||||
-rw-r--r-- | xbyak/xbyak_mnemonic.h | 2 |
5 files changed, 92 insertions, 14 deletions
@@ -1,5 +1,5 @@ -# Xbyak 5.74 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++ +# Xbyak 5.75 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++ ## Abstract @@ -392,6 +392,7 @@ modified new BSD License http://opensource.org/licenses/BSD-3-Clause ## History +* 2018/Oct/29 ver 5.75 unlink LabelManager from Label when msg is destroyed * 2018/Oct/21 ver 5.74 support RegRip +/- int. Xbyak::CastTo is removed * 2018/Oct/15 util::AddressFrame uses push/pop instead of mov * 2018/Sep/19 ver 5.73 fix evex encoding of vpslld, vpslldq, vpsllw, etc for (reg, mem, imm8) @@ -1,5 +1,5 @@ - C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 5.74
+ C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 5.75
-----------------------------------------------------------------------------
◎概要
@@ -373,6 +373,7 @@ sample/{echo,hello}.bfは http://www.kmonos.net/alang/etc/brainfuck.php から -----------------------------------------------------------------------------
◎履歴
+2018/10/29 LabelManagerのデストラクタでLabelから参照を切り離す
2018/10/21 RegRip +/intの形をサポート Xbyak::CastToを削除
2018/10/15 util::StackFrameでmovの代わりにpush/popを使う
2018/09/19 ver 5.73 vpslld, vpslldq, vpsllwなどの(reg, mem, imm8)に対するevexエンコーディング修整
diff --git a/test/jmp.cpp b/test/jmp.cpp index 6a3b461..9fe8ff6 100644 --- a/test/jmp.cpp +++ b/test/jmp.cpp @@ -1016,9 +1016,9 @@ struct GetAddressCode1 : Xbyak::CodeGenerator { }; struct CodeLabelTable : Xbyak::CodeGenerator { - static const int ret0 = 3; - static const int ret1 = 5; - static const int ret2 = 8; + enum { ret0 = 3 }; + enum { ret1 = 5 }; + enum { ret2 = 8 }; CodeLabelTable() { using namespace Xbyak; @@ -1225,3 +1225,48 @@ CYBOZU_TEST_AUTO(rip_addr_with_fixed_buf) code.setProtectModeRW(); } #endif + +struct ReleaseTestCode : Xbyak::CodeGenerator { + ReleaseTestCode(Label& L1, Label& L2, Label& L3) + { + L(L1); + jmp(L1); + L(L2); + jmp(L3); // not assigned + } +}; + +/* + code must unlink label if code is destroyed +*/ +CYBOZU_TEST_AUTO(release_label_after_code) +{ + puts("---"); + { + Label L1, L2, L3, L4, L5; + { + ReleaseTestCode code(L1, L2, L3); + CYBOZU_TEST_ASSERT(L1.getId() > 0); + CYBOZU_TEST_ASSERT(L1.getAddress() != 0); + CYBOZU_TEST_ASSERT(L2.getId() > 0); + CYBOZU_TEST_ASSERT(L2.getAddress() != 0); + CYBOZU_TEST_ASSERT(L3.getId() > 0); + CYBOZU_TEST_ASSERT(L3.getAddress() == 0); // L3 is not assigned + code.assignL(L4, L1); + L5 = L1; + printf("id=%d %d %d %d %d\n", L1.getId(), L2.getId(), L3.getId(), L4.getId(), L5.getId()); + } + puts("code is released"); + CYBOZU_TEST_ASSERT(L1.getId() == 0); + CYBOZU_TEST_ASSERT(L1.getAddress() == 0); + CYBOZU_TEST_ASSERT(L2.getId() == 0); + CYBOZU_TEST_ASSERT(L2.getAddress() == 0); +// CYBOZU_TEST_ASSERT(L3.getId() == 0); // L3 is not assigned so not cleared + CYBOZU_TEST_ASSERT(L3.getAddress() == 0); + CYBOZU_TEST_ASSERT(L4.getId() == 0); + CYBOZU_TEST_ASSERT(L4.getAddress() == 0); + CYBOZU_TEST_ASSERT(L5.getId() == 0); + CYBOZU_TEST_ASSERT(L5.getAddress() == 0); + printf("id=%d %d %d %d %d\n", L1.getId(), L2.getId(), L3.getId(), L4.getId(), L5.getId()); + } +} diff --git a/xbyak/xbyak.h b/xbyak/xbyak.h index 0b0d835..03a2419 100644 --- a/xbyak/xbyak.h +++ b/xbyak/xbyak.h @@ -40,6 +40,8 @@ // This covers -std=(gnu|c)++(0x|11|1y), -stdlib=libc++, and modern Microsoft. #if ((defined(_MSC_VER) && (_MSC_VER >= 1600)) || defined(_LIBCPP_VERSION) ||\ ((__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__))) + #include <unordered_set> + #define XBYAK_STD_UNORDERED_SET std::unordered_set #include <unordered_map> #define XBYAK_STD_UNORDERED_MAP std::unordered_map #define XBYAK_STD_UNORDERED_MULTIMAP std::unordered_multimap @@ -49,16 +51,22 @@ libstdcxx 20070719 (from GCC 4.2.1, the last GPL 2 version). */ #elif XBYAK_GNUC_PREREQ(4, 5) || (XBYAK_GNUC_PREREQ(4, 2) && __GLIBCXX__ >= 20070719) || defined(__INTEL_COMPILER) || defined(__llvm__) + #include <tr1/unordered_set> + #define XBYAK_STD_UNORDERED_SET std::tr1::unordered_set #include <tr1/unordered_map> #define XBYAK_STD_UNORDERED_MAP std::tr1::unordered_map #define XBYAK_STD_UNORDERED_MULTIMAP std::tr1::unordered_multimap #elif defined(_MSC_VER) && (_MSC_VER >= 1500) && (_MSC_VER < 1600) + #include <unordered_set> + #define XBYAK_STD_UNORDERED_SET std::tr1::unordered_set #include <unordered_map> #define XBYAK_STD_UNORDERED_MAP std::tr1::unordered_map #define XBYAK_STD_UNORDERED_MULTIMAP std::tr1::unordered_multimap #else + #include <set> + #define XBYAK_STD_UNORDERED_SET std::set #include <map> #define XBYAK_STD_UNORDERED_MAP std::map #define XBYAK_STD_UNORDERED_MULTIMAP std::multimap @@ -105,7 +113,7 @@ namespace Xbyak { enum { DEFAULT_MAX_CODE_SIZE = 4096, - VERSION = 0x5740 /* 0xABCD = A.BC(D) */ + VERSION = 0x5750 /* 0xABCD = A.BC(D) */ }; #ifndef MIE_INTEGER_TYPE_DEFINED @@ -1129,6 +1137,7 @@ public: Label(const Label& rhs); Label& operator=(const Label& rhs); ~Label(); + void clear() { mgr = 0; id = 0; } int getId() const { return id; } const uint8 *getAddress() const; @@ -1167,6 +1176,7 @@ class LabelManager { }; typedef XBYAK_STD_UNORDERED_MAP<int, ClabelVal> ClabelDefList; typedef XBYAK_STD_UNORDERED_MULTIMAP<int, const JmpLabel> ClabelUndefList; + typedef XBYAK_STD_UNORDERED_SET<Label*> LabelPtrList; CodeArray *base_; // global : stateList_.front(), local : stateList_.back() @@ -1174,6 +1184,7 @@ class LabelManager { mutable int labelId_; ClabelDefList clabelDefList_; ClabelUndefList clabelUndefList_; + LabelPtrList labelPtrList_; int getId(const Label& label) const { @@ -1222,9 +1233,14 @@ class LabelManager { return true; } friend class Label; - void incRefCount(int id) { clabelDefList_[id].refCount++; } - void decRefCount(int id) + void incRefCount(int id, Label *label) { + clabelDefList_[id].refCount++; + labelPtrList_.insert(label); + } + void decRefCount(int id, Label *label) + { + labelPtrList_.erase(label); ClabelDefList::iterator i = clabelDefList_.find(id); if (i == clabelDefList_.end()) return; if (i->second.refCount == 1) { @@ -1243,11 +1259,23 @@ class LabelManager { #endif return !list.empty(); } + // detach all labels linked to LabelManager + void resetLabelPtrList() + { + for (LabelPtrList::iterator i = labelPtrList_.begin(), ie = labelPtrList_.end(); i != ie; ++i) { + (*i)->clear(); + } + labelPtrList_.clear(); + } public: LabelManager() { reset(); } + ~LabelManager() + { + resetLabelPtrList(); + } void reset() { base_ = 0; @@ -1257,6 +1285,7 @@ public: stateList_.push_back(SlabelState()); clabelDefList_.clear(); clabelUndefList_.clear(); + resetLabelPtrList(); } void enterLocal() { @@ -1289,10 +1318,11 @@ public: SlabelState& st = *label.c_str() == '.' ? stateList_.back() : stateList_.front(); define_inner(st.defList, st.undefList, label, base_->getSize()); } - void defineClabel(const Label& label) + void defineClabel(Label& label) { define_inner(clabelDefList_, clabelUndefList_, getId(label), base_->getSize()); label.mgr = this; + labelPtrList_.insert(&label); } void assign(Label& dst, const Label& src) { @@ -1300,6 +1330,7 @@ public: if (i == clabelDefList_.end()) throw Error(ERR_LABEL_ISNOT_SET_BY_L); define_inner(clabelDefList_, clabelUndefList_, dst.id, i->second.offset); dst.mgr = this; + labelPtrList_.insert(&dst); } bool getOffset(size_t *offset, std::string& label) const { @@ -1347,19 +1378,19 @@ inline Label::Label(const Label& rhs) { id = rhs.id; mgr = rhs.mgr; - if (mgr) mgr->incRefCount(id); + if (mgr) mgr->incRefCount(id, this); } inline Label& Label::operator=(const Label& rhs) { if (id) throw Error(ERR_LABEL_IS_ALREADY_SET_BY_L); id = rhs.id; mgr = rhs.mgr; - if (mgr) mgr->incRefCount(id); + if (mgr) mgr->incRefCount(id, this); return *this; } inline Label::~Label() { - if (id && mgr) mgr->decRefCount(id); + if (id && mgr) mgr->decRefCount(id, this); } inline const uint8* Label::getAddress() const { @@ -2163,7 +2194,7 @@ public: const Segment es, cs, ss, ds, fs, gs; #endif void L(const std::string& label) { labelMgr_.defineSlabel(label); } - void L(const Label& label) { labelMgr_.defineClabel(label); } + void L(Label& label) { labelMgr_.defineClabel(label); } Label L() { Label label; L(label); return label; } void inLocalLabel() { labelMgr_.enterLocal(); } void outLocalLabel() { labelMgr_.leaveLocal(); } diff --git a/xbyak/xbyak_mnemonic.h b/xbyak/xbyak_mnemonic.h index 0dc268a..4f81090 100644 --- a/xbyak/xbyak_mnemonic.h +++ b/xbyak/xbyak_mnemonic.h @@ -1,4 +1,4 @@ -const char *getVersionString() const { return "5.74"; } +const char *getVersionString() const { return "5.75"; } void adc(const Operand& op, uint32 imm) { opRM_I(op, imm, 0x10, 2); } void adc(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x10); } void adcx(const Reg32e& reg, const Operand& op) { opGen(reg, op, 0xF6, 0x66, isREG32_REG32orMEM, NONE, 0x38); } |