From e6c780e4e8d85e8a7c3ebba3a05b031e35f9e997 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 23 Sep 2011 20:42:17 -0600 Subject: [PATCH 1/4] whitespace tweak for usage message in bootimage.cpp --- src/bootimage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootimage.cpp b/src/bootimage.cpp index 382552a7b7..efbd240ef0 100644 --- a/src/bootimage.cpp +++ b/src/bootimage.cpp @@ -1642,7 +1642,7 @@ main(int ac, const char** av) { if (ac < 4 or ac > 7) { fprintf(stderr, "usage: %s " - "[ [ []]]\n", av[0]); + " [ [ []]]\n", av[0]); return -1; } From 3fa4a7001dee90b32734c7954cdd1e1af8d292c2 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 23 Sep 2011 22:21:54 -0600 Subject: [PATCH 2/4] fix x86->powerpc boot image cross build This fixes the remaining cross-endian translation issues needed to build powerpc boot images on x86. --- src/arm.cpp | 4 ++++ src/assembler.h | 1 + src/bootimage.cpp | 13 +++++++------ src/compile.cpp | 13 ++++++++----- src/compiler.cpp | 4 ++-- src/powerpc.cpp | 14 +++++++++----- src/x86.cpp | 4 ++++ 7 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/arm.cpp b/src/arm.cpp index 16241d180c..2c7549238c 100644 --- a/src/arm.cpp +++ b/src/arm.cpp @@ -1783,6 +1783,10 @@ class MyArchitecture: public Assembler::Architecture { return 0; } + virtual int scratch() { + return 5; + } + virtual int stack() { return StackRegister; } diff --git a/src/assembler.h b/src/assembler.h index 04c0693a36..1566df6cd7 100644 --- a/src/assembler.h +++ b/src/assembler.h @@ -329,6 +329,7 @@ class Assembler { virtual uint32_t generalRegisterMask() = 0; virtual uint32_t floatRegisterMask() = 0; + virtual int scratch() = 0; virtual int stack() = 0; virtual int thread() = 0; virtual int returnLow() = 0; diff --git a/src/bootimage.cpp b/src/bootimage.cpp index efbd240ef0..bb9f75926d 100644 --- a/src/bootimage.cpp +++ b/src/bootimage.cpp @@ -672,7 +672,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code, expect(t, value >= code); addresses->listener->resolve - (targetVW(static_cast(value - code)), 0); + (static_cast(value - code), 0); } for (; methods; methods = pairSecond(t, methods)) { @@ -987,7 +987,7 @@ copy(Thread* t, object typeMaps, object p, uint8_t* dst) if (field->type == Type_object) { unsigned offset = field->targetOffset / TargetBytesPerWord; reinterpret_cast(mask)[offset / 32] - |= static_cast(1) << (offset % 32); + |= targetV4(static_cast(1) << (offset % 32)); } } @@ -1027,14 +1027,15 @@ copy(Thread* t, object typeMaps, object p, uint8_t* dst) switch (field->type) { case Type_object: reinterpret_cast(objectMask)[i / 32] - |= static_cast(1) << (i % 32); + |= targetV4(static_cast(1) << (i % 32)); break; case Type_float: case Type_double: reinterpret_cast(poolMask) [i / TargetBitsPerWord] - |= static_cast(1) << (i % TargetBitsPerWord); + |= targetVW + (static_cast(1) << (i % TargetBitsPerWord)); break; default: @@ -1083,7 +1084,7 @@ copy(Thread* t, object typeMaps, object referer, unsigned refererOffset, if (field->type == Type_object) { unsigned offset = field->targetOffset / TargetBytesPerWord; reinterpret_cast(dst + (TargetBytesPerWord * 2)) - [offset / 32] |= static_cast(1) << (offset % 32); + [offset / 32] |= targetV4(static_cast(1) << (offset % 32)); } } @@ -1092,7 +1093,7 @@ copy(Thread* t, object typeMaps, object referer, unsigned refererOffset, { unsigned offset = map->targetFixedSizeInWords; reinterpret_cast(dst + (TargetBytesPerWord * 2)) - [offset / 32] |= static_cast(1) << (offset % 32); + [offset / 32] |= targetV4(static_cast(1) << (offset % 32)); } } else { copy(t, typeMaps, p, dst); diff --git a/src/compile.cpp b/src/compile.cpp index 95fef9ee4c..c6f33a0806 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -8347,8 +8347,14 @@ class MyProcessor: public Processor { #define THUNK(s) thunkTable[s##Index] = voidPointer(s); #include "thunks.cpp" #undef THUNK + // Set the dummyIndex entry to a constant which should require the + // maximum number of bytes to represent in assembly code + // (i.e. can't be represented by a smaller number of bytes and + // implicitly sign- or zero-extended). We'll use this property + // later to determine the maximum size of a thunk in the thunk + // table. thunkTable[dummyIndex] = reinterpret_cast - (~static_cast(0)); + (static_cast(UINT64_C(0x5555555555555555))); } virtual Thread* @@ -9396,10 +9402,7 @@ compileCall(MyThread* t, Context* c, ThunkIndex index, bool call = true) if (processor(t)->bootImage) { Assembler::Memory table(t->arch->thread(), TargetThreadThunkTable); - // use Architecture::virtualCallTarget register here as a scratch - // register; any register that isn't used to pass arguments would - // be acceptable: - Assembler::Register scratch(t->arch->virtualCallTarget()); + Assembler::Register scratch(t->arch->scratch()); a->apply(Move, TargetBytesPerWord, MemoryOperand, &table, TargetBytesPerWord, RegisterOperand, &scratch); Assembler::Memory proc(scratch.low, index * TargetBytesPerWord); diff --git a/src/compiler.cpp b/src/compiler.cpp index 5221485cac..737f723da4 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -6953,14 +6953,14 @@ class MyCompiler: public Compiler { (c.machineCode + pad(c.machineCodeSize, TargetBytesPerWord) + i); if (n->promise->resolved()) { - *target = n->promise->value(); + *target = targetVW(n->promise->value()); } else { class Listener: public Promise::Listener { public: Listener(target_intptr_t* target): target(target){ } virtual bool resolve(int64_t value, void** location) { - *target = value; + *target = targetVW(value); if (location) *location = target; return true; } diff --git a/src/powerpc.cpp b/src/powerpc.cpp index 50359e8e78..59e0c77146 100644 --- a/src/powerpc.cpp +++ b/src/powerpc.cpp @@ -789,14 +789,14 @@ updateImmediate(System* s, void* dst, int32_t src, unsigned size, bool address) switch (size) { case 4: { int32_t* p = static_cast(dst); - int r = (p[1] >> 21) & 31; + int r = (targetV4(p[1]) >> 21) & 31; if (address) { - p[0] = lis(r, ha16(src)); - p[1] |= (src & 0xFFFF); + p[0] = targetV4(lis(r, ha16(src))); + p[1] |= targetV4(src & 0xFFFF); } else { - p[0] = lis(r, src >> 16); - p[1] = ori(r, r, src); + p[0] = targetV4(lis(r, src >> 16)); + p[1] = targetV4(ori(r, r, src)); } } break; @@ -2076,6 +2076,10 @@ class MyArchitecture: public Assembler::Architecture { return 0; } + virtual int scratch() { + return 31; + } + virtual int stack() { return StackRegister; } diff --git a/src/x86.cpp b/src/x86.cpp index 2101d04911..28c6dc2bc7 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -2763,6 +2763,10 @@ class MyArchitecture: public Assembler::Architecture { return useSSE(&c) ? FloatRegisterMask : 0; } + virtual int scratch() { + return rax; + } + virtual int stack() { return rsp; } From 0372d999d35b302edabc99b9c6fee660a7e11e20 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 23 Sep 2011 23:25:52 -0600 Subject: [PATCH 3/4] use TargetBytesPerWord instead of BytesPerWord where appropriate --- src/bootimage.cpp | 2 +- src/compile.cpp | 22 +++++++++++++--------- src/machine.h | 8 ++++++-- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/bootimage.cpp b/src/bootimage.cpp index bb9f75926d..32bfe75e82 100644 --- a/src/bootimage.cpp +++ b/src/bootimage.cpp @@ -1242,7 +1242,7 @@ makeHeapImage(Thread* t, BootImage* image, target_uintptr_t* heap, HeapWalker* w = makeHeapWalker(t, &visitor); visitRoots(t, image, w, constants); - image->heapSize = visitor.position * BytesPerWord; + image->heapSize = visitor.position * TargetBytesPerWord; return w; } diff --git a/src/compile.cpp b/src/compile.cpp index c6f33a0806..c993e82f6e 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -380,7 +380,7 @@ compareIpToMethodBounds(Thread* t, intptr_t ip, object method) if (ip < start) { return -1; } else if (ip < start + static_cast - (compiledSize(start) + BytesPerWord)) + (compiledSize(start) + TargetBytesPerWord)) { return 0; } else { @@ -6554,10 +6554,11 @@ simpleFrameMapTableSize(MyThread* t, object method, object map) } uint8_t* -finish(MyThread* t, Allocator* allocator, Assembler* a, const char* name, +finish(MyThread* t, FixedAllocator* allocator, Assembler* a, const char* name, unsigned length) { - uint8_t* start = static_cast(allocator->allocate(pad(length))); + uint8_t* start = static_cast + (allocator->allocate(length, TargetBytesPerWord)); a->setDestination(start); a->write(); @@ -6872,10 +6873,11 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context) unsigned codeSize = c->resolve (allocator->base + allocator->offset + TargetBytesPerWord); - unsigned total = pad(codeSize) + pad(c->poolSize()) + TargetBytesPerWord; + unsigned total = pad(codeSize, TargetBytesPerWord) + + pad(c->poolSize(), TargetBytesPerWord) + TargetBytesPerWord; target_uintptr_t* code = static_cast - (allocator->allocate(total)); + (allocator->allocate(total, TargetBytesPerWord)); code[0] = codeSize; uint8_t* start = reinterpret_cast(code + 1); @@ -8291,7 +8293,7 @@ MyProcessor* processor(MyThread* t); void -compileThunks(MyThread* t, Allocator* allocator); +compileThunks(MyThread* t, FixedAllocator* allocator); class MyProcessor: public Processor { public: @@ -9421,7 +9423,7 @@ compileCall(MyThread* t, Context* c, ThunkIndex index, bool call = true) } void -compileThunks(MyThread* t, Allocator* allocator) +compileThunks(MyThread* t, FixedAllocator* allocator) { MyProcessor* p = processor(t); @@ -9562,7 +9564,8 @@ compileThunks(MyThread* t, Allocator* allocator) p->thunks.table.length = a->endBlock(false)->resolve(0, 0); p->thunks.table.start = static_cast - (allocator->allocate(p->thunks.table.length * ThunkCount)); + (allocator->allocate + (p->thunks.table.length * ThunkCount, TargetBytesPerWord)); } uint8_t* start = p->thunks.table.start; @@ -9681,7 +9684,8 @@ compileVirtualThunk(MyThread* t, unsigned index, unsigned* size) *size = a->endBlock(false)->resolve(0, 0); - uint8_t* start = static_cast(codeAllocator(t)->allocate(*size)); + uint8_t* start = static_cast + (codeAllocator(t)->allocate(*size, TargetBytesPerWord)); a->setDestination(start); a->write(); diff --git a/src/machine.h b/src/machine.h index 1b53c9f8d8..70f3d7295e 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1796,8 +1796,8 @@ class FixedAllocator: public Allocator { abort(s); } - virtual void* allocate(unsigned size) { - unsigned paddedSize = pad(size); + void* allocate(unsigned size, unsigned padAlignment) { + unsigned paddedSize = pad(size, padAlignment); expect(s, offset + paddedSize < capacity); void* p = base + offset; @@ -1805,6 +1805,10 @@ class FixedAllocator: public Allocator { return p; } + virtual void* allocate(unsigned size) { + return allocate(size, BytesPerWord); + } + virtual void free(const void* p, unsigned size) { if (p >= base and static_cast(p) + size == base + offset) { offset -= size; From 4e4d109787fdb9b38b48ed83eae7cf0d4bcb25c3 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 28 Sep 2011 11:12:21 -0600 Subject: [PATCH 4/4] fix regression in static field offset calculation One of the changes in commit 5b4f179 broke this calculation. --- src/bootimage.cpp | 6 ++++-- src/machine.cpp | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/bootimage.cpp b/src/bootimage.cpp index 32bfe75e82..05f99c605e 100644 --- a/src/bootimage.cpp +++ b/src/bootimage.cpp @@ -496,8 +496,10 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code, } if (fieldFlags(t, field) & ACC_STATIC) { - while (targetStaticOffset % targetSize) { - ++ targetStaticOffset; + unsigned excess = (targetStaticOffset % targetSize) + % TargetBytesPerWord; + if (excess) { + targetStaticOffset += TargetBytesPerWord - excess; } buildStaticOffset = fieldOffset(t, field); diff --git a/src/machine.cpp b/src/machine.cpp index 92622cd5ca..838564b5ef 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -1145,8 +1145,9 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool) unsigned size = fieldSize(t, code); if (flags & ACC_STATIC) { - while (staticOffset % size) { - ++ staticOffset; + unsigned excess = (staticOffset % size) % BytesPerWord; + if (excess) { + staticOffset += BytesPerWord - excess; } fieldOffset(t, field) = staticOffset;