Skip to content

Commit

Permalink
[clang][bytecode] Stack-allocate bottom function frame (#125253)
Browse files Browse the repository at this point in the history
Instead of heap-allocating it. This is similar to what the current
interpeter does. In C, we have no function calls, so the extra heap
allocation never makes sense.
  • Loading branch information
tbaederr authored Jan 31, 2025
1 parent 6b8d076 commit f354981
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 7 deletions.
7 changes: 3 additions & 4 deletions clang/lib/AST/ByteCode/EvalEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ using namespace clang::interp;

EvalEmitter::EvalEmitter(Context &Ctx, Program &P, State &Parent,
InterpStack &Stk)
: Ctx(Ctx), P(P), S(Parent, P, Stk, Ctx, this), EvalResult(&Ctx) {
// Create a dummy frame for the interpreter which does not have locals.
S.Current =
new InterpFrame(S, /*Func=*/nullptr, /*Caller=*/nullptr, CodePtr(), 0);
: Ctx(Ctx), P(P), S(Parent, P, Stk, Ctx, this), EvalResult(&Ctx),
BottomFrame(S) {
S.Current = &BottomFrame;
}

EvalEmitter::~EvalEmitter() {
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/AST/ByteCode/EvalEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ class EvalEmitter : public SourceMapper {
/// Active block which should be executed.
LabelTy ActiveLabel = 0;

InterpFrame BottomFrame;

protected:
#define GET_EVAL_PROTO
#include "Opcodes.inc"
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/ByteCode/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,11 +325,11 @@ bool Ret(InterpState &S, CodePtr &PC) {

if (InterpFrame *Caller = S.Current->Caller) {
PC = S.Current->getRetPC();
delete S.Current;
InterpFrame::free(S.Current);
S.Current = Caller;
S.Stk.push<T>(Ret);
} else {
delete S.Current;
InterpFrame::free(S.Current);
S.Current = nullptr;
// The topmost frame should come from an EvalEmitter,
// which has its own implementation of the Ret<> instruction.
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/AST/ByteCode/InterpFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
using namespace clang;
using namespace clang::interp;

InterpFrame::InterpFrame(InterpState &S)
: Caller(nullptr), S(S), Depth(0), Func(nullptr), RetPC(CodePtr()),
ArgSize(0), Args(nullptr), FrameOffset(0), IsBottom(true) {}

InterpFrame::InterpFrame(InterpState &S, const Function *Func,
InterpFrame *Caller, CodePtr RetPC, unsigned ArgSize)
: Caller(Caller), S(S), Depth(Caller ? Caller->Depth + 1 : 0), Func(Func),
Expand Down
11 changes: 11 additions & 0 deletions clang/lib/AST/ByteCode/InterpFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ class InterpFrame final : public Frame {
/// The frame of the previous function.
InterpFrame *Caller;

/// Bottom Frame.
InterpFrame(InterpState &S);

/// Creates a new frame for a method call.
InterpFrame(InterpState &S, const Function *Func, InterpFrame *Caller,
CodePtr RetPC, unsigned ArgSize);
Expand All @@ -42,6 +45,11 @@ class InterpFrame final : public Frame {
/// Destroys the frame, killing all live pointers to stack slots.
~InterpFrame();

static void free(InterpFrame *F) {
if (!F->isBottomFrame())
delete F;
}

/// Invokes the destructors for a scope.
void destroy(unsigned Idx);
void initScope(unsigned Idx);
Expand Down Expand Up @@ -119,6 +127,8 @@ class InterpFrame final : public Frame {

bool isStdFunction() const;

bool isBottomFrame() const { return IsBottom; }

void dump() const { dump(llvm::errs(), 0); }
void dump(llvm::raw_ostream &OS, unsigned Indent = 0) const;

Expand Down Expand Up @@ -167,6 +177,7 @@ class InterpFrame final : public Frame {
const size_t FrameOffset;
/// Mapping from arg offsets to their argument blocks.
llvm::DenseMap<unsigned, std::unique_ptr<char[]>> Params;
bool IsBottom = false;
};

} // namespace interp
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/ByteCode/InterpState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ bool InterpState::inConstantContext() const {
}

InterpState::~InterpState() {
while (Current) {
while (Current && !Current->isBottomFrame()) {
InterpFrame *Next = Current->Caller;
delete Current;
Current = Next;
Expand Down

0 comments on commit f354981

Please sign in to comment.