From 060b5c8f13501b6a2d756420c7016a255553a99c Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Sat, 12 Jul 2014 09:41:52 -0600 Subject: [PATCH] use c++11 variadic templates in Compiler::call --- include/avian/codegen/compiler.h | 36 ++- include/avian/util/cpp.h | 54 +++++ include/avian/util/slice.h | 14 +- src/codegen/compiler.cpp | 24 +- src/compile.cpp | 382 +++++++++++++------------------ 5 files changed, 261 insertions(+), 249 deletions(-) create mode 100644 include/avian/util/cpp.h diff --git a/include/avian/codegen/compiler.h b/include/avian/codegen/compiler.h index 6b38e91054..6e07a06d87 100644 --- a/include/avian/codegen/compiler.h +++ b/include/avian/codegen/compiler.h @@ -25,6 +25,37 @@ class TraceHandler { virtual void handleTrace(Promise* address, unsigned argumentIndex) = 0; }; +template +class Args { + public: + ir::Value* values[N]; + + template + Args(Ts... ts) : values{ts...} + { + } + + operator util::Slice () { + return util::Slice(&values[0], N); + } +}; + +inline Args<0> args() +{ + return Args<0>(); +} + +inline Args<1> args(ir::Value* first) +{ + return Args<1> { first}; +} + +template +inline Args<1 + util::ArgumentCount::Result> args(ir::Value* first, Ts... rest) +{ + return Args<1 + util::ArgumentCount::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 arguments) = 0; virtual ir::Value* stackCall(ir::Value* address, unsigned flags, diff --git a/include/avian/util/cpp.h b/include/avian/util/cpp.h new file mode 100644 index 0000000000..f886c9054d --- /dev/null +++ b/include/avian/util/cpp.h @@ -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 +struct NonConst; + +template +struct NonConst { + typedef T Type; +}; + +template +struct NonConst { + typedef T Type; +}; + +template +struct ArgumentCount; + +template +struct ArgumentCount { + enum { + Result = 1 + ArgumentCount::Result + }; +}; + +template<> +struct ArgumentCount<> { + enum { + Result = 0 + }; +}; + +} // namespace util +} // namespace avian + +#endif // AVIAN_UTIL_CPP_H diff --git a/include/avian/util/slice.h b/include/avian/util/slice.h index a5003f1ac5..e9cd0ec0e3 100644 --- a/include/avian/util/slice.h +++ b/include/avian/util/slice.h @@ -14,23 +14,11 @@ #include "allocator.h" #include "math.h" #include "assert.h" +#include "cpp.h" namespace avian { namespace util { -template -struct NonConst; - -template -struct NonConst { - typedef T Type; -}; - -template -struct NonConst { - typedef T Type; -}; - template class Slice { public: diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 67c622741f..cfa755dd83 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -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 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(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(address), @@ -2577,7 +2571,7 @@ class MyCompiler : public Compiler { flags, traceHandler, result, - util::Slice(RUNTIME_ARRAY_BODY(arguments), index)); + util::Slice(RUNTIME_ARRAY_BODY(args), index)); return result; } diff --git a/src/compile.cpp b/src/compile.cpp index 5dc187d93a..1426d2a8c9 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -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(0), - a, - static_cast(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(0), - a, - static_cast(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(0), + args(nullptr, a, - static_cast(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(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(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;