Smaller c_Continuation

Save 16 bytes in c_Continuation by moving running and done flags to o_subclassData and making labels 2-byte.
Esse commit está contido em:
Alexandru Suhan
2013-06-03 12:56:57 -07:00
commit de Sara Golemon
commit 93edca4397
7 arquivos alterados com 63 adições e 44 exclusões
@@ -98,7 +98,7 @@ void c_ContinuationWaitHandle::Create(c_Continuation* continuation) {
if (UNLIKELY(continuation->m_index != -1)) {
Object e(SystemLib::AllocInvalidOperationExceptionObject(
continuation->m_running
continuation->running()
? "Encountered an attempt to start currently running continuation"
: "Encountered an attempt to start tainted continuation"));
throw e;
@@ -159,7 +159,7 @@ void c_ContinuationWaitHandle::run() {
}
// continuation finished, retrieve result from its m_value
if (m_continuation->m_done) {
if (m_continuation->done()) {
markAsSucceeded(m_continuation->m_value.asTypedValue());
return;
}
+11 -5
Ver Arquivo
@@ -49,8 +49,9 @@ c_Continuation::c_Continuation(Class* cb) :
m_index(-1LL),
m_value(Variant::NullInit()),
m_received(Variant::NullInit()),
m_done(false), m_running(false),
m_vmFunc(nullptr), m_label(0ll) {
m_origFunc(nullptr),
m_label(0) {
o_subclassData.u16 = 0;
}
c_Continuation::~c_Continuation() {
@@ -66,7 +67,7 @@ c_Continuation::~c_Continuation() {
if (ar->hasVarEnv()) {
ar->getVarEnv()->detach(ar);
} else {
frame_free_locals_inl(ar, m_vmFunc->numLocals());
frame_free_locals_inl(ar, ar->m_func->numLocals());
}
}
@@ -74,6 +75,7 @@ void c_Continuation::t___construct() {}
void c_Continuation::t_update(int64_t label, CVarRef value) {
m_label = label;
assert(m_label == label); // check m_label for truncation
m_value.assignVal(value);
}
@@ -128,7 +130,7 @@ void c_Continuation::t_rewind() {
bool c_Continuation::t_valid() {
const_assert(false);
return !m_done;
return !done();
}
void c_Continuation::t_send(CVarRef v) {
@@ -140,7 +142,11 @@ void c_Continuation::t_raise(CVarRef v) {
}
String c_Continuation::t_getorigfuncname() {
return String(const_cast<StringData*>(m_origFuncName));
static auto const closureName = StringData::GetStaticString("{closure}");
auto const origName = m_origFunc->isClosureBody() ? closureName
: m_origFunc->name();
assert(origName->isStatic());
return String(const_cast<StringData*>(origName));
}
String c_Continuation::t_getcalledclass() {
+20 -16
Ver Arquivo
@@ -38,22 +38,18 @@ class c_Continuation : public ExtObjectData {
virtual void sweep();
void operator delete(void* p) {
c_Continuation* this_ = (c_Continuation*)p;
DELETEOBJSZ(sizeForLocalsAndIters(this_->m_vmFunc->numLocals(),
this_->m_vmFunc->numIterators()))(this_);
DELETEOBJSZ((char*)(this_->m_arPtr + 1) - (char*)p)(this_);
}
explicit c_Continuation(Class* cls = c_Continuation::s_cls);
~c_Continuation();
public:
void init(const Func* vmFunc,
const StringData* origFuncName,
void init(const Func* origFunc,
ObjectData* thisPtr,
ArrayData* args) noexcept {
m_vmFunc = const_cast<Func*>(vmFunc);
assert(m_vmFunc);
m_origFuncName = origFuncName;
assert(m_origFuncName->isStatic());
m_origFunc = const_cast<Func*>(origFunc);
assert(m_origFunc);
if (thisPtr != nullptr) {
m_obj = thisPtr;
@@ -64,6 +60,17 @@ public:
m_args = args;
}
bool done() const { return o_subclassData.u8[0]; }
bool running() const { return o_subclassData.u8[1]; }
void setDone(bool done) { o_subclassData.u8[0] = done; }
void setRunning(bool running) { o_subclassData.u8[1] = running; }
static constexpr uint doneOffset() {
return offsetof(c_Continuation, o_subclassData);
}
static constexpr uint runningOffset() {
return offsetof(c_Continuation, o_subclassData) + 1;
}
void t___construct();
void t_update(int64_t label, CVarRef value);
Object t_getwaithandle();
@@ -101,15 +108,15 @@ public:
void call_raise(ObjectData* e);
inline void preNext() {
if (m_done) {
if (done()) {
throw_exception(Object(SystemLib::AllocExceptionObject(
"Continuation is already finished")));
}
if (m_running) {
if (running()) {
throw_exception(Object(SystemLib::AllocExceptionObject(
"Continuation is already running")));
}
m_running = true;
setRunning(true);
++m_index;
}
@@ -126,13 +133,10 @@ public:
int64_t m_index;
Variant m_value;
Variant m_received;
const StringData* m_origFuncName;
bool m_done;
bool m_running;
Func *m_origFunc;
int32_t m_label;
int m_localsOffset;
Func *m_vmFunc;
int64_t m_label;
ActRec* m_arPtr;
p_ContinuationWaitHandle m_waitHandle;
+6 -11
Ver Arquivo
@@ -7036,12 +7036,7 @@ VMExecutionContext::createContinuationHelper(const Func* origFunc,
);
cont->incRefCount();
cont->setNoDestruct();
static auto const closureName = StringData::GetStaticString("{closure}");
auto const origName = origFunc->isClosureBody() ? closureName
: origFunc->name();
cont->init(genFunc, origName, thisPtr, args);
cont->init(origFunc, thisPtr, args);
// The ActRec corresponding to the generator body lives as long as the object
// does. We set it up once, here, and then just change FP to point to it when
@@ -7290,7 +7285,7 @@ inline void OPTBLD_INLINE VMExecutionContext::iopContReceive(PC& pc) {
inline void OPTBLD_INLINE VMExecutionContext::iopContRetC(PC& pc) {
NEXT();
c_Continuation* cont = frame_continuation(m_fp);
cont->m_done = true;
cont->setDone(true);
tvSetIgnoreRef(m_stack.topC(), cont->m_value.asTypedValue());
m_stack.popC();
@@ -7333,7 +7328,7 @@ inline void OPTBLD_INLINE VMExecutionContext::iopContValid(PC& pc) {
NEXT();
TypedValue* tv = m_stack.allocTV();
tvWriteUninit(tv);
tvAsVariant(tv) = !this_continuation(m_fp)->m_done;
tvAsVariant(tv) = !this_continuation(m_fp)->done();
}
inline void OPTBLD_INLINE VMExecutionContext::iopContCurrent(PC& pc) {
@@ -7348,14 +7343,14 @@ inline void OPTBLD_INLINE VMExecutionContext::iopContCurrent(PC& pc) {
inline void OPTBLD_INLINE VMExecutionContext::iopContStopped(PC& pc) {
NEXT();
this_continuation(m_fp)->m_running = false;
this_continuation(m_fp)->setRunning(false);
}
inline void OPTBLD_INLINE VMExecutionContext::iopContHandle(PC& pc) {
NEXT();
c_Continuation* cont = this_continuation(m_fp);
cont->m_running = false;
cont->m_done = true;
cont->setRunning(false);
cont->setDone(true);
cont->m_value.setNull();
Variant exn = tvAsVariant(m_stack.topTV());
+7 -7
Ver Arquivo
@@ -5135,17 +5135,17 @@ void CodeGenerator::cgLinkContVarEnv(IRInstruction* inst) {
void CodeGenerator::cgContPreNext(IRInstruction* inst) {
auto contReg = m_regs[inst->src(0)].reg();
const Offset doneOffset = CONTOFF(m_done);
static_assert((doneOffset + 1) == CONTOFF(m_running),
"m_done should immediately precede m_running");
// Check m_done and m_running at the same time
m_as.test_imm32_disp_reg32(0x0101, doneOffset, contReg);
const Offset doneOffset = c_Continuation::doneOffset();
static_assert((doneOffset + 1) == c_Continuation::runningOffset(),
"done should immediately precede running");
// Check done and running at the same time
m_as.test_imm16_disp_reg16(0x0101, doneOffset, contReg);
emitFwdJcc(CC_NZ, inst->taken());
// ++m_index
m_as.add_imm64_disp_reg64(0x1, CONTOFF(m_index), contReg);
// m_running = true
m_as.store_imm8_disp_reg(0x1, CONTOFF(m_running), contReg);
// running = true
m_as.store_imm8_disp_reg(0x1, c_Continuation::runningOffset(), contReg);
}
void CodeGenerator::cgContStartedCheck(IRInstruction* inst) {
+5 -3
Ver Arquivo
@@ -788,15 +788,17 @@ class RawMemSlot {
: m_offset(offset), m_size(size), m_type(type), m_allowExtra(allowExtra) { }
static RawMemSlot& GetContLabel() {
static RawMemSlot m(CONTOFF(m_label), Transl::sz::qword, Type::Int);
static RawMemSlot m(CONTOFF(m_label), Transl::sz::dword, Type::Int);
return m;
}
static RawMemSlot& GetContDone() {
static RawMemSlot m(CONTOFF(m_done), Transl::sz::byte, Type::Bool);
static RawMemSlot m(c_Continuation::doneOffset(), Transl::sz::byte,
Type::Bool);
return m;
}
static RawMemSlot& GetContRunning() {
static RawMemSlot m(CONTOFF(m_running), Transl::sz::byte, Type::Bool);
static RawMemSlot m(c_Continuation::runningOffset(), Transl::sz::byte,
Type::Bool);
return m;
}
static RawMemSlot& GetContARPtr() {
+12
Ver Arquivo
@@ -1794,6 +1794,12 @@ struct X64Assembler {
sz::byte);
}
void emitIM16(X64Instr op, RegNumber br, RegNumber ir, int s,
int disp, ssize_t imm) ALWAYS_INLINE {
emitCMX(op, 0, br, ir, s, disp, reg::noreg, false, imm, true,
sz::word);
}
void emitIM32(X64Instr op, RegNumber br, RegNumber ir, int s,
int disp, ssize_t imm) ALWAYS_INLINE {
emitCMX(op, 0, br, ir, s, disp, reg::noreg, false, imm, true,
@@ -2039,6 +2045,12 @@ public:
inline void name ## _imm32_reg32(int64_t imm, RegNumber rdest) { \
emitIR32(instr_ ## name, rdest, safe_cast<int32_t>(imm)); \
} \
/* op imm, disp(rdest) */ \
inline void name ## _imm16_disp_reg16(int64_t imm, int disp, \
RegNumber rdest) { \
emitIM16(instr_ ## name, rdest, reg::noreg, \
sz::byte, disp, safe_cast<int16_t>(imm)); \
} \
/* opl imm, disp(rdest) */ \
inline void name ## _imm32_disp_reg32(int64_t imm, int disp, \
RegNumber rdest) { \