Label::getAddress() returns 0 if ready() is not called and in AutoGrow mode

This commit is contained in:
MITSUNARI Shigeo 2016-12-14 12:23:30 +09:00
parent 86759a3bc8
commit fe4765d2fe
4 changed files with 44 additions and 4 deletions

View File

@ -1,5 +1,5 @@
Xbyak 5.34 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++
Xbyak 5.40 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++
=============
Abstract
@ -220,6 +220,15 @@ The above jmp opecode jumps label1.
* srcLabel must be used in L().
* dstLabel must not be used in L().
Label::getAddress() returns the address specified by the label instance and 0 if not specified.
```
// not AutoGrow mode
Label label;
assert(label.getAddress() == 0);
L(label);
assert(label.getAddress() == getCurr());
```
### Rip
```
Label label;
@ -323,6 +332,7 @@ The header files under xbyak/ are independent of cybozulib.
History
-------------
* 2016/Dec/14 ver 5.40 add Label::getAddress() method to get the pointer specified by the label
* 2016/Dec/09 ver 5.34 fix handling of negative offsets when encoding disp8N(thanks to rsdubtso)
* 2016/Dec/08 ver 5.33 fix encoding of vpbroadcast{b,w,d,q}, vpinsr{b,w}, vpextr{b,w} for disp8N
* 2016/Dec/01 ver 5.32 rename __xgetbv() to _xgetbv() to support clang for Visual Studio(thanks to freiro)

View File

@ -1,5 +1,5 @@
C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 5.34
C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 5.40
-----------------------------------------------------------------------------
◎概要
@ -258,6 +258,16 @@ void func2()
* srcLabelはL()により飛び先が確定していないといけません。
* dstLabelはL()により飛び先が確定していてはいけません。
ラベルは`getAddress()`によりそのアドレスを取得できます。
未定義のときは0が返ります。
```
// not AutoGrow mode
Label label;
assert(label.getAddress(), 0);
L(label);
assert(label.getAddress(), getCurr());
```
・Xbyak::CodeGenerator()コンストラクタインタフェース
@param maxSize [in] コード生成最大サイズ(デフォルト4096byte)
@ -333,6 +343,7 @@ cybozulibは単体テストでのみ利用されていて、xbyak/ディレク
-----------------------------------------------------------------------------
◎履歴
2016/12/14 ver 5.40 Labelが示すアドレスを取得するLabel::getAddress()追加
2016/12/07 ver 5.34 disp8N時の負のオフセット処理の修正(thanks to rsdubtso)
2016/12/06 ver 5.33 disp8N時のvpbroadcast{b,w,d,q}, vpinsr{b,w}, vpextr{b,w}のバグ修正
2016/12/01 ver 5.32 clang for Visual Studioサポートのために__xgetbv()を_xgetbv()に変更(thanks to freiro)

View File

@ -1001,15 +1001,28 @@ struct GetAddressCode2 : Xbyak::CodeGenerator {
, a1(0)
, a3(0)
{
bool autoGrow = size != 4096;
nop();
L(L1);
if (autoGrow) {
CYBOZU_TEST_EQUAL_POINTER(L1.getAddress(), 0);
}
a1 = getSize();
nop();
jmp(L2);
if (autoGrow) {
CYBOZU_TEST_EQUAL_POINTER(L2.getAddress(), 0);
}
L(L3);
a3 = getSize();
if (autoGrow) {
CYBOZU_TEST_EQUAL_POINTER(L3.getAddress(), 0);
}
nop();
assignL(L2, L1);
if (autoGrow) {
CYBOZU_TEST_EQUAL_POINTER(L2.getAddress(), 0);
}
}
};

View File

@ -105,7 +105,7 @@ namespace Xbyak {
enum {
DEFAULT_MAX_CODE_SIZE = 4096,
VERSION = 0x5340 /* 0xABCD = A.BC(D) */
VERSION = 0x5400 /* 0xABCD = A.BC(D) */
};
#ifndef MIE_INTEGER_TYPE_DEFINED
@ -786,6 +786,7 @@ protected:
size_t maxSize_;
uint8 *top_;
size_t size_;
bool isCalledCalcJmpAddress_;
/*
allocate new memory and copy old data to the new area
@ -805,11 +806,13 @@ protected:
*/
void calcJmpAddress()
{
if (isCalledCalcJmpAddress_) return;
for (AddrInfoList::const_iterator i = addrInfoList_.begin(), ie = addrInfoList_.end(); i != ie; ++i) {
uint64 disp = i->getVal(top_);
rewrite(i->codeOffset, disp, i->jmpSize);
}
if (alloc_->useProtect() && !protect(top_, size_, true)) throw Error(ERR_CANT_PROTECT);
isCalledCalcJmpAddress_ = true;
}
public:
explicit CodeArray(size_t maxSize, void *userPtr = 0, Allocator *allocator = 0)
@ -818,6 +821,7 @@ public:
, maxSize_(maxSize)
, top_(type_ == USER_BUF ? reinterpret_cast<uint8*>(userPtr) : alloc_->alloc((std::max<size_t>)(maxSize, 1)))
, size_(0)
, isCalledCalcJmpAddress_(false)
{
if (maxSize_ > 0 && top_ == 0) throw Error(ERR_CANT_ALLOC);
if ((type_ == ALLOC_BUF && alloc_->useProtect()) && !protect(top_, maxSize, true)) {
@ -913,6 +917,7 @@ public:
addrInfoList_.push_back(AddrInfo(offset, val, size, mode));
}
bool isAutoGrow() const { return type_ == AUTO_GROW; }
bool isCalledCalcJmpAddress() const { return isCalledCalcJmpAddress_; }
/**
change exec permission of memory
@param addr [in] buffer address
@ -1258,6 +1263,7 @@ public:
}
bool hasUndefClabel() const { return hasUndefinedLabel_inner(clabelUndefList_); }
const uint8 *getCode() const { return base_->getCode(); }
bool isReady() const { return !base_->isAutoGrow() || base_->isCalledCalcJmpAddress(); }
};
inline Label::Label(const Label& rhs)
@ -1280,7 +1286,7 @@ inline Label::~Label()
}
inline const uint8* Label::getAddress() const
{
if (mgr == 0) return 0;
if (mgr == 0 || !mgr->isReady()) return 0;
size_t offset;
if (!mgr->getOffset(&offset, *this)) return 0;
return mgr->getCode() + offset;