mirror of
https://github.com/RPCSX/xbyak.git
synced 2025-03-01 15:06:25 +00:00
use reference counter of label
This commit is contained in:
parent
72cdfb80be
commit
502f65aaee
10
test/jmp.cpp
10
test/jmp.cpp
@ -777,6 +777,14 @@ CYBOZU_TEST_AUTO(testAssign)
|
|||||||
jne(dst, T_NEAR);
|
jne(dst, T_NEAR);
|
||||||
ret();
|
ret();
|
||||||
assignL(dst, src);
|
assignL(dst, src);
|
||||||
|
// test of copy label
|
||||||
|
{
|
||||||
|
Label sss(dst);
|
||||||
|
{
|
||||||
|
Label ttt;
|
||||||
|
ttt = src;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
@ -823,4 +831,4 @@ CYBOZU_TEST_AUTO(doubleDefine)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} code;
|
} code;
|
||||||
}
|
}
|
||||||
|
@ -147,6 +147,7 @@ enum {
|
|||||||
ERR_BAD_VSIB_ADDRESSING,
|
ERR_BAD_VSIB_ADDRESSING,
|
||||||
ERR_CANT_CONVERT,
|
ERR_CANT_CONVERT,
|
||||||
ERR_LABEL_ISNOT_SET_BY_L,
|
ERR_LABEL_ISNOT_SET_BY_L,
|
||||||
|
ERR_LABEL_IS_ALREADY_SET_BY_L,
|
||||||
ERR_INTERNAL
|
ERR_INTERNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -194,6 +195,7 @@ public:
|
|||||||
"bad vsib addressing",
|
"bad vsib addressing",
|
||||||
"can't convert",
|
"can't convert",
|
||||||
"label is not set by L()",
|
"label is not set by L()",
|
||||||
|
"label is already set by L()",
|
||||||
"internal error",
|
"internal error",
|
||||||
};
|
};
|
||||||
assert((size_t)err_ < sizeof(errTbl) / sizeof(*errTbl));
|
assert((size_t)err_ < sizeof(errTbl) / sizeof(*errTbl));
|
||||||
@ -884,11 +886,17 @@ struct JmpLabel {
|
|||||||
inner::LabelMode mode;
|
inner::LabelMode mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LabelManager;
|
||||||
|
|
||||||
class Label {
|
class Label {
|
||||||
|
mutable LabelManager *mgr;
|
||||||
mutable int id;
|
mutable int id;
|
||||||
friend class LabelManager;
|
friend class LabelManager;
|
||||||
public:
|
public:
|
||||||
Label() : id(0) {}
|
Label() : mgr(0), id(0) {}
|
||||||
|
Label(const Label& rhs);
|
||||||
|
Label& operator=(const Label& rhs);
|
||||||
|
~Label();
|
||||||
int getId() const { return id; }
|
int getId() const { return id; }
|
||||||
|
|
||||||
// backward compatibility
|
// backward compatibility
|
||||||
@ -925,8 +933,10 @@ class LabelManager {
|
|||||||
// for Label class
|
// for Label class
|
||||||
typedef XBYAK_STD_UNORDERED_MAP<int, size_t> DefinedList2;
|
typedef XBYAK_STD_UNORDERED_MAP<int, size_t> DefinedList2;
|
||||||
typedef XBYAK_STD_UNORDERED_MULTIMAP<int, const JmpLabel> UndefinedList2;
|
typedef XBYAK_STD_UNORDERED_MULTIMAP<int, const JmpLabel> UndefinedList2;
|
||||||
|
typedef XBYAK_STD_UNORDERED_MAP<int, int> RefCount;
|
||||||
DefinedList2 definedList2_;
|
DefinedList2 definedList2_;
|
||||||
UndefinedList2 undefinedList2_;
|
UndefinedList2 undefinedList2_;
|
||||||
|
RefCount refCount_;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ --> @@.<num>
|
@@ --> @@.<num>
|
||||||
@ -991,6 +1001,19 @@ class LabelManager {
|
|||||||
*offset = i->second;
|
*offset = i->second;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
friend class Label;
|
||||||
|
void incRefCount(int id) { refCount_[id]++; }
|
||||||
|
void decRefCount(int id)
|
||||||
|
{
|
||||||
|
RefCount::iterator i = refCount_.find(id);
|
||||||
|
if (i == refCount_.end()) return;
|
||||||
|
if (i->second == 1) {
|
||||||
|
refCount_.erase(i);
|
||||||
|
definedList2_.erase(id);
|
||||||
|
} else {
|
||||||
|
--i->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
LabelManager()
|
LabelManager()
|
||||||
: base_(0)
|
: base_(0)
|
||||||
@ -1036,12 +1059,16 @@ public:
|
|||||||
void define2(const Label& label)
|
void define2(const Label& label)
|
||||||
{
|
{
|
||||||
define_inner(definedList2_, undefinedList2_, getId(label), base_->getSize());
|
define_inner(definedList2_, undefinedList2_, getId(label), base_->getSize());
|
||||||
|
refCount_[label.id] = 1;
|
||||||
|
label.mgr = this;
|
||||||
}
|
}
|
||||||
void assign(Label& dst, const Label& src)
|
void assign(Label& dst, const Label& src)
|
||||||
{
|
{
|
||||||
DefinedList2::const_iterator i = definedList2_.find(src.id);
|
DefinedList2::const_iterator i = definedList2_.find(src.id);
|
||||||
if (i == definedList2_.end()) throw Error(ERR_LABEL_ISNOT_SET_BY_L);
|
if (i == definedList2_.end()) throw Error(ERR_LABEL_ISNOT_SET_BY_L);
|
||||||
define_inner(definedList2_, undefinedList2_, dst.id, i->second);
|
define_inner(definedList2_, undefinedList2_, dst.id, i->second);
|
||||||
|
refCount_[dst.id] = 1;
|
||||||
|
dst.mgr = this;
|
||||||
}
|
}
|
||||||
bool getOffset(size_t *offset, const std::string& label) const
|
bool getOffset(size_t *offset, const std::string& label) const
|
||||||
{
|
{
|
||||||
@ -1079,6 +1106,25 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline Label::Label(const Label& rhs)
|
||||||
|
{
|
||||||
|
id = rhs.id;
|
||||||
|
mgr = rhs.mgr;
|
||||||
|
if (mgr) mgr->incRefCount(id);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline Label::~Label()
|
||||||
|
{
|
||||||
|
if (id && mgr) mgr->decRefCount(id);
|
||||||
|
}
|
||||||
|
|
||||||
class CodeGenerator : public CodeArray {
|
class CodeGenerator : public CodeArray {
|
||||||
public:
|
public:
|
||||||
enum LabelType {
|
enum LabelType {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user