From 5b4f17997f05321ddcb559baa45da18185de6bf5 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 29 Aug 2011 19:00:17 -0600 Subject: [PATCH] progress towards cross-architecture bootimage builds This monster commit is the first step towards supporting cross-architecture bootimage builds. The challenge is to build a heap and code image for the target platform where the word size and endianess may differ from those of the build architecture. That means the memory layout of objects may differ due to alignment and size differences, so we can't just copy objects into the heap image unchanged; we must copy field by field, resizing values, reversing endianess and shifting offsets as necessary. This commit also removes POD (plain old data) type support from the type generator because it added a lot of complication and little value. --- makefile | 34 +- src/assembler.h | 2 +- src/bootimage.cpp | 971 +++++++++++++++++++++++++++++++++++++---- src/compile.cpp | 216 ++++----- src/compiler.cpp | 206 ++++----- src/heap.cpp | 11 +- src/heap.h | 6 + src/interpret.cpp | 8 +- src/machine.cpp | 45 +- src/machine.h | 77 +++- src/process.cpp | 2 +- src/target.h | 66 +++ src/type-generator.cpp | 267 +++++------ src/types.def | 20 +- src/x86.cpp | 289 ++++++------ 15 files changed, 1567 insertions(+), 653 deletions(-) create mode 100644 src/target.h diff --git a/makefile b/makefile index 3474de80f0..852cb6a816 100755 --- a/makefile +++ b/makefile @@ -169,7 +169,8 @@ common-cflags = $(warnings) -fno-rtti -fno-exceptions \ "-I$(JAVA_HOME)/include" -idirafter $(src) -I$(build) $(classpath-cflags) \ -D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \ -DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \ - -DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" + -DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" \ + -DTARGET_BYTES_PER_WORD=$(pointer-size) ifneq (,$(filter i386 x86_64,$(arch))) ifeq ($(use-frame-pointer),true) @@ -208,6 +209,12 @@ shared = -shared openjdk-extra-cflags = -fvisibility=hidden +ifeq ($(build-arch),powerpc) + ifneq ($(arch),$(build-arch)) + cflags += -DTARGET_OPPOSITE_ENDIAN + endif +endif + ifeq ($(arch),i386) pointer-size = 4 endif @@ -215,6 +222,10 @@ ifeq ($(arch),powerpc) asm = powerpc pointer-size = 4 + ifneq ($(arch),$(build-arch)) + cflags += -DTARGET_OPPOSITE_ENDIAN + endif + ifneq ($(platform),darwin) ifneq ($(arch),$(build-arch)) converter-cflags += -DOPPOSITE_ENDIAN @@ -251,7 +262,13 @@ ifeq ($(arch),arm) endif endif +ifeq ($(platform),linux) + cflags += -DTARGET_PLATFORM_LINUX +endif + ifeq ($(platform),darwin) + cflags += -DTARGET_PLATFORM_DARWIN + ifeq (${OSX_SDK_SYSROOT},) OSX_SDK_SYSROOT = 10.4u endif @@ -330,6 +347,8 @@ ifeq ($(platform),darwin) endif ifeq ($(platform),windows) + cflags += -DTARGET_PLATFORM_WINDOWS + inc = "$(root)/win32/include" lib = "$(root)/win32/lib" @@ -479,7 +498,8 @@ generated-code = \ $(build)/type-constructors.cpp \ $(build)/type-initializations.cpp \ $(build)/type-java-initializations.cpp \ - $(build)/type-name-initializations.cpp + $(build)/type-name-initializations.cpp \ + $(build)/type-maps.cpp vm-depends := $(generated-code) $(wildcard $(src)/*.h) @@ -537,16 +557,6 @@ bootimage-bin = $(build)/bootimage.bin bootimage-object = $(build)/bootimage-bin.o ifeq ($(bootimage),true) - ifneq ($(build-arch),$(arch)) -$(error "bootimage cross-builds not yet supported") - endif - - ifeq ($(arch),x86_64) - ifneq ($(build-platform),$(platform)) -$(error "bootimage cross-builds not yet supported") - endif - endif - vm-classpath-object = $(bootimage-object) cflags += -DBOOT_IMAGE=\"bootimageBin\" -DAVIAN_CLASSPATH=\"\" else diff --git a/src/assembler.h b/src/assembler.h index 4805f54e80..39d0987ce0 100644 --- a/src/assembler.h +++ b/src/assembler.h @@ -343,7 +343,7 @@ class Assembler { virtual void updateCall(UnaryOperation op, void* returnAddress, void* newTarget) = 0; - virtual void setConstant(void* dst, uintptr_t constant) = 0; + virtual void setConstant(void* dst, uint64_t constant) = 0; virtual unsigned alignFrameSize(unsigned sizeInWords) = 0; diff --git a/src/bootimage.cpp b/src/bootimage.cpp index b58439e3a7..0626eb5c77 100644 --- a/src/bootimage.cpp +++ b/src/bootimage.cpp @@ -9,11 +9,14 @@ details. */ #include "bootimage.h" +#include "heap.h" #include "heapwalk.h" #include "common.h" #include "machine.h" #include "util.h" +#include "stream.h" #include "assembler.h" +#include "target.h" // since we aren't linking against libstdc++, we must implement this // ourselves: @@ -25,6 +28,95 @@ namespace { const unsigned HeapCapacity = 256 * 1024 * 1024; +const unsigned TargetFixieSizeInBytes = 8 + (TargetBytesPerWord * 2); +const unsigned TargetFixieSizeInWords = ceiling + (TargetFixieSizeInBytes, TargetBytesPerWord); +const unsigned TargetFixieAge = 0; +const unsigned TargetFixieHasMask = 1; +const unsigned TargetFixieSize = 4; + +const bool DebugNativeTarget = false; + +enum Type { + Type_none, + Type_object, + Type_int8_t, + Type_uint8_t, + Type_int16_t, + Type_uint16_t, + Type_int32_t, + Type_uint32_t, + Type_intptr_t, + Type_uintptr_t, + Type_int64_t, + Type_int64_t_pad, + Type_uint64_t, + Type_float, + Type_double, + Type_double_pad, + Type_word, + Type_array +}; + +class Field { + public: + Field(Type type, unsigned offset, unsigned targetOffset): + type(type), offset(offset), targetOffset(targetOffset) + { } + + Type type; + unsigned offset; + unsigned targetOffset; +}; + +class TypeMap { + public: + enum Kind { + NormalKind, + SingletonKind, + PoolKind + }; + + TypeMap(unsigned buildFixedSizeInWords, unsigned targetFixedSizeInWords, + unsigned fixedFieldCount, Kind kind = NormalKind, + unsigned buildArrayElementSizeInBytes = 0, + unsigned targetArrayElementSizeInBytes = 0, + Type arrayElementType = Type_none): + buildFixedSizeInWords(buildFixedSizeInWords), + targetFixedSizeInWords(targetFixedSizeInWords), + fixedFieldCount(fixedFieldCount), + buildArrayElementSizeInBytes(buildArrayElementSizeInBytes), + targetArrayElementSizeInBytes(targetArrayElementSizeInBytes), + arrayElementType(arrayElementType), + kind(kind) + { } + + uintptr_t* targetFixedOffsets() { + return reinterpret_cast(this + 1); + } + + Field* fixedFields() { + return reinterpret_cast + (targetFixedOffsets() + (buildFixedSizeInWords * BytesPerWord)); + } + + static unsigned sizeInBytes(unsigned buildFixedSizeInWords, + unsigned fixedFieldCount) + { + return sizeof(TypeMap) + + (buildFixedSizeInWords * BytesPerWord * BytesPerWord) + + (sizeof(Field) * fixedFieldCount); + } + + unsigned buildFixedSizeInWords; + unsigned targetFixedSizeInWords; + unsigned fixedFieldCount; + unsigned buildArrayElementSizeInBytes; + unsigned targetArrayElementSizeInBytes; + Type arrayElementType; + Kind kind; +}; + // Notes on immutable references in the heap image: // // One of the advantages of a bootimage-based build is that reduces @@ -66,8 +158,10 @@ endsWith(const char* suffix, const char* s, unsigned length) object makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code, uintptr_t* codeMap, const char* className, - const char* methodName, const char* methodSpec) + const char* methodName, const char* methodSpec, object typeMaps) { + PROTECT(t, typeMaps); + object constants = 0; PROTECT(t, constants); @@ -76,24 +170,259 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code, DelayedPromise* addresses = 0; - for (Finder::Iterator it - (static_cast - (systemClassLoaderFinder(t, root(t, Machine::BootLoader)))); - it.hasMore();) - { + Finder* finder = static_cast + (systemClassLoaderFinder(t, root(t, Machine::BootLoader))); + + for (Finder::Iterator it(finder); it.hasMore();) { unsigned nameSize = 0; const char* name = it.next(&nameSize); if (endsWith(".class", name, nameSize) and (className == 0 or strncmp(name, className, nameSize - 6) == 0)) { -// fprintf(stderr, "%.*s\n", nameSize - 6, name); + // fprintf(stderr, "%.*s\n", nameSize - 6, name); object c = resolveSystemClass (t, root(t, Machine::BootLoader), makeByteArray(t, "%.*s", nameSize - 6, name), true); PROTECT(t, c); + System::Region* region = finder->find(name); + + { THREAD_RESOURCE(t, System::Region*, region, region->dispose()); + + class Client: public Stream::Client { + public: + Client(Thread* t): t(t) { } + + virtual void NO_RETURN handleError() { + vm::abort(t); + } + + private: + Thread* t; + } client(t); + + Stream s(&client, region->start(), region->length()); + + uint32_t magic = s.read4(); + expect(t, magic == 0xCAFEBABE); + s.read2(); // minor version + s.read2(); // major version + + unsigned count = s.read2() - 1; + if (count) { + Type types[count + 2]; + types[0] = Type_object; + types[1] = Type_intptr_t; + + for (unsigned i = 2; i < count + 2; ++i) { + switch (s.read1()) { + case CONSTANT_Class: + case CONSTANT_String: + types[i] = Type_object; + s.skip(2); + break; + + case CONSTANT_Integer: + case CONSTANT_Float: + types[i] = Type_int32_t; + s.skip(4); + break; + + case CONSTANT_NameAndType: + case CONSTANT_Fieldref: + case CONSTANT_Methodref: + case CONSTANT_InterfaceMethodref: + types[i] = Type_object; + s.skip(4); + break; + + case CONSTANT_Long: + types[i++] = Type_int64_t; + types[i] = Type_int64_t_pad; + s.skip(8); + break; + + case CONSTANT_Double: + types[i++] = Type_double; + types[i] = Type_double_pad; + s.skip(8); + break; + + case CONSTANT_Utf8: + types[i] = Type_object; + s.skip(s.read2()); + break; + + default: abort(t); + } + } + + object array = makeByteArray + (t, TypeMap::sizeInBytes(count + 2, count + 2)); + + TypeMap* map = new (&byteArrayBody(t, array, 0)) TypeMap + (count + 2, count + 2, count + 2, TypeMap::PoolKind); + + for (unsigned i = 0; i < count + 2; ++i) { + expect(t, i < map->buildFixedSizeInWords); + + map->targetFixedOffsets()[i * BytesPerWord] + = i * TargetBytesPerWord; + + new (map->fixedFields() + i) Field + (types[i], i * BytesPerWord, i * TargetBytesPerWord); + } + + hashMapInsert + (t, typeMaps, hashMapFind + (t, root(t, Machine::PoolMap), c, objectHash, objectEqual), array, + objectHash); + } + } + + if (classFieldTable(t, c)) { + unsigned count = arrayLength(t, classFieldTable(t, c)); + + Type memberTypes[count + 1]; + memberTypes[0] = Type_object; + unsigned buildMemberOffsets[count + 1]; + buildMemberOffsets[0] = 0; + unsigned targetMemberOffsets[count + 1]; + targetMemberOffsets[0] = 0; + unsigned memberIndex = 1; + unsigned buildMemberOffset = BytesPerWord; + unsigned targetMemberOffset = TargetBytesPerWord; + + Type staticTypes[count + 2]; + staticTypes[0] = Type_object; + staticTypes[1] = Type_intptr_t; + unsigned buildStaticOffsets[count + 2]; + buildStaticOffsets[0] = 0; + buildStaticOffsets[1] = BytesPerWord; + unsigned targetStaticOffsets[count + 2]; + targetStaticOffsets[0] = 0; + targetStaticOffsets[1] = TargetBytesPerWord; + unsigned staticIndex = 2; + unsigned buildStaticOffset = BytesPerWord * 2; + unsigned targetStaticOffset = TargetBytesPerWord * 2; + + for (unsigned i = 0; i < count; ++i) { + object field = arrayBody(t, classFieldTable(t, c), i); + unsigned size = fieldSize(t, fieldCode(t, field)); + + Type type; + switch (fieldCode(t, field)) { + case ObjectField: + type = Type_object; + size = TargetBytesPerWord; + break; + + case ByteField: + case BooleanField: + type = Type_int8_t; + break; + + case CharField: + case ShortField: + type = Type_int8_t; + break; + + case FloatField: + case IntField: + type = Type_int32_t; + break; + + case LongField: + case DoubleField: + type = Type_int64_t; + break; + + default: abort(t); + } + + if (fieldFlags(t, field) & ACC_STATIC) { + staticTypes[staticIndex] = type; + + while (targetStaticOffset % size) { + ++ targetStaticOffset; + } + + targetStaticOffsets[staticIndex] = targetStaticOffset; + + targetStaticOffset += size; + + buildStaticOffset = fieldOffset(t, field); + buildStaticOffsets[staticIndex] = buildStaticOffset; + + ++ staticIndex; + } else { + memberTypes[memberIndex] = type; + + while (targetMemberOffset % size) { + ++ targetMemberOffset; + } + + targetMemberOffsets[memberIndex] = targetMemberOffset; + + targetMemberOffset += size; + + buildMemberOffset = fieldOffset(t, field); + buildMemberOffsets[memberIndex] = buildMemberOffset; + + ++ memberIndex; + } + } + + { object array = makeByteArray + (t, TypeMap::sizeInBytes + (ceiling(classFixedSize(t, c), BytesPerWord), memberIndex)); + + TypeMap* map = new (&byteArrayBody(t, array, 0)) TypeMap + (ceiling(classFixedSize(t, c), BytesPerWord), + ceiling(targetMemberOffset, TargetBytesPerWord), memberIndex); + + for (unsigned i = 0; i < memberIndex; ++i) { + expect(t, buildMemberOffsets[i] + < map->buildFixedSizeInWords * BytesPerWord); + + map->targetFixedOffsets()[buildMemberOffsets[i]] + = targetMemberOffsets[i]; + + new (map->fixedFields() + i) Field + (memberTypes[i], buildMemberOffsets[i], targetMemberOffsets[i]); + } + + hashMapInsert(t, typeMaps, c, array, objectHash); + } + + if (classStaticTable(t, c)) { + object array = makeByteArray + (t, TypeMap::sizeInBytes + (singletonCount(t, classStaticTable(t, c)) + 2, staticIndex)); + + TypeMap* map = new (&byteArrayBody(t, array, 0)) TypeMap + (singletonCount(t, classStaticTable(t, c)) + 2, + ceiling(targetStaticOffset, TargetBytesPerWord), staticIndex, + TypeMap::SingletonKind); + + for (unsigned i = 0; i < staticIndex; ++i) { + expect(t, buildStaticOffsets[i] + < map->buildFixedSizeInWords * BytesPerWord); + + map->targetFixedOffsets()[buildStaticOffsets[i]] + = targetStaticOffsets[i]; + + new (map->fixedFields() + i) Field + (staticTypes[i], buildStaticOffsets[i], targetStaticOffsets[i]); + } + + hashMapInsert + (t, typeMaps, classStaticTable(t, c), array, objectHash); + } + } + if (classMethodTable(t, c)) { for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) { object method = arrayBody(t, classMethodTable(t, c), i); @@ -163,18 +492,18 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code, for (; addresses; addresses = addresses->next) { uint8_t* value = reinterpret_cast(addresses->basis->value()); - assert(t, value >= code); + expect(t, value >= code); void* location; bool flat = addresses->listener->resolve (reinterpret_cast(code), &location); - uintptr_t offset = value - code; + target_uintptr_t offset = value - code; if (flat) { offset |= BootFlatConstant; } - memcpy(location, &offset, BytesPerWord); + memcpy(location, &offset, TargetBytesPerWord); - assert(t, reinterpret_cast(location) + expect(t, reinterpret_cast(location) >= reinterpret_cast(code)); markBit(codeMap, reinterpret_cast(location) @@ -187,8 +516,6 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code, unsigned objectSize(Thread* t, object o) { - assert(t, not objectExtended(t, o)); - return baseSize(t, o, objectClass(t, o)); } @@ -214,20 +541,310 @@ visitRoots(Thread* t, BootImage* image, HeapWalker* w, object constants) } } +TypeMap* +typeMap(Thread* t, object typeMaps, object p) +{ + return reinterpret_cast + (&byteArrayBody + (t, objectClass(t, p) == type(t, Machine::SingletonType) + ? hashMapFind(t, typeMaps, p, objectHash, objectEqual) + : hashMapFind(t, typeMaps, objectClass(t, p), objectHash, objectEqual), + 0)); +} + +unsigned +targetOffset(Thread* t, object typeMaps, object p, unsigned offset) +{ + TypeMap* map = typeMap(t, typeMaps, p); + + if (map->targetArrayElementSizeInBytes + and offset >= map->buildFixedSizeInWords * BytesPerWord) + { + return (map->targetFixedSizeInWords * TargetBytesPerWord) + + (((offset - (map->buildFixedSizeInWords * BytesPerWord)) + / map->buildArrayElementSizeInBytes) + * map->targetArrayElementSizeInBytes); + } else { + return map->targetFixedOffsets()[offset]; + } +} + +unsigned +targetSize(Thread* t, object typeMaps, object p) +{ + TypeMap* map = typeMap(t, typeMaps, p); + + if (map->targetArrayElementSizeInBytes) { + return map->targetFixedSizeInWords + + ceiling(map->targetArrayElementSizeInBytes + * cast + (p, (map->buildFixedSizeInWords - 1) * BytesPerWord), + TargetBytesPerWord); + } else { + switch (map->kind) { + case TypeMap::NormalKind: + return map->targetFixedSizeInWords; + + case TypeMap::SingletonKind: + return map->targetFixedSizeInWords + singletonMaskSize + (map->targetFixedSizeInWords - 2, TargetBitsPerWord); + + case TypeMap::PoolKind: { + unsigned maskSize = poolMaskSize + (map->targetFixedSizeInWords - 2, TargetBitsPerWord); + + return map->targetFixedSizeInWords + maskSize + singletonMaskSize + (map->targetFixedSizeInWords - 2 + maskSize, TargetBitsPerWord); + } + + default: abort(t); + } + } +} + +void +copy(Thread* t, uint8_t* src, uint8_t* dst, Type type) +{ + switch (type) { + case Type_int8_t: + memcpy(dst, src, 1); + break; + + case Type_int16_t: { + int16_t s; memcpy(&s, src, 2); + int16_t d = TARGET_V2(s); + memcpy(dst, &d, 2); + } break; + + case Type_int32_t: + case Type_float: { + int32_t s; memcpy(&s, src, 4); + int32_t d = TARGET_V4(s); + memcpy(dst, &d, 4); + } break; + + case Type_int64_t: + case Type_double: { + int64_t s; memcpy(&s, src, 8); + int64_t d = TARGET_V8(s); + memcpy(dst, &d, 8); + } break; + + case Type_int64_t_pad: + case Type_double_pad: + break; + + case Type_intptr_t: { + intptr_t s; memcpy(&s, src, BytesPerWord); + target_intptr_t d = TARGET_VW(s); + memcpy(dst, &d, TargetBytesPerWord); + } break; + + case Type_object: { + memset(dst, 0, TargetBytesPerWord); + } break; + + default: abort(t); + } +} + +bool +nonObjectsEqual(uint8_t* src, uint8_t* dst, Type type) +{ + switch (type) { + case Type_int8_t: + return memcmp(dst, src, 1) == 0; + + case Type_int16_t: + return memcmp(dst, src, 2) == 0; + + case Type_int32_t: + case Type_float: + return memcmp(dst, src, 4) == 0; + + case Type_int64_t: + case Type_double: + return memcmp(dst, src, 8) == 0; + + case Type_int64_t_pad: + case Type_double_pad: + return true; + + case Type_intptr_t: + return memcmp(dst, src, BytesPerWord) == 0; + + case Type_object: + return true; + + default: abort(); + } +} + +bool +nonObjectsEqual(TypeMap* map, uint8_t* src, uint8_t* dst) +{ + for (unsigned i = 0; i < map->fixedFieldCount; ++i) { + Field* field = map->fixedFields() + i; + if (not nonObjectsEqual + (src + field->offset, dst + field->targetOffset, field->type)) + { + return false; + } + } + + if (map->targetArrayElementSizeInBytes) { + unsigned fixedSize = map->buildFixedSizeInWords * BytesPerWord; + unsigned count = cast(src, fixedSize - BytesPerWord); + + for (unsigned i = 0; i < count; ++i) { + if (not nonObjectsEqual + (src + fixedSize + (i * map->buildArrayElementSizeInBytes), + dst + (map->targetFixedSizeInWords * TargetBytesPerWord) + + (i * map->targetArrayElementSizeInBytes), map->arrayElementType)) + { + return false; + } + } + } + + return true; +} + +void +copy(Thread* t, object typeMaps, object p, uint8_t* dst) +{ + TypeMap* map = typeMap(t, typeMaps, p); + + uint8_t* src = reinterpret_cast(p); + + for (unsigned i = 0; i < map->fixedFieldCount; ++i) { + Field* field = map->fixedFields() + i; + if (field->type > Type_array) abort(t); + copy(t, src + field->offset, dst + field->targetOffset, field->type); + } + + if (map->targetArrayElementSizeInBytes) { + unsigned fixedSize = map->buildFixedSizeInWords * BytesPerWord; + unsigned count = cast(p, fixedSize - BytesPerWord); + + for (unsigned i = 0; i < count; ++i) { + copy(t, src + fixedSize + (i * map->buildArrayElementSizeInBytes), + dst + (map->targetFixedSizeInWords * TargetBytesPerWord) + + (i * map->targetArrayElementSizeInBytes), map->arrayElementType); + } + } else { + switch (map->kind) { + case TypeMap::NormalKind: + break; + + case TypeMap::SingletonKind: { + uint8_t* mask = dst + (map->targetFixedSizeInWords * TargetBytesPerWord); + memset(mask, 0, singletonMaskSize + (map->targetFixedSizeInWords - 2, TargetBitsPerWord) + * TargetBytesPerWord); + + for (unsigned i = 0; i < map->fixedFieldCount; ++i) { + Field* field = map->fixedFields() + i; + if (field->type == Type_object) { + unsigned offset = field->targetOffset / TargetBytesPerWord; + reinterpret_cast(mask)[offset / 32] + |= static_cast(1) << (offset % 32); + } + } + + if (DebugNativeTarget) { + expect + (t, memcmp + (src + (map->targetFixedSizeInWords * TargetBytesPerWord), mask, + singletonMaskSize + (map->targetFixedSizeInWords - 2, TargetBitsPerWord) + * TargetBytesPerWord) == 0); + } + } break; + + case TypeMap::PoolKind: { + unsigned poolMaskSize = vm::poolMaskSize + (map->targetFixedSizeInWords - 2, TargetBitsPerWord); + + uint8_t* poolMask = dst + + (map->targetFixedSizeInWords * TargetBytesPerWord); + + memset(poolMask, 0, poolMaskSize * TargetBytesPerWord); + + uint8_t* objectMask = dst + + ((map->targetFixedSizeInWords + poolMaskSize) * TargetBytesPerWord); + + memset(objectMask, 0, singletonMaskSize + (map->targetFixedSizeInWords - 2 + poolMaskSize, + TargetBitsPerWord) * TargetBytesPerWord); + + for (unsigned i = 0; i < map->fixedFieldCount; ++i) { + Field* field = map->fixedFields() + i; + switch (field->type) { + case Type_object: + reinterpret_cast(objectMask)[i / 32] + |= static_cast(1) << (i % 32); + break; + + case Type_float: + case Type_double: + reinterpret_cast(poolMask) + [i / TargetBitsPerWord] + |= static_cast(1) << (i % TargetBitsPerWord); + break; + + default: + break; + } + } + + if (DebugNativeTarget) { + expect + (t, memcmp + (src + (map->targetFixedSizeInWords * TargetBytesPerWord), poolMask, + (poolMaskSize + singletonMaskSize + (map->targetFixedSizeInWords - 2 + poolMaskSize, + TargetBitsPerWord)) + * TargetBytesPerWord) == 0); + } + } break; + + default: abort(t); + } + } + + if (DebugNativeTarget) { + expect(t, targetSize(t, typeMaps, p) == baseSize(t, p, objectClass(t, p))); + expect(t, nonObjectsEqual(map, src, dst)); + } +} + HeapWalker* makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map, - unsigned capacity, object constants) + unsigned capacity, object constants, object typeMaps) { class Visitor: public HeapVisitor { public: - Visitor(Thread* t, uintptr_t* heap, uintptr_t* map, unsigned capacity): - t(t), currentObject(0), currentNumber(0), currentOffset(0), heap(heap), - map(map), position(0), capacity(capacity) + Visitor(Thread* t, object typeMaps, uintptr_t* heap, + uintptr_t* map, unsigned capacity): + t(t), typeMaps(typeMaps), currentObject(0), currentNumber(0), + currentOffset(0), heap(heap), map(map), position(0), capacity(capacity) { } void visit(unsigned number) { if (currentObject) { - unsigned offset = currentNumber - 1 + currentOffset; + if (DebugNativeTarget) { + expect + (t, targetOffset + (t, typeMaps, currentObject, currentOffset * BytesPerWord) + == currentOffset * BytesPerWord); + } + + unsigned offset = currentNumber - 1 + + (targetOffset + (t, typeMaps, currentObject, currentOffset * BytesPerWord) + / TargetBytesPerWord); + unsigned mark = heap[offset] & (~PointerMask); unsigned value = number | (mark << BootShift); @@ -243,10 +860,11 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map, virtual unsigned visitNew(object p) { if (p) { - unsigned size = objectSize(t, p); + unsigned size = targetSize(t, typeMaps, p); unsigned number; if ((currentObject + and objectClass(t, currentObject) == type(t, Machine::ClassType) and (currentOffset * BytesPerWord) == ClassStaticTable) or instanceOf(t, type(t, Machine::SystemClassLoaderType), p)) { @@ -257,24 +875,41 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map, // to runtime-allocated memory would fail because we don't // scan non-fixed objects in the heap image during GC. - FixedAllocator allocator - (t->m->system, reinterpret_cast(heap + position), - (capacity - position) * BytesPerWord); + target_uintptr_t* dst = heap + position + TargetFixieSizeInWords; - unsigned totalInBytes; - uintptr_t* dst = static_cast - (t->m->heap->allocateImmortalFixed - (&allocator, size, true, &totalInBytes)); + unsigned maskSize = ceiling(size, TargetBytesPerWord); - memcpy(dst, p, size * BytesPerWord); + unsigned total = TargetFixieSizeInWords + size + maskSize; + + expect(t, position + total < capacity); + + memset(heap + position, 0, TargetFixieSizeInBytes); + + uint8_t age = FixieTenureThreshold + 1; + memcpy(reinterpret_cast(heap + position) + + TargetFixieAge, &age, 1); + + uint8_t hasMask = true; + memcpy(reinterpret_cast(heap + position) + + TargetFixieHasMask, &hasMask, 1); + + uint32_t targetSize = TARGET_V4(size); + memcpy(reinterpret_cast(heap + position) + + TargetFixieSize, &targetSize, 4); + + copy(t, typeMaps, p, reinterpret_cast(dst)); dst[0] |= FixedMark; + memset(heap + position + TargetFixieSizeInWords + size, 0, + maskSize * TargetBytesPerWord); + number = (dst - heap) + 1; - position += ceiling(totalInBytes, BytesPerWord); + position += total; } else { - assert(t, position + size < capacity); - memcpy(heap + position, p, size * BytesPerWord); + expect(t, position + size < capacity); + + copy(t, typeMaps, p, reinterpret_cast(heap + position)); number = position + 1; position += size; @@ -303,14 +938,15 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map, } Thread* t; + object typeMaps; object currentObject; unsigned currentNumber; unsigned currentOffset; - uintptr_t* heap; - uintptr_t* map; + target_uintptr_t* heap; + target_uintptr_t* map; unsigned position; unsigned capacity; - } visitor(t, heap, map, capacity / BytesPerWord); + } visitor(t, typeMaps, heap, map, capacity / TargetBytesPerWord); HeapWalker* w = makeHeapWalker(t, &visitor); visitRoots(t, image, w, constants); @@ -326,7 +962,7 @@ updateConstants(Thread* t, object constants, uint8_t* code, uintptr_t* codeMap, { for (; constants; constants = tripleThird(t, constants)) { unsigned target = heapTable->find(tripleFirst(t, constants)); - assert(t, target > 0); + expect(t, target > 0); for (Promise::Listener* pl = static_cast (pointerValue(t, tripleSecond(t, constants)))->listener; @@ -334,13 +970,13 @@ updateConstants(Thread* t, object constants, uint8_t* code, uintptr_t* codeMap, { void* location; bool flat = pl->resolve(0, &location); - uintptr_t offset = target | BootHeapOffset; + target_uintptr_t offset = target | BootHeapOffset; if (flat) { offset |= BootFlatConstant; } - memcpy(location, &offset, BytesPerWord); + memcpy(location, &offset, TargetBytesPerWord); - assert(t, reinterpret_cast(location) + expect(t, reinterpret_cast(location) >= reinterpret_cast(code)); markBit(codeMap, reinterpret_cast(location) @@ -366,74 +1002,221 @@ writeBootImage2(Thread* t, FILE* out, BootImage* image, uint8_t* code, (t->m->heap->allocate(codeMapSize(codeCapacity))); memset(codeMap, 0, codeMapSize(codeCapacity)); - object constants = makeCodeImage - (t, &zone, image, code, codeMap, className, methodName, methodSpec); + object classPoolMap; + object typeMaps; + object constants; - PROTECT(t, constants); + { classPoolMap = makeHashMap(t, 0, 0); + PROTECT(t, classPoolMap); - // this map will not be used when the bootimage is loaded, so - // there's no need to preserve it: - setRoot(t, Machine::ByteArrayMap, makeWeakHashMap(t, 0, 0)); + setRoot(t, Machine::PoolMap, classPoolMap); - // name all primitive classes so we don't try to update immutable - // references at runtime: - { object name = makeByteArray(t, "void"); - set(t, type(t, Machine::JvoidType), ClassName, name); + typeMaps = makeHashMap(t, 0, 0); + PROTECT(t, typeMaps); + + constants = makeCodeImage + (t, &zone, image, code, codeMap, className, methodName, methodSpec, + typeMaps); + + PROTECT(t, constants); + +#include "type-maps.cpp" + + for (unsigned i = 0; i < arrayLength(t, t->m->types); ++i) { + Type* source = types[i]; + unsigned count = 0; + while (source[count] != Type_none) { + ++ count; + } + ++ count; + + Type types[count]; + types[0] = Type_object; + unsigned buildOffsets[count]; + buildOffsets[0] = 0; + unsigned buildOffset = BytesPerWord; + unsigned targetOffsets[count]; + targetOffsets[0] = 0; + unsigned targetOffset = TargetBytesPerWord; + bool sawArray = false; + unsigned buildSize = BytesPerWord; + unsigned targetSize = TargetBytesPerWord; + for (unsigned j = 1; j < count; ++j) { + switch (source[j - 1]) { + case Type_object: + types[j] = Type_object; + buildSize = BytesPerWord; + targetSize = TargetBytesPerWord; + break; + + case Type_word: + case Type_intptr_t: + case Type_uintptr_t: + types[j] = Type_intptr_t; + buildSize = BytesPerWord; + targetSize = TargetBytesPerWord; + break; + + case Type_int8_t: + case Type_uint8_t: + types[j] = Type_int8_t; + buildSize = targetSize = 1; + break; + + case Type_int16_t: + case Type_uint16_t: + types[j] = Type_int16_t; + buildSize = targetSize = 2; + break; + + case Type_int32_t: + case Type_uint32_t: + case Type_float: + types[j] = Type_int32_t; + buildSize = targetSize = 4; + break; + + case Type_int64_t: + case Type_uint64_t: + case Type_double: + types[j] = Type_int64_t; + buildSize = targetSize = 8; + break; + + case Type_array: + types[j] = Type_none; + buildSize = targetSize = 0; + break; + + default: abort(t); + } + + if (source[j - 1] == Type_array) { + sawArray = true; + } + + if (not sawArray) { + while (buildOffset % buildSize) { + ++ buildOffset; + } + + buildOffsets[j] = buildOffset; + + buildOffset += buildSize; + + while (targetOffset % targetSize) { + ++ targetOffset; + } + + targetOffsets[j] = targetOffset; + + targetOffset += targetSize; + } + } + + unsigned fixedFieldCount; + Type arrayElementType; + unsigned buildArrayElementSize; + unsigned targetArrayElementSize; + if (sawArray) { + fixedFieldCount = count - 2; + arrayElementType = types[count - 1]; + buildArrayElementSize = buildSize; + targetArrayElementSize = targetSize; + } else { + fixedFieldCount = count; + arrayElementType = Type_none; + buildArrayElementSize = 0; + targetArrayElementSize = 0; + } + + object array = makeByteArray + (t, TypeMap::sizeInBytes + (ceiling(buildOffset, BytesPerWord), fixedFieldCount)); + + TypeMap* map = new (&byteArrayBody(t, array, 0)) TypeMap + (ceiling(buildOffset, BytesPerWord), + ceiling(targetOffset, TargetBytesPerWord), + fixedFieldCount, TypeMap::NormalKind, buildArrayElementSize, + targetArrayElementSize, arrayElementType); + + for (unsigned j = 0; j < fixedFieldCount; ++j) { + expect(t, buildOffsets[j] < map->buildFixedSizeInWords * BytesPerWord); + + map->targetFixedOffsets()[buildOffsets[j]] = targetOffsets[j]; + + new (map->fixedFields() + j) Field + (types[j], buildOffsets[j], targetOffsets[j]); + } + + hashMapInsertOrReplace + (t, typeMaps, type(t, static_cast(i)), array, + objectHash, objectEqual); + } + + // these roots will not be used when the bootimage is loaded, so + // there's no need to preserve them: + setRoot(t, Machine::PoolMap, 0); + setRoot(t, Machine::ByteArrayMap, makeWeakHashMap(t, 0, 0)); + + // name all primitive classes so we don't try to update immutable + // references at runtime: + { object name = makeByteArray(t, "void"); + set(t, type(t, Machine::JvoidType), ClassName, name); - name = makeByteArray(t, "boolean"); - set(t, type(t, Machine::JbooleanType), ClassName, name); + name = makeByteArray(t, "boolean"); + set(t, type(t, Machine::JbooleanType), ClassName, name); - name = makeByteArray(t, "byte"); - set(t, type(t, Machine::JbyteType), ClassName, name); + name = makeByteArray(t, "byte"); + set(t, type(t, Machine::JbyteType), ClassName, name); - name = makeByteArray(t, "short"); - set(t, type(t, Machine::JshortType), ClassName, name); + name = makeByteArray(t, "short"); + set(t, type(t, Machine::JshortType), ClassName, name); - name = makeByteArray(t, "char"); - set(t, type(t, Machine::JcharType), ClassName, name); + name = makeByteArray(t, "char"); + set(t, type(t, Machine::JcharType), ClassName, name); - name = makeByteArray(t, "int"); - set(t, type(t, Machine::JintType), ClassName, name); + name = makeByteArray(t, "int"); + set(t, type(t, Machine::JintType), ClassName, name); - name = makeByteArray(t, "float"); - set(t, type(t, Machine::JfloatType), ClassName, name); + name = makeByteArray(t, "float"); + set(t, type(t, Machine::JfloatType), ClassName, name); - name = makeByteArray(t, "long"); - set(t, type(t, Machine::JlongType), ClassName, name); + name = makeByteArray(t, "long"); + set(t, type(t, Machine::JlongType), ClassName, name); - name = makeByteArray(t, "double"); - set(t, type(t, Machine::JdoubleType), ClassName, name); + name = makeByteArray(t, "double"); + set(t, type(t, Machine::JdoubleType), ClassName, name); + } + + // resolve primitive array classes in case they are needed at + // runtime: + { object name = makeByteArray(t, "[B"); + resolveSystemClass(t, root(t, Machine::BootLoader), name, true); + + name = makeByteArray(t, "[Z"); + resolveSystemClass(t, root(t, Machine::BootLoader), name, true); + + name = makeByteArray(t, "[S"); + resolveSystemClass(t, root(t, Machine::BootLoader), name, true); + + name = makeByteArray(t, "[C"); + resolveSystemClass(t, root(t, Machine::BootLoader), name, true); + + name = makeByteArray(t, "[I"); + resolveSystemClass(t, root(t, Machine::BootLoader), name, true); + + name = makeByteArray(t, "[J"); + resolveSystemClass(t, root(t, Machine::BootLoader), name, true); + + name = makeByteArray(t, "[F"); + resolveSystemClass(t, root(t, Machine::BootLoader), name, true); + + name = makeByteArray(t, "[D"); + resolveSystemClass(t, root(t, Machine::BootLoader), name, true); + } } - // resolve primitive array classes in case they are needed at - // runtime: - { object name = makeByteArray(t, "[B"); - resolveSystemClass(t, root(t, Machine::BootLoader), name, true); - - name = makeByteArray(t, "[Z"); - resolveSystemClass(t, root(t, Machine::BootLoader), name, true); - - name = makeByteArray(t, "[S"); - resolveSystemClass(t, root(t, Machine::BootLoader), name, true); - - name = makeByteArray(t, "[C"); - resolveSystemClass(t, root(t, Machine::BootLoader), name, true); - - name = makeByteArray(t, "[I"); - resolveSystemClass(t, root(t, Machine::BootLoader), name, true); - - name = makeByteArray(t, "[J"); - resolveSystemClass(t, root(t, Machine::BootLoader), name, true); - - name = makeByteArray(t, "[F"); - resolveSystemClass(t, root(t, Machine::BootLoader), name, true); - - name = makeByteArray(t, "[D"); - resolveSystemClass(t, root(t, Machine::BootLoader), name, true); - } - - collect(t, Heap::MajorCollection); - uintptr_t* heap = static_cast (t->m->heap->allocate(HeapCapacity)); uintptr_t* heapMap = static_cast @@ -441,7 +1224,7 @@ writeBootImage2(Thread* t, FILE* out, BootImage* image, uint8_t* code, memset(heapMap, 0, heapMapSize(HeapCapacity)); HeapWalker* heapWalker = makeHeapImage - (t, image, heap, heapMap, HeapCapacity, constants); + (t, image, heap, heapMap, HeapCapacity, constants, typeMaps); updateConstants(t, constants, code, codeMap, heapWalker->map()); @@ -512,7 +1295,7 @@ writeBootImage2(Thread* t, FILE* out, BootImage* image, uint8_t* code, + (image->stringCount * sizeof(unsigned)) + (image->callCount * sizeof(unsigned) * 2); - while (offset % BytesPerWord) { + while (offset % TargetBytesPerWord) { uint8_t c = 0; fwrite(&c, 1, 1, out); ++ offset; diff --git a/src/compile.cpp b/src/compile.cpp index afd590fc8f..fa1ffa4778 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -13,6 +13,7 @@ #include "vector.h" #include "process.h" #include "assembler.h" +#include "target.h" #include "compiler.h" #include "arch.h" @@ -52,7 +53,7 @@ const bool Continuations = true; const bool Continuations = false; #endif -const unsigned MaxNativeCallFootprint = BytesPerWord == 8 ? 4 : 5; +const unsigned MaxNativeCallFootprint = TargetBytesPerWord == 8 ? 4 : 5; const unsigned InitialZoneCapacityInBytes = 64 * 1024; @@ -3164,7 +3165,7 @@ resultSize(MyThread* t, unsigned code) return 4; case ObjectField: - return BytesPerWord; + return TargetBytesPerWord; case LongField: case DoubleField: @@ -3305,8 +3306,8 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall, methodParameterFootprint(t, target)); c->store - (BytesPerWord, frame->addressOperand(returnAddressPromise), - BytesPerWord, c->memory + (TargetBytesPerWord, frame->addressOperand(returnAddressPromise), + TargetBytesPerWord, c->memory (c->register_(t->arch->thread()), Compiler::AddressType, difference(&(t->tailAddress), t))); @@ -3455,7 +3456,7 @@ compileDirectReferenceInvoke(MyThread* t, Frame* frame, Thunk thunk, (c->constant(getThunk(t, thunk), Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::AddressType, 2, c->register_(t->arch->thread()), frame->append(pair)), reference, isStatic, tailCall); @@ -3497,7 +3498,7 @@ compileDirectAbstractInvoke(MyThread* t, Frame* frame, Thunk thunk, (c->constant(getThunk(t, thunk), Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::AddressType, 2, c->register_(t->arch->thread()), frame->append(target)), target, tailCall); @@ -3560,7 +3561,7 @@ inTryBlock(MyThread* t, object code, unsigned ip) if (table) { unsigned length = exceptionHandlerTableLength(t, table); for (unsigned i = 0; i < length; ++i) { - ExceptionHandler* eh = exceptionHandlerTableBody(t, table, i); + uint64_t eh = exceptionHandlerTableBody(t, table, i); if (ip >= exceptionHandlerStart(eh) and ip < exceptionHandlerEnd(eh)) { @@ -3867,16 +3868,18 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case aaload: frame->pushObject (c->load - (BytesPerWord, BytesPerWord, c->memory - (array, Compiler::ObjectType, ArrayBody, index, BytesPerWord), - BytesPerWord)); + (TargetBytesPerWord, TargetBytesPerWord, c->memory + (array, Compiler::ObjectType, ArrayBody, index, + TargetBytesPerWord), + TargetBytesPerWord)); break; case faload: frame->pushInt (c->load (4, 4, c->memory - (array, Compiler::FloatType, ArrayBody, index, 4), BytesPerWord)); + (array, Compiler::FloatType, ArrayBody, index, 4), + TargetBytesPerWord)); break; case iaload: @@ -3884,7 +3887,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->load (4, 4, c->memory (array, Compiler::IntegerType, ArrayBody, index, 4), - BytesPerWord)); + TargetBytesPerWord)); break; case baload: @@ -3892,7 +3895,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->load (1, 1, c->memory (array, Compiler::IntegerType, ArrayBody, index, 1), - BytesPerWord)); + TargetBytesPerWord)); break; case caload: @@ -3900,7 +3903,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->loadz (2, 2, c->memory (array, Compiler::IntegerType, ArrayBody, index, 2), - BytesPerWord)); + TargetBytesPerWord)); break; case daload: @@ -3922,7 +3925,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->load (2, 2, c->memory (array, Compiler::IntegerType, ArrayBody, index, 2), - BytesPerWord)); + TargetBytesPerWord)); break; } } break; @@ -3968,32 +3971,33 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, c->add (4, c->constant(ArrayBody, Compiler::IntegerType), c->shl - (4, c->constant(log(BytesPerWord), Compiler::IntegerType), index)), + (4, c->constant(log(TargetBytesPerWord), Compiler::IntegerType), + index)), value); } break; case fastore: c->store - (BytesPerWord, value, 4, c->memory + (TargetBytesPerWord, value, 4, c->memory (array, Compiler::FloatType, ArrayBody, index, 4)); break; case iastore: c->store - (BytesPerWord, value, 4, c->memory + (TargetBytesPerWord, value, 4, c->memory (array, Compiler::IntegerType, ArrayBody, index, 4)); break; case bastore: c->store - (BytesPerWord, value, 1, c->memory + (TargetBytesPerWord, value, 1, c->memory (array, Compiler::IntegerType, ArrayBody, index, 1)); break; case castore: case sastore: c->store - (BytesPerWord, value, 2, c->memory + (TargetBytesPerWord, value, 2, c->memory (array, Compiler::IntegerType, ArrayBody, index, 2)); break; @@ -4062,7 +4066,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->constant(getThunk(t, thunk), Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::ObjectType, 3, c->register_(t->arch->thread()), frame->append(argument), length)); @@ -4070,16 +4074,16 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case areturn: { handleExit(t, frame); - c->return_(BytesPerWord, frame->popObject()); + c->return_(TargetBytesPerWord, frame->popObject()); } return; case arraylength: { frame->pushInt (c->load - (BytesPerWord, BytesPerWord, + (TargetBytesPerWord, TargetBytesPerWord, c->memory (frame->popObject(), Compiler::IntegerType, ArrayLength, 0, 1), - BytesPerWord)); + TargetBytesPerWord)); } break; case astore: @@ -4367,7 +4371,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, if (LIKELY(field)) { if ((fieldFlags(t, field) & ACC_VOLATILE) - and BytesPerWord == 4 + and TargetBytesPerWord == 4 and (fieldCode(t, field) == DoubleField or fieldCode(t, field) == LongField)) { @@ -4375,7 +4379,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, c->call (c->constant - (getThunk(t, acquireMonitorForObjectThunk), Compiler::AddressType), + (getThunk(t, acquireMonitorForObjectThunk), + Compiler::AddressType), 0, frame->trace(0, 0), 0, Compiler::VoidType, 2, c->register_(t->arch->thread()), frame->append(field)); @@ -4421,7 +4426,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->load (1, 1, c->memory (table, Compiler::IntegerType, fieldOffset(t, field), 0, 1), - BytesPerWord)); + TargetBytesPerWord)); break; case CharField: @@ -4429,7 +4434,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->loadz (2, 2, c->memory (table, Compiler::IntegerType, fieldOffset(t, field), 0, 1), - BytesPerWord)); + TargetBytesPerWord)); break; case ShortField: @@ -4437,7 +4442,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->load (2, 2, c->memory (table, Compiler::IntegerType, fieldOffset(t, field), 0, 1), - BytesPerWord)); + TargetBytesPerWord)); break; case FloatField: @@ -4445,7 +4450,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->load (4, 4, c->memory (table, Compiler::FloatType, fieldOffset(t, field), 0, 1), - BytesPerWord)); + TargetBytesPerWord)); break; case IntField: @@ -4453,7 +4458,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->load (4, 4, c->memory (table, Compiler::IntegerType, fieldOffset(t, field), 0, 1), - BytesPerWord)); + TargetBytesPerWord)); break; case DoubleField: @@ -4473,10 +4478,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case ObjectField: frame->pushObject (c->load - (BytesPerWord, BytesPerWord, + (TargetBytesPerWord, TargetBytesPerWord, c->memory (table, Compiler::ObjectType, fieldOffset(t, field), 0, 1), - BytesPerWord)); + TargetBytesPerWord)); break; default: @@ -4484,7 +4489,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } if (fieldFlags(t, field) & ACC_VOLATILE) { - if (BytesPerWord == 4 + if (TargetBytesPerWord == 4 and (fieldCode(t, field) == DoubleField or fieldCode(t, field) == LongField)) { @@ -4551,11 +4556,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } break; case i2b: { - frame->pushInt(c->load(BytesPerWord, 1, frame->popInt(), BytesPerWord)); + frame->pushInt + (c->load(TargetBytesPerWord, 1, frame->popInt(), TargetBytesPerWord)); } break; case i2c: { - frame->pushInt(c->loadz(BytesPerWord, 2, frame->popInt(), BytesPerWord)); + frame->pushInt + (c->loadz(TargetBytesPerWord, 2, frame->popInt(), TargetBytesPerWord)); } break; case i2d: { @@ -4567,11 +4574,12 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } break; case i2l: - frame->pushLong(c->load(BytesPerWord, 4, frame->popInt(), 8)); + frame->pushLong(c->load(TargetBytesPerWord, 4, frame->popInt(), 8)); break; case i2s: { - frame->pushInt(c->load(BytesPerWord, 2, frame->popInt(), BytesPerWord)); + frame->pushInt + (c->load(TargetBytesPerWord, 2, frame->popInt(), TargetBytesPerWord)); } break; case iadd: { @@ -4637,9 +4645,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Compiler::Operand* target = frame->machineIp(newIp); if (instruction == if_acmpeq) { - c->jumpIfEqual(BytesPerWord, a, b, target); + c->jumpIfEqual(TargetBytesPerWord, a, b, target); } else { - c->jumpIfNotEqual(BytesPerWord, a, b, target); + c->jumpIfNotEqual(TargetBytesPerWord, a, b, target); } saveStateAndCompile(t, frame, newIp); @@ -4737,9 +4745,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Compiler::Operand* target = frame->machineIp(newIp); if (instruction == ifnull) { - c->jumpIfEqual(BytesPerWord, a, b, target); + c->jumpIfEqual(TargetBytesPerWord, a, b, target); } else { - c->jumpIfNotEqual(BytesPerWord, a, b, target); + c->jumpIfNotEqual(TargetBytesPerWord, a, b, target); } saveStateAndCompile(t, frame, newIp); @@ -4868,7 +4876,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->constant(getThunk(t, thunk), Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::AddressType, 3, c->register_(t->arch->thread()), frame->append(argument), c->peek(1, parameterFootprint - 1)), @@ -4976,7 +4984,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Compiler::Operand* result = c->stackCall (c->memory (c->and_ - (BytesPerWord, c->constant(PointerMask, Compiler::IntegerType), + (TargetBytesPerWord, c->constant + (PointerMask, Compiler::IntegerType), c->memory(instance, Compiler::ObjectType, 0, 0, 1)), Compiler::ObjectType, offset, 0, 1), tailCall ? Compiler::TailJump : 0, @@ -5008,7 +5017,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::AddressType, 3, c->register_(t->arch->thread()), frame->append(pair), c->peek(1, methodReferenceParameterFootprint @@ -5132,7 +5141,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } break; case l2i: - frame->pushInt(c->load(8, 8, frame->popLong(), BytesPerWord)); + frame->pushInt(c->load(8, 8, frame->popLong(), TargetBytesPerWord)); break; case ladd: { @@ -5201,7 +5210,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::ObjectType, 2, c->register_(t->arch->thread()), frame->append(makePair(t, context->method, reference)))); @@ -5216,7 +5225,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (getThunk(t, getJClass64Thunk), Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::ObjectType, 2, c->register_(t->arch->thread()), frame->append(v))); } else { @@ -5330,7 +5339,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->call (c->constant (getThunk(t, lookUpAddressThunk), Compiler::AddressType), - 0, 0, BytesPerWord, Compiler::AddressType, + 0, 0, TargetBytesPerWord, Compiler::AddressType, 4, key, start, c->constant(pairCount, Compiler::IntegerType), default_)); @@ -5477,7 +5486,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (getThunk(t, thunk), Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::ObjectType, 4, c->register_(t->arch->thread()), frame->append(argument), c->constant(dimensions, Compiler::IntegerType), @@ -5516,7 +5525,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->constant(getThunk(t, thunk), Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::ObjectType, 2, c->register_(t->arch->thread()), frame->append(argument))); } break; @@ -5531,7 +5540,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, (c->constant(getThunk(t, makeBlankArrayThunk), Compiler::AddressType), 0, frame->trace(0, 0), - BytesPerWord, + TargetBytesPerWord, Compiler::ObjectType, 3, c->register_(t->arch->thread()), c->constant(type, Compiler::IntegerType), length)); @@ -5593,7 +5602,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } if (fieldFlags(t, field) & ACC_VOLATILE) { - if (BytesPerWord == 4 + if (TargetBytesPerWord == 4 and (fieldCode == DoubleField or fieldCode == LongField)) { PROTECT(t, field); @@ -5625,26 +5634,26 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case ByteField: case BooleanField: c->store - (BytesPerWord, value, 1, c->memory + (TargetBytesPerWord, value, 1, c->memory (table, Compiler::IntegerType, fieldOffset(t, field), 0, 1)); break; case CharField: case ShortField: c->store - (BytesPerWord, value, 2, c->memory + (TargetBytesPerWord, value, 2, c->memory (table, Compiler::IntegerType, fieldOffset(t, field), 0, 1)); break; case FloatField: c->store - (BytesPerWord, value, 4, c->memory + (TargetBytesPerWord, value, 4, c->memory (table, Compiler::FloatType, fieldOffset(t, field), 0, 1)); break; case IntField: c->store - (BytesPerWord, value, 4, c->memory + (TargetBytesPerWord, value, 4, c->memory (table, Compiler::IntegerType, fieldOffset(t, field), 0, 1)); break; @@ -5686,7 +5695,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } if (fieldFlags(t, field) & ACC_VOLATILE) { - if (BytesPerWord == 4 + if (TargetBytesPerWord == 4 and (fieldCode == DoubleField or fieldCode == LongField)) { c->call @@ -5862,9 +5871,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, c->jmp (c->load - (BytesPerWord, BytesPerWord, c->memory - (start, Compiler::AddressType, 0, normalizedKey, BytesPerWord), - BytesPerWord)); + (TargetBytesPerWord, TargetBytesPerWord, c->memory + (start, Compiler::AddressType, 0, normalizedKey, TargetBytesPerWord), + TargetBytesPerWord)); Compiler::State* state = c->saveState(); @@ -6018,9 +6027,9 @@ truncateLineNumberTable(Thread* t, object table, unsigned length) PROTECT(t, table); object newTable = makeLineNumberTable(t, length); - memcpy(lineNumberTableBody(t, newTable, 0), - lineNumberTableBody(t, table, 0), - length * sizeof(LineNumber)); + memcpy(&lineNumberTableBody(t, newTable, 0), + &lineNumberTableBody(t, table, 0), + length * sizeof(uint64_t)); return newTable; } @@ -6046,7 +6055,7 @@ translateExceptionHandlerTable(MyThread* t, Context* context, intptr_t start) unsigned ni = 0; for (unsigned oi = 0; oi < length; ++ oi) { - ExceptionHandler* oldHandler = exceptionHandlerTableBody + uint64_t oldHandler = exceptionHandlerTableBody (t, oldTable, oi); int handlerStart = resolveIpForwards @@ -6107,8 +6116,7 @@ translateLineNumberTable(MyThread* t, Context* context, intptr_t start) object newTable = makeLineNumberTable(t, length); unsigned ni = 0; for (unsigned oi = 0; oi < length; ++oi) { - LineNumber* oldLine = lineNumberTableBody(t, oldTable, oi); - LineNumber* newLine = lineNumberTableBody(t, newTable, ni); + uint64_t oldLine = lineNumberTableBody(t, oldTable, oi); int ip = resolveIpForwards (context, lineNumberIp(oldLine), oi + 1 < length @@ -6116,12 +6124,9 @@ translateLineNumberTable(MyThread* t, Context* context, intptr_t start) : lineNumberIp(oldLine) + 1); if (LIKELY(ip >= 0)) { - lineNumberIp(newLine) - = context->compiler->machineIp(ip)->value() - start; - - lineNumberLine(newLine) = lineNumberLine(oldLine); - - ++ ni; + lineNumberTableBody(t, newTable, ni++) = lineNumber + (context->compiler->machineIp(ip)->value() - start, + lineNumberLine(oldLine)); } } @@ -6675,7 +6680,9 @@ makeGeneralFrameMapTable(MyThread* t, Context* context, uint8_t* start, pathIndex = subroutine->tableIndex; - THREAD_RUNTIME_ARRAY(t, SubroutineTrace*, traces, p->subroutineTraceCount); + THREAD_RUNTIME_ARRAY + (t, SubroutineTrace*, traces, p->subroutineTraceCount); + unsigned i = 0; for (SubroutineTrace* trace = p->subroutineTrace; trace; trace = trace->next) @@ -6795,9 +6802,9 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context) // we must acquire the class lock here at the latest unsigned codeSize = c->resolve - (allocator->base + allocator->offset + BytesPerWord); + (allocator->base + allocator->offset + TargetBytesPerWord); - unsigned total = pad(codeSize) + pad(c->poolSize()) + BytesPerWord; + unsigned total = pad(codeSize) + pad(c->poolSize()) + TargetBytesPerWord; uintptr_t* code = static_cast(allocator->allocate(total)); code[0] = codeSize; @@ -6810,7 +6817,8 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context) if (context->objectPool) { object pool = allocate3 (t, allocator, Machine::ImmortalAllocation, - FixedSizeOfArray + ((context->objectPoolCount + 1) * BytesPerWord), + FixedSizeOfArray + + ((context->objectPoolCount + 1) * TargetBytesPerWord), true); initArray(t, pool, context->objectPoolCount + 1); @@ -6821,7 +6829,7 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context) unsigned i = 1; for (PoolElement* p = context->objectPool; p; p = p->next) { - unsigned offset = ArrayBody + ((i++) * BytesPerWord); + unsigned offset = ArrayBody + ((i++) * TargetBytesPerWord); p->address = reinterpret_cast(pool) + offset; @@ -7023,7 +7031,7 @@ compile(MyThread* t, Context* context) progress = false; for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) { - ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i); + uint64_t eh = exceptionHandlerTableBody(t, eht, i); int start = resolveIpForwards (context, exceptionHandlerStart(eh), exceptionHandlerEnd(eh)); @@ -7042,7 +7050,7 @@ compile(MyThread* t, Context* context) Frame frame2(&frame, RUNTIME_ARRAY_BODY(stackMap)); unsigned end = exceptionHandlerEnd(eh); - if (exceptionHandlerIp(eh) >= start + if (exceptionHandlerIp(eh) >= static_cast(start) and exceptionHandlerIp(eh) < end) { end = exceptionHandlerIp(eh); @@ -9334,15 +9342,15 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p) p->thunks.default_.frameSavedOffset = a->length(); Assembler::Register thread(t->arch->thread()); - a->pushFrame(1, BytesPerWord, RegisterOperand, &thread); + a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread); Assembler::Constant proc(&(defaultContext.promise)); - a->apply(LongCall, BytesPerWord, ConstantOperand, &proc); + a->apply(LongCall, TargetBytesPerWord, ConstantOperand, &proc); a->popFrame(t->arch->alignFrameSize(1)); Assembler::Register result(t->arch->returnLow()); - a->apply(Jump, BytesPerWord, RegisterOperand, &result); + a->apply(Jump, TargetBytesPerWord, RegisterOperand, &result); p->thunks.default_.length = a->endBlock(false)->resolve(0, 0); } @@ -9355,38 +9363,38 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p) Assembler::Memory virtualCallTargetSrc (t->arch->stack(), (t->arch->frameFooterSize() + t->arch->frameReturnAddressSize()) - * BytesPerWord); + * TargetBytesPerWord); - a->apply(Move, BytesPerWord, MemoryOperand, &virtualCallTargetSrc, - BytesPerWord, RegisterOperand, &class_); + a->apply(Move, TargetBytesPerWord, MemoryOperand, &virtualCallTargetSrc, + TargetBytesPerWord, RegisterOperand, &class_); Assembler::Memory virtualCallTargetDst (t->arch->thread(), difference(&(t->virtualCallTarget), t)); - a->apply(Move, BytesPerWord, RegisterOperand, &class_, - BytesPerWord, MemoryOperand, &virtualCallTargetDst); + a->apply(Move, TargetBytesPerWord, RegisterOperand, &class_, + TargetBytesPerWord, MemoryOperand, &virtualCallTargetDst); Assembler::Register index(t->arch->virtualCallIndex()); Assembler::Memory virtualCallIndex (t->arch->thread(), difference(&(t->virtualCallIndex), t)); - a->apply(Move, BytesPerWord, RegisterOperand, &index, - BytesPerWord, MemoryOperand, &virtualCallIndex); + a->apply(Move, TargetBytesPerWord, RegisterOperand, &index, + TargetBytesPerWord, MemoryOperand, &virtualCallIndex); a->saveFrame(difference(&(t->stack), t), difference(&(t->ip), t)); p->thunks.defaultVirtual.frameSavedOffset = a->length(); Assembler::Register thread(t->arch->thread()); - a->pushFrame(1, BytesPerWord, RegisterOperand, &thread); + a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread); Assembler::Constant proc(&(defaultVirtualContext.promise)); - a->apply(LongCall, BytesPerWord, ConstantOperand, &proc); + a->apply(LongCall, TargetBytesPerWord, ConstantOperand, &proc); a->popFrame(t->arch->alignFrameSize(1)); Assembler::Register result(t->arch->returnLow()); - a->apply(Jump, BytesPerWord, RegisterOperand, &result); + a->apply(Jump, TargetBytesPerWord, RegisterOperand, &result); p->thunks.defaultVirtual.length = a->endBlock(false)->resolve(0, 0); } @@ -9400,10 +9408,10 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p) p->thunks.native.frameSavedOffset = a->length(); Assembler::Register thread(t->arch->thread()); - a->pushFrame(1, BytesPerWord, RegisterOperand, &thread); + a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread); Assembler::Constant proc(&(nativeContext.promise)); - a->apply(LongCall, BytesPerWord, ConstantOperand, &proc); + a->apply(LongCall, TargetBytesPerWord, ConstantOperand, &proc); a->popFrameAndUpdateStackAndReturn (t->arch->alignFrameSize(1), difference(&(t->stack), t)); @@ -9420,10 +9428,10 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p) p->thunks.aioob.frameSavedOffset = a->length(); Assembler::Register thread(t->arch->thread()); - a->pushFrame(1, BytesPerWord, RegisterOperand, &thread); + a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread); Assembler::Constant proc(&(aioobContext.promise)); - a->apply(LongCall, BytesPerWord, ConstantOperand, &proc); + a->apply(LongCall, TargetBytesPerWord, ConstantOperand, &proc); p->thunks.aioob.length = a->endBlock(false)->resolve(0, 0); } @@ -9437,10 +9445,10 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p) p->thunks.stackOverflow.frameSavedOffset = a->length(); Assembler::Register thread(t->arch->thread()); - a->pushFrame(1, BytesPerWord, RegisterOperand, &thread); + a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread); Assembler::Constant proc(&(stackOverflowContext.promise)); - a->apply(LongCall, BytesPerWord, ConstantOperand, &proc); + a->apply(LongCall, TargetBytesPerWord, ConstantOperand, &proc); p->thunks.stackOverflow.length = a->endBlock(false)->resolve(0, 0); } @@ -9454,7 +9462,7 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p) p->thunks.table.frameSavedOffset = a->length(); Assembler::Constant proc(&(tableContext.promise)); - a->apply(LongJump, BytesPerWord, ConstantOperand, &proc); + a->apply(LongJump, TargetBytesPerWord, ConstantOperand, &proc); p->thunks.table.length = a->endBlock(false)->resolve(0, 0); } @@ -9633,12 +9641,12 @@ compileVirtualThunk(MyThread* t, unsigned index, unsigned* size) ResolvedPromise indexPromise(index); Assembler::Constant indexConstant(&indexPromise); Assembler::Register indexRegister(t->arch->virtualCallIndex()); - a->apply(Move, BytesPerWord, ConstantOperand, &indexConstant, - BytesPerWord, RegisterOperand, &indexRegister); + a->apply(Move, TargetBytesPerWord, ConstantOperand, &indexConstant, + TargetBytesPerWord, RegisterOperand, &indexRegister); ResolvedPromise defaultVirtualThunkPromise(defaultVirtualThunk(t)); Assembler::Constant thunk(&defaultVirtualThunkPromise); - a->apply(Jump, BytesPerWord, ConstantOperand, &thunk); + a->apply(Jump, TargetBytesPerWord, ConstantOperand, &thunk); *size = a->endBlock(false)->resolve(0, 0); @@ -9723,7 +9731,7 @@ compile(MyThread* t, FixedAllocator* allocator, BootContext* bootContext, // resolve all exception handler catch types before we acquire // the class lock: for (unsigned i = 0; i < exceptionHandlerTableLength(t, ehTable); ++i) { - ExceptionHandler* handler = exceptionHandlerTableBody(t, ehTable, i); + uint64_t handler = exceptionHandlerTableBody(t, ehTable, i); if (exceptionHandlerCatchType(handler)) { resolveClassInPool (t, clone, exceptionHandlerCatchType(handler) - 1); diff --git a/src/compiler.cpp b/src/compiler.cpp index 0b7e8d1917..157bb82d61 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -10,6 +10,7 @@ #include "compiler.h" #include "assembler.h" +#include "target.h" using namespace vm; @@ -34,7 +35,7 @@ const unsigned StealRegisterReserveCount = 2; // this should be equal to the largest number of registers used by a // compare instruction: -const unsigned ResolveRegisterReserveCount = (BytesPerWord == 8 ? 2 : 4); +const unsigned ResolveRegisterReserveCount = (TargetBytesPerWord == 8 ? 2 : 4); const unsigned RegisterCopyCost = 1; const unsigned AddressCopyCost = 2; @@ -143,7 +144,7 @@ class Site { virtual SiteMask nextWordMask(Context*, unsigned) = 0; - virtual unsigned registerSize(Context*) { return BytesPerWord; } + virtual unsigned registerSize(Context*) { return TargetBytesPerWord; } virtual unsigned registerMask(Context*) { return 0; } @@ -467,8 +468,9 @@ class PoolPromise: public Promise { virtual int64_t value() { if (resolved()) { - return reinterpret_cast - (c->machineCode + pad(c->machineCodeSize) + (key * BytesPerWord)); + return reinterpret_cast + (c->machineCode + pad(c->machineCodeSize) + + (key * TargetBytesPerWord)); } abort(c); @@ -740,18 +742,18 @@ frameIndexToOffset(Context* c, unsigned frameIndex) { assert(c, frameIndex < totalFrameSize(c)); - return (frameIndex + c->arch->frameFooterSize()) * BytesPerWord; + return (frameIndex + c->arch->frameFooterSize()) * TargetBytesPerWord; } unsigned offsetToFrameIndex(Context* c, unsigned offset) { assert(c, static_cast - ((offset / BytesPerWord) - c->arch->frameFooterSize()) >= 0); - assert(c, ((offset / BytesPerWord) - c->arch->frameFooterSize()) + ((offset / TargetBytesPerWord) - c->arch->frameFooterSize()) >= 0); + assert(c, ((offset / TargetBytesPerWord) - c->arch->frameFooterSize()) < totalFrameSize(c)); - return (offset / BytesPerWord) - c->arch->frameFooterSize(); + return (offset / TargetBytesPerWord) - c->arch->frameFooterSize(); } unsigned @@ -837,7 +839,7 @@ class SiteIterator { Site** findNext(Site** p) { while (true) { if (*p) { - if (pass == 0 or (*p)->registerSize(c) > BytesPerWord) { + if (pass == 0 or (*p)->registerSize(c) > TargetBytesPerWord) { return p; } else { p = &((*p)->next); @@ -922,7 +924,7 @@ uniqueSite(Context* c, Value* v, Site* s) if (it.hasMore()) { // 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 - if (v->nextWord != v and s->registerSize(c) > BytesPerWord) { + if (v->nextWord != v and s->registerSize(c) > TargetBytesPerWord) { SiteIterator nit(c, v->nextWord); Site* p = nit.next(); if (nit.hasMore()) { @@ -1052,7 +1054,7 @@ deadWord(Context* c, Value* v) for (SiteIterator it(c, v, true, false); it.hasMore();) { Site* s = it.next(); - if (s->registerSize(c) > BytesPerWord) { + if (s->registerSize(c) > TargetBytesPerWord) { it.remove(c); addSite(c, nextWord, s); } @@ -1838,7 +1840,7 @@ class RegisterSite: public Site { RegisterSite* rs = static_cast(s); unsigned size = rs->registerSize(c); - if (size > BytesPerWord) { + if (size > TargetBytesPerWord) { assert(c, number != NoRegister); return number == rs->number; } else { @@ -1940,7 +1942,7 @@ class RegisterSite: public Site { virtual SiteMask nextWordMask(Context* c, unsigned) { assert(c, number != NoRegister); - if (registerSize(c) > BytesPerWord) { + if (registerSize(c) > TargetBytesPerWord) { return SiteMask (1 << RegisterOperand, number, NoFrameIndex); } else { @@ -1955,7 +1957,7 @@ class RegisterSite: public Site { if ((1 << number) & c->arch->floatRegisterMask()) { return c->arch->floatRegisterSize(); } else { - return BytesPerWord; + return TargetBytesPerWord; } } @@ -2065,9 +2067,9 @@ class MemorySite: public Site { MemorySite* ms = static_cast(s); return ms->base == this->base and ((index == 1 and ms->offset == static_cast - (this->offset + BytesPerWord)) + (this->offset + TargetBytesPerWord)) or (index == 0 and this->offset == static_cast - (ms->offset + BytesPerWord))) + (ms->offset + TargetBytesPerWord))) and ms->index == this->index and ms->scale == this->scale; } else { @@ -2149,7 +2151,7 @@ class MemorySite: public Site { assert(c, high == this or (static_cast(high)->base == base and static_cast(high)->offset - == static_cast(offset + BytesPerWord) + == static_cast(offset + TargetBytesPerWord) and static_cast(high)->index == index and static_cast(high)->scale == scale)); @@ -2164,7 +2166,7 @@ class MemorySite: public Site { Site* copyHalf(Context* c, bool add) { if (add) { - return memorySite(c, base, offset + BytesPerWord, index, scale); + return memorySite(c, base, offset + TargetBytesPerWord, index, scale); } else { return copy(c); } @@ -2181,7 +2183,7 @@ class MemorySite: public Site { virtual Site* makeNextWord(Context* c, unsigned index) { return memorySite (c, base, offset + ((index == 1) xor c->arch->bigEndian() - ? BytesPerWord : -BytesPerWord), + ? TargetBytesPerWord : -TargetBytesPerWord), this->index, scale); } @@ -2398,7 +2400,7 @@ maybeMove(Context* c, Read* read, bool intersectRead, bool includeNextWord, unsigned registerReserveCount = 0) { Value* value = read->value; - unsigned size = value == value->nextWord ? BytesPerWord : 8; + unsigned size = value == value->nextWord ? TargetBytesPerWord : 8; class MyCostCalculator: public CostCalculator { public: @@ -2926,8 +2928,8 @@ move(Context* c, Value* value, Site* src, Site* dst) unsigned srcSize; unsigned dstSize; if (value->nextWord == value) { - srcSize = BytesPerWord; - dstSize = BytesPerWord; + srcSize = TargetBytesPerWord; + dstSize = TargetBytesPerWord; } else { srcSize = src->registerSize(c); dstSize = dst->registerSize(c); @@ -2935,7 +2937,7 @@ move(Context* c, Value* value, Site* src, Site* dst) if (srcSize == dstSize) { apply(c, Move, srcSize, src, src, dstSize, dst, dst); - } else if (srcSize > BytesPerWord) { + } else if (srcSize > TargetBytesPerWord) { Site* low, *high, *other = pickSiteOrGrow(c, value, dst, &low, &high); other->freeze(c, value->nextWord); @@ -3065,7 +3067,7 @@ addReads(Context* c, Event* e, Value* v, unsigned size, { SingleRead* r = read(c, lowMask, lowSuccessor); addRead(c, e, v, r); - if (size > BytesPerWord) { + if (size > TargetBytesPerWord) { r->high_ = v->nextWord; addRead(c, e, v->nextWord, highMask, highSuccessor); } @@ -3234,7 +3236,7 @@ class CallEvent: public Event { uint8_t typeMask; uint64_t planRegisterMask; c->arch->plan - ((flags & Compiler::Aligned) ? AlignedCall : Call, BytesPerWord, + ((flags & Compiler::Aligned) ? AlignedCall : Call, TargetBytesPerWord, &typeMask, &planRegisterMask, &thunk); assert(c, not thunk); @@ -3251,10 +3253,11 @@ class CallEvent: public Event { Value* v = stack->value; stack = stack->next; - if ((BytesPerWord == 8 and (v == 0 or (i >= 1 and stack->value == 0))) - or (BytesPerWord == 4 and v->nextWord != v)) + if ((TargetBytesPerWord == 8 + and (v == 0 or (i >= 1 and stack->value == 0))) + or (TargetBytesPerWord == 4 and v->nextWord != v)) { - assert(c, BytesPerWord == 8 or v->nextWord == stack->value); + assert(c, TargetBytesPerWord == 8 or v->nextWord == stack->value); RUNTIME_ARRAY_BODY(arguments)[i--] = stack->value; stack = stack->next; @@ -3405,7 +3408,7 @@ class CallEvent: public Event { op = Call; } - apply(c, op, BytesPerWord, address->source, address->source); + apply(c, op, TargetBytesPerWord, address->source, address->source); if (traceHandler) { traceHandler->handleTrace(codePromise(c, c->assembler->offset(true)), @@ -3436,7 +3439,7 @@ class CallEvent: public Event { if (resultSize and live(c, result)) { addSite(c, result, registerSite(c, c->arch->returnLow())); - if (resultSize > BytesPerWord and live(c, result->nextWord)) { + if (resultSize > TargetBytesPerWord and live(c, result->nextWord)) { addSite(c, result->nextWord, registerSite(c, c->arch->returnHigh())); } } @@ -3758,16 +3761,17 @@ class MoveEvent: public Event { bool noop = srcSelectSize >= dstSize; - if (dstSize > BytesPerWord) { + if (dstSize > TargetBytesPerWord) { grow(c, dst); } - if (srcSelectSize > BytesPerWord) { + if (srcSelectSize > TargetBytesPerWord) { maybeSplit(c, src); } addReads(c, this, src, srcSelectSize, srcLowMask, noop ? dst : 0, - srcHighMask, noop and dstSize > BytesPerWord ? dst->nextWord : 0); + srcHighMask, + noop and dstSize > TargetBytesPerWord ? dst->nextWord : 0); } virtual const char* name() { @@ -3791,43 +3795,46 @@ class MoveEvent: public Event { SiteMask dstLowMask(dstTypeMask, dstRegisterMask, AnyFrameIndex); SiteMask dstHighMask(dstTypeMask, dstRegisterMask >> 32, AnyFrameIndex); - if (srcSelectSize >= BytesPerWord - and dstSize >= BytesPerWord + if (srcSelectSize >= TargetBytesPerWord + and dstSize >= TargetBytesPerWord and srcSelectSize >= dstSize) { if (dst->target) { - if (dstSize > BytesPerWord - and src->source->registerSize(c) > BytesPerWord) + if (dstSize > TargetBytesPerWord + and src->source->registerSize(c) > TargetBytesPerWord) { apply(c, Move, srcSelectSize, src->source, src->source, dstSize, dst->target, dst->target); if (live(c, dst) == 0) { removeSite(c, dst, dst->target); - if (dstSize > BytesPerWord) { + if (dstSize > TargetBytesPerWord) { removeSite(c, dst->nextWord, dst->nextWord->target); } } } else { - maybeMove(c, Move, BytesPerWord, BytesPerWord, src, - BytesPerWord, dst, dstLowMask); - if (dstSize > BytesPerWord) { - maybeMove(c, Move, BytesPerWord, BytesPerWord, src->nextWord, - BytesPerWord, dst->nextWord, dstHighMask); + maybeMove(c, Move, TargetBytesPerWord, TargetBytesPerWord, src, + TargetBytesPerWord, dst, dstLowMask); + if (dstSize > TargetBytesPerWord) { + maybeMove + (c, Move, TargetBytesPerWord, TargetBytesPerWord, src->nextWord, + TargetBytesPerWord, dst->nextWord, dstHighMask); } } } else { Site* low = pickSiteOrMove(c, src, dst, 0, 0); - if (dstSize > BytesPerWord) { + if (dstSize > TargetBytesPerWord) { pickSiteOrMove(c, src->nextWord, dst->nextWord, low, 1); } } - } else if (srcSelectSize <= BytesPerWord and dstSize <= BytesPerWord) { + } else if (srcSelectSize <= TargetBytesPerWord + and dstSize <= TargetBytesPerWord) + { maybeMove(c, type, srcSize, srcSelectSize, src, dstSize, dst, dstLowMask); } else { - assert(c, srcSize == BytesPerWord); - assert(c, srcSelectSize == BytesPerWord); + assert(c, srcSize == TargetBytesPerWord); + assert(c, srcSelectSize == TargetBytesPerWord); if (dst->nextWord->target or live(c, dst->nextWord)) { assert(c, dstLowMask.typeMask & (1 << RegisterOperand)); @@ -3847,8 +3854,8 @@ class MoveEvent: public Event { srcb, dstb, src); } - apply(c, Move, BytesPerWord, src->source, src->source, - BytesPerWord, low, low); + apply(c, Move, TargetBytesPerWord, src->source, src->source, + TargetBytesPerWord, low, low); low->thaw(c, dst); @@ -3871,7 +3878,7 @@ class MoveEvent: public Event { srcb, dstb, dst, dst->nextWord); } - apply(c, Move, BytesPerWord, low, low, dstSize, low, high); + apply(c, Move, TargetBytesPerWord, low, low, dstSize, low, high); high->thaw(c, dst->nextWord); @@ -3972,7 +3979,7 @@ void freezeSource(Context* c, unsigned size, Value* v) { v->source->freeze(c, v); - if (size > BytesPerWord) { + if (size > TargetBytesPerWord) { v->nextWord->source->freeze(c, v->nextWord); } } @@ -3981,7 +3988,7 @@ void thawSource(Context* c, unsigned size, Value* v) { v->source->thaw(c, v); - if (size > BytesPerWord) { + if (size > TargetBytesPerWord) { v->nextWord->source->thaw(c, v->nextWord); } } @@ -4002,7 +4009,7 @@ class CombineEvent: public Event { { addReads(c, this, first, firstSize, firstLowMask, firstHighMask); - if (resultSize > BytesPerWord) { + if (resultSize > TargetBytesPerWord) { grow(c, result); } @@ -4227,7 +4234,7 @@ push(Context* c, unsigned footprint, Value* v) if (footprint > 1) { assert(c, footprint == 2); - if (BytesPerWord == 4) { + if (TargetBytesPerWord == 4) { maybeSplit(c, low); high = pushWord(c, low->nextWord); } else { @@ -4288,9 +4295,9 @@ pop(Context* c, unsigned footprint) high = low->next; } - assert(c, (BytesPerWord == 8 + assert(c, (TargetBytesPerWord == 8 and low->value->nextWord == low->value and high->value == 0) - or (BytesPerWord == 4 and low->value->nextWord == high->value)); + or (TargetBytesPerWord == 4 and low->value->nextWord == high->value)); #endif // not NDEBUG popWord(c); @@ -4331,7 +4338,7 @@ storeLocal(Context* c, unsigned footprint, Value* v, unsigned index, bool copy) highIndex = index; } - if (BytesPerWord == 4) { + if (TargetBytesPerWord == 4) { assert(c, v->nextWord != v); high = storeLocal(c, 1, v->nextWord, highIndex, false); @@ -4423,11 +4430,11 @@ appendCombine(Context* c, TernaryOperation type, intptr_t handler = c->client->getThunk (type, firstSize, resultSize, &threadParameter); - unsigned stackSize = ceiling(secondSize, BytesPerWord) - + ceiling(firstSize, BytesPerWord); + unsigned stackSize = ceiling(secondSize, TargetBytesPerWord) + + ceiling(firstSize, TargetBytesPerWord); - local::push(c, ceiling(secondSize, BytesPerWord), second); - local::push(c, ceiling(firstSize, BytesPerWord), first); + local::push(c, ceiling(secondSize, TargetBytesPerWord), second); + local::push(c, ceiling(firstSize, TargetBytesPerWord), first); if (threadParameter) { ++ stackSize; @@ -4467,7 +4474,7 @@ class TranslateEvent: public Event { { bool condensed = c->arch->alwaysCondensed(type); - if (resultSize > BytesPerWord) { + if (resultSize > TargetBytesPerWord) { grow(c, result); } @@ -4549,7 +4556,7 @@ appendTranslate(Context* c, BinaryOperation type, unsigned firstSize, if (thunk) { Stack* oldStack = c->stack; - local::push(c, ceiling(firstSize, BytesPerWord), first); + local::push(c, ceiling(firstSize, TargetBytesPerWord), first); Stack* argumentStack = c->stack; c->stack = oldStack; @@ -4559,7 +4566,7 @@ appendTranslate(Context* c, BinaryOperation type, unsigned firstSize, (c, ValueGeneral, constantSite (c, c->client->getThunk(type, firstSize, resultSize))), 0, 0, result, resultSize, argumentStack, - ceiling(firstSize, BytesPerWord), 0); + ceiling(firstSize, TargetBytesPerWord), 0); } else { append(c, new (c->zone->allocate(sizeof(TranslateEvent))) TranslateEvent @@ -4632,7 +4639,7 @@ class MemoryEvent: public Event { popRead(c, this, base); if (index) { - if (BytesPerWord == 8 and indexRegister != NoRegister) { + if (TargetBytesPerWord == 8 and indexRegister != NoRegister) { apply(c, Move, 4, index->source, index->source, 8, index->source, index->source); } @@ -4798,7 +4805,7 @@ class BranchEvent: public Event { uint8_t typeMask; uint64_t registerMask; - c->arch->planDestination(type, size, 0, 0, size, 0, 0, BytesPerWord, + c->arch->planDestination(type, size, 0, 0, size, 0, 0, TargetBytesPerWord, &typeMask, ®isterMask); addRead(c, this, address, SiteMask(typeMask, registerMask, AnyFrameIndex)); @@ -4821,7 +4828,7 @@ class BranchEvent: public Event { int64_t firstValue = firstConstant->value->value(); int64_t secondValue = secondConstant->value->value(); - if (size > BytesPerWord) { + if (size > TargetBytesPerWord) { firstValue |= findConstantSite (c, first->nextWord)->value->value() << 32; secondValue |= findConstantSite @@ -4829,18 +4836,18 @@ class BranchEvent: public Event { } if (shouldJump(c, type, size, firstValue, secondValue)) { - apply(c, Jump, BytesPerWord, address->source, address->source); + apply(c, Jump, TargetBytesPerWord, address->source, address->source); } } else { freezeSource(c, size, first); freezeSource(c, size, second); - freezeSource(c, BytesPerWord, address); + freezeSource(c, TargetBytesPerWord, address); apply(c, type, size, first->source, first->nextWord->source, size, second->source, second->nextWord->source, - BytesPerWord, address->source, address->source); + TargetBytesPerWord, address->source, address->source); - thawSource(c, BytesPerWord, address); + thawSource(c, TargetBytesPerWord, address); thawSource(c, size, second); thawSource(c, size, first); } @@ -4872,7 +4879,7 @@ appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first, c->arch->planSource(type, size, &firstTypeMask, &firstRegisterMask, size, &secondTypeMask, &secondRegisterMask, - BytesPerWord, &thunk); + TargetBytesPerWord, &thunk); if (thunk) { Stack* oldStack = c->stack; @@ -4883,8 +4890,8 @@ appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first, assert(c, not threadParameter); - local::push(c, ceiling(size, BytesPerWord), second); - local::push(c, ceiling(size, BytesPerWord), first); + local::push(c, ceiling(size, TargetBytesPerWord), second); + local::push(c, ceiling(size, TargetBytesPerWord), first); Stack* argumentStack = c->stack; c->stack = oldStack; @@ -4893,7 +4900,7 @@ appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first, appendCall (c, value (c, ValueGeneral, constantSite(c, handler)), 0, 0, result, 4, - argumentStack, ceiling(size, BytesPerWord) * 2, 0); + argumentStack, ceiling(size, TargetBytesPerWord) * 2, 0); appendBranch(c, thunkBranch(c, type), 4, value (c, ValueGeneral, constantSite(c, static_cast(0))), @@ -4920,7 +4927,7 @@ class JumpEvent: public Event { bool thunk; uint8_t typeMask; uint64_t registerMask; - c->arch->plan(type, BytesPerWord, &typeMask, ®isterMask, &thunk); + c->arch->plan(type, TargetBytesPerWord, &typeMask, ®isterMask, &thunk); assert(c, not thunk); @@ -4933,7 +4940,7 @@ class JumpEvent: public Event { virtual void compile(Context* c) { if (not unreachable(this)) { - apply(c, type, BytesPerWord, address->source, address->source); + apply(c, type, TargetBytesPerWord, address->source, address->source); } for (Read* r = reads; r; r = r->eventNext) { @@ -4992,7 +4999,7 @@ class BoundsCheckEvent: public Event { if (constant) { if (constant->value->value() < 0) { Assembler::Constant handlerConstant(resolved(c, handler)); - a->apply(Call, BytesPerWord, ConstantOperand, &handlerConstant); + a->apply(Call, TargetBytesPerWord, ConstantOperand, &handlerConstant); } } else { outOfBoundsPromise = codePromise(c, static_cast(0)); @@ -5000,7 +5007,7 @@ class BoundsCheckEvent: public Event { ConstantSite zero(resolved(c, 0)); ConstantSite oob(outOfBoundsPromise); apply(c, JumpIfLess, 4, &zero, &zero, 4, index->source, index->source, - BytesPerWord, &oob, &oob); + TargetBytesPerWord, &oob, &oob); } if (constant == 0 or constant->value->value() >= 0) { @@ -5011,20 +5018,20 @@ class BoundsCheckEvent: public Event { CodePromise* nextPromise = codePromise(c, static_cast(0)); - freezeSource(c, BytesPerWord, index); + freezeSource(c, TargetBytesPerWord, index); ConstantSite next(nextPromise); apply(c, JumpIfGreater, 4, index->source, index->source, 4, &length, - &length, BytesPerWord, &next, &next); + &length, TargetBytesPerWord, &next, &next); - thawSource(c, BytesPerWord, index); + thawSource(c, TargetBytesPerWord, index); if (constant == 0) { outOfBoundsPromise->offset = a->offset(); } Assembler::Constant handlerConstant(resolved(c, handler)); - a->apply(Call, BytesPerWord, ConstantOperand, &handlerConstant); + a->apply(Call, TargetBytesPerWord, ConstantOperand, &handlerConstant); nextPromise->offset = a->offset(); } @@ -6268,7 +6275,7 @@ class MyCompiler: public Compiler { virtual void save(unsigned footprint, Operand* value) { c.saved = cons(&c, static_cast(value), c.saved); - if (BytesPerWord == 4 and footprint > 1) { + if (TargetBytesPerWord == 4 and footprint > 1) { assert(&c, footprint == 2); assert(&c, static_cast(value)->nextWord); @@ -6329,9 +6336,10 @@ class MyCompiler: public Compiler { high = s->next; } - assert(&c, (BytesPerWord == 8 + assert(&c, (TargetBytesPerWord == 8 and low->value->nextWord == low->value and high->value == 0) - or (BytesPerWord == 4 and low->value->nextWord == high->value)); + or (TargetBytesPerWord == 4 + and low->value->nextWord == high->value)); #endif // not NDEBUG if (bigEndian) { @@ -6355,20 +6363,20 @@ class MyCompiler: public Compiler { bool bigEndian = c.arch->bigEndian(); unsigned footprint = 0; - unsigned size = BytesPerWord; + unsigned size = TargetBytesPerWord; RUNTIME_ARRAY(Value*, arguments, argumentCount); int index = 0; for (unsigned i = 0; i < argumentCount; ++i) { Value* o = va_arg(a, Value*); if (o) { - if (bigEndian and size > BytesPerWord) { + if (bigEndian and size > TargetBytesPerWord) { RUNTIME_ARRAY_BODY(arguments)[index++] = o->nextWord; } RUNTIME_ARRAY_BODY(arguments)[index] = o; - if ((not bigEndian) and size > BytesPerWord) { + if ((not bigEndian) and size > TargetBytesPerWord) { RUNTIME_ARRAY_BODY(arguments)[++index] = o->nextWord; } - size = BytesPerWord; + size = TargetBytesPerWord; ++ index; } else { size = 8; @@ -6427,7 +6435,7 @@ class MyCompiler: public Compiler { highIndex = index; } - if (BytesPerWord == 4) { + if (TargetBytesPerWord == 4) { initLocal(1, highIndex, type); Value* next = c.locals[highIndex].value; v->nextWord = next; @@ -6499,7 +6507,7 @@ class MyCompiler: public Compiler { virtual Operand* load(unsigned srcSize, unsigned srcSelectSize, Operand* src, unsigned dstSize) { - assert(&c, dstSize >= BytesPerWord); + assert(&c, dstSize >= TargetBytesPerWord); Value* dst = value(&c, static_cast(src)->type); appendMove(&c, Move, srcSize, srcSelectSize, static_cast(src), @@ -6510,7 +6518,7 @@ class MyCompiler: public Compiler { virtual Operand* loadz(unsigned srcSize, unsigned srcSelectSize, Operand* src, unsigned dstSize) { - assert(&c, dstSize >= BytesPerWord); + assert(&c, dstSize >= TargetBytesPerWord); Value* dst = value(&c, static_cast(src)->type); appendMove(&c, MoveZ, srcSize, srcSelectSize, static_cast(src), @@ -6786,7 +6794,7 @@ class MyCompiler: public Compiler { virtual Operand* shl(unsigned size, Operand* a, Operand* b) { assert(&c, static_cast(a)->type == ValueGeneral); Value* result = value(&c, ValueGeneral); - appendCombine(&c, ShiftLeft, BytesPerWord, static_cast(a), + appendCombine(&c, ShiftLeft, TargetBytesPerWord, static_cast(a), size, static_cast(b), size, result); return result; } @@ -6794,7 +6802,7 @@ class MyCompiler: public Compiler { virtual Operand* shr(unsigned size, Operand* a, Operand* b) { assert(&c, static_cast(a)->type == ValueGeneral); Value* result = value(&c, ValueGeneral); - appendCombine(&c, ShiftRight, BytesPerWord, static_cast(a), + appendCombine(&c, ShiftRight, TargetBytesPerWord, static_cast(a), size, static_cast(b), size, result); return result; } @@ -6803,8 +6811,8 @@ class MyCompiler: public Compiler { assert(&c, static_cast(a)->type == ValueGeneral); Value* result = value(&c, ValueGeneral); appendCombine - (&c, UnsignedShiftRight, BytesPerWord, static_cast(a), size, - static_cast(b), size, result); + (&c, UnsignedShiftRight, TargetBytesPerWord, static_cast(a), + size, static_cast(b), size, result); return result; } @@ -6933,7 +6941,7 @@ class MyCompiler: public Compiler { } virtual unsigned poolSize() { - return c.constantCount * BytesPerWord; + return c.constantCount * TargetBytesPerWord; } virtual void write() { @@ -6962,7 +6970,7 @@ class MyCompiler: public Compiler { new (n->promise->listen(sizeof(Listener))) Listener(target); } - i += BytesPerWord; + i += TargetBytesPerWord; } } diff --git a/src/heap.cpp b/src/heap.cpp index be26c9ea3e..8208cd7e73 100644 --- a/src/heap.cpp +++ b/src/heap.cpp @@ -19,12 +19,6 @@ namespace { namespace local { -// an object must survive TenureThreshold + 2 garbage collections -// before being copied to gen2 (must be at least 1): -const unsigned TenureThreshold = 3; - -const unsigned FixieTenureThreshold = TenureThreshold + 2; - const unsigned Top = ~static_cast(0); const unsigned InitialGen2CapacityInBytes = 4 * 1024 * 1024; @@ -546,11 +540,14 @@ class Fixie { return totalSize(size, hasMask); } + // be sure to update e.g. TargetFixieSizeInBytes in bootimage.cpp if + // you add/remove/change fields in this class: + uint8_t age; bool hasMask; bool marked; bool dirty; - unsigned size; + uint32_t size; Fixie* next; Fixie** handle; uintptr_t body_[0]; diff --git a/src/heap.h b/src/heap.h index ecb60d2637..838d88786c 100644 --- a/src/heap.h +++ b/src/heap.h @@ -16,6 +16,12 @@ namespace vm { +// an object must survive TenureThreshold + 2 garbage collections +// before being copied to gen2 (must be at least 1): +const unsigned TenureThreshold = 3; + +const unsigned FixieTenureThreshold = TenureThreshold + 2; + class Heap: public Allocator { public: enum CollectionType { diff --git a/src/interpret.cpp b/src/interpret.cpp index b5810a434e..255977c25d 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -665,7 +665,7 @@ store(Thread* t, unsigned index) BytesPerWord * 2); } -ExceptionHandler* +uint64_t findExceptionHandler(Thread* t, object method, unsigned ip) { PROTECT(t, method); @@ -674,7 +674,7 @@ findExceptionHandler(Thread* t, object method, unsigned ip) if (eht) { for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) { - ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i); + uint64_t eh = exceptionHandlerTableBody(t, eht, i); if (ip - 1 >= exceptionHandlerStart(eh) and ip - 1 < exceptionHandlerEnd(eh)) @@ -708,7 +708,7 @@ findExceptionHandler(Thread* t, object method, unsigned ip) return 0; } -ExceptionHandler* +uint64_t findExceptionHandler(Thread* t, int frame) { return findExceptionHandler(t, frameMethod(t, frame), frameIp(t, frame)); @@ -2673,7 +2673,7 @@ interpret3(Thread* t, const int base) pokeInt(t, t->frame + FrameIpOffset, t->ip); for (; frame >= base; popFrame(t)) { - ExceptionHandler* eh = findExceptionHandler(t, frame); + uint64_t eh = findExceptionHandler(t, frame); if (eh) { sp = frame + FrameFootprint; ip = exceptionHandlerIp(eh); diff --git a/src/machine.cpp b/src/machine.cpp index 9168c09019..0219894f77 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -1143,11 +1143,10 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool) addendum, class_); + unsigned size = fieldSize(t, code); if (flags & ACC_STATIC) { - unsigned size = fieldSize(t, code); - unsigned excess = (staticOffset % size) % BytesPerWord; - if (excess) { - staticOffset += BytesPerWord - excess; + while (staticOffset % size) { + ++ staticOffset; } fieldOffset(t, field) = staticOffset; @@ -1162,12 +1161,13 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool) classVmFlags(t, class_) |= HasFinalMemberFlag; } - while (memberOffset % fieldSize(t, code)) { + while (memberOffset % size) { ++ memberOffset; } fieldOffset(t, field) = memberOffset; - memberOffset += fieldSize(t, code); + + memberOffset += size; } set(t, fieldTable, ArrayBody + (i * BytesPerWord), field); @@ -1298,11 +1298,12 @@ parseCode(Thread* t, Stream& s, object pool) if (ehtLength) { object eht = makeExceptionHandlerTable(t, ehtLength); for (unsigned i = 0; i < ehtLength; ++i) { - ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i); - exceptionHandlerStart(eh) = s.read2(); - exceptionHandlerEnd(eh) = s.read2(); - exceptionHandlerIp(eh) = s.read2(); - exceptionHandlerCatchType(eh) = s.read2(); + unsigned start = s.read2(); + unsigned end = s.read2(); + unsigned ip = s.read2(); + unsigned catchType = s.read2(); + exceptionHandlerTableBody(t, eht, i) = exceptionHandler + (start, end, ip, catchType); } set(t, code, CodeExceptionHandlerTable, eht); @@ -1319,9 +1320,9 @@ parseCode(Thread* t, Stream& s, object pool) unsigned lntLength = s.read2(); object lnt = makeLineNumberTable(t, lntLength); for (unsigned i = 0; i < lntLength; ++i) { - LineNumber* ln = lineNumberTableBody(t, lnt, i); - lineNumberIp(ln) = s.read2(); - lineNumberLine(ln) = s.read2(); + unsigned ip = s.read2(); + unsigned line = s.read2(); + lineNumberTableBody(t, lnt, i) = lineNumber(ip, line); } set(t, code, CodeLineNumberTable, lnt); @@ -2217,9 +2218,9 @@ boot(Thread* t) #include "type-java-initializations.cpp" -#ifdef AVIAN_HEAPDUMP + //#ifdef AVIAN_HEAPDUMP # include "type-name-initializations.cpp" -#endif + //#endif } } @@ -3428,6 +3429,16 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size, updateClassTables(t, real, class_); + if (root(t, Machine::PoolMap)) { + object bootstrapClass = hashMapFind + (t, root(t, Machine::BootstrapClassMap), className(t, class_), + byteArrayHash, byteArrayEqual); + + hashMapInsert + (t, root(t, Machine::PoolMap), bootstrapClass ? bootstrapClass : real, + pool, objectHash); + } + return real; } @@ -4426,7 +4437,7 @@ vmAddressFromLine(Thread* t, object m, unsigned line) unsigned top = lineNumberTableLength(t, lnt); for(unsigned i = bottom; i < top; i++) { - LineNumber* ln = lineNumberTableBody(t, lnt, i); + uint64_t ln = lineNumberTableBody(t, lnt, i); if(lineNumberLine(ln) == line) return reinterpret_cast(lineNumberIp(ln)); else if(lineNumberLine(ln) > line) diff --git a/src/machine.h b/src/machine.h index 28a3a764f1..1b53c9f8d8 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1253,6 +1253,7 @@ class Machine { MonitorMap, StringMap, ByteArrayMap, + PoolMap, ClassRuntimeDataTable, MethodRuntimeDataTable, JNIMethodTable, @@ -3283,14 +3284,20 @@ methodVirtual(Thread* t, object method) } inline unsigned -singletonMaskSize(unsigned count) +singletonMaskSize(unsigned count, unsigned bitsPerWord) { if (count) { - return ceiling(count + 2, BitsPerWord); + return ceiling(count + 2, bitsPerWord); } return 0; } +inline unsigned +singletonMaskSize(unsigned count) +{ + return singletonMaskSize(count, BitsPerWord); +} + inline unsigned singletonMaskSize(Thread* t, object singleton) { @@ -3315,11 +3322,17 @@ singletonMask(Thread* t, object singleton) (&singletonBody(t, singleton, singletonCount(t, singleton))); } +inline void +singletonMarkObject(uint32_t* mask, unsigned index) +{ + mask[(index + 2) / 32] + |= (static_cast(1) << ((index + 2) % 32)); +} + inline void singletonMarkObject(Thread* t, object singleton, unsigned index) { - singletonMask(t, singleton)[(index + 2) / 32] - |= (static_cast(1) << ((index + 2) % 32)); + singletonMarkObject(singletonMask(t, singleton), index); } inline bool @@ -3370,10 +3383,16 @@ singletonBit(Thread* t, object singleton, unsigned start, unsigned index) & (static_cast(1) << (index % BitsPerWord))) != 0; } +inline unsigned +poolMaskSize(unsigned count, unsigned bitsPerWord) +{ + return ceiling(count, bitsPerWord); +} + inline unsigned poolMaskSize(unsigned count) { - return ceiling(count, BitsPerWord); + return poolMaskSize(count, BitsPerWord); } inline unsigned @@ -3766,6 +3785,54 @@ methodClone(Thread* t, object method) methodCode(t, method)); } +inline uint64_t +exceptionHandler(uint64_t start, uint64_t end, uint64_t ip, uint64_t catchType) +{ + return (start << 48) | (end << 32) | (ip << 16) | catchType; +} + +inline unsigned +exceptionHandlerStart(uint64_t eh) +{ + return eh >> 48; +} + +inline unsigned +exceptionHandlerEnd(uint64_t eh) +{ + return (eh >> 32) & 0xFFFF; +} + +inline unsigned +exceptionHandlerIp(uint64_t eh) +{ + return (eh >> 16) & 0xFFFF; +} + +inline unsigned +exceptionHandlerCatchType(uint64_t eh) +{ + return eh & 0xFFFF; +} + +inline uint64_t +lineNumber(uint64_t ip, uint64_t line) +{ + return (ip << 32) | line; +} + +inline unsigned +lineNumberIp(uint64_t ln) +{ + return ln >> 32; +} + +inline unsigned +lineNumberLine(uint64_t ln) +{ + return ln & 0xFFFFFFFF; +} + inline FILE* errorLog(Thread* t) { diff --git a/src/process.cpp b/src/process.cpp index d2aebb131d..ac1c21917e 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -271,7 +271,7 @@ findLineNumber(Thread* t, object method, unsigned ip) unsigned top = lineNumberTableLength(t, lnt); for (unsigned span = top - bottom; span; span = top - bottom) { unsigned middle = bottom + (span / 2); - LineNumber* ln = lineNumberTableBody(t, lnt, middle); + uint64_t ln = lineNumberTableBody(t, lnt, middle); if (ip >= lineNumberIp(ln) and (middle + 1 == lineNumberTableLength(t, lnt) diff --git a/src/target.h b/src/target.h new file mode 100644 index 0000000000..91244b7ed6 --- /dev/null +++ b/src/target.h @@ -0,0 +1,66 @@ +/* Copyright (c) 2011, 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 TARGET_H +#define TARGET_H + +#define TARGET_V1(v) (v) + +#ifdef TARGET_OPPOSITE_ENDIAN +# define TARGET_V2(v) \ + ((((v) >> 8) & 0xFF) | \ + (((v) << 8))) +# define TARGET_V4(v) \ + ((((v) >> 24) & 0x000000FF) | \ + (((v) >> 8) & 0x0000FF00) | \ + (((v) << 8) & 0x00FF0000) | \ + (((v) << 24))) +# define TARGET_V8(v) \ + (((static_cast(v) >> 56) & UINT64_C(0x00000000000000FF)) | \ + ((static_cast(v) >> 40) & UINT64_C(0x000000000000FF00)) | \ + ((static_cast(v) >> 24) & UINT64_C(0x0000000000FF0000)) | \ + ((static_cast(v) >> 8) & UINT64_C(0x00000000FF000000)) | \ + ((static_cast(v) << 8) & UINT64_C(0x000000FF00000000)) | \ + ((static_cast(v) << 24) & UINT64_C(0x0000FF0000000000)) | \ + ((static_cast(v) << 40) & UINT64_C(0x00FF000000000000)) | \ + ((static_cast(v) << 56))) +#else +# define TARGET_V2(v) (v) +# define TARGET_V4(v) (v) +# define TARGET_V8(v) (v) +#endif + +namespace vm { + +#ifdef TARGET_BYTES_PER_WORD +# if (TARGET_BYTES_PER_WORD == 8) +# define TARGET_VW(v) TARGET_V8(v) +typedef uint64_t target_uintptr_t; +typedef int64_t target_intptr_t; +const unsigned TargetBytesPerWord = 8; +# elif (TARGET_BYTES_PER_WORD == 4) +# define TARGET_VW(v) TARGET_V4(v) +typedef uint32_t target_uintptr_t; +typedef int32_t target_intptr_t; +const unsigned TargetBytesPerWord = 4; +# else +# error +# endif +#else +typedef uintptr_t target_uintptr_t; +typedef intptr_t target_intptr_t; +const unsigned TargetBytesPerWord = BytesPerWord; +#endif + +const unsigned TargetBitsPerWord = TargetBytesPerWord * 8; + +} // namespace vm + +#endif//TARGET_H diff --git a/src/type-generator.cpp b/src/type-generator.cpp index 626573af8e..eb0141f215 100644 --- a/src/type-generator.cpp +++ b/src/type-generator.cpp @@ -225,7 +225,6 @@ class Object { Scalar, Array, Method, - Pod, Type, Pair, Number, @@ -314,20 +313,18 @@ class List { class Scalar : public Object { public: Object* owner; - Object* typeObject; const char* typeName; const char* name; unsigned elementSize; bool noassert; bool nogc; - static Scalar* make(Object* owner, Object* typeObject, const char* typeName, - const char* name, unsigned size) + static Scalar* make(Object* owner, const char* typeName, const char* name, + unsigned size) { Scalar* o = allocate(); o->type = Object::Scalar; o->owner = owner; - o->typeObject = typeObject; o->typeName = typeName; o->name = name; o->elementSize = size; @@ -339,13 +336,12 @@ class Scalar : public Object { class Array : public Scalar { public: - static Array* make(Object* owner, Object* typeObject, const char* typeName, - const char* name, unsigned elementSize) + static Array* make(Object* owner, const char* typeName, const char* name, + unsigned elementSize) { Array* o = allocate(); o->type = Object::Array; o->owner = owner; - o->typeObject = typeObject; o->typeName = typeName; o->name = name; o->elementSize = elementSize; @@ -380,19 +376,6 @@ memberOwner(Object* o) } } -Object* -memberTypeObject(Object* o) -{ - switch (o->type) { - case Object::Scalar: - case Object::Array: - return static_cast(o)->typeObject; - - default: - UNREACHABLE; - } -} - const char* memberTypeName(Object* o) { @@ -406,6 +389,17 @@ memberTypeName(Object* o) } } +const char* +memberTypeEnumName(Object* o) +{ + const char* n = memberTypeName(o); + if (strcmp("void*", n) == 0) { + return "word"; + } else { + return n; + } +} + const char*& memberName(Object* o) { @@ -545,7 +539,7 @@ const char* typeName(Object* o) { switch (o->type) { - case Object::Type: case Object::Pod: + case Object::Type: return static_cast(o)->name; default: @@ -557,7 +551,7 @@ const char* typeJavaName(Object* o) { switch (o->type) { - case Object::Type: case Object::Pod: + case Object::Type: return static_cast(o)->javaName; default: @@ -569,7 +563,7 @@ Object* typeMembers(Object* o) { switch (o->type) { - case Object::Type: case Object::Pod: + case Object::Type: return static_cast(o)->members.first; default: @@ -605,10 +599,10 @@ void addMember(Object* o, Object* member) { switch (o->type) { - case Object::Type: case Object::Pod: + case Object::Type: if (member->type == Object::Array) { static_cast(o)->members.append - (Scalar::make(o, 0, "uintptr_t", "length", BytesPerWord)); + (Scalar::make(o, "uintptr_t", "length", BytesPerWord)); } static_cast(o)->members.append(member); break; @@ -822,7 +816,7 @@ declaration(const char* name, Object* declarations) for (Object* p = declarations; p; p = cdr(p)) { Object* o = car(p); switch (o->type) { - case Object::Type: case Object::Pod: + case Object::Type: if (equal(name, typeName(o))) return o; break; @@ -842,9 +836,6 @@ javaDeclaration(const char* name, Object* declarations) if (typeJavaName(o) and equal(name, typeJavaName(o))) return o; break; - case Object::Pod: - break; - default: UNREACHABLE; } } @@ -854,15 +845,11 @@ javaDeclaration(const char* name, Object* declarations) Object* derivationChain(Object* o) { - if (o->type == Object::Pod) { - return cons(o, 0); - } else { - Object* chain = 0; - for (Object* p = o; p; p = typeSuper(p)) { - chain = cons(p, chain); - } - return chain; + Object* chain = 0; + for (Object* p = o; p; p = typeSuper(p)) { + chain = cons(p, chain); } + return chain; } class MemberIterator { @@ -883,7 +870,7 @@ class MemberIterator { members(0), member(0), index_(-1), - offset_(type->type == Object::Pod ? 0 : BytesPerWord), + offset_(BytesPerWord), size_(0), padding_(0), alignment_(BytesPerWord) @@ -972,21 +959,6 @@ class MemberIterator { } }; -unsigned -typeSize(Object* o) -{ - switch (o->type) { - case Object::Pod: { - MemberIterator it(o); - while (it.hasMore()) it.next(); - return pad(it.offset() + it.space()); - } break; - - default: - UNREACHABLE; - } -} - bool namesPointer(const char* s) { @@ -996,7 +968,7 @@ namesPointer(const char* s) } unsigned -sizeOf(const char* type, Object* declarations) +sizeOf(const char* type) { if (equal(type, "object") or equal(type, "intptr_t") or equal(type, "uintptr_t")) @@ -1021,33 +993,29 @@ sizeOf(const char* type, Object* declarations) } else if (namesPointer(type)) { return BytesPerWord; } else { - Object* dec = declaration(type, declarations); - if (dec) return typeSize(dec); - fprintf(stderr, "unexpected type: %s\n", type); abort(); } } Object* -parseArray(Object* t, Object* p, Object* declarations) +parseArray(Object* t, Object* p) { const char* typeName = string(car(p)); p = cdr(p); const char* name = string(car(p)); - return Array::make(t, declaration(typeName, declarations), - typeName, name, sizeOf(typeName, declarations)); + return Array::make(t, typeName, name, sizeOf(typeName)); } Object* -parseMember(Object* t, Object* p, Object* declarations); +parseMember(Object* t, Object* p); Object* -parseMember(Object* t, Object* p, Object* declarations, bool* isNew) +parseMember(Object* t, Object* p, bool* isNew) { - Object* member = parseMember(t, p, declarations); + Object* member = parseMember(t, p); for (MemberIterator it(t); it.hasMore();) { Object* m = it.next(); if (equal(memberName(m), memberName(member))) { @@ -1063,34 +1031,32 @@ parseMember(Object* t, Object* p, Object* declarations, bool* isNew) } Object* -parseMember(Object* t, Object* p, Object* declarations) +parseMember(Object* t, Object* p) { const char* spec = string(car(p)); if (equal(spec, "array")) { - return parseArray(t, cdr(p), declarations); + return parseArray(t, cdr(p)); } else if (equal(spec, "noassert")) { bool isNew; - Object* member = parseMember(t, cdr(p), declarations, &isNew); + Object* member = parseMember(t, cdr(p), &isNew); memberNoAssert(member) = true; return isNew ? member : 0; } else if (equal(spec, "nogc")) { bool isNew; - Object* member = parseMember(t, cdr(p), declarations, &isNew); + Object* member = parseMember(t, cdr(p), &isNew); memberNoGC(member) = true; return isNew ? member : 0; } else if (equal(spec, "require")) { bool isNew; - Object* member = parseMember(t, cdr(p), declarations, &isNew); + Object* member = parseMember(t, cdr(p), &isNew); return isNew ? member : 0; } else if (equal(spec, "alias")) { bool isNew; - Object* member = parseMember(t, cdr(cdr(p)), declarations, &isNew); + Object* member = parseMember(t, cdr(cdr(p)), &isNew); memberName(member) = string(car(cdr(p))); return 0; } else { - return Scalar::make(t, declaration(spec, declarations), spec, - string(car(cdr(p))), - sizeOf(spec, declarations)); + return Scalar::make(t, spec, string(car(cdr(p))), sizeOf(spec)); } } @@ -1105,7 +1071,7 @@ parseSubdeclaration(Object* t, Object* p, Object* declarations) assert(typeSuper(t)); assert(typeSuper(t)->type == Object::Type); } else { - Object* member = parseMember(t, p, declarations); + Object* member = parseMember(t, p); if (member) { addMember(t, member); } @@ -1297,7 +1263,7 @@ parseJavaClass(Object* type, Stream* s, Object* declarations) const char* memberType = fieldType(spec); Object* member = Scalar::make - (type, 0, memberType, name, sizeOf(memberType, declarations)); + (type, memberType, name, sizeOf(memberType)); addMember(type, member); } @@ -1365,7 +1331,7 @@ parseType(Finder* finder, Object::ObjectType type, Object* p, if (type == Object::Type) { parseSubdeclaration(t, car(p), declarations); } else { - Object* member = parseMember(t, car(p), declarations); + Object* member = parseMember(t, car(p)); if (member) { assert(member->type == Object::Scalar); addMember(t, member); @@ -1390,8 +1356,6 @@ parseDeclaration(Finder* finder, Object* p, Object* declarations) const char* spec = string(car(p)); if (equal(spec, "type")) { return parseType(finder, Object::Type, cdr(p), declarations); - } else if (equal(spec, "pod")) { - return parseType(finder, Object::Pod, cdr(p), declarations); } else { fprintf(stderr, "unexpected declaration spec: %s\n", spec); abort(); @@ -1473,7 +1437,6 @@ void writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false) { const char* typeName = memberTypeName(member); - if (memberTypeObject(member)) typeName = capitalize(typeName); if (not unsafe) { out->write("const unsigned "); @@ -1491,22 +1454,12 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false) out->write("*"); } else { out->write(typeName); - if (member->type != Object::Scalar and memberTypeObject(member)) { - out->write("*"); - } else { - out->write("&"); - } + out->write("&"); } out->write("\n"); writeAccessorName(out, member, unsafe); - if (memberOwner(member)->type == Object::Pod) { - out->write("("); - out->write(capitalize(local::typeName(memberOwner(member)))); - out->write("*"); - } else { - out->write("(Thread* t UNUSED, object"); - } + out->write("(Thread* t UNUSED, object"); out->write(" o"); if (member->type != Object::Scalar) { out->write(", unsigned i"); @@ -1537,41 +1490,22 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false) out->write("*"); } else { out->write(typeName); - if (member->type != Object::Scalar and memberTypeObject(member)) { - out->write("*"); - } else { - out->write("&"); - } + out->write("&"); } out->write(">(reinterpret_cast(o)"); - if (endsWith("[0]", typeName) - or (member->type != Object::Scalar - and memberTypeObject(member))) - { - out->write(" + "); - } else { - out->write("["); - } + out->write("["); out->write(capitalize(local::typeName(memberOwner(member)))); out->write(capitalize(memberName(member))); if (member->type != Object::Scalar) { out->write(" + (i * "); - unsigned elementSize = (memberTypeObject(member) ? - typeSize(memberTypeObject(member)) : - sizeOf(memberTypeName(member), 0)); + unsigned elementSize = sizeOf(memberTypeName(member)); out->write(elementSize); out->write(")"); } - if (not endsWith("[0]", typeName) - and (member->type == Object::Scalar - or memberTypeObject(member) == 0)) - { - out->write("]"); - } - out->write(");\n}\n\n"); + out->write("]);\n}\n\n"); } Object* @@ -1615,39 +1549,13 @@ typeOffset(Object* type) return typeOffset(0, type); } -void -writePods(Output* out, Object* declarations) -{ - for (Object* p = declarations; p; p = cdr(p)) { - Object* o = car(p); - switch (o->type) { - case Object::Pod: { - out->write("const unsigned "); - out->write(capitalize(typeName(o))); - out->write("Size = "); - out->write(typeSize(o)); - out->write(";\n\n"); - - out->write("struct "); - out->write(capitalize(typeName(o))); - out->write(" { uint8_t body["); - out->write(capitalize(typeName(o))); - out->write("Size]; };\n\n"); - } break; - - default: break; - } - } -} - void writeAccessors(Output* out, Object* declarations) { for (Object* p = declarations; p; p = cdr(p)) { Object* o = car(p); switch (o->type) { - case Object::Type: - case Object::Pod: { + case Object::Type: { Object* offset = typeOffset (o, o->type == Object::Type ? typeSuper(o) : 0); for (MemberIterator it(o, true); it.hasMore();) { @@ -2031,15 +1939,6 @@ typeObjectMask(Object* type) case Object::Array: { if (memberGC(m)) { set(&mask, offset); - } else if (memberTypeObject(m) - and memberTypeObject(m)->type == Object::Pod) - { - for (MemberIterator it(memberTypeObject(m)); it.hasMore();) { - Object* m = it.next(); - if (memberGC(m)) { - set(&mask, offset + (it.offset() / BytesPerWord)); - } - } } } break; @@ -2207,13 +2106,73 @@ writeNameInitializations(Output* out, Object* declarations) } } +void +writeMap(Output* out, Object* type) +{ + for (MemberIterator it(type); it.hasMore();) { + Object* m = it.next(); + + switch (m->type) { + case Object::Scalar: { + out->write("Type_"); + out->write(memberTypeEnumName(m)); + } break; + + case Object::Array: { + out->write("Type_array, "); + out->write("Type_"); + out->write(memberTypeEnumName(m)); + } break; + + default: UNREACHABLE; + } + + out->write(", "); + } + + out->write("Type_none"); +} + +void +writeMaps(Output* out, Object* declarations) +{ + unsigned count = 0; + for (Object* p = declarations; p; p = cdr(p)) { + if (car(p)->type == Object::Type) { + ++ count; + } + } + + out->write("Type types[]["); + out->write(count); + out->write("] = {\n"); + bool wrote = false; + for (Object* p = declarations; p; p = cdr(p)) { + Object* o = car(p); + if (o->type == Object::Type) { + if (wrote) { + out->write(",\n"); + } else { + wrote = true; + } + + out->write("// "); + out->write(typeName(o)); + out->write("\n{ "); + writeMap(out, o); + out->write(" }"); + } + } + out->write("\n};"); +} + void usageAndExit(const char* command) { fprintf(stderr, "usage: %s " "{enums,declarations,constructors,initializations," - "java-initializations,name-initializations}\n", + "java-initializations,name-initializations,maps}\n", command); exit(-1); } @@ -2243,7 +2202,8 @@ main(int ac, char** av) or local::equal(av[4], "constructors") or local::equal(av[4], "initializations") or local::equal(av[4], "java-initializations") - or local::equal(av[4], "name-initializations"))) + or local::equal(av[4], "name-initializations") + or local::equal(av[4], "maps"))) { local::usageAndExit(av[0]); } @@ -2301,7 +2261,6 @@ main(int ac, char** av) out.Output::write(local::typeCount(declarations)); out.write(";\n\n"); - local::writePods(&out, declarations); local::writeAccessors(&out, declarations); local::writeSizes(&out, declarations); local::writeInitializerDeclarations(&out, declarations); @@ -2315,6 +2274,8 @@ main(int ac, char** av) local::writeJavaInitializations(&out, declarations); } else if (local::equal(av[4], "name-initializations")) { local::writeNameInitializations(&out, declarations); + } else if (local::equal(av[4], "maps")) { + local::writeMaps(&out, declarations); } return 0; diff --git a/src/types.def b/src/types.def index 2178c3a7fa..c95ed03a0a 100644 --- a/src/types.def +++ b/src/types.def @@ -64,23 +64,13 @@ (type region (void* region) - (unsigned position)) - -(pod exceptionHandler - (uint16_t start) - (uint16_t end) - (uint16_t ip) - (uint16_t catchType)) + (uint32_t position)) (type exceptionHandlerTable - (array exceptionHandler body)) - -(pod lineNumber - (uint32_t ip) - (uint32_t line)) + (array uint64_t body)) (type lineNumberTable - (array lineNumber body)) + (array uint64_t body)) (type code (object pool) @@ -126,7 +116,7 @@ (type traceElement (object method) - (int ip)) + (int32_t ip)) (type treeNode (object value) @@ -155,7 +145,7 @@ (void* waitTail) (object acquireHead) (object acquireTail) - (unsigned depth)) + (uint32_t depth)) (type monitorNode (void* value) diff --git a/src/x86.cpp b/src/x86.cpp index 670c5482d3..5a90ede640 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -9,6 +9,7 @@ details. */ #include "assembler.h" +#include "target.h" #include "vector.h" #define CAST1(x) reinterpret_cast(x) @@ -60,17 +61,17 @@ enum { }; const unsigned GeneralRegisterMask -= BytesPerWord == 4 ? 0x000000ff : 0x0000ffff; += TargetBytesPerWord == 4 ? 0x000000ff : 0x0000ffff; const unsigned FloatRegisterMask -= BytesPerWord == 4 ? 0x00ff0000 : 0xffff0000; += TargetBytesPerWord == 4 ? 0x00ff0000 : 0xffff0000; const unsigned FrameHeaderSize = (UseFramePointer ? 2 : 1); const int LongJumpRegister = r10; const unsigned StackAlignmentInBytes = 16; -const unsigned StackAlignmentInWords = StackAlignmentInBytes / BytesPerWord; +const unsigned StackAlignmentInWords = StackAlignmentInBytes / TargetBytesPerWord; bool isInt8(intptr_t v) @@ -478,7 +479,7 @@ detectFeature(unsigned ecx, unsigned edx); bool useSSE(ArchitectureContext* c) { - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { // amd64 implies SSE2 support return true; } else if (c->useNativeFeatures) { @@ -502,7 +503,7 @@ useSSE(ArchitectureContext* c) void maybeRex(Context* c, unsigned size, int a, int index, int base, bool always) { - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { uint8_t byte; if (size == 8) { byte = REX_W; @@ -656,7 +657,7 @@ storeLoadBarrier(Context* c) } else { // lock addq $0x0,(%rsp): c->code.append(0xf0); - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { c->code.append(0x48); } c->code.append(0x83); @@ -746,7 +747,7 @@ callR(Context*, unsigned, Assembler::Register*); void callC(Context* c, unsigned size UNUSED, Assembler::Constant* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); unconditional(c, 0xe8, a); } @@ -754,9 +755,9 @@ callC(Context* c, unsigned size UNUSED, Assembler::Constant* a) void longCallC(Context* c, unsigned size, Assembler::Constant* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { Assembler::Register r(LongJumpRegister); moveCR2(c, size, a, size, &r, 11); callR(c, size, &r); @@ -768,7 +769,7 @@ longCallC(Context* c, unsigned size, Assembler::Constant* a) void jumpR(Context* c, unsigned size UNUSED, Assembler::Register* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); maybeRex(c, 4, a); opcode(c, 0xff, 0xe0 + regCode(a)); @@ -777,7 +778,7 @@ jumpR(Context* c, unsigned size UNUSED, Assembler::Register* a) void jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); unconditional(c, 0xe9, a); } @@ -785,7 +786,7 @@ jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* a) void jumpM(Context* c, unsigned size UNUSED, Assembler::Memory* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); maybeRex(c, 4, a); opcode(c, 0xff); @@ -795,9 +796,9 @@ jumpM(Context* c, unsigned size UNUSED, Assembler::Memory* a) void longJumpC(Context* c, unsigned size, Assembler::Constant* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { Assembler::Register r(LongJumpRegister); moveCR2(c, size, a, size, &r, 11); jumpR(c, size, &r); @@ -809,7 +810,7 @@ longJumpC(Context* c, unsigned size, Assembler::Constant* a) void callR(Context* c, unsigned size UNUSED, Assembler::Register* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); // maybeRex.W has no meaning here so we disable it maybeRex(c, 4, a); @@ -819,7 +820,7 @@ callR(Context* c, unsigned size UNUSED, Assembler::Register* a) void callM(Context* c, unsigned size UNUSED, Assembler::Memory* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); maybeRex(c, 4, a); opcode(c, 0xff); @@ -836,9 +837,9 @@ alignedCallC(Context* c, unsigned size, Assembler::Constant* a) void alignedLongCallC(Context* c, unsigned size, Assembler::Constant* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { new (c->zone->allocate(sizeof(AlignmentPadding))) AlignmentPadding(c, 2, 8); longCallC(c, size, a); @@ -857,9 +858,9 @@ alignedJumpC(Context* c, unsigned size, Assembler::Constant* a) void alignedLongJumpC(Context* c, unsigned size, Assembler::Constant* a) { - assert(c, size == BytesPerWord); + assert(c, size == TargetBytesPerWord); - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { new (c->zone->allocate(sizeof(AlignmentPadding))) AlignmentPadding(c, 2, 8); longJumpC(c, size, a); @@ -871,7 +872,7 @@ alignedLongJumpC(Context* c, unsigned size, Assembler::Constant* a) void pushR(Context* c, unsigned size, Assembler::Register* a) { - if (BytesPerWord == 4 and size == 8) { + if (TargetBytesPerWord == 4 and size == 8) { Assembler::Register ah(a->high); pushR(c, 4, &ah); @@ -889,7 +890,7 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a, void popR(Context* c, unsigned size, Assembler::Register* a) { - if (BytesPerWord == 4 and size == 8) { + if (TargetBytesPerWord == 4 and size == 8) { Assembler::Register ah(a->high); popR(c, 4, a); @@ -897,7 +898,7 @@ popR(Context* c, unsigned size, Assembler::Register* a) } else { maybeRex(c, 4, a); opcode(c, 0x58 + regCode(a)); - if (BytesPerWord == 8 and size == 4) { + if (TargetBytesPerWord == 8 and size == 4) { moveRR(c, 4, a, 8, a); } } @@ -910,7 +911,7 @@ addCarryCR(Context* c, unsigned size, Assembler::Constant* a, void negateR(Context* c, unsigned size, Assembler::Register* a) { - if (BytesPerWord == 4 and size == 8) { + if (TargetBytesPerWord == 4 and size == 8) { assert(c, a->low == rax and a->high == rdx); ResolvedPromise zeroPromise(0); @@ -940,7 +941,7 @@ void moveCR2(Context* c, UNUSED unsigned aSize, Assembler::Constant* a, UNUSED unsigned bSize, Assembler::Register* b, unsigned promiseOffset) { - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { int64_t v = a->value->value(); ResolvedPromise high((v >> 32) & 0xFFFFFFFF); @@ -954,13 +955,13 @@ moveCR2(Context* c, UNUSED unsigned aSize, Assembler::Constant* a, moveCR(c, 4, &al, 4, b); moveCR(c, 4, &ah, 4, &bh); } else { - maybeRex(c, BytesPerWord, b); + maybeRex(c, TargetBytesPerWord, b); opcode(c, 0xb8 + regCode(b)); if (a->value->resolved()) { c->code.appendAddress(a->value->value()); } else { appendImmediateTask - (c, a->value, offset(c), BytesPerWord, promiseOffset); + (c, a->value, offset(c), TargetBytesPerWord, promiseOffset); c->code.appendAddress(static_cast(0)); } } @@ -1008,7 +1009,7 @@ void sseMoveCR(Context* c, unsigned aSize, Assembler::Constant* a, unsigned bSize, Assembler::Register* b) { - assert(c, aSize <= BytesPerWord); + assert(c, aSize <= TargetBytesPerWord); Assembler::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); moveCR2(c, aSize, a, aSize, &tmp, 0); sseMoveRR(c, aSize, &tmp, bSize, b); @@ -1031,7 +1032,7 @@ swapRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a, unsigned bSize UNUSED, Assembler::Register* b) { assert(c, aSize == bSize); - assert(c, aSize == BytesPerWord); + assert(c, aSize == TargetBytesPerWord); alwaysRex(c, aSize, a, b); opcode(c, 0x87); @@ -1047,7 +1048,7 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a, return; } - if (BytesPerWord == 4 and aSize == 8 and bSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8 and bSize == 8) { Assembler::Register ah(a->high); Assembler::Register bh(b->high); @@ -1065,11 +1066,11 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a, } else { switch (aSize) { case 1: - if (BytesPerWord == 4 and a->low > rbx) { + if (TargetBytesPerWord == 4 and a->low > rbx) { assert(c, b->low <= rbx); - moveRR(c, BytesPerWord, a, BytesPerWord, b); - moveRR(c, 1, b, BytesPerWord, b); + moveRR(c, TargetBytesPerWord, a, TargetBytesPerWord, b); + moveRR(c, 1, b, TargetBytesPerWord, b); } else { alwaysRex(c, aSize, b, a); opcode(c, 0x0f, 0xbe); @@ -1085,7 +1086,7 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a, case 4: if (bSize == 8) { - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { alwaysRex(c, bSize, b, a); opcode(c, 0x63); modrm(c, 0xc0, a, b); @@ -1125,7 +1126,7 @@ sseMoveMR(Context* c, unsigned aSize, Assembler::Memory* a, { assert(c, aSize >= 4); - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { opcode(c, 0xf3); opcode(c, 0x0f, 0x7e); modrmSibImm(c, b, a); @@ -1160,7 +1161,7 @@ moveMR(Context* c, unsigned aSize, Assembler::Memory* a, break; case 4: - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { maybeRex(c, bSize, b, a); opcode(c, 0x63); modrmSibImm(c, b, a); @@ -1179,7 +1180,7 @@ moveMR(Context* c, unsigned aSize, Assembler::Memory* a, break; case 8: - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { Assembler::Memory ah(a->base, a->offset + 4, a->index, a->scale); Assembler::Register bh(b->high); @@ -1203,7 +1204,7 @@ sseMoveRM(Context* c, unsigned aSize, Assembler::Register* a, assert(c, aSize >= 4); assert(c, aSize == bSize); - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { opcode(c, 0x66); opcode(c, 0x0f, 0xd6); modrmSibImm(c, a, b); @@ -1241,7 +1242,7 @@ moveRM(Context* c, unsigned aSize, Assembler::Register* a, break; case 4: - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { maybeRex(c, bSize, a, b); opcode(c, 0x89); modrmSibImm(c, a, b); @@ -1253,7 +1254,7 @@ moveRM(Context* c, unsigned aSize, Assembler::Register* a, break; case 8: - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { maybeRex(c, bSize, a, b); opcode(c, 0x89); modrmSibImm(c, a, b); @@ -1274,7 +1275,7 @@ void moveAR(Context* c, unsigned aSize, Assembler::Address* a, unsigned bSize, Assembler::Register* b) { - assert(c, BytesPerWord == 8 or (aSize == 4 and bSize == 4)); + assert(c, TargetBytesPerWord == 8 or (aSize == 4 and bSize == 4)); Assembler::Constant constant(a->address); Assembler::Memory memory(b->low, 0, -1, 0); @@ -1323,7 +1324,7 @@ moveCM(Context* c, unsigned aSize UNUSED, Assembler::Constant* a, break; case 8: { - if (BytesPerWord == 8) { + if (TargetBytesPerWord == 8) { if (a->value->resolved() and isInt32(a->value->value())) { maybeRex(c, bSize, b); opcode(c, 0xc7); @@ -1370,7 +1371,7 @@ void moveZMR(Context* c, unsigned aSize UNUSED, Assembler::Memory* a, unsigned bSize UNUSED, Assembler::Register* b) { - assert(c, bSize == BytesPerWord); + assert(c, bSize == TargetBytesPerWord); assert(c, aSize == 2); maybeRex(c, bSize, b, a); @@ -1382,7 +1383,7 @@ void addCarryRR(Context* c, unsigned size, Assembler::Register* a, Assembler::Register* b) { - assert(c, BytesPerWord == 8 or size == 4); + assert(c, TargetBytesPerWord == 8 or size == 4); maybeRex(c, size, a, b); opcode(c, 0x11); @@ -1395,7 +1396,7 @@ addRR(Context* c, unsigned aSize, Assembler::Register* a, { assert(c, aSize == bSize); - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { Assembler::Register ah(a->high); Assembler::Register bh(b->high); @@ -1432,7 +1433,7 @@ addCR(Context* c, unsigned aSize, Assembler::Constant* a, int64_t v = a->value->value(); if (v) { - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); Assembler::Constant ah(&high); @@ -1468,7 +1469,7 @@ void subtractBorrowCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, Assembler::Register* b) { - assert(c, BytesPerWord == 8 or size == 4); + assert(c, TargetBytesPerWord == 8 or size == 4); int64_t v = a->value->value(); if (isInt8(v)) { @@ -1491,7 +1492,7 @@ subtractCR(Context* c, unsigned aSize, Assembler::Constant* a, int64_t v = a->value->value(); if (v) { - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); Assembler::Constant ah(&high); @@ -1527,7 +1528,7 @@ void subtractBorrowRR(Context* c, unsigned size, Assembler::Register* a, Assembler::Register* b) { - assert(c, BytesPerWord == 8 or size == 4); + assert(c, TargetBytesPerWord == 8 or size == 4); maybeRex(c, size, a, b); opcode(c, 0x19); @@ -1540,7 +1541,7 @@ subtractRR(Context* c, unsigned aSize, Assembler::Register* a, { assert(c, aSize == bSize); - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { Assembler::Register ah(a->high); Assembler::Register bh(b->high); @@ -1560,7 +1561,7 @@ andRR(Context* c, unsigned aSize, Assembler::Register* a, assert(c, aSize == bSize); - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { Assembler::Register ah(a->high); Assembler::Register bh(b->high); @@ -1581,7 +1582,7 @@ andCR(Context* c, unsigned aSize, Assembler::Constant* a, int64_t v = a->value->value(); - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); Assembler::Constant ah(&high); @@ -1618,7 +1619,7 @@ orRR(Context* c, unsigned aSize, Assembler::Register* a, { assert(c, aSize == bSize); - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { Assembler::Register ah(a->high); Assembler::Register bh(b->high); @@ -1639,7 +1640,7 @@ orCR(Context* c, unsigned aSize, Assembler::Constant* a, int64_t v = a->value->value(); if (v) { - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); Assembler::Constant ah(&high); @@ -1675,7 +1676,7 @@ void xorRR(Context* c, unsigned aSize, Assembler::Register* a, unsigned bSize UNUSED, Assembler::Register* b) { - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { Assembler::Register ah(a->high); Assembler::Register bh(b->high); @@ -1696,7 +1697,7 @@ xorCR(Context* c, unsigned aSize, Assembler::Constant* a, int64_t v = a->value->value(); if (v) { - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); Assembler::Constant ah(&high); @@ -1735,7 +1736,7 @@ multiplyRR(Context* c, unsigned aSize, Assembler::Register* a, assert(c, aSize == bSize); - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { assert(c, b->high == rdx); assert(c, b->low != rax); assert(c, a->low != rax); @@ -1870,7 +1871,7 @@ compareRR(Context* c, unsigned aSize, Assembler::Register* a, unsigned bSize UNUSED, Assembler::Register* b) { assert(c, aSize == bSize); - assert(c, aSize <= BytesPerWord); + assert(c, aSize <= TargetBytesPerWord); maybeRex(c, aSize, a, b); opcode(c, 0x39); @@ -1882,7 +1883,7 @@ compareCR(Context* c, unsigned aSize, Assembler::Constant* a, unsigned bSize, Assembler::Register* b) { assert(c, aSize == bSize); - assert(c, BytesPerWord == 8 or aSize == 4); + assert(c, TargetBytesPerWord == 8 or aSize == 4); if (a->value->resolved() and isInt32(a->value->value())) { int64_t v = a->value->value(); @@ -1907,9 +1908,9 @@ compareRM(Context* c, unsigned aSize, Assembler::Register* a, unsigned bSize UNUSED, Assembler::Memory* b) { assert(c, aSize == bSize); - assert(c, BytesPerWord == 8 or aSize == 4); + assert(c, TargetBytesPerWord == 8 or aSize == 4); - if (BytesPerWord == 8 and aSize == 4) { + if (TargetBytesPerWord == 8 and aSize == 4) { moveRR(c, 4, a, 8, a); } maybeRex(c, bSize, a, b); @@ -1922,7 +1923,7 @@ compareCM(Context* c, unsigned aSize, Assembler::Constant* a, unsigned bSize, Assembler::Memory* b) { assert(c, aSize == bSize); - assert(c, BytesPerWord == 8 or aSize == 4); + assert(c, TargetBytesPerWord == 8 or aSize == 4); if (a->value->resolved()) { int64_t v = a->value->value(); @@ -2048,7 +2049,7 @@ branchRR(Context* c, TernaryOperation op, unsigned size, if (isFloatBranch(op)) { compareFloatRR(c, size, a, size, b); branchFloat(c, op, target); - } else if (size > BytesPerWord) { + } else if (size > TargetBytesPerWord) { Assembler::Register ah(a->high); Assembler::Register bh(b->high); @@ -2066,7 +2067,7 @@ branchCR(Context* c, TernaryOperation op, unsigned size, { assert(c, not isFloatBranch(op)); - if (size > BytesPerWord) { + if (size > TargetBytesPerWord) { int64_t v = a->value->value(); ResolvedPromise low(v & ~static_cast(0)); @@ -2090,7 +2091,7 @@ branchRM(Context* c, TernaryOperation op, unsigned size, Assembler::Constant* target) { assert(c, not isFloatBranch(op)); - assert(c, size <= BytesPerWord); + assert(c, size <= TargetBytesPerWord); compareRM(c, size, a, size, b); branch(c, op, target); @@ -2102,7 +2103,7 @@ branchCM(Context* c, TernaryOperation op, unsigned size, Assembler::Constant* target) { assert(c, not isFloatBranch(op)); - assert(c, size <= BytesPerWord); + assert(c, size <= TargetBytesPerWord); compareCM(c, size, a, size, b); branch(c, op, target); @@ -2114,7 +2115,7 @@ multiplyCR(Context* c, unsigned aSize, Assembler::Constant* a, { assert(c, aSize == bSize); - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); Assembler::Register tmp(c->client->acquireTemporary(mask), c->client->acquireTemporary(mask)); @@ -2182,7 +2183,7 @@ remainderRR(Context* c, unsigned aSize, Assembler::Register* a, opcode(c, 0xf7, 0xf8 + regCode(a)); Assembler::Register dx(rdx); - moveRR(c, BytesPerWord, &dx, BytesPerWord, b); + moveRR(c, TargetBytesPerWord, &dx, TargetBytesPerWord, b); } void @@ -2194,7 +2195,7 @@ doShift(Context* c, UNUSED void (*shift) { int64_t v = a->value->value(); - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { c->client->save(rcx); Assembler::Register cx(rcx); @@ -2219,7 +2220,7 @@ shiftLeftRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a, { assert(c, a->low == rcx); - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { // shld opcode(c, 0x0f, 0xa5); modrm(c, 0xc0, b->high, b->low); @@ -2255,7 +2256,7 @@ shiftRightRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a, unsigned bSize, Assembler::Register* b) { assert(c, a->low == rcx); - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { // shrd opcode(c, 0x0f, 0xad); modrm(c, 0xc0, b->low, b->high); @@ -2295,7 +2296,7 @@ unsignedShiftRightRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a, { assert(c, a->low == rcx); - if (BytesPerWord == 4 and bSize == 8) { + if (TargetBytesPerWord == 4 and bSize == 8) { // shrd opcode(c, 0x0f, 0xad); modrm(c, 0xc0, b->low, b->high); @@ -2556,7 +2557,7 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED, uint8_t* instruction = static_cast(*ip); // skip stack overflow check, if present: - if (BytesPerWord == 4) { + if (TargetBytesPerWord == 4) { if (*start == 0x39) { start += 11; } @@ -2571,7 +2572,7 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED, if (UseFramePointer) { // skip preamble - start += (BytesPerWord == 4 ? 3 : 4); + start += (TargetBytesPerWord == 4 ? 3 : 4); if (instruction <= start or *instruction == 0x5d) { *ip = static_cast(*stack)[1]; @@ -2596,13 +2597,13 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED, // check for post-non-tail-call stack adjustment of the form "add // $offset,%rsp": - if (BytesPerWord == 4) { + if (TargetBytesPerWord == 4) { if ((*instruction == 0x83 or *instruction == 0x81) and instruction[1] == 0xec) { offset -= (*instruction == 0x83 ? instruction[2] : read4(instruction + 2)) - / BytesPerWord; + / TargetBytesPerWord; } } else if (*instruction == 0x48 and (instruction[1] == 0x83 or instruction[1] == 0x81) @@ -2610,7 +2611,7 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED, { offset -= (instruction[1] == 0x83 ? instruction[3] : read4(instruction + 3)) - / BytesPerWord; + / TargetBytesPerWord; } // todo: check for and handle tail calls @@ -2773,7 +2774,7 @@ class MyArchitecture: public Assembler::Architecture { } virtual int returnHigh() { - return (BytesPerWord == 4 ? rdx : NoRegister); + return (TargetBytesPerWord == 4 ? rdx : NoRegister); } virtual int virtualCallTarget() { @@ -2807,7 +2808,7 @@ class MyArchitecture: public Assembler::Architecture { } virtual unsigned frameFootprint(unsigned footprint) { -#ifdef PLATFORM_WINDOWS +#ifdef TARGET_PLATFORM_WINDOWS return max(footprint, StackAlignmentInWords); #else return max(footprint > argumentRegisterCount() ? @@ -2829,18 +2830,18 @@ class MyArchitecture: public Assembler::Architecture { } virtual unsigned argumentRegisterCount() { -#ifdef PLATFORM_WINDOWS - if (BytesPerWord == 8) return 4; else +#ifdef TARGET_PLATFORM_WINDOWS + if (TargetBytesPerWord == 8) return 4; else #else - if (BytesPerWord == 8) return 6; else + if (TargetBytesPerWord == 8) return 6; else #endif return 0; } virtual int argumentRegister(unsigned index) { - assert(&c, BytesPerWord == 8); + assert(&c, TargetBytesPerWord == 8); switch (index) { -#ifdef PLATFORM_WINDOWS +#ifdef TARGET_PLATFORM_WINDOWS case 0: return rcx; case 1: @@ -2913,7 +2914,7 @@ class MyArchitecture: public Assembler::Architecture { assertAlignment = false; } - if (BytesPerWord == 4 or op == Call or op == Jump) { + if (TargetBytesPerWord == 4 or op == Call or op == Jump) { uint8_t* instruction = static_cast(returnAddress) - 5; assert(&c, ((op == Call or op == LongCall) and *instruction == 0xE8) @@ -2945,8 +2946,9 @@ class MyArchitecture: public Assembler::Architecture { } } - virtual void setConstant(void* dst, uintptr_t constant) { - memcpy(dst, &constant, BytesPerWord); + virtual void setConstant(void* dst, uint64_t constant) { + target_uintptr_t v = TARGET_VW(constant); + memcpy(dst, &v, TargetBytesPerWord); } virtual unsigned alignFrameSize(unsigned sizeInWords) { @@ -3040,7 +3042,7 @@ class MyArchitecture: public Assembler::Architecture { break; case Absolute: - if (aSize <= BytesPerWord) { + if (aSize <= TargetBytesPerWord) { *aTypeMask = (1 << RegisterOperand); *aRegisterMask = (static_cast(1) << rax); } else { @@ -3089,7 +3091,7 @@ class MyArchitecture: public Assembler::Architecture { break; case Float2Int: - if (useSSE(&c) and bSize <= BytesPerWord) { + if (useSSE(&c) and bSize <= TargetBytesPerWord) { *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); *aRegisterMask = (static_cast(FloatRegisterMask) << 32) | FloatRegisterMask; @@ -3099,7 +3101,7 @@ class MyArchitecture: public Assembler::Architecture { break; case Int2Float: - if (useSSE(&c) and aSize <= BytesPerWord) { + if (useSSE(&c) and aSize <= TargetBytesPerWord) { *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); *aRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); @@ -3112,7 +3114,7 @@ class MyArchitecture: public Assembler::Architecture { *aTypeMask = ~0; *aRegisterMask = ~static_cast(0); - if (BytesPerWord == 4) { + if (TargetBytesPerWord == 4) { if (aSize == 4 and bSize == 8) { *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); const uint32_t mask @@ -3188,7 +3190,7 @@ class MyArchitecture: public Assembler::Architecture { *bTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); } - if (BytesPerWord == 4) { + if (TargetBytesPerWord == 4) { if (aSize == 4 and bSize == 8) { *bRegisterMask = (static_cast(1) << (rdx + 32)) | (static_cast(1) << rax); @@ -3223,7 +3225,7 @@ class MyArchitecture: public Assembler::Architecture { *tmpRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); } else if (dstTypeMask & (1 << RegisterOperand)) { - if (size > BytesPerWord) { + if (size > TargetBytesPerWord) { // can't move directly from FPR to GPR or vice-versa for // values larger than the GPR size if (dstRegisterMask & FloatRegisterMask) { @@ -3239,7 +3241,7 @@ class MyArchitecture: public Assembler::Architecture { if (dstRegisterMask & FloatRegisterMask) { // can't move directly from constant to FPR *srcTypeMask &= ~(1 << ConstantOperand); - if (size > BytesPerWord) { + if (size > TargetBytesPerWord) { *tmpTypeMask = 1 << MemoryOperand; } else { *tmpTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); @@ -3290,7 +3292,7 @@ class MyArchitecture: public Assembler::Architecture { break; case Multiply: - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); *aRegisterMask = (static_cast(mask) << 32) | mask; *bRegisterMask = (static_cast(1) << (rdx + 32)) | mask; @@ -3301,7 +3303,7 @@ class MyArchitecture: public Assembler::Architecture { break; case Divide: - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { *thunk = true; } else { *aTypeMask = (1 << RegisterOperand); @@ -3311,7 +3313,7 @@ class MyArchitecture: public Assembler::Architecture { break; case Remainder: - if (BytesPerWord == 4 and aSize == 8) { + if (TargetBytesPerWord == 4 and aSize == 8) { *thunk = true; } else { *aTypeMask = (1 << RegisterOperand); @@ -3404,15 +3406,15 @@ class MyAssembler: public Assembler { Register stack(rsp); Memory stackLimit(rbx, stackLimitOffsetFromThread); Constant handlerConstant(resolved(&c, handler)); - branchRM(&c, JumpIfGreaterOrEqual, BytesPerWord, &stack, &stackLimit, + branchRM(&c, JumpIfGreaterOrEqual, TargetBytesPerWord, &stack, &stackLimit, &handlerConstant); } virtual void saveFrame(unsigned stackOffset, unsigned) { Register stack(rsp); Memory stackDst(rbx, stackOffset); - apply(Move, BytesPerWord, RegisterOperand, &stack, - BytesPerWord, MemoryOperand, &stackDst); + apply(Move, TargetBytesPerWord, RegisterOperand, &stack, + TargetBytesPerWord, MemoryOperand, &stackDst); } virtual void pushFrame(unsigned argumentCount, ...) { @@ -3430,7 +3432,7 @@ class MyAssembler: public Assembler { = static_cast(va_arg(a, int)); RUNTIME_ARRAY_BODY(arguments)[i].operand = va_arg(a, Operand*); footprint += ceiling - (RUNTIME_ARRAY_BODY(arguments)[i].size, BytesPerWord); + (RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord); } va_end(a); @@ -3448,7 +3450,7 @@ class MyAssembler: public Assembler { RegisterOperand, &dst); } else { - Memory dst(rsp, offset * BytesPerWord); + Memory dst(rsp, offset * TargetBytesPerWord); apply(Move, RUNTIME_ARRAY_BODY(arguments)[i].size, RUNTIME_ARRAY_BODY(arguments)[i].type, @@ -3456,7 +3458,8 @@ class MyAssembler: public Assembler { pad(RUNTIME_ARRAY_BODY(arguments)[i].size), MemoryOperand, &dst); - offset += ceiling(RUNTIME_ARRAY_BODY(arguments)[i].size, BytesPerWord); + offset += ceiling + (RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord); } } } @@ -3466,40 +3469,40 @@ class MyAssembler: public Assembler { if (UseFramePointer) { Register base(rbp); - pushR(&c, BytesPerWord, &base); + pushR(&c, TargetBytesPerWord, &base); - apply(Move, BytesPerWord, RegisterOperand, &stack, - BytesPerWord, RegisterOperand, &base); + apply(Move, TargetBytesPerWord, RegisterOperand, &stack, + TargetBytesPerWord, RegisterOperand, &base); } - Constant footprintConstant(resolved(&c, footprint * BytesPerWord)); - apply(Subtract, BytesPerWord, ConstantOperand, &footprintConstant, - BytesPerWord, RegisterOperand, &stack, - BytesPerWord, RegisterOperand, &stack); + Constant footprintConstant(resolved(&c, footprint * TargetBytesPerWord)); + apply(Subtract, TargetBytesPerWord, ConstantOperand, &footprintConstant, + TargetBytesPerWord, RegisterOperand, &stack, + TargetBytesPerWord, RegisterOperand, &stack); } virtual void adjustFrame(unsigned difference) { Register stack(rsp); - Constant differenceConstant(resolved(&c, difference * BytesPerWord)); - apply(Subtract, BytesPerWord, ConstantOperand, &differenceConstant, - BytesPerWord, RegisterOperand, &stack, - BytesPerWord, RegisterOperand, &stack); + Constant differenceConstant(resolved(&c, difference * TargetBytesPerWord)); + apply(Subtract, TargetBytesPerWord, ConstantOperand, &differenceConstant, + TargetBytesPerWord, RegisterOperand, &stack, + TargetBytesPerWord, RegisterOperand, &stack); } virtual void popFrame(unsigned frameFootprint) { if (UseFramePointer) { Register base(rbp); Register stack(rsp); - apply(Move, BytesPerWord, RegisterOperand, &base, - BytesPerWord, RegisterOperand, &stack); + apply(Move, TargetBytesPerWord, RegisterOperand, &base, + TargetBytesPerWord, RegisterOperand, &stack); - popR(&c, BytesPerWord, &base); + popR(&c, TargetBytesPerWord, &base); } else { Register stack(rsp); - Constant footprint(resolved(&c, frameFootprint * BytesPerWord)); - apply(Add, BytesPerWord, ConstantOperand, &footprint, - BytesPerWord, RegisterOperand, &stack, - BytesPerWord, RegisterOperand, &stack); + Constant footprint(resolved(&c, frameFootprint * TargetBytesPerWord)); + apply(Add, TargetBytesPerWord, ConstantOperand, &footprint, + TargetBytesPerWord, RegisterOperand, &stack, + TargetBytesPerWord, RegisterOperand, &stack); } } @@ -3515,40 +3518,44 @@ class MyAssembler: public Assembler { unsigned baseSize = UseFramePointer ? 1 : 0; Memory returnAddressSrc - (rsp, (frameFootprint + baseSize) * BytesPerWord); - moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &tmp); + (rsp, (frameFootprint + baseSize) * TargetBytesPerWord); + moveMR(&c, TargetBytesPerWord, &returnAddressSrc, TargetBytesPerWord, + &tmp); Memory returnAddressDst - (rsp, (frameFootprint - offset + baseSize) * BytesPerWord); - moveRM(&c, BytesPerWord, &tmp, BytesPerWord, &returnAddressDst); + (rsp, (frameFootprint - offset + baseSize) * TargetBytesPerWord); + moveRM(&c, TargetBytesPerWord, &tmp, TargetBytesPerWord, + &returnAddressDst); c.client->releaseTemporary(tmp.low); if (UseFramePointer) { - Memory baseSrc(rsp, frameFootprint * BytesPerWord); + Memory baseSrc(rsp, frameFootprint * TargetBytesPerWord); Register base(rbp); - moveMR(&c, BytesPerWord, &baseSrc, BytesPerWord, &base); + moveMR(&c, TargetBytesPerWord, &baseSrc, TargetBytesPerWord, &base); } Register stack(rsp); Constant footprint - (resolved(&c, (frameFootprint - offset + baseSize) * BytesPerWord)); - addCR(&c, BytesPerWord, &footprint, BytesPerWord, &stack); + (resolved + (&c, (frameFootprint - offset + baseSize) * TargetBytesPerWord)); + + addCR(&c, TargetBytesPerWord, &footprint, TargetBytesPerWord, &stack); if (returnAddressSurrogate != NoRegister) { assert(&c, offset > 0); Register ras(returnAddressSurrogate); - Memory dst(rsp, offset * BytesPerWord); - moveRM(&c, BytesPerWord, &ras, BytesPerWord, &dst); + Memory dst(rsp, offset * TargetBytesPerWord); + moveRM(&c, TargetBytesPerWord, &ras, TargetBytesPerWord, &dst); } if (framePointerSurrogate != NoRegister) { assert(&c, offset > 0); Register fps(framePointerSurrogate); - Memory dst(rsp, (offset - 1) * BytesPerWord); - moveRM(&c, BytesPerWord, &fps, BytesPerWord, &dst); + Memory dst(rsp, (offset - 1) * TargetBytesPerWord); + moveRM(&c, TargetBytesPerWord, &fps, TargetBytesPerWord, &dst); } } else { popFrame(frameFootprint); @@ -3568,15 +3575,15 @@ class MyAssembler: public Assembler { if (TailCalls and argumentFootprint > StackAlignmentInWords) { Register returnAddress(rcx); - popR(&c, BytesPerWord, &returnAddress); + popR(&c, TargetBytesPerWord, &returnAddress); Register stack(rsp); Constant adjustment (resolved(&c, (argumentFootprint - StackAlignmentInWords) - * BytesPerWord)); - addCR(&c, BytesPerWord, &adjustment, BytesPerWord, &stack); + * TargetBytesPerWord)); + addCR(&c, TargetBytesPerWord, &adjustment, TargetBytesPerWord, &stack); - jumpR(&c, BytesPerWord, &returnAddress); + jumpR(&c, TargetBytesPerWord, &returnAddress); } else { return_(&c); } @@ -3588,13 +3595,13 @@ class MyAssembler: public Assembler { popFrame(frameFootprint); Register returnAddress(rcx); - popR(&c, BytesPerWord, &returnAddress); + popR(&c, TargetBytesPerWord, &returnAddress); Register stack(rsp); Memory stackSrc(rbx, stackOffsetFromThread); - moveMR(&c, BytesPerWord, &stackSrc, BytesPerWord, &stack); + moveMR(&c, TargetBytesPerWord, &stackSrc, TargetBytesPerWord, &stack); - jumpR(&c, BytesPerWord, &returnAddress); + jumpR(&c, TargetBytesPerWord, &returnAddress); } virtual void apply(Operation op) { @@ -3624,7 +3631,7 @@ class MyAssembler: public Assembler { { if (isBranch(op)) { assert(&c, aSize == bSize); - assert(&c, cSize == BytesPerWord); + assert(&c, cSize == TargetBytesPerWord); assert(&c, cType == ConstantOperand); arch_->c.branchOperations[branchIndex(&(arch_->c), aType, bType)]