disable use of SSE when compiling ahead-of-time

This commit is contained in:
Joel Dice 2009-10-10 17:46:43 -06:00
parent 38bf29300f
commit 44a6620aa1
8 changed files with 184 additions and 131 deletions

View File

@ -428,7 +428,7 @@ class Assembler {
}; };
Assembler::Architecture* Assembler::Architecture*
makeArchitecture(System* system); makeArchitecture(System* system, bool useNativeFeatures);
Assembler* Assembler*
makeAssembler(System* system, Allocator* allocator, Zone* zone, makeAssembler(System* system, Allocator* allocator, Zone* zone,

View File

@ -386,7 +386,7 @@ main(int ac, const char** av)
System* s = makeSystem(0); System* s = makeSystem(0);
Heap* h = makeHeap(s, 128 * 1024 * 1024); Heap* h = makeHeap(s, 128 * 1024 * 1024);
Finder* f = makeFinder(s, av[1], 0); Finder* f = makeFinder(s, av[1], 0);
Processor* p = makeProcessor(s, h); Processor* p = makeProcessor(s, h, false);
BootImage image; BootImage image;
const unsigned CodeCapacity = 32 * 1024 * 1024; const unsigned CodeCapacity = 32 * 1024 * 1024;

View File

@ -92,7 +92,8 @@ class MyThread: public Thread {
CallTrace* next; CallTrace* next;
}; };
MyThread(Machine* m, object javaThread, MyThread* parent): MyThread(Machine* m, object javaThread, MyThread* parent,
bool useNativeFeatures):
Thread(m, javaThread, parent), Thread(m, javaThread, parent),
ip(0), ip(0),
base(0), base(0),
@ -106,7 +107,9 @@ class MyThread: public Thread {
virtualCallIndex(0), virtualCallIndex(0),
trace(0), trace(0),
reference(0), reference(0),
arch(parent ? parent->arch : makeArchitecture(m->system)) arch(parent
? parent->arch
: makeArchitecture(m->system, useNativeFeatures))
{ {
arch->acquire(); arch->acquire();
} }
@ -786,12 +789,14 @@ class Context {
} else { } else {
return local::getThunk(t, negateDoubleThunk); return local::getThunk(t, negateDoubleThunk);
} }
case Float2Float: case Float2Float:
if (size == 4 and resultSize == 8) { if (size == 4 and resultSize == 8) {
return local::getThunk(t, floatToDoubleThunk); return local::getThunk(t, floatToDoubleThunk);
} else if (size == 8 and resultSize == 4) { } else if (size == 8 and resultSize == 4) {
return local::getThunk(t, doubleToFloatThunk); return local::getThunk(t, doubleToFloatThunk);
} }
case Float2Int: case Float2Int:
if (size == 4 and resultSize == 4) { if (size == 4 and resultSize == 4) {
return local::getThunk(t, floatToIntThunk); return local::getThunk(t, floatToIntThunk);
@ -802,6 +807,7 @@ class Context {
} else if (size == 8 and resultSize == 8) { } else if (size == 8 and resultSize == 8) {
return local::getThunk(t, doubleToLongThunk); return local::getThunk(t, doubleToLongThunk);
} }
case Int2Float: case Int2Float:
if (size == 4 and resultSize == 4) { if (size == 4 and resultSize == 4) {
return local::getThunk(t, intToFloatThunk); return local::getThunk(t, intToFloatThunk);
@ -819,49 +825,72 @@ class Context {
abort(t); abort(t);
} }
virtual intptr_t getThunk(TernaryOperation op, unsigned size UNUSED, virtual intptr_t getThunk(TernaryOperation op, unsigned size, unsigned)
unsigned resultSize)
{ {
if (size == 8) {
switch (op) { switch (op) {
case Divide: case Divide:
if (resultSize == 8) {
return local::getThunk(t, divideLongThunk); return local::getThunk(t, divideLongThunk);
}
break;
case Remainder: case Remainder:
if (resultSize == 8) {
return local::getThunk(t, moduloLongThunk); return local::getThunk(t, moduloLongThunk);
}
break;
case FloatAdd: case FloatAdd:
if(resultSize == 4) {
return local::getThunk(t, addFloatThunk);
} else {
return local::getThunk(t, addDoubleThunk); return local::getThunk(t, addDoubleThunk);
}
case FloatSubtract: case FloatSubtract:
if(resultSize == 4) {
return local::getThunk(t, subtractFloatThunk);
} else {
return local::getThunk(t, subtractDoubleThunk); return local::getThunk(t, subtractDoubleThunk);
}
case FloatMultiply: case FloatMultiply:
if(resultSize == 4) {
return local::getThunk(t, multiplyFloatThunk);
} else {
return local::getThunk(t, multiplyDoubleThunk); return local::getThunk(t, multiplyDoubleThunk);
}
case FloatDivide: case FloatDivide:
if(resultSize == 4) {
return local::getThunk(t, divideFloatThunk);
} else {
return local::getThunk(t, divideDoubleThunk); return local::getThunk(t, divideDoubleThunk);
}
case JumpIfFloatEqual:
case JumpIfFloatNotEqual:
case JumpIfFloatLess:
case JumpIfFloatGreater:
case JumpIfFloatLessOrEqual:
case JumpIfFloatGreaterOrUnordered:
case JumpIfFloatGreaterOrEqualOrUnordered:
return local::getThunk(t, compareDoublesGThunk);
case JumpIfFloatGreaterOrEqual:
case JumpIfFloatLessOrUnordered:
case JumpIfFloatLessOrEqualOrUnordered:
return local::getThunk(t, compareDoublesLThunk);
default: break; default: break;
} }
} else if (size == 4) {
switch (op) {
case FloatAdd:
return local::getThunk(t, addFloatThunk);
case FloatSubtract:
return local::getThunk(t, subtractFloatThunk);
case FloatMultiply:
return local::getThunk(t, multiplyFloatThunk);
case FloatDivide:
return local::getThunk(t, divideFloatThunk);
case JumpIfFloatEqual:
case JumpIfFloatNotEqual:
case JumpIfFloatLess:
case JumpIfFloatGreater:
case JumpIfFloatLessOrEqual:
case JumpIfFloatGreaterOrUnordered:
case JumpIfFloatGreaterOrEqualOrUnordered:
return local::getThunk(t, compareFloatsGThunk);
case JumpIfFloatGreaterOrEqual:
case JumpIfFloatLessOrUnordered:
case JumpIfFloatLessOrEqualOrUnordered:
return local::getThunk(t, compareFloatsLThunk);
default: break;
}
}
abort(t); abort(t);
} }
@ -6784,7 +6813,7 @@ processor(MyThread* t);
class MyProcessor: public Processor { class MyProcessor: public Processor {
public: public:
MyProcessor(System* s, Allocator* allocator): MyProcessor(System* s, Allocator* allocator, bool useNativeFeatures):
s(s), s(s),
allocator(allocator), allocator(allocator),
defaultThunk(0), defaultThunk(0),
@ -6792,7 +6821,6 @@ class MyProcessor: public Processor {
nativeThunk(0), nativeThunk(0),
aioobThunk(0), aioobThunk(0),
callTable(0), callTable(0),
callTableSize(0),
methodTree(0), methodTree(0),
methodTreeSentinal(0), methodTreeSentinal(0),
objectPools(0), objectPools(0),
@ -6801,15 +6829,19 @@ class MyProcessor: public Processor {
receiveMethod(0), receiveMethod(0),
windMethod(0), windMethod(0),
rewindMethod(0), rewindMethod(0),
bootImage(0),
codeAllocator(s, 0, 0), codeAllocator(s, 0, 0),
bootImage(0) thunkSize(0),
callTableSize(0),
useNativeFeatures(useNativeFeatures)
{ } { }
virtual Thread* virtual Thread*
makeThread(Machine* m, object javaThread, Thread* parent) makeThread(Machine* m, object javaThread, Thread* parent)
{ {
MyThread* t = new (m->heap->allocate(sizeof(MyThread))) MyThread* t = new (m->heap->allocate(sizeof(MyThread)))
MyThread(m, javaThread, static_cast<MyThread*>(parent)); MyThread(m, javaThread, static_cast<MyThread*>(parent),
useNativeFeatures);
t->init(); t->init();
if (false) { if (false) {
@ -7275,9 +7307,7 @@ class MyProcessor: public Processor {
uint8_t* nativeThunk; uint8_t* nativeThunk;
uint8_t* aioobThunk; uint8_t* aioobThunk;
uint8_t* thunkTable; uint8_t* thunkTable;
unsigned thunkSize;
object callTable; object callTable;
unsigned callTableSize;
object methodTree; object methodTree;
object methodTreeSentinal; object methodTreeSentinal;
object objectPools; object objectPools;
@ -7286,9 +7316,12 @@ class MyProcessor: public Processor {
object receiveMethod; object receiveMethod;
object windMethod; object windMethod;
object rewindMethod; object rewindMethod;
BootImage* bootImage;
SegFaultHandler segFaultHandler; SegFaultHandler segFaultHandler;
FixedAllocator codeAllocator; FixedAllocator codeAllocator;
BootImage* bootImage; unsigned thunkSize;
unsigned callTableSize;
bool useNativeFeatures;
}; };
object object
@ -7485,7 +7518,7 @@ void
fixupCode(Thread* t, uintptr_t* map, unsigned size, uint8_t* code, fixupCode(Thread* t, uintptr_t* map, unsigned size, uint8_t* code,
uintptr_t* heap) uintptr_t* heap)
{ {
Assembler::Architecture* arch = makeArchitecture(t->m->system); Assembler::Architecture* arch = makeArchitecture(t->m->system, false);
arch->acquire(); arch->acquire();
for (unsigned word = 0; word < size; ++word) { for (unsigned word = 0; word < size; ++word) {
@ -8092,10 +8125,10 @@ codeAllocator(MyThread* t)
namespace vm { namespace vm {
Processor* Processor*
makeProcessor(System* system, Allocator* allocator) makeProcessor(System* system, Allocator* allocator, bool useNativeFeatures)
{ {
return new (allocator->allocate(sizeof(local::MyProcessor))) return new (allocator->allocate(sizeof(local::MyProcessor)))
local::MyProcessor(system, allocator); local::MyProcessor(system, allocator, useNativeFeatures);
} }
} // namespace vm } // namespace vm

View File

@ -893,7 +893,7 @@ bool
uniqueSite(Context* c, Value* v, Site* s) uniqueSite(Context* c, Value* v, Site* s)
{ {
SiteIterator it(c, v); SiteIterator it(c, v);
Site* p = it.next(); Site* p UNUSED = it.next();
if (it.hasMore()) { if (it.hasMore()) {
// the site is not this word's only site, but if the site is // the site is not this word's only site, but if the site is
// shared with the next word, it may be that word's only site // shared with the next word, it may be that word's only site
@ -1784,7 +1784,7 @@ class RegisterSite: public Site {
} }
} }
virtual unsigned registerMask(Context* c) { virtual unsigned registerMask(Context* c UNUSED) {
assert(c, number != NoRegister); assert(c, number != NoRegister);
return 1 << number; return 1 << number;
@ -4266,6 +4266,37 @@ shouldJump(Context* c, TernaryOperation type, unsigned size, int64_t b,
} }
} }
TernaryOperation
thunkBranch(Context* c, TernaryOperation type)
{
switch (type) {
case JumpIfFloatEqual:
return JumpIfEqual;
case JumpIfFloatNotEqual:
return JumpIfNotEqual;
case JumpIfFloatLess:
case JumpIfFloatLessOrUnordered:
return JumpIfLess;
case JumpIfFloatGreater:
case JumpIfFloatGreaterOrUnordered:
return JumpIfGreater;
case JumpIfFloatLessOrEqual:
case JumpIfFloatLessOrEqualOrUnordered:
return JumpIfLessOrEqual;
case JumpIfFloatGreaterOrEqual:
case JumpIfFloatGreaterOrEqualOrUnordered:
return JumpIfGreaterOrEqual;
default:
abort(c);
}
}
class BranchEvent: public Event { class BranchEvent: public Event {
public: public:
BranchEvent(Context* c, TernaryOperation type, unsigned size, BranchEvent(Context* c, TernaryOperation type, unsigned size,
@ -4354,7 +4385,7 @@ appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first,
0, 0, result, 4, argumentStack, 0, 0, result, 4, argumentStack,
ceiling(size, BytesPerWord) * 2, 0); ceiling(size, BytesPerWord) * 2, 0);
appendBranch(c, JumpIfEqual, 4, value appendBranch(c, thunkBranch(c, type), 4, value
(c, ValueGeneral, constantSite(c, static_cast<int64_t>(0))), (c, ValueGeneral, constantSite(c, static_cast<int64_t>(0))),
result, address); result, address);
} else { } else {

View File

@ -3333,7 +3333,7 @@ class MyProcessor: public Processor {
namespace vm { namespace vm {
Processor* Processor*
makeProcessor(System* system, Allocator* allocator) makeProcessor(System* system, Allocator* allocator, bool)
{ {
return new (allocator->allocate(sizeof(MyProcessor))) return new (allocator->allocate(sizeof(MyProcessor)))
MyProcessor(system, allocator); MyProcessor(system, allocator);

View File

@ -2155,7 +2155,7 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
System* s = makeSystem(crashDumpDirectory); System* s = makeSystem(crashDumpDirectory);
Heap* h = makeHeap(s, heapLimit); Heap* h = makeHeap(s, heapLimit);
Finder* f = makeFinder(s, RUNTIME_ARRAY_BODY(classpathBuffer), bootLibrary); Finder* f = makeFinder(s, RUNTIME_ARRAY_BODY(classpathBuffer), bootLibrary);
Processor* p = makeProcessor(s, h); Processor* p = makeProcessor(s, h, true);
const char** properties = static_cast<const char**> const char** properties = static_cast<const char**>
(h->allocate(sizeof(const char*) * propertyCount)); (h->allocate(sizeof(const char*) * propertyCount));

View File

@ -180,7 +180,7 @@ class Processor {
}; };
Processor* Processor*
makeProcessor(System* system, Allocator* allocator); makeProcessor(System* system, Allocator* allocator, bool useNativeFeatures);
} // namespace vm } // namespace vm

View File

@ -15,10 +15,6 @@
#define CAST2(x) reinterpret_cast<BinaryOperationType>(x) #define CAST2(x) reinterpret_cast<BinaryOperationType>(x)
#define CAST_BRANCH(x) reinterpret_cast<BranchOperationType>(x) #define CAST_BRANCH(x) reinterpret_cast<BranchOperationType>(x)
const bool DebugSSE = false;
const bool EnableSSE = true;
const bool EnableSSE2 = true;
using namespace vm; using namespace vm;
namespace { namespace {
@ -150,9 +146,12 @@ typedef void (*BranchOperationType)
class ArchitectureContext { class ArchitectureContext {
public: public:
ArchitectureContext(System* s): s(s) { } ArchitectureContext(System* s, bool useNativeFeatures):
s(s), useNativeFeatures(useNativeFeatures)
{ }
System* s; System* s;
bool useNativeFeatures;
OperationType operations[OperationCount]; OperationType operations[OperationCount];
UnaryOperationType unaryOperations[UnaryOperationCount UnaryOperationType unaryOperations[UnaryOperationCount
* OperandTypeCount]; * OperandTypeCount];
@ -443,33 +442,22 @@ padding(AlignmentPadding* p, unsigned start, unsigned offset,
return padding; return padding;
} }
extern "C" extern "C" bool
bool detectFeature(unsigned ecx, unsigned edx); detectFeature(unsigned ecx, unsigned edx);
bool bool
supportsSSE() useSSE(ArchitectureContext* c)
{ {
if (c->useNativeFeatures) {
static int supported = -1; static int supported = -1;
if (supported == -1) { if (supported == -1) {
supported = EnableSSE and detectFeature(0, 0x2000000); supported = detectFeature(0, 0x2000000) // SSE 1
if(DebugSSE) { and detectFeature(0, 0x4000000); // SSE 2
fprintf(stderr, "sse %sdetected.\n", supported ? "" : "not ");
}
} }
return supported; return supported;
} else {
return false;
} }
bool
supportsSSE2()
{
static int supported = -1;
if(supported == -1) {
supported = EnableSSE2 and detectFeature(0, 0x4000000);
if(DebugSSE) {
fprintf(stderr, "sse2 %sdetected.\n", supported ? "" : "not ");
}
}
return supported;
} }
#define REX_W 0x48 #define REX_W 0x48
@ -2354,7 +2342,6 @@ void
float2FloatRR(Context* c, unsigned aSize, Assembler::Register* a, float2FloatRR(Context* c, unsigned aSize, Assembler::Register* a,
unsigned bSize UNUSED, Assembler::Register* b) unsigned bSize UNUSED, Assembler::Register* b)
{ {
assert(c, supportsSSE2());
floatRegOp(c, aSize, a, 4, b, 0x5a); floatRegOp(c, aSize, a, 4, b, 0x5a);
} }
@ -2362,7 +2349,6 @@ void
float2FloatMR(Context* c, unsigned aSize, Assembler::Memory* a, float2FloatMR(Context* c, unsigned aSize, Assembler::Memory* a,
unsigned bSize UNUSED, Assembler::Register* b) unsigned bSize UNUSED, Assembler::Register* b)
{ {
assert(c, supportsSSE2());
floatMemOp(c, aSize, a, 4, b, 0x5a); floatMemOp(c, aSize, a, 4, b, 0x5a);
} }
@ -2370,7 +2356,7 @@ void
float2IntRR(Context* c, unsigned aSize, Assembler::Register* a, float2IntRR(Context* c, unsigned aSize, Assembler::Register* a,
unsigned bSize, Assembler::Register* b) unsigned bSize, Assembler::Register* b)
{ {
assert(c, !floatReg(b)); assert(c, not floatReg(b));
floatRegOp(c, aSize, a, bSize, b, 0x2d); floatRegOp(c, aSize, a, bSize, b, 0x2d);
} }
@ -2571,14 +2557,17 @@ populateTables(ArchitectureContext* c)
bro[branchIndex(c, C, M)] = CAST_BRANCH(branchCM); bro[branchIndex(c, C, M)] = CAST_BRANCH(branchCM);
bro[branchIndex(c, R, M)] = CAST_BRANCH(branchRM); bro[branchIndex(c, R, M)] = CAST_BRANCH(branchRM);
} }
class MyArchitecture: public Assembler::Architecture { class MyArchitecture: public Assembler::Architecture {
public: public:
MyArchitecture(System* system): c(system), referenceCount(0) { MyArchitecture(System* system, bool useNativeFeatures):
c(system, useNativeFeatures), referenceCount(0)
{
populateTables(&c); populateTables(&c);
} }
virtual unsigned floatRegisterSize() { virtual unsigned floatRegisterSize() {
if (supportsSSE()) { if (useSSE(&c)) {
return 8; return 8;
} else { } else {
return 0; return 0;
@ -2590,7 +2579,7 @@ class MyArchitecture: public Assembler::Architecture {
} }
virtual uint32_t floatRegisterMask() { virtual uint32_t floatRegisterMask() {
return supportsSSE() ? FloatRegisterMask : 0; return useSSE(&c) ? FloatRegisterMask : 0;
} }
virtual int stack() { virtual int stack() {
@ -2822,7 +2811,7 @@ class MyArchitecture: public Assembler::Architecture {
const char* parameterSpec) const char* parameterSpec)
{ {
if (strcmp(className, "java/lang/Math") == 0) { if (strcmp(className, "java/lang/Math") == 0) {
if (supportsSSE() if (useSSE(&c)
and strcmp(methodName, "sqrt") == 0 and strcmp(methodName, "sqrt") == 0
and strcmp(parameterSpec, "(D)D") == 0) and strcmp(parameterSpec, "(D)D") == 0)
{ {
@ -2832,8 +2821,7 @@ class MyArchitecture: public Assembler::Architecture {
or strcmp(parameterSpec, "(J)J") == 0) or strcmp(parameterSpec, "(J)J") == 0)
{ {
return Abs; return Abs;
} else if (supportsSSE() } else if (useSSE(&c)
and supportsSSE2()
and strcmp(parameterSpec, "(F)F") == 0) and strcmp(parameterSpec, "(F)F") == 0)
{ {
return FloatAbs; return FloatAbs;
@ -2881,7 +2869,7 @@ class MyArchitecture: public Assembler::Architecture {
case FloatNegate: case FloatNegate:
// floatNegateRR does not support doubles // floatNegateRR does not support doubles
if (supportsSSE() and aSize == 4 and bSize == 4) { if (useSSE(&c) and aSize == 4 and bSize == 4) {
*aTypeMask = (1 << RegisterOperand); *aTypeMask = (1 << RegisterOperand);
*aRegisterMask = FloatRegisterMask; *aRegisterMask = FloatRegisterMask;
} else { } else {
@ -2896,7 +2884,7 @@ class MyArchitecture: public Assembler::Architecture {
break; break;
case Float2Float: case Float2Float:
if (supportsSSE() and supportsSSE2()) { if (useSSE(&c)) {
*aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
*aRegisterMask = (static_cast<uint64_t>(FloatRegisterMask) << 32) *aRegisterMask = (static_cast<uint64_t>(FloatRegisterMask) << 32)
| FloatRegisterMask; | FloatRegisterMask;
@ -2906,7 +2894,7 @@ class MyArchitecture: public Assembler::Architecture {
break; break;
case Float2Int: case Float2Int:
if (supportsSSE() and (bSize <= BytesPerWord)) { if (useSSE(&c) and (bSize <= BytesPerWord)) {
*aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
*aRegisterMask = (static_cast<uint64_t>(FloatRegisterMask) << 32) *aRegisterMask = (static_cast<uint64_t>(FloatRegisterMask) << 32)
| FloatRegisterMask; | FloatRegisterMask;
@ -2916,7 +2904,7 @@ class MyArchitecture: public Assembler::Architecture {
break; break;
case Int2Float: case Int2Float:
if (supportsSSE()) { if (useSSE(&c)) {
*aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
*aRegisterMask = GeneralRegisterMask *aRegisterMask = GeneralRegisterMask
| (static_cast<uint64_t>(GeneralRegisterMask) << 32); | (static_cast<uint64_t>(GeneralRegisterMask) << 32);
@ -3081,7 +3069,7 @@ class MyArchitecture: public Assembler::Architecture {
case FloatSubtract: case FloatSubtract:
case FloatMultiply: case FloatMultiply:
case FloatDivide: case FloatDivide:
if (supportsSSE()) { if (useSSE(&c)) {
*aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
*bTypeMask = (1 << RegisterOperand); *bTypeMask = (1 << RegisterOperand);
@ -3145,7 +3133,7 @@ class MyArchitecture: public Assembler::Architecture {
case JumpIfFloatGreaterOrUnordered: case JumpIfFloatGreaterOrUnordered:
case JumpIfFloatLessOrEqualOrUnordered: case JumpIfFloatLessOrEqualOrUnordered:
case JumpIfFloatGreaterOrEqualOrUnordered: case JumpIfFloatGreaterOrEqualOrUnordered:
if (supportsSSE()) { if (useSSE(&c)) {
*aTypeMask = (1 << RegisterOperand); *aTypeMask = (1 << RegisterOperand);
*aRegisterMask = (static_cast<uint64_t>(FloatRegisterMask) << 32) *aRegisterMask = (static_cast<uint64_t>(FloatRegisterMask) << 32)
| FloatRegisterMask; | FloatRegisterMask;
@ -3400,7 +3388,8 @@ class MyAssembler: public Assembler {
virtual void apply(TernaryOperation op, virtual void apply(TernaryOperation op,
unsigned aSize, OperandType aType, Operand* aOperand, unsigned aSize, OperandType aType, Operand* aOperand,
unsigned bSize, OperandType bType, Operand* bOperand, unsigned bSize, OperandType bType, Operand* bOperand,
unsigned cSize, OperandType cType, Operand* cOperand) unsigned cSize UNUSED, OperandType cType UNUSED,
Operand* cOperand)
{ {
if (isBranch(op)) { if (isBranch(op)) {
assert(&c, aSize == bSize); assert(&c, aSize == bSize);
@ -3484,10 +3473,10 @@ class MyAssembler: public Assembler {
namespace vm { namespace vm {
Assembler::Architecture* Assembler::Architecture*
makeArchitecture(System* system) makeArchitecture(System* system, bool useNativeFeatures)
{ {
return new (allocate(system, sizeof(local::MyArchitecture))) return new (allocate(system, sizeof(local::MyArchitecture)))
local::MyArchitecture(system); local::MyArchitecture(system, useNativeFeatures);
} }
Assembler* Assembler*