diff --git a/src/dobject.h b/src/dobject.h index 5cf877fed..7aeedc57c 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -357,6 +357,7 @@ protected: template friend T* Create(Args&&... args); + friend class JitCompiler; }; // This is the only method aside from calling CreateNew that should be used for creating DObjects diff --git a/src/scripting/vm/jit_load.cpp b/src/scripting/vm/jit_load.cpp index 1c6061541..89466de94 100644 --- a/src/scripting/vm/jit_load.cpp +++ b/src/scripting/vm/jit_load.cpp @@ -76,6 +76,28 @@ void JitCompiler::EmitLFP() cc.lea(regA[A], asmjit::x86::ptr(vmframe, offsetExtra)); } +#if 1 // Inline implementation + +void JitCompiler::EmitMETA() +{ + auto label = EmitThrowExceptionLabel(X_READ_NIL); + cc.test(regA[B], regA[B]); + cc.je(label); + + cc.mov(regA[A], asmjit::x86::qword_ptr(regA[B], offsetof(DObject, Class))); + cc.mov(regA[A], asmjit::x86::qword_ptr(regA[A], offsetof(PClass, Meta))); +} + +void JitCompiler::EmitCLSS() +{ + auto label = EmitThrowExceptionLabel(X_READ_NIL); + cc.test(regA[B], regA[B]); + cc.je(label); + cc.mov(regA[A], asmjit::x86::qword_ptr(regA[B], offsetof(DObject, Class))); +} + +#else + static uint8_t *GetClassMeta(DObject *o) { return o->GetClass()->Meta; @@ -112,6 +134,8 @@ void JitCompiler::EmitCLSS() cc.mov(regA[A], result); } +#endif + ///////////////////////////////////////////////////////////////////////////// // Load from memory. rA = *(rB + rkC) @@ -221,6 +245,41 @@ void JitCompiler::EmitLS_R() call->setArg(1, ptr); } +#if 1 // Inline read barrier impl + +void JitCompiler::EmitReadBarrier() +{ + auto isnull = cc.newLabel(); + cc.test(regA[A], regA[A]); + cc.je(isnull); + + auto mask = newTempIntPtr(); + cc.mov(mask.r32(), asmjit::x86::dword_ptr(regA[A], offsetof(DObject, ObjectFlags))); + cc.shl(mask, 63 - 5); // put OF_EuthanizeMe (1 << 5) in the highest bit + cc.sar(mask, 63); // sign extend so all bits are set if OF_EuthanizeMe was set + cc.andn(regA[A], mask, regA[A]); + + cc.bind(isnull); +} + +void JitCompiler::EmitLO() +{ + EmitNullPointerThrow(B, X_READ_NIL); + + cc.mov(regA[A], asmjit::x86::ptr(regA[B], konstd[C])); + EmitReadBarrier(); +} + +void JitCompiler::EmitLO_R() +{ + EmitNullPointerThrow(B, X_READ_NIL); + + cc.mov(regA[A], asmjit::x86::ptr(regA[B], regD[C])); + EmitReadBarrier(); +} + +#else + static DObject *ReadBarrier(DObject *p) { return GC::ReadBarrier(p); @@ -254,6 +313,8 @@ void JitCompiler::EmitLO_R() cc.mov(regA[A], result); } +#endif + void JitCompiler::EmitLP() { EmitNullPointerThrow(B, X_READ_NIL); diff --git a/src/scripting/vm/jitintern.h b/src/scripting/vm/jitintern.h index 69422557f..29e53059b 100644 --- a/src/scripting/vm/jitintern.h +++ b/src/scripting/vm/jitintern.h @@ -203,6 +203,8 @@ private: asmjit::X86Gp newResultIntPtr() { return newTempRegister(regResultIntPtr, resultPosIntPtr, "resultPtr", [&](const char *name) { return cc.newIntPtr(name); }); } asmjit::X86Xmm newResultXmmSd() { return newTempRegister(regResultXmmSd, resultPosXmmSd, "resultXmmSd", [&](const char *name) { return cc.newXmmSd(name); }); } + void EmitReadBarrier(); + void EmitNullPointerThrow(int index, EVMAbortException reason); void EmitThrowException(EVMAbortException reason); asmjit::Label EmitThrowExceptionLabel(EVMAbortException reason);