diff --git a/src/assembler.h b/src/assembler.h index 0075ed1c8e..6d6033e38f 100644 --- a/src/assembler.h +++ b/src/assembler.h @@ -282,8 +282,6 @@ class Assembler { virtual void updateCall(UnaryOperation op, bool assertAlignment, void* returnAddress, void* newTarget) = 0; - virtual unsigned constantCallSize() = 0; - virtual uintptr_t getConstant(const void* src) = 0; virtual void setConstant(void* dst, uintptr_t constant) = 0; @@ -293,8 +291,8 @@ class Assembler { virtual unsigned frameHeaderSize() = 0; virtual unsigned frameReturnAddressSize() = 0; virtual unsigned frameFooterSize() = 0; - virtual unsigned returnAddressOffset() = 0; - virtual unsigned framePointerOffset() = 0; + virtual int returnAddressOffset() = 0; + virtual int framePointerOffset() = 0; virtual void nextFrame(void** stack, void** base) = 0; virtual void plan diff --git a/src/compile.cpp b/src/compile.cpp index 881ff5d30b..20cbca17bf 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -487,11 +487,11 @@ class TraceElementPromise: public Promise { virtual int64_t value() { assert(s, resolved()); - return reinterpret_cast(trace->address); + return trace->address->value(); } virtual bool resolved() { - return trace->address != 0; + return trace->address != 0 and trace->address->resolved(); } System* s; @@ -1943,7 +1943,7 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall, Compiler::Operand* result = c->stackCall (returnAddress, flags | Compiler::Aligned, - 0, + trace, rSize, methodParameterFootprint(t, target)); @@ -1982,14 +1982,16 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall, } } -void +bool compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall) { unsigned rSize = resultSize(t, methodReturnCode(t, target)); Compiler::Operand* result = 0; - if (not emptyMethod(t, target)) { + if (emptyMethod(t, target)) { + tailCall = false; + } else { BootContext* bc = frame->context->bootContext; if (bc) { if (methodClass(t, target) == methodClass(t, frame->context->method) @@ -2024,6 +2026,8 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall) if (rSize) { pushReturnValue(t, frame, methodReturnCode(t, target), result); } + + return tailCall; } void @@ -3157,7 +3161,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, tailCall = isTailCall(t, code, ip, context->method, target); - compileDirectInvoke(t, frame, target, tailCall); + tailCall = compileDirectInvoke(t, frame, target, tailCall); } break; case invokestatic: { @@ -3170,7 +3174,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, tailCall = isTailCall(t, code, ip, context->method, target); - compileDirectInvoke(t, frame, target, tailCall); + tailCall = compileDirectInvoke(t, frame, target, tailCall); } break; case invokevirtual: { @@ -3199,7 +3203,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Compiler::Operand* result = c->stackCall (c->memory(classOperand, offset, 0, 1), - tailCall ? Compiler::TailCall : 0, + tailCall ? Compiler::TailJump : 0, frame->trace(0, 0), rSize, parameterFootprint); @@ -4594,11 +4598,9 @@ compileMethod2(MyThread* t, void* ip) } else { void* address = reinterpret_cast(methodAddress(t, target)); uint8_t* updateIp = static_cast(ip); - if (callNodeFlags(t, node) & TraceElement::TailCall) { - updateIp -= t->arch->constantCallSize(); - } - updateCall(t, Call, true, updateIp, address); + updateCall(t, (callNodeFlags(t, node) & TraceElement::TailCall) + ? Jump : Call, true, updateIp, address); return address; } diff --git a/src/compiler.cpp b/src/compiler.cpp index 0a90033ce9..6906be054f 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -649,10 +649,8 @@ int frameIndex(Context* c, int localIndex) { assert(c, localIndex >= 0); - assert(c, localIndex < static_cast - (c->parameterFootprint + c->localFootprint)); - int index = c->alignedFrameSize + c->parameterFootprint - localIndex; + int index = c->alignedFrameSize + c->parameterFootprint - localIndex - 1; if (localIndex < static_cast(c->parameterFootprint)) { index += c->arch->frameHeaderSize(); @@ -661,6 +659,7 @@ frameIndex(Context* c, int localIndex) } assert(c, index >= 0); + assert(c, static_cast(index) < totalFrameSize(c)); return index; } @@ -668,15 +667,31 @@ frameIndex(Context* c, int localIndex) unsigned frameIndexToOffset(Context* c, unsigned frameIndex) { + assert(c, frameIndex < totalFrameSize(c)); + return (frameIndex + c->arch->frameFooterSize()) * BytesPerWord; } unsigned offsetToFrameIndex(Context* c, unsigned offset) { + assert(c, static_cast + ((offset / BytesPerWord) - c->arch->frameFooterSize()) >= 0); + + assert(c, (offset / BytesPerWord) - c->arch->frameFooterSize() + < totalFrameSize(c)); + return (offset / BytesPerWord) - c->arch->frameFooterSize(); } +unsigned +frameBase(Context* c) +{ + return c->alignedFrameSize - 1 + - c->arch->frameFooterSize() + + c->arch->frameHeaderSize(); +} + class FrameIterator { public: class Element { @@ -2307,10 +2322,10 @@ class CallEvent: public Event { int returnAddressIndex = -1; int framePointerIndex = -1; - if (flags & (Compiler::TailJump | Compiler::TailCall)) { + if (flags & Compiler::TailJump) { assert(c, argumentCount == 0); - unsigned base = c->alignedFrameSize - c->arch->frameFooterSize(); + int base = frameBase(c); returnAddressIndex = base + c->arch->returnAddressOffset(); framePointerIndex = base + c->arch->framePointerOffset(); @@ -2387,9 +2402,7 @@ class CallEvent: public Event { addRead(c, this, s->value, read (c, SiteMask(1 << MemoryOperand, 0, frameIndex))); } - } - else if ((flags & (Compiler::TailJump | Compiler::TailCall)) == 0) - { + } else if ((flags & Compiler::TailJump) == 0) { unsigned logicalIndex = ::frameIndex (c, s->index + c->localFootprint); @@ -2405,7 +2418,7 @@ class CallEvent: public Event { -- footprint; - if (footprint == 0) { + if (footprint == 0 and (flags & Compiler::TailJump) == 0) { unsigned logicalIndex = ::frameIndex (c, s->index + c->localFootprint); @@ -2418,7 +2431,7 @@ class CallEvent: public Event { ++ frameIndex; } - if ((flags & (Compiler::TailJump | Compiler::TailCall)) == 0) { + if ((flags & Compiler::TailJump) == 0) { popIndex = c->alignedFrameSize - c->arch->frameFooterSize() @@ -2438,19 +2451,11 @@ class CallEvent: public Event { virtual void compile(Context* c) { UnaryOperation op; - if (flags & (Compiler::TailJump | Compiler::TailCall)) { - if (flags & Compiler::TailJump) { - if (flags & Compiler::Aligned) { - op = AlignedJump; - } else { - op = Jump; - } + if (flags & Compiler::TailJump) { + if (flags & Compiler::Aligned) { + op = AlignedJump; } else { - if (flags & Compiler::Aligned) { - op = AlignedCall; - } else { - op = Call; - } + op = Jump; } assert(c, returnAddressSurrogate == 0 @@ -2464,8 +2469,8 @@ class CallEvent: public Event { (framePointerSurrogate->source)->number : NoRegister); int offset - = static_cast(c->arch->argumentFootprint(c->parameterFootprint)) - - static_cast(c->arch->argumentFootprint(stackArgumentFootprint)); + = static_cast(c->arch->argumentFootprint(stackArgumentFootprint)) + - static_cast(c->arch->argumentFootprint(c->parameterFootprint)); c->assembler->popFrameForTailCall(c->alignedFrameSize, offset, ras, fps); } else if (flags & Compiler::Aligned) { @@ -4920,7 +4925,7 @@ class MyCompiler: public Compiler { new (c.frameResources + i) FrameResource; } - unsigned base = alignedFrameSize - c.arch->frameFooterSize(); + unsigned base = frameBase(&c); c.frameResources[base + c.arch->returnAddressOffset()].reserved = true; c.frameResources[base + c.arch->framePointerOffset()].reserved = true; diff --git a/src/compiler.h b/src/compiler.h index b2fed6f48a..98c5dfb620 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -27,8 +27,7 @@ class Compiler { static const unsigned Aligned = 1 << 0; static const unsigned NoReturn = 1 << 1; - static const unsigned TailCall = 1 << 2; - static const unsigned TailJump = 1 << 3; + static const unsigned TailJump = 1 << 2; class Operand { }; class StackElement { }; diff --git a/src/x86.cpp b/src/x86.cpp index 53bce312d5..b33b418263 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -673,6 +673,13 @@ alignedCallC(Context* c, unsigned size, Assembler::Constant* a) callC(c, size, a); } +void +alignedJumpC(Context* c, unsigned size, Assembler::Constant* a) +{ + new (c->zone->allocate(sizeof(AlignmentPadding))) AlignmentPadding(c); + jumpC(c, size, a); +} + void pushR(Context* c, unsigned size, Assembler::Register* a) { @@ -1938,6 +1945,8 @@ populateTables(ArchitectureContext* c) uo[index(Jump, C)] = CAST1(jumpC); uo[index(Jump, M)] = CAST1(jumpM); + uo[index(AlignedJump, C)] = CAST1(alignedJumpC); + uo[index(JumpIfEqual, C)] = CAST1(jumpIfEqualC); uo[index(JumpIfNotEqual, C)] = CAST1(jumpIfNotEqualC); uo[index(JumpIfGreater, C)] = CAST1(jumpIfGreaterC); @@ -2126,10 +2135,6 @@ class MyArchitecture: public Assembler::Architecture { } } - virtual unsigned constantCallSize() { - return 5; - } - virtual uintptr_t getConstant(const void* src) { uintptr_t v; memcpy(&v, src, BytesPerWord); @@ -2162,12 +2167,12 @@ class MyArchitecture: public Assembler::Architecture { return 0; } - virtual unsigned returnAddressOffset() { - return 1; + virtual int returnAddressOffset() { + return 0; } - virtual unsigned framePointerOffset() { - return 0; + virtual int framePointerOffset() { + return -1; } virtual void nextFrame(void** stack, void** base) { @@ -2427,12 +2432,13 @@ class MyAssembler: public Assembler { c.client->releaseTemporary(tmp.low); - Memory baseSrc(rbp, footprint * BytesPerWord); + Memory baseSrc(rsp, footprint * BytesPerWord); Register base(rbp); moveMR(&c, BytesPerWord, &baseSrc, BytesPerWord, &base); Register stack(rsp); - Constant footprintConstant(resolved(&c, footprint * BytesPerWord)); + Constant footprintConstant + (resolved(&c, (footprint - offset + 1) * BytesPerWord)); addCR(&c, BytesPerWord, &footprintConstant, BytesPerWord, &stack); if (returnAddressSurrogate != NoRegister) {