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;
};
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 {
public:
class Client {
@ -83,12 +114,11 @@ class Compiler {
virtual unsigned topOfStack() = 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,
TraceHandler* traceHandler,
ir::Type resultType,
unsigned argumentCount,
...) = 0;
util::Slice<ir::Value*> arguments) = 0;
virtual ir::Value* stackCall(ir::Value* address,
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 "math.h"
#include "assert.h"
#include "cpp.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 T>
class Slice {
public:

View File

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

View File

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