use c++11 variadic templates in Compiler::call

This commit is contained in:
Joshua Warner 2014-07-12 09:41:52 -06:00 committed by Joshua Warner
parent d8ddc95315
commit 060b5c8f13
5 changed files with 261 additions and 249 deletions

View File

@ -25,6 +25,37 @@ class TraceHandler {
virtual void handleTrace(Promise* address, unsigned argumentIndex) = 0; virtual void handleTrace(Promise* address, unsigned argumentIndex) = 0;
}; };
template<size_t N>
class Args {
public:
ir::Value* values[N];
template<class... Ts>
Args(Ts... ts) : values{ts...}
{
}
operator util::Slice<ir::Value*> () {
return util::Slice<ir::Value*>(&values[0], N);
}
};
inline Args<0> args()
{
return Args<0>();
}
inline Args<1> args(ir::Value* first)
{
return Args<1> { first};
}
template<class... Ts>
inline Args<1 + util::ArgumentCount<Ts...>::Result> args(ir::Value* first, Ts... rest)
{
return Args<1 + util::ArgumentCount<Ts...>::Result> { first, rest... };
}
class Compiler { class Compiler {
public: public:
class Client { class Client {
@ -83,12 +114,11 @@ class Compiler {
virtual unsigned topOfStack() = 0; virtual unsigned topOfStack() = 0;
virtual ir::Value* peek(unsigned footprint, unsigned index) = 0; virtual ir::Value* peek(unsigned footprint, unsigned index) = 0;
virtual ir::Value* call(ir::Value* address, virtual ir::Value* nativeCall(ir::Value* address,
unsigned flags, unsigned flags,
TraceHandler* traceHandler, TraceHandler* traceHandler,
ir::Type resultType, ir::Type resultType,
unsigned argumentCount, util::Slice<ir::Value*> arguments) = 0;
...) = 0;
virtual ir::Value* stackCall(ir::Value* address, virtual ir::Value* stackCall(ir::Value* address,
unsigned flags, unsigned flags,

54
include/avian/util/cpp.h Normal file
View File

@ -0,0 +1,54 @@
/* Copyright (c) 2008-2014, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
#ifndef AVIAN_UTIL_CPP_H
#define AVIAN_UTIL_CPP_H
#include "allocator.h"
#include "math.h"
#include "assert.h"
namespace avian {
namespace util {
template <class T>
struct NonConst;
template <class T>
struct NonConst<const T> {
typedef T Type;
};
template <class T>
struct NonConst {
typedef T Type;
};
template<class... Ts>
struct ArgumentCount;
template<class T, class... Ts>
struct ArgumentCount<T, Ts...> {
enum {
Result = 1 + ArgumentCount<Ts...>::Result
};
};
template<>
struct ArgumentCount<> {
enum {
Result = 0
};
};
} // namespace util
} // namespace avian
#endif // AVIAN_UTIL_CPP_H

View File

@ -14,23 +14,11 @@
#include "allocator.h" #include "allocator.h"
#include "math.h" #include "math.h"
#include "assert.h" #include "assert.h"
#include "cpp.h"
namespace avian { namespace avian {
namespace util { namespace util {
template <class T>
struct NonConst;
template <class T>
struct NonConst<const T> {
typedef T Type;
};
template <class T>
struct NonConst {
typedef T Type;
};
template <class T> template <class T>
class Slice { class Slice {
public: public:

View File

@ -2534,31 +2534,27 @@ class MyCompiler : public Compiler {
return s->value; return s->value;
} }
virtual ir::Value* call(ir::Value* address, virtual ir::Value* nativeCall(ir::Value* address,
unsigned flags, unsigned flags,
TraceHandler* traceHandler, TraceHandler* traceHandler,
ir::Type resultType, ir::Type resultType,
unsigned argumentCount, util::Slice<ir::Value*> arguments)
...)
{ {
va_list a;
va_start(a, argumentCount);
bool bigEndian = c.arch->bigEndian(); bool bigEndian = c.arch->bigEndian();
unsigned footprint = 0; unsigned footprint = 0;
unsigned size = TargetBytesPerWord; unsigned size = TargetBytesPerWord;
RUNTIME_ARRAY(ir::Value*, arguments, argumentCount); RUNTIME_ARRAY(ir::Value*, args, arguments.count);
int index = 0; int index = 0;
for (unsigned i = 0; i < argumentCount; ++i) { for (unsigned i = 0; i < arguments.count; ++i) {
Value* o = va_arg(a, Value*); Value* o = static_cast<Value*>(arguments[i]);
if (o) { if (o) {
if (bigEndian and size > TargetBytesPerWord) { if (bigEndian and size > TargetBytesPerWord) {
RUNTIME_ARRAY_BODY(arguments)[index++] = o->nextWord; RUNTIME_ARRAY_BODY(args)[index++] = o->nextWord;
} }
RUNTIME_ARRAY_BODY(arguments)[index] = o; RUNTIME_ARRAY_BODY(args)[index] = o;
if ((not bigEndian) and size > TargetBytesPerWord) { if ((not bigEndian) and size > TargetBytesPerWord) {
RUNTIME_ARRAY_BODY(arguments)[++index] = o->nextWord; RUNTIME_ARRAY_BODY(args)[++index] = o->nextWord;
} }
size = TargetBytesPerWord; size = TargetBytesPerWord;
++index; ++index;
@ -2568,8 +2564,6 @@ class MyCompiler : public Compiler {
++footprint; ++footprint;
} }
va_end(a);
Value* result = value(&c, resultType); Value* result = value(&c, resultType);
appendCall(&c, appendCall(&c,
static_cast<Value*>(address), static_cast<Value*>(address),
@ -2577,7 +2571,7 @@ class MyCompiler : public Compiler {
flags, flags,
traceHandler, traceHandler,
result, result,
util::Slice<ir::Value*>(RUNTIME_ARRAY_BODY(arguments), index)); util::Slice<ir::Value*>(RUNTIME_ARRAY_BODY(args), index));
return result; return result;
} }

View File

@ -3084,12 +3084,11 @@ bool useLongJump(MyThread* t, uintptr_t target)
void compileSafePoint(MyThread* t, Compiler* c, Frame* frame) void compileSafePoint(MyThread* t, Compiler* c, Frame* frame)
{ {
c->call(c->constant(getThunk(t, idleIfNecessaryThunk), ir::Type::iptr()), c->nativeCall(c->constant(getThunk(t, idleIfNecessaryThunk), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::void_(), ir::Type::void_(),
1, args(c->threadRegister()));
c->threadRegister());
} }
void compileDirectInvoke(MyThread* t, void compileDirectInvoke(MyThread* t,
@ -3229,13 +3228,11 @@ void compileDirectReferenceInvoke(MyThread* t,
compileReferenceInvoke( compileReferenceInvoke(
frame, frame,
c->call(c->constant(getThunk(t, thunk), ir::Type::iptr()), c->nativeCall(c->constant(getThunk(t, thunk), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::iptr(), ir::Type::iptr(),
2, args(c->threadRegister(), frame->append(pair))),
c->threadRegister(),
frame->append(pair)),
reference, reference,
isStatic, isStatic,
tailCall); tailCall);
@ -3260,13 +3257,11 @@ void compileDirectAbstractInvoke(MyThread* t,
compileAbstractInvoke( compileAbstractInvoke(
frame, frame,
c->call(c->constant(getThunk(t, thunk), ir::Type::iptr()), c->nativeCall(c->constant(getThunk(t, thunk), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::iptr(), ir::Type::iptr(),
2, args(c->threadRegister(), frame->append(target))),
c->threadRegister(),
frame->append(target)),
target, target,
tailCall); tailCall);
} }
@ -3287,13 +3282,11 @@ void handleMonitorEvent(MyThread* t, Frame* frame, intptr_t function)
frame->context, 1, ir::Type::object(), savedTargetIndex(t, method)); frame->context, 1, ir::Type::object(), savedTargetIndex(t, method));
} }
c->call(c->constant(function, ir::Type::iptr()), c->nativeCall(c->constant(function, ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::void_(), ir::Type::void_(),
2, args(c->threadRegister(), lock));
c->threadRegister(),
lock);
} }
} }
@ -3923,12 +3916,11 @@ loop:
frame->pushObject(); frame->pushObject();
c->call(c->constant(getThunk(t, gcIfNecessaryThunk), ir::Type::iptr()), c->nativeCall(c->constant(getThunk(t, gcIfNecessaryThunk), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::void_(), ir::Type::void_(),
1, args(c->threadRegister()));
c->threadRegister());
} }
if (DebugInstructions) { if (DebugInstructions) {
@ -4082,22 +4074,22 @@ loop:
switch (instruction) { switch (instruction) {
case aastore: { case aastore: {
c->call(c->constant(getThunk(t, setMaybeNullThunk), ir::Type::iptr()), c->nativeCall(
0, c->constant(getThunk(t, setMaybeNullThunk), ir::Type::iptr()),
frame->trace(0, 0), 0,
ir::Type::void_(), frame->trace(0, 0),
4, ir::Type::void_(),
c->threadRegister(), args(c->threadRegister(),
array, array,
c->binaryOp(lir::Add, c->binaryOp(lir::Add,
ir::Type::i4(), ir::Type::i4(),
c->constant(TargetArrayBody, ir::Type::i4()), c->constant(TargetArrayBody, ir::Type::i4()),
c->binaryOp(lir::ShiftLeft, c->binaryOp(lir::ShiftLeft,
ir::Type::i4(), ir::Type::i4(),
c->constant(log(TargetBytesPerWord), c->constant(log(TargetBytesPerWord),
ir::Type::i4()), ir::Type::i4()),
index)), index)),
value); value));
} break; } break;
case fastore: case fastore:
@ -4180,15 +4172,14 @@ loop:
thunk = makeBlankObjectArrayFromReferenceThunk; thunk = makeBlankObjectArrayFromReferenceThunk;
} }
frame->push(ir::Type::object(), frame->push(
c->call(c->constant(getThunk(t, thunk), ir::Type::iptr()), ir::Type::object(),
0, c->nativeCall(
frame->trace(0, 0), c->constant(getThunk(t, thunk), ir::Type::iptr()),
ir::Type::object(), 0,
3, frame->trace(0, 0),
c->threadRegister(), ir::Type::object(),
frame->append(argument), args(c->threadRegister(), frame->append(argument), length)));
length));
} break; } break;
case areturn: { case areturn: {
@ -4228,13 +4219,11 @@ loop:
case athrow: { case athrow: {
ir::Value* target = frame->pop(ir::Type::object()); ir::Value* target = frame->pop(ir::Type::object());
c->call(c->constant(getThunk(t, throw_Thunk), ir::Type::iptr()), c->nativeCall(c->constant(getThunk(t, throw_Thunk), ir::Type::iptr()),
Compiler::NoReturn, Compiler::NoReturn,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::void_(), ir::Type::void_(),
2, args(c->threadRegister(), target));
c->threadRegister(),
target);
c->nullaryOp(lir::Trap); c->nullaryOp(lir::Trap);
} }
@ -4269,14 +4258,12 @@ loop:
ir::Value* instance = c->peek(1, 0); ir::Value* instance = c->peek(1, 0);
c->call(c->constant(getThunk(t, thunk), ir::Type::iptr()), c->nativeCall(
0, c->constant(getThunk(t, thunk), ir::Type::iptr()),
frame->trace(0, 0), 0,
ir::Type::void_(), frame->trace(0, 0),
3, ir::Type::void_(),
c->threadRegister(), args(c->threadRegister(), frame->append(argument), instance));
frame->append(argument),
instance);
} break; } break;
case d2f: { case d2f: {
@ -4316,16 +4303,12 @@ loop:
goto branch; goto branch;
} else { } else {
frame->push(ir::Type::i4(), frame->push(ir::Type::i4(),
c->call(c->constant(getThunk(t, compareDoublesGThunk), c->nativeCall(c->constant(getThunk(t, compareDoublesGThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
0, 0,
ir::Type::i4(), ir::Type::i4(),
4, args(nullptr, a, nullptr, b)));
static_cast<ir::Value*>(0),
a,
static_cast<ir::Value*>(0),
b));
} }
} break; } break;
@ -4337,16 +4320,12 @@ loop:
goto branch; goto branch;
} else { } else {
frame->push(ir::Type::i4(), frame->push(ir::Type::i4(),
c->call(c->constant(getThunk(t, compareDoublesLThunk), c->nativeCall(c->constant(getThunk(t, compareDoublesLThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
0, 0,
ir::Type::i4(), ir::Type::i4(),
4, args(nullptr, a, nullptr, b)));
static_cast<ir::Value*>(0),
a,
static_cast<ir::Value*>(0),
b));
} }
} break; } break;
@ -4427,14 +4406,12 @@ loop:
goto branch; goto branch;
} else { } else {
frame->push(ir::Type::i4(), frame->push(ir::Type::i4(),
c->call(c->constant(getThunk(t, compareFloatsGThunk), c->nativeCall(c->constant(getThunk(t, compareFloatsGThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
0, 0,
ir::Type::i4(), ir::Type::i4(),
2, args(a, b)));
a,
b));
} }
} break; } break;
@ -4446,14 +4423,12 @@ loop:
goto branch; goto branch;
} else { } else {
frame->push(ir::Type::i4(), frame->push(ir::Type::i4(),
c->call(c->constant(getThunk(t, compareFloatsLThunk), c->nativeCall(c->constant(getThunk(t, compareFloatsLThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
0, 0,
ir::Type::i4(), ir::Type::i4(),
2, args(a, b)));
a,
b));
} }
} break; } break;
@ -4493,14 +4468,12 @@ loop:
and (field->code() == DoubleField or field->code() == LongField)) { and (field->code() == DoubleField or field->code() == LongField)) {
PROTECT(t, field); PROTECT(t, field);
c->call(c->constant(getThunk(t, acquireMonitorForObjectThunk), c->nativeCall(c->constant(getThunk(t, acquireMonitorForObjectThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::void_(), ir::Type::void_(),
2, args(c->threadRegister(), frame->append(field)));
c->threadRegister(),
frame->append(field));
} }
ir::Value* table; ir::Value* table;
@ -4511,14 +4484,13 @@ loop:
PROTECT(t, field); PROTECT(t, field);
if (classNeedsInit(t, field->class_())) { if (classNeedsInit(t, field->class_())) {
c->call( c->nativeCall(
c->constant(getThunk(t, tryInitClassThunk), ir::Type::iptr()), c->constant(getThunk(t, tryInitClassThunk), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::void_(), ir::Type::void_(),
2, args(c->threadRegister(),
c->threadRegister(), frame->append(field->class_())));
frame->append(field->class_()));
} }
table = frame->append(field->class_()->staticTable()); table = frame->append(field->class_()->staticTable());
@ -4614,14 +4586,13 @@ loop:
if (field->flags() & ACC_VOLATILE) { if (field->flags() & ACC_VOLATILE) {
if (TargetBytesPerWord == 4 and (field->code() == DoubleField if (TargetBytesPerWord == 4 and (field->code() == DoubleField
or field->code() == LongField)) { or field->code() == LongField)) {
c->call(c->constant(getThunk(t, releaseMonitorForObjectThunk), c->nativeCall(c->constant(getThunk(t, releaseMonitorForObjectThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::void_(), ir::Type::void_(),
2, args(c->threadRegister(),
c->threadRegister(), frame->append(field)));
frame->append(field));
} else { } else {
c->nullaryOp(lir::LoadBarrier); c->nullaryOp(lir::LoadBarrier);
} }
@ -4637,28 +4608,26 @@ loop:
ir::Value* result; ir::Value* result;
if (instruction == getstatic) { if (instruction == getstatic) {
result = c->call( result = c->nativeCall(
c->constant(getThunk(t, getStaticFieldValueFromReferenceThunk), c->constant(getThunk(t, getStaticFieldValueFromReferenceThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
rType, rType,
2, args(c->threadRegister(),
c->threadRegister(), frame->append(pair)));
frame->append(pair));
} else { } else {
ir::Value* instance = frame->pop(ir::Type::object()); ir::Value* instance = frame->pop(ir::Type::object());
result = c->call( result = c->nativeCall(
c->constant(getThunk(t, getFieldValueFromReferenceThunk), c->constant(getThunk(t, getFieldValueFromReferenceThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
rType, rType,
3, args(c->threadRegister(),
c->threadRegister(),
frame->append(pair), frame->append(pair),
instance); instance));
} }
frame->pushReturnValue(fieldCode, result); frame->pushReturnValue(fieldCode, result);
@ -4950,14 +4919,13 @@ loop:
} }
frame->push(ir::Type::i4(), frame->push(ir::Type::i4(),
c->call(c->constant(getThunk(t, thunk), ir::Type::iptr()), c->nativeCall(c->constant(getThunk(t, thunk), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::i4(), ir::Type::i4(),
3, args(c->threadRegister(),
c->threadRegister(),
frame->append(argument), frame->append(argument),
instance)); instance)));
} break; } break;
case invokeinterface: { case invokeinterface: {
@ -4999,14 +4967,13 @@ loop:
unsigned rSize = resultSize(t, returnCode); unsigned rSize = resultSize(t, returnCode);
ir::Value* result = c->stackCall( ir::Value* result = c->stackCall(
c->call(c->constant(getThunk(t, thunk), ir::Type::iptr()), c->nativeCall(c->constant(getThunk(t, thunk), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::iptr(), ir::Type::iptr(),
3, args(c->threadRegister(),
c->threadRegister(),
frame->append(argument), frame->append(argument),
c->peek(1, parameterFootprint - 1)), c->peek(1, parameterFootprint - 1))),
tailCall ? Compiler::TailJump : 0, tailCall ? Compiler::TailJump : 0,
frame->trace(0, 0), frame->trace(0, 0),
operandTypeForFieldCode(t, returnCode), operandTypeForFieldCode(t, returnCode),
@ -5146,17 +5113,16 @@ loop:
compileReferenceInvoke( compileReferenceInvoke(
frame, frame,
c->call( c->nativeCall(
c->constant(getThunk(t, findVirtualMethodFromReferenceThunk), c->constant(getThunk(t, findVirtualMethodFromReferenceThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::iptr(), ir::Type::iptr(),
3, args(c->threadRegister(),
c->threadRegister(),
frame->append(pair), frame->append(pair),
c->peek(1, c->peek(1,
methodReferenceParameterFootprint(t, ref, false) - 1)), methodReferenceParameterFootprint(t, ref, false) - 1))),
ref, ref,
false, false,
isReferenceTailCall(t, code, ip, context->method, ref)); isReferenceTailCall(t, code, ip, context->method, ref));
@ -5283,16 +5249,15 @@ loop:
goto branch; goto branch;
} else { } else {
frame->push(ir::Type::i4(), frame->push(ir::Type::i4(),
c->call(c->constant(getThunk(t, compareLongsThunk), c->nativeCall(c->constant(getThunk(t, compareLongsThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
0, 0,
ir::Type::i4(), ir::Type::i4(),
4, args(nullptr,
static_cast<ir::Value*>(0),
a, a,
static_cast<ir::Value*>(0), nullptr,
b)); b)));
} }
} break; } break;
@ -5330,29 +5295,27 @@ loop:
if (UNLIKELY(v == 0)) { if (UNLIKELY(v == 0)) {
frame->push( frame->push(
ir::Type::object(), ir::Type::object(),
c->call( c->nativeCall(
c->constant(getThunk(t, getJClassFromReferenceThunk), c->constant(getThunk(t, getJClassFromReferenceThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::object(), ir::Type::object(),
2, args(c->threadRegister(),
c->threadRegister(), frame->append(makePair(t, context->method, reference)))));
frame->append(makePair(t, context->method, reference))));
} }
} }
if (v) { if (v) {
if (objectClass(t, v) == type(t, GcClass::Type)) { if (objectClass(t, v) == type(t, GcClass::Type)) {
frame->push(ir::Type::object(), frame->push(ir::Type::object(),
c->call(c->constant(getThunk(t, getJClass64Thunk), c->nativeCall(c->constant(getThunk(t, getJClass64Thunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::object(), ir::Type::object(),
2, args(c->threadRegister(),
c->threadRegister(), frame->append(v))));
frame->append(v)));
} else { } else {
frame->push(ir::Type::object(), frame->append(v)); frame->push(ir::Type::object(), frame->append(v));
} }
@ -5468,16 +5431,15 @@ loop:
} }
assertT(t, start); assertT(t, start);
ir::Value* address = c->call( ir::Value* address = c->nativeCall(
c->constant(getThunk(t, lookUpAddressThunk), ir::Type::iptr()), c->constant(getThunk(t, lookUpAddressThunk), ir::Type::iptr()),
0, 0,
0, 0,
ir::Type::iptr(), ir::Type::iptr(),
4, args(key,
key, frame->absoluteAddressOperand(start),
frame->absoluteAddressOperand(start), c->constant(pairCount, ir::Type::i4()),
c->constant(pairCount, ir::Type::i4()), default_));
default_);
c->jmp(context->bootContext c->jmp(context->bootContext
? c->binaryOp(lir::Add, ? c->binaryOp(lir::Add,
@ -5572,26 +5534,24 @@ loop:
case monitorenter: { case monitorenter: {
ir::Value* target = frame->pop(ir::Type::object()); ir::Value* target = frame->pop(ir::Type::object());
c->call(c->constant(getThunk(t, acquireMonitorForObjectThunk), c->nativeCall(c->constant(getThunk(t, acquireMonitorForObjectThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::void_(), ir::Type::void_(),
2, args(c->threadRegister(),
c->threadRegister(), target));
target);
} break; } break;
case monitorexit: { case monitorexit: {
ir::Value* target = frame->pop(ir::Type::object()); ir::Value* target = frame->pop(ir::Type::object());
c->call(c->constant(getThunk(t, releaseMonitorForObjectThunk), c->nativeCall(c->constant(getThunk(t, releaseMonitorForObjectThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::void_(), ir::Type::void_(),
2, args(c->threadRegister(),
c->threadRegister(), target));
target);
} break; } break;
case multianewarray: { case multianewarray: {
@ -5622,15 +5582,14 @@ loop:
context->method) + t->arch->frameReturnAddressSize(); context->method) + t->arch->frameReturnAddressSize();
ir::Value* result ir::Value* result
= c->call(c->constant(getThunk(t, thunk), ir::Type::iptr()), = c->nativeCall(c->constant(getThunk(t, thunk), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::object(), ir::Type::object(),
4, args(c->threadRegister(),
c->threadRegister(),
frame->append(argument), frame->append(argument),
c->constant(dimensions, ir::Type::i4()), c->constant(dimensions, ir::Type::i4()),
c->constant(offset, ir::Type::i4())); c->constant(offset, ir::Type::i4())));
frame->popFootprint(dimensions); frame->popFootprint(dimensions);
frame->push(ir::Type::object(), result); frame->push(ir::Type::object(), result);
@ -5662,13 +5621,12 @@ loop:
} }
frame->push(ir::Type::object(), frame->push(ir::Type::object(),
c->call(c->constant(getThunk(t, thunk), ir::Type::iptr()), c->nativeCall(c->constant(getThunk(t, thunk), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::object(), ir::Type::object(),
2, args(c->threadRegister(),
c->threadRegister(), frame->append(argument))));
frame->append(argument)));
} break; } break;
case newarray: { case newarray: {
@ -5677,15 +5635,14 @@ loop:
ir::Value* length = frame->pop(ir::Type::i4()); ir::Value* length = frame->pop(ir::Type::i4());
frame->push(ir::Type::object(), frame->push(ir::Type::object(),
c->call(c->constant(getThunk(t, makeBlankArrayThunk), c->nativeCall(c->constant(getThunk(t, makeBlankArrayThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::object(), ir::Type::object(),
3, args(c->threadRegister(),
c->threadRegister(),
c->constant(type, ir::Type::i4()), c->constant(type, ir::Type::i4()),
length)); length)));
} break; } break;
case nop: case nop:
@ -5721,14 +5678,13 @@ loop:
if (classNeedsInit(t, field->class_())) { if (classNeedsInit(t, field->class_())) {
PROTECT(t, field); PROTECT(t, field);
c->call( c->nativeCall(
c->constant(getThunk(t, tryInitClassThunk), ir::Type::iptr()), c->constant(getThunk(t, tryInitClassThunk), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::void_(), ir::Type::void_(),
2, args(c->threadRegister(),
c->threadRegister(), frame->append(field->class_())));
frame->append(field->class_()));
} }
staticTable = field->class_()->staticTable(); staticTable = field->class_()->staticTable();
@ -5746,14 +5702,13 @@ loop:
and (fieldCode == DoubleField or fieldCode == LongField)) { and (fieldCode == DoubleField or fieldCode == LongField)) {
PROTECT(t, field); PROTECT(t, field);
c->call(c->constant(getThunk(t, acquireMonitorForObjectThunk), c->nativeCall(c->constant(getThunk(t, acquireMonitorForObjectThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::void_(), ir::Type::void_(),
2, args(c->threadRegister(),
c->threadRegister(), frame->append(field)));
frame->append(field));
} else { } else {
c->nullaryOp(lir::StoreStoreBarrier); c->nullaryOp(lir::StoreStoreBarrier);
} }
@ -5818,27 +5773,25 @@ loop:
case ObjectField: case ObjectField:
if (instruction == putfield) { if (instruction == putfield) {
c->call( c->nativeCall(
c->constant(getThunk(t, setMaybeNullThunk), ir::Type::iptr()), c->constant(getThunk(t, setMaybeNullThunk), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::void_(), ir::Type::void_(),
4, args(c->threadRegister(),
c->threadRegister(),
table, table,
c->constant(targetFieldOffset(context, field), ir::Type::i4()), c->constant(targetFieldOffset(context, field), ir::Type::i4()),
value); value));
} else { } else {
c->call( c->nativeCall(
c->constant(getThunk(t, setObjectThunk), ir::Type::iptr()), c->constant(getThunk(t, setObjectThunk), ir::Type::iptr()),
0, 0,
0, 0,
ir::Type::void_(), ir::Type::void_(),
4, args(c->threadRegister(),
c->threadRegister(),
table, table,
c->constant(targetFieldOffset(context, field), ir::Type::i4()), c->constant(targetFieldOffset(context, field), ir::Type::i4()),
value); value));
} }
break; break;
@ -5849,14 +5802,13 @@ loop:
if (field->flags() & ACC_VOLATILE) { if (field->flags() & ACC_VOLATILE) {
if (TargetBytesPerWord == 4 if (TargetBytesPerWord == 4
and (fieldCode == DoubleField or fieldCode == LongField)) { and (fieldCode == DoubleField or fieldCode == LongField)) {
c->call(c->constant(getThunk(t, releaseMonitorForObjectThunk), c->nativeCall(c->constant(getThunk(t, releaseMonitorForObjectThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
ir::Type::void_(), ir::Type::void_(),
2, args(c->threadRegister(),
c->threadRegister(), frame->append(field)));
frame->append(field));
} else { } else {
c->nullaryOp(lir::StoreLoadBarrier); c->nullaryOp(lir::StoreLoadBarrier);
} }
@ -5879,91 +5831,85 @@ loop:
case FloatField: case FloatField:
case IntField: { case IntField: {
if (instruction == putstatic) { if (instruction == putstatic) {
c->call( c->nativeCall(
c->constant(getThunk(t, setStaticFieldValueFromReferenceThunk), c->constant(getThunk(t, setStaticFieldValueFromReferenceThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
rType, rType,
3, args(c->threadRegister(),
c->threadRegister(),
frame->append(pair), frame->append(pair),
value); value));
} else { } else {
ir::Value* instance = frame->pop(ir::Type::object()); ir::Value* instance = frame->pop(ir::Type::object());
c->call(c->constant(getThunk(t, setFieldValueFromReferenceThunk), c->nativeCall(c->constant(getThunk(t, setFieldValueFromReferenceThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
rType, rType,
4, args(c->threadRegister(),
c->threadRegister(),
frame->append(pair), frame->append(pair),
instance, instance,
value); value));
} }
} break; } break;
case DoubleField: case DoubleField:
case LongField: { case LongField: {
if (instruction == putstatic) { if (instruction == putstatic) {
c->call(c->constant( c->nativeCall(c->constant(
getThunk(t, setStaticLongFieldValueFromReferenceThunk), getThunk(t, setStaticLongFieldValueFromReferenceThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
rType, rType,
4, args(c->threadRegister(),
c->threadRegister(),
frame->append(pair), frame->append(pair),
static_cast<ir::Value*>(0), nullptr,
value); value));
} else { } else {
ir::Value* instance = frame->pop(ir::Type::object()); ir::Value* instance = frame->pop(ir::Type::object());
c->call( c->nativeCall(
c->constant(getThunk(t, setLongFieldValueFromReferenceThunk), c->constant(getThunk(t, setLongFieldValueFromReferenceThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
rType, rType,
5, args(c->threadRegister(),
c->threadRegister(),
frame->append(pair), frame->append(pair),
instance, instance,
static_cast<ir::Value*>(0), nullptr,
value); value));
} }
} break; } break;
case ObjectField: { case ObjectField: {
if (instruction == putstatic) { if (instruction == putstatic) {
c->call( c->nativeCall(
c->constant( c->constant(
getThunk(t, setStaticObjectFieldValueFromReferenceThunk), getThunk(t, setStaticObjectFieldValueFromReferenceThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
rType, rType,
3, args(c->threadRegister(),
c->threadRegister(),
frame->append(pair), frame->append(pair),
value); value));
} else { } else {
ir::Value* instance = frame->pop(ir::Type::object()); ir::Value* instance = frame->pop(ir::Type::object());
c->call( c->nativeCall(
c->constant(getThunk(t, setObjectFieldValueFromReferenceThunk), c->constant(getThunk(t, setObjectFieldValueFromReferenceThunk),
ir::Type::iptr()), ir::Type::iptr()),
0, 0,
frame->trace(0, 0), frame->trace(0, 0),
rType, rType,
4, args(c->threadRegister(),
c->threadRegister(),
frame->append(pair), frame->append(pair),
instance, instance,
value); value));
} }
} break; } break;